From 1f11c7e46c513d56198eb19b8d40d79b1269f991 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 5 Jul 2024 08:46:15 -0700 Subject: [PATCH] Get sources building with esbuild --- .eslintrc.json | 5 +- .gitignore | 2 + .vscode/settings.json | 8 +- .vscode/tasks.json | 114 +++++----- addons/addon-attach/package.json | 2 +- addons/addon-attach/test/playwright.config.ts | 2 +- addons/addon-canvas/package.json | 2 +- addons/addon-canvas/test/playwright.config.ts | 2 +- addons/addon-clipboard/package.json | 2 +- .../addon-clipboard/test/playwright.config.ts | 2 +- addons/addon-fit/package.json | 2 +- addons/addon-fit/test/playwright.config.ts | 2 +- addons/addon-image/package.json | 2 +- addons/addon-image/test/playwright.config.ts | 2 +- addons/addon-search/package.json | 2 +- addons/addon-search/test/playwright.config.ts | 2 +- addons/addon-serialize/package.json | 2 +- addons/addon-serialize/src/SerializeAddon.ts | 2 +- .../addon-serialize/test/playwright.config.ts | 2 +- .../UnicodeGraphemeAddon.benchmark.ts | 10 +- addons/addon-unicode-graphemes/package.json | 2 +- .../test/playwright.config.ts | 2 +- addons/addon-unicode11/package.json | 2 +- .../addon-unicode11/test/playwright.config.ts | 2 +- addons/addon-web-links/package.json | 2 +- .../addon-web-links/test/playwright.config.ts | 2 +- addons/addon-webgl/package.json | 2 +- addons/addon-webgl/test/playwright.config.ts | 2 +- addons/addon-webgl/typings/addon-webgl.d.ts | 5 + bin/esbuild.mjs | 197 ++++++++++++++++++ bin/esbuild_all.mjs | 55 +++++ demo/client.ts | 91 ++++---- demo/start-server-only.js | 10 - demo/start.js | 16 -- demo/tsconfig.json | 20 +- package.json | 61 ++++-- .../{Terminal.ts => CoreBrowserTerminal.ts} | 2 +- src/browser/Terminal2.test.ts | 8 +- src/browser/TestUtils.test.ts | 4 +- src/browser/Types.ts | 49 +++++ src/browser/public/Terminal.ts | 2 +- src/browser/services/ThemeService.test.ts | 3 +- src/browser/services/ThemeService.ts | 52 +---- test/benchmark/Terminal.benchmark.ts | 10 +- yarn.lock | 150 +++++++++++++ 45 files changed, 666 insertions(+), 254 deletions(-) create mode 100644 bin/esbuild.mjs create mode 100644 bin/esbuild_all.mjs delete mode 100644 demo/start-server-only.js rename src/browser/{Terminal.ts => CoreBrowserTerminal.ts} (99%) diff --git a/.eslintrc.json b/.eslintrc.json index d4d7eddc..9c8493dd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -45,10 +45,13 @@ "addons/*/src/third-party/*.ts", "out/*", "out-test/*", + "out-esbuild/*", + "out-esbuild-test/*", "**/inwasm-sdks/*", "**/typings/*.d.ts", "**/node_modules", - "**/*.js" + "**/*.js", + "**/*.mjs" ], "plugins": [ "@stylistic/ts", diff --git a/.gitignore b/.gitignore index 8aea04b2..b33a6471 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ node_modules/ lib/ out/ out-test/ +out-esbuild/ +out-esbuild-test/ .nyc_output/ Makefile.gyp *.Makefile diff --git a/.vscode/settings.json b/.vscode/settings.json index af3cc208..20356fd5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,10 +7,14 @@ "mochaExplorer.envPath": ".mocha.env", "mochaExplorer.files": [ "out/**/*.test.js", - "addons/**/out/*.test.js" + "addons/**/out/*.test.js", + "out-*/**/*.test.js", + "addons/**/out-*/*.test.js" ], "mochaExplorer.watch": [ "out/**/*.js", - "addons/**/out/*.js" + "addons/**/out/*.js", + "out-*/**/*.js", + "addons/**/out-*/*.js" ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 89a811b7..1681bb8d 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,7 +7,66 @@ "panel": "dedicated", "showReuseMessage": true }, - "tasks": [ + "tasks": [// Compound tasks + { + "label": "Development", + "dependsOn": ["demo-server", "tsc", "esbuild", "esbuild-demo"], + "group": { + "kind": "build", + "isDefault": true + } + }, + + // Demo + { + "label": "demo-server", + "type": "npm", + "script": "start", + "group": "build", + "isBackground": true, + "problemMatcher": [], + "presentation": { + "group": "xterm-demo" + } + }, + + // Build + { + "label": "tsc", + "type": "npm", + "script": "tsc-watch", + "group": "build", + "isBackground": true, + "problemMatcher": "$tsc-watch", + "presentation": { + "group": "xterm-build" + } + }, + { + "label": "esbuild", + "type": "npm", + "script": "esbuild-watch", + "group": "build", + "isBackground": true, + "problemMatcher": "$esbuild-watch", + "presentation": { + "group": "xterm-build" + } + }, + { + "label": "esbuild-demo", + "type": "npm", + "script": "esbuild-demo-watch", + "dependsOn": ["esbuild", "tsc"], + "group": "build", + "isBackground": true, + "problemMatcher": "$esbuild-watch", + "presentation": { + "group": "xterm-demo" + } + }, + + // Test { "type": "npm", "script": "test", @@ -16,59 +75,6 @@ "isDefault": true }, "problemMatcher": [] - }, - { - "label": "watch", - "type": "npm", - "script": "watch", - "group": "build", - "isBackground": true, - "problemMatcher": "$tsc-watch", - "presentation": { - "group": "vscode" - } - }, - { - "label": "start", - "type": "npm", - "script": "start", - "group": "build", - "isBackground": true, - "problemMatcher": [], - "presentation": { - "group": "vscode" - } - }, - { - "label": "Start demo", - "dependsOn": ["start", "watch"], - "group": { - "kind": "build", - "isDefault": true - }, - "isBackground": true, - "problemMatcher": { - "owner": "typescript", - "fileLocation": [ - "relative", - "${workspaceFolder}" - ], - "pattern": [ - { - "regexp": "^([^\\\\s].*)\\\\((\\\\d+,\\\\d+)\\\\):\\\\s*(.*)$", - "file": 1, - "location": 2, - "message": 3 - } - ], - "background": { - "beginsPattern": "assets by", - "endsPattern": "webpack \\d+\\.\\d+\\.\\d+ compiled successfully" - } - }, - "presentation": { - "group": "vscode" - } } ] } diff --git a/addons/addon-attach/package.json b/addons/addon-attach/package.json index 3a73b384..6f0c32b7 100644 --- a/addons/addon-attach/package.json +++ b/addons/addon-attach/package.json @@ -19,7 +19,7 @@ "prepackage": "npm run build", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only" + "start": "node ../../demo/start" }, "peerDependencies": { "@xterm/xterm": "^5.0.0" diff --git a/addons/addon-attach/test/playwright.config.ts b/addons/addon-attach/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-attach/test/playwright.config.ts +++ b/addons/addon-attach/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-canvas/package.json b/addons/addon-canvas/package.json index 2ca5d163..cb5ded7c 100644 --- a/addons/addon-canvas/package.json +++ b/addons/addon-canvas/package.json @@ -20,7 +20,7 @@ "prepackage": "npm run build", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only" + "start": "node ../../demo/start" }, "peerDependencies": { "@xterm/xterm": "^5.0.0" diff --git a/addons/addon-canvas/test/playwright.config.ts b/addons/addon-canvas/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-canvas/test/playwright.config.ts +++ b/addons/addon-canvas/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-clipboard/package.json b/addons/addon-clipboard/package.json index ef6c46f6..8ecdd6af 100644 --- a/addons/addon-clipboard/package.json +++ b/addons/addon-clipboard/package.json @@ -19,7 +19,7 @@ "prepackage": "npm run build", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only" + "start": "node ../../demo/start" }, "peerDependencies": { "@xterm/xterm": "^5.4.0" diff --git a/addons/addon-clipboard/test/playwright.config.ts b/addons/addon-clipboard/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-clipboard/test/playwright.config.ts +++ b/addons/addon-clipboard/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-fit/package.json b/addons/addon-fit/package.json index 561283a2..14d65f30 100644 --- a/addons/addon-fit/package.json +++ b/addons/addon-fit/package.json @@ -19,7 +19,7 @@ "prepackage": "npm run build", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only" + "start": "node ../../demo/start" }, "peerDependencies": { "@xterm/xterm": "^5.0.0" diff --git a/addons/addon-fit/test/playwright.config.ts b/addons/addon-fit/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-fit/test/playwright.config.ts +++ b/addons/addon-fit/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-image/package.json b/addons/addon-image/package.json index 19e56f94..2ea80c65 100644 --- a/addons/addon-image/package.json +++ b/addons/addon-image/package.json @@ -20,7 +20,7 @@ "prepackage": "../../node_modules/.bin/tsc -p .", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only" + "start": "node ../../demo/start" }, "peerDependencies": { "@xterm/xterm": "^5.2.0" diff --git a/addons/addon-image/test/playwright.config.ts b/addons/addon-image/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-image/test/playwright.config.ts +++ b/addons/addon-image/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-search/package.json b/addons/addon-search/package.json index d43699aa..91dfef2e 100644 --- a/addons/addon-search/package.json +++ b/addons/addon-search/package.json @@ -18,7 +18,7 @@ "prepackage": "../../node_modules/.bin/tsc -p .", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only" + "start": "node ../../demo/start" }, "peerDependencies": { "@xterm/xterm": "^5.0.0" diff --git a/addons/addon-search/test/playwright.config.ts b/addons/addon-search/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-search/test/playwright.config.ts +++ b/addons/addon-search/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-serialize/package.json b/addons/addon-serialize/package.json index d07b898b..3901addc 100644 --- a/addons/addon-serialize/package.json +++ b/addons/addon-serialize/package.json @@ -19,7 +19,7 @@ "prepackage": "npm run build", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only", + "start": "node ../../demo/start", "benchmark": "NODE_PATH=../../out:./out:./out-benchmark/ ../../node_modules/.bin/xterm-benchmark -r 5 -c benchmark/benchmark.json", "benchmark-baseline": "NODE_PATH=../../out:./out:./out-benchmark/ ../../node_modules/.bin/xterm-benchmark -r 5 -c benchmark/benchmark.json --baseline out-benchmark/benchmark/*benchmark.js", "benchmark-eval": "NODE_PATH=../../out:./out:./out-benchmark/ ../../node_modules/.bin/xterm-benchmark -r 5 -c benchmark/benchmark.json --eval out-benchmark/benchmark/*benchmark.js" diff --git a/addons/addon-serialize/src/SerializeAddon.ts b/addons/addon-serialize/src/SerializeAddon.ts index cd15cfc3..6f1d5d43 100644 --- a/addons/addon-serialize/src/SerializeAddon.ts +++ b/addons/addon-serialize/src/SerializeAddon.ts @@ -7,8 +7,8 @@ import type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm'; import type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize'; -import { DEFAULT_ANSI_COLORS } from 'browser/services/ThemeService'; import { IAttributeData, IColor } from 'common/Types'; +import { DEFAULT_ANSI_COLORS } from 'browser/Types'; function constrain(value: number, low: number, high: number): number { return Math.max(low, Math.min(value, high)); diff --git a/addons/addon-serialize/test/playwright.config.ts b/addons/addon-serialize/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-serialize/test/playwright.config.ts +++ b/addons/addon-serialize/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-unicode-graphemes/benchmark/UnicodeGraphemeAddon.benchmark.ts b/addons/addon-unicode-graphemes/benchmark/UnicodeGraphemeAddon.benchmark.ts index f1acf8b3..7538b934 100644 --- a/addons/addon-unicode-graphemes/benchmark/UnicodeGraphemeAddon.benchmark.ts +++ b/addons/addon-unicode-graphemes/benchmark/UnicodeGraphemeAddon.benchmark.ts @@ -7,7 +7,7 @@ import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark'; import { spawn } from 'node-pty'; import { Utf8ToUtf32, stringFromCodePoint } from 'common/input/TextDecoder'; -import { Terminal } from 'browser/Terminal'; +import { CoreBrowserTerminal } from 'browser/CoreBrowserTerminal'; import { UnicodeGraphemeProvider } from 'UnicodeGraphemeProvider'; @@ -54,9 +54,9 @@ perfContext('Terminal: ls -lR /usr/lib', () => { }); perfContext('write/string/async', () => { - let terminal: Terminal; + let terminal: CoreBrowserTerminal; before(() => { - terminal = new Terminal({ cols: 80, rows: 25, scrollback: 1000 }); + terminal = new CoreBrowserTerminal({ cols: 80, rows: 25, scrollback: 1000 }); fakedAddonLoad(terminal); }); new ThroughputRuntimeCase('', async () => { @@ -66,9 +66,9 @@ perfContext('Terminal: ls -lR /usr/lib', () => { }); perfContext('write/Utf8/async', () => { - let terminal: Terminal; + let terminal: CoreBrowserTerminal; before(() => { - terminal = new Terminal({ cols: 80, rows: 25, scrollback: 1000 }); + terminal = new CoreBrowserTerminal({ cols: 80, rows: 25, scrollback: 1000 }); }); new ThroughputRuntimeCase('', async () => { await new Promise(res => terminal.write(content, res)); diff --git a/addons/addon-unicode-graphemes/package.json b/addons/addon-unicode-graphemes/package.json index e883d86b..193cdecd 100644 --- a/addons/addon-unicode-graphemes/package.json +++ b/addons/addon-unicode-graphemes/package.json @@ -19,7 +19,7 @@ "prepackage": "npm run build", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only", + "start": "node ../../demo/start", "benchmark": "NODE_PATH=../../out:./out:./out-benchmark/ ../../node_modules/.bin/xterm-benchmark -r 5 -c benchmark/benchmark.json out-benchmark/benchmark/*benchmark.js", "benchmark-baseline": "NODE_PATH=../../out:./out:./out-benchmark/ ../../node_modules/.bin/xterm-benchmark -r 5 -c benchmark/benchmark.json --baseline out-benchmark/benchmark/*benchmark.js", "benchmark-eval": "NODE_PATH=../../out:./out:./out-benchmark/ ../../node_modules/.bin/xterm-benchmark -r 5 -c benchmark/benchmark.json --eval out-benchmark/benchmark/*benchmark.js" diff --git a/addons/addon-unicode-graphemes/test/playwright.config.ts b/addons/addon-unicode-graphemes/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-unicode-graphemes/test/playwright.config.ts +++ b/addons/addon-unicode-graphemes/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-unicode11/package.json b/addons/addon-unicode11/package.json index ce8c3e25..0981702b 100644 --- a/addons/addon-unicode11/package.json +++ b/addons/addon-unicode11/package.json @@ -19,7 +19,7 @@ "prepackage": "npm run build", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only" + "start": "node ../../demo/start" }, "peerDependencies": { "@xterm/xterm": "^5.0.0" diff --git a/addons/addon-unicode11/test/playwright.config.ts b/addons/addon-unicode11/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-unicode11/test/playwright.config.ts +++ b/addons/addon-unicode11/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-web-links/package.json b/addons/addon-web-links/package.json index 148047ec..be5cf7c3 100644 --- a/addons/addon-web-links/package.json +++ b/addons/addon-web-links/package.json @@ -19,7 +19,7 @@ "prepackage": "npm run build", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only" + "start": "node ../../demo/start" }, "peerDependencies": { "@xterm/xterm": "^5.0.0" diff --git a/addons/addon-web-links/test/playwright.config.ts b/addons/addon-web-links/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-web-links/test/playwright.config.ts +++ b/addons/addon-web-links/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-webgl/package.json b/addons/addon-webgl/package.json index da37eb26..6c91daf9 100644 --- a/addons/addon-webgl/package.json +++ b/addons/addon-webgl/package.json @@ -20,7 +20,7 @@ "prepackage": "npm run build", "package": "../../node_modules/.bin/webpack", "prepublishOnly": "npm run package", - "start-server-only": "node ../../demo/start-server-only" + "start": "node ../../demo/start" }, "peerDependencies": { "@xterm/xterm": "^5.0.0" diff --git a/addons/addon-webgl/test/playwright.config.ts b/addons/addon-webgl/test/playwright.config.ts index 79cf9f02..22834be1 100644 --- a/addons/addon-webgl/test/playwright.config.ts +++ b/addons/addon-webgl/test/playwright.config.ts @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = { ], reporter: 'list', webServer: { - command: 'npm run start-server-only', + command: 'npm run start', port: 3000, timeout: 120000, reuseExistingServer: !process.env.CI diff --git a/addons/addon-webgl/typings/addon-webgl.d.ts b/addons/addon-webgl/typings/addon-webgl.d.ts index 8c560421..6efa709e 100644 --- a/addons/addon-webgl/typings/addon-webgl.d.ts +++ b/addons/addon-webgl/typings/addon-webgl.d.ts @@ -27,6 +27,11 @@ declare module '@xterm/addon-webgl' { */ public readonly onAddTextureAtlasCanvas: IEvent; + /** + * An event that is fired when the a page is removed from the texture atlas. + */ + public readonly onRemoveTextureAtlasCanvas: IEvent; + constructor(preserveDrawingBuffer?: boolean); /** diff --git a/bin/esbuild.mjs b/bin/esbuild.mjs new file mode 100644 index 00000000..38638841 --- /dev/null +++ b/bin/esbuild.mjs @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2023 The xterm.js authors. All rights reserved. + * @license MIT + */ + +// @ts-check + +import { build, context, default as esbuild } from 'esbuild'; +import { argv } from 'process'; + +const config = { + isProd: argv.includes('--prod'), + isWatch: argv.includes('--watch'), + isDemoClient: argv.includes('--demo-client'), + addon: argv.find(e => e.startsWith('--addon='))?.replace(/^--addon=/, ''), +}; + +// console.info('Running with config:', JSON.stringify(config, undefined, 2)); + +/** @type {esbuild.BuildOptions} */ +const commonOptions = { + format: 'esm', + target: 'es2021', + logLevel: 'debug', +}; + +/** @type {esbuild.BuildOptions} */ +const devOptions = { + sourcemap: true, + minify: false, +}; + +/** @type {esbuild.BuildOptions} */ +const prodOptions = { + minify: true, + treeShaking: true, + logLevel: 'debug', + legalComments: 'none', + // TODO: Mangling private and protected properties will reduce bundle size quite a bit, we must + // make sure we don't cast privates to `any` in order to prevent regressions. + //mangleProps: /_.+/, + banner: { + js: `/** + * Copyright (c) 2014-2024 The xterm.js authors. All rights reserved. + * @license MIT + * + * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) + * @license MIT + * + * Originally forked from (with the author's permission): + * Fabrice Bellard's javascript vt100 for jslinux: + * http://bellard.org/jslinux/ + * Copyright (c) 2011 Fabrice Bellard + */ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/` + } + // mangleProps: /_.+/, +}; + +/** + * @param {string} addon + */ +function getAddonEntryPoint(addon) { + let result = ''; + let nextCap = true; + for (const char of addon) { + if (char === '-') { + nextCap = true; + continue; + } + result += nextCap ? char.toUpperCase() : char + nextCap = false; + } + result += 'Addon'; + return result; +} + +/** @type {esbuild.BuildOptions} */ +let bundleConfig = { + bundle: true, + ...commonOptions, + ...(config.isProd ? prodOptions : devOptions) +}; + +/** @type {esbuild.BuildOptions} */ +let outConfig = { + format: 'cjs' +} +let skipOut = false; + +/** @type {esbuild.BuildOptions} */ +let outTestConfig = { + format: 'cjs' +} +let skipOutTest = false; + +if (config.addon) { + bundleConfig = { + ...bundleConfig, + entryPoints: [`addons/addon-${config.addon}/src/${getAddonEntryPoint(config.addon)}.ts`], + outfile: `addons/addon-${config.addon}/lib/xterm-addon-${config.addon}.js`, + }; + outConfig = { + ...outConfig, + entryPoints: [`addons/addon-${config.addon}/src/**/*.ts`], + outdir: `addons/addon-${config.addon}/out-esbuild/` + }; + outTestConfig = { + ...outConfig, + entryPoints: [`addons/addon-${config.addon}/test/**/*.ts`], + outdir: `addons/addon-${config.addon}/out-esbuild-test/` + }; + + if (config.addon === 'ligatures') { + bundleConfig.platform = 'node'; + } + + if (config.addon === 'serialize') { + bundleConfig.tsconfig = 'addons/addon-serialize/src/tsconfig.json' + } + + // Addons that don't have unit tests + if (['ligatures'].includes(config.addon)) { + skipOutTest = true; + } + + // TODO: Fix these + if (config.addon === 'image') { + skipOut = true; + skipOutTest = true; + } +} else { + bundleConfig = { + ...bundleConfig, + entryPoints: [`src/browser/public/Terminal.ts`], + outfile: `lib/xterm.js` + }; + outConfig = { + ...outConfig, + entryPoints: ['src/**/*.ts'], + outdir: 'out-esbuild/' + }; + outTestConfig = { + ...outConfig, + entryPoints: ['test/**/*.ts'], + outdir: 'out-esbuild-test/' + }; +} + +if (config.isDemoClient) { + bundleConfig = { + ...bundleConfig, + entryPoints: [`demo/client.ts`], + outfile: 'demo/dist/client-bundle.js', + external: ['util', 'os', 'fs', 'path', 'stream', 'Terminal'], + alias: { + "@xterm/xterm": ".", + "@xterm/addon-attach": "./addons/addon-attach/lib/xterm-addon-attach.js", + "@xterm/addon-canvas": "./addons/addon-canvas/lib/xterm-addon-canvas.js", + "@xterm/addon-clipboard": "./addons/addon-clipboard/lib/xterm-addon-clipboard.js", + "@xterm/addon-fit": "./addons/addon-fit/lib/xterm-addon-fit.js", + // "@xterm/addon-image": "./addons/addon-image/lib/xterm-addon-image.js", + // "@xterm/addon-ligatures": "./addons/addon-ligatures/lib/xterm-addon-ligatures.js", + "@xterm/addon-search": "./addons/addon-search/lib/xterm-addon-search.js", + "@xterm/addon-serialize": "./addons/addon-serialize/lib/xterm-addon-serialize.js", + "@xterm/addon-web-links": "./addons/addon-web-links/lib/xterm-addon-web-links.js", + "@xterm/addon-webgl": "./addons/addon-webgl/lib/xterm-addon-webgl.js", + "@xterm/addon-unicode11": "./addons/addon-unicode11/lib/xterm-addon-unicode11.js", + "@xterm/addon-unicode-graphemes": "./addons/addon-unicode-graphemes/lib/xterm-addon-unicode-graphemes.js", + + // Needed for out-tsc based image addon + "common/Lifecycle": "./src/common/Lifecycle.ts", + } + } +}; + +if (config.isWatch) { + // TODO: This doesn't report errors? + context(bundleConfig).then(e => e.watch()); + if (!skipOut) { + context(outConfig).then(e => e.watch()); + } + if (!skipOutTest) { + context(outTestConfig).then(e => e.watch()); + } +} else { + await build(bundleConfig); + if (!skipOut) { + await build(outConfig); + } + if (!skipOutTest) { + await build(outTestConfig); + } +} diff --git a/bin/esbuild_all.mjs b/bin/esbuild_all.mjs new file mode 100644 index 00000000..c2d6ba72 --- /dev/null +++ b/bin/esbuild_all.mjs @@ -0,0 +1,55 @@ +// @ts-check + +import { spawn } from "child_process"; +import { readdir } from "fs/promises"; +import { argv } from "process"; + +/** @type {{cp: import("child_process").ChildProcessByStdio, name: string}[]} */ +const jobs = []; + +// Core job +jobs.push(createJob('xterm', [])); + +// Addon jobs +const addons = (await readdir('addons')).map(e => e.replace('addon-', '')); +for (const addon of addons) { + if (addon !== 'image') { + jobs.push(createJob(`xterm-addon-${addon}`, [`--addon=${addon}`])); + } +} + +// Demo job - This requires the others to be built so it's not included when building all +// jobs.push(createJob('demo-client', [`--demo-client`])); + +await Promise.all(jobs.map((job, i) => { + return new Promise(r => { + job.cp.on('exit', code => { + log(`Finished \x1b[32m${job.name}\x1b[0m${code ? ' \x1b[31mwith errors\x1b[0m' : ''}`); + r(code); + }); + }); +})); + +/** + * @param {string} message + */ +function log(message) { + console.info(`[\x1b[2m${new Date().toLocaleTimeString('en-GB')}\x1b[0m] ${message}`); +} + +/** + * @param {string} name + * @param {string[]} extraArgs + */ +function createJob(name, extraArgs) { + log(`Starting \x1b[32m${name}\x1b[0m...`); + const args = [ + 'bin/esbuild.mjs', + ...extraArgs, + ...argv + ]; + return { + name, + cp: spawn('node', args, { stdio: ["inherit", "inherit", "inherit"] }) + }; +} diff --git a/demo/client.ts b/demo/client.ts index 4df15eb5..6cd0e1bc 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -8,21 +8,11 @@ /// -// Use tsc version (yarn watch) -import { Terminal } from '../out/browser/public/Terminal'; -import { AttachAddon } from '../addons/addon-attach/out/AttachAddon'; -import { CanvasAddon } from '../addons/addon-canvas/out/CanvasAddon'; -import { ClipboardAddon } from '../addons/addon-clipboard/out/ClipboardAddon'; -import { FitAddon } from '../addons/addon-fit/out/FitAddon'; -import { SearchAddon, ISearchOptions } from '../addons/addon-search/out/SearchAddon'; -import { SerializeAddon } from '../addons/addon-serialize/out/SerializeAddon'; -import { WebLinksAddon } from '../addons/addon-web-links/out/WebLinksAddon'; -import { WebglAddon } from '../addons/addon-webgl/out/WebglAddon'; -import { Unicode11Addon } from '../addons/addon-unicode11/out/Unicode11Addon'; -import { UnicodeGraphemesAddon } from '../addons/addon-unicode-graphemes/out/UnicodeGraphemesAddon'; -import { LigaturesAddon } from '../addons/addon-ligatures/out/LigaturesAddon'; +// TODO: Move to regular import? +import { LigaturesAddon } from '../addons/addon-ligatures/out-esbuild/LigaturesAddon'; -// Playwright/WebKit on Windows does not support WebAssembly https://stackoverflow.com/q/62311688/1156119 +// DEBT: The image addon is not currently build with esbuild +// HACK: Playwright/WebKit on Windows does not support WebAssembly https://stackoverflow.com/q/62311688/1156119 import type { ImageAddonType, IImageAddonOptions } from '../addons/addon-image/out/ImageAddon'; let ImageAddon: ImageAddonType | undefined; // eslint-disable-line @typescript-eslint/naming-convention if ('WebAssembly' in window) { @@ -30,32 +20,28 @@ if ('WebAssembly' in window) { ImageAddon = imageAddon.ImageAddon; } -// Use webpacked version (yarn package) -// import { Terminal } from '../lib/xterm'; -// import { AttachAddon } from '@xterm/addon-attach'; -// import { ClipboardAddon } from '@xterm/addon-clipboard'; -// import { FitAddon } from '@xterm/addon-fit'; +import { Terminal as TerminalCtor, ITerminalOptions, type IDisposable } from '@xterm/xterm'; +import { AttachAddon } from '@xterm/addon-attach'; +import { CanvasAddon } from '@xterm/addon-canvas'; +import { ClipboardAddon } from '@xterm/addon-clipboard'; +import { FitAddon } from '@xterm/addon-fit'; // import { ImageAddon } from '@xterm/addon-image'; -// import { SearchAddon, ISearchOptions } from '@xterm/addon-search'; -// import { SerializeAddon } from '@xterm/addon-serialize'; -// import { WebLinksAddon } from '@xterm/addon-web-links'; -// import { WebglAddon } from '@@xterm/addon-webgl'; -// import { Unicode11Addon } from '@xterm/addon-unicode11'; -// import { UnicodeGraphemesAddon } from '@xterm/addon-unicode-graphemes'; // import { LigaturesAddon } from '@xterm/addon-ligatures'; - -// Pulling in the module's types relies on the above, it's looks a -// little weird here as we're importing "this" module -import { Terminal as TerminalType, ITerminalOptions, type IDisposable } from '@xterm/xterm'; +import { SearchAddon, ISearchOptions } from '@xterm/addon-search'; +import { SerializeAddon } from '@xterm/addon-serialize'; +import { WebLinksAddon } from '@xterm/addon-web-links'; +import { WebglAddon } from '@xterm/addon-webgl'; +import { Unicode11Addon } from '@xterm/addon-unicode11'; +import { UnicodeGraphemesAddon } from '@xterm/addon-unicode-graphemes'; export interface IWindowWithTerminal extends Window { - term: TerminalType; - Terminal?: typeof TerminalType; // eslint-disable-line @typescript-eslint/naming-convention + term: TerminalCtor; + Terminal: typeof TerminalCtor; AttachAddon?: typeof AttachAddon; // eslint-disable-line @typescript-eslint/naming-convention CanvasAddon?: typeof CanvasAddon; // eslint-disable-line @typescript-eslint/naming-convention ClipboardAddon?: typeof ClipboardAddon; // eslint-disable-line @typescript-eslint/naming-convention FitAddon?: typeof FitAddon; // eslint-disable-line @typescript-eslint/naming-convention - ImageAddon?: typeof ImageAddonType; // eslint-disable-line @typescript-eslint/naming-convention + ImageAddon?: typeof ImageAddon; // eslint-disable-line @typescript-eslint/naming-convention SearchAddon?: typeof SearchAddon; // eslint-disable-line @typescript-eslint/naming-convention SerializeAddon?: typeof SerializeAddon; // eslint-disable-line @typescript-eslint/naming-convention WebLinksAddon?: typeof WebLinksAddon; // eslint-disable-line @typescript-eslint/naming-convention @@ -84,13 +70,14 @@ interface IDemoAddon { T extends 'clipboard' ? typeof ClipboardAddon : T extends 'fit' ? typeof FitAddon : T extends 'image' ? typeof ImageAddonType : - T extends 'search' ? typeof SearchAddon : - T extends 'serialize' ? typeof SerializeAddon : - T extends 'webLinks' ? typeof WebLinksAddon : - T extends 'unicode11' ? typeof Unicode11Addon : - T extends 'unicodeGraphemes' ? typeof UnicodeGraphemesAddon : - T extends 'ligatures' ? typeof LigaturesAddon : - typeof WebglAddon + T extends 'ligatures' ? typeof LigaturesAddon : + T extends 'search' ? typeof SearchAddon : + T extends 'serialize' ? typeof SerializeAddon : + T extends 'webLinks' ? typeof WebLinksAddon : + T extends 'unicode11' ? typeof Unicode11Addon : + T extends 'unicodeGraphemes' ? typeof UnicodeGraphemesAddon : + T extends 'webgl' ? typeof WebglAddon : + never ); instance?: ( T extends 'attach' ? AttachAddon : @@ -98,13 +85,13 @@ interface IDemoAddon { T extends 'clipboard' ? ClipboardAddon : T extends 'fit' ? FitAddon : T extends 'image' ? ImageAddonType : - T extends 'search' ? SearchAddon : - T extends 'serialize' ? SerializeAddon : - T extends 'webLinks' ? WebLinksAddon : - T extends 'webgl' ? WebglAddon : - T extends 'unicode11' ? typeof Unicode11Addon : - T extends 'unicodeGraphemes' ? typeof UnicodeGraphemesAddon : - T extends 'ligatures' ? typeof LigaturesAddon : + T extends 'ligatures' ? LigaturesAddon : + T extends 'search' ? SearchAddon : + T extends 'serialize' ? SerializeAddon : + T extends 'webLinks' ? WebLinksAddon : + T extends 'unicode11' ? Unicode11Addon : + T extends 'unicodeGraphemes' ? UnicodeGraphemesAddon : + T extends 'webgl' ? WebglAddon : never ); } @@ -232,7 +219,7 @@ const createNewWindowButtonHandler: () => void = () => { }; if (document.location.pathname === '/test') { - window.Terminal = Terminal; + window.Terminal = TerminalCtor; window.AttachAddon = AttachAddon; window.CanvasAddon = CanvasAddon; window.ClipboardAddon = ClipboardAddon; @@ -278,7 +265,7 @@ function createTerminal(): void { } const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0; - term = new Terminal({ + term = new TerminalCtor({ allowProposedApi: true, windowsPty: isWindows ? { // In a real scenario, these values should be verified on the backend @@ -290,7 +277,7 @@ function createTerminal(): void { } as ITerminalOptions); // Load addons - const typedTerm = term as TerminalType; + const typedTerm = term as TerminalCtor; addons.search.instance = new SearchAddon(); addons.serialize.instance = new SerializeAddon(); addons.fit.instance = new FitAddon(); @@ -443,7 +430,7 @@ function runFakeTerminal(): void { }); } -function initOptions(term: TerminalType): void { +function initOptions(term: TerminalCtor): void { const blacklistedOptions = [ // Internal only options 'cancelEvents', @@ -619,7 +606,7 @@ function initOptions(term: TerminalType): void { }); } -function initAddons(term: TerminalType): void { +function initAddons(term: TerminalCtor): void { const fragment = document.createDocumentFragment(); Object.keys(addons).forEach((name: AddonType) => { const addon = addons[name]; @@ -1190,7 +1177,7 @@ function decorationStressTest(): void { } decorationStressTestDecorations = undefined; } else { - const t = term as Terminal; + const t = term as TerminalCtor; const buffer = t.buffer.active; const cursorY = buffer.baseY + buffer.cursorY; decorationStressTestDecorations = []; diff --git a/demo/start-server-only.js b/demo/start-server-only.js deleted file mode 100644 index b240966f..00000000 --- a/demo/start-server-only.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copyright (c) 2018 The xterm.js authors. All rights reserved. - * @license MIT - */ - -// @ts-check - -const startServer = require('./server.js'); - -startServer(); diff --git a/demo/start.js b/demo/start.js index c0037545..b240966f 100644 --- a/demo/start.js +++ b/demo/start.js @@ -5,22 +5,6 @@ // @ts-check -const clientConfig = require('./webpack.config'); -const webpack = require('webpack'); const startServer = require('./server.js'); startServer(); - -const compiler = webpack(clientConfig); - -compiler.watch({ - aggregateTimeout: 300, - poll: undefined -}, (err, stats) => { - if (err) { - console.error(err); - } - console.log(stats?.toString({ - colors: true - })); -}); diff --git a/demo/tsconfig.json b/demo/tsconfig.json index 4114f6d6..1d632e8f 100644 --- a/demo/tsconfig.json +++ b/demo/tsconfig.json @@ -6,14 +6,18 @@ "sourceMap": true, "baseUrl": ".", "paths": { - "addon-attach": ["../addons/addon-attach"], - "addon-clipboard": ["../addons/addon-clipboard"], - "addon-fit": ["../addons/addon-fit"], - "addon-image": ["../addons/addon-image"], - "addon-search": ["../addons/addon-search"], - "addon-serialize": ["../addons/addon-serialize"], - "addon-web-links": ["../addons/addon-web-links"], - "addon-webgl": ["../addons/addon-webgl"] + "@xterm/addon-attach": ["../addons/addon-attach"], + "@xterm/addon-canvas": ["../addons/addon-canvas"], + "@xterm/addon-clipboard": ["../addons/addon-clipboard"], + "@xterm/addon-fit": ["../addons/addon-fit"], + "@xterm/addon-image": ["../addons/addon-image"], + "@xterm/addon-search": ["../addons/addon-search"], + "@xterm/addon-serialize": ["../addons/addon-serialize"], + "@xterm/addon-web-links": ["../addons/addon-web-links"], + "@xterm/addon-webgl": ["../addons/addon-webgl"], + "@xterm/addon-unicode11": ["../addons/addon-unicode11"], + "@xterm/addon-unicode-graphemes": ["../addons/addon-unicode-graphemes"], + "@xterm/addon-ligatures": ["../addons/addon-ligatures"] } }, "include": [ diff --git a/package.json b/package.json index 4790fc43..5174f39e 100644 --- a/package.json +++ b/package.json @@ -23,36 +23,58 @@ "xterm" ], "scripts": { - "prepackage": "npm run build", - "package": "webpack", - "package-headless": "webpack --config ./webpack.config.headless.js", - "postpackage-headless": "node ./bin/package_headless.js", + "setup": "npm run build", + "presetup": "npm run install-addons", + "install-addons": "node ./bin/install-addons.js", + "start": "node demo/start", - "start-server-only": "node demo/start-server-only", "build-demo": "webpack --config ./demo/webpack.config.js", - "lint": "eslint -c .eslintrc.json --max-warnings 0 --ext .ts src/ addons/", - "lint-api": "eslint --no-eslintrc -c .eslintrc.json.typings --max-warnings 0 --no-ignore --ext .d.ts typings/", + + "build": "npm run tsc", + "watch": "npm run tsc-watch", + "tsc": "tsc -b ./tsconfig.all.json", + "tsc-watch": "tsc -b -w ./tsconfig.all.json --preserveWatchOutput", + + "esbuild": "node bin/esbuild_all.mjs", + "esbuild-watch": "node bin/esbuild_all.mjs --watch", + "esbuild-package": "node bin/esbuild_all.mjs --prod", + "esbuild-package-watch": "node bin/esbuild_all.mjs --prod --watch", + "esbuild-demo": "node bin/esbuild.mjs --demo-client", + "esbuild-demo-watch": "node bin/esbuild.mjs --demo-client --watch", + "test": "npm run test-unit", "posttest": "npm run lint", + + "lint": "eslint -c .eslintrc.json --max-warnings 0 --ext .ts src/ addons/", + "lint-api": "eslint --no-eslintrc -c .eslintrc.json.typings --max-warnings 0 --no-ignore --ext .d.ts typings/", + + "test-unit": "node ./bin/test.js", + "test-unit-coverage": "node ./bin/test.js --coverage", + "test-unit-dev": "cross-env NODE_PATH='./out' mocha", + + "test-api": "npm run test-api-chromium", + "test-api-chromium": "node ./bin/test_api.js --browser=chromium --timeout=20000", + "test-api-firefox": "node ./bin/test_api.js --browser=firefox --timeout=20000", + "test-api-webkit": "node ./bin/test_api.js --browser=webkit --timeout=20000", + "test-integration": "node ./bin/test_playwright.js --workers=75%", "test-integration-chromium": "node ./bin/test_playwright.js --workers=75% \"--project=ChromeStable\"", "test-integration-firefox": "node ./bin/test_playwright.js --workers=75% \"--project=FirefoxStable\"", "test-integration-webkit": "node ./bin/test_playwright.js --workers=75% \"--project=WebKit\"", "test-integration-debug": "node ./bin/test_playwright.js --workers=1 --headed --timeout=30000", - "test-unit": "node ./bin/test.js", - "test-unit-coverage": "node ./bin/test.js --coverage", - "test-unit-dev": "cross-env NODE_PATH='./out' mocha", - "build": "tsc -b ./tsconfig.all.json", - "install-addons": "node ./bin/install-addons.js", - "presetup": "npm run install-addons", - "setup": "npm run build", - "prepublishOnly": "npm run package", - "watch": "tsc -b -w ./tsconfig.all.json --preserveWatchOutput", + "benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json", - "benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark/test/benchmark/*benchmark.js", - "benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark/test/benchmark/*benchmark.js", + "benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-tsc/test-benchmark/test/benchmark/*benchmark.js", + "benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-tsc/test-benchmark/test/benchmark/*benchmark.js", + "clean": "rm -rf lib out addons/*/lib addons/*/out", - "vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts" + "vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts", + + "prepackage": "npm run build", + "package": "webpack", + "package-headless": "webpack --config ./webpack.config.headless.js", + "postpackage-headless": "node ./bin/package_headless.js", + "prepublishOnly": "npm run package" }, "devDependencies": { "@lunapaint/png-codec": "^0.2.0", @@ -75,6 +97,7 @@ "chai": "^4.3.4", "cross-env": "^7.0.3", "deep-equal": "^2.0.5", + "esbuild": "^0.23.0", "eslint": "^8.56.0", "eslint-plugin-jsdoc": "^46.9.1", "express": "^4.19.2", diff --git a/src/browser/Terminal.ts b/src/browser/CoreBrowserTerminal.ts similarity index 99% rename from src/browser/Terminal.ts rename to src/browser/CoreBrowserTerminal.ts index 0e945aa9..6d684953 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/CoreBrowserTerminal.ts @@ -59,7 +59,7 @@ import { WindowsOptionsReportType } from '../common/InputHandler'; import { AccessibilityManager } from './AccessibilityManager'; import { LinkProviderService } from 'browser/services/LinkProviderService'; -export class Terminal extends CoreTerminal implements ITerminal { +export class CoreBrowserTerminal extends CoreTerminal implements ITerminal { public textarea: HTMLTextAreaElement | undefined; public element: HTMLElement | undefined; public screenElement: HTMLElement | undefined; diff --git a/src/browser/Terminal2.test.ts b/src/browser/Terminal2.test.ts index abbb42d3..8401ba78 100644 --- a/src/browser/Terminal2.test.ts +++ b/src/browser/Terminal2.test.ts @@ -8,7 +8,7 @@ import * as path from 'path'; import * as os from 'os'; import * as fs from 'fs'; import * as pty from 'node-pty'; -import { Terminal } from 'browser/Terminal'; +import { CoreBrowserTerminal } from 'browser/CoreBrowserTerminal'; import { IDisposable } from '@xterm/xterm'; // all test files expect terminal in 80x25 @@ -40,7 +40,7 @@ describe('Escape Sequence Files', function(): void { let ptyTerm: any; let slaveEnd: any; - let term: Terminal; + let term: CoreBrowserTerminal; let customHandler: IDisposable | undefined; before(() => { @@ -49,7 +49,7 @@ describe('Escape Sequence Files', function(): void { } ptyTerm = (pty as any).open({cols: COLS, rows: ROWS}); slaveEnd = ptyTerm._slave; - term = new Terminal({cols: COLS, rows: ROWS}); + term = new CoreBrowserTerminal({cols: COLS, rows: ROWS}); ptyTerm._master.on('data', (data: string) => term.write(data)); }); @@ -121,7 +121,7 @@ function formatError(input: string, output: string, expected: string): string { } // simple debug output of terminal cells -function terminalToString(term: Terminal): string { +function terminalToString(term: CoreBrowserTerminal): string { let result = ''; let lineText = ''; for (let line = term.buffer.ybase; line < term.buffer.ybase + term.rows; line++) { diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index c7c8438c..45af130f 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -12,7 +12,7 @@ import { IBuffer, IBufferSet } from 'common/buffer/Types'; import { IBufferLine, ICellData, IAttributeData, ICircularList, XtermListener, ICharset, ITerminalOptions, ColorIndex } from 'common/Types'; import { Buffer } from 'common/buffer/Buffer'; import * as Browser from 'common/Platform'; -import { Terminal } from 'browser/Terminal'; +import { CoreBrowserTerminal } from 'browser/CoreBrowserTerminal'; import { IUnicodeService, IOptionsService, ICoreService, ICoreMouseService } from 'common/services/Services'; import { IFunctionIdentifier, IParams } from 'common/parser/Types'; import { AttributeData } from 'common/buffer/AttributeData'; @@ -20,7 +20,7 @@ import { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from import { css } from 'common/Color'; import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils'; -export class TestTerminal extends Terminal { +export class TestTerminal extends CoreBrowserTerminal { public get curAttrData(): IAttributeData { return (this as any)._inputHandler._curAttrData; } public keyDown(ev: any): boolean | undefined { return this._keyDown(ev); } public keyPress(ev: any): boolean { return this._keyPress(ev); } diff --git a/src/browser/Types.ts b/src/browser/Types.ts index 24f008a1..9ef9d3a8 100644 --- a/src/browser/Types.ts +++ b/src/browser/Types.ts @@ -7,6 +7,7 @@ import { IEvent } from 'common/EventEmitter'; import { CharData, IColor, ICoreTerminal, ITerminalOptions } from 'common/Types'; import { IBuffer } from 'common/buffer/Types'; import { IDisposable, Terminal as ITerminalApi } from '@xterm/xterm'; +import { channels, css } from 'common/Color'; /** * A portion of the public API that are implemented identially internally and simply passed through. @@ -172,3 +173,51 @@ export interface IRenderDebouncerWithCallback extends IRenderDebouncer { export interface IBufferElementProvider { provideBufferElements(): DocumentFragment | HTMLElement; } + +// An IIFE to generate DEFAULT_ANSI_COLORS. +export const DEFAULT_ANSI_COLORS = Object.freeze((() => { + const colors = [ + // dark: + css.toColor('#2e3436'), + css.toColor('#cc0000'), + css.toColor('#4e9a06'), + css.toColor('#c4a000'), + css.toColor('#3465a4'), + css.toColor('#75507b'), + css.toColor('#06989a'), + css.toColor('#d3d7cf'), + // bright: + css.toColor('#555753'), + css.toColor('#ef2929'), + css.toColor('#8ae234'), + css.toColor('#fce94f'), + css.toColor('#729fcf'), + css.toColor('#ad7fa8'), + css.toColor('#34e2e2'), + css.toColor('#eeeeec') + ]; + + // Fill in the remaining 240 ANSI colors. + // Generate colors (16-231) + const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; + for (let i = 0; i < 216; i++) { + const r = v[(i / 36) % 6 | 0]; + const g = v[(i / 6) % 6 | 0]; + const b = v[i % 6]; + colors.push({ + css: channels.toCss(r, g, b), + rgba: channels.toRgba(r, g, b) + }); + } + + // Generate greys (232-255) + for (let i = 0; i < 24; i++) { + const c = 8 + i * 10; + colors.push({ + css: channels.toCss(c, c, c), + rgba: channels.toRgba(c, c, c) + }); + } + + return colors; +})()); diff --git a/src/browser/public/Terminal.ts b/src/browser/public/Terminal.ts index 56edbc50..cb4f221e 100644 --- a/src/browser/public/Terminal.ts +++ b/src/browser/public/Terminal.ts @@ -4,7 +4,7 @@ */ import * as Strings from 'browser/LocalizableStrings'; -import { Terminal as TerminalCore } from 'browser/Terminal'; +import { CoreBrowserTerminal as TerminalCore } from 'browser/CoreBrowserTerminal'; import { IBufferRange, ITerminal } from 'browser/Types'; import { IEvent } from 'common/EventEmitter'; import { Disposable } from 'common/Lifecycle'; diff --git a/src/browser/services/ThemeService.test.ts b/src/browser/services/ThemeService.test.ts index cdfa87df..a36dea31 100644 --- a/src/browser/services/ThemeService.test.ts +++ b/src/browser/services/ThemeService.test.ts @@ -5,8 +5,9 @@ import jsdom = require('jsdom'); import { assert } from 'chai'; -import { ThemeService, DEFAULT_ANSI_COLORS } from 'browser/services/ThemeService'; +import { ThemeService } from 'browser/services/ThemeService'; import { OptionsService } from 'common/services/OptionsService'; +import { DEFAULT_ANSI_COLORS } from 'browser/Types'; describe('ThemeService', () => { let themeService: ThemeService; diff --git a/src/browser/services/ThemeService.ts b/src/browser/services/ThemeService.ts index 199b3ace..31b1192c 100644 --- a/src/browser/services/ThemeService.ts +++ b/src/browser/services/ThemeService.ts @@ -5,8 +5,8 @@ import { ColorContrastCache } from 'browser/ColorContrastCache'; import { IThemeService } from 'browser/services/Services'; -import { IColorContrastCache, IColorSet, ReadonlyColorSet } from 'browser/Types'; -import { channels, color, css, NULL_COLOR } from 'common/Color'; +import { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from 'browser/Types'; +import { color, css, NULL_COLOR } from 'common/Color'; import { EventEmitter } from 'common/EventEmitter'; import { Disposable } from 'common/Lifecycle'; import { IOptionsService, ITheme } from 'common/services/Services'; @@ -29,54 +29,6 @@ const DEFAULT_SELECTION = { rgba: 0xFFFFFF4D }; -// An IIFE to generate DEFAULT_ANSI_COLORS. -export const DEFAULT_ANSI_COLORS = Object.freeze((() => { - const colors = [ - // dark: - css.toColor('#2e3436'), - css.toColor('#cc0000'), - css.toColor('#4e9a06'), - css.toColor('#c4a000'), - css.toColor('#3465a4'), - css.toColor('#75507b'), - css.toColor('#06989a'), - css.toColor('#d3d7cf'), - // bright: - css.toColor('#555753'), - css.toColor('#ef2929'), - css.toColor('#8ae234'), - css.toColor('#fce94f'), - css.toColor('#729fcf'), - css.toColor('#ad7fa8'), - css.toColor('#34e2e2'), - css.toColor('#eeeeec') - ]; - - // Fill in the remaining 240 ANSI colors. - // Generate colors (16-231) - const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]; - for (let i = 0; i < 216; i++) { - const r = v[(i / 36) % 6 | 0]; - const g = v[(i / 6) % 6 | 0]; - const b = v[i % 6]; - colors.push({ - css: channels.toCss(r, g, b), - rgba: channels.toRgba(r, g, b) - }); - } - - // Generate greys (232-255) - for (let i = 0; i < 24; i++) { - const c = 8 + i * 10; - colors.push({ - css: channels.toCss(c, c, c), - rgba: channels.toRgba(c, c, c) - }); - } - - return colors; -})()); - export class ThemeService extends Disposable implements IThemeService { public serviceBrand: undefined; diff --git a/test/benchmark/Terminal.benchmark.ts b/test/benchmark/Terminal.benchmark.ts index d2b6ed8f..4944495b 100644 --- a/test/benchmark/Terminal.benchmark.ts +++ b/test/benchmark/Terminal.benchmark.ts @@ -7,7 +7,7 @@ import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark'; import { spawn } from 'node-pty'; import { Utf8ToUtf32, stringFromCodePoint } from 'common/input/TextDecoder'; -import { Terminal } from 'browser/Terminal'; +import { CoreBrowserTerminal } from 'browser/CoreBrowserTerminal'; perfContext('Terminal: ls -lR /usr/lib', () => { let content = ''; @@ -45,9 +45,9 @@ perfContext('Terminal: ls -lR /usr/lib', () => { }); perfContext('write/string/async', () => { - let terminal: Terminal; + let terminal: CoreBrowserTerminal; before(() => { - terminal = new Terminal({ cols: 80, rows: 25, scrollback: 1000 }); + terminal = new CoreBrowserTerminal({ cols: 80, rows: 25, scrollback: 1000 }); }); new ThroughputRuntimeCase('', async () => { await new Promise(res => terminal.write(content, res)); @@ -56,9 +56,9 @@ perfContext('Terminal: ls -lR /usr/lib', () => { }); perfContext('write/Utf8/async', () => { - let terminal: Terminal; + let terminal: CoreBrowserTerminal; before(() => { - terminal = new Terminal({ cols: 80, rows: 25, scrollback: 1000 }); + terminal = new CoreBrowserTerminal({ cols: 80, rows: 25, scrollback: 1000 }); }); new ThroughputRuntimeCase('', async () => { await new Promise(res => terminal.write(content, res)); diff --git a/yarn.lock b/yarn.lock index 4a8c5e7d..1422c7db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -274,6 +274,126 @@ esquery "^1.5.0" jsdoc-type-pratt-parser "~4.0.0" +"@esbuild/aix-ppc64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz#145b74d5e4a5223489cabdc238d8dad902df5259" + integrity sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ== + +"@esbuild/android-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz#453bbe079fc8d364d4c5545069e8260228559832" + integrity sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ== + +"@esbuild/android-arm@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.0.tgz#26c806853aa4a4f7e683e519cd9d68e201ebcf99" + integrity sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g== + +"@esbuild/android-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.0.tgz#1e51af9a6ac1f7143769f7ee58df5b274ed202e6" + integrity sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ== + +"@esbuild/darwin-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz#d996187a606c9534173ebd78c58098a44dd7ef9e" + integrity sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow== + +"@esbuild/darwin-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz#30c8f28a7ef4e32fe46501434ebe6b0912e9e86c" + integrity sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ== + +"@esbuild/freebsd-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz#30f4fcec8167c08a6e8af9fc14b66152232e7fb4" + integrity sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw== + +"@esbuild/freebsd-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz#1003a6668fe1f5d4439e6813e5b09a92981bc79d" + integrity sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ== + +"@esbuild/linux-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz#3b9a56abfb1410bb6c9138790f062587df3e6e3a" + integrity sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw== + +"@esbuild/linux-arm@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz#237a8548e3da2c48cd79ae339a588f03d1889aad" + integrity sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw== + +"@esbuild/linux-ia32@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz#4269cd19cb2de5de03a7ccfc8855dde3d284a238" + integrity sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA== + +"@esbuild/linux-loong64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz#82b568f5658a52580827cc891cb69d2cb4f86280" + integrity sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A== + +"@esbuild/linux-mips64el@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz#9a57386c926262ae9861c929a6023ed9d43f73e5" + integrity sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w== + +"@esbuild/linux-ppc64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz#f3a79fd636ba0c82285d227eb20ed8e31b4444f6" + integrity sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw== + +"@esbuild/linux-riscv64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz#f9d2ef8356ce6ce140f76029680558126b74c780" + integrity sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw== + +"@esbuild/linux-s390x@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz#45390f12e802201f38a0229e216a6aed4351dfe8" + integrity sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg== + +"@esbuild/linux-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz#c8409761996e3f6db29abcf9b05bee8d7d80e910" + integrity sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ== + +"@esbuild/netbsd-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz#ba70db0114380d5f6cfb9003f1d378ce989cd65c" + integrity sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw== + +"@esbuild/openbsd-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz#72fc55f0b189f7a882e3cf23f332370d69dfd5db" + integrity sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ== + +"@esbuild/openbsd-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz#b6ae7a0911c18fe30da3db1d6d17a497a550e5d8" + integrity sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg== + +"@esbuild/sunos-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz#58f0d5e55b9b21a086bfafaa29f62a3eb3470ad8" + integrity sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA== + +"@esbuild/win32-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz#b858b2432edfad62e945d5c7c9e5ddd0f528ca6d" + integrity sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ== + +"@esbuild/win32-ia32@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz#167ef6ca22a476c6c0c014a58b4f43ae4b80dec7" + integrity sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA== + +"@esbuild/win32-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz#db44a6a08520b5f25bbe409f34a59f2d4bcc7ced" + integrity sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g== + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -1756,6 +1876,36 @@ es6-error@^4.0.1: resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== +esbuild@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.0.tgz#de06002d48424d9fdb7eb52dbe8e95927f852599" + integrity sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA== + optionalDependencies: + "@esbuild/aix-ppc64" "0.23.0" + "@esbuild/android-arm" "0.23.0" + "@esbuild/android-arm64" "0.23.0" + "@esbuild/android-x64" "0.23.0" + "@esbuild/darwin-arm64" "0.23.0" + "@esbuild/darwin-x64" "0.23.0" + "@esbuild/freebsd-arm64" "0.23.0" + "@esbuild/freebsd-x64" "0.23.0" + "@esbuild/linux-arm" "0.23.0" + "@esbuild/linux-arm64" "0.23.0" + "@esbuild/linux-ia32" "0.23.0" + "@esbuild/linux-loong64" "0.23.0" + "@esbuild/linux-mips64el" "0.23.0" + "@esbuild/linux-ppc64" "0.23.0" + "@esbuild/linux-riscv64" "0.23.0" + "@esbuild/linux-s390x" "0.23.0" + "@esbuild/linux-x64" "0.23.0" + "@esbuild/netbsd-x64" "0.23.0" + "@esbuild/openbsd-arm64" "0.23.0" + "@esbuild/openbsd-x64" "0.23.0" + "@esbuild/sunos-x64" "0.23.0" + "@esbuild/win32-arm64" "0.23.0" + "@esbuild/win32-ia32" "0.23.0" + "@esbuild/win32-x64" "0.23.0" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"