Trigger ::onWillMeasure before measuring anything

This commit is contained in:
Antonio Scandurra
2015-09-16 12:07:57 +02:00
parent 2750a384ac
commit 2dd944f3ee
2 changed files with 51 additions and 10 deletions

View File

@@ -220,10 +220,36 @@ describe "TextEditorPresenter", ->
expect(stateFn(presenter).tiles[0]).toBeDefined()
describe "during state retrieval", ->
it "does not trigger onDidUpdateState events", ->
it "does not trigger ::onDidUpdateState events", ->
presenter = buildPresenter()
expectNoStateUpdate presenter, -> presenter.getState()
it "triggers ::onWillMeasure events before computing any state that needs measurement", ->
editor.setCursorBufferPosition([0, 0])
cursorLine = editor.tokenizedLineForScreenRow(0)
called = false
onWillMeasureSpy = (state) ->
called = true
expect(Object.keys(state.content.tiles).length).toBeGreaterThan(0)
for tile, tileState of state.content.tiles
expect(tileState.highlights).toEqual({})
expect(state.content.tiles[0].lines[cursorLine.id].decorationClasses).not.toBeNull()
expect(state.gutters).toEqual([])
expect(state.hiddenInput).toEqual({})
expect(state.content.overlays).toEqual({})
expect(state.content.cursors).toEqual({})
expect(state.content.width).toBeUndefined()
expect(state.content.scrollWidth).toBeUndefined()
presenter = buildPresenter(explicitHeight: 6, scrollTop: 0, lineHeight: 1, tileSize: 2)
presenter.onWillMeasure(onWillMeasureSpy)
presenter.getState()
expect(called).toBe(true)
describe ".horizontalScrollbar", ->
describe ".visible", ->
it "is true if the scrollWidth exceeds the computed client width", ->

View File

@@ -43,6 +43,10 @@ class TextEditorPresenter
destroy: ->
@disposables.dispose()
# Calls your `callback` while performing ::getState(), before computing any state that needs measurements.
onWillMeasure: (callback) ->
@emitter.on "will-measure", callback
# Calls your `callback` when some changes in the model occurred and the current state has been updated.
onDidUpdateState: (callback) ->
@emitter.on 'did-update-state', callback
@@ -74,8 +78,13 @@ class TextEditorPresenter
@updateScrollbarDimensions()
@updateStartRow()
@updateEndRow()
@updateCommonGutterState()
@updateLinesDecorations() if @shouldUpdateDecorations
@updateTilesState() if @shouldUpdateLinesState or @shouldUpdateLineNumbersState
@emitter.emit "will-measure", @state
@updateCommonGutterState()
@updateHorizontalDimensions()
@updateFocusedState() if @shouldUpdateFocusedState
@@ -85,8 +94,7 @@ class TextEditorPresenter
@updateScrollbarsState() if @shouldUpdateScrollbarsState
@updateHiddenInputState() if @shouldUpdateHiddenInputState
@updateContentState() if @shouldUpdateContentState
@updateDecorations() if @shouldUpdateDecorations
@updateTilesState() if @shouldUpdateLinesState or @shouldUpdateLineNumbersState
@updateHighlightDecorations() if @shouldUpdateDecorations
@updateCursorsState() if @shouldUpdateCursorsState
@updateOverlaysState() if @shouldUpdateOverlaysState
@updateLineNumberGutterState() if @shouldUpdateLineNumberGutterState
@@ -240,6 +248,7 @@ class TextEditorPresenter
tiles: {}
highlights: {}
overlays: {}
cursors: {}
gutters: []
# Shared state that is copied into ``@state.gutters`.
@sharedGutterStyles = {}
@@ -1144,22 +1153,28 @@ class TextEditorPresenter
@emitDidUpdateState()
updateDecorations: ->
updateLinesDecorations: ->
@rangesByDecorationId = {}
@lineDecorationsByScreenRow = {}
@lineNumberDecorationsByScreenRow = {}
@customGutterDecorationsByGutterNameAndScreenRow = {}
return unless 0 <= @startRow <= @endRow <= Infinity
for markerId, decorations of @model.decorationsForScreenRowRange(@startRow, @endRow - 1)
range = @model.getMarker(markerId).getScreenRange()
for decoration in decorations when decoration.isType('line') or decoration.isType('gutter')
@addToLineDecorationCaches(decoration, range)
updateHighlightDecorations: ->
@visibleHighlights = {}
return unless 0 <= @startRow <= @endRow <= Infinity
for markerId, decorations of @model.decorationsForScreenRowRange(@startRow, @endRow - 1)
range = @model.getMarker(markerId).getScreenRange()
for decoration in decorations
if decoration.isType('line') or decoration.isType('gutter')
@addToLineDecorationCaches(decoration, range)
else if decoration.isType('highlight')
@updateHighlightState(decoration, range)
for decoration in decorations when decoration.isType('highlight')
@updateHighlightState(decoration, range)
for tileId, tileState of @state.content.tiles
for id, highlight of tileState.highlights