mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge branch 'master' into osc52
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
{
|
||||
"name": "xterm.js",
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:0-18-buster",
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:18-bookworm",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/node:1": {} // yarn
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": 18
|
||||
} // yarn
|
||||
},
|
||||
"forwardPorts": [
|
||||
3000
|
||||
],
|
||||
"postCreateCommand": "yarn install",
|
||||
"postCreateCommand": "yarn install && yarn setup",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
|
||||
Vendored
+1
-1
@@ -61,7 +61,7 @@
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["start"],
|
||||
"stopOnEntry": true,
|
||||
"runtimeVersion": "16",
|
||||
"runtimeVersion": "18",
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "App listening to (http://.*?:[0-9]+)"
|
||||
|
||||
@@ -223,6 +223,7 @@ Xterm.js is used in several world-class applications to provide great terminal e
|
||||
- [**Cloudtutor.io**](https://cloudtutor.io): innovative online learning platform that offers users access to an interactive lab.
|
||||
- [**Helix Editor Playground**](https://github.com/tomgroenwoldt/helix-editor-playground): Online playground for the terminal based helix editor.
|
||||
- [**Coder**](https://github.com/coder/coder): Self-Hosted Remote Development Environments
|
||||
- [**Wave Terminal**](https://waveterm.dev): An open-source, ai-native, terminal built for seamless workflows.
|
||||
- [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.
|
||||
|
||||
@@ -25,7 +25,9 @@ module.exports = {
|
||||
filename: mainFile,
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd'
|
||||
libraryTarget: 'umd',
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production'
|
||||
};
|
||||
|
||||
@@ -33,7 +33,9 @@ module.exports = {
|
||||
filename: mainFile,
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd'
|
||||
libraryTarget: 'umd',
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production'
|
||||
};
|
||||
|
||||
@@ -25,7 +25,9 @@ module.exports = {
|
||||
filename: mainFile,
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd'
|
||||
libraryTarget: 'umd',
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production'
|
||||
};
|
||||
|
||||
@@ -33,7 +33,9 @@ const addon = {
|
||||
filename: mainFile,
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd'
|
||||
libraryTarget: 'umd',
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production'
|
||||
};
|
||||
|
||||
@@ -25,7 +25,9 @@ module.exports = {
|
||||
filename: mainFile,
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd'
|
||||
libraryTarget: 'umd',
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production',
|
||||
externals: {
|
||||
|
||||
@@ -86,9 +86,9 @@ fd-slicer@~1.1.0:
|
||||
pend "~1.2.0"
|
||||
|
||||
follow-redirects@^1.15.0:
|
||||
version "1.15.3"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
|
||||
integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
|
||||
version "1.15.6"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
|
||||
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
|
||||
|
||||
font-finder@^1.0.3:
|
||||
version "1.0.4"
|
||||
|
||||
@@ -32,7 +32,9 @@ module.exports = {
|
||||
filename: mainFile,
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd'
|
||||
libraryTarget: 'umd',
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production'
|
||||
};
|
||||
|
||||
@@ -138,6 +138,16 @@ describe('SerializeAddon', () => {
|
||||
assert.equal((output.match(/<div><span>terminal<\/span><\/div>/g) || []).length, 1, output);
|
||||
});
|
||||
|
||||
it('basic terminal with html unsafe chars', async () => {
|
||||
await writeP(terminal, ' <a>π ');
|
||||
terminal.select(1, 0, 7);
|
||||
|
||||
const output = serializeAddon.serializeAsHTML({
|
||||
onlySelection: true
|
||||
});
|
||||
assert.equal((output.match(/<div><span><a>&pi;<\/span><\/div>/g) || []).length, 1, output);
|
||||
});
|
||||
|
||||
it('cells with bold styling', async () => {
|
||||
await writeP(terminal, ' ' + sgr('1') + 'terminal' + sgr('22') + ' ');
|
||||
|
||||
|
||||
@@ -14,6 +14,14 @@ function constrain(value: number, low: number, high: number): number {
|
||||
return Math.max(low, Math.min(value, high));
|
||||
}
|
||||
|
||||
function escapeHTMLChar(c: string): string {
|
||||
switch (c) {
|
||||
case '&': return '&';
|
||||
case '<': return '<';
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
// TODO: Refine this template class later
|
||||
abstract class BaseSerializeHandler {
|
||||
constructor(
|
||||
@@ -669,7 +677,7 @@ export class HTMLSerializeHandler extends BaseSerializeHandler {
|
||||
if (isEmptyCell) {
|
||||
this._currentRow += ' ';
|
||||
} else {
|
||||
this._currentRow += cell.getChars();
|
||||
this._currentRow += escapeHTMLChar(cell.getChars());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@ module.exports = {
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd',
|
||||
globalObject: 'this'
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production'
|
||||
};
|
||||
|
||||
@@ -32,7 +32,9 @@ module.exports = {
|
||||
filename: mainFile,
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd'
|
||||
libraryTarget: 'umd',
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production'
|
||||
};
|
||||
|
||||
@@ -33,7 +33,8 @@ module.exports = {
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd',
|
||||
globalObject: 'this'
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production'
|
||||
};
|
||||
|
||||
@@ -25,7 +25,9 @@ module.exports = {
|
||||
filename: mainFile,
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd'
|
||||
libraryTarget: 'umd',
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production'
|
||||
};
|
||||
|
||||
@@ -33,7 +33,9 @@ module.exports = {
|
||||
filename: mainFile,
|
||||
path: path.resolve('./lib'),
|
||||
library: addonName,
|
||||
libraryTarget: 'umd'
|
||||
libraryTarget: 'umd',
|
||||
// Force usage of globalThis instead of global / self. (This is cross-env compatible)
|
||||
globalObject: 'globalThis',
|
||||
},
|
||||
mode: 'production'
|
||||
};
|
||||
|
||||
@@ -51,6 +51,8 @@ export class Viewport extends Disposable implements IViewport {
|
||||
target: -1
|
||||
};
|
||||
|
||||
private _ensureTimeout: number;
|
||||
|
||||
private readonly _onRequestScrollLines = this.register(new EventEmitter<{ amount: number, suppressScrollEvent: boolean }>());
|
||||
public readonly onRequestScrollLines = this._onRequestScrollLines.event;
|
||||
|
||||
@@ -83,7 +85,7 @@ export class Viewport extends Disposable implements IViewport {
|
||||
this.register(this._optionsService.onSpecificOptionChange('scrollback', () => this.syncScrollArea()));
|
||||
|
||||
// Perform this async to ensure the ICharSizeService is ready.
|
||||
setTimeout(() => this.syncScrollArea());
|
||||
this._ensureTimeout = window.setTimeout(() => this.syncScrollArea());
|
||||
}
|
||||
|
||||
private _handleThemeChange(colors: ReadonlyColorSet): void {
|
||||
@@ -405,4 +407,8 @@ export class Viewport extends Disposable implements IViewport {
|
||||
this._viewportElement.scrollTop += deltaY;
|
||||
return this._bubbleScroll(ev, deltaY);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
clearTimeout(this._ensureTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,6 +343,9 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
}
|
||||
|
||||
this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode);
|
||||
if (!this._selectionRenderModel.hasSelection) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Translate from buffer position to viewport position
|
||||
const viewportStartRow = this._selectionRenderModel.viewportStartRow;
|
||||
@@ -350,11 +353,6 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow;
|
||||
const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow;
|
||||
|
||||
// No need to draw the selection
|
||||
if (viewportCappedStartRow >= this._bufferService.rows || viewportCappedEndRow < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the selections
|
||||
const documentFragment = this._document.createDocumentFragment();
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user