From 1d84d74e50c86d05d2e101516378422aa7aeb403 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 19 Feb 2015 14:57:30 -0700 Subject: [PATCH] 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. --- spec/spec-helper.coffee | 1 + spec/text-editor-component-spec.coffee | 13 +++++++------ src/text-editor-component.coffee | 24 ++++-------------------- src/view-registry.coffee | 8 ++++++++ 4 files changed, 20 insertions(+), 26 deletions(-) diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index a8b7478c1..d34c72b1a 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -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' diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 24a24ead6..2ebe9b373 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -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 = " diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index eb0a70293..cea4cae3e 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -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() diff --git a/src/view-registry.coffee b/src/view-registry.coffee index f3750171d..47b3658a3 100644 --- a/src/view-registry.coffee +++ b/src/view-registry.coffee @@ -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