Overshoot to the nearest character when text nodes are not contiguous

This commit is contained in:
Antonio Scandurra 2016-05-01 11:05:14 +02:00
parent 334b4c1104
commit 4f5efe98ff
2 changed files with 56 additions and 30 deletions

View File

@ -160,6 +160,34 @@ describe "LinesYardstick", ->
expect(linesYardstick.screenPositionForPixelPosition({top: 70, left: 225})).toEqual([5, 30])
expect(linesYardstick.screenPositionForPixelPosition({top: 84, left: 247.1})).toEqual([6, 33])
it "overshoots to the nearest character when text nodes are not spatially contiguous", ->
atom.styles.addStyleSheet """
* {
font-size: 12px;
font-family: monospace;
}
"""
buildLineNode = (screenRow) ->
lineNode = document.createElement("div")
lineNode.style.whiteSpace = "pre"
lineNode.innerHTML = '<span>foo</span><span style="margin-left: 40px">bar</span>'
jasmine.attachToDOM(lineNode)
createdLineNodes.push(lineNode)
lineNode
editor.setText("foobar")
expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 7})).toEqual([0, 1])
expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 14})).toEqual([0, 2])
expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 21})).toEqual([0, 3])
expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 30})).toEqual([0, 3])
expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 50})).toEqual([0, 3])
expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 62})).toEqual([0, 3])
expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 69})).toEqual([0, 4])
expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 76})).toEqual([0, 5])
expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 100})).toEqual([0, 6])
expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 200})).toEqual([0, 6])
it "clips pixel positions above buffer start", ->
expect(linesYardstick.screenPositionForPixelPosition(top: -Infinity, left: -Infinity)).toEqual [0, 0]
expect(linesYardstick.screenPositionForPixelPosition(top: -Infinity, left: Infinity)).toEqual [0, 0]

View File

@ -32,7 +32,7 @@ class LinesYardstick
lineOffset = lineNode.getBoundingClientRect().left
targetLeft += lineOffset
textNodeIndex = -1
textNodeIndex = 0
low = 0
high = textNodes.length - 1
while low <= high
@ -41,19 +41,16 @@ class LinesYardstick
rangeRect = @clientRectForRange(textNode, 0, textNode.length)
if targetLeft < rangeRect.left
high = mid - 1
textNodeIndex = Math.max(0, mid - 1)
else if targetLeft > rangeRect.right
low = mid + 1
textNodeIndex = Math.min(textNodes.length - 1, mid + 1)
else
textNodeIndex = mid
break
if textNodeIndex is -1
textNodesExtent = 0
textNodesExtent += textContent.length for {textContent} in textNodes
Point(row, textNodesExtent)
else
textNode = textNodes[textNodeIndex]
characterIndex = -1
characterIndex = 0
low = 0
high = textNode.textContent.length - 1
while low <= high
@ -66,8 +63,10 @@ class LinesYardstick
rangeRect = @clientRectForRange(textNode, charIndex, nextCharIndex)
if targetLeft < rangeRect.left
high = charIndex - 1
characterIndex = Math.max(0, charIndex - 1)
else if targetLeft > rangeRect.right
low = nextCharIndex
characterIndex = Math.min(textNode.textContent.length, nextCharIndex)
else
if targetLeft <= ((rangeRect.left + rangeRect.right) / 2)
characterIndex = charIndex
@ -75,7 +74,6 @@ class LinesYardstick
characterIndex = nextCharIndex
break
characterIndex = textNode.textContent.length if characterIndex is -1
textNodeStartColumn = 0
textNodeStartColumn += textNodes[i].length for i in [0...textNodeIndex] by 1
Point(row, textNodeStartColumn + characterIndex)