From 5af1554bbfda78300acea7b731e3b22e0ae654f4 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 3 Jun 2020 16:05:53 -0400 Subject: [PATCH 1/3] Only removeChild valid children in DomRenderer dispose --- src/browser/renderer/dom/DomRenderer.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index a01c2208..d9faf79c 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -95,10 +95,20 @@ export class DomRenderer extends Disposable implements IRenderer { public dispose(): void { this._element.classList.remove(TERMINAL_CLASS_PREFIX + this._terminalClass); - this._screenElement.removeChild(this._rowContainer); - this._screenElement.removeChild(this._selectionContainer); - this._screenElement.removeChild(this._themeStyleElement); - this._screenElement.removeChild(this._dimensionsStyleElement); + + // Outside influences such as React unmounts may manipulate the DOM before our disposal. + // https://github.com/xtermjs/xterm.js/issues/2960 + for (const element of [ + this._rowContainer, + this._selectionContainer, + this._themeStyleElement, + this._dimensionsStyleElement, + ]) { + if (element.parentElement === this._screenElement) { + this._screenElement.removeChild(element); + } + } + super.dispose(); } From 8ee08a3be7da3ab724b730646123ad30d4940d3b Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 3 Jun 2020 16:16:00 -0400 Subject: [PATCH 2/3] ESLint? What is that? Never heard of the thing. --- src/browser/renderer/dom/DomRenderer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index d9faf79c..5e6231f3 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -102,13 +102,13 @@ export class DomRenderer extends Disposable implements IRenderer { this._rowContainer, this._selectionContainer, this._themeStyleElement, - this._dimensionsStyleElement, + this._dimensionsStyleElement ]) { if (element.parentElement === this._screenElement) { this._screenElement.removeChild(element); } } - + super.dispose(); } From fbb8c6273b38f879f1186e2be3121aab1402cd92 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 4 Jun 2020 10:12:36 -0400 Subject: [PATCH 3/3] Switched to parentElement optionals --- src/browser/renderer/dom/DomRenderer.ts | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index 5e6231f3..9082e36b 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -98,16 +98,10 @@ export class DomRenderer extends Disposable implements IRenderer { // Outside influences such as React unmounts may manipulate the DOM before our disposal. // https://github.com/xtermjs/xterm.js/issues/2960 - for (const element of [ - this._rowContainer, - this._selectionContainer, - this._themeStyleElement, - this._dimensionsStyleElement - ]) { - if (element.parentElement === this._screenElement) { - this._screenElement.removeChild(element); - } - } + this._rowContainer.parentElement?.removeChild(this._rowContainer); + this._selectionContainer.parentElement?.removeChild(this._selectionContainer); + this._themeStyleElement.parentElement?.removeChild(this._themeStyleElement); + this._dimensionsStyleElement.parentElement?.removeChild(this._dimensionsStyleElement); super.dispose(); }