diff --git a/spec/fixtures/sample-bidirectional.txt b/spec/fixtures/sample-bidirectional.txt new file mode 100644 index 000000000..d74de4f6c --- /dev/null +++ b/spec/fixtures/sample-bidirectional.txt @@ -0,0 +1 @@ +Persian, locally known as Parsi or Farsi (زبان فارسی), the predominant modern descendant of Old Persian. diff --git a/spec/lines-yardstick-spec.coffee b/spec/lines-yardstick-spec.coffee index 2172267db..d718f3aae 100644 --- a/spec/lines-yardstick-spec.coffee +++ b/spec/lines-yardstick-spec.coffee @@ -202,3 +202,73 @@ describe "LinesYardstick", -> it "clips negative horizontal pixel positions", -> expect(linesYardstick.screenPositionForPixelPosition(top: 0, left: -10)).toEqual [0, 0] expect(linesYardstick.screenPositionForPixelPosition(top: 1 * 14, left: -10)).toEqual [1, 0] + +describe "In bidirectional lines", -> + [editor, linesYardstick, createdLineNodes, mockLineNodesProvider] = [] + beforeEach -> + waitsForPromise -> + atom.workspace.open('sample-bidirectional.txt').then (o) -> editor = o + + runs -> + createdLineNodes = [] + + buildLineNode = (screenRow) -> + startIndex = 0 + scopes = [] + screenLine = editor.screenLineForScreenRow(screenRow) + lineNode = document.createElement("div") + lineNode.style.whiteSpace = "pre" + for tagCode in screenLine.tagCodes when tagCode isnt 0 + if editor.displayLayer.isCloseTagCode(tagCode) + scopes.pop() + else if editor.displayLayer.isOpenTagCode(tagCode) + scopes.push(editor.displayLayer.tagForCode(tagCode)) + else + text = screenLine.lineText.substr(startIndex, tagCode) + startIndex += tagCode + + span = document.createElement("span") + span.className = scopes.join(' ').replace(/\.+/g, ' ') + span.textContent = text + lineNode.appendChild(span) + jasmine.attachToDOM(lineNode) + createdLineNodes.push(lineNode) + lineNode + + mockLineNodesProvider = + lineNodesById: {} + + lineIdForScreenRow: (screenRow) -> + editor.screenLineForScreenRow(screenRow)?.id + + lineNodeForScreenRow: (screenRow) -> + if id = @lineIdForScreenRow(screenRow) + @lineNodesById[id] ?= buildLineNode(screenRow) + + textNodesForScreenRow: (screenRow) -> + lineNode = @lineNodeForScreenRow(screenRow) + iterator = document.createNodeIterator(lineNode, NodeFilter.SHOW_TEXT) + textNodes = [] + textNodes.push(textNode) while textNode = iterator.nextNode() + textNodes + + editor.setLineHeightInPixels(14) + lineTopIndex = new LineTopIndex({defaultLineHeight: editor.getLineHeightInPixels()}) + linesYardstick = new LinesYardstick(editor, mockLineNodesProvider, lineTopIndex, atom.grammars) + + afterEach -> + lineNode.remove() for lineNode in createdLineNodes + atom.themes.removeStylesheet('test') + + describe "LinesYardstick::pixelPositionForScreenPosition(screenPosition)", -> + it "should converts screen positions to correct pixel positions", -> + atom.styles.addStyleSheet """ + * { + font-size: 14px; + font-family: monospace; + } + """ + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 15))).toEqual({left: 126, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 62))).toEqual({left: 521, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 58))).toEqual({left: 487, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, Infinity))).toEqual({left: 873.703125, top: 0})