From 4fffb96f25628a8b17f7640086cb0cad0807f47b Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Dec 2025 03:51:01 -0800 Subject: [PATCH] Move addCjk into window, move window interactions out of createTerminal --- demo/client.ts | 97 +++++++++++++--------------- demo/components/controlBar.ts | 4 +- demo/components/window/testWindow.ts | 23 ++++++- 3 files changed, 68 insertions(+), 56 deletions(-) diff --git a/demo/client.ts b/demo/client.ts index 5885388e..1c2508e8 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -67,7 +67,6 @@ let addonsWindow: AddonsWindow; let gpuWindow: GpuWindow; let optionsWindow: OptionsWindow; let styleWindow: StyleWindow; -let testWindow: TestWindow; let vtWindow: VtWindow; type AddonType = 'attach' | 'clipboard' | 'fit' | 'image' | 'progress' | 'search' | 'serialize' | 'unicode11' | 'unicodeGraphemes' | 'webLinks' | 'webgl' | 'ligatures'; @@ -242,6 +241,8 @@ if (document.location.pathname === '/test') { window.WebLinksAddon = WebLinksAddon; window.WebglAddon = WebglAddon; } else { + const typedTerm = createTerminal(); + controlBar = new ControlBar(document.getElementById('sidebar'), document.querySelector('.banner-tabs'), []); addonsWindow = new AddonsWindow(); controlBar.registerWindow(addonsWindow); @@ -253,16 +254,49 @@ if (document.location.pathname === '/test') { gpuWindow = new GpuWindow(); controlBar.registerWindow(gpuWindow, { afterId: 'addons', hidden: true, smallTab: true }); optionsWindow = new OptionsWindow(updateTerminalSize, updateTerminalContainerBackground); - controlBar.registerWindow(optionsWindow); - styleWindow = new StyleWindow(); - controlBar.registerWindow(styleWindow); + const styleWindow = controlBar.registerWindow(new StyleWindow()); paddingElement = styleWindow.paddingElement; - testWindow = new TestWindow(); - controlBar.registerWindow(testWindow); + controlBar.registerWindow(optionsWindow); + controlBar.registerWindow(new TestWindow(typedTerm)); vtWindow = new VtWindow(); controlBar.registerWindow(vtWindow); + vtWindow.initTerminal(term); controlBar.activateDefaultTab(); - createTerminal(); + + // TODO: Most of below should be encapsulated within windows + controlBar.setTabVisible('gpu', true); + gpuWindow.setTextureAtlas(addons.webgl.instance.textureAtlas); + addons.webgl.instance.onChangeTextureAtlas(e => gpuWindow.setTextureAtlas(e)); + addons.webgl.instance.onAddTextureAtlasCanvas(e => gpuWindow.appendTextureAtlas(e)); + addons.webgl.instance.onRemoveTextureAtlasCanvas(e => gpuWindow.removeTextureAtlas(e)); + + paddingElement.value = '0'; + addDomListener(paddingElement, 'change', setPadding); + addDomListener(actionElements.findNext, 'keydown', (e) => { + if (e.key === 'Enter') { + addons.search.instance.findNext(actionElements.findNext.value, getSearchOptions()); + e.preventDefault(); + } + }); + addDomListener(actionElements.findNext, 'input', (e) => { + addons.search.instance.findNext(actionElements.findNext.value, getSearchOptions()); + }); + addDomListener(actionElements.findPrevious, 'keydown', (e) => { + if (e.key === 'Enter') { + addons.search.instance.findPrevious(actionElements.findPrevious.value, getSearchOptions()); + e.preventDefault(); + } + }); + addDomListener(actionElements.findPrevious, 'input', (e) => { + addons.search.instance.findPrevious(actionElements.findPrevious.value, getSearchOptions()); + }); + addDomListener(actionElements.findNext, 'blur', (e) => { + addons.search.instance.clearActiveDecoration(); + }); + addDomListener(actionElements.findPrevious, 'blur', (e) => { + addons.search.instance.clearActiveDecoration(); + }); + document.getElementById('dispose').addEventListener('click', disposeRecreateButtonHandler); document.getElementById('create-new-window').addEventListener('click', createNewWindowButtonHandler); document.getElementById('serialize').addEventListener('click', serializeButtonHandler); @@ -271,7 +305,6 @@ if (document.location.pathname === '/test') { document.getElementById('custom-glyph-ranges').addEventListener('click', customGlyphRangesHandler); document.getElementById('load-test').addEventListener('click', loadTest); document.getElementById('load-test-long-lines').addEventListener('click', loadTestLongLines); - document.getElementById('print-cjk').addEventListener('click', addCjk); document.getElementById('print-cjk-sgr').addEventListener('click', addCjkRandomSgr); document.getElementById('powerline-symbol-test').addEventListener('click', powerlineSymbolTest); document.getElementById('underline-test').addEventListener('click', underlineTest); @@ -290,7 +323,7 @@ if (document.location.pathname === '/test') { progressButtons(); } -function createTerminal(): void { +function createTerminal(): Terminal { // Clean terminal while (terminalContainer.children.length) { terminalContainer.removeChild(terminalContainer.children[0]); @@ -352,11 +385,6 @@ function createTerminal(): void { try { typedTerm.loadAddon(addons.webgl.instance); term.open(terminalContainer); - controlBar.setTabVisible('gpu', true); - gpuWindow.setTextureAtlas(addons.webgl.instance.textureAtlas); - addons.webgl.instance.onChangeTextureAtlas(e => gpuWindow.setTextureAtlas(e)); - addons.webgl.instance.onAddTextureAtlasCanvas(e => gpuWindow.appendTextureAtlas(e)); - addons.webgl.instance.onRemoveTextureAtlasCanvas(e => gpuWindow.removeTextureAtlas(e)); } catch (e) { console.warn('error during loading webgl addon:', e); addons.webgl.instance.dispose(); @@ -370,7 +398,6 @@ function createTerminal(): void { term.focus(); updateTerminalContainerBackground(); - vtWindow?.initTerminal(term); const resizeObserver = new ResizeObserver(entries => { if (optionsWindow.autoResize) { @@ -379,37 +406,9 @@ function createTerminal(): void { }); resizeObserver.observe(terminalContainer); - addDomListener(paddingElement, 'change', setPadding); - - addDomListener(actionElements.findNext, 'keydown', (e) => { - if (e.key === 'Enter') { - addons.search.instance.findNext(actionElements.findNext.value, getSearchOptions()); - e.preventDefault(); - } - }); - addDomListener(actionElements.findNext, 'input', (e) => { - addons.search.instance.findNext(actionElements.findNext.value, getSearchOptions()); - }); - addDomListener(actionElements.findPrevious, 'keydown', (e) => { - if (e.key === 'Enter') { - addons.search.instance.findPrevious(actionElements.findPrevious.value, getSearchOptions()); - e.preventDefault(); - } - }); - addDomListener(actionElements.findPrevious, 'input', (e) => { - addons.search.instance.findPrevious(actionElements.findPrevious.value, getSearchOptions()); - }); - addDomListener(actionElements.findNext, 'blur', (e) => { - addons.search.instance.clearActiveDecoration(); - }); - addDomListener(actionElements.findPrevious, 'blur', (e) => { - addons.search.instance.clearActiveDecoration(); - }); - // fit is called within a setTimeout, cols and rows need this. setTimeout(async () => { optionsWindow.initOptions(term, addDomListener); - paddingElement.value = '0'; // Set terminal size again to set the specific dimensions on the demo updateTerminalSize(); @@ -428,6 +427,8 @@ function createTerminal(): void { socket.onerror = runFakeTerminal; } }, 0); + + return typedTerm; } function runRealTerminal(): void { @@ -1163,16 +1164,6 @@ function addAnsiHyperlink(): void { term.write('\x1b[3A\x1b[1C\x1b]8;;https://xtermjs.org\x07xter\x1b[B\x1b[4Dm.js\x1b]8;;\x07\x1b[2B\x1b[5D'); } -/** - * Prints the 20977 characters from the CJK Unified Ideographs unicode block. - */ -function addCjk(): void { - term.write('\n\n\r'); - for (let i = 0x4E00; i < 0x9FCC; i++) { - term.write(String.fromCharCode(i)); - } -} - /** * Prints the 20977 characters from the CJK Unified Ideographs unicode block with randomized styles. */ diff --git a/demo/components/controlBar.ts b/demo/components/controlBar.ts index b82d9a0d..fba37af5 100644 --- a/demo/components/controlBar.ts +++ b/demo/components/controlBar.ts @@ -146,7 +146,7 @@ export class ControlBar { } } - public registerWindow(window: IControlWindow, options?: { afterId?: string; hidden?: boolean; smallTab?: boolean }): void { + public registerWindow(window: T, options?: { afterId?: string; hidden?: boolean; smallTab?: boolean }): T { // Create button const button = document.createElement('button'); button.id = `${window.id}button`; @@ -187,6 +187,8 @@ export class ControlBar { window.build(content); this._tabs.set(window.id, { button, content }); + + return window; } public setTabVisible(tabId: string, visible: boolean): void { diff --git a/demo/components/window/testWindow.ts b/demo/components/window/testWindow.ts index 5626751c..5456aa6a 100644 --- a/demo/components/window/testWindow.ts +++ b/demo/components/window/testWindow.ts @@ -3,12 +3,20 @@ * @license MIT */ +/// + import type { IControlWindow } from '../controlBar'; +import type { Terminal } from '@xterm/xterm'; export class TestWindow implements IControlWindow { public readonly id = 'test'; public readonly label = 'Test'; + private _printCjkButton: HTMLButtonElement; + + constructor(private readonly _terminal: Terminal) { + } + public build(container: HTMLElement): void { const heading = document.createElement('h3'); heading.textContent = 'Test'; @@ -30,7 +38,7 @@ export class TestWindow implements IControlWindow { this._addDt(dl, 'Performance'); this._addDdWithButton(dl, 'load-test', 'Load test', 'Write several MB of data to simulate a lot of data coming from the process'); this._addDdWithButton(dl, 'load-test-long-lines', 'Load test (long lines)', 'Write several MB of data with long lines to simulate a lot of data coming from the process'); - this._addDdWithButton(dl, 'print-cjk', 'CJK Unified Ideographs', 'Prints the 20977 characters from the CJK Unified Ideographs unicode block'); + this._addDdWithButton(dl, 'print-cjk', 'CJK Unified Ideographs', 'Prints the 20977 characters from the CJK Unified Ideographs unicode block', () => addCjk(this._terminal)); this._addDdWithButton(dl, 'print-cjk-sgr', 'CJK Unified Ideographs (random SGR)', 'Prints the 20977 characters from the CJK Unified Ideographs unicode block with randomized SGR attributes'); // Styles section @@ -113,7 +121,7 @@ export class TestWindow implements IControlWindow { dl.appendChild(dt); } - private _addDdWithButton(dl: HTMLElement, id: string, label: string, title: string): void { + private _addDdWithButton(dl: HTMLElement, id: string, label: string, title: string, handler?: () => void): void { const dd = document.createElement('dd'); const button = document.createElement('button'); button.id = id; @@ -123,6 +131,7 @@ export class TestWindow implements IControlWindow { } dd.appendChild(button); dl.appendChild(dd); + button.addEventListener('click', handler); } private _addDdWithCheckbox(dl: HTMLElement, id: string, label: string, title: string, checked: boolean): void { @@ -175,3 +184,13 @@ export class TestWindow implements IControlWindow { container.appendChild(style); } } + +/** + * Prints the 20977 characters from the CJK Unified Ideographs unicode block. + */ +export function addCjk(term: Terminal): void { + term.write('\n\n\r'); + for (let i = 0x4E00; i < 0x9FCC; i++) { + term.write(String.fromCharCode(i)); + } +}