From 583c2c537da3037a5e5dea2a091aeef86f07f040 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 23 Feb 2017 21:30:35 -0700 Subject: [PATCH] Iron out scheduling issues * Ensure multiple calls to scheduleUpdate only result in a single call to updateSync in the future. * Explicit calls to update sync after scheduling an update fulfill the scheduled update. * Track whether we think the editor is visible or not to avoid redundant didShow calls. * Ensure we only update on resize events if the editor actually changed size. --- spec/text-editor-component-spec.js | 6 ++++- src/text-editor-component.js | 38 ++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 5432065b1..e6bf8877b 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -19,7 +19,11 @@ describe('TextEditorComponent', () => { function buildComponent (params = {}) { const buffer = new TextBuffer({text: SAMPLE_TEXT}) const editor = new TextEditor({buffer}) - const component = new TextEditorComponent({model: editor, rowsPerTile: params.rowsPerTile}) + const component = new TextEditorComponent({ + model: editor, + rowsPerTile: params.rowsPerTile, + updatedSynchronously: false + }) const {element} = component element.style.width = params.width ? params.width + 'px' : '800px' element.style.height = params.height ? params.height + 'px' : '600px' diff --git a/src/text-editor-component.js b/src/text-editor-component.js index fa4773dc9..89c09277d 100644 --- a/src/text-editor-component.js +++ b/src/text-editor-component.js @@ -19,9 +19,12 @@ class TextEditorComponent { this.virtualNode = $('atom-text-editor') this.virtualNode.domNode = this.element this.refs = {} - etch.updateSync(this) + this.updateScheduled = false + this.visible = false resizeDetector.listenTo(this.element, this.didResize.bind(this)) + + etch.updateSync(this) } update (props) { @@ -32,14 +35,16 @@ class TextEditorComponent { scheduleUpdate () { if (this.updatedSynchronously) { this.updateSync() - } else { + } else if (!this.updateScheduled) { + this.updateScheduled = true etch.getScheduler().updateDocument(() => { - this.updateSync() + if (this.updateScheduled) this.updateSync() }) } } updateSync () { + this.updateScheduled = false if (this.nextUpdatePromise) { this.resolveNextUpdatePromise() this.nextUpdatePromise = null @@ -271,13 +276,19 @@ class TextEditorComponent { } didShow () { - this.getModel().setVisible(true) - if (!this.measurements) this.performInitialMeasurements() - this.updateSync() + if (!this.visible) { + this.visible = true + this.getModel().setVisible(true) + if (!this.measurements) this.performInitialMeasurements() + this.updateSync() + } } didHide () { - this.getModel().setVisible(false) + if (this.visible) { + this.visible = false + this.getModel().setVisible(false) + } } didScroll () { @@ -286,8 +297,9 @@ class TextEditorComponent { } didResize () { - this.measureEditorDimensions() - this.scheduleUpdate() + if (this.measureEditorDimensions()) { + this.scheduleUpdate() + } } performInitialMeasurements () { @@ -300,7 +312,13 @@ class TextEditorComponent { } measureEditorDimensions () { - this.measurements.scrollerHeight = this.refs.scroller.offsetHeight + const scrollerHeight = this.refs.scroller.offsetHeight + if (scrollerHeight !== this.measurements.scrollerHeight) { + this.measurements.scrollerHeight = this.refs.scroller.offsetHeight + return true + } else { + return false + } } measureScrollPosition () {