Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18100d32fb | ||
|
|
07bdaf8767 | ||
|
|
584954b4fb | ||
|
|
9a96b27566 | ||
|
|
a04941a936 | ||
|
|
91fcb46a1a | ||
|
|
1d569f873d | ||
|
|
db244ea5a8 | ||
|
|
fdcd1c2720 | ||
|
|
57b48f6048 | ||
|
|
ec0c93fd5a | ||
|
|
be339bf796 | ||
|
|
7294124736 | ||
|
|
2c3fad39af | ||
|
|
edb4f89dd8 | ||
|
|
224c113b64 | ||
|
|
3e0c7d18e5 | ||
|
|
95d9224b8c | ||
|
|
7499a2181d | ||
|
|
7dc820f5fa | ||
|
|
e59a6c1f7b | ||
|
|
f3e2c08a5d | ||
|
|
b138bf38d0 | ||
|
|
c6e4627b45 | ||
|
|
d91045dc5f | ||
|
|
41dfdba2cf | ||
|
|
ba33decb68 | ||
|
|
17e3b84bcc | ||
|
|
182ff2f635 | ||
|
|
bcb4e5298b | ||
|
|
42facac2d9 | ||
|
|
2ab0f10a26 | ||
|
|
280dc0a36a | ||
|
|
ebe8cb749a | ||
|
|
c28f3c8d73 | ||
|
|
3bd7ac083a | ||
|
|
30b42838fd | ||
|
|
80e832e417 | ||
|
|
470947abd8 | ||
|
|
bb49a80ace | ||
|
|
65b87e0f40 | ||
|
|
39fc0f259e | ||
|
|
b787ac8b1b | ||
|
|
457efbf55d | ||
|
|
42270a0b68 | ||
|
|
090b77f354 | ||
|
|
534ce1365b | ||
|
|
f757c965ee | ||
|
|
4aa02f3fd9 | ||
|
|
f43273b3f0 | ||
|
|
c06c3025f2 | ||
|
|
1064e4f783 | ||
|
|
fad4821fd9 | ||
|
|
306c3d73ec | ||
|
|
8f2bb32c9c | ||
|
|
7b6c814566 | ||
|
|
adc9dea083 | ||
|
|
d565a2750e | ||
|
|
c5ab83d697 | ||
|
|
c62e6dd765 | ||
|
|
29a07f1d8f | ||
|
|
88cef97049 | ||
|
|
0e823004e6 | ||
|
|
df3422fb0b | ||
|
|
4ec85e67ba | ||
|
|
1a67b6f4b3 | ||
|
|
afaed108e4 | ||
|
|
c27d6bb462 | ||
|
|
9c4f0f96ca | ||
|
|
18c370a154 | ||
|
|
850f4ad738 | ||
|
|
b665f6259a | ||
|
|
d195dc9a3b | ||
|
|
4e5994d8a2 | ||
|
|
4a0cb5ae6b | ||
|
|
9e72a4b6d3 | ||
|
|
f484584b70 | ||
|
|
17e7dafa17 | ||
|
|
41d9c4080f | ||
|
|
685434ca84 | ||
|
|
ff72c00219 | ||
|
|
69ee4ad23b | ||
|
|
253d1e9beb |
@@ -24,6 +24,7 @@ test-results/
|
||||
|
||||
# Tracing/debug files
|
||||
.cursor/nal-trace/
|
||||
.cursor/*.log
|
||||
|
||||
# Keep bundled code out of Git
|
||||
dist/
|
||||
|
||||
@@ -13,15 +13,11 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"@xterm/addon-attach": [
|
||||
"../typings/addon-attach.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-attach.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,19 +13,12 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-clipboard": [
|
||||
"../typings/addon-clipboard.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-clipboard.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type { Terminal, ITerminalAddon, IRenderDimensions } from '@xterm/xterm';
|
||||
import type { FitAddon as IFitApi } from '@xterm/addon-fit';
|
||||
import { ViewportConstants } from 'browser/shared/Constants';
|
||||
import { ViewportConstants } from '../../../src/browser/shared/Constants';
|
||||
|
||||
interface ITerminalDimensions {
|
||||
/**
|
||||
|
||||
@@ -13,19 +13,12 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-fit": [
|
||||
"../typings/addon-fit.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-fit.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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/Event';
|
||||
import { Emitter, type IEvent } from '../../../src/common/Event';
|
||||
import { IIPHandler } from './IIPHandler';
|
||||
import { ImageRenderer } from './ImageRenderer';
|
||||
import { ImageStorage, CELL_SIZE_DEFAULT } from './ImageStorage';
|
||||
|
||||
@@ -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/Lifecycle';
|
||||
import { Disposable, MutableDisposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
|
||||
const enum Constants {
|
||||
PLACEHOLDER_LENGTH = 4096,
|
||||
@@ -21,9 +21,7 @@ const enum Constants {
|
||||
*/
|
||||
export class ImageRenderer extends Disposable implements IDisposable {
|
||||
/** @deprecated Kept for backward compat — points to top layer canvas. */
|
||||
public get canvas(): HTMLCanvasElement | undefined {
|
||||
return this._layers.get('top')?.canvas;
|
||||
}
|
||||
public get canvas(): HTMLCanvasElement | undefined { return this._layers.get('top')?.canvas; }
|
||||
private _layers = new Map<ImageLayer, CanvasRenderingContext2D>();
|
||||
private _placeholder: HTMLCanvasElement | undefined;
|
||||
private _placeholderBitmap: ImageBitmap | undefined;
|
||||
|
||||
@@ -31,9 +31,7 @@ class ExtendedAttrsImage implements IExtendedAttrsImage {
|
||||
}
|
||||
return this._ext;
|
||||
}
|
||||
public set ext(value: number) {
|
||||
this._ext = value;
|
||||
}
|
||||
public set ext(value: number) { this._ext = value; }
|
||||
|
||||
public get underlineStyle(): UnderlineStyle {
|
||||
// Always return the URL style if it has one
|
||||
|
||||
@@ -91,7 +91,7 @@ export class SixelHandler implements IDcsHandler, IResetHandler {
|
||||
const height = this._dec.height;
|
||||
|
||||
// partial fix for https://github.com/jerch/xterm-addon-image/issues/37
|
||||
if (!width || ! height) {
|
||||
if (!width || !height) {
|
||||
if (height) {
|
||||
this._storage.advanceCursor(height);
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
import { IDisposable, IMarker, Terminal } from '@xterm/xterm';
|
||||
|
||||
// private imports from base repo we build against
|
||||
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 { IBufferLine, IExtendedAttrs, IInputHandler } from 'common/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';
|
||||
import { Attributes, BgFlags, Content, ExtFlags, UnderlineStyle } from '../../../src/common/buffer/Constants';
|
||||
import type { AttributeData } from '../../../src/common/buffer/AttributeData';
|
||||
import type { IParams, IDcsHandler, IOscHandler, IApcHandler, IEscapeSequenceParser } from '../../../src/common/parser/Types';
|
||||
import type { IBufferLine, IExtendedAttrs, IInputHandler } from '../../../src/common/Types';
|
||||
import type { ITerminal, ReadonlyColorSet } from '../../../src/browser/Types';
|
||||
import type { IRenderDimensions } from '../../../src/browser/renderer/shared/Types';
|
||||
import type { ICoreBrowserService, IRenderService, IThemeService } from '../../../src/browser/services/Services';
|
||||
|
||||
export const enum Cell {
|
||||
CONTENT = 0, // codepoint and wcwidth information (enum Content)
|
||||
|
||||
@@ -10,20 +10,19 @@
|
||||
"preserveWatchOutput": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"browser/*": [ "../../../src/browser/*" ],
|
||||
"common/*": [ "../../../src/common/*" ],
|
||||
"@xterm/addon-image": [ "../typings/addon-image.d.ts" ],
|
||||
"*": [ "./*" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-image.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../../../src/browser" },
|
||||
{ "path": "../../../src/common" }
|
||||
{
|
||||
"path": "../../../src/browser"
|
||||
},
|
||||
{
|
||||
"path": "../../../src/common"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -322,9 +322,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('chunked transfer responds OK on final chunk when i= on first only', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
const half = Math.floor(KITTY_BLACK_1X1_BASE64.length / 2);
|
||||
@@ -544,9 +542,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
let response = '';
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write('\x1b_Gi=31,a=q;\x1b\\');
|
||||
@@ -560,9 +556,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
let response = '';
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=42,a=q,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -587,9 +581,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
let response = '';
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write('\x1b_Gi=60,a=q,f=100;!!!invalid!!!\x1b\\');
|
||||
@@ -603,9 +595,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
let response = '';
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write('\x1b_Gi=70,a=q,f=24;AAAA\x1b\\');
|
||||
@@ -618,9 +608,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('suppresses OK response when q=1', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=80,a=q,q=1,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -632,9 +620,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('suppresses OK response when q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=81,a=q,q=2,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -646,9 +632,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('suppresses error response when q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write('\x1b_Gi=90,a=q,q=2,f=100;!!!invalid!!!\x1b\\');
|
||||
@@ -661,9 +645,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
let response = '';
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
// Per spec: "Specifying both i and I keys in any command is an error"
|
||||
@@ -678,9 +660,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
let response = '';
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
// Delete command with both i and I (no payload case)
|
||||
@@ -696,9 +676,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=t sends EINVAL on decode error when id is specified', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write('\x1b_Gi=110,a=t,f=100;!!!invalid!!!\x1b\\');
|
||||
@@ -711,9 +689,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=t sends no response on decode error without id', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write('\x1b_Ga=t,f=100;!!!invalid!!!\x1b\\');
|
||||
@@ -725,9 +701,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=T sends EINVAL on decode error when id is specified', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write('\x1b_Gi=120,a=T,f=100;!!!invalid!!!\x1b\\');
|
||||
@@ -740,9 +714,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=T sends no response on decode error without id', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write('\x1b_Ga=T,f=100;!!!invalid!!!\x1b\\');
|
||||
@@ -754,9 +726,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=T sends EINVAL when raw pixel render fails (missing dimensions)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=130,a=T,f=24;${RAW_RGB_1X1_BLACK}\x1b\\`);
|
||||
@@ -769,9 +739,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=T sends OK on successful render with id', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=140,a=T,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -784,9 +752,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=t sends OK on successful transmit with id', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=150,a=t,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -799,9 +765,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=t EINVAL suppressed by q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write('\x1b_Gi=160,a=t,q=2,f=100;!!!invalid!!!\x1b\\');
|
||||
@@ -813,9 +777,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=T EINVAL suppressed by q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write('\x1b_Gi=170,a=T,q=2,f=100;!!!invalid!!!\x1b\\');
|
||||
@@ -827,9 +789,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=t OK suppressed by q=1', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=180,a=t,q=1,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -841,9 +801,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=T OK suppressed by q=1', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=190,a=T,q=1,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -855,9 +813,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=t OK suppressed by q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=181,a=t,q=2,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -869,9 +825,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('a=T OK suppressed by q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=191,a=T,q=2,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -885,9 +839,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query rejects t=f (file transmission)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=200,a=q,t=f,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -900,9 +852,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query rejects t=s (shared memory)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=201,a=q,t=s,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -915,9 +865,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query rejects t=t (temp file)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=202,a=q,t=t,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -930,9 +878,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query accepts t=d (direct transmission)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=203,a=q,t=d,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -945,9 +891,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query without t key defaults to direct (OK)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=204,a=q,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -960,9 +904,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('transmit rejects t=f with id (EINVAL response)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=300,a=t,t=f,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -975,9 +917,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('transmit rejects t=s with id (EINVAL response)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=301,a=t,t=s,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -990,9 +930,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('transmit rejects t=t with id (EINVAL response)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=302,a=t,t=t,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -1005,9 +943,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('transmit rejects t=f without id (no response)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=t,t=f,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -1020,9 +956,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('transmit+display rejects t=f with id (EINVAL response)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=310,a=T,t=f,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -1035,9 +969,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('transmit+display rejects t=s with id (EINVAL response)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=311,a=T,t=s,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -1050,9 +982,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('transmit+display rejects t=t with id (EINVAL response)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=312,a=T,t=t,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -1065,9 +995,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('transmit+display rejects t=f without id (no response)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=T,t=f,f=100;${KITTY_BLACK_1X1_BASE64}\x1b\\`);
|
||||
@@ -1098,9 +1026,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=p,i=211\x1b\\`);
|
||||
@@ -1113,9 +1039,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('responds ENOENT for non-existent image id', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=p,i=9999\x1b\\`);
|
||||
@@ -1128,9 +1052,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('without id sends no response', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=p\x1b\\`);
|
||||
@@ -1250,9 +1172,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=p,i=220,q=1\x1b\\`);
|
||||
@@ -1268,9 +1188,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=p,i=221,q=2\x1b\\`);
|
||||
@@ -1283,9 +1201,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('ENOENT error suppressed by q=2', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyGotResponse = false;
|
||||
(window as any).term.onData(() => {
|
||||
(window as any).kittyGotResponse = true;
|
||||
});
|
||||
(window as any).term.onData(() => { (window as any).kittyGotResponse = true; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=p,i=9998,q=2\x1b\\`);
|
||||
@@ -1297,9 +1213,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('ENOENT still reported when q=1 (only suppresses OK)', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=p,i=9997,q=1\x1b\\`);
|
||||
@@ -1354,9 +1268,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Ga=p,i=224,p=42\x1b\\`);
|
||||
@@ -1891,9 +1803,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('responds with OK for valid 200x100 PNG query', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
|
||||
await ctx.proxy.write(`\x1b_Gi=600,a=q,f=100;${KITTY_MULTICOLOR_200X100_BASE64}\x1b\\`);
|
||||
@@ -2042,9 +1952,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query returns EINVAL without dimensions', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
await ctx.proxy.write(`\x1b_Gi=200,a=q,f=24;${RAW_RGB_1X1_BLACK}\x1b\\`);
|
||||
await timeout(100);
|
||||
@@ -2055,9 +1963,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query returns EINVAL for insufficient pixel data', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
await ctx.proxy.write(`\x1b_Gi=201,a=q,f=24,s=2,v=2;${RAW_RGB_1X1_BLACK}\x1b\\`);
|
||||
await timeout(100);
|
||||
@@ -2068,9 +1974,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query returns OK for valid RGB data with correct dimensions', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
await ctx.proxy.write(`\x1b_Gi=202,a=q,f=24,s=1,v=1;${RAW_RGB_1X1_RED}\x1b\\`);
|
||||
await timeout(100);
|
||||
@@ -2182,9 +2086,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query returns EINVAL without dimensions', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
await ctx.proxy.write(`\x1b_Gi=300,a=q,f=32;${RAW_RGBA_1X1_RED}\x1b\\`);
|
||||
await timeout(100);
|
||||
@@ -2195,9 +2097,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query returns EINVAL for insufficient pixel data', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
await ctx.proxy.write(`\x1b_Gi=301,a=q,f=32,s=2,v=2;${RAW_RGBA_1X1_RED}\x1b\\`);
|
||||
await timeout(100);
|
||||
@@ -2208,9 +2108,7 @@ test.describe('Kitty Graphics Protocol', () => {
|
||||
test('query returns OK for valid RGBA data with correct dimensions', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
(window as any).kittyResponse = '';
|
||||
(window as any).term.onData((data: string) => {
|
||||
(window as any).kittyResponse = data;
|
||||
});
|
||||
(window as any).term.onData((data: string) => { (window as any).kittyResponse = data; });
|
||||
});
|
||||
await ctx.proxy.write(`\x1b_Gi=302,a=q,f=32,s=1,v=1;${RAW_RGBA_1X1_RED}\x1b\\`);
|
||||
await timeout(100);
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"package": "webpack",
|
||||
"pretest": "npm run build",
|
||||
"test": "nyc mocha out/**/*.test.js",
|
||||
"prepublish": "npm run package"
|
||||
"prepublishOnly": "npm run package"
|
||||
},
|
||||
"keywords": [
|
||||
"font",
|
||||
@@ -37,7 +37,7 @@
|
||||
"devDependencies": {
|
||||
"@types/lru-cache": "^5.1.0",
|
||||
"@types/opentype.js": "^0.7.0",
|
||||
"axios": "^1.15.0",
|
||||
"axios": "^1.15.2",
|
||||
"font-finder": "^1.1.0",
|
||||
"mkdirp": "0.5.5",
|
||||
"yauzl": "^3.2.1"
|
||||
|
||||
@@ -65,8 +65,9 @@ export default async function load(fontFamily: string, cacheSize: number): Promi
|
||||
console.error(err.name, err.message);
|
||||
}
|
||||
}
|
||||
} else if (typeof window !== 'undefined' && 'queryLocalFonts' in window) {
|
||||
// Latest proposal https://bugs.chromium.org/p/chromium/issues/detail?id=1312603
|
||||
}
|
||||
// Latest proposal https://bugs.chromium.org/p/chromium/issues/detail?id=1312603
|
||||
else if (typeof window !== 'undefined' && 'queryLocalFonts' in window) {
|
||||
const fonts: Record<string, IFontMetadata[]> = {};
|
||||
try {
|
||||
const fontsIterator = await (window as any).queryLocalFonts();
|
||||
|
||||
@@ -10,17 +10,12 @@
|
||||
"preserveWatchOutput": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha",
|
||||
// HACK: src shouldn't use node types but it's needed for index.test.ts
|
||||
"../../../node_modules/@types/node"
|
||||
],
|
||||
"paths": {
|
||||
"@xterm/addon-ligatures" : [
|
||||
"../typings/addon-ligatures.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-ligatures.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -46,9 +46,7 @@ describe('LigaturesAddon', () => {
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
onRefresh = Object.assign((..._args: any[]) => {
|
||||
onRefresh.called = true; onRefresh.callCount++;
|
||||
}, { called: false, callCount: 0 });
|
||||
onRefresh = Object.assign((..._args: any[]) => { onRefresh.called = true; onRefresh.callCount++; }, { called: false, callCount: 0 });
|
||||
term = new MockTerminal(onRefresh);
|
||||
ligatureSupport.enableLigatures(term as any);
|
||||
});
|
||||
@@ -129,9 +127,7 @@ class MockTerminal {
|
||||
public deregisterCharacterJoiner(id: number): void {
|
||||
this.joiner = undefined;
|
||||
}
|
||||
public get options(): { [name: string]: string | number } {
|
||||
return this._options;
|
||||
}
|
||||
public get options(): { [name: string]: string | number } { return this._options; }
|
||||
public set options(options: { [name: string]: string | number }) {
|
||||
for (const key in this._options) {
|
||||
this._options[key] = options[key];
|
||||
|
||||
@@ -10,11 +10,6 @@
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"strict": true,
|
||||
"paths": {
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha",
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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/Event';
|
||||
import type { Emitter, IEvent } from '../../../src/common/Event';
|
||||
|
||||
|
||||
const enum ProgressType {
|
||||
|
||||
@@ -13,22 +13,12 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-progress": [
|
||||
"../typings/addon-progress.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-progress.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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/Lifecycle';
|
||||
import { dispose, Disposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import type { ISearchResult } from './SearchEngine';
|
||||
|
||||
/**
|
||||
@@ -64,9 +64,7 @@ export class DecorationManager extends Disposable {
|
||||
public createActiveDecoration(result: ISearchResult, options: ISearchDecorationOptions): IMultiHighlight | undefined {
|
||||
const decorations = this._createResultDecorations(result, options, true);
|
||||
if (decorations) {
|
||||
return { decorations, match: result, dispose() {
|
||||
dispose(decorations);
|
||||
} };
|
||||
return { decorations, match: result, dispose() { dispose(decorations); } };
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -87,9 +85,7 @@ export class DecorationManager extends Disposable {
|
||||
*/
|
||||
private _storeDecoration(decoration: IDecoration, match: ISearchResult): void {
|
||||
this._highlightedLines.add(decoration.marker.line);
|
||||
this._highlightDecorations.push({ decoration, match, dispose() {
|
||||
decoration.dispose();
|
||||
} });
|
||||
this._highlightDecorations.push({ decoration, match, dispose() { decoration.dispose(); } });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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/Event';
|
||||
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
||||
import { disposableTimeout } from 'common/Async';
|
||||
import { Emitter, type IEvent } from '../../../src/common/Event';
|
||||
import { Disposable, MutableDisposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { disposableTimeout } from '../../../src/common/Async';
|
||||
import { SearchLineCache } from './SearchLineCache';
|
||||
import { SearchState } from './SearchState';
|
||||
import { SearchEngine, type ISearchResult } from './SearchEngine';
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
import { assert } from 'chai';
|
||||
import { SearchEngine } from './SearchEngine';
|
||||
import { SearchLineCache } from './SearchLineCache';
|
||||
import { Terminal } from 'browser/public/Terminal';
|
||||
import { Terminal } from '../../../src/browser/public/Terminal';
|
||||
import type { ISearchOptions } from '@xterm/addon-search';
|
||||
import { DisposableStore } from 'common/Lifecycle';
|
||||
import { DisposableStore } from '../../../src/common/Lifecycle';
|
||||
|
||||
function writeP(terminal: Terminal, data: string): Promise<void> {
|
||||
return new Promise(r => terminal.write(data, r));
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
import { assert } from 'chai';
|
||||
import { SearchLineCache, LineCacheEntry } from './SearchLineCache';
|
||||
import { Terminal } from 'browser/public/Terminal';
|
||||
import { timeout } from 'common/Async';
|
||||
import { Terminal } from '../../../src/browser/public/Terminal';
|
||||
import { timeout } from '../../../src/common/Async';
|
||||
|
||||
function writeP(terminal: Terminal, data: string): Promise<void> {
|
||||
return new Promise(r => terminal.write(data, r));
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import type { Terminal } from '@xterm/xterm';
|
||||
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
||||
import { disposableTimeout } from 'common/Async';
|
||||
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { disposableTimeout } from '../../../src/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/Event';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
import { Emitter, type IEvent } from '../../../src/common/Event';
|
||||
import { Disposable } from '../../../src/common/Lifecycle';
|
||||
import type { ISearchResult } from './SearchEngine';
|
||||
|
||||
/**
|
||||
@@ -25,9 +25,7 @@ export class SearchResultTracker extends Disposable {
|
||||
private _selectedDecoration: ISelectedDecoration | undefined;
|
||||
|
||||
private readonly _onDidChangeResults = this._register(new Emitter<ISearchResultChangeEvent>());
|
||||
public get onDidChangeResults(): IEvent<ISearchResultChangeEvent> {
|
||||
return this._onDidChangeResults.event;
|
||||
}
|
||||
public get onDidChangeResults(): IEvent<ISearchResultChangeEvent> { return this._onDidChangeResults.event; }
|
||||
|
||||
/**
|
||||
* Gets the current search results.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"target": "es2021",
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out",
|
||||
@@ -13,22 +13,12 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-search" : [
|
||||
"../typings/addon-search.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-search.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark';
|
||||
|
||||
import { spawn } from 'node-pty';
|
||||
import { Utf8ToUtf32, stringFromCodePoint } from 'common/input/TextDecoder';
|
||||
import { Terminal } from 'browser/public/Terminal';
|
||||
import { SerializeAddon } from 'SerializeAddon';
|
||||
import { Utf8ToUtf32, stringFromCodePoint } from '../../../src/common/input/TextDecoder';
|
||||
import { Terminal } from '../../../src/browser/public/Terminal';
|
||||
import { SerializeAddon } from '../src/SerializeAddon';
|
||||
|
||||
class TestTerminal extends Terminal {
|
||||
public writeSync(data: string): void {
|
||||
|
||||
@@ -6,24 +6,28 @@
|
||||
],
|
||||
"rootDir": "..",
|
||||
"outDir": "../out-benchmark",
|
||||
"types": ["../../../node_modules/@types/node"],
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
],
|
||||
"moduleResolution": "node",
|
||||
"strict": false,
|
||||
"target": "es2021",
|
||||
"module": "commonjs",
|
||||
"paths": {
|
||||
"common/*": ["../../../src/common/*"],
|
||||
"browser/*": ["../../../src/browser/*"],
|
||||
"SerializeAddon": ["../src/SerializeAddon"],
|
||||
"@xterm/addon-serialize": [
|
||||
"../typings/addon-serialize.d.ts"
|
||||
]
|
||||
}
|
||||
"module": "commonjs"
|
||||
},
|
||||
"include": ["../**/*", "../../../typings/xterm.d.ts"],
|
||||
"exclude": ["../../../**/*test.ts", "../../**/*api.ts"],
|
||||
"include": [
|
||||
"../**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"../../../**/*test.ts",
|
||||
"../../**/*api.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../../../src/common" },
|
||||
{ "path": "../../../src/browser" }
|
||||
{
|
||||
"path": "../../../src/common"
|
||||
},
|
||||
{
|
||||
"path": "../../../src/browser"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
import jsdom = require('jsdom');
|
||||
import { assert } from 'chai';
|
||||
import { SerializeAddon } from './SerializeAddon';
|
||||
import { Terminal } from 'browser/public/Terminal';
|
||||
import { SelectionModel } from 'browser/selection/SelectionModel';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
import { ThemeService } from 'browser/services/ThemeService';
|
||||
import { Terminal } from '../../../src/browser/public/Terminal';
|
||||
import { SelectionModel } from '../../../src/browser/selection/SelectionModel';
|
||||
import { IBufferService } from '../../../src/common/services/Services';
|
||||
import { ThemeService } from '../../../src/browser/services/ThemeService';
|
||||
|
||||
function sgr(...seq: string[]): string {
|
||||
return `\x1b[${seq.join(';')}m`;
|
||||
@@ -29,20 +29,12 @@ class TestSelectionService {
|
||||
this._model = new SelectionModel(bufferService);
|
||||
}
|
||||
|
||||
public get model(): SelectionModel {
|
||||
return this._model;
|
||||
}
|
||||
public get model(): SelectionModel { return this._model; }
|
||||
|
||||
public get hasSelection(): boolean {
|
||||
return this._hasSelection;
|
||||
}
|
||||
public get hasSelection(): boolean { return this._hasSelection; }
|
||||
|
||||
public get selectionStart(): [number, number] | undefined {
|
||||
return this._model.finalSelectionStart;
|
||||
}
|
||||
public get selectionEnd(): [number, number] | undefined {
|
||||
return this._model.finalSelectionEnd;
|
||||
}
|
||||
public get selectionStart(): [number, number] | undefined { return this._model.finalSelectionStart; }
|
||||
public get selectionEnd(): [number, number] | undefined { return this._model.finalSelectionEnd; }
|
||||
|
||||
public setSelection(col: number, row: number, length: number): void {
|
||||
this._model.selectionStart = [col, row];
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
import type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm';
|
||||
import type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize';
|
||||
import { IAttributeData, IColor } from 'common/Types';
|
||||
import { DEFAULT_ANSI_COLORS } from 'browser/Types';
|
||||
import { UnderlineStyle } from 'common/buffer/Constants';
|
||||
import { IAttributeData, IColor } from '../../../src/common/Types';
|
||||
import { DEFAULT_ANSI_COLORS } from '../../../src/browser/Types';
|
||||
import { UnderlineStyle } from '../../../src/common/buffer/Constants';
|
||||
|
||||
function constrain(value: number, low: number, high: number): number {
|
||||
return Math.max(low, Math.min(value, high));
|
||||
@@ -70,9 +70,7 @@ abstract class BaseSerializeHandler {
|
||||
protected _rowEnd(row: number, isLastRow: boolean): void { }
|
||||
protected _beforeSerialize(rows: number, startRow: number, endRow: number): void { }
|
||||
protected _afterSerialize(): void { }
|
||||
protected _serializeString(excludeFinalCursorPosition?: boolean): string {
|
||||
return '';
|
||||
}
|
||||
protected _serializeString(excludeFinalCursorPosition?: boolean): string { return ''; }
|
||||
}
|
||||
|
||||
function equalFg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {
|
||||
@@ -293,39 +291,25 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
} else {
|
||||
if (fgChanged) {
|
||||
const color = cell.getFgColor();
|
||||
if (cell.isFgRGB()) {
|
||||
sgrSeq.push(38, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF);
|
||||
} else if (cell.isFgPalette()) {
|
||||
if (color >= 16) {
|
||||
sgrSeq.push(38, 5, color);
|
||||
} else {
|
||||
sgrSeq.push(color & 8 ? 90 + (color & 7) : 30 + (color & 7));
|
||||
}
|
||||
} else {
|
||||
sgrSeq.push(39);
|
||||
if (cell.isFgRGB()) { sgrSeq.push(38, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }
|
||||
else if (cell.isFgPalette()) {
|
||||
if (color >= 16) { sgrSeq.push(38, 5, color); }
|
||||
else { sgrSeq.push(color & 8 ? 90 + (color & 7) : 30 + (color & 7)); }
|
||||
}
|
||||
else { sgrSeq.push(39); }
|
||||
}
|
||||
if (bgChanged) {
|
||||
const color = cell.getBgColor();
|
||||
if (cell.isBgRGB()) {
|
||||
sgrSeq.push(48, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF);
|
||||
} else if (cell.isBgPalette()) {
|
||||
if (color >= 16) {
|
||||
sgrSeq.push(48, 5, color);
|
||||
} else {
|
||||
sgrSeq.push(color & 8 ? 100 + (color & 7) : 40 + (color & 7));
|
||||
}
|
||||
} else {
|
||||
sgrSeq.push(49);
|
||||
if (cell.isBgRGB()) { sgrSeq.push(48, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }
|
||||
else if (cell.isBgPalette()) {
|
||||
if (color >= 16) { sgrSeq.push(48, 5, color); }
|
||||
else { sgrSeq.push(color & 8 ? 100 + (color & 7) : 40 + (color & 7)); }
|
||||
}
|
||||
else { sgrSeq.push(49); }
|
||||
}
|
||||
if (flagsChanged) {
|
||||
if (cell.isInverse() !== oldCell.isInverse()) {
|
||||
sgrSeq.push(cell.isInverse() ? 7 : 27);
|
||||
}
|
||||
if (cell.isBold() !== oldCell.isBold()) {
|
||||
sgrSeq.push(cell.isBold() ? 1 : 22);
|
||||
}
|
||||
if (cell.isInverse() !== oldCell.isInverse()) { sgrSeq.push(cell.isInverse() ? 7 : 27); }
|
||||
if (cell.isBold() !== oldCell.isBold()) { sgrSeq.push(cell.isBold() ? 1 : 22); }
|
||||
if (!equalUnderline(cell, oldCell)) {
|
||||
const style = cell.getUnderlineStyle();
|
||||
if (style === UnderlineStyle.NONE) {
|
||||
@@ -348,24 +332,12 @@ class StringSerializeHandler extends BaseSerializeHandler {
|
||||
} else if (cell.isUnderline() !== oldCell.isUnderline()) {
|
||||
sgrSeq.push(cell.isUnderline() ? 4 : 24);
|
||||
}
|
||||
if (cell.isOverline() !== oldCell.isOverline()) {
|
||||
sgrSeq.push(cell.isOverline() ? 53 : 55);
|
||||
}
|
||||
if (cell.isBlink() !== oldCell.isBlink()) {
|
||||
sgrSeq.push(cell.isBlink() ? 5 : 25);
|
||||
}
|
||||
if (cell.isInvisible() !== oldCell.isInvisible()) {
|
||||
sgrSeq.push(cell.isInvisible() ? 8 : 28);
|
||||
}
|
||||
if (cell.isItalic() !== oldCell.isItalic()) {
|
||||
sgrSeq.push(cell.isItalic() ? 3 : 23);
|
||||
}
|
||||
if (cell.isDim() !== oldCell.isDim()) {
|
||||
sgrSeq.push(cell.isDim() ? 2 : 22);
|
||||
}
|
||||
if (cell.isStrikethrough() !== oldCell.isStrikethrough()) {
|
||||
sgrSeq.push(cell.isStrikethrough() ? 9 : 29);
|
||||
}
|
||||
if (cell.isOverline() !== oldCell.isOverline()) { sgrSeq.push(cell.isOverline() ? 53 : 55); }
|
||||
if (cell.isBlink() !== oldCell.isBlink()) { sgrSeq.push(cell.isBlink() ? 5 : 25); }
|
||||
if (cell.isInvisible() !== oldCell.isInvisible()) { sgrSeq.push(cell.isInvisible() ? 8 : 28); }
|
||||
if (cell.isItalic() !== oldCell.isItalic()) { sgrSeq.push(cell.isItalic() ? 3 : 23); }
|
||||
if (cell.isDim() !== oldCell.isDim()) { sgrSeq.push(cell.isDim() ? 2 : 22); }
|
||||
if (cell.isStrikethrough() !== oldCell.isStrikethrough()) { sgrSeq.push(cell.isStrikethrough() ? 9 : 29); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -674,7 +646,8 @@ export class HTMLSerializeHandler extends BaseSerializeHandler {
|
||||
// For xterm headless: fallback to ansi colors
|
||||
if ((_terminal as any)._core._themeService) {
|
||||
this._ansiColors = (_terminal as any)._core._themeService.colors.ansi;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this._ansiColors = DEFAULT_ANSI_COLORS;
|
||||
}
|
||||
}
|
||||
@@ -779,12 +752,8 @@ export class HTMLSerializeHandler extends BaseSerializeHandler {
|
||||
content.push('background-color: ' + bgHexColor + ';');
|
||||
}
|
||||
|
||||
if (cell.isInverse()) {
|
||||
content.push('color: #000000; background-color: #BFBFBF;');
|
||||
}
|
||||
if (cell.isBold()) {
|
||||
content.push('font-weight: bold;');
|
||||
}
|
||||
if (cell.isInverse()) { content.push('color: #000000; background-color: #BFBFBF;'); }
|
||||
if (cell.isBold()) { content.push('font-weight: bold;'); }
|
||||
|
||||
// Handle text-decoration (underline, overline, strikethrough, blink)
|
||||
const decorations: string[] = [];
|
||||
@@ -812,15 +781,9 @@ export class HTMLSerializeHandler extends BaseSerializeHandler {
|
||||
}
|
||||
}
|
||||
|
||||
if (cell.isInvisible()) {
|
||||
content.push('visibility: hidden;');
|
||||
}
|
||||
if (cell.isItalic()) {
|
||||
content.push('font-style: italic;');
|
||||
}
|
||||
if (cell.isDim()) {
|
||||
content.push('opacity: 0.5;');
|
||||
}
|
||||
if (cell.isInvisible()) { content.push('visibility: hidden;'); }
|
||||
if (cell.isItalic()) { content.push('font-style: italic;'); }
|
||||
if (cell.isDim()) { content.push('opacity: 0.5;'); }
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
@@ -10,17 +10,6 @@
|
||||
"outDir": "../out",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-serialize": [
|
||||
"../typings/addon-serialize.d.ts"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"types": [
|
||||
@@ -29,7 +18,8 @@
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-serialize.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,20 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,8 +2,14 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" },
|
||||
{ "path": "./benchmark" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
},
|
||||
{
|
||||
"path": "./benchmark"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
import { perfContext, before, ThroughputRuntimeCase } from 'xterm-benchmark';
|
||||
|
||||
import { spawn } from 'node-pty';
|
||||
import { Utf8ToUtf32, stringFromCodePoint } from 'common/input/TextDecoder';
|
||||
import { CoreBrowserTerminal } from 'browser/CoreBrowserTerminal';
|
||||
import { UnicodeGraphemeProvider } from 'UnicodeGraphemeProvider';
|
||||
import { Utf8ToUtf32, stringFromCodePoint } from '../../../src/common/input/TextDecoder';
|
||||
import { CoreBrowserTerminal } from '../../../src/browser/CoreBrowserTerminal';
|
||||
import { UnicodeGraphemeProvider } from '../src/UnicodeGraphemeProvider';
|
||||
|
||||
|
||||
function fakedAddonLoad(terminal: any): void {
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["dom", "es6"],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es6"
|
||||
],
|
||||
"rootDir": "..",
|
||||
"outDir": "../out-benchmark",
|
||||
"types": ["../../../node_modules/@types/node"],
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
],
|
||||
"moduleResolution": "node",
|
||||
"strict": false,
|
||||
"target": "es2015",
|
||||
"module": "commonjs",
|
||||
"paths": {
|
||||
"common/*": ["../../../src/common/*"],
|
||||
"browser/*": ["../../../src/browser/*"],
|
||||
"UnicodeGraphemeProvider": ["../src/UnicodeGraphemeProvider"],
|
||||
"@xterm/addon-unicode-graphemes": [
|
||||
"../typings/addon-unicode-graphemes.d.ts"
|
||||
]
|
||||
}
|
||||
"module": "commonjs"
|
||||
},
|
||||
"include": ["../**/*", "../../../typings/xterm.d.ts"],
|
||||
"exclude": ["../../../**/*test.ts", "../../**/*api.ts"],
|
||||
"include": [
|
||||
"../**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"../../../**/*test.ts",
|
||||
"../../**/*api.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../../../src/common" },
|
||||
{ "path": "../../../src/browser" }
|
||||
{
|
||||
"path": "../../../src/common"
|
||||
},
|
||||
{
|
||||
"path": "../../../src/browser"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import { IUnicodeVersionProvider } from '@xterm/xterm';
|
||||
import { UnicodeCharProperties, UnicodeCharWidth } from 'common/services/Services';
|
||||
import { UnicodeService } from 'common/services/UnicodeService';
|
||||
import { UnicodeCharProperties, UnicodeCharWidth } from '../../../src/common/services/Services';
|
||||
import { UnicodeService } from '../../../src/common/services/UnicodeService';
|
||||
import * as UC from './third-party/UnicodeProperties';
|
||||
|
||||
export class UnicodeGraphemeProvider implements IUnicodeVersionProvider {
|
||||
|
||||
@@ -11,21 +11,14 @@
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"strict": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"@xterm/addon-unicode-graphemes": [
|
||||
"../typings/addon-unicode-graphemes.d.ts"
|
||||
]
|
||||
},
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-unicode-graphemes.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,20 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,8 +2,14 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" },
|
||||
{ "path": "./benchmark" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
},
|
||||
{
|
||||
"path": "./benchmark"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import { IUnicodeVersionProvider } from '@xterm/xterm';
|
||||
import { UnicodeCharProperties, UnicodeCharWidth } from 'common/services/Services';
|
||||
import { UnicodeService } from 'common/services/UnicodeService';
|
||||
import { UnicodeCharProperties, UnicodeCharWidth } from '../../../src/common/services/Services';
|
||||
import { UnicodeService } from '../../../src/common/services/UnicodeService';
|
||||
|
||||
const BMP_COMBINING = [
|
||||
[0x0300, 0x036F], [0x0483, 0x0489], [0x0591, 0x05BD],
|
||||
|
||||
@@ -11,24 +11,14 @@
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"strict": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"@xterm/addon-unicode11": [
|
||||
"../typings/addon-unicode11.d.ts"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-unicode11.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -14,15 +14,11 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"@xterm/addon-web-fonts": [
|
||||
"../typings/addon-web-fonts.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-web-fonts.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,24 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "es2021",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
// "downlevelIteration": true,
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,15 +13,11 @@
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/mocha"
|
||||
],
|
||||
"paths": {
|
||||
"@xterm/addon-web-links": [
|
||||
"../typings/addon-web-links.d.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-web-links.d.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,24 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "es2021",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
// "downlevelIteration": true,
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
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/buffer/Constants';
|
||||
import { IDecorationService, IOptionsService } from 'common/services/Services';
|
||||
import { ICellData } from 'common/Types';
|
||||
import { ISelectionRenderModel } from '../../../src/browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from '../../../src/browser/services/Services';
|
||||
import { ReadonlyColorSet } from '../../../src/browser/Types';
|
||||
import { Attributes, BgFlags, ExtFlags, FgFlags, NULL_CELL_CODE, UnderlineStyle } from '../../../src/common/buffer/Constants';
|
||||
import { IDecorationService, IOptionsService } from '../../../src/common/services/Services';
|
||||
import { ICellData } from '../../../src/common/Types';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { rgba } from 'common/Color';
|
||||
import { treatGlyphAsBackgroundColor } from 'browser/renderer/shared/RendererUtils';
|
||||
import { rgba } from '../../../src/common/Color';
|
||||
import { treatGlyphAsBackgroundColor } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
import { blockPatternCodepoints } from './customGlyphs/CustomGlyphDefinitions';
|
||||
|
||||
// Work variables to avoid garbage collection
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
import { TextureAtlas } from './TextureAtlas';
|
||||
import { ITerminalOptions, Terminal } from '@xterm/xterm';
|
||||
import { ITerminal, ReadonlyColorSet } from 'browser/Types';
|
||||
import { ITerminal, ReadonlyColorSet } from '../../../src/browser/Types';
|
||||
import { ICharAtlasConfig, ITextureAtlas } from './Types';
|
||||
import { generateConfig, configEquals } from './CharAtlasUtils';
|
||||
import type { ILogService } from 'common/services/Services';
|
||||
import type { ILogService } from '../../../src/common/services/Services';
|
||||
|
||||
interface ITextureAtlasCacheEntry {
|
||||
atlas: ITextureAtlas;
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { configEquals } from './CharAtlasUtils';
|
||||
import { ICharAtlasConfig } from './Types';
|
||||
import { NULL_COLOR } from '../../../src/common/Color';
|
||||
import { IColor } from '../../../src/common/Types';
|
||||
|
||||
function createTestConfig(overrides: Partial<ICharAtlasConfig> = {}): ICharAtlasConfig {
|
||||
const color: IColor = { css: '#ffffff', rgba: 0xffffffff };
|
||||
const contrastCache = {
|
||||
clear: () => {},
|
||||
setCss: () => {},
|
||||
getCss: () => undefined,
|
||||
setColor: () => {},
|
||||
getColor: () => undefined
|
||||
};
|
||||
const colors = {
|
||||
foreground: color,
|
||||
background: color,
|
||||
cursor: NULL_COLOR,
|
||||
cursorAccent: NULL_COLOR,
|
||||
selectionForeground: undefined,
|
||||
selectionBackgroundTransparent: NULL_COLOR,
|
||||
selectionBackgroundOpaque: NULL_COLOR,
|
||||
selectionInactiveBackgroundTransparent: NULL_COLOR,
|
||||
selectionInactiveBackgroundOpaque: NULL_COLOR,
|
||||
overviewRulerBorder: NULL_COLOR,
|
||||
scrollbarSliderBackground: NULL_COLOR,
|
||||
scrollbarSliderHoverBackground: NULL_COLOR,
|
||||
scrollbarSliderActiveBackground: NULL_COLOR,
|
||||
ansi: new Array(256).fill(color),
|
||||
contrastCache,
|
||||
halfContrastCache: contrastCache
|
||||
};
|
||||
return {
|
||||
customGlyphs: true,
|
||||
devicePixelRatio: 1,
|
||||
deviceMaxTextureSize: 4096,
|
||||
letterSpacing: 0,
|
||||
lineHeight: 1,
|
||||
fontSize: 15,
|
||||
fontFamily: 'monospace',
|
||||
fontWeight: 'normal',
|
||||
fontWeightBold: 'bold',
|
||||
deviceCellWidth: 10,
|
||||
deviceCellHeight: 20,
|
||||
deviceCharWidth: 8,
|
||||
deviceCharHeight: 16,
|
||||
allowTransparency: false,
|
||||
drawBoldTextInBrightColors: true,
|
||||
minimumContrastRatio: 1,
|
||||
colors,
|
||||
...overrides
|
||||
};
|
||||
}
|
||||
|
||||
describe('CharAtlasUtils', () => {
|
||||
describe('configEquals', () => {
|
||||
it('should return true for identical configs', () => {
|
||||
const a = createTestConfig();
|
||||
const b = createTestConfig();
|
||||
assert.ok(configEquals(a, b));
|
||||
});
|
||||
|
||||
it('should return false when deviceMaxTextureSize differs', () => {
|
||||
const a = createTestConfig();
|
||||
const b = createTestConfig({ deviceMaxTextureSize: 8192 });
|
||||
assert.ok(!configEquals(a, b));
|
||||
});
|
||||
|
||||
it('should return false when deviceCellWidth differs', () => {
|
||||
const a = createTestConfig();
|
||||
const b = createTestConfig({ deviceCellWidth: 11 });
|
||||
assert.ok(!configEquals(a, b));
|
||||
});
|
||||
|
||||
it('should return false when deviceCellHeight differs', () => {
|
||||
const a = createTestConfig();
|
||||
const b = createTestConfig({ deviceCellHeight: 21 });
|
||||
assert.ok(!configEquals(a, b));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,10 +4,10 @@
|
||||
*/
|
||||
|
||||
import { ICharAtlasConfig } from './Types';
|
||||
import { Attributes } from 'common/buffer/Constants';
|
||||
import { Attributes } from '../../../src/common/buffer/Constants';
|
||||
import { ITerminalOptions } from '@xterm/xterm';
|
||||
import { IColorSet, ReadonlyColorSet } from 'browser/Types';
|
||||
import { NULL_COLOR } from 'common/Color';
|
||||
import { IColorSet, ReadonlyColorSet } from '../../../src/browser/Types';
|
||||
import { NULL_COLOR } from '../../../src/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
|
||||
@@ -59,6 +59,7 @@ export function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean
|
||||
}
|
||||
}
|
||||
return a.devicePixelRatio === b.devicePixelRatio &&
|
||||
a.deviceMaxTextureSize === b.deviceMaxTextureSize &&
|
||||
a.customGlyphs === b.customGlyphs &&
|
||||
a.lineHeight === b.lineHeight &&
|
||||
a.letterSpacing === b.letterSpacing &&
|
||||
@@ -67,6 +68,8 @@ export function configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean
|
||||
a.fontWeight === b.fontWeight &&
|
||||
a.fontWeightBold === b.fontWeightBold &&
|
||||
a.allowTransparency === b.allowTransparency &&
|
||||
a.deviceCellWidth === b.deviceCellWidth &&
|
||||
a.deviceCellHeight === b.deviceCellHeight &&
|
||||
a.deviceCharWidth === b.deviceCharWidth &&
|
||||
a.deviceCharHeight === b.deviceCharHeight &&
|
||||
a.drawBoldTextInBrightColors === b.drawBoldTextInBrightColors &&
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { isFirefox, isLegacyEdge } from 'common/Platform';
|
||||
import { isFirefox, isLegacyEdge } from '../../../src/common/Platform';
|
||||
|
||||
export const DIM_OPACITY = 0.5;
|
||||
// The text baseline is set conditionally by browser. Using 'ideographic' for Firefox or Legacy Edge
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { RendererConstants } from 'browser/renderer/shared/Constants';
|
||||
import { ICoreBrowserService } from 'browser/services/Services';
|
||||
import { RendererConstants } from '../../../src/browser/renderer/shared/Constants';
|
||||
import { ICoreBrowserService } from '../../../src/browser/services/Services';
|
||||
|
||||
const enum Constants {
|
||||
/**
|
||||
@@ -40,9 +40,7 @@ export class CursorBlinkStateManager {
|
||||
}
|
||||
}
|
||||
|
||||
public get isPaused(): boolean {
|
||||
return !(this._blinkStartTimeout || this._blinkInterval);
|
||||
}
|
||||
public get isPaused(): boolean { return !(this._blinkStartTimeout || this._blinkInterval); }
|
||||
|
||||
public dispose(): void {
|
||||
if (this._blinkInterval) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { toDisposable, IDisposable } from 'common/Lifecycle';
|
||||
import { toDisposable, IDisposable } from '../../../src/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,14 +3,14 @@
|
||||
* @license MIT
|
||||
*/
|
||||
import { TextureAtlas } from './TextureAtlas';
|
||||
import { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import { NULL_CELL_CODE } from 'common/buffer/Constants';
|
||||
import { Disposable, toDisposable } from 'common/Lifecycle';
|
||||
import { IRenderDimensions } from '../../../src/browser/renderer/shared/Types';
|
||||
import { NULL_CELL_CODE } from '../../../src/common/buffer/Constants';
|
||||
import { Disposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject, type IRasterizedGlyph, type ITextureAtlas } from './Types';
|
||||
import { createProgram, GLTexture, PROJECTION_MATRIX } from './WebglUtils';
|
||||
import type { IOptionsService } from 'common/services/Services';
|
||||
import { allowRescaling, throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import type { ILogService, IOptionsService } from '../../../src/common/services/Services';
|
||||
import { allowRescaling, throwIfFalsy } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
|
||||
interface IVertices {
|
||||
attributes: Float32Array;
|
||||
@@ -114,7 +114,8 @@ export class GlyphRenderer extends Disposable {
|
||||
private readonly _terminal: Terminal,
|
||||
private readonly _gl: IWebGL2RenderingContext,
|
||||
private _dimensions: IRenderDimensions,
|
||||
private readonly _optionsService: IOptionsService
|
||||
private readonly _optionsService: IOptionsService,
|
||||
private readonly _logService: ILogService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -127,7 +128,7 @@ export class GlyphRenderer extends Disposable {
|
||||
TextureAtlas.maxTextureSize = throwIfFalsy(gl.getParameter(gl.MAX_TEXTURE_SIZE) as number | null);
|
||||
}
|
||||
|
||||
this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, createFragmentShaderSource(TextureAtlas.maxAtlasPages)));
|
||||
this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, createFragmentShaderSource(TextureAtlas.maxAtlasPages), this._logService));
|
||||
this._register(toDisposable(() => gl.deleteProgram(this._program)));
|
||||
|
||||
// Uniform locations
|
||||
@@ -136,8 +137,9 @@ export class GlyphRenderer extends Disposable {
|
||||
this._textureLocation = throwIfFalsy(gl.getUniformLocation(this._program, 'u_texture'));
|
||||
|
||||
// Create and set the vertex array object
|
||||
this._vertexArrayObject = gl.createVertexArray();
|
||||
gl.bindVertexArray(this._vertexArrayObject);
|
||||
const vertexArrayObject = this._vertexArrayObject = gl.createVertexArray();
|
||||
this._register(toDisposable(() => gl.deleteVertexArray(vertexArrayObject)));
|
||||
gl.bindVertexArray(vertexArrayObject);
|
||||
|
||||
// Setup a_unitquad, this defines the 4 vertices of a rectangle
|
||||
const unitQuadVertices = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import { IThemeService } from 'browser/services/Services';
|
||||
import { ReadonlyColorSet } from 'browser/Types';
|
||||
import { Attributes, FgFlags } from 'common/buffer/Constants';
|
||||
import { Disposable, toDisposable } from 'common/Lifecycle';
|
||||
import { IColor } from 'common/Types';
|
||||
import { IRenderDimensions } from '../../../src/browser/renderer/shared/Types';
|
||||
import { IThemeService } from '../../../src/browser/services/Services';
|
||||
import { ReadonlyColorSet } from '../../../src/browser/Types';
|
||||
import { Attributes, FgFlags } from '../../../src/common/buffer/Constants';
|
||||
import { Disposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { IColor } from '../../../src/common/Types';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { RenderModelConstants } from './RenderModel';
|
||||
import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject } from './Types';
|
||||
import { createProgram, expandFloat32Array, PROJECTION_MATRIX } from './WebglUtils';
|
||||
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { throwIfFalsy } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
import type { ILogService } from '../../../src/common/services/Services';
|
||||
|
||||
const enum VertexAttribLocations {
|
||||
POSITION = 0,
|
||||
@@ -89,21 +90,23 @@ export class RectangleRenderer extends Disposable {
|
||||
private _terminal: Terminal,
|
||||
private _gl: IWebGL2RenderingContext,
|
||||
private _dimensions: IRenderDimensions,
|
||||
private readonly _themeService: IThemeService
|
||||
private readonly _themeService: IThemeService,
|
||||
private readonly _logService: ILogService
|
||||
) {
|
||||
super();
|
||||
|
||||
const gl = this._gl;
|
||||
|
||||
this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, fragmentShaderSource));
|
||||
this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, fragmentShaderSource, this._logService));
|
||||
this._register(toDisposable(() => gl.deleteProgram(this._program)));
|
||||
|
||||
// Uniform locations
|
||||
this._projectionLocation = throwIfFalsy(gl.getUniformLocation(this._program, 'u_projection'));
|
||||
|
||||
// Create and set the vertex array object
|
||||
this._vertexArrayObject = gl.createVertexArray();
|
||||
gl.bindVertexArray(this._vertexArrayObject);
|
||||
const vertexArrayObject = this._vertexArrayObject = gl.createVertexArray();
|
||||
this._register(toDisposable(() => gl.deleteVertexArray(vertexArrayObject)));
|
||||
gl.bindVertexArray(vertexArrayObject);
|
||||
|
||||
// Setup a_unitquad, this defines the 4 vertices of a rectangle
|
||||
const unitQuadVertices = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
*/
|
||||
|
||||
import { ICursorRenderModel, IRenderModel } from './Types';
|
||||
import { ISelectionRenderModel } from 'browser/renderer/shared/Types';
|
||||
import { createSelectionRenderModel } from 'browser/renderer/shared/SelectionRenderModel';
|
||||
import { ISelectionRenderModel } from '../../../src/browser/renderer/shared/Types';
|
||||
import { createSelectionRenderModel } from '../../../src/browser/renderer/shared/SelectionRenderModel';
|
||||
|
||||
export const enum RenderModelConstants {
|
||||
INDICIES_PER_CELL = 4,
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IColorContrastCache } from 'browser/Types';
|
||||
import { IColorContrastCache } from '../../../src/browser/Types';
|
||||
import { DIM_OPACITY, TEXT_BASELINE } from './Constants';
|
||||
import { tryDrawCustomGlyph } from './customGlyphs/CustomGlyphRasterizer';
|
||||
import { computeNextVariantOffset, treatGlyphAsBackgroundColor, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { computeNextVariantOffset, treatGlyphAsBackgroundColor, isPowerlineGlyph, isRestrictedPowerlineGlyph, throwIfFalsy } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
import { IBoundingBox, ICharAtlasConfig, IRasterizedGlyph, ITextureAtlas } from './Types';
|
||||
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/Event';
|
||||
import { NULL_COLOR, channels, color, rgba } from '../../../src/common/Color';
|
||||
import { FourKeyMap } from '../../../src/common/MultiKeyMap';
|
||||
import { IdleTaskQueue } from '../../../src/common/TaskQueue';
|
||||
import { IColor } from '../../../src/common/Types';
|
||||
import { AttributeData } from '../../../src/common/buffer/AttributeData';
|
||||
import { Attributes, DEFAULT_COLOR, DEFAULT_EXT, UnderlineStyle } from '../../../src/common/buffer/Constants';
|
||||
import { ILogService, IUnicodeService } from '../../../src/common/services/Services';
|
||||
import { Emitter } from '../../../src/common/Event';
|
||||
|
||||
/**
|
||||
* A shared object which is used to draw nothing for a particular cell.
|
||||
@@ -62,9 +62,7 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
|
||||
// The texture that the atlas is drawn to
|
||||
private _pages: AtlasPage[] = [];
|
||||
public get pages(): { canvas: HTMLCanvasElement, version: number }[] {
|
||||
return this._pages;
|
||||
}
|
||||
public get pages(): { canvas: HTMLCanvasElement, version: number }[] { return this._pages; }
|
||||
|
||||
// The set of atlas pages that can be written to
|
||||
private _activePages: AtlasPage[] = [];
|
||||
@@ -111,6 +109,7 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
page.canvas.remove();
|
||||
}
|
||||
this._onAddTextureAtlasCanvas.dispose();
|
||||
this._onRemoveTextureAtlasCanvas.dispose();
|
||||
}
|
||||
|
||||
public warmUp(): void {
|
||||
@@ -531,7 +530,7 @@ export class TextureAtlas implements ITextureAtlas {
|
||||
let customGlyph = false;
|
||||
if (this._config.customGlyphs !== false) {
|
||||
const variantOffset = this._workAttributeData.getUnderlineVariantOffset();
|
||||
customGlyph = tryDrawCustomGlyph(this._tmpCtx, chars, padding, padding, this._config.deviceCellWidth, this._config.deviceCellHeight, this._config.deviceCharWidth, this._config.deviceCharHeight, this._config.fontSize, this._config.devicePixelRatio, backgroundColor.css, variantOffset);
|
||||
customGlyph = tryDrawCustomGlyph(this._tmpCtx, chars, padding, padding, this._config.deviceCellWidth, this._config.deviceCellHeight, this._config.deviceCharWidth, this._config.deviceCharHeight, this._config.fontSize, this._config.devicePixelRatio, this._logService, backgroundColor.css, variantOffset);
|
||||
}
|
||||
|
||||
// Whether to clear pixels based on a threshold difference between the glyph color and the
|
||||
@@ -1041,14 +1040,10 @@ class AtlasPage {
|
||||
public readonly ctx: CanvasRenderingContext2D;
|
||||
|
||||
private _usedPixels: number = 0;
|
||||
public get percentageUsed(): number {
|
||||
return this._usedPixels / (this.canvas.width * this.canvas.height);
|
||||
}
|
||||
public get percentageUsed(): number { return this._usedPixels / (this.canvas.width * this.canvas.height); }
|
||||
|
||||
private readonly _glyphs: IRasterizedGlyph[] = [];
|
||||
public get glyphs(): ReadonlyArray<IRasterizedGlyph> {
|
||||
return this._glyphs;
|
||||
}
|
||||
public get glyphs(): ReadonlyArray<IRasterizedGlyph> { return this._glyphs; }
|
||||
public addGlyph(glyph: IRasterizedGlyph): void {
|
||||
this._glyphs.push(glyph);
|
||||
this._usedPixels += glyph.size.x * glyph.size.y;
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
*/
|
||||
|
||||
import { FontWeight } from '@xterm/xterm';
|
||||
import { IColorSet } from 'browser/Types';
|
||||
import { ISelectionRenderModel } from 'browser/renderer/shared/Types';
|
||||
import { CursorInactiveStyle, CursorStyle, type IDisposable } from 'common/Types';
|
||||
import type { IEvent } from 'common/Event';
|
||||
import { IColorSet } from '../../../src/browser/Types';
|
||||
import { ISelectionRenderModel } from '../../../src/browser/renderer/shared/Types';
|
||||
import { CursorInactiveStyle, CursorStyle, type IDisposable } from '../../../src/common/Types';
|
||||
import type { IEvent } from '../../../src/common/Event';
|
||||
|
||||
export interface IRenderModel {
|
||||
cells: Uint32Array;
|
||||
@@ -28,6 +28,7 @@ export interface ICursorRenderModel {
|
||||
export interface IWebGL2RenderingContext extends WebGLRenderingContext {
|
||||
vertexAttribDivisor(index: number, divisor: number): void;
|
||||
createVertexArray(): IWebGLVertexArrayObject;
|
||||
deleteVertexArray(vao: IWebGLVertexArrayObject): void;
|
||||
bindVertexArray(vao: IWebGLVertexArrayObject): void;
|
||||
drawElementsInstanced(mode: number, count: number, type: number, offset: number, instanceCount: number): void;
|
||||
}
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
|
||||
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/Lifecycle';
|
||||
import { getSafariVersion, isSafari } from 'common/Platform';
|
||||
import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
|
||||
import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from '../../../src/browser/services/Services';
|
||||
import { ITerminal } from '../../../src/browser/Types';
|
||||
import { Disposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { getSafariVersion, isSafari } from '../../../src/common/Platform';
|
||||
import { ICoreService, IDecorationService, ILogService, IOptionsService } from '../../../src/common/services/Services';
|
||||
import { IWebGL2RenderingContext } from './Types';
|
||||
import { WebglRenderer } from './WebglRenderer';
|
||||
import { Emitter, EventUtils } from 'common/Event';
|
||||
import { Emitter, EventUtils } from '../../../src/common/Event';
|
||||
|
||||
export class WebglAddon extends Disposable implements ITerminalAddon, IWebglApi {
|
||||
private _terminal?: Terminal;
|
||||
@@ -65,6 +65,7 @@ export class WebglAddon extends Disposable implements ITerminalAddon, IWebglApi
|
||||
const charSizeService: ICharSizeService = unsafeCore._charSizeService;
|
||||
const coreBrowserService: ICoreBrowserService = unsafeCore._coreBrowserService;
|
||||
const decorationService: IDecorationService = unsafeCore._decorationService;
|
||||
const logService: ILogService = unsafeCore._logService;
|
||||
const themeService: IThemeService = unsafeCore._themeService;
|
||||
|
||||
this._renderer = this._register(new WebglRenderer(
|
||||
@@ -74,6 +75,7 @@ export class WebglAddon extends Disposable implements ITerminalAddon, IWebglApi
|
||||
coreBrowserService,
|
||||
coreService,
|
||||
decorationService,
|
||||
logService,
|
||||
optionsService,
|
||||
themeService,
|
||||
this._customGlyphs,
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ITerminal } from 'browser/Types';
|
||||
import { ITerminal } from '../../../src/browser/Types';
|
||||
import { CellColorResolver } from './CellColorResolver';
|
||||
import { acquireTextureAtlas, removeTerminalFromCache } from './CharAtlasCache';
|
||||
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/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, IOptionsService } from 'common/services/Services';
|
||||
import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from '../../../src/browser/renderer/shared/Types';
|
||||
import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IThemeService } from '../../../src/browser/services/Services';
|
||||
import { CharData, IBufferLine, ICellData } from '../../../src/common/Types';
|
||||
import { AttributeData } from '../../../src/common/buffer/AttributeData';
|
||||
import { CellData } from '../../../src/common/buffer/CellData';
|
||||
import { Attributes, Content, FgFlags, NULL_CELL_CHAR, NULL_CELL_CODE } from '../../../src/common/buffer/Constants';
|
||||
import { TextBlinkStateManager } from '../../../src/browser/renderer/shared/TextBlinkStateManager';
|
||||
import { ICoreService, IDecorationService, ILogService, IOptionsService } from '../../../src/common/services/Services';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { GlyphRenderer } from './GlyphRenderer';
|
||||
import { RectangleRenderer } from './RectangleRenderer';
|
||||
@@ -23,10 +23,10 @@ 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/Event';
|
||||
import { addDisposableListener } from 'browser/Dom';
|
||||
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
||||
import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
|
||||
import { Emitter, EventUtils } from '../../../src/common/Event';
|
||||
import { addDisposableListener } from '../../../src/browser/Dom';
|
||||
import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from '../../../src/common/Lifecycle';
|
||||
import { createRenderDimensions } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
|
||||
const enum Constants {
|
||||
MERGE_RETRY_LIMIT = 32
|
||||
@@ -77,6 +77,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
private readonly _coreBrowserService: ICoreBrowserService,
|
||||
private readonly _coreService: ICoreService,
|
||||
private readonly _decorationService: IDecorationService,
|
||||
private readonly _logService: ILogService,
|
||||
private readonly _optionsService: IOptionsService,
|
||||
private readonly _themeService: IThemeService,
|
||||
private readonly _customGlyphs: boolean = true,
|
||||
@@ -122,19 +123,19 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
this._deviceMaxTextureSize = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE);
|
||||
|
||||
this._register(addDisposableListener(this._canvas, 'webglcontextlost', (e) => {
|
||||
console.log('webglcontextlost event received');
|
||||
this._logService.debug('webglcontextlost event received');
|
||||
// Prevent the default behavior in order to enable WebGL context restoration.
|
||||
e.preventDefault();
|
||||
// Wait a few seconds to see if the 'webglcontextrestored' event is fired.
|
||||
// If not, dispatch the onContextLoss notification to observers.
|
||||
this._contextRestorationTimeout = setTimeout(() => {
|
||||
this._contextRestorationTimeout = undefined;
|
||||
console.warn('webgl context not restored; firing onContextLoss');
|
||||
this._logService.warn('webgl context not restored; firing onContextLoss');
|
||||
this._onContextLoss.fire(e);
|
||||
}, 3000 /* ms */);
|
||||
}));
|
||||
this._register(addDisposableListener(this._canvas, 'webglcontextrestored', (e) => {
|
||||
console.warn('webglcontextrestored event received');
|
||||
this._logService.warn('webglcontextrestored event received');
|
||||
clearTimeout(this._contextRestorationTimeout);
|
||||
this._contextRestorationTimeout = undefined;
|
||||
// The texture atlas and glyph renderer must be fully reinitialized
|
||||
@@ -158,6 +159,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
this._isAttached = this._core.screenElement!.isConnected;
|
||||
|
||||
this._register(toDisposable(() => {
|
||||
clearTimeout(this._contextRestorationTimeout);
|
||||
this._contextRestorationTimeout = undefined;
|
||||
for (const l of this._renderLayers) {
|
||||
l.dispose();
|
||||
}
|
||||
@@ -274,8 +277,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
* Initializes members dependent on WebGL context state.
|
||||
*/
|
||||
private _initializeWebGLState(): [RectangleRenderer, GlyphRenderer] {
|
||||
this._rectangleRenderer.value = new RectangleRenderer(this._terminal, this._gl, this.dimensions, this._themeService);
|
||||
this._glyphRenderer.value = new GlyphRenderer(this._terminal, this._gl, this.dimensions, this._optionsService);
|
||||
this._rectangleRenderer.value = new RectangleRenderer(this._terminal, this._gl, this.dimensions, this._themeService, this._logService);
|
||||
this._glyphRenderer.value = new GlyphRenderer(this._terminal, this._gl, this.dimensions, this._optionsService, this._logService);
|
||||
|
||||
// Update dimensions and acquire char atlas
|
||||
this.handleCharSizeChanged();
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { throwIfFalsy } from '../../../src/browser/renderer/shared/RendererUtils';
|
||||
import type { ILogService } from '../../../src/common/services/Services';
|
||||
|
||||
/**
|
||||
* A matrix that when multiplies will translate 0-1 coordinates (left to right,
|
||||
@@ -16,21 +17,21 @@ export const PROJECTION_MATRIX = new Float32Array([
|
||||
-1, 1, 0, 1
|
||||
]);
|
||||
|
||||
export function createProgram(gl: WebGLRenderingContext, vertexSource: string, fragmentSource: string): WebGLProgram | undefined {
|
||||
export function createProgram(gl: WebGLRenderingContext, vertexSource: string, fragmentSource: string, logService: ILogService): WebGLProgram | undefined {
|
||||
const program = throwIfFalsy(gl.createProgram());
|
||||
gl.attachShader(program, throwIfFalsy(createShader(gl, gl.VERTEX_SHADER, vertexSource)));
|
||||
gl.attachShader(program, throwIfFalsy(createShader(gl, gl.FRAGMENT_SHADER, fragmentSource)));
|
||||
gl.attachShader(program, throwIfFalsy(createShader(gl, gl.VERTEX_SHADER, vertexSource, logService)));
|
||||
gl.attachShader(program, throwIfFalsy(createShader(gl, gl.FRAGMENT_SHADER, fragmentSource, logService)));
|
||||
gl.linkProgram(program);
|
||||
const success = gl.getProgramParameter(program, gl.LINK_STATUS);
|
||||
if (success) {
|
||||
return program;
|
||||
}
|
||||
|
||||
console.error(gl.getProgramInfoLog(program));
|
||||
logService.error(gl.getProgramInfoLog(program));
|
||||
gl.deleteProgram(program);
|
||||
}
|
||||
|
||||
export function createShader(gl: WebGLRenderingContext, type: number, source: string): WebGLShader | undefined {
|
||||
export function createShader(gl: WebGLRenderingContext, type: number, source: string, logService: ILogService): WebGLShader | undefined {
|
||||
const shader = throwIfFalsy(gl.createShader(type));
|
||||
gl.shaderSource(shader, source);
|
||||
gl.compileShader(shader);
|
||||
@@ -39,7 +40,7 @@ export function createShader(gl: WebGLRenderingContext, type: number, source: st
|
||||
return shader;
|
||||
}
|
||||
|
||||
console.error(gl.getShaderInfoLog(shader));
|
||||
logService.error(gl.getShaderInfoLog(shader));
|
||||
gl.deleteShader(shader);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { throwIfFalsy } from '../../../../src/browser/renderer/shared/RendererUtils';
|
||||
import type { ILogService } from '../../../../src/common/services/Services';
|
||||
import { customGlyphDefinitions } from './CustomGlyphDefinitions';
|
||||
import { CustomGlyphDefinitionType, CustomGlyphScaleType, CustomGlyphVectorType, type CustomGlyphDefinitionPart, type CustomGlyphPathDrawFunctionDefinition, type CustomGlyphPatternDefinition, type ICustomGlyphSolidOctantBlockVector, type ICustomGlyphVectorShape } from './Types';
|
||||
|
||||
@@ -22,6 +23,7 @@ export function tryDrawCustomGlyph(
|
||||
deviceCharHeight: number,
|
||||
fontSize: number,
|
||||
devicePixelRatio: number,
|
||||
logService: ILogService,
|
||||
backgroundColor?: string,
|
||||
variantOffset: number = 0
|
||||
): boolean {
|
||||
@@ -30,7 +32,7 @@ export function tryDrawCustomGlyph(
|
||||
// Normalize to array for uniform handling
|
||||
const parts = Array.isArray(unifiedCharDefinition) ? unifiedCharDefinition : [unifiedCharDefinition];
|
||||
for (const part of parts) {
|
||||
drawDefinitionPart(ctx, part, xOffset, yOffset, deviceCellWidth, deviceCellHeight, deviceCharWidth, deviceCharHeight, fontSize, devicePixelRatio, backgroundColor, variantOffset);
|
||||
drawDefinitionPart(ctx, part, xOffset, yOffset, deviceCellWidth, deviceCellHeight, deviceCharWidth, deviceCharHeight, fontSize, devicePixelRatio, logService, backgroundColor, variantOffset);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -49,6 +51,7 @@ function drawDefinitionPart(
|
||||
deviceCharHeight: number,
|
||||
fontSize: number,
|
||||
devicePixelRatio: number,
|
||||
logService: ILogService,
|
||||
backgroundColor?: string,
|
||||
variantOffset: number = 0
|
||||
): void {
|
||||
@@ -79,7 +82,7 @@ function drawDefinitionPart(
|
||||
drawPatternChar(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, variantOffset);
|
||||
break;
|
||||
case CustomGlyphDefinitionType.PATH_FUNCTION:
|
||||
drawPathFunctionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, part.strokeWidth);
|
||||
drawPathFunctionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, logService, part.strokeWidth);
|
||||
break;
|
||||
case CustomGlyphDefinitionType.PATH:
|
||||
drawPathDefinitionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, part.strokeWidth);
|
||||
@@ -88,7 +91,7 @@ function drawDefinitionPart(
|
||||
drawPathNegativeDefinitionCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, devicePixelRatio, backgroundColor);
|
||||
break;
|
||||
case CustomGlyphDefinitionType.VECTOR_SHAPE:
|
||||
drawVectorShape(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, fontSize, devicePixelRatio);
|
||||
drawVectorShape(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight, fontSize, devicePixelRatio, logService);
|
||||
break;
|
||||
case CustomGlyphDefinitionType.BRAILLE:
|
||||
drawBrailleCharacter(ctx, part.data, drawXOffset, drawYOffset, drawWidth, drawHeight);
|
||||
@@ -510,6 +513,7 @@ function drawPathFunctionCharacter(
|
||||
deviceCellWidth: number,
|
||||
deviceCellHeight: number,
|
||||
devicePixelRatio: number,
|
||||
logService: ILogService,
|
||||
strokeWidth?: number
|
||||
): void {
|
||||
ctx.save();
|
||||
@@ -536,7 +540,7 @@ function drawPathFunctionCharacter(
|
||||
}
|
||||
const f = svgToCanvasInstructionMap[type];
|
||||
if (!f) {
|
||||
console.error(`Could not find drawing instructions for "${type}"`);
|
||||
logService.error(`Could not find drawing instructions for "${type}"`);
|
||||
continue;
|
||||
}
|
||||
const args: string[] = instruction.substring(1).split(',');
|
||||
@@ -598,7 +602,8 @@ function drawVectorShape(
|
||||
deviceCellWidth: number,
|
||||
deviceCellHeight: number,
|
||||
fontSize: number,
|
||||
devicePixelRatio: number
|
||||
devicePixelRatio: number,
|
||||
logService: ILogService
|
||||
): void {
|
||||
// Clip the cell to make sure drawing doesn't occur beyond bounds
|
||||
const clipRegion = new Path2D();
|
||||
@@ -619,7 +624,7 @@ function drawVectorShape(
|
||||
}
|
||||
const f = svgToCanvasInstructionMap[type];
|
||||
if (!f) {
|
||||
console.error(`Could not find drawing instructions for "${type}"`);
|
||||
logService.error(`Could not find drawing instructions for "${type}"`);
|
||||
continue;
|
||||
}
|
||||
const args: string[] = instruction.substring(1).split(',');
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ReadonlyColorSet } from 'browser/Types';
|
||||
import { ReadonlyColorSet } from '../../../../src/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/Lifecycle';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { IOptionsService } from 'common/services/Services';
|
||||
import { IRenderDimensions } from '../../../../src/browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from '../../../../src/browser/services/Services';
|
||||
import { Disposable, toDisposable } from '../../../../src/common/Lifecycle';
|
||||
import { CellData } from '../../../../src/common/buffer/CellData';
|
||||
import { IOptionsService } from '../../../../src/common/services/Services';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { IRenderLayer } from './Types';
|
||||
import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
|
||||
import { throwIfFalsy } from '../../../../src/browser/renderer/shared/RendererUtils';
|
||||
import { TEXT_BASELINE } from '../Constants';
|
||||
import type { ITextureAtlas } from '../Types';
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
*/
|
||||
|
||||
import { is256Color } from '../CharAtlasUtils';
|
||||
import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants';
|
||||
import { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
|
||||
import { ILinkifier2, ILinkifierEvent } from 'browser/Types';
|
||||
import { IOptionsService } from 'common/services/Services';
|
||||
import { INVERTED_DEFAULT_COLOR } from '../../../../src/browser/renderer/shared/Constants';
|
||||
import { IRenderDimensions } from '../../../../src/browser/renderer/shared/Types';
|
||||
import { ICoreBrowserService, IThemeService } from '../../../../src/browser/services/Services';
|
||||
import { ILinkifier2, ILinkifierEvent } from '../../../../src/browser/Types';
|
||||
import { IOptionsService } from '../../../../src/common/services/Services';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { BaseRenderLayer } from './BaseRenderLayer';
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { IDisposable, Terminal } from '@xterm/xterm';
|
||||
import { IRenderDimensions } from 'browser/renderer/shared/Types';
|
||||
import { IRenderDimensions } from '../../../../src/browser/renderer/shared/Types';
|
||||
|
||||
export interface IRenderLayer extends IDisposable {
|
||||
/**
|
||||
|
||||
@@ -10,20 +10,6 @@
|
||||
"outDir": "../out",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"@xterm/addon-webgl": [
|
||||
"../typings/addon-webgl.d.ts"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"downlevelIteration": true,
|
||||
"experimentalDecorators": true,
|
||||
@@ -33,7 +19,8 @@
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../../typings/xterm.d.ts"
|
||||
"../../../typings/xterm.d.ts",
|
||||
"../typings/addon-webgl.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
||||
@@ -3,23 +3,12 @@
|
||||
"module": "commonjs",
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"es2021",
|
||||
"es2021"
|
||||
],
|
||||
"rootDir": ".",
|
||||
"outDir": "../out-test",
|
||||
"sourceMap": true,
|
||||
"removeComments": true,
|
||||
"paths": {
|
||||
"common/*": [
|
||||
"../../../src/common/*"
|
||||
],
|
||||
"browser/*": [
|
||||
"../../../src/browser/*"
|
||||
],
|
||||
"*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"strict": true,
|
||||
"types": [
|
||||
"../../../node_modules/@types/node",
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{ "path": "./src" },
|
||||
{ "path": "./test" }
|
||||
{
|
||||
"path": "./src"
|
||||
},
|
||||
{
|
||||
"path": "./test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+10
-3
@@ -107,13 +107,20 @@ if (config.addon) {
|
||||
};
|
||||
outConfig = {
|
||||
...outConfig,
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
packages: 'external',
|
||||
entryPoints: [`addons/addon-${config.addon}/src/**/*.ts`],
|
||||
outdir: `addons/addon-${config.addon}/out-esbuild/`
|
||||
outdir: `addons/addon-${config.addon}/out-esbuild/`,
|
||||
// Public API stays external; src/common|browser are bundled from source.
|
||||
external: ['@xterm/xterm', '@xterm/headless', '@xterm/addon-*'],
|
||||
};
|
||||
// Playwright suites only (not run by unit tests); keep unbundled.
|
||||
outTestConfig = {
|
||||
...outConfig,
|
||||
format: 'cjs',
|
||||
sourcemap: true,
|
||||
entryPoints: [`addons/addon-${config.addon}/test/**/*.ts`],
|
||||
outdir: `addons/addon-${config.addon}/out-esbuild-test/`
|
||||
outdir: `addons/addon-${config.addon}/out-esbuild-test/`,
|
||||
};
|
||||
|
||||
if (config.addon === 'ligatures') {
|
||||
|
||||
+15
-4
@@ -7,19 +7,30 @@ import { argv } from "process";
|
||||
/** @type {{cp: import("child_process").ChildProcessByStdio<any, any, any>, name: string}[]} */
|
||||
const jobs = [];
|
||||
|
||||
// Core job
|
||||
jobs.push(createJob('xterm', []));
|
||||
// Core job must finish before addons (addon tests resolve src/* via out-esbuild).
|
||||
const xtermJob = createJob('xterm', []);
|
||||
const xtermCode = await new Promise(r => {
|
||||
xtermJob.cp.on('exit', code => {
|
||||
log(`Finished \x1b[32m${xtermJob.name}\x1b[0m${code ? ' \x1b[31mwith errors\x1b[0m' : ''}`);
|
||||
r(code ?? 1);
|
||||
});
|
||||
});
|
||||
if (xtermCode !== 0) {
|
||||
process.exit(xtermCode);
|
||||
}
|
||||
|
||||
// Addon jobs
|
||||
const addons = (await readdir('addons')).filter(e => e.startsWith('addon-')).map(e => e.replace('addon-', ''));
|
||||
/** @type {{cp: import("child_process").ChildProcessByStdio<any, any, any>, name: string}[]} */
|
||||
const addonJobs = [];
|
||||
for (const addon of addons) {
|
||||
jobs.push(createJob(`xterm-addon-${addon}`, [`--addon=${addon}`]));
|
||||
addonJobs.push(createJob(`xterm-addon-${addon}`, [`--addon=${addon}`]));
|
||||
}
|
||||
|
||||
// Demo job - This requires the others to be built so it's not included when building all
|
||||
// jobs.push(createJob('demo-client', [`--demo-client`]));
|
||||
|
||||
await Promise.all(jobs.map((job, i) => {
|
||||
await Promise.all(addonJobs.map(job => {
|
||||
return new Promise(r => {
|
||||
job.cp.on('exit', code => {
|
||||
log(`Finished \x1b[32m${job.name}\x1b[0m${code ? ' \x1b[31mwith errors\x1b[0m' : ''}`);
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ const path = require('path');
|
||||
|
||||
const COVERAGE_LINES_THRESHOLD = 40;
|
||||
|
||||
// Add `out` to the NODE_PATH so absolute paths can be resolved.
|
||||
// Add `out-esbuild` to NODE_PATH for any remaining non-relative requires in test bundles.
|
||||
const env = { ...process.env };
|
||||
env.NODE_PATH = path.resolve(__dirname, '../out-esbuild');
|
||||
|
||||
|
||||
@@ -521,7 +521,8 @@ function initAddons(term: Terminal): void {
|
||||
} else if (name === 'webLinks') {
|
||||
controlBar.setTabVisible('addon-web-links', true);
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
catch {
|
||||
addon.instance = undefined;
|
||||
checkbox.checked = false;
|
||||
checkbox.disabled = true;
|
||||
|
||||
@@ -30,9 +30,7 @@ export class AddonWebFontsWindow extends BaseWindow implements IControlWindow {
|
||||
this._terminal.options.lineHeight = 1.3;
|
||||
this._addons.fit.instance?.fit();
|
||||
setTimeout(() => this._terminal.write('\x1b[?12h\x1b]12;#776CF9\x07\x1b[38;2;119;108;249;48;2;21;8;150m\x1b[2J\x1b[2;5H**** COMMODORE 64 BASIC V2 ****\r\n\r\n 64K RAM SYSTEM 38911 BASIC BYTES FREE\r\n\r\nREADY.\r\nLOAD '), 1000);
|
||||
setTimeout(() => {
|
||||
this._terminal.write('🤣\x1b[m\x1b[99;1H'); this._terminal.input('\r');
|
||||
}, 5000);
|
||||
setTimeout(() => { this._terminal.write('🤣\x1b[m\x1b[99;1H'); this._terminal.input('\r'); }, 5000);
|
||||
});
|
||||
ddKongtext.appendChild(btnKongtext);
|
||||
dl.appendChild(ddKongtext);
|
||||
|
||||
@@ -8,9 +8,7 @@ import type { IControlWindow } from '../controlBar';
|
||||
import type { Terminal } from '@xterm/xterm';
|
||||
|
||||
export abstract class BaseWindow implements IControlWindow {
|
||||
protected get _terminal(): Terminal {
|
||||
return this._terminalPrivate;
|
||||
}
|
||||
protected get _terminal(): Terminal { return this._terminalPrivate; }
|
||||
|
||||
constructor(
|
||||
private _terminalPrivate: Terminal,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { BaseWindow } from './baseWindow';
|
||||
import type { Terminal, ITheme } from '@xterm/xterm';
|
||||
import type { IControlWindow } from '../controlBar';
|
||||
import type { AddonCollection } from 'types';
|
||||
import type { AddonCollection } from '../../types';
|
||||
|
||||
const xtermjsTheme: ITheme = Object.freeze({
|
||||
foreground: '#F8F8F8',
|
||||
|
||||
@@ -7,7 +7,7 @@ import { writeUnicodeTable } from '../../unicodeTable';
|
||||
import type { IControlWindow } from '../controlBar';
|
||||
import { BaseWindow } from './baseWindow';
|
||||
import type { IDisposable, Terminal } from '@xterm/xterm';
|
||||
import type { AddonCollection } from 'types';
|
||||
import type { AddonCollection } from '../../types';
|
||||
|
||||
export class TestWindow extends BaseWindow implements IControlWindow {
|
||||
public readonly id = 'test';
|
||||
|
||||
@@ -6,23 +6,7 @@
|
||||
"rootDir": ".",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"@xterm/addon-attach": ["../../addons/addon-attach"],
|
||||
"@xterm/addon-clipboard": ["../../addons/addon-clipboard"],
|
||||
"@xterm/addon-fit": ["../../addons/addon-fit"],
|
||||
"@xterm/addon-image": ["../../addons/addon-image"],
|
||||
"@xterm/addon-progress": ["../../addons/addon-progress"],
|
||||
"@xterm/addon-search": ["../../addons/addon-search"],
|
||||
"@xterm/addon-serialize": ["../../addons/addon-serialize"],
|
||||
"@xterm/addon-web-fonts": ["../../addons/addon-web-fonts"],
|
||||
"@xterm/addon-web-links": ["../../addons/addon-web-links"],
|
||||
"@xterm/addon-webgl": ["../../addons/addon-webgl"],
|
||||
"@xterm/addon-unicode11": ["../../addons/addon-unicode11"],
|
||||
"@xterm/addon-unicode-graphemes": ["../../addons/addon-unicode-graphemes"],
|
||||
"@xterm/addon-ligatures": ["../../addons/addon-ligatures"],
|
||||
"*": ["./*"]
|
||||
}
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"./**/*"
|
||||
]
|
||||
}
|
||||
|
||||
+6
-2
@@ -1,7 +1,11 @@
|
||||
{
|
||||
"references": [
|
||||
{ "path": "./client" },
|
||||
{ "path": "./server" }
|
||||
{
|
||||
"path": "./client"
|
||||
},
|
||||
{
|
||||
"path": "./server"
|
||||
}
|
||||
],
|
||||
"files": []
|
||||
}
|
||||
|
||||
+2
-1
@@ -43,6 +43,7 @@ export default tseslint.config(
|
||||
singleline: { delimiter: 'comma', requireLast: false }
|
||||
}],
|
||||
'@stylistic/type-annotation-spacing': 'warn',
|
||||
'@stylistic/space-unary-ops': 'warn',
|
||||
|
||||
'@typescript-eslint/array-type': ['warn', { default: 'array', readonly: 'generic' }],
|
||||
'@typescript-eslint/consistent-type-assertions': 'warn',
|
||||
@@ -85,6 +86,7 @@ export default tseslint.config(
|
||||
'eqeqeq': ['warn', 'always'],
|
||||
'jsdoc/check-alignment': 'warn',
|
||||
'jsdoc/check-param-names': 'warn',
|
||||
'jsdoc/multiline-blocks': 'warn',
|
||||
'jsdoc/no-multi-asterisks': 'warn',
|
||||
'keyword-spacing': 'warn',
|
||||
'max-len': ['warn', {
|
||||
@@ -128,7 +130,6 @@ export default tseslint.config(
|
||||
'no-fallthrough': 'off',
|
||||
'prefer-spread': 'off',
|
||||
'object-curly-spacing': ['warn', 'always'],
|
||||
'brace-style': ['warn', '1tbs', { allowSingleLine: false }],
|
||||
'prefer-const': 'warn',
|
||||
'spaced-comment': ['warn', 'always', { markers: ['/'], exceptions: ['-'] }]
|
||||
}
|
||||
|
||||
@@ -3,15 +3,13 @@
|
||||
"description": "A headless terminal component that runs in Node.js",
|
||||
"version": "6.0.0",
|
||||
"main": "lib-headless/xterm-headless.js",
|
||||
"module": "lib-headless/xterm-headless.mjs",
|
||||
"module": "lib/xterm.mjs",
|
||||
"types": "typings/xterm-headless.d.ts",
|
||||
"exports": {
|
||||
"types": "./typings/xterm-headless.d.ts",
|
||||
"import": "./lib-headless/xterm-headless.mjs",
|
||||
"require": "./lib-headless/xterm-headless.js"
|
||||
},
|
||||
"repository": "https://github.com/xtermjs/xterm.js",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"addons/*"
|
||||
],
|
||||
"keywords": [
|
||||
"cli",
|
||||
"command-line",
|
||||
@@ -27,4 +25,4 @@
|
||||
"webgl",
|
||||
"xterm"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Smoke test: @xterm/headless loads and runs in Node.js (require).
|
||||
*/
|
||||
const { strictEqual } = require('node:assert');
|
||||
const { Terminal } = require('./lib-headless/xterm-headless.js');
|
||||
|
||||
function writeSync(term, data) {
|
||||
return new Promise(resolve => term.write(data, resolve));
|
||||
}
|
||||
|
||||
function lineEquals(term, index, text) {
|
||||
strictEqual(term.buffer.active.getLine(index).translateToString(true), text);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const term = new Terminal({ cols: 80, rows: 24, allowProposedApi: true });
|
||||
strictEqual(term.cols, 80);
|
||||
strictEqual(term.rows, 24);
|
||||
|
||||
await writeSync(term, 'hello from node');
|
||||
lineEquals(term, 0, 'hello from node');
|
||||
|
||||
await writeSync(term, 'foo');
|
||||
await writeSync(term, 'bar');
|
||||
await writeSync(term, '文');
|
||||
lineEquals(term, 0, 'hello from nodefoobar文');
|
||||
|
||||
term.resize(60, 15);
|
||||
strictEqual(term.cols, 60);
|
||||
strictEqual(term.rows, 15);
|
||||
|
||||
term.dispose();
|
||||
strictEqual(term._core._store.isDisposed, true);
|
||||
|
||||
console.log('headless package (CJS): load, write, buffer, resize, dispose OK');
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Smoke test: @xterm/headless loads and runs in Node.js (ESM + CJS).
|
||||
*/
|
||||
import { createRequire } from 'node:module';
|
||||
import { strictEqual } from 'node:assert';
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
function writeSync(term, data) {
|
||||
return new Promise(resolve => term.write(data, resolve));
|
||||
}
|
||||
|
||||
function lineEquals(term, index, text) {
|
||||
strictEqual(term.buffer.active.getLine(index).translateToString(true), text);
|
||||
}
|
||||
|
||||
const { Terminal: TerminalEsm } = await import('./lib-headless/xterm-headless.mjs');
|
||||
const termEsm = new TerminalEsm({ cols: 80, rows: 24 });
|
||||
await writeSync(termEsm, 'esm ok');
|
||||
lineEquals(termEsm, 0, 'esm ok');
|
||||
termEsm.dispose();
|
||||
|
||||
const { Terminal: TerminalCjs } = require('./lib-headless/xterm-headless.js');
|
||||
const termCjs = new TerminalCjs({ cols: 40, rows: 10 });
|
||||
await writeSync(termCjs, 'cjs ok');
|
||||
lineEquals(termCjs, 0, 'cjs ok');
|
||||
termCjs.dispose();
|
||||
|
||||
console.log('headless package: ESM and CJS load, write, and buffer read OK');
|
||||
Generated
+9
-8
@@ -84,7 +84,7 @@
|
||||
"devDependencies": {
|
||||
"@types/lru-cache": "^5.1.0",
|
||||
"@types/opentype.js": "^0.7.0",
|
||||
"axios": "^1.15.0",
|
||||
"axios": "^1.15.2",
|
||||
"font-finder": "^1.1.0",
|
||||
"mkdirp": "0.5.5",
|
||||
"yauzl": "^3.2.1"
|
||||
@@ -2546,9 +2546,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz",
|
||||
"integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==",
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz",
|
||||
"integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -3895,9 +3895,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fast-uri": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -3908,7 +3908,8 @@
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
]
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/fastest-levenshtein": {
|
||||
"version": "1.0.16",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user