Compare commits

..
Author SHA1 Message Date
Cursor AgentandDaniel Imms 812328bff1 fix(deps): override serialize-javascript to ^7.0.5 on mocha 11.x
Revert Mocha 12 beta; keep stable mocha ^11.7.5 and force patched
serialize-javascript (Dependabot #94 / GHSA-5c6j-r48x-rmvq) via npm overrides.

Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
2026-06-02 13:03:57 +00:00
Cursor AgentandDaniel Imms a7592068a2 fix(deps): upgrade mocha to 12.0.0-beta-10 for serialize-javascript 7.x
Mocha 11.x still depends on serialize-javascript ^6.0.2 (vulnerable).
Remove npm overrides; use Mocha 12 beta which pulls serialize-javascript
^7.0.2 (resolves to 7.0.5, fixing Dependabot alert #94).

Resolves GHSA-5c6j-r48x-rmvq.

Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
2026-06-02 12:58:43 +00:00
Cursor AgentandDaniel Imms 9269f02353 fix(deps): override serialize-javascript to >=7.0.5
Resolves Dependabot alert #94 (GHSA-5c6j-r48x-rmvq): mocha still
depends on serialize-javascript ^6.0.2; force patched 7.x via npm
overrides until mocha updates its dependency range.

Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
2026-06-02 12:46:04 +00:00
181 changed files with 687 additions and 981 deletions
+27 -19
View File
@@ -11,9 +11,9 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v3
- name: Use Node.js 22.x
uses: actions/setup-node@v5
uses: actions/setup-node@v3
with:
node-version: 22.x
cache: 'npm'
@@ -69,7 +69,7 @@ jobs:
./addons/addon-webgl/out/* \
./addons/addon-webgl/out-*st/*
- name: Upload artifacts
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: compressed-build.zip
@@ -79,9 +79,9 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v3
- name: Use Node.js 22.x
uses: actions/setup-node@v5
uses: actions/setup-node@v3
with:
node-version: 22.x
cache: 'npm'
@@ -100,16 +100,16 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v3
- name: Use Node.js 22.x
uses: actions/setup-node@v5
uses: actions/setup-node@v3
with:
node-version: 22.x
cache: 'npm'
- name: Install dependencies
run: |
npm ci
- uses: actions/download-artifact@v7
- uses: actions/download-artifact@v4
with:
name: build-artifacts
- name: Unzip artifacts
@@ -129,7 +129,6 @@ jobs:
exit $EXIT_CODE
test-unit:
needs: build
timeout-minutes: 20
strategy:
matrix:
@@ -137,16 +136,21 @@ jobs:
runs-on: [ubuntu, macos, windows]
runs-on: ${{ matrix.runs-on }}-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}.x
uses: actions/setup-node@v5
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}.x
cache: 'npm'
- name: Install dependencies
run: |
npm ci
- uses: actions/download-artifact@v7
- name: Wait for build job
uses: NathanFirmo/wait-for-other-job@v1.1.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
job: build
- uses: actions/download-artifact@v4
with:
name: build-artifacts
- name: Unzip artifacts
@@ -162,7 +166,6 @@ jobs:
run: npm run test-unit --forbid-only
test-integration:
needs: build
timeout-minutes: 20
strategy:
matrix:
@@ -171,9 +174,9 @@ jobs:
browser: [chromium, firefox, webkit]
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}.x
uses: actions/setup-node@v5
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}.x
cache: 'npm'
@@ -182,7 +185,12 @@ jobs:
npm ci
- name: Install playwright
run: npx playwright install --with-deps ${{ matrix.browser }}
- uses: actions/download-artifact@v7
- name: Wait for build job
uses: NathanFirmo/wait-for-other-job@v1.1.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
job: build
- uses: actions/download-artifact@v4
with:
name: build-artifacts
- name: Unzip artifacts
@@ -232,9 +240,9 @@ jobs:
matrix:
node-version: [22]
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}.x
uses: actions/setup-node@v5
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}.x
cache: 'npm'
@@ -243,7 +251,7 @@ jobs:
npm ci
- name: Install playwright
run: npx playwright install
- uses: actions/download-artifact@v7
- uses: actions/download-artifact@v4
with:
name: build-artifacts
- name: Unzip artifacts
+4 -4
View File
@@ -24,12 +24,12 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v4
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
uses: github/codeql-action/analyze@v2
+2 -2
View File
@@ -18,9 +18,9 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Use Node.js 22.x
uses: actions/setup-node@v5
uses: actions/setup-node@v3
with:
node-version: 22.x
cache: 'npm'
+2 -2
View File
@@ -10,9 +10,9 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v3
- name: Use Node.js 22.x
uses: actions/setup-node@v5
uses: actions/setup-node@v3
with:
node-version: 22.x
cache: 'npm'
+2 -32
View File
@@ -78,43 +78,13 @@ export class BrowserClipboardProvider implements IClipboardProvider {
}
}
/**
* TODO: Once the base64 handling on Uint8Arrays is more common,
* remove the btoa/atob fallbacks below.
*/
interface IUint8ArrayB64 extends Uint8Array {
toBase64(): string;
}
interface IUint8ArrayB64Ctor extends Uint8ArrayConstructor {
fromBase64(s: string): IUint8ArrayB64;
}
export class Base64 implements IBase64 {
public encodeText(data: string): string {
const bytes = new TextEncoder().encode(data) as IUint8ArrayB64;
if (bytes.toBase64 !== undefined) {
return bytes.toBase64();
}
let bin = '';
for (let i = 0; i < bytes.length; i++) {
bin += String.fromCharCode(bytes[i]);
}
return btoa(bin);
return btoa(data);
}
public decodeText(data: string): string {
if ((Uint8Array as IUint8ArrayB64Ctor).fromBase64 !== undefined) {
try {
return new TextDecoder().decode((Uint8Array as IUint8ArrayB64Ctor).fromBase64(data));
} catch {}
return '';
}
try {
const bin = atob(data);
const bytes = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; ++i) {
bytes[i] = bin.charCodeAt(i);
}
return new TextDecoder().decode(bytes);
return atob(data);
} catch {}
return '';
}
@@ -29,7 +29,7 @@ test.describe('ClipboardAddon', () => {
await ctx.page.context().grantPermissions(['clipboard-read', 'clipboard-write']);
}
await ctx.page.evaluate(`
window.term.reset();
window.term.reset()
window.clipboard?.dispose();
window.clipboard = new ClipboardAddon();
window.term.loadAddon(window.clipboard);
@@ -92,22 +92,4 @@ test.describe('ClipboardAddon', () => {
deepEqual(await ctx.page.evaluate(() => window.navigator.clipboard.readText()), '');
});
});
test.describe('non-ASCII', () => {
const testDataEncoded = '4oKsbWzDpMO8dMOf';
const testDataDecoded = '€mläütß';
test('write simple string', async () => {
await ctx.proxy.write(`\x1b]52;c;${testDataEncoded}\x07`);
deepEqual(await ctx.page.evaluate(() => window.navigator.clipboard.readText()), testDataDecoded);
});
test('read simple string', async () => {
await ctx.page.evaluate(`
window.data2 = [];
window.term.onData(e => data2.push(e));
`);
await ctx.page.evaluate((d) => window.navigator.clipboard.writeText(d), testDataDecoded);
await ctx.proxy.write(`\x1b]52;c;?\x07`);
deepEqual(await ctx.page.evaluate('window.data2'), [`\x1b]52;c;${testDataEncoded}\x07`]);
});
});
});
+1 -1
View File
@@ -5,7 +5,7 @@
import type { ITerminalAddon, IDisposable } from '@xterm/xterm';
import type { ImageAddon as IImageApi } from '@xterm/addon-image';
import { Emitter, type IEvent } from 'common/primitives/Event';
import { Emitter, type IEvent } from 'common/Event';
import { IIPHandler } from './IIPHandler';
import { ImageRenderer } from './ImageRenderer';
import { ImageStorage, CELL_SIZE_DEFAULT } from './ImageStorage';
+1 -1
View File
@@ -6,7 +6,7 @@
import { toRGBA8888 } from 'sixel/lib/Colors';
import { IDisposable } from '@xterm/xterm';
import { ICellSize, ImageLayer, ITerminalExt, IImageSpec, IRenderDimensions, IRenderService } from './Types';
import { Disposable, MutableDisposable, toDisposable } from 'common/primitives/Lifecycle';
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
const enum Constants {
PLACEHOLDER_LENGTH = 4096,
+4 -4
View File
@@ -6,11 +6,11 @@
import { IDisposable, IMarker, Terminal } from '@xterm/xterm';
// private imports from base repo we build against
import { Attributes, BgFlags, Content, ExtFlags, UnderlineStyle } from 'common/primitives/buffer/Constants';
import type { AttributeData } from 'common/primitives/buffer/AttributeData';
import type { IParams, IDcsHandler, IOscHandler, IApcHandler, IEscapeSequenceParser } from 'common/primitives/parser/Types';
import { Attributes, BgFlags, Content, ExtFlags, UnderlineStyle } from 'common/buffer/Constants';
import type { AttributeData } from 'common/buffer/AttributeData';
import type { IParams, IDcsHandler, IOscHandler, IApcHandler, IEscapeSequenceParser } from 'common/parser/Types';
import type { IInputHandler } from 'common/Types';
import type { IBufferLine, IExtendedAttrs } from 'common/primitives/buffer/Types';
import type { IBufferLine, IExtendedAttrs } from 'common/buffer/Types';
import type { ITerminal, ReadonlyColorSet } from 'browser/Types';
import type { IRenderDimensions } from 'browser/renderer/shared/Types';
import type { ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
+1 -1
View File
@@ -5,7 +5,7 @@
import type { Terminal, ITerminalAddon, IDisposable } from '@xterm/xterm';
import type { ProgressAddon as IProgressApi, IProgressState } from '@xterm/addon-progress';
import type { Emitter, IEvent } from 'common/primitives/Event';
import type { Emitter, IEvent } from 'common/Event';
const enum ProgressType {
@@ -10,7 +10,7 @@ import { SearchLineCache } from './SearchLineCache';
import { Terminal } from 'browser/public/Terminal';
import type { ISearchDecorationOptions } from '@xterm/addon-search';
import type { IDecorationOptions } from '@xterm/xterm';
import { DisposableStore } from 'common/primitives/Lifecycle';
import { DisposableStore } from 'common/Lifecycle';
function writeP(terminal: Terminal, data: string): Promise<void> {
return new Promise(r => terminal.write(data, r));
+1 -1
View File
@@ -5,7 +5,7 @@
import type { Terminal, IDisposable, IDecoration } from '@xterm/xterm';
import type { ISearchDecorationOptions } from '@xterm/addon-search';
import { dispose, Disposable, toDisposable } from 'common/primitives/Lifecycle';
import { dispose, Disposable, toDisposable } from 'common/Lifecycle';
import type { ISearchResult } from './SearchEngine';
/**
+9 -11
View File
@@ -5,9 +5,9 @@
import type { Terminal, IDisposable, ITerminalAddon } from '@xterm/xterm';
import type { SearchAddon as ISearchApi, ISearchOptions, ISearchAddonOptions, ISearchResultChangeEvent, ISearchDecorationOptions } from '@xterm/addon-search';
import { Emitter, type IEvent } from 'common/primitives/Event';
import { Disposable, MutableDisposable, toDisposable } from 'common/primitives/Lifecycle';
import { disposableTimeout } from 'common/primitives/Async';
import { Emitter, type IEvent } from 'common/Event';
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
import { disposableTimeout } from 'common/Async';
import { SearchLineCache } from './SearchLineCache';
import { SearchState } from './SearchState';
import { SearchEngine, type ISearchResult } from './SearchEngine';
@@ -142,14 +142,12 @@ export class SearchAddon extends Disposable implements ITerminalAddon, ISearchAp
}
prevResult = result;
results.push(prevResult);
const cols = this._terminal.cols;
let nextCol = prevResult.col + prevResult.size;
let nextRow = prevResult.row;
if (nextCol >= cols) {
nextRow += Math.floor(nextCol / cols);
nextCol = nextCol % cols;
}
result = this._engine.find(term, nextRow, nextCol, searchOptions);
result = this._engine.find(
term,
prevResult.col + prevResult.term.length >= this._terminal.cols ? prevResult.row + 1 : prevResult.row,
prevResult.col + prevResult.term.length >= this._terminal.cols ? 0 : prevResult.col + 1,
searchOptions
);
}
this._resultTracker.updateResults(results, this._highlightLimit);
+1 -1
View File
@@ -7,7 +7,7 @@ import { SearchEngine } from './SearchEngine';
import { SearchLineCache } from './SearchLineCache';
import { Terminal } from 'browser/public/Terminal';
import type { ISearchOptions } from '@xterm/addon-search';
import { DisposableStore } from 'common/primitives/Lifecycle';
import { DisposableStore } from 'common/Lifecycle';
function writeP(terminal: Terminal, data: string): Promise<void> {
return new Promise(r => terminal.write(data, r));
@@ -5,7 +5,7 @@
import { assert } from 'chai';
import { SearchLineCache, LineCacheEntry } from './SearchLineCache';
import { Terminal } from 'browser/public/Terminal';
import { timeout } from 'common/primitives/Async';
import { timeout } from 'common/Async';
function writeP(terminal: Terminal, data: string): Promise<void> {
return new Promise(r => terminal.write(data, r));
+2 -2
View File
@@ -4,8 +4,8 @@
*/
import type { Terminal } from '@xterm/xterm';
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/primitives/Lifecycle';
import { disposableTimeout } from 'common/primitives/Async';
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
import { disposableTimeout } from 'common/Async';
export type LineCacheEntry = [
/**
@@ -5,8 +5,8 @@
import type { ISearchResultChangeEvent } from '@xterm/addon-search';
import type { IDisposable } from '@xterm/xterm';
import { Emitter, type IEvent } from 'common/primitives/Event';
import { Disposable } from 'common/primitives/Lifecycle';
import { Emitter, type IEvent } from 'common/Event';
import { Disposable } from 'common/Lifecycle';
import type { ISearchResult } from './SearchEngine';
/**
@@ -414,20 +414,6 @@ test.describe('Search Tests', () => {
});
test.describe('Regression tests', () => {
test('should advance highlight-all scan by buffer match size for wide characters', async () => {
await ctx.page.evaluate(`
window.calls = [];
window.search.onDidChangeResults(e => window.calls.push(e));
`);
await ctx.proxy.resize(3, 5);
await ctx.proxy.write('𝄞𝄞𝄞');
strictEqual(await ctx.page.evaluate(`window.search.findNext('𝄞', { decorations: { activeMatchColorOverviewRuler: '#ff0000', matchOverviewRuler: '#ffff00' } })`), true);
deepStrictEqual(await ctx.page.evaluate('window.calls'), [
{ resultCount: 3, resultIndex: 0 }
]);
await ctx.proxy.resize(80, 24);
});
test.describe('#2444 wrapped line content not being found', () => {
let fixture: string;
test.beforeAll(async () => {
@@ -6,7 +6,7 @@
import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark';
import { spawn } from 'node-pty';
import { Utf8ToUtf32, stringFromCodePoint } from 'common/primitives/input/TextDecoder';
import { Utf8ToUtf32, stringFromCodePoint } from 'common/input/TextDecoder';
import { Terminal } from 'browser/public/Terminal';
import { SerializeAddon } from 'SerializeAddon';
+3 -3
View File
@@ -7,10 +7,10 @@
import type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm';
import type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize';
import { IColor } from 'common/primitives/Types';
import { IAttributeData } from 'common/primitives/buffer/Types';
import { IColor } from 'common/Types';
import { IAttributeData } from 'common/buffer/Types';
import { DEFAULT_ANSI_COLORS } from 'browser/Types';
import { UnderlineStyle } from 'common/primitives/buffer/Constants';
import { UnderlineStyle } from 'common/buffer/Constants';
function constrain(value: number, low: number, high: number): number {
return Math.max(low, Math.min(value, high));
@@ -6,7 +6,7 @@
import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark';
import { spawn } from 'node-pty';
import { Utf8ToUtf32, stringFromCodePoint } from 'common/primitives/input/TextDecoder';
import { Utf8ToUtf32, stringFromCodePoint } from 'common/input/TextDecoder';
import { CoreBrowserTerminal } from 'browser/CoreBrowserTerminal';
import { UnicodeGraphemeProvider } from 'UnicodeGraphemeProvider';
+3 -3
View File
@@ -1,11 +1,11 @@
import { ISelectionRenderModel } from 'browser/renderer/shared/Types';
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { ReadonlyColorSet } from 'browser/Types';
import { Attributes, BgFlags, ExtFlags, FgFlags, NULL_CELL_CODE, UnderlineStyle } from 'common/primitives/buffer/Constants';
import { Attributes, BgFlags, ExtFlags, FgFlags, NULL_CELL_CODE, UnderlineStyle } from 'common/buffer/Constants';
import { IDecorationService, IOptionsService } from 'common/services/Services';
import { ICellData } from 'common/primitives/buffer/Types';
import { ICellData } from 'common/buffer/Types';
import { Terminal } from '@xterm/xterm';
import { rgba } from 'common/primitives/Color';
import { rgba } from 'common/Color';
import { treatGlyphAsBackgroundColor } from 'browser/renderer/shared/RendererUtils';
import { blockPatternCodepoints } from './customGlyphs/CustomGlyphDefinitions';
@@ -6,8 +6,8 @@
import { assert } from 'chai';
import { configEquals } from './CharAtlasUtils';
import { ICharAtlasConfig } from './Types';
import { NULL_COLOR } from 'common/primitives/Color';
import { IColor } from 'common/primitives/Types';
import { NULL_COLOR } from 'common/Color';
import { IColor } from 'common/Types';
function createTestConfig(overrides: Partial<ICharAtlasConfig> = {}): ICharAtlasConfig {
const color: IColor = { css: '#ffffff', rgba: 0xffffffff };
+2 -2
View File
@@ -4,10 +4,10 @@
*/
import { ICharAtlasConfig } from './Types';
import { Attributes } from 'common/primitives/buffer/Constants';
import { Attributes } from 'common/buffer/Constants';
import { ITerminalOptions } from '@xterm/xterm';
import { IColorSet, ReadonlyColorSet } from 'browser/Types';
import { NULL_COLOR } from 'common/primitives/Color';
import { NULL_COLOR } from 'common/Color';
export function generateConfig(deviceCellWidth: number, deviceCellHeight: number, deviceCharWidth: number, deviceCharHeight: number, options: Required<ITerminalOptions>, colors: ReadonlyColorSet, devicePixelRatio: number, deviceMaxTextureSize: number, customGlyphs: boolean = true): ICharAtlasConfig {
// null out some fields that don't matter
+1 -1
View File
@@ -3,7 +3,7 @@
* @license MIT
*/
import { isFirefox, isLegacyEdge } from 'common/primitives/Platform';
import { isFirefox, isLegacyEdge } from 'common/Platform';
export const DIM_OPACITY = 0.5;
// The text baseline is set conditionally by browser. Using 'ideographic' for Firefox or Legacy Edge
@@ -3,7 +3,7 @@
* @license MIT
*/
import { toDisposable, IDisposable } from 'common/primitives/Lifecycle';
import { toDisposable, IDisposable } from 'common/Lifecycle';
export function observeDevicePixelDimensions(element: HTMLElement, parentWindow: Window & typeof globalThis, callback: (deviceWidth: number, deviceHeight: number) => void): IDisposable {
// Observe any resizes to the element and extract the actual pixel size of the element if the
+3 -4
View File
@@ -4,8 +4,8 @@
*/
import { TextureAtlas } from './TextureAtlas';
import { IRenderDimensions } from 'browser/renderer/shared/Types';
import { NULL_CELL_CODE } from 'common/primitives/buffer/Constants';
import { Disposable, toDisposable } from 'common/primitives/Lifecycle';
import { NULL_CELL_CODE } from 'common/buffer/Constants';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { Terminal } from '@xterm/xterm';
import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject, type IRasterizedGlyph, type ITextureAtlas } from './Types';
import { createProgram, GLTexture, PROJECTION_MATRIX } from './WebglUtils';
@@ -389,9 +389,8 @@ export class GlyphRenderer extends Disposable {
gl.bindTexture(gl.TEXTURE_2D, this._atlasTextures[i].texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, atlas.pages[i].canvas);
gl.generateMipmap(gl.TEXTURE_2D);
this._atlasTextures[i].version = atlas.pages[i].version;
}
+3 -3
View File
@@ -6,9 +6,9 @@
import { IRenderDimensions } from 'browser/renderer/shared/Types';
import { IThemeService } from 'browser/services/Services';
import { ReadonlyColorSet } from 'browser/Types';
import { Attributes, FgFlags } from 'common/primitives/buffer/Constants';
import { Disposable, toDisposable } from 'common/primitives/Lifecycle';
import { IColor } from 'common/primitives/Types';
import { Attributes, FgFlags } from 'common/buffer/Constants';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { IColor } from 'common/Types';
import { Terminal } from '@xterm/xterm';
import { RenderModelConstants } from './RenderModel';
import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject } from './Types';
+13 -29
View File
@@ -8,14 +8,14 @@ import { DIM_OPACITY, TEXT_BASELINE } from './Constants';
import { tryDrawCustomGlyph } from './customGlyphs/CustomGlyphRasterizer';
import { computeNextVariantOffset, treatGlyphAsBackgroundColor, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
import { IBoundingBox, ICharAtlasConfig, IRasterizedGlyph, ITextureAtlas } from './Types';
import { NULL_COLOR, channels, color, rgba } from 'common/primitives/Color';
import { FourKeyMap } from 'common/primitives/MultiKeyMap';
import { IdleTaskQueue } from 'common/primitives/TaskQueue';
import { IColor } from 'common/primitives/Types';
import { AttributeData } from 'common/primitives/buffer/AttributeData';
import { Attributes, DEFAULT_COLOR, DEFAULT_EXT, UnderlineStyle } from 'common/primitives/buffer/Constants';
import { NULL_COLOR, channels, color, rgba } from 'common/Color';
import { FourKeyMap } from 'common/MultiKeyMap';
import { IdleTaskQueue } from 'common/TaskQueue';
import { IColor } from 'common/Types';
import { AttributeData } from 'common/buffer/AttributeData';
import { Attributes, DEFAULT_COLOR, DEFAULT_EXT, UnderlineStyle } from 'common/buffer/Constants';
import { ILogService, IUnicodeService } from 'common/services/Services';
import { Emitter } from 'common/primitives/Event';
import { Emitter } from 'common/Event';
/**
* A shared object which is used to draw nothing for a particular cell.
@@ -1080,33 +1080,17 @@ class AtlasPage {
size: number,
sourcePages?: AtlasPage[]
) {
if (sourcePages) {
for (const p of sourcePages) {
this._glyphs.push(...p.glyphs);
this._usedPixels += p._usedPixels;
}
}
this.canvas = createCanvas(document, size, size);
// The canvas needs alpha because we use clearColor to convert the background color to alpha.
// It might also contain some characters with transparent backgrounds if allowTransparency is
// set.
this.ctx = throwIfFalsy(this.canvas.getContext('2d', { alpha: true }));
if (sourcePages) {
if (sourcePages.length === 4) {
// optimized for quadmerge
this._glyphs = this._glyphs.concat(
sourcePages[0].glyphs,
sourcePages[1].glyphs,
sourcePages[2].glyphs,
sourcePages[3].glyphs
);
this._usedPixels = sourcePages[0]._usedPixels +
sourcePages[1]._usedPixels +
sourcePages[2]._usedPixels +
sourcePages[3]._usedPixels;
} else {
// fallback for non quadmerges (should never be used)
for (let i = 0; i < sourcePages.length; ++i) {
this._glyphs = this._glyphs.concat(sourcePages[i].glyphs);
this._usedPixels += sourcePages[i]._usedPixels;
}
}
}
}
public clear(): void {
+2 -2
View File
@@ -6,8 +6,8 @@
import { FontWeight } from '@xterm/xterm';
import { IColorSet } from 'browser/Types';
import { ISelectionRenderModel } from 'browser/renderer/shared/Types';
import { CursorInactiveStyle, CursorStyle, type IDisposable } from 'common/primitives/Types';
import type { IEvent } from 'common/primitives/Event';
import { CursorInactiveStyle, CursorStyle, type IDisposable } from 'common/Types';
import type { IEvent } from 'common/Event';
export interface IRenderModel {
cells: Uint32Array;
+3 -3
View File
@@ -7,12 +7,12 @@ import type { ITerminalAddon, Terminal } from '@xterm/xterm';
import type { IWebglAddonOptions, WebglAddon as IWebglApi } from '@xterm/addon-webgl';
import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
import { ITerminal } from 'browser/Types';
import { Disposable, toDisposable } from 'common/primitives/Lifecycle';
import { getSafariVersion, isSafari } from 'common/primitives/Platform';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { getSafariVersion, isSafari } from 'common/Platform';
import { ICoreService, IDecorationService, ILogService, IOptionsService } from 'common/services/Services';
import { IWebGL2RenderingContext } from './Types';
import { WebglRenderer } from './WebglRenderer';
import { Emitter, EventUtils } from 'common/primitives/Event';
import { Emitter, EventUtils } from 'common/Event';
export class WebglAddon extends Disposable implements ITerminalAddon, IWebglApi {
private _terminal?: Terminal;
+12 -27
View File
@@ -10,10 +10,10 @@ import { CursorBlinkStateManager } from './CursorBlinkStateManager';
import { observeDevicePixelDimensions } from './DevicePixelObserver';
import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/renderer/shared/Types';
import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { CharData, IBufferLine, ICellData } from 'common/primitives/buffer/Types';
import { AttributeData } from 'common/primitives/buffer/AttributeData';
import { CellData } from 'common/primitives/buffer/CellData';
import { Attributes, Content, FgFlags, NULL_CELL_CHAR, NULL_CELL_CODE } from 'common/primitives/buffer/Constants';
import { CharData, IBufferLine, ICellData } from 'common/buffer/Types';
import { AttributeData } from 'common/buffer/AttributeData';
import { CellData } from 'common/buffer/CellData';
import { Attributes, Content, FgFlags, NULL_CELL_CHAR, NULL_CELL_CODE } from 'common/buffer/Constants';
import { TextBlinkStateManager } from 'browser/renderer/shared/TextBlinkStateManager';
import { ICoreService, IDecorationService, ILogService, IOptionsService } from 'common/services/Services';
import { Terminal } from '@xterm/xterm';
@@ -23,9 +23,9 @@ import { COMBINED_CHAR_BIT_MASK, RenderModel, RenderModelConstants } from './Ren
import { IWebGL2RenderingContext, type ITextureAtlas } from './Types';
import { LinkRenderLayer } from './renderLayer/LinkRenderLayer';
import { IRenderLayer } from './renderLayer/Types';
import { Emitter, EventUtils } from 'common/primitives/Event';
import { Emitter, EventUtils } from 'common/Event';
import { addDisposableListener } from 'browser/Dom';
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/primitives/Lifecycle';
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
const enum Constants {
@@ -456,18 +456,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
for (y = start; y <= end; y++) {
row = y + terminal.buffer.ydisp;
const bufferLine = terminal.buffer.lines.get(row);
if (!bufferLine) {
this._model.lineLengths[y] = 0;
for (x = 0; x < terminal.cols; x++) {
j = ((y * terminal.cols) + x) * RenderModelConstants.INDICIES_PER_CELL;
modelUpdated = true;
this._nullModelCell(x, y, j, 0, 0, 0);
}
this._setRowBlinkState(y, false);
continue;
}
line = bufferLine;
line = terminal.buffer.lines.get(row)!;
let rowHasBlinkingCells = false;
this._model.lineLengths[y] = 0;
isCursorRow = cursorY === row;
@@ -598,9 +587,13 @@ export class WebglRenderer extends Disposable implements IRenderer {
// Null out non-first cells
for (x++; x <= lastCharX; x++) {
j = ((y * terminal.cols) + x) * RenderModelConstants.INDICIES_PER_CELL;
this._glyphRenderer.value!.updateCell(x, y, NULL_CELL_CODE, 0, 0, 0, NULL_CELL_CHAR, 0, 0);
this._model.cells[j] = NULL_CELL_CODE;
// Don't re-resolve the cell color since multi-colored ligature backgrounds are not
// supported
this._nullModelCell(x, y, j, this._cellColorResolver.result.bg, this._cellColorResolver.result.fg, this._cellColorResolver.result.ext);
this._model.cells[j + RenderModelConstants.BG_OFFSET] = this._cellColorResolver.result.bg;
this._model.cells[j + RenderModelConstants.FG_OFFSET] = this._cellColorResolver.result.fg;
this._model.cells[j + RenderModelConstants.EXT_OFFSET] = this._cellColorResolver.result.ext;
}
x--; // Go back to the previous update cell for next iteration
}
@@ -614,14 +607,6 @@ export class WebglRenderer extends Disposable implements IRenderer {
this._updateTextBlinkState();
}
private _nullModelCell(x: number, y: number, cellIndex: number, bg: number, fg: number, ext: number): void {
this._glyphRenderer.value!.updateCell(x, y, NULL_CELL_CODE, bg, fg, ext, NULL_CELL_CHAR, 0, 0);
this._model.cells[cellIndex] = NULL_CELL_CODE;
this._model.cells[cellIndex + RenderModelConstants.BG_OFFSET] = bg;
this._model.cells[cellIndex + RenderModelConstants.FG_OFFSET] = fg;
this._model.cells[cellIndex + RenderModelConstants.EXT_OFFSET] = ext;
}
private _resetBlinkingRowState(): void {
this._rowHasBlinkingCells = new Array(this._terminal.rows).fill(false);
this._rowHasBlinkingCellsCount = 0;
@@ -7,8 +7,8 @@ import { ReadonlyColorSet } from 'browser/Types';
import { acquireTextureAtlas } from '../CharAtlasCache';
import { IRenderDimensions } from 'browser/renderer/shared/Types';
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { Disposable, toDisposable } from 'common/primitives/Lifecycle';
import { CellData } from 'common/primitives/buffer/CellData';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { CellData } from 'common/buffer/CellData';
import { IOptionsService } from 'common/services/Services';
import { Terminal } from '@xterm/xterm';
import { IRenderLayer } from './Types';
@@ -7,7 +7,7 @@ import { BaseWindow } from './baseWindow';
import type { IControlWindow } from '../controlBar';
import type { IBufferCell } from '@xterm/xterm';
// Underline style values from common/primitives/buffer/Constants.ts
// Underline style values from common/buffer/Constants.ts
const enum UnderlineStyle {
NONE = 0,
SINGLE = 1,
@@ -11,33 +11,8 @@ export class WebglWindow extends BaseWindow implements IControlWindow {
public readonly label = 'webgl';
private _textureAtlasContainer!: HTMLElement;
private _stressRunning = false;
private _stressScrolling: HTMLInputElement | undefined;
public build(container: HTMLElement): void {
const stressDiv = document.createElement('div');
const stressStart = document.createElement('button');
stressStart.id = 'stress-start';
stressStart.textContent = 'atlas stress start';
stressStart.addEventListener('click', () => this._stress());
stressDiv.appendChild(stressStart);
const stressStop = document.createElement('button');
stressStop.id = 'stress-stop';
stressStop.textContent = 'atlas stress stop';
stressStop.addEventListener('click', () => this._stressRunning = false);
stressDiv.appendChild(stressStop);
this._stressScrolling = document.createElement('input');
this._stressScrolling.type = 'checkbox';
this._stressScrolling.id = 'stress-scrolling';
stressDiv.appendChild(this._stressScrolling);
const stressScrollingLabel = document.createElement('label');
stressScrollingLabel.htmlFor = 'stress-scrolling';
stressScrollingLabel.textContent = 'stress scrolling';
stressDiv.appendChild(stressScrollingLabel);
container.appendChild(stressDiv);
const zoomCheckbox = document.createElement('input');
zoomCheckbox.type = 'checkbox';
zoomCheckbox.id = 'texture-atlas-zoom';
@@ -73,33 +48,4 @@ export class WebglWindow extends BaseWindow implements IControlWindow {
canvas.style.width = `${canvas.width / dpr}px`;
canvas.style.height = `${canvas.height / dpr}px`;
}
private async _stress(): Promise<void> {
const TEXT = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
if (this._stressRunning) {
return;
}
this._stressRunning = true;
const scrolling = !!(this._stressScrolling?.checked);
for (let r = 0; r < 256; r += 2) {
for (let g = 0; g < 256; g += 2) {
let s: string[] = [];
for (let b = 0; b < 256; b += 2) {
if (!this._stressRunning) {
return;
}
const rbg = `RGB: ${[r, g, b]}`;
s.push(`\r\x1b[38;2;${r};${g};${b}m${rbg.padEnd(18, ' ')}${TEXT}`);
if (s.length >= 16) {
if (scrolling) {
await new Promise<void>(r => this._terminal.write(s.join('\r\n') + '\r\n', r));
} else {
await new Promise<void>(r => this._terminal.write('\x1b[H' + s.join('\r\n'), r));
}
s = [];
}
}
}
}
}
}
+64 -167
View File
@@ -4700,22 +4700,18 @@
}
},
"node_modules/glob": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
"deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
"integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"dev": true,
"license": "ISC",
"license": "BlueOak-1.0.0",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
"minimatch": "^10.2.2",
"minipass": "^7.1.3",
"path-scurry": "^2.0.2"
},
"bin": {
"glob": "dist/esm/bin.mjs"
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -4741,39 +4737,6 @@
"dev": true,
"license": "BSD-2-Clause"
},
"node_modules/glob/node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/glob/node_modules/brace-expansion": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
"integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/glob/node_modules/minimatch": {
"version": "9.0.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -5795,15 +5758,44 @@
"license": "MIT"
},
"node_modules/mocha/node_modules/brace-expansion": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
"integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
"integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/mocha/node_modules/glob": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
"deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
"dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/mocha/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
"license": "ISC"
},
"node_modules/mocha/node_modules/minimatch": {
"version": "9.0.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
@@ -5820,6 +5812,23 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/mocha/node_modules/path-scurry": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
"node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -5987,24 +5996,6 @@
"node": ">=8"
}
},
"node_modules/nyc/node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
"integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"minimatch": "^10.2.2",
"minipass": "^7.1.3",
"path-scurry": "^2.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/nyc/node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -6047,23 +6038,6 @@
"node": ">=8"
}
},
"node_modules/nyc/node_modules/path-scurry": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
"integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/nyc/node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -6461,29 +6435,22 @@
"license": "MIT"
},
"node_modules/path-scurry": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
"integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
},
"engines": {
"node": ">=16 || 14 >=14.18"
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
"license": "ISC"
},
"node_modules/path-to-regexp": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
@@ -6860,41 +6827,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rimraf/node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
"integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"minimatch": "^10.2.2",
"minipass": "^7.1.3",
"path-scurry": "^2.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rimraf/node_modules/path-scurry": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
"integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/router": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
@@ -7654,41 +7586,6 @@
"node": "20 || >=22"
}
},
"node_modules/test-exclude/node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
"integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"minimatch": "^10.2.2",
"minipass": "^7.1.3",
"path-scurry": "^2.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/test-exclude/node_modules/path-scurry": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
"integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+3 -3
View File
@@ -11,9 +11,6 @@
"workspaces": [
"addons/*"
],
"overrides": {
"serialize-javascript": "^7.0.3"
},
"keywords": [
"cli",
"command-line",
@@ -118,5 +115,8 @@
"webpack-cli": "^7.0.2",
"ws": "^8.20.0",
"xterm-benchmark": "^0.3.2"
},
"overrides": {
"serialize-javascript": "^7.0.5"
}
}
+2 -2
View File
@@ -6,9 +6,9 @@
import * as Strings from './LocalizableStrings';
import { ITerminal, IRenderDebouncer } from './Types';
import { TimeBasedDebouncer } from './TimeBasedDebouncer';
import { Disposable, toDisposable } from '../common/primitives/Lifecycle';
import { Disposable, toDisposable } from '../common/Lifecycle';
import { ICoreBrowserService, IRenderService } from './services/Services';
import { IBuffer } from '../common/primitives/buffer/Types';
import { IBuffer } from '../common/buffer/Types';
import { IInstantiationService } from '../common/services/Services';
import { addDisposableListener } from './Dom';
+2 -2
View File
@@ -4,8 +4,8 @@
*/
import { IColorContrastCache } from './Types';
import { IColor } from '../common/primitives/Types';
import { TwoKeyMap } from '../common/primitives/MultiKeyMap';
import { IColor } from '../common/Types';
import { TwoKeyMap } from '../common/MultiKeyMap';
export class ColorContrastCache implements IColorContrastCache {
private _color: TwoKeyMap</* bg */number, /* fg */number, IColor | null> = new TwoKeyMap();
+13 -10
View File
@@ -43,23 +43,22 @@ import { SelectionService } from './services/SelectionService';
import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IKeyboardService, ILinkProviderService, IMouseCoordsService, IMouseService, IRenderService, ISelectionService, IThemeService } from './services/Services';
import { ThemeService } from './services/ThemeService';
import { KeyboardService } from './services/KeyboardService';
import { channels, color, rgb } from '../common/primitives/Color';
import { channels, color, rgb } from '../common/Color';
import { CoreTerminal } from '../common/CoreTerminal';
import * as Browser from '../common/primitives/Platform';
import { ColorRequestType, IColorEvent, KeyboardResultType, SpecialColorIndex } from '../common/primitives/Types';
import { ITerminalOptions } from '../common/Types';
import { DEFAULT_ATTR_DATA } from '../common/primitives/buffer/BufferLine';
import { IBuffer } from '../common/primitives/buffer/Types';
import { C0, C1ESCAPED } from '../common/primitives/data/EscapeSequences';
import { toRgbString } from '../common/primitives/input/XParseColor';
import * as Browser from '../common/Platform';
import { ColorRequestType, IColorEvent, ITerminalOptions, KeyboardResultType, SpecialColorIndex } from '../common/Types';
import { DEFAULT_ATTR_DATA } from '../common/buffer/BufferLine';
import { IBuffer } from '../common/buffer/Types';
import { C0, C1ESCAPED } from '../common/data/EscapeSequences';
import { toRgbString } from '../common/input/XParseColor';
import { DecorationService } from '../common/services/DecorationService';
import { IDecorationService } from '../common/services/Services';
import { WindowsOptionsReportType } from '../common/InputHandler';
import { AccessibilityManager } from './AccessibilityManager';
import { Linkifier } from './Linkifier';
import { Emitter, EventUtils, type IEvent } from '../common/primitives/Event';
import { Emitter, EventUtils, type IEvent } from '../common/Event';
import { addDisposableListener } from './Dom';
import { MutableDisposable, toDisposable } from '../common/primitives/Lifecycle';
import { MutableDisposable, toDisposable } from '../common/Lifecycle';
export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
public textarea: HTMLTextAreaElement | undefined;
@@ -1073,6 +1072,10 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
* Clear the entire buffer, making the prompt line the new first line.
*/
public clear(): void {
if (this.buffer.ybase === 0 && this.buffer.y === 0) {
// Don't clear if it's already clear
return;
}
this.buffer.clearAllMarkers();
this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)!);
this.buffer.lines.length = 1;
+2 -2
View File
@@ -5,8 +5,8 @@
* Minimal DOM helpers for xterm.js browser code.
*/
import { IntervalTimer } from '../common/primitives/Async';
import { IDisposable } from '../common/primitives/Lifecycle';
import { IntervalTimer } from '../common/Async';
import { IDisposable } from '../common/Lifecycle';
export function getWindow(e: Node | UIEvent | undefined | null): Window {
const candidateNode = e as Node | undefined | null;
+3 -3
View File
@@ -4,11 +4,11 @@
*/
import { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from './Types';
import { Disposable, dispose, toDisposable } from '../common/primitives/Lifecycle';
import { IDisposable } from '../common/primitives/Types';
import { Disposable, dispose, toDisposable } from '../common/Lifecycle';
import { IDisposable } from '../common/Types';
import { IBufferService } from '../common/services/Services';
import { ILinkProviderService, IMouseCoordsService, IRenderService } from './services/Services';
import { Emitter } from '../common/primitives/Event';
import { Emitter } from '../common/Event';
import { addDisposableListener } from './Dom';
export class Linkifier extends Disposable implements ILinkifier2 {
+2 -2
View File
@@ -8,8 +8,8 @@ import { OscLinkProvider } from './OscLinkProvider';
import { ILink } from './Types';
import { createCellData, MockBufferService, MockOptionsService } from '../common/TestUtils.test';
import { IBufferService, IOscLinkService } from '../common/services/Services';
import { IOscLinkData } from '../common/primitives/Types';
import { IBufferLine } from '../common/primitives/buffer/Types';
import { IOscLinkData } from '../common/Types';
import { IBufferLine } from '../common/buffer/Types';
class TestOscLinkService implements IOscLinkService {
public serviceBrand: any;
+2 -2
View File
@@ -5,8 +5,8 @@
import { IBufferRange, ILink } from './Types';
import { ILinkProvider } from './services/Services';
import { CellData } from '../common/primitives/buffer/CellData';
import { IBufferLine } from '../common/primitives/buffer/Types';
import { CellData } from '../common/buffer/CellData';
import { IBufferLine } from '../common/buffer/Types';
import { IBufferService, IOptionsService, IOscLinkService } from '../common/services/Services';
export class OscLinkProvider implements ILinkProvider {
+3 -3
View File
@@ -6,10 +6,10 @@
import { MockCompositionHelper, MockRenderer, MockViewport, TestTerminal } from './TestUtils.test';
import type { IBrowser } from './Types';
import { assert } from 'chai';
import { DEFAULT_ATTR_DATA } from '../common/primitives/buffer/BufferLine';
import { CellData } from '../common/primitives/buffer/CellData';
import { DEFAULT_ATTR_DATA } from '../common/buffer/BufferLine';
import { CellData } from '../common/buffer/CellData';
import { MockUnicodeService, createCellData } from '../common/TestUtils.test';
import { IMarker } from '../common/primitives/buffer/Types';
import { IMarker } from '../common/buffer/Types';
const INIT_COLS = 80;
const INIT_ROWS = 24;
+9 -10
View File
@@ -7,20 +7,19 @@ import { IDisposable, IMarker, ILinkProvider, IDecorationOptions, IDecoration, I
import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IMouseService, IRenderService, ISelectionService, IThemeService } from './services/Services';
import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from './renderer/shared/Types';
import { IColorSet, ITerminal, ILinkifier2, IBrowser, IViewport, ICompositionHelper, CharacterJoinerHandler, IBufferRange, ReadonlyColorSet, IBufferElementProvider } from './Types';
import { IAttributeData, IBuffer, IBufferLine, IBufferSet, ICellData } from '../common/primitives/buffer/Types';
import { ICircularList } from '../common/primitives/CircularList';
import { XtermListener, ICharset, ColorIndex } from '../common/primitives/Types';
import { ITerminalOptions } from '../common/Types';
import { Buffer } from '../common/primitives/buffer/Buffer';
import * as Browser from '../common/primitives/Platform';
import { IAttributeData, IBuffer, IBufferLine, IBufferSet, ICellData } from '../common/buffer/Types';
import { ICircularList } from '../common/CircularList';
import { XtermListener, ICharset, ITerminalOptions, ColorIndex } from '../common/Types';
import { Buffer } from '../common/buffer/Buffer';
import * as Browser from '../common/Platform';
import { CoreBrowserTerminal } from './CoreBrowserTerminal';
import { IUnicodeService, IOptionsService, ICoreService, IMouseStateService } from '../common/services/Services';
import { IFunctionIdentifier, IParams } from '../common/primitives/parser/Types';
import { AttributeData } from '../common/primitives/buffer/AttributeData';
import { IFunctionIdentifier, IParams } from '../common/parser/Types';
import { AttributeData } from '../common/buffer/AttributeData';
import { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from './selection/Types';
import { css } from '../common/primitives/Color';
import { css } from '../common/Color';
import { createRenderDimensions } from './renderer/shared/RendererUtils';
import { Emitter, type IEvent } from '../common/primitives/Event';
import { Emitter, type IEvent } from '../common/Event';
export class TestTerminal extends CoreBrowserTerminal {
public get curAttrData(): IAttributeData { return (this as any)._inputHandler._curAttrData; }
+4 -5
View File
@@ -3,13 +3,12 @@
* @license MIT
*/
import { IColor } from '../common/primitives/Types';
import { ITerminalOptions } from '../common/Types';
import { CharData, IBuffer } from '../common/primitives/buffer/Types';
import { IColor, ITerminalOptions } from '../common/Types';
import { CharData, IBuffer } from '../common/buffer/Types';
import { ICoreTerminal } from '../common/CoreTerminal';
import { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';
import { channels, css } from '../common/primitives/Color';
import type { IEvent } from '../common/primitives/Event';
import { channels, css } from '../common/Color';
import type { IEvent } from '../common/Event';
/**
* A portion of the public API that are implemented identially internally and simply passed through.
+3 -3
View File
@@ -5,13 +5,13 @@
import { ICoreBrowserService, IRenderService, IThemeService } from './services/Services';
import { ViewportConstants } from './shared/Constants';
import { Disposable, toDisposable } from '../common/primitives/Lifecycle';
import { Disposable, toDisposable } from '../common/Lifecycle';
import { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../common/services/Services';
import { CoreMouseEventType } from '../common/primitives/Types';
import { CoreMouseEventType } from '../common/Types';
import { scheduleAtNextAnimationFrame } from './Dom';
import { SmoothScrollableElement } from './scrollable/scrollableElement';
import type { IScrollableElementChangeOptions } from './scrollable/scrollableElementOptions';
import { Emitter, EventUtils } from '../common/primitives/Event';
import { Emitter, EventUtils } from '../common/Event';
import { Scrollable, ScrollbarVisibility, type IScrollEvent } from './scrollable/scrollable';
export class Viewport extends Disposable {
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { ICoreBrowserService, IRenderService } from '../services/Services';
import { Disposable, toDisposable } from '../../common/primitives/Lifecycle';
import { Disposable, toDisposable } from '../../common/Lifecycle';
import { IBufferService, IDecorationService, IInternalDecoration } from '../../common/services/Services';
export class BufferDecorationRenderer extends Disposable {
@@ -5,7 +5,7 @@
import { ColorZoneStore, IColorZone, IColorZoneStore } from './ColorZoneStore';
import { ICoreBrowserService, IRenderService, IThemeService } from '../services/Services';
import { Disposable, toDisposable } from '../../common/primitives/Lifecycle';
import { Disposable, toDisposable } from '../../common/Lifecycle';
import { IBufferService, IDecorationService, IOptionsService } from '../../common/services/Services';
const enum Constants {
+1 -1
View File
@@ -5,7 +5,7 @@
import { IRenderService } from '../services/Services';
import { IBufferService, ICoreService, IOptionsService } from '../../common/services/Services';
import { C0 } from '../../common/primitives/data/EscapeSequences';
import { C0 } from '../../common/data/EscapeSequences';
interface IPosition {
start: number;
+1 -1
View File
@@ -3,7 +3,7 @@
* @license MIT
*/
import { C0 } from '../../common/primitives/data/EscapeSequences';
import { C0 } from '../../common/data/EscapeSequences';
import { IBufferService } from '../../common/services/Services';
const enum Direction {
+2 -2
View File
@@ -6,14 +6,14 @@
import * as Strings from '../LocalizableStrings';
import { CoreBrowserTerminal as TerminalCore } from '../CoreBrowserTerminal';
import { IBufferRange, ITerminal } from '../Types';
import { Disposable } from '../../common/primitives/Lifecycle';
import { Disposable } from '../../common/Lifecycle';
import { ITerminalOptions } from '../../common/Types';
import { AddonManager } from '../../common/public/AddonManager';
import { BufferNamespaceApi } from '../../common/public/BufferNamespaceApi';
import { ParserApi } from '../../common/public/ParserApi';
import { UnicodeApi } from '../../common/public/UnicodeApi';
import { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, IRenderDimensions, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';
import type { IEvent } from '../../common/primitives/Event';
import type { IEvent } from '../../common/Event';
/**
* The set of options that only have an effect when set in the Terminal constructor.
+7 -17
View File
@@ -12,10 +12,10 @@ import { TextBlinkStateManager } from '../shared/TextBlinkStateManager';
import { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from '../shared/Types';
import { ICharSizeService, ICoreBrowserService, IThemeService } from '../../services/Services';
import { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from '../../Types';
import { color } from '../../../common/primitives/Color';
import { Disposable, toDisposable } from '../../../common/primitives/Lifecycle';
import { color } from '../../../common/Color';
import { Disposable, toDisposable } from '../../../common/Lifecycle';
import { IBufferService, ICoreService, IInstantiationService, IOptionsService } from '../../../common/services/Services';
import { Emitter } from '../../../common/primitives/Event';
import { Emitter } from '../../../common/Event';
import { addDisposableListener } from '../../Dom';
@@ -536,14 +536,9 @@ export class DomRenderer extends Disposable implements IRenderer {
for (let y = start; y <= end; y++) {
const row = y + buffer.ydisp;
const rowElement = this._rowElements[y];
if (!rowElement) {
continue;
}
const lineData = buffer.lines.get(row);
if (!lineData) {
rowElement.replaceChildren();
this._setRowBlinkState(y, false);
continue;
if (!rowElement || !lineData) {
break;
}
rowElement.replaceChildren(
...this._rowFactory.createRow(
@@ -615,14 +610,9 @@ export class DomRenderer extends Disposable implements IRenderer {
for (let i = y; i <= y2; ++i) {
const row = i + buffer.ydisp;
const rowElement = this._rowElements[i];
if (!rowElement) {
continue;
}
const bufferline = buffer.lines.get(row);
if (!bufferline) {
rowElement.replaceChildren();
this._setRowBlinkState(i, false);
continue;
if (!rowElement || !bufferline) {
break;
}
rowElement.replaceChildren(
...this._rowFactory.createRow(
@@ -6,11 +6,11 @@
import jsdom = require('jsdom');
import { assert } from 'chai';
import { DomRendererRowFactory } from './DomRendererRowFactory';
import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, DEFAULT_ATTR, FgFlags, BgFlags, Attributes, UnderlineStyle } from '../../../common/primitives/buffer/Constants';
import { BufferLine, DEFAULT_ATTR_DATA } from '../../../common/primitives/buffer/BufferLine';
import { BufferLineStringCache } from '../../../common/primitives/buffer/BufferLineStringCache';
import { IBufferLine } from '../../../common/primitives/buffer/Types';
import { CellData } from '../../../common/primitives/buffer/CellData';
import { NULL_CELL_CODE, NULL_CELL_WIDTH, NULL_CELL_CHAR, DEFAULT_ATTR, FgFlags, BgFlags, Attributes, UnderlineStyle } from '../../../common/buffer/Constants';
import { BufferLine, DEFAULT_ATTR_DATA } from '../../../common/buffer/BufferLine';
import { BufferLineStringCache } from '../../../common/buffer/BufferLineStringCache';
import { IBufferLine } from '../../../common/buffer/Types';
import { CellData } from '../../../common/buffer/CellData';
import { MockCoreService, MockDecorationService, MockOptionsService, createCellData, NULL_CELL_DATA } from '../../../common/TestUtils.test';
import { MockCharacterJoinerService, MockCoreBrowserService, MockThemeService } from '../../TestUtils.test';
import { TestWidthCache } from './WidthCache.test';
@@ -3,17 +3,17 @@
* @license MIT
*/
import { IColor } from '../../../common/primitives/Types';
import { IBufferLine, ICellData } from '../../../common/primitives/buffer/Types';
import { IColor } from '../../../common/Types';
import { IBufferLine, ICellData } from '../../../common/buffer/Types';
import { INVERTED_DEFAULT_COLOR } from '../shared/Constants';
import { WHITESPACE_CELL_CHAR, Attributes } from '../../../common/primitives/buffer/Constants';
import { CellData } from '../../../common/primitives/buffer/CellData';
import { WHITESPACE_CELL_CHAR, Attributes } from '../../../common/buffer/Constants';
import { CellData } from '../../../common/buffer/CellData';
import { ICoreService, IDecorationService, IOptionsService } from '../../../common/services/Services';
import { channels, color } from '../../../common/primitives/Color';
import { channels, color } from '../../../common/Color';
import { ICharacterJoinerService, ICoreBrowserService, IThemeService } from '../../services/Services';
import { JoinedCellData } from '../../services/CharacterJoinerService';
import { treatGlyphAsBackgroundColor } from '../shared/RendererUtils';
import { AttributeData } from '../../../common/primitives/buffer/AttributeData';
import { AttributeData } from '../../../common/buffer/AttributeData';
import { WidthCache } from './WidthCache';
import { IColorContrastCache } from '../../Types';
+1 -1
View File
@@ -4,7 +4,7 @@
*/
import { throwIfFalsy } from '../shared/RendererUtils';
import { IDisposable } from '../../../common/primitives/Types';
import { IDisposable } from '../../../common/Types';
import { FontWeight } from '../../../common/services/Services';
@@ -7,7 +7,7 @@ import { assert } from 'chai';
import { TextBlinkStateManager } from './TextBlinkStateManager';
import { MockOptionsService } from '../../../common/TestUtils.test';
import type { ICoreBrowserService } from '../../services/Services';
import { Emitter } from '../../../common/primitives/Event';
import { Emitter } from '../../../common/Event';
class FakeWindow {
public nextId = 1;
@@ -4,7 +4,7 @@
*/
import { ICoreBrowserService } from '../../services/Services';
import { Disposable, toDisposable } from '../../../common/primitives/Lifecycle';
import { Disposable, toDisposable } from '../../../common/Lifecycle';
import { IOptionsService } from '../../../common/services/Services';
export class TextBlinkStateManager extends Disposable {
+2 -2
View File
@@ -5,8 +5,8 @@
import { Terminal } from '@xterm/xterm';
import { ITerminal } from '../../Types';
import { IDisposable } from '../../../common/primitives/Types';
import type { IEvent } from '../../../common/primitives/Event';
import { IDisposable } from '../../../common/Types';
import type { IEvent } from '../../../common/Event';
export interface IDimensions {
width: number;
+1 -1
View File
@@ -11,7 +11,7 @@ import { ScrollbarArrow, IScrollbarArrowOptions } from './scrollbarArrow';
import { ScrollbarState } from './scrollbarState';
import { ScrollbarVisibilityController } from './scrollbarVisibilityController';
import { Widget } from './widget';
import * as platform from '../../common/primitives/Platform';
import * as platform from '../../common/Platform';
import { INewScrollPosition, Scrollable, ScrollbarVisibility } from './scrollable';
/**
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as dom from '../Dom';
import { DisposableStore, IDisposable, toDisposable } from '../../common/primitives/Lifecycle';
import { DisposableStore, IDisposable, toDisposable } from '../../common/Lifecycle';
type PointerMoveCallback = (event: PointerEvent) => void;
type OnStopCallback = () => void;
+1 -1
View File
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as platform from '../../common/primitives/Platform';
import * as platform from '../../common/Platform';
interface IWindowChainElement {
readonly window: WeakRef<Window>;
+2 -2
View File
@@ -3,8 +3,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Emitter, IEvent } from '../../common/primitives/Event';
import { Disposable, IDisposable } from '../../common/primitives/Lifecycle';
import { Emitter, IEvent } from '../../common/Event';
import { Disposable, IDisposable } from '../../common/Lifecycle';
export const enum ScrollbarVisibility {
AUTO = 1,
+4 -4
View File
@@ -11,10 +11,10 @@ import { HorizontalScrollbar } from './horizontalScrollbar';
import { IScrollableElementChangeOptions, IScrollableElementCreationOptions, IScrollableElementResolvedOptions } from './scrollableElementOptions';
import { VerticalScrollbar } from './verticalScrollbar';
import { Widget } from './widget';
import { TimeoutTimer } from '../../common/primitives/Async';
import { Emitter, IEvent } from '../../common/primitives/Event';
import { IDisposable, dispose } from '../../common/primitives/Lifecycle';
import * as platform from '../../common/primitives/Platform';
import { TimeoutTimer } from '../../common/Async';
import { Emitter, IEvent } from '../../common/Event';
import { IDisposable, dispose } from '../../common/Lifecycle';
import * as platform from '../../common/Platform';
import { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, IScrollEvent, Scrollable, ScrollbarVisibility } from './scrollable';
// import 'vs/css!./media/scrollbars';
+1 -1
View File
@@ -5,7 +5,7 @@
import { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';
import { Widget } from './widget';
import { TimeoutTimer } from '../../common/primitives/Async';
import { TimeoutTimer } from '../../common/Async';
import * as dom from '../Dom';
export interface IScrollbarArrowOptions {
@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import { FastDomNode } from './fastDomNode';
import { TimeoutTimer } from '../../common/primitives/Async';
import { Disposable } from '../../common/primitives/Lifecycle';
import { TimeoutTimer } from '../../common/Async';
import { Disposable } from '../../common/Lifecycle';
import { ScrollbarVisibility } from './scrollable';
export class ScrollbarVisibilityController extends Disposable {
+1 -1
View File
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as DomUtils from '../Dom';
import { Disposable, IDisposable, toDisposable } from '../../common/primitives/Lifecycle';
import { Disposable, IDisposable, toDisposable } from '../../common/Lifecycle';
const mainWindow = (typeof window === 'object' ? window : globalThis) as Window & typeof globalThis;
+1 -1
View File
@@ -5,7 +5,7 @@
import * as dom from '../Dom';
import { IMouseEvent, StandardMouseEvent } from './mouseEvent';
import { Disposable } from '../../common/primitives/Lifecycle';
import { Disposable } from '../../common/Lifecycle';
export abstract class Widget extends Disposable {
@@ -64,13 +64,6 @@ describe('SelectionModel', () => {
assert.deepEqual(model.finalSelectionStart, undefined);
assert.deepEqual(model.finalSelectionEnd, undefined);
});
it('should reset selection start to origin when start row is trimmed', () => {
model.selectionStart = [50, 0];
model.selectionEnd = [10, 2];
assert.equal(model.handleTrim(1), true);
assert.deepEqual(model.finalSelectionStart, [0, 0]);
assert.deepEqual(model.finalSelectionEnd, [10, 1]);
});
});
describe('finalSelectionStart', () => {
+2 -3
View File
@@ -135,10 +135,9 @@ export class SelectionModel {
return true;
}
// If the selection start row is trimmed away, reset to the buffer origin.
// If the selection start is trimmed, ensure the start column is 0.
if (this.selectionStart && this.selectionStart[1] < 0) {
this.selectionStart = [0, 0];
return true;
this.selectionStart[1] = 0;
}
return false;
}
+2 -2
View File
@@ -5,8 +5,8 @@
import { IOptionsService } from '../../common/services/Services';
import { ICharSizeService } from './Services';
import { Disposable } from '../../common/primitives/Lifecycle';
import { Emitter } from '../../common/primitives/Event';
import { Disposable } from '../../common/Lifecycle';
import { Emitter } from '../../common/Event';
export class CharSizeService extends Disposable implements ICharSizeService {
public serviceBrand: undefined;
@@ -6,10 +6,10 @@
import { assert } from 'chai';
import { ICharacterJoinerService } from './Services';
import { CharacterJoinerService } from './CharacterJoinerService';
import { BufferLine } from '../../common/primitives/buffer/BufferLine';
import { BufferLineStringCache } from '../../common/primitives/buffer/BufferLineStringCache';
import { IBufferLine } from '../../common/primitives/buffer/Types';
import { CellData } from '../../common/primitives/buffer/CellData';
import { BufferLine } from '../../common/buffer/BufferLine';
import { BufferLineStringCache } from '../../common/buffer/BufferLineStringCache';
import { IBufferLine } from '../../common/buffer/Types';
import { CellData } from '../../common/buffer/CellData';
import { MockBufferService, createCellData } from '../../common/TestUtils.test';
const TEST_STRING_CACHE = new BufferLineStringCache();
+8 -10
View File
@@ -3,11 +3,11 @@
* @license MIT
*/
import { CharData, IBufferLine, ICellData } from '../../common/primitives/buffer/Types';
import { CharData, IBufferLine, ICellData } from '../../common/buffer/Types';
import { ICharacterJoiner } from '../Types';
import { AttributeData } from '../../common/primitives/buffer/AttributeData';
import { WHITESPACE_CELL_CHAR, Content } from '../../common/primitives/buffer/Constants';
import { CellData } from '../../common/primitives/buffer/CellData';
import { AttributeData } from '../../common/buffer/AttributeData';
import { WHITESPACE_CELL_CHAR, Content } from '../../common/buffer/Constants';
import { CellData } from '../../common/buffer/CellData';
import { IBufferService } from '../../common/services/Services';
import { ICharacterJoinerService } from './Services';
@@ -100,7 +100,6 @@ export class CharacterJoinerService implements ICharacterJoinerService {
const ranges: [number, number][] = [];
const lineStr = line.translateToString(true);
const trimmedLength = line.getTrimmedLength();
// Because some cells can be represented by multiple javascript characters,
// we track the cell and the string indexes separately. This allows us to
@@ -112,7 +111,7 @@ export class CharacterJoinerService implements ICharacterJoinerService {
let rangeAttrFG = line.getFg(0);
let rangeAttrBG = line.getBg(0);
for (let x = 0; x < trimmedLength; x++) {
for (let x = 0; x < line.getTrimmedLength(); x++) {
line.loadCell(x, this._workCell);
if (this._workCell.getWidth() === 0) {
@@ -148,7 +147,7 @@ export class CharacterJoinerService implements ICharacterJoinerService {
}
// Process any trailing ranges.
if (trimmedLength - rangeStartColumn > 1) {
if (this._bufferService.cols - rangeStartColumn > 1) {
const joinedRanges = this._getJoinedRanges(
lineStr,
rangeStartStringIndex,
@@ -217,8 +216,7 @@ export class CharacterJoinerService implements ICharacterJoinerService {
return;
}
const trimmedLength = line.getTrimmedLength();
for (let x = startCol; x < trimmedLength; x++) {
for (let x = startCol; x < this._bufferService.cols; x++) {
const width = line.getWidth(x);
const length = line.getString(x).length || WHITESPACE_CELL_CHAR.length;
@@ -266,7 +264,7 @@ export class CharacterJoinerService implements ICharacterJoinerService {
// If there is still a range left at the end, it must extend all the way to
// the end of the line.
if (currentRange) {
currentRange[1] = trimmedLength;
currentRange[1] = this._bufferService.cols;
}
}
+2 -2
View File
@@ -4,9 +4,9 @@
*/
import { ICoreBrowserService } from './Services';
import { Emitter, EventUtils } from '../../common/primitives/Event';
import { Emitter, EventUtils } from '../../common/Event';
import { addDisposableListener } from '../Dom';
import { Disposable, MutableDisposable, toDisposable } from '../../common/primitives/Lifecycle';
import { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';
export class CoreBrowserService extends Disposable implements ICoreBrowserService {
public serviceBrand: undefined;
+5 -5
View File
@@ -4,12 +4,12 @@
*/
import { IKeyboardService } from './Services';
import { evaluateKeyboardEvent } from '../../common/primitives/input/Keyboard';
import { KittyKeyboard, KittyKeyboardEventType, KittyKeyboardFlags } from '../../common/primitives/input/KittyKeyboard';
import { Win32InputMode } from '../../common/primitives/input/Win32InputMode';
import { isMac } from '../../common/primitives/Platform';
import { evaluateKeyboardEvent } from '../../common/input/Keyboard';
import { KittyKeyboard, KittyKeyboardEventType, KittyKeyboardFlags } from '../../common/input/KittyKeyboard';
import { Win32InputMode } from '../../common/input/Win32InputMode';
import { isMac } from '../../common/Platform';
import { ICoreService, IOptionsService } from '../../common/services/Services';
import { IKeyboardResult } from '../../common/primitives/Types';
import { IKeyboardResult } from '../../common/Types';
export class KeyboardService implements IKeyboardService {
public serviceBrand: undefined;
+2 -2
View File
@@ -1,6 +1,6 @@
import { ILinkProvider, ILinkProviderService } from './Services';
import { Disposable, toDisposable } from '../../common/primitives/Lifecycle';
import { IDisposable } from '../../common/primitives/Types';
import { Disposable, toDisposable } from '../../common/Lifecycle';
import { IDisposable } from '../../common/Types';
export class LinkProviderService extends Disposable implements ILinkProviderService {
declare public serviceBrand: undefined;
+1 -1
View File
@@ -5,7 +5,7 @@
import { assert } from 'chai';
import { AltMouseCursorController, MouseEventCssClasses, MouseService } from './MouseService';
import { MouseStateService } from '../../common/services/MouseStateService';
import { CoreMouseAction, CoreMouseButton } from '../../common/primitives/Types';
import { CoreMouseAction, CoreMouseButton } from '../../common/Types';
import { IBufferService, ICoreService, ILogService, IOptionsService } from '../../common/services/Services';
import { OptionsService } from '../../common/services/OptionsService';
import { MockCoreBrowserService, MockRenderService, MockSelectionService } from '../TestUtils.test';
+3 -3
View File
@@ -5,9 +5,9 @@
import { addDisposableListener } from '../Dom';
import { IBufferService, IMouseStateService, ICoreService, ILogService, IOptionsService } from '../../common/services/Services';
import { CoreMouseAction, CoreMouseButton, CoreMouseEventType, ICoreMouseEvent, IDisposable } from '../../common/primitives/Types';
import { C0 } from '../../common/primitives/data/EscapeSequences';
import { DisposableStore, MutableDisposable, toDisposable } from '../../common/primitives/Lifecycle';
import { CoreMouseAction, CoreMouseButton, CoreMouseEventType, ICoreMouseEvent, IDisposable } from '../../common/Types';
import { C0 } from '../../common/data/EscapeSequences';
import { DisposableStore, MutableDisposable, toDisposable } from '../../common/Lifecycle';
import { ICoreBrowserService, IMouseCoordsService, IMouseService, IMouseServiceTarget, IRenderService, ISelectionService } from './Services';
import { Gesture, EventType as GestureEventType, IGestureEvent } from '../scrollable/touch';
+3 -3
View File
@@ -7,10 +7,10 @@ import { RenderDebouncer } from '../RenderDebouncer';
import { IRenderDebouncerWithCallback } from '../Types';
import { IRenderDimensions, IRenderer } from '../renderer/shared/Types';
import { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from './Services';
import { Disposable, MutableDisposable, toDisposable } from '../../common/primitives/Lifecycle';
import { DebouncedIdleTask } from '../../common/primitives/TaskQueue';
import { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';
import { DebouncedIdleTask } from '../../common/TaskQueue';
import { IBufferService, ICoreService, IDecorationService, ILogService, IOptionsService } from '../../common/services/Services';
import { Emitter } from '../../common/primitives/Event';
import { Emitter } from '../../common/Event';
interface ISelectionState {
start: [number, number] | undefined;
@@ -6,13 +6,13 @@
import { assert } from 'chai';
import { SelectionService, SelectionMode } from './SelectionService';
import { SelectionModel } from '../selection/SelectionModel';
import { IBuffer, IBufferLine } from '../../common/primitives/buffer/Types';
import { IBuffer, IBufferLine } from '../../common/buffer/Types';
import { MockBufferService, MockOptionsService, MockCoreService, MockMouseStateService, createCellData } from '../../common/TestUtils.test';
import { BufferLine } from '../../common/primitives/buffer/BufferLine';
import { BufferLineStringCache } from '../../common/primitives/buffer/BufferLineStringCache';
import { BufferLine } from '../../common/buffer/BufferLine';
import { BufferLineStringCache } from '../../common/buffer/BufferLineStringCache';
import { IBufferService, IOptionsService } from '../../common/services/Services';
import { MockCoreBrowserService, MockMouseService, MockRenderService } from '../TestUtils.test';
import { CellData } from '../../common/primitives/buffer/CellData';
import { CellData } from '../../common/buffer/CellData';
import { IRenderService } from './Services';
const TEST_STRING_CACHE = new BufferLineStringCache();
+8 -8
View File
@@ -9,14 +9,14 @@ import { moveToCellSequence } from '../input/MoveToCell';
import { SelectionModel } from '../selection/SelectionModel';
import { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';
import { ICoreBrowserService, IMouseCoordsService, IRenderService, ISelectionService } from './Services';
import { Disposable, MutableDisposable, toDisposable } from '../../common/primitives/Lifecycle';
import * as Browser from '../../common/primitives/Platform';
import { IDisposable } from '../../common/primitives/Types';
import { IBuffer, IBufferLine, ICellData } from '../../common/primitives/buffer/Types';
import { getRangeLength } from '../../common/primitives/buffer/BufferRange';
import { CellData } from '../../common/primitives/buffer/CellData';
import { Disposable, MutableDisposable, toDisposable } from '../../common/Lifecycle';
import * as Browser from '../../common/Platform';
import { IDisposable } from '../../common/Types';
import { IBuffer, IBufferLine, ICellData } from '../../common/buffer/Types';
import { getRangeLength } from '../../common/buffer/BufferRange';
import { CellData } from '../../common/buffer/CellData';
import { IBufferService, ICoreService, IMouseStateService, IOptionsService } from '../../common/services/Services';
import { Emitter } from '../../common/primitives/Event';
import { Emitter } from '../../common/Event';
const enum Constants {
/**
@@ -704,7 +704,7 @@ export class SelectionService extends Disposable implements ISelectionService {
if (this._activeSelectionMode !== SelectionMode.COLUMN) {
this._model.selectionEnd[0] = this._bufferService.cols;
}
this._model.selectionEnd[1] = Math.min(buffer.ydisp + this._bufferService.rows - 1, buffer.lines.length - 1);
this._model.selectionEnd[1] = Math.min(buffer.ydisp + this._bufferService.rows, buffer.lines.length - 1);
} else {
if (this._activeSelectionMode !== SelectionMode.COLUMN) {
this._model.selectionEnd[0] = 0;
+2 -2
View File
@@ -7,8 +7,8 @@ import { IRenderDimensions, IRenderer } from '../renderer/shared/Types';
import { IColorSet, ILink, ReadonlyColorSet } from '../Types';
import { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from '../selection/Types';
import { createDecorator } from '../../common/services/ServiceRegistry';
import { AllColorIndex, IDisposable, IKeyboardResult } from '../../common/primitives/Types';
import type { IEvent } from '../../common/primitives/Event';
import { AllColorIndex, IDisposable, IKeyboardResult } from '../../common/Types';
import type { IEvent } from '../../common/Event';
export const ICharSizeService = createDecorator<ICharSizeService>('CharSizeService');
export interface ICharSizeService {
+4 -4
View File
@@ -6,11 +6,11 @@
import { ColorContrastCache } from '../ColorContrastCache';
import { IThemeService } from './Services';
import { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from '../Types';
import { color, css, NULL_COLOR } from '../../common/primitives/Color';
import { Disposable } from '../../common/primitives/Lifecycle';
import { color, css, NULL_COLOR } from '../../common/Color';
import { Disposable } from '../../common/Lifecycle';
import { IOptionsService, ITheme } from '../../common/services/Services';
import { AllColorIndex, IColor, SpecialColorIndex } from '../../common/primitives/Types';
import { Emitter } from '../../common/primitives/Event';
import { AllColorIndex, IColor, SpecialColorIndex } from '../../common/Types';
import { Emitter } from '../../common/Event';
interface IRestoreColorSet {
foreground: IColor;
+7 -8
View File
@@ -26,21 +26,20 @@ import { InstantiationService } from './services/InstantiationService';
import { LogService } from './services/LogService';
import { BufferService, BufferServiceConstants } from './services/BufferService';
import { OptionsService } from './services/OptionsService';
import { IDisposable, IParams } from './primitives/Types';
import { IScrollEvent, ITerminalOptions } from './Types';
import { IAttributeData, IBufferSet } from './primitives/buffer/Types';
import { IDisposable, IScrollEvent, ITerminalOptions, IParams } from './Types';
import { IAttributeData, IBufferSet } from './buffer/Types';
import { CoreService } from './services/CoreService';
import { MouseStateService } from './services/MouseStateService';
import { UnicodeV6 } from './primitives/input/UnicodeV6';
import { UnicodeV6 } from './input/UnicodeV6';
import { UnicodeService } from './services/UnicodeService';
import { CharsetService } from './services/CharsetService';
import { updateWindowsModeWrappedState } from './WindowsMode';
import { IFunctionIdentifier } from './primitives/parser/Types';
import { IFunctionIdentifier } from './parser/Types';
import { InputHandler } from './InputHandler';
import { WriteBuffer } from './primitives/input/WriteBuffer';
import { WriteBuffer } from './input/WriteBuffer';
import { OscLinkService } from './services/OscLinkService';
import { Emitter, EventUtils, type IEvent } from './primitives/Event';
import { Disposable, MutableDisposable, toDisposable } from './primitives/Lifecycle';
import { Emitter, EventUtils, type IEvent } from './Event';
import { Disposable, MutableDisposable, toDisposable } from './Lifecycle';
// Only trigger this warning a single time per session
let hasWriteSyncWarnHappened = false;
+8 -8
View File
@@ -5,13 +5,13 @@
import { assert } from 'chai';
import { InputHandler } from './InputHandler';
import { IColorEvent, ColorRequestType, SpecialColorIndex } from './primitives/Types';
import { IAttributeData, IBufferLine } from './primitives/buffer/Types';
import { DEFAULT_ATTR_DATA } from './primitives/buffer/BufferLine';
import { CellData } from './primitives/buffer/CellData';
import { Attributes, BgFlags, UnderlineStyle } from './primitives/buffer/Constants';
import { AttributeData, ExtendedAttrs } from './primitives/buffer/AttributeData';
import { Params } from './primitives/parser/Params';
import { IColorEvent, ColorRequestType, SpecialColorIndex } from './Types';
import { IAttributeData, IBufferLine } from './buffer/Types';
import { DEFAULT_ATTR_DATA } from './buffer/BufferLine';
import { CellData } from './buffer/CellData';
import { Attributes, BgFlags, UnderlineStyle } from './buffer/Constants';
import { AttributeData, ExtendedAttrs } from './buffer/AttributeData';
import { Params } from './parser/Params';
import { MockCoreService, MockBufferService, MockOptionsService, MockLogService, MockMouseStateService, MockCharsetService, MockUnicodeService, MockOscLinkService, extendedAttributes } from './TestUtils.test';
import { IBufferService, ICoreService, type IOscLinkService } from './services/Services';
import { DEFAULT_OPTIONS } from './services/OptionsService';
@@ -19,7 +19,7 @@ import { BufferService } from './services/BufferService';
import { CharsetService } from './services/CharsetService';
import { CoreService } from './services/CoreService';
import { OscLinkService } from './services/OscLinkService';
import { CHARSETS } from './primitives/data/Charsets';
import { CHARSETS } from './data/Charsets';
function getCursor(bufferService: IBufferService): number[] {
+18 -19
View File
@@ -4,27 +4,26 @@
* @license MIT
*/
import { IDisposable, IColorEvent, ColorIndex, ColorRequestType, SpecialColorIndex } from './primitives/Types';
import { IInputHandler, IWindowOptions, IParseStack } from './Types';
import { IAttributeData, IBuffer } from './primitives/buffer/Types';
import { C0, C1 } from './primitives/data/EscapeSequences';
import { CHARSETS, DEFAULT_CHARSET } from './primitives/data/Charsets';
import { EscapeSequenceParser } from './primitives/parser/EscapeSequenceParser';
import { Disposable } from './primitives/Lifecycle';
import { StringToUtf32, stringFromCodePoint, Utf8ToUtf32 } from './primitives/input/TextDecoder';
import { BufferLine, DEFAULT_ATTR_DATA } from './primitives/buffer/BufferLine';
import { IParsingState, IEscapeSequenceParser, IParams, IFunctionIdentifier } from './primitives/parser/Types';
import { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content, UnderlineStyle } from './primitives/buffer/Constants';
import { CellData } from './primitives/buffer/CellData';
import { AttributeData } from './primitives/buffer/AttributeData';
import { IInputHandler, IDisposable, IWindowOptions, IColorEvent, IParseStack, ColorIndex, ColorRequestType, SpecialColorIndex } from './Types';
import { IAttributeData, IBuffer } from './buffer/Types';
import { C0, C1 } from './data/EscapeSequences';
import { CHARSETS, DEFAULT_CHARSET } from './data/Charsets';
import { EscapeSequenceParser } from './parser/EscapeSequenceParser';
import { Disposable } from './Lifecycle';
import { StringToUtf32, stringFromCodePoint, Utf8ToUtf32 } from './input/TextDecoder';
import { BufferLine, DEFAULT_ATTR_DATA } from './buffer/BufferLine';
import { IParsingState, IEscapeSequenceParser, IParams, IFunctionIdentifier } from './parser/Types';
import { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content, UnderlineStyle } from './buffer/Constants';
import { CellData } from './buffer/CellData';
import { AttributeData } from './buffer/AttributeData';
import { ICoreService, IBufferService, IOptionsService, ILogService, IMouseStateService, ICharsetService, IUnicodeService, LogLevelEnum, IOscLinkService } from './services/Services';
import { UnicodeService } from './services/UnicodeService';
import { OscHandler } from './primitives/parser/OscParser';
import { DcsHandler } from './primitives/parser/DcsParser';
import { ApcHandler } from './primitives/parser/ApcParser';
import { parseColor } from './primitives/input/XParseColor';
import { Emitter } from './primitives/Event';
import { XTERM_VERSION } from './primitives/Version';
import { OscHandler } from './parser/OscParser';
import { DcsHandler } from './parser/DcsParser';
import { ApcHandler } from './parser/ApcParser';
import { parseColor } from './input/XParseColor';
import { Emitter } from './Event';
import { XTERM_VERSION } from './Version';
/**
* Map collect to glevel. Used in `selectCharset`.
@@ -6,9 +6,9 @@
* Simplified from VS Code's lifecycle.ts - no tracking/leak detection.
*/
import type { IDisposable } from './Types';
export type { IDisposable };
export interface IDisposable {
dispose(): void;
}
export function toDisposable(fn: () => void): IDisposable {
return { dispose: fn };
@@ -5,7 +5,7 @@
import { assert } from 'chai';
import { SortedList } from './SortedList';
import { MockLogService } from '../TestUtils.test';
import { MockLogService } from './TestUtils.test';
const deepStrictEqual = assert.deepStrictEqual;
@@ -4,7 +4,7 @@
*/
import { IdleTaskQueue } from './TaskQueue';
import type { ILogService } from '../services/Services';
import type { ILogService } from './services/Services';
// Work variables to avoid garbage collection.
let i = 0;

Some files were not shown because too many files have changed in this diff Show More