Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3261beaea | ||
|
|
345b8d910b | ||
|
|
922ee7c48d | ||
|
|
131e11b52b | ||
|
|
5a3e0612a7 | ||
|
|
b246318090 | ||
|
|
d807bdac5e | ||
|
|
1695baa5b0 | ||
|
|
c71252cd23 | ||
|
|
6c18b7f2cc | ||
|
|
5e77ad5cb4 | ||
|
|
e1578813a7 | ||
|
|
21811cb37d | ||
|
|
265227edcb | ||
|
|
1d3c1964f9 | ||
|
|
58b7a4a2d7 | ||
|
|
a6b0734fe8 | ||
|
|
55cd34c7a5 | ||
|
|
0e8aeebedb | ||
|
|
1c4d41db86 | ||
|
|
63c281e405 | ||
|
|
f03d0858cc | ||
|
|
8bdeb14bc6 | ||
|
|
ad7fe8f881 | ||
|
|
1dcc1d1baf | ||
|
|
0029bc3b42 | ||
|
|
0b73a8d469 | ||
|
|
3a2b97e0f7 | ||
|
|
9bcc98beb9 | ||
|
|
1fb11707a5 | ||
|
|
84548d5d7b | ||
|
|
6f666f56c1 | ||
|
|
2866977941 | ||
|
|
c087592e2c | ||
|
|
65182176b9 | ||
|
|
c8123d911e | ||
|
|
cacda99707 | ||
|
|
bac4eba35e | ||
|
|
625df61489 | ||
|
|
ccca58bb95 | ||
|
|
9557b9132b | ||
|
|
d6d540e748 |
Vendored
+4
-1
@@ -11,7 +11,10 @@
|
|||||||
{
|
{
|
||||||
"type": "npm",
|
"type": "npm",
|
||||||
"script": "test",
|
"script": "test",
|
||||||
"group": "test",
|
"group":{
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
"problemMatcher": []
|
"problemMatcher": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -185,7 +185,10 @@ Xterm.js is used in several world-class applications to provide great terminal e
|
|||||||
- [**gdbgui**](https://github.com/cs01/gdbgui): Browser-based frontend to gdb (gnu debugger)
|
- [**gdbgui**](https://github.com/cs01/gdbgui): Browser-based frontend to gdb (gnu debugger)
|
||||||
- [**goormIDE**](https://ide.goorm.io/): Run almost every programming languages with real-time collaboration, live pair programming, and built-in messenger.
|
- [**goormIDE**](https://ide.goorm.io/): Run almost every programming languages with real-time collaboration, live pair programming, and built-in messenger.
|
||||||
- [**FleetDeck**](https://fleetdeck.io): Remote desktop & virtual terminal
|
- [**FleetDeck**](https://fleetdeck.io): Remote desktop & virtual terminal
|
||||||
- [And much more...](https://github.com/xtermjs/xterm.js/network/dependents)
|
- [**OpenSumi**](https://github.com/opensumi/core): A framework helps you quickly build Cloud or Desktop IDE products.
|
||||||
|
- [**KubeSail**](https://kubesail.com): The Self-Hosting Company - uses xterm to allow users to exec into kubernetes pods and build github apps
|
||||||
|
- [**WiTTY**](https://github.com/syssecfsu/witty): Web-based interactive terminal emulator that allows users to easily record, share, and replay console sessions.
|
||||||
|
- [And much more...](https://github.com/xtermjs/xterm.js/network/dependents?package_id=UGFja2FnZS0xNjYzMjc4OQ%3D%3D)
|
||||||
|
|
||||||
Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it on our list. Note: Please add any new contributions to the end of the list only.
|
Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it on our list. Note: Please add any new contributions to the end of the list only.
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
"types": "typings/xterm-addon-attach.d.ts",
|
"types": "typings/xterm-addon-attach.d.ts",
|
||||||
"repository": "https://github.com/xtermjs/xterm.js",
|
"repository": "https://github.com/xtermjs/xterm.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"terminal",
|
||||||
|
"xterm",
|
||||||
|
"xterm.js"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "../../node_modules/.bin/tsc -p .",
|
"build": "../../node_modules/.bin/tsc -p .",
|
||||||
"prepackage": "npm run build",
|
"prepackage": "npm run build",
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
"types": "typings/xterm-addon-fit.d.ts",
|
"types": "typings/xterm-addon-fit.d.ts",
|
||||||
"repository": "https://github.com/xtermjs/xterm.js",
|
"repository": "https://github.com/xtermjs/xterm.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"terminal",
|
||||||
|
"xterm",
|
||||||
|
"xterm.js"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "../../node_modules/.bin/tsc -p .",
|
"build": "../../node_modules/.bin/tsc -p .",
|
||||||
"prepackage": "npm run build",
|
"prepackage": "npm run build",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xterm-addon-ligatures",
|
"name": "xterm-addon-ligatures",
|
||||||
"version": "0.5.1",
|
"version": "0.5.2",
|
||||||
"description": "Add support for programming ligatures to xterm.js",
|
"description": "Add support for programming ligatures to xterm.js",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "The xterm.js authors",
|
"name": "The xterm.js authors",
|
||||||
@@ -25,14 +25,14 @@
|
|||||||
"keywords": [
|
"keywords": [
|
||||||
"font",
|
"font",
|
||||||
"ligature",
|
"ligature",
|
||||||
|
"terminal",
|
||||||
"xterm",
|
"xterm",
|
||||||
"xterm.js",
|
"xterm.js"
|
||||||
"terminal"
|
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"font-finder": "^1.1.0",
|
"font-finder": "^1.1.0",
|
||||||
"font-ligatures": "^1.4.0"
|
"font-ligatures": "^1.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/sinon": "^5.0.1",
|
"@types/sinon": "^5.0.1",
|
||||||
|
|||||||
@@ -67,9 +67,9 @@ fd-slicer@~1.1.0:
|
|||||||
pend "~1.2.0"
|
pend "~1.2.0"
|
||||||
|
|
||||||
follow-redirects@^1.14.0:
|
follow-redirects@^1.14.0:
|
||||||
version "1.14.3"
|
version "1.14.7"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.3.tgz#6ada78118d8d24caee595595accdc0ac6abd022e"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
|
||||||
integrity sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw==
|
integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
|
||||||
|
|
||||||
font-finder@^1.0.3:
|
font-finder@^1.0.3:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
@@ -86,10 +86,10 @@ font-finder@^1.1.0:
|
|||||||
get-system-fonts "^2.0.0"
|
get-system-fonts "^2.0.0"
|
||||||
promise-stream-reader "^1.0.1"
|
promise-stream-reader "^1.0.1"
|
||||||
|
|
||||||
font-ligatures@^1.4.0:
|
font-ligatures@^1.4.1:
|
||||||
version "1.4.0"
|
version "1.4.1"
|
||||||
resolved "https://registry.npmjs.org/font-ligatures/-/font-ligatures-1.4.0.tgz#6a7b370d96be1358dddfad67830e82fbfd59e6dc"
|
resolved "https://registry.npmjs.org/font-ligatures/-/font-ligatures-1.4.1.tgz#e8c9df7cf6bee80c0cca4a9a578618c7b1f5d8de"
|
||||||
integrity sha512-n7DFnnEpJ0NrVoLqZIL4tMGVs+CnFwQc92m80LWyrbgAFO4x234+t2/H9o4eOYA1eh6ta9dZAEEsJAwsBdNezA==
|
integrity sha512-7W6zlfyhvCqShZ5ReUWqmSd9vBaUudW0Hxis+tqUjtHhsPU+L3Grf8mcZAtCiXHTzorhwdRTId2WeH/88gdFkw==
|
||||||
dependencies:
|
dependencies:
|
||||||
font-finder "^1.0.3"
|
font-finder "^1.0.3"
|
||||||
lru-cache "^6.0.0"
|
lru-cache "^6.0.0"
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
"types": "typings/xterm-addon-search.d.ts",
|
"types": "typings/xterm-addon-search.d.ts",
|
||||||
"repository": "https://github.com/xtermjs/xterm.js",
|
"repository": "https://github.com/xtermjs/xterm.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"terminal",
|
||||||
|
"xterm",
|
||||||
|
"xterm.js"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "../../node_modules/.bin/tsc -p .",
|
"build": "../../node_modules/.bin/tsc -p .",
|
||||||
"prepackage": "npm run build",
|
"prepackage": "npm run build",
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
"types": "typings/xterm-addon-serialize.d.ts",
|
"types": "typings/xterm-addon-serialize.d.ts",
|
||||||
"repository": "https://github.com/xtermjs/xterm.js",
|
"repository": "https://github.com/xtermjs/xterm.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"terminal",
|
||||||
|
"xterm",
|
||||||
|
"xterm.js"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "../../node_modules/.bin/tsc -p .",
|
"build": "../../node_modules/.bin/tsc -p .",
|
||||||
"prepackage": "npm run build",
|
"prepackage": "npm run build",
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
"types": "typings/xterm-addon-unicode11.d.ts",
|
"types": "typings/xterm-addon-unicode11.d.ts",
|
||||||
"repository": "https://github.com/xtermjs/xterm.js",
|
"repository": "https://github.com/xtermjs/xterm.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"terminal",
|
||||||
|
"xterm",
|
||||||
|
"xterm.js"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "../../node_modules/.bin/tsc -p .",
|
"build": "../../node_modules/.bin/tsc -p .",
|
||||||
"prepackage": "npm run build",
|
"prepackage": "npm run build",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xterm-addon-web-links",
|
"name": "xterm-addon-web-links",
|
||||||
"version": "0.5.0",
|
"version": "0.5.1",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "The xterm.js authors",
|
"name": "The xterm.js authors",
|
||||||
"url": "https://xtermjs.org/"
|
"url": "https://xtermjs.org/"
|
||||||
@@ -9,6 +9,11 @@
|
|||||||
"types": "typings/xterm-addon-web-links.d.ts",
|
"types": "typings/xterm-addon-web-links.d.ts",
|
||||||
"repository": "https://github.com/xtermjs/xterm.js",
|
"repository": "https://github.com/xtermjs/xterm.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"terminal",
|
||||||
|
"xterm",
|
||||||
|
"xterm.js"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "../../node_modules/.bin/tsc -p .",
|
"build": "../../node_modules/.bin/tsc -p .",
|
||||||
"prepackage": "npm run build",
|
"prepackage": "npm run build",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const protocolClause = '(https?:\\/\\/)';
|
|||||||
const domainCharacterSet = '[\\da-z\\.-]+';
|
const domainCharacterSet = '[\\da-z\\.-]+';
|
||||||
const negatedDomainCharacterSet = '[^\\da-z\\.-]+';
|
const negatedDomainCharacterSet = '[^\\da-z\\.-]+';
|
||||||
const domainBodyClause = '(' + domainCharacterSet + ')';
|
const domainBodyClause = '(' + domainCharacterSet + ')';
|
||||||
const tldClause = '([a-z\\.]{2,6})';
|
const tldClause = '([a-z\\.]{2,18})';
|
||||||
const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})';
|
const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})';
|
||||||
const localHostClause = '(localhost)';
|
const localHostClause = '(localhost)';
|
||||||
const portClause = '(:\\d{1,5})';
|
const portClause = '(:\\d{1,5})';
|
||||||
|
|||||||
@@ -9,6 +9,12 @@
|
|||||||
"types": "typings/xterm-addon-webgl.d.ts",
|
"types": "typings/xterm-addon-webgl.d.ts",
|
||||||
"repository": "https://github.com/xtermjs/xterm.js",
|
"repository": "https://github.com/xtermjs/xterm.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"terminal",
|
||||||
|
"webgl",
|
||||||
|
"xterm",
|
||||||
|
"xterm.js"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "../../node_modules/.bin/tsc -p .",
|
"build": "../../node_modules/.bin/tsc -p .",
|
||||||
"prepackage": "npm run build",
|
"prepackage": "npm run build",
|
||||||
|
|||||||
+18
-17
@@ -105,22 +105,23 @@ jobs:
|
|||||||
- script: xvfb-run --auto-servernum -- bash -c "yarn test-api-firefox --headless --forbid-only"
|
- script: xvfb-run --auto-servernum -- bash -c "yarn test-api-firefox --headless --forbid-only"
|
||||||
displayName: 'Integration tests (Firefox)'
|
displayName: 'Integration tests (Firefox)'
|
||||||
|
|
||||||
- job: macOS_IntegrationTests
|
# Integration tests are too flaky on macOS https://github.com/xtermjs/xterm.js/issues/3590
|
||||||
pool:
|
# - job: macOS_IntegrationTests
|
||||||
vmImage: 'macOS-10.15'
|
# pool:
|
||||||
steps:
|
# vmImage: 'macOS-10.15'
|
||||||
- task: NodeTool@0
|
# steps:
|
||||||
inputs:
|
# - task: NodeTool@0
|
||||||
versionSpec: '14.x'
|
# inputs:
|
||||||
displayName: 'Install Node.js'
|
# versionSpec: '14.x'
|
||||||
- script: yarn --frozen-lockfile
|
# displayName: 'Install Node.js'
|
||||||
displayName: 'Install dependencies and build'
|
# - script: yarn --frozen-lockfile
|
||||||
- script: yarn test-api-chromium --headless --forbid-only
|
# displayName: 'Install dependencies and build'
|
||||||
displayName: 'Integration tests (Chromium)'
|
# - script: yarn test-api-chromium --headless --forbid-only
|
||||||
- script: yarn test-api-firefox --headless --forbid-only
|
# displayName: 'Integration tests (Chromium)'
|
||||||
displayName: 'Integration tests (Firefox)'
|
# - script: yarn test-api-firefox --headless --forbid-only
|
||||||
- script: yarn test-api-webkit --headless --forbid-only
|
# displayName: 'Integration tests (Firefox)'
|
||||||
displayName: 'Integration tests (Webkit)'
|
# - script: yarn test-api-webkit --headless --forbid-only
|
||||||
|
# displayName: 'Integration tests (Webkit)'
|
||||||
|
|
||||||
- job: Windows_IntegrationTests
|
- job: Windows_IntegrationTests
|
||||||
pool:
|
pool:
|
||||||
@@ -143,7 +144,7 @@ jobs:
|
|||||||
- macOS
|
- macOS
|
||||||
- Windows
|
- Windows
|
||||||
- Linux_IntegrationTests
|
- Linux_IntegrationTests
|
||||||
- macOS_IntegrationTests
|
# - macOS_IntegrationTests
|
||||||
- Windows_IntegrationTests
|
- Windows_IntegrationTests
|
||||||
condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(variables['FORCE_RELEASE'], 'true')))
|
condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(variables['FORCE_RELEASE'], 'true')))
|
||||||
pool:
|
pool:
|
||||||
|
|||||||
+16
-1
@@ -1,12 +1,27 @@
|
|||||||
{
|
{
|
||||||
"name": "xterm",
|
"name": "xterm",
|
||||||
"description": "Full xterm terminal, in your browser",
|
"description": "Full xterm terminal, in your browser",
|
||||||
"version": "4.16.0",
|
"version": "4.17.0",
|
||||||
"main": "lib/xterm.js",
|
"main": "lib/xterm.js",
|
||||||
"style": "css/xterm.css",
|
"style": "css/xterm.css",
|
||||||
"types": "typings/xterm.d.ts",
|
"types": "typings/xterm.d.ts",
|
||||||
"repository": "https://github.com/xtermjs/xterm.js",
|
"repository": "https://github.com/xtermjs/xterm.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"cli",
|
||||||
|
"command-line",
|
||||||
|
"console",
|
||||||
|
"pty",
|
||||||
|
"shell",
|
||||||
|
"ssh",
|
||||||
|
"styles",
|
||||||
|
"terminal-emulator",
|
||||||
|
"terminal",
|
||||||
|
"tty",
|
||||||
|
"vt100",
|
||||||
|
"webgl",
|
||||||
|
"xterm"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepackage": "npm run build",
|
"prepackage": "npm run build",
|
||||||
"package": "webpack",
|
"package": "webpack",
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ export class MouseZoneManager extends Disposable implements IMouseZoneManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Restart the tooltip timeout
|
// Restart the tooltip timeout
|
||||||
this._tooltipTimeout = window.setTimeout(() => this._onTooltip(e), this._optionsService.options.linkTooltipHoverDuration);
|
this._tooltipTimeout = window.setTimeout(() => this._onTooltip(e), this._optionsService.rawOptions.linkTooltipHoverDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onTooltip(e: MouseEvent): void {
|
private _onTooltip(e: MouseEvent): void {
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|||||||
this.viewport?.syncScrollArea();
|
this.viewport?.syncScrollArea();
|
||||||
break;
|
break;
|
||||||
case 'screenReaderMode':
|
case 'screenReaderMode':
|
||||||
if (this.optionsService.options.screenReaderMode) {
|
if (this.optionsService.rawOptions.screenReaderMode) {
|
||||||
if (!this._accessibilityManager && this._renderService) {
|
if (!this._accessibilityManager && this._renderService) {
|
||||||
this._accessibilityManager = new AccessibilityManager(this, this._renderService);
|
this._accessibilityManager = new AccessibilityManager(this, this._renderService);
|
||||||
}
|
}
|
||||||
@@ -309,7 +309,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|||||||
break;
|
break;
|
||||||
case 'tabStopWidth': this.buffers.setupTabStops(); break;
|
case 'tabStopWidth': this.buffers.setupTabStops(); break;
|
||||||
case 'theme':
|
case 'theme':
|
||||||
this._setTheme(this.optionsService.options.theme);
|
this._setTheme(this.optionsService.rawOptions.theme);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -753,7 +753,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|||||||
this.register(this.coreMouseService.onProtocolChange(events => {
|
this.register(this.coreMouseService.onProtocolChange(events => {
|
||||||
// apply global changes on events
|
// apply global changes on events
|
||||||
if (events) {
|
if (events) {
|
||||||
if (this.optionsService.options.logLevel === 'debug') {
|
if (this.optionsService.rawOptions.logLevel === 'debug') {
|
||||||
this._logService.debug('Binding to mouse events:', this.coreMouseService.explainEvents(events));
|
this._logService.debug('Binding to mouse events:', this.coreMouseService.explainEvents(events));
|
||||||
}
|
}
|
||||||
this.element!.classList.add('enable-mouse-events');
|
this.element!.classList.add('enable-mouse-events');
|
||||||
@@ -1125,7 +1125,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|||||||
// other listeners. When screen reader mode is enabled, this could cause issues if the event
|
// other listeners. When screen reader mode is enabled, this could cause issues if the event
|
||||||
// is handled at a higher level, this is a compromise in order to echo keys to the screen
|
// is handled at a higher level, this is a compromise in order to echo keys to the screen
|
||||||
// reader.
|
// reader.
|
||||||
if (!this.optionsService.options.screenReaderMode) {
|
if (!this.optionsService.rawOptions.screenReaderMode) {
|
||||||
return this.cancel(event, true);
|
return this.cancel(event, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1220,7 +1220,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|||||||
protected _inputEvent(ev: InputEvent): boolean {
|
protected _inputEvent(ev: InputEvent): boolean {
|
||||||
// Only support emoji IMEs when screen reader mode is disabled as the event must bubble up to
|
// Only support emoji IMEs when screen reader mode is disabled as the event must bubble up to
|
||||||
// support reading out character input which can doubling up input characters
|
// support reading out character input which can doubling up input characters
|
||||||
if (ev.data && ev.inputType === 'insertText' && !ev.composed && !this.optionsService.options.screenReaderMode) {
|
if (ev.data && ev.inputType === 'insertText' && !ev.composed && !this.optionsService.rawOptions.screenReaderMode) {
|
||||||
if (this._keyPressHandled) {
|
if (this._keyPressHandled) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ export class Viewport extends Disposable implements IViewport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update scroll bar width
|
// Update scroll bar width
|
||||||
if (this._optionsService.options.scrollback === 0) {
|
if (this._optionsService.rawOptions.scrollback === 0) {
|
||||||
this.scrollBarWidth = 0;
|
this.scrollBarWidth = 0;
|
||||||
} else {
|
} else {
|
||||||
this.scrollBarWidth = (this._viewportElement.offsetWidth - this._scrollArea.offsetWidth) || FALLBACK_SCROLL_BAR_WIDTH;
|
this.scrollBarWidth = (this._viewportElement.offsetWidth - this._scrollArea.offsetWidth) || FALLBACK_SCROLL_BAR_WIDTH;
|
||||||
@@ -153,7 +153,7 @@ export class Viewport extends Disposable implements IViewport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the scroll bar visibility changed
|
// If the scroll bar visibility changed
|
||||||
if (this._lastHadScrollBar !== (this._optionsService.options.scrollback > 0)) {
|
if (this._lastHadScrollBar !== (this._optionsService.rawOptions.scrollback > 0)) {
|
||||||
this._refresh(immediate);
|
this._refresh(immediate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,15 +259,15 @@ export class Viewport extends Disposable implements IViewport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _applyScrollModifier(amount: number, ev: WheelEvent): number {
|
private _applyScrollModifier(amount: number, ev: WheelEvent): number {
|
||||||
const modifier = this._optionsService.options.fastScrollModifier;
|
const modifier = this._optionsService.rawOptions.fastScrollModifier;
|
||||||
// Multiply the scroll speed when the modifier is down
|
// Multiply the scroll speed when the modifier is down
|
||||||
if ((modifier === 'alt' && ev.altKey) ||
|
if ((modifier === 'alt' && ev.altKey) ||
|
||||||
(modifier === 'ctrl' && ev.ctrlKey) ||
|
(modifier === 'ctrl' && ev.ctrlKey) ||
|
||||||
(modifier === 'shift' && ev.shiftKey)) {
|
(modifier === 'shift' && ev.shiftKey)) {
|
||||||
return amount * this._optionsService.options.fastScrollSensitivity * this._optionsService.options.scrollSensitivity;
|
return amount * this._optionsService.rawOptions.fastScrollSensitivity * this._optionsService.rawOptions.scrollSensitivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
return amount * this._optionsService.options.scrollSensitivity;
|
return amount * this._optionsService.rawOptions.scrollSensitivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -217,8 +217,8 @@ export class CompositionHelper {
|
|||||||
this._compositionView.style.top = cursorTop + 'px';
|
this._compositionView.style.top = cursorTop + 'px';
|
||||||
this._compositionView.style.height = cellHeight + 'px';
|
this._compositionView.style.height = cellHeight + 'px';
|
||||||
this._compositionView.style.lineHeight = cellHeight + 'px';
|
this._compositionView.style.lineHeight = cellHeight + 'px';
|
||||||
this._compositionView.style.fontFamily = this._optionsService.options.fontFamily;
|
this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;
|
||||||
this._compositionView.style.fontSize = this._optionsService.options.fontSize + 'px';
|
this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';
|
||||||
// Sync the textarea to the exact position of the composition view so the IME knows where the
|
// Sync the textarea to the exact position of the composition view so the IME knows where the
|
||||||
// text is.
|
// text is.
|
||||||
const compositionViewBounds = this._compositionView.getBoundingClientRect();
|
const compositionViewBounds = this._compositionView.getBoundingClientRect();
|
||||||
|
|||||||
@@ -30,17 +30,21 @@ export class Terminal implements ITerminalApi {
|
|||||||
this._core = new TerminalCore(options);
|
this._core = new TerminalCore(options);
|
||||||
this._addonManager = new AddonManager();
|
this._addonManager = new AddonManager();
|
||||||
|
|
||||||
this._publicOptions = {};
|
this._publicOptions = { ... this._core.options };
|
||||||
|
const getter = (propName: string): any => {
|
||||||
|
return this._core.options[propName];
|
||||||
|
};
|
||||||
|
const setter = (propName: string, value: any): void => {
|
||||||
|
this._checkReadonlyOptions(propName);
|
||||||
|
this._core.options[propName] = value;
|
||||||
|
};
|
||||||
|
|
||||||
for (const propName in this._core.options) {
|
for (const propName in this._core.options) {
|
||||||
Object.defineProperty(this._publicOptions, propName, {
|
const desc = {
|
||||||
get: () => {
|
get: getter.bind(this, propName),
|
||||||
return this._core.options[propName];
|
set: setter.bind(this, propName)
|
||||||
},
|
};
|
||||||
set: (value: any) => {
|
Object.defineProperty(this._publicOptions, propName, desc);
|
||||||
this._checkReadonlyOptions(propName);
|
|
||||||
this._core.options[propName] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +58,7 @@ export class Terminal implements ITerminalApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _checkProposedApi(): void {
|
private _checkProposedApi(): void {
|
||||||
if (!this._core.optionsService.options.allowProposedApi) {
|
if (!this._core.optionsService.rawOptions.allowProposedApi) {
|
||||||
throw new Error('You must set the allowProposedApi option to true to use proposed API');
|
throw new Error('You must set the allowProposedApi option to true to use proposed API');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
|||||||
if (this._scaledCharWidth <= 0 && this._scaledCharHeight <= 0) {
|
if (this._scaledCharWidth <= 0 && this._scaledCharHeight <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._charAtlas = acquireCharAtlas(this._optionsService.options, this._rendererId, colorSet, this._scaledCharWidth, this._scaledCharHeight);
|
this._charAtlas = acquireCharAtlas(this._optionsService.rawOptions, this._rendererId, colorSet, this._scaledCharWidth, this._scaledCharHeight);
|
||||||
this._charAtlas.warmUp();
|
this._charAtlas.warmUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +267,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
|||||||
|
|
||||||
// Draw custom characters if applicable
|
// Draw custom characters if applicable
|
||||||
let drawSuccess = false;
|
let drawSuccess = false;
|
||||||
if (this._optionsService.options.customGlyphs !== false) {
|
if (this._optionsService.rawOptions.customGlyphs !== false) {
|
||||||
drawSuccess = tryDrawCustomChar(this._ctx, cell.getChars(), x * this._scaledCellWidth, y * this._scaledCellHeight, this._scaledCellWidth, this._scaledCellHeight);
|
drawSuccess = tryDrawCustomChar(this._ctx, cell.getChars(), x * this._scaledCellWidth, y * this._scaledCellHeight, this._scaledCellWidth, this._scaledCellHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +315,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
|||||||
fg = (cell.isFgDefault()) ? DEFAULT_COLOR : cell.getFgColor();
|
fg = (cell.isFgDefault()) ? DEFAULT_COLOR : cell.getFgColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
const drawInBrightColor = this._optionsService.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8;
|
const drawInBrightColor = this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8;
|
||||||
|
|
||||||
fg += drawInBrightColor ? 8 : 0;
|
fg += drawInBrightColor ? 8 : 0;
|
||||||
this._currentGlyphIdentifier.chars = cell.getChars() || WHITESPACE_CELL_CHAR;
|
this._currentGlyphIdentifier.chars = cell.getChars() || WHITESPACE_CELL_CHAR;
|
||||||
@@ -356,7 +356,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
|||||||
this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getBgColor()).join(',')})`;
|
this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getBgColor()).join(',')})`;
|
||||||
} else {
|
} else {
|
||||||
let bg = cell.getBgColor();
|
let bg = cell.getBgColor();
|
||||||
if (this._optionsService.options.drawBoldTextInBrightColors && cell.isBold() && bg < 8) {
|
if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && bg < 8) {
|
||||||
bg += 8;
|
bg += 8;
|
||||||
}
|
}
|
||||||
this._ctx.fillStyle = this._colors.ansi[bg].css;
|
this._ctx.fillStyle = this._colors.ansi[bg].css;
|
||||||
@@ -370,7 +370,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
|||||||
this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`;
|
this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`;
|
||||||
} else {
|
} else {
|
||||||
let fg = cell.getFgColor();
|
let fg = cell.getFgColor();
|
||||||
if (this._optionsService.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {
|
if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {
|
||||||
fg += 8;
|
fg += 8;
|
||||||
}
|
}
|
||||||
this._ctx.fillStyle = this._colors.ansi[fg].css;
|
this._ctx.fillStyle = this._colors.ansi[fg].css;
|
||||||
@@ -386,7 +386,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
|||||||
|
|
||||||
// Draw custom characters if applicable
|
// Draw custom characters if applicable
|
||||||
let drawSuccess = false;
|
let drawSuccess = false;
|
||||||
if (this._optionsService.options.customGlyphs !== false) {
|
if (this._optionsService.rawOptions.customGlyphs !== false) {
|
||||||
drawSuccess = tryDrawCustomChar(this._ctx, cell.getChars(), x * this._scaledCellWidth, y * this._scaledCellHeight, this._scaledCellWidth, this._scaledCellHeight);
|
drawSuccess = tryDrawCustomChar(this._ctx, cell.getChars(), x * this._scaledCellWidth, y * this._scaledCellHeight, this._scaledCellWidth, this._scaledCellHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,14 +421,14 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
|||||||
* @param isBold If we should use the bold fontWeight.
|
* @param isBold If we should use the bold fontWeight.
|
||||||
*/
|
*/
|
||||||
protected _getFont(isBold: boolean, isItalic: boolean): string {
|
protected _getFont(isBold: boolean, isItalic: boolean): string {
|
||||||
const fontWeight = isBold ? this._optionsService.options.fontWeightBold : this._optionsService.options.fontWeight;
|
const fontWeight = isBold ? this._optionsService.rawOptions.fontWeightBold : this._optionsService.rawOptions.fontWeight;
|
||||||
const fontStyle = isItalic ? 'italic' : '';
|
const fontStyle = isItalic ? 'italic' : '';
|
||||||
|
|
||||||
return `${fontStyle} ${fontWeight} ${this._optionsService.options.fontSize * window.devicePixelRatio}px ${this._optionsService.options.fontFamily}`;
|
return `${fontStyle} ${fontWeight} ${this._optionsService.rawOptions.fontSize * window.devicePixelRatio}px ${this._optionsService.rawOptions.fontFamily}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getContrastColor(cell: CellData): IColor | undefined {
|
private _getContrastColor(cell: CellData): IColor | undefined {
|
||||||
if (this._optionsService.options.minimumContrastRatio === 1) {
|
if (this._optionsService.rawOptions.minimumContrastRatio === 1) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,7 +455,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
|||||||
|
|
||||||
const bgRgba = this._resolveBackgroundRgba(bgColorMode, bgColor, isInverse);
|
const bgRgba = this._resolveBackgroundRgba(bgColorMode, bgColor, isInverse);
|
||||||
const fgRgba = this._resolveForegroundRgba(fgColorMode, fgColor, isInverse, isBold);
|
const fgRgba = this._resolveForegroundRgba(fgColorMode, fgColor, isInverse, isBold);
|
||||||
const result = rgba.ensureContrastRatio(bgRgba, fgRgba, this._optionsService.options.minimumContrastRatio);
|
const result = rgba.ensureContrastRatio(bgRgba, fgRgba, this._optionsService.rawOptions.minimumContrastRatio);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
this._colors.contrastCache.setColor(cell.bg, cell.fg, null);
|
this._colors.contrastCache.setColor(cell.bg, cell.fg, null);
|
||||||
@@ -495,7 +495,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
|||||||
switch (fgColorMode) {
|
switch (fgColorMode) {
|
||||||
case Attributes.CM_P16:
|
case Attributes.CM_P16:
|
||||||
case Attributes.CM_P256:
|
case Attributes.CM_P256:
|
||||||
if (this._optionsService.options.drawBoldTextInBrightColors && bold && fgColor < 8) {
|
if (this._optionsService.rawOptions.drawBoldTextInBrightColors && bold && fgColor < 8) {
|
||||||
fgColor += 8;
|
fgColor += 8;
|
||||||
}
|
}
|
||||||
return this._colors.ansi[fgColor].rgba;
|
return this._colors.ansi[fgColor].rgba;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ export class CursorRenderLayer extends BaseRenderLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onOptionsChanged(): void {
|
public onOptionsChanged(): void {
|
||||||
if (this._optionsService.options.cursorBlink) {
|
if (this._optionsService.rawOptions.cursorBlink) {
|
||||||
if (!this._cursorBlinkStateManager) {
|
if (!this._cursorBlinkStateManager) {
|
||||||
this._cursorBlinkStateManager = new CursorBlinkStateManager(this._coreBrowserService.isFocused, () => {
|
this._cursorBlinkStateManager = new CursorBlinkStateManager(this._coreBrowserService.isFocused, () => {
|
||||||
this._render(true);
|
this._render(true);
|
||||||
@@ -148,7 +148,7 @@ export class CursorRenderLayer extends BaseRenderLayer {
|
|||||||
this._clearCursor();
|
this._clearCursor();
|
||||||
this._ctx.save();
|
this._ctx.save();
|
||||||
this._ctx.fillStyle = this._colors.cursor.css;
|
this._ctx.fillStyle = this._colors.cursor.css;
|
||||||
const cursorStyle = this._optionsService.options.cursorStyle;
|
const cursorStyle = this._optionsService.rawOptions.cursorStyle;
|
||||||
if (cursorStyle && cursorStyle !== 'block') {
|
if (cursorStyle && cursorStyle !== 'block') {
|
||||||
this._cursorRenderers[cursorStyle](cursorX, viewportRelativeCursorY, this._cell);
|
this._cursorRenderers[cursorStyle](cursorX, viewportRelativeCursorY, this._cell);
|
||||||
} else {
|
} else {
|
||||||
@@ -174,7 +174,7 @@ export class CursorRenderLayer extends BaseRenderLayer {
|
|||||||
if (this._state.x === cursorX &&
|
if (this._state.x === cursorX &&
|
||||||
this._state.y === viewportRelativeCursorY &&
|
this._state.y === viewportRelativeCursorY &&
|
||||||
this._state.isFocused === this._coreBrowserService.isFocused &&
|
this._state.isFocused === this._coreBrowserService.isFocused &&
|
||||||
this._state.style === this._optionsService.options.cursorStyle &&
|
this._state.style === this._optionsService.rawOptions.cursorStyle &&
|
||||||
this._state.width === this._cell.getWidth()) {
|
this._state.width === this._cell.getWidth()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -182,13 +182,13 @@ export class CursorRenderLayer extends BaseRenderLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._ctx.save();
|
this._ctx.save();
|
||||||
this._cursorRenderers[this._optionsService.options.cursorStyle || 'block'](cursorX, viewportRelativeCursorY, this._cell);
|
this._cursorRenderers[this._optionsService.rawOptions.cursorStyle || 'block'](cursorX, viewportRelativeCursorY, this._cell);
|
||||||
this._ctx.restore();
|
this._ctx.restore();
|
||||||
|
|
||||||
this._state.x = cursorX;
|
this._state.x = cursorX;
|
||||||
this._state.y = viewportRelativeCursorY;
|
this._state.y = viewportRelativeCursorY;
|
||||||
this._state.isFocused = false;
|
this._state.isFocused = false;
|
||||||
this._state.style = this._optionsService.options.cursorStyle;
|
this._state.style = this._optionsService.rawOptions.cursorStyle;
|
||||||
this._state.width = this._cell.getWidth();
|
this._state.width = this._cell.getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ export class CursorRenderLayer extends BaseRenderLayer {
|
|||||||
private _renderBarCursor(x: number, y: number, cell: ICellData): void {
|
private _renderBarCursor(x: number, y: number, cell: ICellData): void {
|
||||||
this._ctx.save();
|
this._ctx.save();
|
||||||
this._ctx.fillStyle = this._colors.cursor.css;
|
this._ctx.fillStyle = this._colors.cursor.css;
|
||||||
this._fillLeftLineAtCell(x, y, this._optionsService.options.cursorWidth);
|
this._fillLeftLineAtCell(x, y, this._optionsService.rawOptions.cursorWidth);
|
||||||
this._ctx.restore();
|
this._ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export class Renderer extends Disposable implements IRenderer {
|
|||||||
@IOptionsService private readonly _optionsService: IOptionsService
|
@IOptionsService private readonly _optionsService: IOptionsService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
const allowTransparency = this._optionsService.options.allowTransparency;
|
const allowTransparency = this._optionsService.rawOptions.allowTransparency;
|
||||||
this._renderLayers = [
|
this._renderLayers = [
|
||||||
instantiationService.createInstance(TextRenderLayer, this._screenElement, 0, this._colors, allowTransparency, this._id),
|
instantiationService.createInstance(TextRenderLayer, this._screenElement, 0, this._colors, allowTransparency, this._id),
|
||||||
instantiationService.createInstance(SelectionRenderLayer, this._screenElement, 1, this._colors, this._id),
|
instantiationService.createInstance(SelectionRenderLayer, this._screenElement, 1, this._colors, this._id),
|
||||||
@@ -178,18 +178,18 @@ export class Renderer extends Disposable implements IRenderer {
|
|||||||
// will be floored because since lineHeight can never be lower then 1, there
|
// will be floored because since lineHeight can never be lower then 1, there
|
||||||
// is a guarentee that the scaled line height will always be larger than
|
// is a guarentee that the scaled line height will always be larger than
|
||||||
// scaled char height.
|
// scaled char height.
|
||||||
this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._optionsService.options.lineHeight);
|
this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._optionsService.rawOptions.lineHeight);
|
||||||
|
|
||||||
// Calculate the y coordinate within a cell that text should draw from in
|
// Calculate the y coordinate within a cell that text should draw from in
|
||||||
// order to draw in the center of a cell.
|
// order to draw in the center of a cell.
|
||||||
this.dimensions.scaledCharTop = this._optionsService.options.lineHeight === 1 ? 0 : Math.round((this.dimensions.scaledCellHeight - this.dimensions.scaledCharHeight) / 2);
|
this.dimensions.scaledCharTop = this._optionsService.rawOptions.lineHeight === 1 ? 0 : Math.round((this.dimensions.scaledCellHeight - this.dimensions.scaledCharHeight) / 2);
|
||||||
|
|
||||||
// Calculate the scaled cell width, taking the letterSpacing into account.
|
// Calculate the scaled cell width, taking the letterSpacing into account.
|
||||||
this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._optionsService.options.letterSpacing);
|
this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._optionsService.rawOptions.letterSpacing);
|
||||||
|
|
||||||
// Calculate the x coordinate with a cell that text should draw from in
|
// Calculate the x coordinate with a cell that text should draw from in
|
||||||
// order to draw in the center of a cell.
|
// order to draw in the center of a cell.
|
||||||
this.dimensions.scaledCharLeft = Math.floor(this._optionsService.options.letterSpacing / 2);
|
this.dimensions.scaledCharLeft = Math.floor(this._optionsService.rawOptions.letterSpacing / 2);
|
||||||
|
|
||||||
// Recalculate the canvas dimensions; scaled* define the actual number of
|
// Recalculate the canvas dimensions; scaled* define the actual number of
|
||||||
// pixel in the canvas
|
// pixel in the canvas
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ export class TextRenderLayer extends BaseRenderLayer {
|
|||||||
this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getBgColor()).join(',')})`;
|
this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getBgColor()).join(',')})`;
|
||||||
} else {
|
} else {
|
||||||
let bg = cell.getBgColor();
|
let bg = cell.getBgColor();
|
||||||
if (this._optionsService.options.drawBoldTextInBrightColors && cell.isBold() && bg < 8) {
|
if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && bg < 8) {
|
||||||
bg += 8;
|
bg += 8;
|
||||||
}
|
}
|
||||||
this._ctx.fillStyle = this._colors.ansi[bg].css;
|
this._ctx.fillStyle = this._colors.ansi[bg].css;
|
||||||
@@ -237,7 +237,7 @@ export class TextRenderLayer extends BaseRenderLayer {
|
|||||||
this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`;
|
this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`;
|
||||||
} else {
|
} else {
|
||||||
let fg = cell.getFgColor();
|
let fg = cell.getFgColor();
|
||||||
if (this._optionsService.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {
|
if (this._optionsService.rawOptions.drawBoldTextInBrightColors && cell.isBold() && fg < 8) {
|
||||||
fg += 8;
|
fg += 8;
|
||||||
}
|
}
|
||||||
this._ctx.fillStyle = this._colors.ansi[fg].css;
|
this._ctx.fillStyle = this._colors.ansi[fg].css;
|
||||||
@@ -271,7 +271,7 @@ export class TextRenderLayer extends BaseRenderLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onOptionsChanged(): void {
|
public onOptionsChanged(): void {
|
||||||
this._setTransparency(this._optionsService.options.allowTransparency);
|
this._setTransparency(this._optionsService.rawOptions.allowTransparency);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
* @license MIT
|
* @license MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { isFirefox } from 'common/Platform';
|
import { isFirefox, isLegacyEdge } from 'common/Platform';
|
||||||
|
|
||||||
export const INVERTED_DEFAULT_COLOR = 257;
|
export const INVERTED_DEFAULT_COLOR = 257;
|
||||||
export const DIM_OPACITY = 0.5;
|
export const DIM_OPACITY = 0.5;
|
||||||
// The text baseline is set conditionally by browser. Using 'ideographic' for Firefox would
|
// The text baseline is set conditionally by browser. Using 'ideographic' for Firefox or Legacy Edge would
|
||||||
// result in truncated text (Issue 3353). Using 'bottom' for Chrome would result in slightly
|
// result in truncated text (Issue 3353). Using 'bottom' for Chrome would result in slightly
|
||||||
// unaligned Powerline fonts (PR 3356#issuecomment-850928179).
|
// unaligned Powerline fonts (PR 3356#issuecomment-850928179).
|
||||||
export const TEXT_BASELINE: CanvasTextBaseline = isFirefox ? 'bottom' : 'ideographic';
|
export const TEXT_BASELINE: CanvasTextBaseline = isFirefox || isLegacyEdge ? 'bottom' : 'ideographic';
|
||||||
|
|
||||||
export const CHAR_ATLAS_CELL_SPACING = 1;
|
export const CHAR_ATLAS_CELL_SPACING = 1;
|
||||||
|
|||||||
@@ -107,8 +107,8 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|||||||
private _updateDimensions(): void {
|
private _updateDimensions(): void {
|
||||||
this.dimensions.scaledCharWidth = this._charSizeService.width * window.devicePixelRatio;
|
this.dimensions.scaledCharWidth = this._charSizeService.width * window.devicePixelRatio;
|
||||||
this.dimensions.scaledCharHeight = Math.ceil(this._charSizeService.height * window.devicePixelRatio);
|
this.dimensions.scaledCharHeight = Math.ceil(this._charSizeService.height * window.devicePixelRatio);
|
||||||
this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._optionsService.options.letterSpacing);
|
this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._optionsService.rawOptions.letterSpacing);
|
||||||
this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._optionsService.options.lineHeight);
|
this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._optionsService.rawOptions.lineHeight);
|
||||||
this.dimensions.scaledCharLeft = 0;
|
this.dimensions.scaledCharLeft = 0;
|
||||||
this.dimensions.scaledCharTop = 0;
|
this.dimensions.scaledCharTop = 0;
|
||||||
this.dimensions.scaledCanvasWidth = this.dimensions.scaledCellWidth * this._bufferService.cols;
|
this.dimensions.scaledCanvasWidth = this.dimensions.scaledCellWidth * this._bufferService.cols;
|
||||||
@@ -161,16 +161,16 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|||||||
let styles =
|
let styles =
|
||||||
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} {` +
|
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} {` +
|
||||||
` color: ${this._colors.foreground.css};` +
|
` color: ${this._colors.foreground.css};` +
|
||||||
` font-family: ${this._optionsService.options.fontFamily};` +
|
` font-family: ${this._optionsService.rawOptions.fontFamily};` +
|
||||||
` font-size: ${this._optionsService.options.fontSize}px;` +
|
` font-size: ${this._optionsService.rawOptions.fontSize}px;` +
|
||||||
`}`;
|
`}`;
|
||||||
// Text styles
|
// Text styles
|
||||||
styles +=
|
styles +=
|
||||||
`${this._terminalSelector} span:not(.${BOLD_CLASS}) {` +
|
`${this._terminalSelector} span:not(.${BOLD_CLASS}) {` +
|
||||||
` font-weight: ${this._optionsService.options.fontWeight};` +
|
` font-weight: ${this._optionsService.rawOptions.fontWeight};` +
|
||||||
`}` +
|
`}` +
|
||||||
`${this._terminalSelector} span.${BOLD_CLASS} {` +
|
`${this._terminalSelector} span.${BOLD_CLASS} {` +
|
||||||
` font-weight: ${this._optionsService.options.fontWeightBold};` +
|
` font-weight: ${this._optionsService.rawOptions.fontWeightBold};` +
|
||||||
`}` +
|
`}` +
|
||||||
`${this._terminalSelector} span.${ITALIC_CLASS} {` +
|
`${this._terminalSelector} span.${ITALIC_CLASS} {` +
|
||||||
` font-style: italic;` +
|
` font-style: italic;` +
|
||||||
@@ -210,7 +210,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|||||||
` color: ${this._colors.cursorAccent.css};` +
|
` color: ${this._colors.cursorAccent.css};` +
|
||||||
`}` +
|
`}` +
|
||||||
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${CURSOR_CLASS}.${CURSOR_STYLE_BAR_CLASS} {` +
|
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${CURSOR_CLASS}.${CURSOR_STYLE_BAR_CLASS} {` +
|
||||||
` box-shadow: ${this._optionsService.options.cursorWidth}px 0 0 ${this._colors.cursor.css} inset;` +
|
` box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${this._colors.cursor.css} inset;` +
|
||||||
`}` +
|
`}` +
|
||||||
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${CURSOR_CLASS}.${CURSOR_STYLE_UNDERLINE_CLASS} {` +
|
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${CURSOR_CLASS}.${CURSOR_STYLE_UNDERLINE_CLASS} {` +
|
||||||
` box-shadow: 0 -1px 0 ${this._colors.cursor.css} inset;` +
|
` box-shadow: 0 -1px 0 ${this._colors.cursor.css} inset;` +
|
||||||
@@ -356,7 +356,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|||||||
public renderRows(start: number, end: number): void {
|
public renderRows(start: number, end: number): void {
|
||||||
const cursorAbsoluteY = this._bufferService.buffer.ybase + this._bufferService.buffer.y;
|
const cursorAbsoluteY = this._bufferService.buffer.ybase + this._bufferService.buffer.y;
|
||||||
const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);
|
const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);
|
||||||
const cursorBlink = this._optionsService.options.cursorBlink;
|
const cursorBlink = this._optionsService.rawOptions.cursorBlink;
|
||||||
|
|
||||||
for (let y = start; y <= end; y++) {
|
for (let y = start; y <= end; y++) {
|
||||||
const rowElement = this._rowElements[y];
|
const rowElement = this._rowElements[y];
|
||||||
@@ -364,7 +364,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|||||||
|
|
||||||
const row = y + this._bufferService.buffer.ydisp;
|
const row = y + this._bufferService.buffer.ydisp;
|
||||||
const lineData = this._bufferService.buffer.lines.get(row);
|
const lineData = this._bufferService.buffer.lines.get(row);
|
||||||
const cursorStyle = this._optionsService.options.cursorStyle;
|
const cursorStyle = this._optionsService.rawOptions.cursorStyle;
|
||||||
rowElement.appendChild(this._rowFactory.createRow(lineData!, row, row === cursorAbsoluteY, cursorStyle, cursorX, cursorBlink, this.dimensions.actualCellWidth, this._bufferService.cols));
|
rowElement.appendChild(this._rowFactory.createRow(lineData!, row, row === cursorAbsoluteY, cursorStyle, cursorX, cursorBlink, this.dimensions.actualCellWidth, this._bufferService.cols));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ export class DomRendererRowFactory {
|
|||||||
switch (fgColorMode) {
|
switch (fgColorMode) {
|
||||||
case Attributes.CM_P16:
|
case Attributes.CM_P16:
|
||||||
case Attributes.CM_P256:
|
case Attributes.CM_P256:
|
||||||
if (cell.isBold() && fg < 8 && this._optionsService.options.drawBoldTextInBrightColors) {
|
if (cell.isBold() && fg < 8 && this._optionsService.rawOptions.drawBoldTextInBrightColors) {
|
||||||
fg += 8;
|
fg += 8;
|
||||||
}
|
}
|
||||||
if (!this._applyMinimumContrast(charElement, this._colors.background, this._colors.ansi[fg])) {
|
if (!this._applyMinimumContrast(charElement, this._colors.background, this._colors.ansi[fg])) {
|
||||||
@@ -225,7 +225,7 @@ export class DomRendererRowFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor): boolean {
|
private _applyMinimumContrast(element: HTMLElement, bg: IColor, fg: IColor): boolean {
|
||||||
if (this._optionsService.options.minimumContrastRatio === 1) {
|
if (this._optionsService.rawOptions.minimumContrastRatio === 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ export class DomRendererRowFactory {
|
|||||||
|
|
||||||
// Calculate and store in cache
|
// Calculate and store in cache
|
||||||
if (adjustedColor === undefined) {
|
if (adjustedColor === undefined) {
|
||||||
adjustedColor = color.ensureContrastRatio(bg, fg, this._optionsService.options.minimumContrastRatio);
|
adjustedColor = color.ensureContrastRatio(bg, fg, this._optionsService.rawOptions.minimumContrastRatio);
|
||||||
this._colors.contrastCache.setColor(this._workCell.bg, this._workCell.fg, adjustedColor ?? null);
|
this._colors.contrastCache.setColor(this._workCell.bg, this._workCell.fg, adjustedColor ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ class DomMeasureStrategy implements IMeasureStrategy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public measure(): IReadonlyMeasureResult {
|
public measure(): IReadonlyMeasureResult {
|
||||||
this._measureElement.style.fontFamily = this._optionsService.options.fontFamily;
|
this._measureElement.style.fontFamily = this._optionsService.rawOptions.fontFamily;
|
||||||
this._measureElement.style.fontSize = `${this._optionsService.options.fontSize}px`;
|
this._measureElement.style.fontSize = `${this._optionsService.rawOptions.fontSize}px`;
|
||||||
|
|
||||||
// Note that this triggers a synchronous layout
|
// Note that this triggers a synchronous layout
|
||||||
const geometry = this._measureElement.getBoundingClientRect();
|
const geometry = this._measureElement.getBoundingClientRect();
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|||||||
*/
|
*/
|
||||||
public shouldForceSelection(event: MouseEvent): boolean {
|
public shouldForceSelection(event: MouseEvent): boolean {
|
||||||
if (Browser.isMac) {
|
if (Browser.isMac) {
|
||||||
return event.altKey && this._optionsService.options.macOptionClickForcesSelection;
|
return event.altKey && this._optionsService.rawOptions.macOptionClickForcesSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
return event.shiftKey;
|
return event.shiftKey;
|
||||||
@@ -567,7 +567,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|||||||
* @param event the mouse or keyboard event
|
* @param event the mouse or keyboard event
|
||||||
*/
|
*/
|
||||||
public shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean {
|
public shouldColumnSelect(event: KeyboardEvent | MouseEvent): boolean {
|
||||||
return event.altKey && !(Browser.isMac && this._optionsService.options.macOptionClickForcesSelection);
|
return event.altKey && !(Browser.isMac && this._optionsService.rawOptions.macOptionClickForcesSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -993,7 +993,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|||||||
if (cell.getWidth() === 0) {
|
if (cell.getWidth() === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this._optionsService.options.wordSeparator.indexOf(cell.getChars()) >= 0;
|
return this._optionsService.rawOptions.wordSeparator.indexOf(cell.getChars()) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export class SoundService implements ISoundService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const bellAudioSource = ctx.createBufferSource();
|
const bellAudioSource = ctx.createBufferSource();
|
||||||
ctx.decodeAudioData(this._base64ToArrayBuffer(this._removeMimeType(this._optionsService.options.bellSound)), (buffer) => {
|
ctx.decodeAudioData(this._base64ToArrayBuffer(this._removeMimeType(this._optionsService.rawOptions.bellSound)), (buffer) => {
|
||||||
bellAudioSource.buffer = buffer;
|
bellAudioSource.buffer = buffer;
|
||||||
bellAudioSource.connect(ctx.destination);
|
bellAudioSource.connect(ctx.destination);
|
||||||
bellAudioSource.start(0);
|
bellAudioSource.start(0);
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected _setup(): void {
|
protected _setup(): void {
|
||||||
if (this.optionsService.options.windowsMode) {
|
if (this.optionsService.rawOptions.windowsMode) {
|
||||||
this._enableWindowsMode();
|
this._enableWindowsMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,7 +267,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
|||||||
this.buffers.resize(this.cols, this.rows);
|
this.buffers.resize(this.cols, this.rows);
|
||||||
break;
|
break;
|
||||||
case 'windowsMode':
|
case 'windowsMode':
|
||||||
if (this.optionsService.options.windowsMode) {
|
if (this.optionsService.rawOptions.windowsMode) {
|
||||||
this._enableWindowsMode();
|
this._enableWindowsMode();
|
||||||
} else {
|
} else {
|
||||||
this._windowsMode?.dispose();
|
this._windowsMode?.dispose();
|
||||||
|
|||||||
+10
-10
@@ -177,8 +177,8 @@ class DECRQSS implements IDcsHandler {
|
|||||||
break;
|
break;
|
||||||
case ' q': // DECSCUSR
|
case ' q': // DECSCUSR
|
||||||
const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 };
|
const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 };
|
||||||
let style = STYLES[this._optionsService.options.cursorStyle];
|
let style = STYLES[this._optionsService.rawOptions.cursorStyle];
|
||||||
style -= this._optionsService.options.cursorBlink ? 1 : 0;
|
style -= this._optionsService.rawOptions.cursorBlink ? 1 : 0;
|
||||||
this._coreService.triggerDataEvent(`${C0.ESC}P1$r${style} q${C0.ESC}\\`);
|
this._coreService.triggerDataEvent(`${C0.ESC}P1$r${style} q${C0.ESC}\\`);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -603,7 +603,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
|||||||
let code: number;
|
let code: number;
|
||||||
let chWidth: number;
|
let chWidth: number;
|
||||||
const charset = this._charsetService.charset;
|
const charset = this._charsetService.charset;
|
||||||
const screenReaderMode = this._optionsService.options.screenReaderMode;
|
const screenReaderMode = this._optionsService.rawOptions.screenReaderMode;
|
||||||
const cols = this._bufferService.cols;
|
const cols = this._bufferService.cols;
|
||||||
const wraparoundMode = this._coreService.decPrivateModes.wraparound;
|
const wraparoundMode = this._coreService.decPrivateModes.wraparound;
|
||||||
const insertMode = this._coreService.modes.insertMode;
|
const insertMode = this._coreService.modes.insertMode;
|
||||||
@@ -745,7 +745,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
|||||||
if (id.final === 't' && !id.prefix && !id.intermediates) {
|
if (id.final === 't' && !id.prefix && !id.intermediates) {
|
||||||
// security: always check whether window option is allowed
|
// security: always check whether window option is allowed
|
||||||
return this._parser.registerCsiHandler(id, params => {
|
return this._parser.registerCsiHandler(id, params => {
|
||||||
if (!paramToWindowOption(params.params[0], this._optionsService.options.windowOptions)) {
|
if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return callback(params);
|
return callback(params);
|
||||||
@@ -800,7 +800,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
|||||||
*/
|
*/
|
||||||
public lineFeed(): boolean {
|
public lineFeed(): boolean {
|
||||||
this._dirtyRowService.markDirty(this._activeBuffer.y);
|
this._dirtyRowService.markDirty(this._activeBuffer.y);
|
||||||
if (this._optionsService.options.convertEol) {
|
if (this._optionsService.rawOptions.convertEol) {
|
||||||
this._activeBuffer.x = 0;
|
this._activeBuffer.x = 0;
|
||||||
}
|
}
|
||||||
this._activeBuffer.y++;
|
this._activeBuffer.y++;
|
||||||
@@ -904,7 +904,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
|||||||
}
|
}
|
||||||
const originalX = this._activeBuffer.x;
|
const originalX = this._activeBuffer.x;
|
||||||
this._activeBuffer.x = this._activeBuffer.nextStop();
|
this._activeBuffer.x = this._activeBuffer.nextStop();
|
||||||
if (this._optionsService.options.screenReaderMode) {
|
if (this._optionsService.rawOptions.screenReaderMode) {
|
||||||
this._onA11yTab.fire(this._activeBuffer.x - originalX);
|
this._onA11yTab.fire(this._activeBuffer.x - originalX);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -1763,7 +1763,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
|||||||
* @param term The terminal name to evaluate
|
* @param term The terminal name to evaluate
|
||||||
*/
|
*/
|
||||||
private _is(term: string): boolean {
|
private _is(term: string): boolean {
|
||||||
return (this._optionsService.options.termName + '').indexOf(term) === 0;
|
return (this._optionsService.rawOptions.termName + '').indexOf(term) === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1929,7 +1929,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
|||||||
* This is only active if 'SetWinLines' (24) is enabled
|
* This is only active if 'SetWinLines' (24) is enabled
|
||||||
* through `options.windowsOptions`.
|
* through `options.windowsOptions`.
|
||||||
*/
|
*/
|
||||||
if (this._optionsService.options.windowOptions.setWinLines) {
|
if (this._optionsService.rawOptions.windowOptions.setWinLines) {
|
||||||
this._bufferService.resize(132, this._bufferService.rows);
|
this._bufferService.resize(132, this._bufferService.rows);
|
||||||
this._onRequestReset.fire();
|
this._onRequestReset.fire();
|
||||||
}
|
}
|
||||||
@@ -2163,7 +2163,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
|||||||
* This is only active if 'SetWinLines' (24) is enabled
|
* This is only active if 'SetWinLines' (24) is enabled
|
||||||
* through `options.windowsOptions`.
|
* through `options.windowsOptions`.
|
||||||
*/
|
*/
|
||||||
if (this._optionsService.options.windowOptions.setWinLines) {
|
if (this._optionsService.rawOptions.windowOptions.setWinLines) {
|
||||||
this._bufferService.resize(80, this._bufferService.rows);
|
this._bufferService.resize(80, this._bufferService.rows);
|
||||||
this._onRequestReset.fire();
|
this._onRequestReset.fire();
|
||||||
}
|
}
|
||||||
@@ -2740,7 +2740,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
|||||||
* Ps >= 24 not implemented
|
* Ps >= 24 not implemented
|
||||||
*/
|
*/
|
||||||
public windowOptions(params: IParams): boolean {
|
public windowOptions(params: IParams): boolean {
|
||||||
if (!paramToWindowOption(params.params[0], this._optionsService.options.windowOptions)) {
|
if (!paramToWindowOption(params.params[0], this._optionsService.rawOptions.windowOptions)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const second = (params.length > 1) ? params.params[1] : 0;
|
const second = (params.length > 1) ? params.params[1] : 0;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const userAgent = (isNode) ? 'node' : navigator.userAgent;
|
|||||||
const platform = (isNode) ? 'node' : navigator.platform;
|
const platform = (isNode) ? 'node' : navigator.platform;
|
||||||
|
|
||||||
export const isFirefox = userAgent.includes('Firefox');
|
export const isFirefox = userAgent.includes('Firefox');
|
||||||
|
export const isLegacyEdge = userAgent.includes('Edge');
|
||||||
export const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
|
export const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
|
||||||
|
|
||||||
// Find the users platform. We use this to interpret the meta key
|
// Find the users platform. We use this to interpret the meta key
|
||||||
|
|||||||
@@ -120,12 +120,13 @@ export class MockLogService implements ILogService {
|
|||||||
|
|
||||||
export class MockOptionsService implements IOptionsService {
|
export class MockOptionsService implements IOptionsService {
|
||||||
public serviceBrand: any;
|
public serviceBrand: any;
|
||||||
public options: ITerminalOptions = clone(DEFAULT_OPTIONS);
|
public readonly rawOptions: ITerminalOptions = clone(DEFAULT_OPTIONS);
|
||||||
|
public options: ITerminalOptions = this.rawOptions;
|
||||||
public onOptionChange: IEvent<string> = new EventEmitter<string>().event;
|
public onOptionChange: IEvent<string> = new EventEmitter<string>().event;
|
||||||
constructor(testOptions?: Partial<ITerminalOptions>) {
|
constructor(testOptions?: Partial<ITerminalOptions>) {
|
||||||
if (testOptions) {
|
if (testOptions) {
|
||||||
for (const key of Object.keys(testOptions)) {
|
for (const key of Object.keys(testOptions)) {
|
||||||
this.options[key] = testOptions[key];
|
this.rawOptions[key] = testOptions[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export class Buffer implements IBuffer {
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
const correctBufferLength = rows + this._optionsService.options.scrollback;
|
const correctBufferLength = rows + this._optionsService.rawOptions.scrollback;
|
||||||
|
|
||||||
return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength;
|
return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength;
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,7 @@ export class Buffer implements IBuffer {
|
|||||||
if (this._rows < newRows) {
|
if (this._rows < newRows) {
|
||||||
for (let y = this._rows; y < newRows; y++) {
|
for (let y = this._rows; y < newRows; y++) {
|
||||||
if (this.lines.length < newRows + this.ybase) {
|
if (this.lines.length < newRows + this.ybase) {
|
||||||
if (this._optionsService.options.windowsMode) {
|
if (this._optionsService.rawOptions.windowsMode) {
|
||||||
// Just add the new missing rows on Windows as conpty reprints the screen with it's
|
// Just add the new missing rows on Windows as conpty reprints the screen with it's
|
||||||
// view of the world. Once a line enters scrollback for conpty it remains there
|
// view of the world. Once a line enters scrollback for conpty it remains there
|
||||||
this.lines.push(new BufferLine(newCols, nullCell));
|
this.lines.push(new BufferLine(newCols, nullCell));
|
||||||
@@ -252,7 +252,7 @@ export class Buffer implements IBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private get _isReflowEnabled(): boolean {
|
private get _isReflowEnabled(): boolean {
|
||||||
return this._hasScrollback && !this._optionsService.options.windowsMode;
|
return this._hasScrollback && !this._optionsService.rawOptions.windowsMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _reflow(newCols: number, newRows: number): void {
|
private _reflow(newCols: number, newRows: number): void {
|
||||||
@@ -367,6 +367,11 @@ export class Buffer implements IBuffer {
|
|||||||
let srcCol = lastLineLength;
|
let srcCol = lastLineLength;
|
||||||
while (srcLineIndex >= 0) {
|
while (srcLineIndex >= 0) {
|
||||||
const cellsToCopy = Math.min(srcCol, destCol);
|
const cellsToCopy = Math.min(srcCol, destCol);
|
||||||
|
if (wrappedLines[destLineIndex] === undefined) {
|
||||||
|
// Sanity check that the line exists, this has been known to fail for an unknown reason
|
||||||
|
// which would stop the reflow from happening if an exception would throw.
|
||||||
|
break;
|
||||||
|
}
|
||||||
wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol - cellsToCopy, destCol - cellsToCopy, cellsToCopy, true);
|
wrappedLines[destLineIndex].copyCellsFrom(wrappedLines[srcLineIndex], srcCol - cellsToCopy, destCol - cellsToCopy, cellsToCopy, true);
|
||||||
destCol -= cellsToCopy;
|
destCol -= cellsToCopy;
|
||||||
if (destCol === 0) {
|
if (destCol === 0) {
|
||||||
@@ -550,7 +555,7 @@ export class Buffer implements IBuffer {
|
|||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; i < this._cols; i += this._optionsService.options.tabStopWidth) {
|
for (; i < this._cols; i += this._optionsService.rawOptions.tabStopWidth) {
|
||||||
this.tabs[i] = true;
|
this.tabs[i] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ export class BufferService extends Disposable implements IBufferService {
|
|||||||
@IOptionsService private _optionsService: IOptionsService
|
@IOptionsService private _optionsService: IOptionsService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this.cols = Math.max(_optionsService.options.cols || 0, MINIMUM_COLS);
|
this.cols = Math.max(_optionsService.rawOptions.cols || 0, MINIMUM_COLS);
|
||||||
this.rows = Math.max(_optionsService.options.rows || 0, MINIMUM_ROWS);
|
this.rows = Math.max(_optionsService.rawOptions.rows || 0, MINIMUM_ROWS);
|
||||||
this.buffers = new BufferSet(_optionsService, this);
|
this.buffers = new BufferSet(_optionsService, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export class CoreService extends Disposable implements ICoreService {
|
|||||||
|
|
||||||
public triggerDataEvent(data: string, wasUserInput: boolean = false): void {
|
public triggerDataEvent(data: string, wasUserInput: boolean = false): void {
|
||||||
// Prevents all events to pty process if stdin is disabled
|
// Prevents all events to pty process if stdin is disabled
|
||||||
if (this._optionsService.options.disableStdin) {
|
if (this._optionsService.rawOptions.disableStdin) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ export class CoreService extends Disposable implements ICoreService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public triggerBinaryEvent(data: string): void {
|
public triggerBinaryEvent(data: string): void {
|
||||||
if (this._optionsService.options.disableStdin) {
|
if (this._optionsService.rawOptions.disableStdin) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._logService.debug(`sending binary "${data}"`, () => data.split('').map(e => e.charCodeAt(0)));
|
this._logService.debug(`sending binary "${data}"`, () => data.split('').map(e => e.charCodeAt(0)));
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export class LogService implements ILogService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _updateLogLevel(): void {
|
private _updateLogLevel(): void {
|
||||||
this.logLevel = optionsKeyToLogLevel[this._optionsService.options.logLevel];
|
this.logLevel = optionsKeyToLogLevel[this._optionsService.rawOptions.logLevel];
|
||||||
}
|
}
|
||||||
|
|
||||||
private _evalLazyOptionalParams(optionalParams: any[]): void {
|
private _evalLazyOptionalParams(optionalParams: any[]): void {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ describe('OptionsService', () => {
|
|||||||
describe('constructor', () => {
|
describe('constructor', () => {
|
||||||
const originalError = console.error;
|
const originalError = console.error;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
console.error = () => {};
|
console.error = () => { };
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
console.error = originalError;
|
console.error = originalError;
|
||||||
@@ -26,7 +26,11 @@ describe('OptionsService', () => {
|
|||||||
assert.equal(optionsService.getOption('cols'), 80);
|
assert.equal(optionsService.getOption('cols'), 80);
|
||||||
});
|
});
|
||||||
it('uses default value if invalid constructor option value passed', () => {
|
it('uses default value if invalid constructor option value passed', () => {
|
||||||
assert.equal(new OptionsService({tabStopWidth: 0}).getOption('tabStopWidth'), DEFAULT_OPTIONS.tabStopWidth);
|
assert.equal(new OptionsService({ tabStopWidth: 0 }).getOption('tabStopWidth'), DEFAULT_OPTIONS.tabStopWidth);
|
||||||
|
});
|
||||||
|
it('object.keys return the correct number of options', () => {
|
||||||
|
const optionsService = new OptionsService({ cols: 80, rows: 25 });
|
||||||
|
assert.notEqual(Object.keys(optionsService.options).length, 0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('setOption', () => {
|
describe('setOption', () => {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ const FONT_WEIGHT_OPTIONS: Extract<FontWeight, string>[] = ['normal', 'bold', '1
|
|||||||
export class OptionsService implements IOptionsService {
|
export class OptionsService implements IOptionsService {
|
||||||
public serviceBrand: any;
|
public serviceBrand: any;
|
||||||
|
|
||||||
private _options: ITerminalOptions;
|
public readonly rawOptions: ITerminalOptions;
|
||||||
public options: ITerminalOptions;
|
public options: ITerminalOptions;
|
||||||
|
|
||||||
private _onOptionChange = new EventEmitter<string>();
|
private _onOptionChange = new EventEmitter<string>();
|
||||||
@@ -68,12 +68,12 @@ export class OptionsService implements IOptionsService {
|
|||||||
|
|
||||||
constructor(options: Partial<ITerminalOptions>) {
|
constructor(options: Partial<ITerminalOptions>) {
|
||||||
// set the default value of each option
|
// set the default value of each option
|
||||||
this._options = { ...DEFAULT_OPTIONS };
|
const defaultOptions = { ...DEFAULT_OPTIONS };
|
||||||
for (const key in options) {
|
for (const key in options) {
|
||||||
if (key in this._options) {
|
if (key in defaultOptions) {
|
||||||
try {
|
try {
|
||||||
const newValue = options[key];
|
const newValue = options[key];
|
||||||
this._options[key] = this._sanitizeAndValidateOption(key, newValue);
|
defaultOptions[key] = this._sanitizeAndValidateOption(key, newValue);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
@@ -81,34 +81,39 @@ export class OptionsService implements IOptionsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set up getters and setters for each option
|
// set up getters and setters for each option
|
||||||
this.options = this._setupOptions(this._options);
|
this.rawOptions = defaultOptions;
|
||||||
|
this.options = { ... defaultOptions };
|
||||||
|
this._setupOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setupOptions(options: ITerminalOptions): ITerminalOptions {
|
private _setupOptions(): void {
|
||||||
const copiedOptions = { ... options };
|
const getter = (propName: string): any => {
|
||||||
for (const propName in copiedOptions) {
|
if (!(propName in DEFAULT_OPTIONS)) {
|
||||||
Object.defineProperty(copiedOptions, propName, {
|
throw new Error(`No option with key "${propName}"`);
|
||||||
get: () => {
|
}
|
||||||
if (!(propName in DEFAULT_OPTIONS)) {
|
return this.rawOptions[propName];
|
||||||
throw new Error(`No option with key "${propName}"`);
|
};
|
||||||
}
|
|
||||||
return this._options[propName];
|
|
||||||
},
|
|
||||||
set: (value: any) => {
|
|
||||||
if (!(propName in DEFAULT_OPTIONS)) {
|
|
||||||
throw new Error(`No option with key "${propName}"`);
|
|
||||||
}
|
|
||||||
|
|
||||||
value = this._sanitizeAndValidateOption(propName, value);
|
const setter = (propName: string, value: any): void => {
|
||||||
// Don't fire an option change event if they didn't change
|
if (!(propName in DEFAULT_OPTIONS)) {
|
||||||
if (this._options[propName] !== value) {
|
throw new Error(`No option with key "${propName}"`);
|
||||||
this._options[propName] = value;
|
}
|
||||||
this._onOptionChange.fire(propName);
|
|
||||||
}
|
value = this._sanitizeAndValidateOption(propName, value);
|
||||||
}
|
// Don't fire an option change event if they didn't change
|
||||||
});
|
if (this.rawOptions[propName] !== value) {
|
||||||
|
this.rawOptions[propName] = value;
|
||||||
|
this._onOptionChange.fire(propName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const propName in this.rawOptions) {
|
||||||
|
const desc = {
|
||||||
|
get: getter.bind(this, propName),
|
||||||
|
set: setter.bind(this, propName)
|
||||||
|
};
|
||||||
|
Object.defineProperty(this.options, propName, desc);
|
||||||
}
|
}
|
||||||
return copiedOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public setOption(key: string, value: any): void {
|
public setOption(key: string, value: any): void {
|
||||||
|
|||||||
@@ -188,6 +188,12 @@ export const IOptionsService = createDecorator<IOptionsService>('OptionsService'
|
|||||||
export interface IOptionsService {
|
export interface IOptionsService {
|
||||||
serviceBrand: undefined;
|
serviceBrand: undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read only access to the raw options object, this is an internal-only fast path for accessing
|
||||||
|
* single options without any validation as we trust TypeScript to enforce correct usage
|
||||||
|
* internally.
|
||||||
|
*/
|
||||||
|
readonly rawOptions: Readonly<ITerminalOptions>;
|
||||||
readonly options: ITerminalOptions;
|
readonly options: ITerminalOptions;
|
||||||
|
|
||||||
readonly onOptionChange: IEvent<string>;
|
readonly onOptionChange: IEvent<string>;
|
||||||
|
|||||||
@@ -5,10 +5,11 @@
|
|||||||
|
|
||||||
import { deepStrictEqual, strictEqual, throws } from 'assert';
|
import { deepStrictEqual, strictEqual, throws } from 'assert';
|
||||||
import { Terminal } from 'headless/public/Terminal';
|
import { Terminal } from 'headless/public/Terminal';
|
||||||
|
import { ITerminalOptions } from 'xterm-headless';
|
||||||
|
|
||||||
let term: Terminal;
|
let term: Terminal;
|
||||||
|
|
||||||
describe('Headless API Tests', function(): void {
|
describe('Headless API Tests', function (): void {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Create default terminal to be used by most tests
|
// Create default terminal to be used by most tests
|
||||||
term = new Terminal();
|
term = new Terminal();
|
||||||
@@ -119,13 +120,43 @@ describe('Headless API Tests', function(): void {
|
|||||||
strictEqual(term.getOption('scrollback'), 50);
|
strictEqual(term.getOption('scrollback'), 50);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('options', () => {
|
||||||
|
const termOptions = {
|
||||||
|
cols: 80,
|
||||||
|
rows: 24
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
term = new Terminal(termOptions);
|
||||||
|
});
|
||||||
|
it('get options', () => {
|
||||||
|
const options: ITerminalOptions = term.options;
|
||||||
|
strictEqual(options.cols, 80);
|
||||||
|
strictEqual(options.rows, 24);
|
||||||
|
});
|
||||||
|
it('set options', async () => {
|
||||||
|
const options: ITerminalOptions = term.options;
|
||||||
|
throws(() => options.cols = 40);
|
||||||
|
throws(() => options.rows = 20);
|
||||||
|
term.options.scrollback = 1;
|
||||||
|
strictEqual(term.options.scrollback, 1);
|
||||||
|
term.options= {
|
||||||
|
fontSize: 12,
|
||||||
|
fontFamily: 'Arial'
|
||||||
|
};
|
||||||
|
strictEqual(term.options.fontSize, 12);
|
||||||
|
strictEqual(term.options.fontFamily, 'Arial');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('loadAddon', () => {
|
describe('loadAddon', () => {
|
||||||
it('constructor', async () => {
|
it('constructor', async () => {
|
||||||
term = new Terminal({ cols: 5 });
|
term = new Terminal({ cols: 5 });
|
||||||
let cols = 0;
|
let cols = 0;
|
||||||
term.loadAddon({
|
term.loadAddon({
|
||||||
activate: (t) => cols = t.cols,
|
activate: (t) => cols = t.cols,
|
||||||
dispose: () => {}
|
dispose: () => { }
|
||||||
});
|
});
|
||||||
strictEqual(cols, 5);
|
strictEqual(cols, 5);
|
||||||
});
|
});
|
||||||
@@ -133,7 +164,7 @@ describe('Headless API Tests', function(): void {
|
|||||||
it('dispose (addon)', async () => {
|
it('dispose (addon)', async () => {
|
||||||
let disposeCalled = false;
|
let disposeCalled = false;
|
||||||
const addon = {
|
const addon = {
|
||||||
activate: () => {},
|
activate: () => { },
|
||||||
dispose: () => disposeCalled = true
|
dispose: () => disposeCalled = true
|
||||||
};
|
};
|
||||||
term.loadAddon(addon);
|
term.loadAddon(addon);
|
||||||
@@ -145,7 +176,7 @@ describe('Headless API Tests', function(): void {
|
|||||||
it('dispose (terminal)', async () => {
|
it('dispose (terminal)', async () => {
|
||||||
let disposeCalled = false;
|
let disposeCalled = false;
|
||||||
term.loadAddon({
|
term.loadAddon({
|
||||||
activate: () => {},
|
activate: () => { },
|
||||||
dispose: () => disposeCalled = true
|
dispose: () => disposeCalled = true
|
||||||
});
|
});
|
||||||
strictEqual(disposeCalled, false);
|
strictEqual(disposeCalled, false);
|
||||||
|
|||||||
@@ -7,19 +7,61 @@ import { IEvent } from 'common/EventEmitter';
|
|||||||
import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi';
|
import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi';
|
||||||
import { ParserApi } from 'common/public/ParserApi';
|
import { ParserApi } from 'common/public/ParserApi';
|
||||||
import { UnicodeApi } from 'common/public/UnicodeApi';
|
import { UnicodeApi } from 'common/public/UnicodeApi';
|
||||||
import { IBufferNamespace as IBufferNamespaceApi, IMarker, IModes, IParser, ITerminalAddon, ITerminalOptions, IUnicodeHandling, Terminal as ITerminalApi } from 'xterm-headless';
|
import { IBufferNamespace as IBufferNamespaceApi, IMarker, IModes, IParser, ITerminalAddon, IUnicodeHandling, Terminal as ITerminalApi } from 'xterm-headless';
|
||||||
import { Terminal as TerminalCore } from 'headless/Terminal';
|
import { Terminal as TerminalCore } from 'headless/Terminal';
|
||||||
import { AddonManager } from 'common/public/AddonManager';
|
import { AddonManager } from 'common/public/AddonManager';
|
||||||
|
import { ITerminalOptions } from 'common/Types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The set of options that only have an effect when set in the Terminal constructor.
|
||||||
|
*/
|
||||||
|
const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];
|
||||||
|
|
||||||
export class Terminal implements ITerminalApi {
|
export class Terminal implements ITerminalApi {
|
||||||
private _core: TerminalCore;
|
private _core: TerminalCore;
|
||||||
private _addonManager: AddonManager;
|
private _addonManager: AddonManager;
|
||||||
private _parser: IParser | undefined;
|
private _parser: IParser | undefined;
|
||||||
private _buffer: BufferNamespaceApi | undefined;
|
private _buffer: BufferNamespaceApi | undefined;
|
||||||
|
private _publicOptions: ITerminalOptions;
|
||||||
|
|
||||||
constructor(options?: ITerminalOptions) {
|
constructor(options?: ITerminalOptions) {
|
||||||
this._core = new TerminalCore(options);
|
this._core = new TerminalCore(options);
|
||||||
this._addonManager = new AddonManager();
|
this._addonManager = new AddonManager();
|
||||||
|
|
||||||
|
this._publicOptions = { ... this._core.options };
|
||||||
|
const getter = (propName: string): any => {
|
||||||
|
return this._core.options[propName];
|
||||||
|
};
|
||||||
|
const setter = (propName: string, value: any): void => {
|
||||||
|
this._checkReadonlyOptions(propName);
|
||||||
|
this._core.options[propName] = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const propName in this._core.options) {
|
||||||
|
Object.defineProperty(this._publicOptions, propName, {
|
||||||
|
get: () => {
|
||||||
|
return this._core.options[propName];
|
||||||
|
},
|
||||||
|
set: (value: any) => {
|
||||||
|
this._checkReadonlyOptions(propName);
|
||||||
|
this._core.options[propName] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const desc = {
|
||||||
|
get: getter.bind(this, propName),
|
||||||
|
set: setter.bind(this, propName)
|
||||||
|
};
|
||||||
|
Object.defineProperty(this._publicOptions, propName, desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _checkReadonlyOptions(propName: string): void {
|
||||||
|
// Throw an error if any constructor only option is modified
|
||||||
|
// from terminal.options
|
||||||
|
// Modifications from anywhere else are allowed
|
||||||
|
if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) {
|
||||||
|
throw new Error(`Option "${propName}" can only be set in the constructor`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _checkProposedApi(): void {
|
private _checkProposedApi(): void {
|
||||||
@@ -82,6 +124,14 @@ export class Terminal implements ITerminalApi {
|
|||||||
wraparoundMode: m.wraparound
|
wraparoundMode: m.wraparound
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
public get options(): ITerminalOptions {
|
||||||
|
return this._publicOptions;
|
||||||
|
}
|
||||||
|
public set options(options: ITerminalOptions) {
|
||||||
|
for (const propName in options) {
|
||||||
|
this._publicOptions[propName] = options[propName];
|
||||||
|
}
|
||||||
|
}
|
||||||
public resize(columns: number, rows: number): void {
|
public resize(columns: number, rows: number): void {
|
||||||
this._verifyIntegers(columns, rows);
|
this._verifyIntegers(columns, rows);
|
||||||
this._core.resize(columns, rows);
|
this._core.resize(columns, rows);
|
||||||
|
|||||||
@@ -189,6 +189,10 @@ describe('API Integration Tests', function(): void {
|
|||||||
assert.equal(await page.evaluate(`window.term.options.fontSize`), 30);
|
assert.equal(await page.evaluate(`window.term.options.fontSize`), 30);
|
||||||
assert.equal(await page.evaluate(`window.term.options.fontFamily`), 'Arial');
|
assert.equal(await page.evaluate(`window.term.options.fontFamily`), 'Arial');
|
||||||
});
|
});
|
||||||
|
it('object.keys return the correct number of options', async () => {
|
||||||
|
await openTerminal(page);
|
||||||
|
assert.notEqual(await page.evaluate(`Object.keys(window.term.options).length`), 0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('renderer', () => {
|
describe('renderer', () => {
|
||||||
|
|||||||
Vendored
+23
@@ -534,6 +534,29 @@ declare module 'xterm-headless' {
|
|||||||
*/
|
*/
|
||||||
readonly modes: IModes;
|
readonly modes: IModes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets or sets the terminal options. This supports setting multiple options.
|
||||||
|
*
|
||||||
|
* @example Get a single option
|
||||||
|
* ```typescript
|
||||||
|
* console.log(terminal.options.fontSize);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @example Set a single option
|
||||||
|
* ```typescript
|
||||||
|
* terminal.options.fontSize = 12;
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @example Set multiple options
|
||||||
|
* ```typescript
|
||||||
|
* terminal.options = {
|
||||||
|
* fontSize: 12,
|
||||||
|
* fontFamily: 'Arial',
|
||||||
|
* };
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
options: ITerminalOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Natural language strings that can be localized.
|
* Natural language strings that can be localized.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user