Improve LinesYardstick design

We have shifted the responsibility of orchestrating state updates and
measurements to the yardstick. The presenter still needs to be updated to make
use of these new capabilities.
This commit is contained in:
Antonio Scandurra
2015-09-18 10:17:53 +02:00
parent 5a2e4ba2aa
commit bf7d7e0d2a
4 changed files with 31 additions and 32 deletions

View File

@@ -1,8 +1,8 @@
LinesYardstick = require '../src/lines-yardstick'
MockLineNodesProvider = require './mock-line-nodes-provider'
MockLinesComponent = require './mock-lines-component'
describe "LinesYardstick", ->
[editor, mockLineNodesProvider, builtLineNodes, linesYardstick] = []
[editor, mockPresenter, mockLinesComponent, linesYardstick] = []
beforeEach ->
waitsForPromise ->
@@ -12,14 +12,23 @@ describe "LinesYardstick", ->
atom.project.open('sample.js').then (o) -> editor = o
runs ->
mockLineNodesProvider = new MockLineNodesProvider(editor)
linesYardstick = new LinesYardstick(editor, mockLineNodesProvider)
mockPresenter = {getStateForMeasurements: jasmine.createSpy()}
mockLinesComponent = new MockLinesComponent(editor)
linesYardstick = new LinesYardstick(editor, mockPresenter, mockLinesComponent)
mockLinesComponent.setDefaultFont("14px monospace")
afterEach ->
mockLineNodesProvider.dispose()
doSomething = true
it "converts screen positions to pixel positions", ->
mockLineNodesProvider.setDefaultFont("14px monospace")
stubState = {anything: {}}
mockPresenter.getStateForMeasurements.andReturn(stubState)
linesYardstick.prepareScreenRowsForMeasurement([0, 1, 2])
expect(mockPresenter.getStateForMeasurements).toHaveBeenCalledWith([0, 1, 2])
expect(mockLinesComponent.updateSync).toHaveBeenCalledWith(stubState)
conversionTable = [
[[0, 0], {left: 0, top: editor.getLineHeightInPixels() * 0}]
@@ -37,7 +46,7 @@ describe "LinesYardstick", ->
linesYardstick.pixelPositionForScreenPosition(point)
).toEqual(position)
mockLineNodesProvider.setFontForScopes(
mockLinesComponent.setFontForScopes(
["source.js", "storage.modifier.js"], "16px monospace"
)
linesYardstick.clearCache()
@@ -57,19 +66,3 @@ describe "LinesYardstick", ->
expect(
linesYardstick.pixelPositionForScreenPosition(point)
).toEqual(position)
it "does not compute the same position twice unless the cache gets cleared", ->
mockLineNodesProvider.setDefaultFont("14px monospace")
oldPosition1 = linesYardstick.pixelPositionForScreenPosition([0, 5])
oldPosition2 = linesYardstick.pixelPositionForScreenPosition([1, 4])
mockLineNodesProvider.setDefaultFont("16px monospace")
expect(linesYardstick.pixelPositionForScreenPosition([0, 5])).toEqual(oldPosition1)
expect(linesYardstick.pixelPositionForScreenPosition([1, 4])).toEqual(oldPosition2)
linesYardstick.clearCache()
expect(linesYardstick.pixelPositionForScreenPosition([0, 5])).not.toEqual(oldPosition1)
expect(linesYardstick.pixelPositionForScreenPosition([1, 4])).not.toEqual(oldPosition2)

View File

@@ -1,8 +1,8 @@
TokenIterator = require '../src/token-iterator'
module.exports =
class MockLineNodesProvider
constructor: (@editor) ->
class MockLinesComponent
constructor: (@model) ->
@defaultFont = ""
@fontsByScopes = {}
@tokenIterator = new TokenIterator
@@ -11,14 +11,12 @@ class MockLineNodesProvider
dispose: ->
node.remove() for node in @builtLineNodes
setFontForScopes: (scopes, font) -> @fontsByScopes[scopes] = font
setDefaultFont: (font) -> @defaultFont = font
updateSync: jasmine.createSpy()
lineNodeForLineIdAndScreenRow: (id, screenRow) ->
lineNode = document.createElement("div")
lineNode.style.whiteSpace = "pre"
lineState = @editor.tokenizedLineForScreenRow(screenRow)
lineState = @model.tokenizedLineForScreenRow(screenRow)
@tokenIterator.reset(lineState)
while @tokenIterator.next()
@@ -32,3 +30,7 @@ class MockLineNodesProvider
document.body.appendChild(lineNode)
lineNode
setFontForScopes: (scopes, font) -> @fontsByScopes[scopes] = font
setDefaultFont: (font) -> @defaultFont = font

View File

@@ -5,7 +5,7 @@ TextBuffer = require 'text-buffer'
TextEditor = require '../src/text-editor'
TextEditorPresenter = require '../src/text-editor-presenter'
LinesYardstick = require '../src/lines-yardstick'
MockLineNodesProvider = require './mock-line-nodes-provider'
MockLineNodesProvider = require './mock-lines-component'
describe "TextEditorPresenter", ->
# These `describe` and `it` blocks mirror the structure of the ::state object.

View File

@@ -4,14 +4,18 @@ AcceptFilter = {acceptNode: -> NodeFilter.FILTER_ACCEPT}
module.exports =
class LinesYardstick
constructor: (@model, @lineNodesProvider) ->
constructor: (@model, @presenter, @lineNodesProvider) ->
@cachedPositionsByLineId = {}
@tokenIterator = new TokenIterator
@rangeForMeasurement = document.createRange()
@cachedPositionsByLineId = {}
clearCache: ->
@cachedPositionsByLineId = {}
prepareScreenRowsForMeasurement: (screenRows) ->
state = @presenter.getStateForMeasurements(screenRows)
@lineNodesProvider.updateSync(state)
pixelPositionForScreenPosition: (screenPosition, clip=true) ->
screenPosition = Point.fromObject(screenPosition)
screenPosition = @model.clipScreenPosition(screenPosition) if clip