From c1981ffb44b704fce9a69d6ba2fd1ba8feed5c9c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 7 Sep 2017 17:52:04 +0200 Subject: [PATCH] Correctly remove block decorations whose markers have been destroyed In https://github.com/atom/atom/pull/15503 we mistakenly assumed `marker.isValid` accounted only for the validity of the marker. However, that method returns `false` also for markers that are valid but have been destroyed. As a result, the editor component was mistakenly not removing block decorations associated with such markers. With this commit we will rely on the local `wasValid` variable instead. If its value is `true`, it means that the block decoration has been accounted for in the `lineTopIndex` and must, as a result, be cleaned up in case the marker or the decoration gets destroyed. --- spec/text-editor-component-spec.js | 21 +++++++++++++++++++++ src/text-editor-component.js | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index e2cd0988b..d1ff883c9 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -2299,6 +2299,27 @@ describe('TextEditorComponent', () => { ]) }) + it('removes block decorations whose markers have been destroyed', async () => { + const {editor, component, element} = buildComponent({rowsPerTile: 3}) + const {marker} = createBlockDecorationAtScreenRow(editor, 2, {height: 5, position: 'before'}) + await component.getNextUpdatePromise() + assertLinesAreAlignedWithLineNumbers(component) + assertTilesAreSizedAndPositionedCorrectly(component, [ + {tileStartRow: 0, height: 3 * component.getLineHeight() + 5}, + {tileStartRow: 3, height: 3 * component.getLineHeight()}, + {tileStartRow: 6, height: 3 * component.getLineHeight()} + ]) + + marker.destroy() + await component.getNextUpdatePromise() + assertLinesAreAlignedWithLineNumbers(component) + assertTilesAreSizedAndPositionedCorrectly(component, [ + {tileStartRow: 0, height: 3 * component.getLineHeight()}, + {tileStartRow: 3, height: 3 * component.getLineHeight()}, + {tileStartRow: 6, height: 3 * component.getLineHeight()} + ]) + }) + it('removes block decorations whose markers are invalidated, and adds them back when they become valid again', async () => { const editor = buildEditor({rowsPerTile: 3, autoHeight: false}) const {item, decoration, marker} = createBlockDecorationAtScreenRow(editor, 3, {height: 44, position: 'before', invalidate: 'touch'}) diff --git a/src/text-editor-component.js b/src/text-editor-component.js index 333486df8..c668ea8f6 100644 --- a/src/text-editor-component.js +++ b/src/text-editor-component.js @@ -2506,7 +2506,7 @@ class TextEditorComponent { didUpdateDisposable.dispose() didDestroyDisposable.dispose() - if (marker.isValid()) { + if (wasValid) { this.blockDecorationsToMeasure.delete(decoration) this.heightsByBlockDecoration.delete(decoration) this.blockDecorationsByElement.delete(element)