mirror of
https://github.com/atom/atom.git
synced 2026-01-22 21:38:10 -05:00
presenter: use 'markers-updated' event for state updates
Signed-off-by: Nathan Sobo <nathan@github.com>
This commit is contained in:
committed by
Nathan Sobo
parent
76c696f1a2
commit
f5895d8b0b
@@ -1207,50 +1207,6 @@ describe "DisplayBuffer", ->
|
||||
expect(markerCreated1).toHaveBeenCalled()
|
||||
expect(markerCreated2).not.toHaveBeenCalled()
|
||||
|
||||
describe "::observeMarkers(callback)", ->
|
||||
[observationWindow, events] = []
|
||||
|
||||
beforeEach ->
|
||||
events = []
|
||||
observationWindow = displayBuffer.observeMarkers (event) -> events.push(event)
|
||||
displayBuffer.unfoldBufferRow(4, 7)
|
||||
|
||||
it "calls the callback when markers enter, leave, or move within the screen range", ->
|
||||
expect(events).toHaveLength 0
|
||||
|
||||
observationWindow.setScreenRange([[0, 0], [4, 0]])
|
||||
expect(events).toHaveLength 0
|
||||
|
||||
marker1 = displayBuffer.markScreenPosition([4, 2])
|
||||
expect(events).toHaveLength 0
|
||||
|
||||
observationWindow.setScreenRange([[0, 0], [5, 0]])
|
||||
expect(events).toHaveLength 1
|
||||
expect(events[0]).toEqual {
|
||||
insert: new Set([marker1.id])
|
||||
update: new Set
|
||||
remove: new Set
|
||||
}
|
||||
|
||||
marker2 = displayBuffer.markScreenPosition([5, 2])
|
||||
expect(events).toHaveLength 1
|
||||
|
||||
observationWindow.setBufferRange([[1, 0], [6, 0]])
|
||||
expect(events).toHaveLength 2
|
||||
expect(events[1]).toEqual {
|
||||
insert: new Set([marker2.id])
|
||||
update: new Set([marker1.id])
|
||||
remove: new Set
|
||||
}
|
||||
|
||||
marker1.destroy()
|
||||
expect(events).toHaveLength 3
|
||||
expect(events[2]).toEqual {
|
||||
insert: new Set
|
||||
update: new Set
|
||||
remove: new Set([marker1.id])
|
||||
}
|
||||
|
||||
describe "decorations", ->
|
||||
[marker, decoration, decorationProperties] = []
|
||||
beforeEach ->
|
||||
|
||||
@@ -1532,21 +1532,27 @@ describe "TextEditorPresenter", ->
|
||||
expect(stateForHighlight(presenter, destroyedSelection.decoration)).toBeUndefined()
|
||||
|
||||
it "updates when highlight decorations' properties are updated", ->
|
||||
marker = editor.markBufferRange([[2, 2], [2, 4]])
|
||||
marker = editor.markBufferPosition([2, 2])
|
||||
highlight = editor.decorateMarker(marker, type: 'highlight', class: 'a')
|
||||
|
||||
presenter = buildPresenter(explicitHeight: 30, scrollTop: 20)
|
||||
|
||||
expectValues stateForHighlight(presenter, highlight), {class: 'a'}
|
||||
expectStateUpdate presenter, -> highlight.setProperties(class: 'b', type: 'highlight')
|
||||
expect(stateForHighlight(presenter, highlight)).toBeUndefined()
|
||||
|
||||
expectStateUpdate presenter, ->
|
||||
marker.setBufferRange([[2, 2], [2, 4]])
|
||||
highlight.setProperties(class: 'b', type: 'highlight')
|
||||
|
||||
expectValues stateForHighlight(presenter, highlight), {class: 'b'}
|
||||
|
||||
it "increments the .flashCount and sets the .flashClass and .flashDuration when the highlight model flashes", ->
|
||||
presenter = buildPresenter(explicitHeight: 30, scrollTop: 20)
|
||||
|
||||
marker = editor.markBufferRange([[2, 2], [2, 4]])
|
||||
marker = editor.markBufferPosition([2, 2])
|
||||
highlight = editor.decorateMarker(marker, type: 'highlight', class: 'a')
|
||||
expectStateUpdate presenter, -> highlight.flash('b', 500)
|
||||
expectStateUpdate presenter, ->
|
||||
marker.setBufferRange([[2, 2], [2, 4]])
|
||||
highlight.flash('b', 500)
|
||||
|
||||
expectValues stateForHighlight(presenter, highlight), {
|
||||
flashClass: 'b'
|
||||
|
||||
@@ -10,7 +10,6 @@ Model = require './model'
|
||||
Token = require './token'
|
||||
Decoration = require './decoration'
|
||||
Marker = require './marker'
|
||||
MarkerObservationWindow = require './marker-observation-window'
|
||||
|
||||
class BufferToScreenConversionError extends Error
|
||||
constructor: (@message, @metadata) ->
|
||||
@@ -41,6 +40,7 @@ class DisplayBuffer extends Model
|
||||
@disposables.add @tokenizedBuffer.observeGrammar @subscribeToScopedConfigSettings
|
||||
@disposables.add @tokenizedBuffer.onDidChange @handleTokenizedBufferChange
|
||||
@disposables.add @buffer.onDidCreateMarker @handleBufferMarkerCreated
|
||||
@disposables.add @buffer.onDidUpdateMarkers => @emitter.emit 'did-update-markers'
|
||||
@foldMarkerAttributes = Object.freeze({class: 'fold', displayBufferId: @id})
|
||||
folds = (new Fold(this, marker) for marker in @buffer.findMarkers(@getFoldMarkerAttributes()))
|
||||
@updateAllScreenLines()
|
||||
@@ -1049,9 +1049,6 @@ class DisplayBuffer extends Model
|
||||
params = @translateToBufferMarkerParams(params)
|
||||
@buffer.findMarkers(params).map (stringMarker) => @getMarker(stringMarker.id)
|
||||
|
||||
observeMarkers: (callback) ->
|
||||
new MarkerObservationWindow(this, @buffer.observeMarkers(callback))
|
||||
|
||||
translateToBufferMarkerParams: (params) ->
|
||||
bufferMarkerParams = {}
|
||||
for key, value of params
|
||||
|
||||
@@ -29,7 +29,6 @@ class TextEditorPresenter
|
||||
@lineDecorationsByScreenRow = {}
|
||||
@lineNumberDecorationsByScreenRow = {}
|
||||
@customGutterDecorationsByGutterNameAndScreenRow = {}
|
||||
@highlightDecorationsById = {}
|
||||
@transferMeasurementsToModel()
|
||||
@observeModel()
|
||||
@observeConfig()
|
||||
@@ -126,17 +125,21 @@ class TextEditorPresenter
|
||||
@shouldUpdateLineNumbersState = true
|
||||
@shouldUpdateGutterOrderState = true
|
||||
@shouldUpdateCustomGutterDecorationState = true
|
||||
|
||||
@emitDidUpdateState()
|
||||
|
||||
@markerObservationWindow = @model.observeMarkers(@markersInRangeDidChange.bind(this))
|
||||
@disposables.add new Disposable => @markerObservationWindow.destroy()
|
||||
@model.onDidUpdateMarkers =>
|
||||
@shouldUpdateTilesState = true
|
||||
@shouldUpdateLineNumbersState = true
|
||||
@shouldUpdateDecorations = true
|
||||
@shouldUpdateOverlaysState = true
|
||||
@shouldUpdateCustomGutterDecorationState = true
|
||||
@emitDidUpdateState()
|
||||
|
||||
@disposables.add @model.onDidChangeGrammar(@didChangeGrammar.bind(this))
|
||||
@disposables.add @model.onDidChangePlaceholderText =>
|
||||
@shouldUpdateContentState = true
|
||||
|
||||
@emitDidUpdateState()
|
||||
|
||||
@disposables.add @model.onDidChangeMini =>
|
||||
@shouldUpdateScrollbarsState = true
|
||||
@shouldUpdateContentState = true
|
||||
@@ -148,14 +151,14 @@ class TextEditorPresenter
|
||||
@shouldUpdateCustomGutterDecorationState = true
|
||||
@updateScrollbarDimensions()
|
||||
@updateCommonGutterState()
|
||||
|
||||
@emitDidUpdateState()
|
||||
|
||||
@disposables.add @model.onDidChangeLineNumberGutterVisible =>
|
||||
@shouldUpdateLineNumberGutterState = true
|
||||
@shouldUpdateGutterOrderState = true
|
||||
@updateCommonGutterState()
|
||||
|
||||
@emitDidUpdateState()
|
||||
|
||||
@disposables.add @model.onDidAddDecoration(@didAddDecoration.bind(this))
|
||||
@disposables.add @model.onDidAddCursor(@didAddCursor.bind(this))
|
||||
@disposables.add @model.onDidChangeScrollTop(@setScrollTop.bind(this))
|
||||
@@ -614,7 +617,6 @@ class TextEditorPresenter
|
||||
visibleLinesCount = Math.ceil(@height / @lineHeight) + 1
|
||||
endRow = startRow + visibleLinesCount
|
||||
@endRow = Math.min(@model.getScreenLineCount(), endRow)
|
||||
@markerObservationWindow.setScreenRange(Range(Point(@startRow, 0), Point(@endRow, 0)))
|
||||
|
||||
updateScrollWidth: ->
|
||||
return unless @contentWidth? and @clientWidth?
|
||||
@@ -1098,58 +1100,21 @@ class TextEditorPresenter
|
||||
observeDecoration: (decoration) ->
|
||||
decorationDisposables = new CompositeDisposable
|
||||
if decoration.isType('highlight')
|
||||
decorationDisposables.add decoration.onDidFlash(@highlightDidFlash.bind(this, decoration))
|
||||
decorationDisposables.add decoration.onDidChangeProperties(@decorationPropertiesDidChange.bind(this, decoration))
|
||||
decorationDisposables.add decoration.onDidFlash =>
|
||||
@shouldUpdateDecorations = true
|
||||
@emitDidUpdateState()
|
||||
|
||||
decorationDisposables.add decoration.onDidChangeProperties (event) =>
|
||||
@decorationPropertiesDidChange(decoration, event)
|
||||
decorationDisposables.add decoration.onDidDestroy =>
|
||||
@disposables.remove(decorationDisposables)
|
||||
decorationDisposables.dispose()
|
||||
@didDestroyDecoration(decoration)
|
||||
@disposables.add(decorationDisposables)
|
||||
|
||||
markersInRangeDidChange: (event) ->
|
||||
event.insert.forEach (markerId) =>
|
||||
range = @model.getMarker(markerId).getScreenRange()
|
||||
if decorations = @model.decorationsForMarkerId(markerId)
|
||||
for decoration in decorations
|
||||
@decorationMarkerDidChange(decoration)
|
||||
if decoration.isType('line') or decoration.isType('gutter')
|
||||
@addToLineDecorationCaches(decoration, range)
|
||||
event.update.forEach (markerId) =>
|
||||
range = @model.getMarker(markerId).getScreenRange()
|
||||
if decorations = @model.decorationsForMarkerId(markerId)
|
||||
for decoration in decorations
|
||||
@decorationMarkerDidChange(decoration)
|
||||
if decoration.isType('line') or decoration.isType('gutter')
|
||||
@removeFromLineDecorationCaches(decoration)
|
||||
@addToLineDecorationCaches(decoration, range)
|
||||
event.remove.forEach (markerId) =>
|
||||
if decorations = @model.decorationsForMarkerId(markerId)
|
||||
for decoration in decorations
|
||||
@decorationMarkerDidChange(decoration)
|
||||
if decoration.isType('line') or decoration.isType('gutter')
|
||||
@removeFromLineDecorationCaches(decoration)
|
||||
@emitDidUpdateState()
|
||||
|
||||
decorationMarkerDidChange: (decoration) ->
|
||||
if decoration.isType('highlight')
|
||||
@updateHighlightState(decoration)
|
||||
if decoration.isType('overlay')
|
||||
@shouldUpdateOverlaysState = true
|
||||
if decoration.isType('line')
|
||||
@shouldUpdateTilesState = true
|
||||
if decoration.isType('line-number')
|
||||
@shouldUpdateLineNumbersState = true
|
||||
else if decoration.isType('gutter')
|
||||
@shouldUpdateCustomGutterDecorationState = true
|
||||
|
||||
decorationPropertiesDidChange: (decoration, event) ->
|
||||
{oldProperties} = event
|
||||
decorationPropertiesDidChange: (decoration, {oldProperties}) ->
|
||||
@shouldUpdateDecorations = true
|
||||
if decoration.isType('line') or decoration.isType('gutter')
|
||||
@removePropertiesFromLineDecorationCaches(
|
||||
decoration.id,
|
||||
oldProperties,
|
||||
decoration.getMarker().getScreenRange())
|
||||
@addToLineDecorationCaches(decoration, decoration.getMarker().getScreenRange())
|
||||
if decoration.isType('line') or Decoration.isType(oldProperties, 'line')
|
||||
@shouldUpdateTilesState = true
|
||||
if decoration.isType('line-number') or Decoration.isType(oldProperties, 'line-number')
|
||||
@@ -1159,14 +1124,11 @@ class TextEditorPresenter
|
||||
@shouldUpdateCustomGutterDecorationState = true
|
||||
else if decoration.isType('overlay')
|
||||
@shouldUpdateOverlaysState = true
|
||||
else if decoration.isType('highlight')
|
||||
@updateHighlightState(decoration, event)
|
||||
|
||||
@emitDidUpdateState()
|
||||
|
||||
didDestroyDecoration: (decoration) ->
|
||||
@shouldUpdateDecorations = true
|
||||
if decoration.isType('line') or decoration.isType('gutter')
|
||||
@removeFromLineDecorationCaches(decoration, decoration.getMarker().getScreenRange())
|
||||
@shouldUpdateTilesState = true if decoration.isType('line')
|
||||
if decoration.isType('line-number')
|
||||
@shouldUpdateLineNumbersState = true
|
||||
@@ -1179,14 +1141,6 @@ class TextEditorPresenter
|
||||
|
||||
@emitDidUpdateState()
|
||||
|
||||
highlightDidFlash: (decoration) ->
|
||||
flash = decoration.consumeNextFlash()
|
||||
if decorationState = @state.content.highlights[decoration.id]
|
||||
decorationState.flashCount++
|
||||
decorationState.flashClass = flash.class
|
||||
decorationState.flashDuration = flash.duration
|
||||
@emitDidUpdateState()
|
||||
|
||||
didAddDecoration: (decoration) ->
|
||||
@observeDecoration(decoration)
|
||||
|
||||
@@ -1209,7 +1163,6 @@ class TextEditorPresenter
|
||||
@lineDecorationsByScreenRow = {}
|
||||
@lineNumberDecorationsByScreenRow = {}
|
||||
@customGutterDecorationsByGutterNameAndScreenRow = {}
|
||||
@highlightDecorationsById = {}
|
||||
|
||||
visibleHighlights = {}
|
||||
return unless 0 <= @startRow <= @endRow <= Infinity
|
||||
@@ -1304,6 +1257,12 @@ class TextEditorPresenter
|
||||
flashDuration: null
|
||||
flashClass: null
|
||||
}
|
||||
|
||||
if flash = decoration.consumeNextFlash()
|
||||
highlightState.flashCount++
|
||||
highlightState.flashClass = flash.class
|
||||
highlightState.flashDuration = flash.duration
|
||||
|
||||
highlightState.class = properties.class
|
||||
highlightState.deprecatedRegionClass = properties.deprecatedRegionClass
|
||||
highlightState.regions = @buildHighlightRegions(range)
|
||||
|
||||
@@ -163,10 +163,10 @@ class TextEditor extends Model
|
||||
|
||||
subscribeToDisplayBuffer: ->
|
||||
@disposables.add @displayBuffer.onDidCreateMarker @handleMarkerCreated
|
||||
@disposables.add @displayBuffer.onDidUpdateMarkers => @mergeIntersectingSelections()
|
||||
@disposables.add @displayBuffer.onDidChangeGrammar => @handleGrammarChange()
|
||||
@disposables.add @displayBuffer.onDidTokenize => @handleTokenization()
|
||||
@disposables.add @displayBuffer.onDidChange (e) =>
|
||||
@mergeIntersectingSelections()
|
||||
@emit 'screen-lines-changed', e if includeDeprecatedAPIs
|
||||
@emitter.emit 'did-change', e
|
||||
|
||||
@@ -461,6 +461,9 @@ class TextEditor extends Model
|
||||
onDidChangeIcon: (callback) ->
|
||||
@emitter.on 'did-change-icon', callback
|
||||
|
||||
onDidUpdateMarkers: (callback) ->
|
||||
@displayBuffer.onDidUpdateMarkers(callback)
|
||||
|
||||
# Public: Retrieves the current {TextBuffer}.
|
||||
getBuffer: -> @buffer
|
||||
|
||||
|
||||
Reference in New Issue
Block a user