mirror of
https://github.com/atom/atom.git
synced 2026-01-23 05:48:10 -05:00
Use presenter to render flashes
Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
@@ -923,7 +923,6 @@ describe "TextEditorComponent", ->
|
||||
it "will flash the selection when flash:true is passed to editor::setSelectedBufferRange", ->
|
||||
editor.setSelectedBufferRange([[1, 6], [1, 10]], flash: true)
|
||||
nextAnimationFrame()
|
||||
nextAnimationFrame() # flash starts on its own frame
|
||||
selectionNode = componentNode.querySelector('.selection')
|
||||
expect(selectionNode.classList.contains('flash')).toBe true
|
||||
|
||||
@@ -1183,6 +1182,8 @@ describe "TextEditorComponent", ->
|
||||
advanceClock(2)
|
||||
|
||||
decoration.flash('flash-class', 10)
|
||||
nextAnimationFrame()
|
||||
|
||||
# Removed for 1 frame to force CSS transition to restart
|
||||
expect(highlightNode.classList.contains('flash-class')).toBe false
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ React = require 'react-atom-fork'
|
||||
module.exports =
|
||||
HighlightComponent = React.createClass
|
||||
displayName: 'HighlightComponent'
|
||||
lastFlashCount: 0
|
||||
lastFlashClass: null
|
||||
currentFlashCount: 0
|
||||
currentFlashClass: null
|
||||
|
||||
render: ->
|
||||
{editor, state} = @props
|
||||
{state} = @props
|
||||
|
||||
className = 'highlight'
|
||||
className += " #{state.class}" if state.class?
|
||||
@@ -20,30 +20,31 @@ HighlightComponent = React.createClass
|
||||
regionClassName += " #{state.deprecatedRegionClass}" if state.deprecatedRegionClass?
|
||||
div className: regionClassName, key: i, style: region
|
||||
|
||||
componentDidUpdate: ->
|
||||
if @props.state.flashCount > @lastFlashCount
|
||||
@startFlashAnimation()
|
||||
@lastFlashCount = @props.state.flashCount
|
||||
@lastFlashClass = @props.state.flashClass
|
||||
|
||||
componentDidMount: ->
|
||||
{key} = @props
|
||||
presenter.onDidFlashHighlight @startFlashAnimation.bind(this)
|
||||
@flashIfRequested()
|
||||
|
||||
componentWillUnmount: ->
|
||||
@decorationDisposable?.dispose()
|
||||
@decorationDisposable = null
|
||||
componentDidUpdate: ->
|
||||
@flashIfRequested()
|
||||
|
||||
startFlashAnimation: ->
|
||||
node = @getDOMNode()
|
||||
flashIfRequested: ->
|
||||
if @props.state.flashCount > @currentFlashCount
|
||||
@currentFlashCount = @props.state.flashCount
|
||||
|
||||
if @lastFlashClass?
|
||||
clearTimeout(@flashTimeoutId)
|
||||
node.classList.remove(@lastFlashClass)
|
||||
@lastFlashClass = null
|
||||
node = @getDOMNode()
|
||||
{flashClass, flashDuration} = @props.state
|
||||
|
||||
requestAnimationFrame =>
|
||||
flashClass = @props.state.flashClass
|
||||
node.classList.add(flashClass)
|
||||
removeFlashClass = -> node.classList.remove(flashClass)
|
||||
@flashTimeoutId = setTimeout(removeFlashClass, flash.duration)
|
||||
addFlashClass = =>
|
||||
node.classList.add(flashClass)
|
||||
@currentFlashClass = flashClass
|
||||
@flashTimeoutId = setTimeout(removeFlashClass, flashDuration)
|
||||
|
||||
removeFlashClass = =>
|
||||
node.classList.remove(@currentFlashClass)
|
||||
@currentFlashClass = null
|
||||
clearTimeout(@flashTimeoutId)
|
||||
|
||||
if @currentFlashClass?
|
||||
removeFlashClass()
|
||||
requestAnimationFrame(addFlashClass)
|
||||
else
|
||||
addFlashClass()
|
||||
|
||||
@@ -15,7 +15,7 @@ HighlightsComponent = React.createClass
|
||||
{editor, presenter} = @props
|
||||
highlightComponents = []
|
||||
for key, state of presenter.state.content.highlights
|
||||
highlightComponents.push(HighlightComponent({editor, key, state}))
|
||||
highlightComponents.push(HighlightComponent({key, state}))
|
||||
highlightComponents
|
||||
|
||||
componentDidMount: ->
|
||||
@@ -23,6 +23,3 @@ HighlightsComponent = React.createClass
|
||||
insertionPoint = document.createElement('content')
|
||||
insertionPoint.setAttribute('select', '.underlayer')
|
||||
@getDOMNode().appendChild(insertionPoint)
|
||||
|
||||
shouldComponentUpdate: (newProps) ->
|
||||
not isEqualForProperties(newProps, @props, 'highlightDecorations', 'lineHeightInPixels', 'defaultCharWidth', 'scopedCharacterWidthsChangeCount')
|
||||
|
||||
@@ -37,11 +37,7 @@ LinesComponent = React.createClass
|
||||
div className: 'placeholder-text', placeholderText if placeholderText?
|
||||
|
||||
CursorsComponent {presenter}
|
||||
|
||||
HighlightsComponent {
|
||||
editor, highlightDecorations, lineHeightInPixels, defaultCharWidth,
|
||||
scopedCharacterWidthsChangeCount, performedInitialMeasurement, presenter
|
||||
}
|
||||
HighlightsComponent {presenter, performedInitialMeasurement}
|
||||
|
||||
getTransform: ->
|
||||
{scrollTop, scrollLeft} = @newState
|
||||
|
||||
@@ -110,9 +110,11 @@ class TextEditorPresenter
|
||||
@emitter.emit 'did-update-state'
|
||||
|
||||
updateHighlightsState: ->
|
||||
@state.content.highlights ?= {}
|
||||
|
||||
startRow = @getStartRow()
|
||||
endRow = @getEndRow()
|
||||
@state.content.highlights = {}
|
||||
visibleHighlights = {}
|
||||
|
||||
for decoration in @model.getHighlightDecorations()
|
||||
continue unless decoration.getMarker().isValid()
|
||||
@@ -125,13 +127,23 @@ class TextEditorPresenter
|
||||
screenRange.end.row = endRow
|
||||
screenRange.end.column = 0
|
||||
continue if screenRange.isEmpty()
|
||||
@state.content.highlights[decoration.id] =
|
||||
class: decoration.getProperties().class
|
||||
deprecatedRegionClass: decoration.getProperties().deprecatedRegionClass
|
||||
regions: @buildHighlightRegions(screenRange)
|
||||
|
||||
visibleHighlights[decoration.id] = true
|
||||
|
||||
@state.content.highlights[decoration.id] ?= {
|
||||
flashCount: 0
|
||||
flashDuration: null
|
||||
flashClass: null
|
||||
}
|
||||
highlightState = @state.content.highlights[decoration.id]
|
||||
highlightState.class = decoration.getProperties().class
|
||||
highlightState.deprecatedRegionClass = decoration.getProperties().deprecatedRegionClass
|
||||
highlightState.regions = @buildHighlightRegions(screenRange)
|
||||
|
||||
for id of @state.content.highlights
|
||||
unless visibleHighlights.hasOwnProperty(id)
|
||||
delete @state.content.highlights[id]
|
||||
|
||||
@emitter.emit 'did-update-state'
|
||||
|
||||
buildHighlightRegions: (screenRange) ->
|
||||
@@ -356,11 +368,11 @@ class TextEditorPresenter
|
||||
|
||||
highlightDidFlash: (decoration) ->
|
||||
flash = decoration.consumeNextFlash()
|
||||
decorationState = @state.content.highlights[decoration.id]
|
||||
decorationState.flashCount++
|
||||
decorationState.flashClass = flash.class
|
||||
decorationState.flashDuration = flash.duration
|
||||
@emitter.emit "did-update-state"
|
||||
if decorationState = @state.content.highlights[decoration.id]
|
||||
decorationState.flashCount++
|
||||
decorationState.flashClass = flash.class
|
||||
decorationState.flashDuration = flash.duration
|
||||
@emitter.emit "did-update-state"
|
||||
|
||||
didAddDecoration: (decoration) ->
|
||||
if decoration.isType('line')
|
||||
|
||||
Reference in New Issue
Block a user