@wendongfly/zihi 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/lib/xterm/README.md +27 -14
- package/dist/lib/xterm/css/xterm.css +81 -5
- package/dist/lib/xterm/lib/xterm.js +1 -1
- package/dist/lib/xterm/lib/xterm.js.map +1 -1
- package/dist/lib/xterm/lib/xterm.mjs +53 -0
- package/dist/lib/xterm/lib/xterm.mjs.map +7 -0
- package/dist/lib/xterm/package.json +49 -38
- package/dist/lib/xterm/src/browser/AccessibilityManager.ts +185 -50
- package/dist/lib/xterm/src/browser/CoreBrowserTerminal.ts +1339 -0
- package/dist/lib/xterm/src/browser/Linkifier.ts +403 -0
- package/dist/lib/xterm/src/browser/LocalizableStrings.ts +15 -4
- package/dist/lib/xterm/src/browser/OscLinkProvider.ts +2 -1
- package/dist/lib/xterm/src/browser/RenderDebouncer.ts +6 -5
- package/dist/lib/xterm/src/browser/TimeBasedDebouncer.ts +2 -2
- package/dist/lib/xterm/src/browser/Types.ts +226 -0
- package/dist/lib/xterm/src/browser/Viewport.ts +148 -357
- package/dist/lib/xterm/src/browser/decorations/BufferDecorationRenderer.ts +17 -12
- package/dist/lib/xterm/src/browser/decorations/OverviewRulerRenderer.ts +47 -52
- package/dist/lib/xterm/src/browser/input/CompositionHelper.ts +5 -3
- package/dist/lib/xterm/src/browser/input/MoveToCell.ts +3 -1
- package/dist/lib/xterm/src/browser/public/Terminal.ts +39 -24
- package/dist/lib/xterm/src/browser/renderer/dom/DomRenderer.ts +76 -40
- package/dist/lib/xterm/src/browser/renderer/dom/DomRendererRowFactory.ts +47 -23
- package/dist/lib/xterm/src/browser/renderer/dom/WidthCache.ts +19 -9
- package/dist/lib/xterm/src/browser/renderer/shared/Constants.ts +0 -8
- package/dist/lib/xterm/src/browser/renderer/shared/RendererUtils.ts +38 -1
- package/dist/lib/xterm/src/browser/renderer/shared/SelectionRenderModel.ts +6 -4
- package/dist/lib/xterm/src/browser/renderer/shared/Types.ts +84 -0
- package/dist/lib/xterm/src/browser/selection/Types.ts +15 -0
- package/dist/lib/xterm/src/browser/services/CharSizeService.ts +57 -32
- package/dist/lib/xterm/src/browser/services/CoreBrowserService.ts +108 -4
- package/dist/lib/xterm/src/browser/services/LinkProviderService.ts +28 -0
- package/dist/lib/xterm/src/browser/services/RenderService.ts +132 -40
- package/dist/lib/xterm/src/browser/services/SelectionService.ts +19 -9
- package/dist/lib/xterm/src/browser/services/Services.ts +36 -16
- package/dist/lib/xterm/src/browser/services/ThemeService.ts +19 -58
- package/dist/lib/xterm/src/browser/shared/Constants.ts +8 -0
- package/dist/lib/xterm/src/common/CircularList.ts +5 -5
- package/dist/lib/xterm/src/common/Color.ts +34 -14
- package/dist/lib/xterm/src/common/CoreTerminal.ts +40 -41
- package/dist/lib/xterm/src/common/InputHandler.ts +177 -125
- package/dist/lib/xterm/src/common/Platform.ts +2 -1
- package/dist/lib/xterm/src/common/SortedList.ts +86 -10
- package/dist/lib/xterm/src/common/TaskQueue.ts +7 -7
- package/dist/lib/xterm/src/common/Types.ts +552 -0
- package/dist/lib/xterm/src/common/buffer/AttributeData.ts +15 -0
- package/dist/lib/xterm/src/common/buffer/Buffer.ts +15 -7
- package/dist/lib/xterm/src/common/buffer/BufferLine.ts +53 -22
- package/dist/lib/xterm/src/common/buffer/BufferRange.ts +1 -1
- package/dist/lib/xterm/src/common/buffer/BufferReflow.ts +9 -6
- package/dist/lib/xterm/src/common/buffer/BufferSet.ts +5 -5
- package/dist/lib/xterm/src/common/buffer/Constants.ts +10 -2
- package/dist/lib/xterm/src/common/buffer/Marker.ts +4 -4
- package/dist/lib/xterm/src/common/buffer/Types.ts +52 -0
- package/dist/lib/xterm/src/common/input/Keyboard.ts +2 -27
- package/dist/lib/xterm/src/common/input/UnicodeV6.ts +18 -5
- package/dist/lib/xterm/src/common/input/WriteBuffer.ts +9 -8
- package/dist/lib/xterm/src/common/parser/EscapeSequenceParser.ts +13 -13
- package/dist/lib/xterm/src/common/parser/Types.ts +275 -0
- package/dist/lib/xterm/src/common/public/AddonManager.ts +1 -1
- package/dist/lib/xterm/src/common/public/BufferApiView.ts +1 -1
- package/dist/lib/xterm/src/common/public/BufferLineApiView.ts +1 -1
- package/dist/lib/xterm/src/common/public/BufferNamespaceApi.ts +4 -4
- package/dist/lib/xterm/src/common/public/ParserApi.ts +1 -1
- package/dist/lib/xterm/src/common/public/UnicodeApi.ts +1 -1
- package/dist/lib/xterm/src/common/services/BufferService.ts +14 -11
- package/dist/lib/xterm/src/common/services/CoreMouseService.ts +53 -6
- package/dist/lib/xterm/src/common/services/CoreService.ts +13 -8
- package/dist/lib/xterm/src/common/services/DecorationService.ts +11 -11
- package/dist/lib/xterm/src/common/services/InstantiationService.ts +1 -1
- package/dist/lib/xterm/src/common/services/LogService.ts +2 -2
- package/dist/lib/xterm/src/common/services/OptionsService.ts +16 -5
- package/dist/lib/xterm/src/common/services/ServiceRegistry.ts +1 -1
- package/dist/lib/xterm/src/common/services/Services.ts +73 -19
- package/dist/lib/xterm/src/common/services/UnicodeService.ts +30 -5
- package/dist/lib/xterm/src/vs/base/browser/browser.ts +141 -0
- package/dist/lib/xterm/src/vs/base/browser/canIUse.ts +49 -0
- package/dist/lib/xterm/src/vs/base/browser/dom.ts +2369 -0
- package/dist/lib/xterm/src/vs/base/browser/fastDomNode.ts +316 -0
- package/dist/lib/xterm/src/vs/base/browser/globalPointerMoveMonitor.ts +112 -0
- package/dist/lib/xterm/src/vs/base/browser/iframe.ts +135 -0
- package/dist/lib/xterm/src/vs/base/browser/keyboardEvent.ts +213 -0
- package/dist/lib/xterm/src/vs/base/browser/mouseEvent.ts +229 -0
- package/dist/lib/xterm/src/vs/base/browser/touch.ts +372 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +303 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +114 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +720 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +165 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +114 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +243 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +118 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +116 -0
- package/dist/lib/xterm/src/vs/base/browser/ui/widget.ts +57 -0
- package/dist/lib/xterm/src/vs/base/browser/window.ts +14 -0
- package/dist/lib/xterm/src/vs/base/common/arrays.ts +887 -0
- package/dist/lib/xterm/src/vs/base/common/arraysFind.ts +202 -0
- package/dist/lib/xterm/src/vs/base/common/assert.ts +71 -0
- package/dist/lib/xterm/src/vs/base/common/async.ts +1992 -0
- package/dist/lib/xterm/src/vs/base/common/cancellation.ts +148 -0
- package/dist/lib/xterm/src/vs/base/common/charCode.ts +450 -0
- package/dist/lib/xterm/src/vs/base/common/collections.ts +140 -0
- package/dist/lib/xterm/src/vs/base/common/decorators.ts +130 -0
- package/dist/lib/xterm/src/vs/base/common/equals.ts +146 -0
- package/dist/lib/xterm/src/vs/base/common/errors.ts +303 -0
- package/dist/lib/xterm/src/vs/base/common/event.ts +1778 -0
- package/dist/lib/xterm/src/vs/base/common/functional.ts +32 -0
- package/dist/lib/xterm/src/vs/base/common/hash.ts +316 -0
- package/dist/lib/xterm/src/vs/base/common/iterator.ts +159 -0
- package/dist/lib/xterm/src/vs/base/common/keyCodes.ts +526 -0
- package/dist/lib/xterm/src/vs/base/common/keybindings.ts +284 -0
- package/dist/lib/xterm/src/vs/base/common/lazy.ts +47 -0
- package/dist/lib/xterm/src/vs/base/common/lifecycle.ts +801 -0
- package/dist/lib/xterm/src/vs/base/common/linkedList.ts +142 -0
- package/dist/lib/xterm/src/vs/base/common/map.ts +202 -0
- package/dist/lib/xterm/src/vs/base/common/numbers.ts +98 -0
- package/dist/lib/xterm/src/vs/base/common/observable.ts +76 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/api.ts +31 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/autorun.ts +281 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/base.ts +489 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/debugName.ts +145 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/derived.ts +428 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/lazyObservableValue.ts +146 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/logging.ts +328 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/promise.ts +209 -0
- package/dist/lib/xterm/src/vs/base/common/observableInternal/utils.ts +610 -0
- package/dist/lib/xterm/src/vs/base/common/platform.ts +281 -0
- package/dist/lib/xterm/src/vs/base/common/scrollable.ts +522 -0
- package/dist/lib/xterm/src/vs/base/common/sequence.ts +34 -0
- package/dist/lib/xterm/src/vs/base/common/stopwatch.ts +43 -0
- package/dist/lib/xterm/src/vs/base/common/strings.ts +557 -0
- package/dist/lib/xterm/src/vs/base/common/symbols.ts +9 -0
- package/dist/lib/xterm/src/vs/base/common/uint.ts +59 -0
- package/dist/lib/xterm/src/vs/patches/nls.ts +90 -0
- package/dist/lib/xterm/src/vs/typings/base-common.d.ts +20 -0
- package/dist/lib/xterm/src/vs/typings/require.d.ts +42 -0
- package/dist/lib/xterm/src/vs/typings/vscode-globals-nls.d.ts +36 -0
- package/dist/lib/xterm/src/vs/typings/vscode-globals-product.d.ts +33 -0
- package/dist/lib/xterm/typings/xterm.d.ts +156 -43
- package/dist/lib/xterm-fit/README.md +5 -5
- package/dist/lib/xterm-fit/lib/addon-fit.js +2 -0
- package/dist/lib/xterm-fit/lib/addon-fit.js.map +1 -0
- package/dist/lib/xterm-fit/lib/addon-fit.mjs +18 -0
- package/dist/lib/xterm-fit/lib/addon-fit.mjs.map +7 -0
- package/dist/lib/xterm-fit/package.json +9 -9
- package/dist/lib/xterm-fit/src/FitAddon.ts +7 -4
- package/dist/lib/xterm-fit/typings/addon-fit.d.ts +55 -0
- package/dist/lib/xterm-links/README.md +5 -5
- package/dist/lib/xterm-links/lib/addon-web-links.js +2 -0
- package/dist/lib/xterm-links/lib/addon-web-links.js.map +1 -0
- package/dist/lib/xterm-links/lib/addon-web-links.mjs +18 -0
- package/dist/lib/xterm-links/lib/addon-web-links.mjs.map +7 -0
- package/dist/lib/xterm-links/package.json +9 -9
- package/dist/lib/xterm-links/src/WebLinkProvider.ts +16 -15
- package/dist/lib/xterm-links/src/WebLinksAddon.ts +4 -3
- package/dist/lib/xterm-links/typings/addon-web-links.d.ts +57 -0
- package/package.json +5 -6
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "xterm",
|
|
2
|
+
"name": "@xterm/xterm",
|
|
3
3
|
"description": "Full xterm terminal, in your browser",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "6.0.0",
|
|
5
5
|
"main": "lib/xterm.js",
|
|
6
|
+
"module": "lib/xterm.mjs",
|
|
6
7
|
"style": "css/xterm.css",
|
|
7
8
|
"types": "typings/xterm.d.ts",
|
|
8
9
|
"repository": "https://github.com/xtermjs/xterm.js",
|
|
9
10
|
"license": "MIT",
|
|
11
|
+
"workspaces": [
|
|
12
|
+
"addons/*"
|
|
13
|
+
],
|
|
10
14
|
"keywords": [
|
|
11
15
|
"cli",
|
|
12
16
|
"command-line",
|
|
@@ -23,52 +27,58 @@
|
|
|
23
27
|
"xterm"
|
|
24
28
|
],
|
|
25
29
|
"scripts": {
|
|
26
|
-
"
|
|
27
|
-
"package": "webpack",
|
|
28
|
-
"package-headless": "webpack --config ./webpack.config.headless.js",
|
|
29
|
-
"postpackage-headless": "node ./bin/package_headless.js",
|
|
30
|
+
"setup": "npm run build",
|
|
30
31
|
"start": "node demo/start",
|
|
31
|
-
"build
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
32
|
+
"build": "npm run tsc",
|
|
33
|
+
"watch": "npm run tsc-watch",
|
|
34
|
+
"tsc": "tsc -b ./tsconfig.all.json",
|
|
35
|
+
"tsc-watch": "tsc -b -w ./tsconfig.all.json --preserveWatchOutput",
|
|
36
|
+
"esbuild": "node bin/esbuild_all.mjs",
|
|
37
|
+
"esbuild-watch": "node bin/esbuild_all.mjs --watch",
|
|
38
|
+
"esbuild-package": "node bin/esbuild_all.mjs --prod",
|
|
39
|
+
"esbuild-package-watch": "node bin/esbuild_all.mjs --prod --watch",
|
|
40
|
+
"esbuild-package-headless-only": "node bin/esbuild.mjs --prod --headless",
|
|
41
|
+
"esbuild-demo": "node bin/esbuild.mjs --demo-client",
|
|
42
|
+
"esbuild-demo-watch": "node bin/esbuild.mjs --demo-client --watch",
|
|
35
43
|
"test": "npm run test-unit",
|
|
36
44
|
"posttest": "npm run lint",
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"test-
|
|
41
|
-
"test-
|
|
42
|
-
"test-playwright-chromium": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='Chrome Stable'",
|
|
43
|
-
"test-playwright-firefox": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='Firefox Stable'",
|
|
44
|
-
"test-playwright-webkit": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='WebKit'",
|
|
45
|
-
"test-playwright-debug": "playwright test -c ./out-test/playwright/playwright.config.js --headed --workers 1 --timeout 30000",
|
|
46
|
-
"test-unit": "node ./bin/test.js",
|
|
47
|
-
"test-unit-coverage": "node ./bin/test.js --coverage",
|
|
45
|
+
"lint": "eslint -c .eslintrc.json --max-warnings 0 --ext .ts src/ addons/",
|
|
46
|
+
"lint-fix": "eslint -c .eslintrc.json --fix --ext .ts src/ addons/",
|
|
47
|
+
"lint-api": "eslint --no-eslintrc -c .eslintrc.json.typings --max-warnings 0 --no-ignore --ext .d.ts typings/",
|
|
48
|
+
"test-unit": "node ./bin/test_unit.js",
|
|
49
|
+
"test-unit-coverage": "node ./bin/test_unit.js --coverage",
|
|
48
50
|
"test-unit-dev": "cross-env NODE_PATH='./out' mocha",
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"watch": "tsc -b -w ./tsconfig.all.json --preserveWatchOutput",
|
|
51
|
+
"test-integration": "node ./bin/test_integration.js --workers=75%",
|
|
52
|
+
"test-integration-chromium": "node ./bin/test_integration.js --workers=75% \"--project=ChromeStable\"",
|
|
53
|
+
"test-integration-firefox": "node ./bin/test_integration.js --workers=75% \"--project=FirefoxStable\"",
|
|
54
|
+
"test-integration-webkit": "node ./bin/test_integration.js --workers=75% \"--project=WebKit\"",
|
|
55
|
+
"test-integration-debug": "node ./bin/test_integration.js --workers=1 --headed --timeout=30000",
|
|
55
56
|
"benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json",
|
|
56
|
-
"benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark
|
|
57
|
-
"benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark
|
|
57
|
+
"benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark/*benchmark.js",
|
|
58
|
+
"benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark/*benchmark.js",
|
|
58
59
|
"clean": "rm -rf lib out addons/*/lib addons/*/out",
|
|
59
|
-
"vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts"
|
|
60
|
+
"vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts",
|
|
61
|
+
"prepackage": "npm run build",
|
|
62
|
+
"package": "webpack",
|
|
63
|
+
"postpackage": "npm run esbuild-package",
|
|
64
|
+
"prepackage-headless": "npm run esbuild-package-headless-only",
|
|
65
|
+
"package-headless": "webpack --config ./webpack.config.headless.js",
|
|
66
|
+
"postpackage-headless": "node ./bin/package_headless.js",
|
|
67
|
+
"prepublishOnly": "npm run package"
|
|
60
68
|
},
|
|
61
69
|
"devDependencies": {
|
|
70
|
+
"@lunapaint/png-codec": "^0.2.0",
|
|
62
71
|
"@playwright/test": "^1.37.1",
|
|
72
|
+
"@stylistic/eslint-plugin": "^2.3.0",
|
|
63
73
|
"@types/chai": "^4.2.22",
|
|
64
74
|
"@types/debug": "^4.1.7",
|
|
65
75
|
"@types/deep-equal": "^1.0.1",
|
|
66
76
|
"@types/express": "4",
|
|
67
77
|
"@types/express-ws": "^3.0.1",
|
|
68
|
-
"@types/glob": "^7.2.0",
|
|
69
78
|
"@types/jsdom": "^16.2.13",
|
|
70
79
|
"@types/mocha": "^9.0.0",
|
|
71
80
|
"@types/node": "^18.16.0",
|
|
81
|
+
"@types/trusted-types": "^1.0.6",
|
|
72
82
|
"@types/utf8": "^3.0.0",
|
|
73
83
|
"@types/webpack": "^5.28.0",
|
|
74
84
|
"@types/ws": "^8.2.0",
|
|
@@ -77,24 +87,25 @@
|
|
|
77
87
|
"chai": "^4.3.4",
|
|
78
88
|
"cross-env": "^7.0.3",
|
|
79
89
|
"deep-equal": "^2.0.5",
|
|
80
|
-
"
|
|
81
|
-
"eslint
|
|
82
|
-
"
|
|
90
|
+
"esbuild": "~0.25.2",
|
|
91
|
+
"eslint": "^8.56.0",
|
|
92
|
+
"eslint-plugin-jsdoc": "^46.9.1",
|
|
93
|
+
"express": "^4.19.2",
|
|
83
94
|
"express-ws": "^5.0.2",
|
|
84
|
-
"glob": "^7.2.0",
|
|
85
95
|
"jsdom": "^18.0.1",
|
|
86
96
|
"mocha": "^10.1.0",
|
|
87
97
|
"mustache": "^4.2.0",
|
|
88
|
-
"node-pty": "
|
|
98
|
+
"node-pty": "1.1.0-beta19",
|
|
89
99
|
"nyc": "^15.1.0",
|
|
90
100
|
"source-map-loader": "^3.0.0",
|
|
91
101
|
"source-map-support": "^0.5.20",
|
|
92
102
|
"ts-loader": "^9.3.1",
|
|
93
|
-
"typescript": "
|
|
103
|
+
"typescript": "5.5",
|
|
94
104
|
"utf8": "^3.0.0",
|
|
95
105
|
"webpack": "^5.61.0",
|
|
96
106
|
"webpack-cli": "^4.9.1",
|
|
97
107
|
"ws": "^8.2.3",
|
|
98
108
|
"xterm-benchmark": "^0.3.1"
|
|
99
|
-
}
|
|
109
|
+
},
|
|
110
|
+
"commit": "f447274f430fd22513f6adbf9862d19524471c04"
|
|
100
111
|
}
|
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
import * as Strings from 'browser/LocalizableStrings';
|
|
7
7
|
import { ITerminal, IRenderDebouncer } from 'browser/Types';
|
|
8
|
-
import { isMac } from 'common/Platform';
|
|
9
8
|
import { TimeBasedDebouncer } from 'browser/TimeBasedDebouncer';
|
|
10
|
-
import { Disposable, toDisposable } from 'common/
|
|
11
|
-
import {
|
|
12
|
-
import { IRenderService } from 'browser/services/Services';
|
|
13
|
-
import { addDisposableDomListener } from 'browser/Lifecycle';
|
|
9
|
+
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
10
|
+
import { ICoreBrowserService, IRenderService } from 'browser/services/Services';
|
|
14
11
|
import { IBuffer } from 'common/buffer/Types';
|
|
12
|
+
import { IInstantiationService } from 'common/services/Services';
|
|
13
|
+
import { addDisposableListener } from 'vs/base/browser/dom';
|
|
15
14
|
|
|
16
15
|
const MAX_ROWS_TO_READ = 20;
|
|
17
16
|
|
|
@@ -20,18 +19,22 @@ const enum BoundaryPosition {
|
|
|
20
19
|
BOTTOM
|
|
21
20
|
}
|
|
22
21
|
|
|
22
|
+
// Turn this on to unhide the accessibility tree and display it under
|
|
23
|
+
// (instead of overlapping with) the terminal.
|
|
24
|
+
const DEBUG = false;
|
|
25
|
+
|
|
23
26
|
export class AccessibilityManager extends Disposable {
|
|
27
|
+
private _debugRootContainer: HTMLElement | undefined;
|
|
24
28
|
private _accessibilityContainer: HTMLElement;
|
|
25
29
|
|
|
26
30
|
private _rowContainer: HTMLElement;
|
|
27
31
|
private _rowElements: HTMLElement[];
|
|
32
|
+
private _rowColumns: WeakMap<HTMLElement, number[]> = new WeakMap();
|
|
28
33
|
|
|
29
34
|
private _liveRegion: HTMLElement;
|
|
30
35
|
private _liveRegionLineCount: number = 0;
|
|
31
36
|
private _liveRegionDebouncer: IRenderDebouncer;
|
|
32
37
|
|
|
33
|
-
private _screenDprMonitor: ScreenDprMonitor;
|
|
34
|
-
|
|
35
38
|
private _topBoundaryFocusListener: (e: FocusEvent) => void;
|
|
36
39
|
private _bottomBoundaryFocusListener: (e: FocusEvent) => void;
|
|
37
40
|
|
|
@@ -50,13 +53,16 @@ export class AccessibilityManager extends Disposable {
|
|
|
50
53
|
|
|
51
54
|
constructor(
|
|
52
55
|
private readonly _terminal: ITerminal,
|
|
56
|
+
@IInstantiationService instantiationService: IInstantiationService,
|
|
57
|
+
@ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,
|
|
53
58
|
@IRenderService private readonly _renderService: IRenderService
|
|
54
59
|
) {
|
|
55
60
|
super();
|
|
56
|
-
|
|
61
|
+
const doc = this._coreBrowserService.mainDocument;
|
|
62
|
+
this._accessibilityContainer = doc.createElement('div');
|
|
57
63
|
this._accessibilityContainer.classList.add('xterm-accessibility');
|
|
58
64
|
|
|
59
|
-
this._rowContainer =
|
|
65
|
+
this._rowContainer = doc.createElement('div');
|
|
60
66
|
this._rowContainer.setAttribute('role', 'list');
|
|
61
67
|
this._rowContainer.classList.add('xterm-accessibility-tree');
|
|
62
68
|
this._rowElements = [];
|
|
@@ -70,41 +76,56 @@ export class AccessibilityManager extends Disposable {
|
|
|
70
76
|
this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener);
|
|
71
77
|
this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener);
|
|
72
78
|
|
|
73
|
-
this._refreshRowsDimensions();
|
|
74
79
|
this._accessibilityContainer.appendChild(this._rowContainer);
|
|
75
80
|
|
|
76
|
-
this._liveRegion =
|
|
81
|
+
this._liveRegion = doc.createElement('div');
|
|
77
82
|
this._liveRegion.classList.add('live-region');
|
|
78
83
|
this._liveRegion.setAttribute('aria-live', 'assertive');
|
|
79
84
|
this._accessibilityContainer.appendChild(this._liveRegion);
|
|
80
|
-
this._liveRegionDebouncer = this.
|
|
85
|
+
this._liveRegionDebouncer = this._register(new TimeBasedDebouncer(this._renderRows.bind(this)));
|
|
81
86
|
|
|
82
87
|
if (!this._terminal.element) {
|
|
83
88
|
throw new Error('Cannot enable accessibility before Terminal.open');
|
|
84
89
|
}
|
|
85
|
-
this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer);
|
|
86
90
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
if (DEBUG) {
|
|
92
|
+
this._accessibilityContainer.classList.add('debug');
|
|
93
|
+
this._rowContainer.classList.add('debug');
|
|
94
|
+
|
|
95
|
+
// Use a `<div class="xterm">` container so that the css will still apply.
|
|
96
|
+
this._debugRootContainer = doc.createElement('div');
|
|
97
|
+
this._debugRootContainer.classList.add('xterm');
|
|
98
|
+
|
|
99
|
+
this._debugRootContainer.appendChild(doc.createTextNode('------start a11y------'));
|
|
100
|
+
this._debugRootContainer.appendChild(this._accessibilityContainer);
|
|
101
|
+
this._debugRootContainer.appendChild(doc.createTextNode('------end a11y------'));
|
|
102
|
+
|
|
103
|
+
this._terminal.element.insertAdjacentElement('afterend', this._debugRootContainer);
|
|
104
|
+
} else {
|
|
105
|
+
this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this._register(this._terminal.onResize(e => this._handleResize(e.rows)));
|
|
109
|
+
this._register(this._terminal.onRender(e => this._refreshRows(e.start, e.end)));
|
|
110
|
+
this._register(this._terminal.onScroll(() => this._refreshRows()));
|
|
90
111
|
// Line feed is an issue as the prompt won't be read out after a command is run
|
|
91
|
-
this.
|
|
92
|
-
this.
|
|
93
|
-
this.
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
96
|
-
this.
|
|
97
|
-
|
|
98
|
-
this.
|
|
99
|
-
this.register(this._screenDprMonitor);
|
|
100
|
-
this._screenDprMonitor.setListener(() => this._refreshRowsDimensions());
|
|
101
|
-
// This shouldn't be needed on modern browsers but is present in case the
|
|
102
|
-
// media query that drives the ScreenDprMonitor isn't supported
|
|
103
|
-
this.register(addDisposableDomListener(window, 'resize', () => this._refreshRowsDimensions()));
|
|
112
|
+
this._register(this._terminal.onA11yChar(char => this._handleChar(char)));
|
|
113
|
+
this._register(this._terminal.onLineFeed(() => this._handleChar('\n')));
|
|
114
|
+
this._register(this._terminal.onA11yTab(spaceCount => this._handleTab(spaceCount)));
|
|
115
|
+
this._register(this._terminal.onKey(e => this._handleKey(e.key)));
|
|
116
|
+
this._register(this._terminal.onBlur(() => this._clearLiveRegion()));
|
|
117
|
+
this._register(this._renderService.onDimensionsChange(() => this._refreshRowsDimensions()));
|
|
118
|
+
this._register(addDisposableListener(doc, 'selectionchange', () => this._handleSelectionChange()));
|
|
119
|
+
this._register(this._coreBrowserService.onDprChange(() => this._refreshRowsDimensions()));
|
|
104
120
|
|
|
121
|
+
this._refreshRowsDimensions();
|
|
105
122
|
this._refreshRows();
|
|
106
|
-
this.
|
|
107
|
-
|
|
123
|
+
this._register(toDisposable(() => {
|
|
124
|
+
if (DEBUG) {
|
|
125
|
+
this._debugRootContainer!.remove();
|
|
126
|
+
} else {
|
|
127
|
+
this._accessibilityContainer.remove();
|
|
128
|
+
}
|
|
108
129
|
this._rowElements.length = 0;
|
|
109
130
|
}));
|
|
110
131
|
}
|
|
@@ -130,16 +151,7 @@ export class AccessibilityManager extends Disposable {
|
|
|
130
151
|
if (char === '\n') {
|
|
131
152
|
this._liveRegionLineCount++;
|
|
132
153
|
if (this._liveRegionLineCount === MAX_ROWS_TO_READ + 1) {
|
|
133
|
-
this._liveRegion.textContent += Strings.tooMuchOutput;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Only detach/attach on mac as otherwise messages can go unaccounced
|
|
138
|
-
if (isMac) {
|
|
139
|
-
if (this._liveRegion.textContent && this._liveRegion.textContent.length > 0 && !this._liveRegion.parentNode) {
|
|
140
|
-
setTimeout(() => {
|
|
141
|
-
this._accessibilityContainer.appendChild(this._liveRegion);
|
|
142
|
-
}, 0);
|
|
154
|
+
this._liveRegion.textContent += Strings.tooMuchOutput.get();
|
|
143
155
|
}
|
|
144
156
|
}
|
|
145
157
|
}
|
|
@@ -148,11 +160,6 @@ export class AccessibilityManager extends Disposable {
|
|
|
148
160
|
private _clearLiveRegion(): void {
|
|
149
161
|
this._liveRegion.textContent = '';
|
|
150
162
|
this._liveRegionLineCount = 0;
|
|
151
|
-
|
|
152
|
-
// Only detach/attach on mac as otherwise messages can go unaccounced
|
|
153
|
-
if (isMac) {
|
|
154
|
-
this._liveRegion.remove();
|
|
155
|
-
}
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
private _handleKey(keyChar: string): void {
|
|
@@ -171,17 +178,22 @@ export class AccessibilityManager extends Disposable {
|
|
|
171
178
|
const buffer: IBuffer = this._terminal.buffer;
|
|
172
179
|
const setSize = buffer.lines.length.toString();
|
|
173
180
|
for (let i = start; i <= end; i++) {
|
|
174
|
-
const
|
|
181
|
+
const line = buffer.lines.get(buffer.ydisp + i);
|
|
182
|
+
const columns: number[] = [];
|
|
183
|
+
const lineData = line?.translateToString(true, undefined, undefined, columns) || '';
|
|
175
184
|
const posInSet = (buffer.ydisp + i + 1).toString();
|
|
176
185
|
const element = this._rowElements[i];
|
|
177
186
|
if (element) {
|
|
178
187
|
if (lineData.length === 0) {
|
|
179
|
-
element.
|
|
188
|
+
element.textContent = '\u00a0';
|
|
189
|
+
this._rowColumns.set(element, [0, 1]);
|
|
180
190
|
} else {
|
|
181
191
|
element.textContent = lineData;
|
|
192
|
+
this._rowColumns.set(element, columns);
|
|
182
193
|
}
|
|
183
194
|
element.setAttribute('aria-posinset', posInSet);
|
|
184
195
|
element.setAttribute('aria-setsize', setSize);
|
|
196
|
+
this._alignRowWidth(element);
|
|
185
197
|
}
|
|
186
198
|
}
|
|
187
199
|
this._announceCharacters();
|
|
@@ -255,6 +267,103 @@ export class AccessibilityManager extends Disposable {
|
|
|
255
267
|
e.stopImmediatePropagation();
|
|
256
268
|
}
|
|
257
269
|
|
|
270
|
+
private _handleSelectionChange(): void {
|
|
271
|
+
if (this._rowElements.length === 0) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const selection = this._coreBrowserService.mainDocument.getSelection();
|
|
276
|
+
if (!selection) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (selection.isCollapsed) {
|
|
281
|
+
// Only do something when the anchorNode is inside the row container. This
|
|
282
|
+
// behavior mirrors what we do with mouse --- if the mouse clicks
|
|
283
|
+
// somewhere outside of the terminal, we don't clear the selection.
|
|
284
|
+
if (this._rowContainer.contains(selection.anchorNode)) {
|
|
285
|
+
this._terminal.clearSelection();
|
|
286
|
+
}
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (!selection.anchorNode || !selection.focusNode) {
|
|
291
|
+
console.error('anchorNode and/or focusNode are null');
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Sort the two selection points in document order.
|
|
296
|
+
let begin = { node: selection.anchorNode, offset: selection.anchorOffset };
|
|
297
|
+
let end = { node: selection.focusNode, offset: selection.focusOffset };
|
|
298
|
+
if ((begin.node.compareDocumentPosition(end.node) & Node.DOCUMENT_POSITION_PRECEDING) || (begin.node === end.node && begin.offset > end.offset) ) {
|
|
299
|
+
[begin, end] = [end, begin];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Clamp begin/end to the inside of the row container.
|
|
303
|
+
if (begin.node.compareDocumentPosition(this._rowElements[0]) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING)) {
|
|
304
|
+
begin = { node: this._rowElements[0].childNodes[0], offset: 0 };
|
|
305
|
+
}
|
|
306
|
+
if (!this._rowContainer.contains(begin.node)) {
|
|
307
|
+
// This happens when `begin` is below the last row.
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
const lastRowElement = this._rowElements.slice(-1)[0];
|
|
311
|
+
if (end.node.compareDocumentPosition(lastRowElement) & (Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_PRECEDING)) {
|
|
312
|
+
end = {
|
|
313
|
+
node: lastRowElement,
|
|
314
|
+
offset: lastRowElement.textContent?.length ?? 0
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
if (!this._rowContainer.contains(end.node)) {
|
|
318
|
+
// This happens when `end` is above the first row.
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const toRowColumn = ({ node, offset }: typeof begin): {row: number, column: number} | null => {
|
|
323
|
+
// `node` is either the row element or the Text node inside it.
|
|
324
|
+
const rowElement: any = node instanceof Text ? node.parentNode : node;
|
|
325
|
+
let row = parseInt(rowElement?.getAttribute('aria-posinset'), 10) - 1;
|
|
326
|
+
if (isNaN(row)) {
|
|
327
|
+
console.warn('row is invalid. Race condition?');
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const columns = this._rowColumns.get(rowElement);
|
|
332
|
+
if (!columns) {
|
|
333
|
+
console.warn('columns is null. Race condition?');
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
let column = offset < columns.length ? columns[offset] : columns.slice(-1)[0] + 1;
|
|
338
|
+
if (column >= this._terminal.cols) {
|
|
339
|
+
++row;
|
|
340
|
+
column = 0;
|
|
341
|
+
}
|
|
342
|
+
return {
|
|
343
|
+
row,
|
|
344
|
+
column
|
|
345
|
+
};
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
const beginRowColumn = toRowColumn(begin);
|
|
349
|
+
const endRowColumn = toRowColumn(end);
|
|
350
|
+
|
|
351
|
+
if (!beginRowColumn || !endRowColumn) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (beginRowColumn.row > endRowColumn.row || (beginRowColumn.row === endRowColumn.row && beginRowColumn.column >= endRowColumn.column)) {
|
|
356
|
+
// This should not happen unless we have some bugs.
|
|
357
|
+
throw new Error('invalid range');
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
this._terminal.select(
|
|
361
|
+
beginRowColumn.column,
|
|
362
|
+
beginRowColumn.row,
|
|
363
|
+
(endRowColumn.row - beginRowColumn.row) * this._terminal.cols - beginRowColumn.column + endRowColumn.column
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
|
|
258
367
|
private _handleResize(rows: number): void {
|
|
259
368
|
// Remove bottom boundary listener
|
|
260
369
|
this._rowElements[this._rowElements.length - 1].removeEventListener('focus', this._bottomBoundaryFocusListener);
|
|
@@ -276,25 +385,51 @@ export class AccessibilityManager extends Disposable {
|
|
|
276
385
|
}
|
|
277
386
|
|
|
278
387
|
private _createAccessibilityTreeNode(): HTMLElement {
|
|
279
|
-
const element =
|
|
388
|
+
const element = this._coreBrowserService.mainDocument.createElement('div');
|
|
280
389
|
element.setAttribute('role', 'listitem');
|
|
281
390
|
element.tabIndex = -1;
|
|
282
391
|
this._refreshRowDimensions(element);
|
|
283
392
|
return element;
|
|
284
393
|
}
|
|
394
|
+
|
|
285
395
|
private _refreshRowsDimensions(): void {
|
|
286
396
|
if (!this._renderService.dimensions.css.cell.height) {
|
|
287
397
|
return;
|
|
288
398
|
}
|
|
289
|
-
this._accessibilityContainer.style
|
|
399
|
+
Object.assign(this._accessibilityContainer.style, {
|
|
400
|
+
width: `${this._renderService.dimensions.css.canvas.width}px`,
|
|
401
|
+
fontSize: `${this._terminal.options.fontSize}px`
|
|
402
|
+
});
|
|
290
403
|
if (this._rowElements.length !== this._terminal.rows) {
|
|
291
404
|
this._handleResize(this._terminal.rows);
|
|
292
405
|
}
|
|
293
406
|
for (let i = 0; i < this._terminal.rows; i++) {
|
|
294
407
|
this._refreshRowDimensions(this._rowElements[i]);
|
|
408
|
+
this._alignRowWidth(this._rowElements[i]);
|
|
295
409
|
}
|
|
296
410
|
}
|
|
411
|
+
|
|
297
412
|
private _refreshRowDimensions(element: HTMLElement): void {
|
|
298
413
|
element.style.height = `${this._renderService.dimensions.css.cell.height}px`;
|
|
299
414
|
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Scale the width of a row so that each of the character is (mostly) aligned
|
|
418
|
+
* with the actual rendering. This will allow the screen reader to draw
|
|
419
|
+
* selection outline at the correct position.
|
|
420
|
+
*
|
|
421
|
+
* On top of using the "monospace" font and correct font size, the scaling
|
|
422
|
+
* here is necessary to handle characters that are not covered by the font
|
|
423
|
+
* (e.g. CJK).
|
|
424
|
+
*/
|
|
425
|
+
private _alignRowWidth(element: HTMLElement): void {
|
|
426
|
+
element.style.transform = '';
|
|
427
|
+
const width = element.getBoundingClientRect().width;
|
|
428
|
+
const lastColumn = this._rowColumns.get(element)?.slice(-1)?.[0];
|
|
429
|
+
if (!lastColumn) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
const targetWidth = lastColumn * this._renderService.dimensions.css.cell.width;
|
|
433
|
+
element.style.transform = `scaleX(${targetWidth / width})`;
|
|
434
|
+
}
|
|
300
435
|
}
|