diff --git a/addons/xterm-addon-search/src/SearchAddon.ts b/addons/xterm-addon-search/src/SearchAddon.ts index 345b9153..c92c6c8a 100644 --- a/addons/xterm-addon-search/src/SearchAddon.ts +++ b/addons/xterm-addon-search/src/SearchAddon.ts @@ -128,7 +128,7 @@ export class SearchAddon implements ITerminalAddon { } this._lastSearchOptions = searchOptions; if (searchOptions?.decorations) { - if (this._resultIndex || this._cachedSearchTerm && term !== this._cachedSearchTerm) { + if (this._resultIndex !== undefined || this._cachedSearchTerm && term !== this._cachedSearchTerm) { this._highlightAllMatches(term, searchOptions); } } @@ -306,7 +306,7 @@ export class SearchAddon implements ITerminalAddon { throw new Error('Cannot use addon until it has been loaded'); } this._lastSearchOptions = searchOptions; - if (searchOptions?.decorations && (this._resultIndex || term !== this._cachedSearchTerm)) { + if (searchOptions?.decorations && (this._resultIndex !== undefined || term !== this._cachedSearchTerm)) { this._highlightAllMatches(term, searchOptions); } return this._fireResults(term, this._findPreviousAndSelect(term, searchOptions), searchOptions); @@ -693,7 +693,6 @@ export class SearchAddon implements ITerminalAddon { * @param element the decoration's element * @param backgroundColor the background color to apply * @param borderColor the border color to apply - * @param result the search result associated with the decoration * @returns */ private _applyStyles(element: HTMLElement, backgroundColor: string | undefined, borderColor: string | undefined): void { @@ -714,13 +713,13 @@ export class SearchAddon implements ITerminalAddon { /** * Creates a decoration for the result and applies styles * @param result the search result for which to create the decoration - * @param color the color to use for the decoration + * @param options the options for the decoration * @returns the {@link IDecoration} or undefined if the marker has already been disposed of */ - private _createResultDecoration(result: ISearchResult, decorations: ISearchDecorationOptions): IDecoration | undefined { + private _createResultDecoration(result: ISearchResult, options: ISearchDecorationOptions): IDecoration | undefined { const terminal = this._terminal!; const marker = terminal.registerMarker(-terminal.buffer.active.baseY - terminal.buffer.active.cursorY + result.row); - if (!marker || !decorations?.matchOverviewRuler) { + if (!marker || !options?.matchOverviewRuler) { return undefined; } const findResultDecoration = terminal.registerDecoration({ @@ -728,10 +727,10 @@ export class SearchAddon implements ITerminalAddon { x: result.col, width: result.size, overviewRulerOptions: this._resultDecorations?.get(marker.line) ? undefined : { - color: decorations.matchOverviewRuler, position: 'center' + color: options.matchOverviewRuler, position: 'center' } }); - findResultDecoration?.onRender((e) => this._applyStyles(e, decorations.matchBackground, decorations.matchBorder)); + findResultDecoration?.onRender((e) => this._applyStyles(e, options.matchBackground, options.matchBorder)); findResultDecoration?.onDispose(() => marker.dispose()); return findResultDecoration; } diff --git a/src/browser/Decorations/BufferDecorationRenderer.ts b/src/browser/Decorations/BufferDecorationRenderer.ts index 5bd0f940..f548750a 100644 --- a/src/browser/Decorations/BufferDecorationRenderer.ts +++ b/src/browser/Decorations/BufferDecorationRenderer.ts @@ -64,20 +64,10 @@ export class BufferDecorationRenderer extends Disposable { } private _renderDecoration(decoration: IInternalDecoration): void { - let element = this._decorationElements.get(decoration); - if (!element) { - element = this._createElement(decoration); - decoration.onDispose(() => this._removeDecoration(decoration)); - decoration.marker.onDispose(() => decoration.dispose()); - decoration.element = element; - this._decorationElements.set(decoration, element); - this._container.appendChild(element); - } - this._refreshStyle(decoration, element); + this._refreshStyle(decoration); if (this._dimensionsChanged) { this._refreshXPosition(decoration, element); } - decoration.onRenderEmitter.fire(element); } private _createElement(decoration: IInternalDecoration): HTMLElement { @@ -98,14 +88,26 @@ export class BufferDecorationRenderer extends Disposable { return element; } - private _refreshStyle(decoration: IInternalDecoration, element: HTMLElement): void { + private _refreshStyle(decoration: IInternalDecoration): void { const line = decoration.marker.line - this._bufferService.buffers.active.ydisp; if (line < 0 || line >= this._bufferService.rows) { // outside of viewport - element.style.display = 'none'; + if (decoration.element) { + decoration.element.style.display = 'none'; + decoration.onRenderEmitter.fire(decoration.element); + } } else { + let element = this._decorationElements.get(decoration); + if (!element) { + decoration.onDispose(() => this._removeDecoration(decoration)); + element = this._createElement(decoration); + decoration.element = element; + this._decorationElements.set(decoration, element); + this._container.appendChild(element); + } element.style.top = `${line * this._renderService.dimensions.actualCellHeight}px`; element.style.display = this._altBufferIsActive ? 'none' : 'block'; + decoration.onRenderEmitter.fire(element); } } diff --git a/src/common/services/DecorationService.ts b/src/common/services/DecorationService.ts index 03cfab4d..61936e15 100644 --- a/src/common/services/DecorationService.ts +++ b/src/common/services/DecorationService.ts @@ -30,6 +30,7 @@ export class DecorationService extends Disposable implements IDecorationService } const decoration = new Decoration(options); if (decoration) { + const markerDispose = decoration.marker.onDispose(() => decoration.dispose()); decoration.onDispose(() => { if (decoration) { const index = this._decorations.indexOf(decoration); @@ -37,6 +38,7 @@ export class DecorationService extends Disposable implements IDecorationService this._decorations.splice(this._decorations.indexOf(decoration), 1); this._onDecorationRemoved.fire(decoration); } + markerDispose.dispose(); } }); this._decorations.push(decoration);