From 3c8f600c572f16b63008e9d1bb6f56bf13325fdd Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 1 Sep 2021 11:27:14 -0700 Subject: [PATCH 1/3] fix #3348 --- addons/xterm-addon-webgl/src/WebglRenderer.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/xterm-addon-webgl/src/WebglRenderer.ts index 75b6230c..a3b8ddef 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/xterm-addon-webgl/src/WebglRenderer.ts @@ -108,7 +108,9 @@ export class WebglRenderer extends Disposable implements IRenderer { for (const l of this._renderLayers) { l.dispose(); } - this._core.screenElement!.removeChild(this._canvas); + if (this._canvas.parentNode) { + this._core.screenElement?.removeChild(this._canvas); + } super.dispose(); } From 199e477349f8c5be149b1c9b57d23624ab1b65d6 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 1 Sep 2021 13:45:49 -0700 Subject: [PATCH 2/3] 3 -> 1 line --- addons/xterm-addon-webgl/src/WebglRenderer.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/xterm-addon-webgl/src/WebglRenderer.ts index a3b8ddef..9d8bde79 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/xterm-addon-webgl/src/WebglRenderer.ts @@ -108,9 +108,7 @@ export class WebglRenderer extends Disposable implements IRenderer { for (const l of this._renderLayers) { l.dispose(); } - if (this._canvas.parentNode) { - this._core.screenElement?.removeChild(this._canvas); - } + this._canvas.parentElement?.removeChild(this._canvas); super.dispose(); } From 453688a555b9589666c161b69e5167235d9c4b8a Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Thu, 2 Sep 2021 06:26:31 -0700 Subject: [PATCH 3/3] Split up unicode surrogates tests to avoid timeout Fixes #3441 --- src/browser/Terminal.test.ts | 144 +++++++++++++++++------------------ 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/src/browser/Terminal.test.ts b/src/browser/Terminal.test.ts index 84e6a87e..a102d93f 100644 --- a/src/browser/Terminal.test.ts +++ b/src/browser/Terminal.test.ts @@ -732,80 +732,78 @@ describe('Terminal', () => { }); describe('unicode - surrogates', () => { - it('2 characters per cell', async function (): Promise { - this.timeout(10000); // This is needed because istanbul patches code and slows it down - const high = String.fromCharCode(0xD800); - const cell = new CellData(); - for (let i = 0xDC00; i <= 0xDCFF; ++i) { - await term.writeP(high + String.fromCharCode(i)); - const tchar = term.buffer.lines.get(0)!.loadCell(0, cell); - assert.equal(tchar.getChars(), high + String.fromCharCode(i)); - assert.equal(tchar.getChars().length, 2); - assert.equal(tchar.getWidth(), 1); - assert.equal(term.buffer.lines.get(0)!.loadCell(1, cell).getChars(), ''); - term.reset(); - } - }); - it('2 characters at last cell', async () => { - const high = String.fromCharCode(0xD800); - const cell = new CellData(); - for (let i = 0xDC00; i <= 0xDCFF; ++i) { - term.buffer.x = term.cols - 1; - await term.writeP(high + String.fromCharCode(i)); - assert.equal(term.buffer.lines.get(0)!.loadCell(term.buffer.x - 1, cell).getChars(), high + String.fromCharCode(i)); - assert.equal(term.buffer.lines.get(0)!.loadCell(term.buffer.x - 1, cell).getChars().length, 2); - assert.equal(term.buffer.lines.get(1)!.loadCell(0, cell).getChars(), ''); - term.reset(); - } - }); - it('2 characters per cell over line end with autowrap', async function (): Promise { - this.timeout(10000); - const high = String.fromCharCode(0xD800); - const cell = new CellData(); - for (let i = 0xDC00; i <= 0xDCFF; ++i) { - term.buffer.x = term.cols - 1; - - await term.writeP('a' + high + String.fromCharCode(i)); - assert.equal(term.buffer.lines.get(0)!.loadCell(term.cols - 1, cell).getChars(), 'a'); - assert.equal(term.buffer.lines.get(1)!.loadCell(0, cell).getChars(), high + String.fromCharCode(i)); - assert.equal(term.buffer.lines.get(1)!.loadCell(0, cell).getChars().length, 2); - assert.equal(term.buffer.lines.get(1)!.loadCell(1, cell).getChars(), ''); - term.reset(); - } - }); - it('2 characters per cell over line end without autowrap', async function (): Promise { - this.timeout(10000); - const high = String.fromCharCode(0xD800); - const cell = new CellData(); - for (let i = 0xDC00; i <= 0xDCFF; ++i) { - term.buffer.x = term.cols - 1; - await term.writeP('\x1b[?7l'); // Disable wraparound mode - const width = wcwidth((0xD800 - 0xD800) * 0x400 + i - 0xDC00 + 0x10000); - if (width !== 1) { - continue; + for (let i = 0xDC00; i <= 0xDCF0; i += 0x10) { + const range = `0x${i.toString(16).toUpperCase()}-0x${(i + 0xF).toString(16).toUpperCase()}`; + it(`${range}: 2 characters per cell`, async function (): Promise { + const high = String.fromCharCode(0xD800); + const cell = new CellData(); + for (let j = i; j <= i + 0xF; j++) { + await term.writeP(high + String.fromCharCode(j)); + const tchar = term.buffer.lines.get(0)!.loadCell(0, cell); + assert.equal(tchar.getChars(), high + String.fromCharCode(j)); + assert.equal(tchar.getChars().length, 2); + assert.equal(tchar.getWidth(), 1); + assert.equal(term.buffer.lines.get(0)!.loadCell(1, cell).getChars(), ''); + term.reset(); } - await term.writeP('a' + high + String.fromCharCode(i)); - // auto wraparound mode should cut off the rest of the line - assert.equal(term.buffer.lines.get(0)!.loadCell(term.cols - 1, cell).getChars(), high + String.fromCharCode(i)); - assert.equal(term.buffer.lines.get(0)!.loadCell(term.cols - 1, cell).getChars().length, 2); - assert.equal(term.buffer.lines.get(1)!.loadCell(1, cell).getChars(), ''); - term.reset(); - } - }); - it('splitted surrogates', async function (): Promise { - this.timeout(10000); - const high = String.fromCharCode(0xD800); - const cell = new CellData(); - for (let i = 0xDC00; i <= 0xDCFF; ++i) { - await term.writeP(high + String.fromCharCode(i)); - const tchar = term.buffer.lines.get(0)!.loadCell(0, cell); - assert.equal(tchar.getChars(), high + String.fromCharCode(i)); - assert.equal(tchar.getChars().length, 2); - assert.equal(tchar.getWidth(), 1); - assert.equal(term.buffer.lines.get(0)!.loadCell(1, cell).getChars(), ''); - term.reset(); - } - }); + }); + it(`${range}: 2 characters at last cell`, async () => { + const high = String.fromCharCode(0xD800); + const cell = new CellData(); + term.buffer.x = term.cols - 1; + for (let j = i; j <= i + 0xF; j++) { + await term.writeP(high + String.fromCharCode(j)); + assert.equal(term.buffer.lines.get(0)!.loadCell(term.buffer.x - 1, cell).getChars(), high + String.fromCharCode(j)); + assert.equal(term.buffer.lines.get(0)!.loadCell(term.buffer.x - 1, cell).getChars().length, 2); + assert.equal(term.buffer.lines.get(1)!.loadCell(0, cell).getChars(), ''); + term.reset(); + } + }); + it(`${range}: 2 characters per cell over line end with autowrap`, async function (): Promise { + const high = String.fromCharCode(0xD800); + const cell = new CellData(); + for (let j = i; j <= i + 0xF; j++) { + term.buffer.x = term.cols - 1; + await term.writeP('a' + high + String.fromCharCode(j)); + assert.equal(term.buffer.lines.get(0)!.loadCell(term.cols - 1, cell).getChars(), 'a'); + assert.equal(term.buffer.lines.get(1)!.loadCell(0, cell).getChars(), high + String.fromCharCode(j)); + assert.equal(term.buffer.lines.get(1)!.loadCell(0, cell).getChars().length, 2); + assert.equal(term.buffer.lines.get(1)!.loadCell(1, cell).getChars(), ''); + term.reset(); + } + }); + it(`${range}: 2 characters per cell over line end without autowrap`, async function (): Promise { + const high = String.fromCharCode(0xD800); + const cell = new CellData(); + for (let j = i; j <= i + 0xF; j++) { + term.buffer.x = term.cols - 1; + await term.writeP('\x1b[?7l'); // Disable wraparound mode + const width = wcwidth((0xD800 - 0xD800) * 0x400 + j - 0xDC00 + 0x10000); + if (width !== 1) { + continue; + } + await term.writeP('a' + high + String.fromCharCode(j)); + // auto wraparound mode should cut off the rest of the line + assert.equal(term.buffer.lines.get(0)!.loadCell(term.cols - 1, cell).getChars(), high + String.fromCharCode(j)); + assert.equal(term.buffer.lines.get(0)!.loadCell(term.cols - 1, cell).getChars().length, 2); + assert.equal(term.buffer.lines.get(1)!.loadCell(1, cell).getChars(), ''); + term.reset(); + } + }); + it(`${range}: splitted surrogates`, async function (): Promise { + const high = String.fromCharCode(0xD800); + const cell = new CellData(); + for (let j = i; j <= i + 0xF; j++) { + await term.writeP(high + String.fromCharCode(j)); + const tchar = term.buffer.lines.get(0)!.loadCell(0, cell); + assert.equal(tchar.getChars(), high + String.fromCharCode(j)); + assert.equal(tchar.getChars().length, 2); + assert.equal(tchar.getWidth(), 1); + assert.equal(term.buffer.lines.get(0)!.loadCell(1, cell).getChars(), ''); + term.reset(); + } + }); + } }); describe('unicode - combining characters', () => {