Centralize text editor DOM interaction through atom.views

This ensures that DOM writing, reading, and polling properly interleaves
with DOM interactions from other text editors and any other code that
coordinates via atom.views. Not sure about the location of it though.
This commit is contained in:
Nathan Sobo 2015-02-19 14:57:30 -07:00
parent de4d995190
commit 1d84d74e50
4 changed files with 20 additions and 26 deletions

View File

@ -82,6 +82,7 @@ beforeEach ->
atom.keymaps.keyBindings = _.clone(keyBindingsToRestore)
atom.commands.restoreSnapshot(commandsToRestore)
atom.styles.restoreSnapshot(styleElementsToRestore)
atom.views.clearDocumentRequests()
atom.workspaceViewParentSelector = '#jasmine-content'

View File

@ -193,7 +193,8 @@ describe "TextEditorComponent", ->
expect(linesNode.style.backgroundColor).toBe backgroundColor
wrapperNode.style.backgroundColor = 'rgb(255, 0, 0)'
advanceClock(component.domPollingInterval)
advanceClock(atom.views.documentPollingInterval)
nextAnimationFrame()
expect(linesNode.style.backgroundColor).toBe 'rgb(255, 0, 0)'
@ -562,7 +563,7 @@ describe "TextEditorComponent", ->
# favor gutter color if it's assigned
gutterNode.style.backgroundColor = 'rgb(255, 0, 0)'
advanceClock(component.domPollingInterval)
advanceClock(atom.views.documentPollingInterval)
nextAnimationFrame()
expect(lineNumbersNode.style.backgroundColor).toBe 'rgb(255, 0, 0)'
@ -2355,7 +2356,7 @@ describe "TextEditorComponent", ->
expect(componentNode.querySelectorAll('.line').length).toBe 0
hiddenParent.style.display = 'block'
advanceClock(component.domPollingInterval)
advanceClock(atom.views.documentPollingInterval)
expect(componentNode.querySelectorAll('.line').length).toBeGreaterThan 0
@ -2465,13 +2466,13 @@ describe "TextEditorComponent", ->
expect(parseInt(newHeight)).toBeLessThan wrapperNode.offsetHeight
wrapperNode.style.height = newHeight
advanceClock(component.domPollingInterval)
advanceClock(atom.views.documentPollingInterval)
nextAnimationFrame()
expect(componentNode.querySelectorAll('.line')).toHaveLength(4 + lineOverdrawMargin + 1)
gutterWidth = componentNode.querySelector('.gutter').offsetWidth
componentNode.style.width = gutterWidth + 14 * charWidth + editor.getVerticalScrollbarWidth() + 'px'
advanceClock(component.domPollingInterval)
advanceClock(atom.views.documentPollingInterval)
nextAnimationFrame()
expect(componentNode.querySelector('.line').textContent).toBe "var quicksort "
@ -2480,7 +2481,7 @@ describe "TextEditorComponent", ->
scrollViewNode.style.paddingLeft = 20 + 'px'
componentNode.style.width = 30 * charWidth + 'px'
advanceClock(component.domPollingInterval)
advanceClock(atom.views.documentPollingInterval)
nextAnimationFrame()
expect(component.lineNodeForScreenRow(0).textContent).toBe "var quicksort = "

View File

@ -15,7 +15,6 @@ ScrollbarCornerComponent = require './scrollbar-corner-component'
module.exports =
class TextEditorComponent
scrollSensitivity: 0.4
domPollingInterval: 100
cursorBlinkPeriod: 800
cursorBlinkResumeDelay: 100
lineOverdrawMargin: 15
@ -29,8 +28,6 @@ class TextEditorComponent
cursorMoved: false
selectionChanged: false
inputEnabled: true
domPollingIntervalId: null
domPollingPaused: false
measureScrollbarsWhenShown: true
measureLineHeightAndDefaultCharWidthWhenShown: true
remeasureCharacterWidthsWhenShown: false
@ -94,7 +91,7 @@ class TextEditorComponent
@disposables.add atom.themes.onDidChangeActiveThemes @onAllThemesLoaded
@disposables.add scrollbarStyle.changes.onValue @refreshScrollbars
@domPollingIntervalId = setInterval(@pollDOM, @domPollingInterval)
@disposables.add atom.views.pollDocument(@pollDOM)
@updateSync()
@checkForVisibilityChange()
@ -104,8 +101,6 @@ class TextEditorComponent
@disposables.dispose()
@presenter.destroy()
window.removeEventListener 'resize', @requestHeightAndWidthMeasurement
clearInterval(@domPollingIntervalId)
@domPollingIntervalId = null
updateSync: ->
@oldState ?= {}
@ -153,6 +148,7 @@ class TextEditorComponent
@hostElement.__spacePenView.trigger 'selection:changed' if selectionChanged
@hostElement.__spacePenView.trigger 'editor:display-updated'
readAfterUpdateSync: =>
@linesComponent.measureCharactersInNewLines() if @isVisible() and not @newState.content.scrollingVertically
mountGutterComponent: ->
@ -183,16 +179,16 @@ class TextEditorComponent
@updateSync()
else unless @updateRequested
@updateRequested = true
requestAnimationFrame =>
atom.views.updateDocument =>
@updateRequested = false
@updateSync() if @editor.isAlive()
atom.views.readDocument(@readAfterUpdateSync)
canUpdate: ->
@mounted and @editor.isAlive()
requestAnimationFrame: (fn) ->
@updatesPaused = true
@pauseDOMPolling()
requestAnimationFrame =>
fn()
@updatesPaused = false
@ -550,19 +546,7 @@ class TextEditorComponent
isVisible: ->
@domNode.offsetHeight > 0 or @domNode.offsetWidth > 0
pauseDOMPolling: ->
@domPollingPaused = true
@resumeDOMPollingAfterDelay ?= _.debounce(@resumeDOMPolling, 100)
@resumeDOMPollingAfterDelay()
resumeDOMPolling: ->
@domPollingPaused = false
resumeDOMPollingAfterDelay: null # created lazily
pollDOM: =>
return if @domPollingPaused or @updateRequested or not @mounted
unless @checkForVisibilityChange()
@sampleBackgroundColors()
@measureHeightAndWidth()

View File

@ -43,6 +43,8 @@ Grim = require 'grim'
module.exports =
class ViewRegistry
documentPollingInterval: 200
documentUpdateRequested: false
pollIntervalHandle: null
constructor: ->
@views = new WeakMap
@ -175,6 +177,12 @@ class ViewRegistry
@documentPollers = @documentPollers.filter (poller) -> poller isnt fn
@stopPollingDocument() if @documentPollers.length is 0
clearDocumentRequests: ->
@documentReaders = []
@documentWriters = []
@documentPollers = []
@documentUpdateRequested = false
requestDocumentUpdate: ->
unless @documentUpdateRequested
@documentUpdateRequested = true