Encapsulate state update inside TextEditorPresenter#getState

This commit is contained in:
Antonio Scandurra
2015-02-28 09:25:53 +01:00
parent 290acb356c
commit 0dca5a5fcd
11 changed files with 288 additions and 303 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -2,14 +2,13 @@ module.exports =
class CursorsComponent
oldState: null
constructor: (@presenter) ->
constructor: ->
@cursorNodesById = {}
@domNode = document.createElement('div')
@domNode.classList.add('cursors')
@updateSync()
updateSync: ->
newState = @presenter.state.content
updateSync: (state) ->
newState = state.content
@oldState ?= {cursors: {}}
# update blink class

View File

@@ -18,10 +18,8 @@ class GutterComponent
@domNode.addEventListener 'click', @onClick
@domNode.addEventListener 'mousedown', @onMouseDown
@updateSync()
updateSync: ->
@newState = @presenter.state.gutter
updateSync: (state) ->
@newState = state.gutter
@oldState ?= {lineNumbers: {}}
@appendDummyLineNumber() unless @dummyLineNumberNode?

View File

@@ -5,7 +5,7 @@ module.exports =
class HighlightsComponent
oldState: null
constructor: (@presenter) ->
constructor: ->
@highlightNodesById = {}
@regionNodesByHighlightId = {}
@@ -17,8 +17,8 @@ class HighlightsComponent
insertionPoint.setAttribute('select', '.underlayer')
@domNode.appendChild(insertionPoint)
updateSync: ->
newState = @presenter.state.content.highlights
updateSync: (state) ->
newState = state.content.highlights
@oldState ?= {}
# remove highlights

View File

@@ -1,16 +1,15 @@
module.exports =
class InputComponent
constructor: (@presenter) ->
constructor: ->
@domNode = document.createElement('input')
@domNode.classList.add('hidden-input')
@domNode.setAttribute('data-react-skip-selection-restoration', true)
@domNode.style['-webkit-transform'] = 'translateZ(0)'
@domNode.addEventListener 'paste', (event) -> event.preventDefault()
@updateSync()
updateSync: ->
updateSync: (state) ->
@oldState ?= {}
newState = @presenter.state.hiddenInput
newState = state.hiddenInput
if newState.top isnt @oldState.top
@domNode.style.top = newState.top + 'px'

View File

@@ -42,15 +42,13 @@ class LinesComponent
insertionPoint = document.createElement('content')
insertionPoint.setAttribute('select', 'atom-overlay')
@overlayManager = new OverlayManager(@hostElement)
@overlayManager = new OverlayManager(@presenter, @hostElement)
@domNode.appendChild(insertionPoint)
else
@overlayManager = new OverlayManager(@domNode)
@overlayManager = new OverlayManager(@presenter, @domNode)
@updateSync(visible)
updateSync: ->
@newState = @presenter.state.content
updateSync: (state) ->
@newState = state.content
@oldState ?= {lines: {}}
if @newState.scrollHeight isnt @oldState.scrollHeight
@@ -81,10 +79,10 @@ class LinesComponent
@domNode.style.width = @newState.scrollWidth + 'px'
@oldState.scrollWidth = @newState.scrollWidth
@cursorsComponent.updateSync()
@highlightsComponent.updateSync()
@cursorsComponent.updateSync(state)
@highlightsComponent.updateSync(state)
@overlayManager?.render(@presenter)
@overlayManager?.render(state)
@oldState.indentGuidesVisible = @newState.indentGuidesVisible
@oldState.scrollWidth = @newState.scrollWidth

View File

@@ -1,20 +1,20 @@
module.exports =
class OverlayManager
constructor: (@container) ->
constructor: (@presenter, @container) ->
@overlayNodesById = {}
render: (presenter) ->
for decorationId, {pixelPosition, item} of presenter.state.content.overlays
@renderOverlay(presenter, decorationId, item, pixelPosition)
render: (state) ->
for decorationId, {pixelPosition, item} of state.content.overlays
@renderOverlay(state, decorationId, item, pixelPosition)
for id, overlayNode of @overlayNodesById
unless presenter.state.content.overlays.hasOwnProperty(id)
unless state.content.overlays.hasOwnProperty(id)
delete @overlayNodesById[id]
overlayNode.remove()
return
renderOverlay: (presenter, decorationId, item, pixelPosition) ->
renderOverlay: (state, decorationId, item, pixelPosition) ->
item = atom.views.getView(item)
unless overlayNode = @overlayNodesById[decorationId]
overlayNode = @overlayNodesById[decorationId] = document.createElement('atom-overlay')
@@ -25,15 +25,15 @@ class OverlayManager
itemHeight = item.offsetHeight
{scrollTop, scrollLeft} = presenter.state.content
{scrollTop, scrollLeft} = state.content
left = pixelPosition.left
if left + itemWidth - scrollLeft > presenter.contentFrameWidth and left - itemWidth >= scrollLeft
if left + itemWidth - scrollLeft > @presenter.contentFrameWidth and left - itemWidth >= scrollLeft
left -= itemWidth
top = pixelPosition.top + presenter.lineHeight
if top + itemHeight - scrollTop > presenter.height and top - itemHeight - presenter.lineHeight >= scrollTop
top -= itemHeight + presenter.lineHeight
top = pixelPosition.top + @presenter.lineHeight
if top + itemHeight - scrollTop > @presenter.height and top - itemHeight - @presenter.lineHeight >= scrollTop
top -= itemHeight + @presenter.lineHeight
overlayNode.style.top = top + 'px'
overlayNode.style.left = left + 'px'

View File

@@ -1,6 +1,6 @@
module.exports =
class ScrollbarComponent
constructor: ({@presenter, @orientation, @onScroll}) ->
constructor: ({@orientation, @onScroll}) ->
@domNode = document.createElement('div')
@domNode.classList.add "#{@orientation}-scrollbar"
@domNode.style['-webkit-transform'] = 'translateZ(0)' # See atom/atom#3559
@@ -12,16 +12,14 @@ class ScrollbarComponent
@domNode.addEventListener 'scroll', @onScrollCallback
@updateSync()
updateSync: ->
updateSync: (state) ->
@oldState ?= {}
switch @orientation
when 'vertical'
@newState = @presenter.state.verticalScrollbar
@newState = state.verticalScrollbar
@updateVertical()
when 'horizontal'
@newState = @presenter.state.horizontalScrollbar
@newState = state.horizontalScrollbar
@updateHorizontal()
if @newState.visible isnt @oldState.visible

View File

@@ -1,20 +1,18 @@
module.exports =
class ScrollbarCornerComponent
constructor: (@presenter) ->
constructor: () ->
@domNode = document.createElement('div')
@domNode.classList.add('scrollbar-corner')
@contentNode = document.createElement('div')
@domNode.appendChild(@contentNode)
@updateSync()
updateSync: ->
updateSync: (state) ->
@oldState ?= {}
@newState ?= {}
newHorizontalState = @presenter.state.horizontalScrollbar
newVerticalState = @presenter.state.verticalScrollbar
newHorizontalState = state.horizontalScrollbar
newVerticalState = state.verticalScrollbar
@newState.visible = newHorizontalState.visible and newVerticalState.visible
@newState.height = newHorizontalState.height
@newState.width = newVerticalState.width

View File

@@ -64,21 +64,21 @@ class TextEditorComponent
@scrollViewNode.classList.add('scroll-view')
@domNode.appendChild(@scrollViewNode)
@mountGutterComponent() if @presenter.state.gutter.visible
@mountGutterComponent() if @presenter.getState().gutter.visible
@hiddenInputComponent = new InputComponent(@presenter)
@hiddenInputComponent = new InputComponent
@scrollViewNode.appendChild(@hiddenInputComponent.domNode)
@linesComponent = new LinesComponent({@presenter, @hostElement, @useShadowDOM})
@scrollViewNode.appendChild(@linesComponent.domNode)
@horizontalScrollbarComponent = new ScrollbarComponent({@presenter, orientation: 'horizontal', onScroll: @onHorizontalScroll})
@horizontalScrollbarComponent = new ScrollbarComponent({orientation: 'horizontal', onScroll: @onHorizontalScroll})
@scrollViewNode.appendChild(@horizontalScrollbarComponent.domNode)
@verticalScrollbarComponent = new ScrollbarComponent({@presenter, orientation: 'vertical', onScroll: @onVerticalScroll})
@verticalScrollbarComponent = new ScrollbarComponent({orientation: 'vertical', onScroll: @onVerticalScroll})
@domNode.appendChild(@verticalScrollbarComponent.domNode)
@scrollbarCornerComponent = new ScrollbarCornerComponent(@presenter)
@scrollbarCornerComponent = new ScrollbarCornerComponent
@domNode.appendChild(@scrollbarCornerComponent.domNode)
@observeEditor()
@@ -103,10 +103,8 @@ class TextEditorComponent
window.removeEventListener 'resize', @requestHeightAndWidthMeasurement
updateSync: ->
@presenter.update()
@oldState ?= {}
@newState = @presenter.state
@newState = @presenter.getState()
cursorMoved = @cursorMoved
selectionChanged = @selectionChanged
@@ -130,18 +128,18 @@ class TextEditorComponent
else
@domNode.style.height = ''
if @presenter.state.gutter.visible
if @newState.gutter.visible
@mountGutterComponent() unless @gutterComponent?
@gutterComponent.updateSync()
@gutterComponent.updateSync(@newState)
else
@gutterComponent?.domNode?.remove()
@gutterComponent = null
@hiddenInputComponent.updateSync()
@linesComponent.updateSync()
@horizontalScrollbarComponent.updateSync()
@verticalScrollbarComponent.updateSync()
@scrollbarCornerComponent.updateSync()
@hiddenInputComponent.updateSync(@newState)
@linesComponent.updateSync(@newState)
@horizontalScrollbarComponent.updateSync(@newState)
@verticalScrollbarComponent.updateSync(@newState)
@scrollbarCornerComponent.updateSync(@newState)
if @editor.isAlive()
@updateParentViewFocusedClassIfNeeded()
@@ -154,7 +152,7 @@ class TextEditorComponent
@linesComponent.measureCharactersInNewLines() if @isVisible() and not @newState.content.scrollingVertically
mountGutterComponent: ->
@gutterComponent = new GutterComponent({@presenter, @editor, onMouseDown: @onGutterMouseDown})
@gutterComponent = new GutterComponent({@editor, onMouseDown: @onGutterMouseDown})
@domNode.insertBefore(@gutterComponent.domNode, @domNode.firstChild)
becameVisible: ->

View File

@@ -53,8 +53,7 @@ class TextEditorPresenter
isBatching: ->
@updating == false
# Updates the state, applying only those changes that occurred between this call and a previous call to this method.
update: ->
getState: ->
@updating = true
@updateFocusedState() if @shouldUpdateFocusedState
@@ -87,6 +86,8 @@ class TextEditorPresenter
@updating = false
@state
observeModel: ->
@disposables.add @model.onDidChange =>
@updateContentDimensions()