diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index fd2af0ce2..258be57aa 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -558,6 +558,36 @@ describe('TextEditorComponent', () => { await component.getNextUpdatePromise() expect(element.className).toBe('editor a b') }) + + it('ignores resize events when the editor is hidden', async () => { + const {component, element, editor} = buildComponent({autoHeight: false}) + element.style.height = 5 * component.getLineHeight() + 'px' + await component.getNextUpdatePromise() + const originalClientContainerHeight = component.getClientContainerHeight() + const originalGutterContainerWidth = component.getGutterContainerWidth() + const originalLineNumberGutterWidth = component.getLineNumberGutterWidth() + expect(originalClientContainerHeight).toBeGreaterThan(0) + expect(originalGutterContainerWidth).toBeGreaterThan(0) + expect(originalLineNumberGutterWidth).toBeGreaterThan(0) + + element.style.display = 'none' + // In production, resize events are triggered before the intersection + // observer detects the editor's visibility has changed. In tests, we are + // unable to reproduce this scenario and so we simulate them. + expect(component.visible).toBe(true) + component.didResize() + component.didResizeGutterContainer() + expect(component.getClientContainerHeight()).toBe(originalClientContainerHeight) + expect(component.getGutterContainerWidth()).toBe(originalGutterContainerWidth) + expect(component.getLineNumberGutterWidth()).toBe(originalLineNumberGutterWidth) + + // Ensure measurements stay the same after receiving the intersection + // observer events. + await conditionPromise(() => !component.visible) + expect(component.getClientContainerHeight()).toBe(originalClientContainerHeight) + expect(component.getGutterContainerWidth()).toBe(originalGutterContainerWidth) + expect(component.getLineNumberGutterWidth()).toBe(originalLineNumberGutterWidth) + }) }) describe('mini editors', () => { diff --git a/src/text-editor-component.js b/src/text-editor-component.js index 2e8f8839b..56d008fa2 100644 --- a/src/text-editor-component.js +++ b/src/text-editor-component.js @@ -1311,21 +1311,27 @@ class TextEditorComponent { } didResize () { - const clientContainerWidthChanged = this.measureClientContainerWidth() - const clientContainerHeightChanged = this.measureClientContainerHeight() - if (clientContainerWidthChanged || clientContainerHeightChanged) { - if (clientContainerWidthChanged) { - this.remeasureAllBlockDecorations = true - } + // Prevent the component from measuring the client container dimensions when + // getting spurious resize events. + if (this.isVisible()) { + const clientContainerWidthChanged = this.measureClientContainerWidth() + const clientContainerHeightChanged = this.measureClientContainerHeight() + if (clientContainerWidthChanged || clientContainerHeightChanged) { + if (clientContainerWidthChanged) { + this.remeasureAllBlockDecorations = true + } - this.resizeObserver.disconnect() - this.scheduleUpdate() - process.nextTick(() => { this.resizeObserver.observe(this.element) }) + this.resizeObserver.disconnect() + this.scheduleUpdate() + process.nextTick(() => { this.resizeObserver.observe(this.element) }) + } } } didResizeGutterContainer () { - if (this.measureGutterDimensions()) { + // Prevent the component from measuring the gutter dimensions when getting + // spurious resize events. + if (this.isVisible() && this.measureGutterDimensions()) { this.gutterContainerResizeObserver.disconnect() this.scheduleUpdate() process.nextTick(() => { this.gutterContainerResizeObserver.observe(this.refs.gutterContainer.element) })