Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1040b799ce | ||
|
|
1c42ae9af4 |
@@ -21,7 +21,9 @@ 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,7 +31,9 @@ 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
|
||||
|
||||
@@ -322,7 +322,9 @@ 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);
|
||||
@@ -542,7 +544,9 @@ 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\\');
|
||||
@@ -556,7 +560,9 @@ 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\\`);
|
||||
@@ -581,7 +587,9 @@ 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\\');
|
||||
@@ -595,7 +603,9 @@ 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\\');
|
||||
@@ -608,7 +618,9 @@ 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\\`);
|
||||
@@ -620,7 +632,9 @@ 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\\`);
|
||||
@@ -632,7 +646,9 @@ 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\\');
|
||||
@@ -645,7 +661,9 @@ 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"
|
||||
@@ -660,7 +678,9 @@ 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)
|
||||
@@ -676,7 +696,9 @@ 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\\');
|
||||
@@ -689,7 +711,9 @@ 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\\');
|
||||
@@ -701,7 +725,9 @@ 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\\');
|
||||
@@ -714,7 +740,9 @@ 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\\');
|
||||
@@ -726,7 +754,9 @@ 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\\`);
|
||||
@@ -739,7 +769,9 @@ 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\\`);
|
||||
@@ -752,7 +784,9 @@ 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\\`);
|
||||
@@ -765,7 +799,9 @@ 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\\');
|
||||
@@ -777,7 +813,9 @@ 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\\');
|
||||
@@ -789,7 +827,9 @@ 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\\`);
|
||||
@@ -801,7 +841,9 @@ 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\\`);
|
||||
@@ -813,7 +855,9 @@ 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\\`);
|
||||
@@ -825,7 +869,9 @@ 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\\`);
|
||||
@@ -839,7 +885,9 @@ 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\\`);
|
||||
@@ -852,7 +900,9 @@ 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\\`);
|
||||
@@ -865,7 +915,9 @@ 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\\`);
|
||||
@@ -878,7 +930,9 @@ 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\\`);
|
||||
@@ -891,7 +945,9 @@ 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\\`);
|
||||
@@ -904,7 +960,9 @@ 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\\`);
|
||||
@@ -917,7 +975,9 @@ 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\\`);
|
||||
@@ -930,7 +990,9 @@ 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\\`);
|
||||
@@ -943,7 +1005,9 @@ 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\\`);
|
||||
@@ -956,7 +1020,9 @@ 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\\`);
|
||||
@@ -969,7 +1035,9 @@ 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\\`);
|
||||
@@ -982,7 +1050,9 @@ 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\\`);
|
||||
@@ -995,7 +1065,9 @@ 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\\`);
|
||||
@@ -1026,7 +1098,9 @@ 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\\`);
|
||||
@@ -1039,7 +1113,9 @@ 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\\`);
|
||||
@@ -1052,7 +1128,9 @@ 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\\`);
|
||||
@@ -1172,7 +1250,9 @@ 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\\`);
|
||||
@@ -1188,7 +1268,9 @@ 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\\`);
|
||||
@@ -1201,7 +1283,9 @@ 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\\`);
|
||||
@@ -1213,7 +1297,9 @@ 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\\`);
|
||||
@@ -1268,7 +1354,9 @@ 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\\`);
|
||||
@@ -1803,7 +1891,9 @@ 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\\`);
|
||||
@@ -1952,7 +2042,9 @@ 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);
|
||||
@@ -1963,7 +2055,9 @@ 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);
|
||||
@@ -1974,7 +2068,9 @@ 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);
|
||||
@@ -2086,7 +2182,9 @@ 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);
|
||||
@@ -2097,7 +2195,9 @@ 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);
|
||||
@@ -2108,7 +2208,9 @@ 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);
|
||||
|
||||
@@ -65,9 +65,8 @@ export default async function load(fontFamily: string, cacheSize: number): Promi
|
||||
console.error(err.name, err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Latest proposal https://bugs.chromium.org/p/chromium/issues/detail?id=1312603
|
||||
else if (typeof window !== 'undefined' && 'queryLocalFonts' in window) {
|
||||
} else if (typeof window !== 'undefined' && 'queryLocalFonts' in window) {
|
||||
// Latest proposal https://bugs.chromium.org/p/chromium/issues/detail?id=1312603
|
||||
const fonts: Record<string, IFontMetadata[]> = {};
|
||||
try {
|
||||
const fontsIterator = await (window as any).queryLocalFonts();
|
||||
|
||||
@@ -46,7 +46,9 @@ 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);
|
||||
});
|
||||
@@ -127,7 +129,9 @@ 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];
|
||||
|
||||
@@ -64,7 +64,9 @@ 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;
|
||||
}
|
||||
@@ -85,7 +87,9 @@ 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();
|
||||
} });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,9 @@ 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.
|
||||
|
||||
@@ -29,12 +29,20 @@ 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];
|
||||
|
||||
@@ -70,7 +70,9 @@ 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 {
|
||||
@@ -291,25 +293,39 @@ 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)); }
|
||||
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);
|
||||
}
|
||||
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)); }
|
||||
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);
|
||||
}
|
||||
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) {
|
||||
@@ -332,12 +348,24 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -646,8 +674,7 @@ 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;
|
||||
}
|
||||
}
|
||||
@@ -752,8 +779,12 @@ 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[] = [];
|
||||
@@ -781,9 +812,15 @@ 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;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@ 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) {
|
||||
|
||||
@@ -62,7 +62,9 @@ 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[] = [];
|
||||
@@ -1039,10 +1041,14 @@ 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;
|
||||
|
||||
@@ -521,8 +521,7 @@ 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,7 +30,9 @@ 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,7 +8,9 @@ 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,
|
||||
|
||||
@@ -128,6 +128,7 @@ 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: ['-'] }]
|
||||
}
|
||||
|
||||
@@ -71,7 +71,9 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
||||
private _compositionView: HTMLElement | undefined;
|
||||
|
||||
private readonly _linkifier: MutableDisposable<ILinkifier2> = this._register(new MutableDisposable());
|
||||
public get linkifier(): ILinkifier2 | undefined { return this._linkifier.value; }
|
||||
public get linkifier(): ILinkifier2 | undefined {
|
||||
return this._linkifier.value;
|
||||
}
|
||||
private _overviewRulerRenderer: OverviewRulerRenderer | undefined;
|
||||
private _viewport: Viewport | undefined;
|
||||
|
||||
@@ -136,15 +138,25 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
||||
public readonly onBell = this._onBell.event;
|
||||
|
||||
private _onFocus = this._register(new Emitter<void>());
|
||||
public get onFocus(): IEvent<void> { return this._onFocus.event; }
|
||||
public get onFocus(): IEvent<void> {
|
||||
return this._onFocus.event;
|
||||
}
|
||||
private _onBlur = this._register(new Emitter<void>());
|
||||
public get onBlur(): IEvent<void> { return this._onBlur.event; }
|
||||
public get onBlur(): IEvent<void> {
|
||||
return this._onBlur.event;
|
||||
}
|
||||
private _onA11yCharEmitter = this._register(new Emitter<string>());
|
||||
public get onA11yChar(): IEvent<string> { return this._onA11yCharEmitter.event; }
|
||||
public get onA11yChar(): IEvent<string> {
|
||||
return this._onA11yCharEmitter.event;
|
||||
}
|
||||
private _onA11yTabEmitter = this._register(new Emitter<number>());
|
||||
public get onA11yTab(): IEvent<number> { return this._onA11yTabEmitter.event; }
|
||||
public get onA11yTab(): IEvent<number> {
|
||||
return this._onA11yTabEmitter.event;
|
||||
}
|
||||
private _onWillOpen = this._register(new Emitter<HTMLElement>());
|
||||
public get onWillOpen(): IEvent<HTMLElement> { return this._onWillOpen.event; }
|
||||
public get onWillOpen(): IEvent<HTMLElement> {
|
||||
return this._onWillOpen.event;
|
||||
}
|
||||
private readonly _onDimensionsChange = this._register(new Emitter<IRenderDimensionsApi>());
|
||||
public readonly onDimensionsChange = this._onDimensionsChange.event;
|
||||
|
||||
@@ -563,8 +575,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
||||
|
||||
try {
|
||||
this._onWillOpen.fire(this.element);
|
||||
}
|
||||
catch { /* fails to load addon for some reason */ }
|
||||
} catch { /* fails to load addon for some reason */ }
|
||||
if (!this._renderService.hasRenderer()) {
|
||||
this._renderService.setRenderer(this._createRenderer());
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ import { Emitter } from 'common/Event';
|
||||
import { addDisposableListener } from 'browser/Dom';
|
||||
|
||||
export class Linkifier extends Disposable implements ILinkifier2 {
|
||||
public get currentLink(): ILinkWithState | undefined { return this._currentLink; }
|
||||
public get currentLink(): ILinkWithState | undefined {
|
||||
return this._currentLink;
|
||||
}
|
||||
protected _currentLink: ILinkWithState | undefined;
|
||||
private _mouseDownLink: ILinkWithState | undefined;
|
||||
private _lastMouseEvent: MouseEvent | undefined;
|
||||
|
||||
@@ -21,9 +21,15 @@ import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
|
||||
import { Emitter, type IEvent } from 'common/Event';
|
||||
|
||||
export class TestTerminal extends CoreBrowserTerminal {
|
||||
public get curAttrData(): IAttributeData { return (this as any)._inputHandler._curAttrData; }
|
||||
public keyDown(ev: any): boolean | undefined { return this._keyDown(ev); }
|
||||
public keyPress(ev: any): boolean { return this._keyPress(ev); }
|
||||
public get curAttrData(): IAttributeData {
|
||||
return (this as any)._inputHandler._curAttrData;
|
||||
}
|
||||
public keyDown(ev: any): boolean | undefined {
|
||||
return this._keyDown(ev);
|
||||
}
|
||||
public keyPress(ev: any): boolean {
|
||||
return this._keyPress(ev);
|
||||
}
|
||||
public writeP(data: string | Uint8Array): Promise<void> {
|
||||
return new Promise(r => this.write(data, r));
|
||||
}
|
||||
@@ -213,7 +219,9 @@ export class MockTerminal implements ITerminal {
|
||||
public refresh(start: number, end: number): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
public registerCharacterJoiner(handler: CharacterJoinerHandler): number { return 0; }
|
||||
public registerCharacterJoiner(handler: CharacterJoinerHandler): number {
|
||||
return 0;
|
||||
}
|
||||
public deregisterCharacterJoiner(joinerId: number): void { }
|
||||
}
|
||||
|
||||
@@ -377,7 +385,9 @@ export class MockCoreBrowserService implements ICoreBrowserService {
|
||||
|
||||
export class MockCharSizeService implements ICharSizeService {
|
||||
public serviceBrand: undefined;
|
||||
public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }
|
||||
public get hasValidSize(): boolean {
|
||||
return this.width > 0 && this.height > 0;
|
||||
}
|
||||
public onCharSizeChange: IEvent<void> = new Emitter<void>().event;
|
||||
constructor(public width: number, public height: number) {}
|
||||
public measure(): void {}
|
||||
|
||||
@@ -23,7 +23,9 @@ export class CompositionHelper {
|
||||
* IME. This variable determines whether the compositionText should be displayed on the UI.
|
||||
*/
|
||||
private _isComposing: boolean;
|
||||
public get isComposing(): boolean { return this._isComposing; }
|
||||
public get isComposing(): boolean {
|
||||
return this._isComposing;
|
||||
}
|
||||
|
||||
/**
|
||||
* The position within the input textarea's value of the current composition.
|
||||
|
||||
@@ -68,22 +68,52 @@ export class Terminal extends Disposable implements ITerminalApi {
|
||||
}
|
||||
}
|
||||
|
||||
public get onBell(): IEvent<void> { return this._core.onBell; }
|
||||
public get onBinary(): IEvent<string> { return this._core.onBinary; }
|
||||
public get onCursorMove(): IEvent<void> { return this._core.onCursorMove; }
|
||||
public get onData(): IEvent<string> { return this._core.onData; }
|
||||
public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }
|
||||
public get onLineFeed(): IEvent<void> { return this._core.onLineFeed; }
|
||||
public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }
|
||||
public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }
|
||||
public get onScroll(): IEvent<number> { return this._core.onScroll; }
|
||||
public get onSelectionChange(): IEvent<void> { return this._core.onSelectionChange; }
|
||||
public get onTitleChange(): IEvent<string> { return this._core.onTitleChange; }
|
||||
public get onWriteParsed(): IEvent<void> { return this._core.onWriteParsed; }
|
||||
public get onDimensionsChange(): IEvent<IRenderDimensions> { return this._core.onDimensionsChange; }
|
||||
public get onBell(): IEvent<void> {
|
||||
return this._core.onBell;
|
||||
}
|
||||
public get onBinary(): IEvent<string> {
|
||||
return this._core.onBinary;
|
||||
}
|
||||
public get onCursorMove(): IEvent<void> {
|
||||
return this._core.onCursorMove;
|
||||
}
|
||||
public get onData(): IEvent<string> {
|
||||
return this._core.onData;
|
||||
}
|
||||
public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> {
|
||||
return this._core.onKey;
|
||||
}
|
||||
public get onLineFeed(): IEvent<void> {
|
||||
return this._core.onLineFeed;
|
||||
}
|
||||
public get onRender(): IEvent<{ start: number, end: number }> {
|
||||
return this._core.onRender;
|
||||
}
|
||||
public get onResize(): IEvent<{ cols: number, rows: number }> {
|
||||
return this._core.onResize;
|
||||
}
|
||||
public get onScroll(): IEvent<number> {
|
||||
return this._core.onScroll;
|
||||
}
|
||||
public get onSelectionChange(): IEvent<void> {
|
||||
return this._core.onSelectionChange;
|
||||
}
|
||||
public get onTitleChange(): IEvent<string> {
|
||||
return this._core.onTitleChange;
|
||||
}
|
||||
public get onWriteParsed(): IEvent<void> {
|
||||
return this._core.onWriteParsed;
|
||||
}
|
||||
public get onDimensionsChange(): IEvent<IRenderDimensions> {
|
||||
return this._core.onDimensionsChange;
|
||||
}
|
||||
|
||||
public get element(): HTMLElement | undefined { return this._core.element; }
|
||||
public get screenElement(): HTMLElement | undefined { return this._core.screenElement; }
|
||||
public get element(): HTMLElement | undefined {
|
||||
return this._core.element;
|
||||
}
|
||||
public get screenElement(): HTMLElement | undefined {
|
||||
return this._core.screenElement;
|
||||
}
|
||||
public get parser(): IParser {
|
||||
return this._parser ??= new ParserApi(this._core);
|
||||
}
|
||||
@@ -91,9 +121,15 @@ export class Terminal extends Disposable implements ITerminalApi {
|
||||
this._checkProposedApi();
|
||||
return new UnicodeApi(this._core);
|
||||
}
|
||||
public get textarea(): HTMLTextAreaElement | undefined { return this._core.textarea; }
|
||||
public get rows(): number { return this._core.rows; }
|
||||
public get cols(): number { return this._core.cols; }
|
||||
public get textarea(): HTMLTextAreaElement | undefined {
|
||||
return this._core.textarea;
|
||||
}
|
||||
public get rows(): number {
|
||||
return this._core.rows;
|
||||
}
|
||||
public get cols(): number {
|
||||
return this._core.cols;
|
||||
}
|
||||
public get buffer(): IBufferNamespaceApi {
|
||||
return this._buffer ??= this._register(new BufferNamespaceApi(this._core));
|
||||
}
|
||||
@@ -247,10 +283,18 @@ export class Terminal extends Disposable implements ITerminalApi {
|
||||
public static get strings(): ILocalizableStrings {
|
||||
// A wrapper is required here because esbuild prevents setting an `export let`
|
||||
return {
|
||||
get promptLabel(): string { return Strings.promptLabel.get(); },
|
||||
set promptLabel(value: string) { Strings.promptLabel.set(value); },
|
||||
get tooMuchOutput(): string { return Strings.tooMuchOutput.get(); },
|
||||
set tooMuchOutput(value: string) { Strings.tooMuchOutput.set(value); }
|
||||
get promptLabel(): string {
|
||||
return Strings.promptLabel.get();
|
||||
},
|
||||
set promptLabel(value: string) {
|
||||
Strings.promptLabel.set(value);
|
||||
},
|
||||
get tooMuchOutput(): string {
|
||||
return Strings.tooMuchOutput.get();
|
||||
},
|
||||
set tooMuchOutput(value: string) {
|
||||
Strings.tooMuchOutput.set(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@ export class CharSizeService extends Disposable implements ICharSizeService {
|
||||
public height: number = 0;
|
||||
private _measureStrategy: IMeasureStrategy;
|
||||
|
||||
public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }
|
||||
public get hasValidSize(): boolean {
|
||||
return this.width > 0 && this.height > 0;
|
||||
}
|
||||
|
||||
private readonly _onCharSizeChange = this._register(new Emitter<void>());
|
||||
public readonly onCharSizeChange = this._onCharSizeChange.event;
|
||||
|
||||
@@ -52,7 +52,9 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
private readonly _onRefreshRequest = this._register(new Emitter<{ start: number, end: number }>());
|
||||
public readonly onRefreshRequest = this._onRefreshRequest.event;
|
||||
|
||||
public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; }
|
||||
public get dimensions(): IRenderDimensions {
|
||||
return this._renderer.value!.dimensions;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private _rowCount: number,
|
||||
|
||||
@@ -27,13 +27,23 @@ class TestSelectionService extends SelectionService {
|
||||
super(null!, null!, null!, bufferService, new MockCoreService(), new MockMouseService(), optionsService, renderService, new MockCoreBrowserService());
|
||||
}
|
||||
|
||||
public get model(): SelectionModel { return this._model; }
|
||||
public get model(): SelectionModel {
|
||||
return this._model;
|
||||
}
|
||||
|
||||
public set selectionMode(mode: SelectionMode) { this._activeSelectionMode = mode; }
|
||||
public set selectionMode(mode: SelectionMode) {
|
||||
this._activeSelectionMode = mode;
|
||||
}
|
||||
|
||||
public selectLineAt(line: number): void { this._selectLineAt(line); }
|
||||
public selectWordAt(coords: [number, number]): void { this._selectWordAt(coords, true); }
|
||||
public areCoordsInSelection(coords: [number, number], start: [number, number], end: [number, number]): boolean { return this._areCoordsInSelection(coords, start, end); }
|
||||
public selectLineAt(line: number): void {
|
||||
this._selectLineAt(line);
|
||||
}
|
||||
public selectWordAt(coords: [number, number]): void {
|
||||
this._selectWordAt(coords, true);
|
||||
}
|
||||
public areCoordsInSelection(coords: [number, number], start: [number, number], end: [number, number]): boolean {
|
||||
return this._areCoordsInSelection(coords, start, end);
|
||||
}
|
||||
|
||||
// Disable DOM interaction
|
||||
public enable(): void {}
|
||||
|
||||
@@ -181,8 +181,12 @@ export class SelectionService extends Disposable implements ISelectionService {
|
||||
this._enabled = true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether there is an active text selection.
|
||||
|
||||
@@ -38,7 +38,9 @@ export class ThemeService extends Disposable implements IThemeService {
|
||||
private _halfContrastCache: IColorContrastCache = new ColorContrastCache();
|
||||
private _restoreColors!: IRestoreColorSet;
|
||||
|
||||
public get colors(): ReadonlyColorSet { return this._colors; }
|
||||
public get colors(): ReadonlyColorSet {
|
||||
return this._colors;
|
||||
}
|
||||
|
||||
private readonly _onChangeColors = this._register(new Emitter<ReadonlyColorSet>());
|
||||
public readonly onChangeColors = this._onChangeColors.event;
|
||||
|
||||
+1
-2
@@ -132,8 +132,7 @@ export namespace css {
|
||||
$ctx.globalCompositeOperation = 'copy';
|
||||
$litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
|
||||
|
||||
@@ -88,10 +88,18 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
||||
return this._onScrollApi.event;
|
||||
}
|
||||
|
||||
public get cols(): number { return this._bufferService.cols; }
|
||||
public get rows(): number { return this._bufferService.rows; }
|
||||
public get buffers(): IBufferSet { return this._bufferService.buffers; }
|
||||
public get options(): Required<ITerminalOptions> { return this.optionsService.options; }
|
||||
public get cols(): number {
|
||||
return this._bufferService.cols;
|
||||
}
|
||||
public get rows(): number {
|
||||
return this._bufferService.rows;
|
||||
}
|
||||
public get buffers(): IBufferSet {
|
||||
return this._bufferService.buffers;
|
||||
}
|
||||
public get options(): Required<ITerminalOptions> {
|
||||
return this.optionsService.options;
|
||||
}
|
||||
public set options(options: ITerminalOptions) {
|
||||
for (const key in options) {
|
||||
this.optionsService.options[key] = options[key];
|
||||
|
||||
@@ -15,14 +15,18 @@ describe('Emitter', () => {
|
||||
it('should fire with 1 listener', () => {
|
||||
const emitter = new Emitter<number>();
|
||||
let received: number | undefined;
|
||||
emitter.event(e => { received = e; });
|
||||
emitter.event(e => {
|
||||
received = e;
|
||||
});
|
||||
emitter.fire(42);
|
||||
assert.strictEqual(received, 42);
|
||||
});
|
||||
|
||||
it('should fire with 1 listener using thisArgs', () => {
|
||||
const emitter = new Emitter<number>();
|
||||
const obj = { value: 0, handler(e: number) { this.value = e; } };
|
||||
const obj = { value: 0, handler(e: number) {
|
||||
this.value = e;
|
||||
} };
|
||||
emitter.event(obj.handler, obj);
|
||||
emitter.fire(42);
|
||||
assert.strictEqual(obj.value, 42);
|
||||
@@ -54,7 +58,9 @@ describe('Emitter', () => {
|
||||
it('should not fire after dispose', () => {
|
||||
const emitter = new Emitter<number>();
|
||||
let called = false;
|
||||
emitter.event(() => { called = true; });
|
||||
emitter.event(() => {
|
||||
called = true;
|
||||
});
|
||||
emitter.dispose();
|
||||
emitter.fire(42);
|
||||
assert.strictEqual(called, false);
|
||||
@@ -63,7 +69,9 @@ describe('Emitter', () => {
|
||||
it('should allow disposing a listener', () => {
|
||||
const emitter = new Emitter<number>();
|
||||
let count = 0;
|
||||
const disposable = emitter.event(() => { count++; });
|
||||
const disposable = emitter.event(() => {
|
||||
count++;
|
||||
});
|
||||
emitter.fire(1);
|
||||
disposable.dispose();
|
||||
emitter.fire(2);
|
||||
|
||||
@@ -39,9 +39,15 @@ function getLines(bufferService: IBufferService, limit: number = bufferService.r
|
||||
}
|
||||
|
||||
class TestInputHandler extends InputHandler {
|
||||
public get curAttrData(): IAttributeData { return (this as any)._curAttrData; }
|
||||
public get windowTitleStack(): string[] { return this._windowTitleStack; }
|
||||
public get iconNameStack(): string[] { return this._iconNameStack; }
|
||||
public get curAttrData(): IAttributeData {
|
||||
return (this as any)._curAttrData;
|
||||
}
|
||||
public get windowTitleStack(): string[] {
|
||||
return this._windowTitleStack;
|
||||
}
|
||||
public get iconNameStack(): string[] {
|
||||
return this._iconNameStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Promise based parse call to await the full resolve of given input data.
|
||||
@@ -2511,7 +2517,9 @@ describe('InputHandler', () => {
|
||||
bufferService = new BufferService(optionsService, new MockLogService());
|
||||
bufferService.resize(80, 30);
|
||||
coreService = new CoreService(bufferService, new MockLogService(), optionsService);
|
||||
coreService.onData(data => { console.log(data); });
|
||||
coreService.onData(data => {
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
inputHandler = new TestInputHandler(bufferService, new MockCharsetService(), coreService, new MockLogService(), optionsService, new MockOscLinkService(), new MockMouseStateService(), new MockUnicodeService());
|
||||
});
|
||||
|
||||
@@ -107,7 +107,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
protected _iconNameStack: string[] = [];
|
||||
|
||||
private _curAttrData: IAttributeData = DEFAULT_ATTR_DATA.clone();
|
||||
public getAttrData(): IAttributeData { return this._curAttrData; }
|
||||
public getAttrData(): IAttributeData {
|
||||
return this._curAttrData;
|
||||
}
|
||||
private _eraseAttrDataInternal: IAttributeData = DEFAULT_ATTR_DATA.clone();
|
||||
|
||||
private _activeBuffer: IBuffer;
|
||||
@@ -283,7 +285,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* OSC handler
|
||||
*/
|
||||
// 0 - icon name + title
|
||||
this._parser.registerOscHandler(0, new OscHandler(data => { this.setTitle(data); this.setIconName(data); return true; }));
|
||||
this._parser.registerOscHandler(0, new OscHandler(data => {
|
||||
this.setTitle(data); this.setIconName(data); return true;
|
||||
}));
|
||||
// 1 - icon name
|
||||
this._parser.registerOscHandler(1, new OscHandler(data => this.setIconName(data)));
|
||||
// 2 - title
|
||||
@@ -1268,8 +1272,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
for (; j >= 0; j--) {
|
||||
this._bufferService.scroll(this._eraseAttrData());
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
j = this._bufferService.rows;
|
||||
this._dirtyRowTracker.markDirty(j - 1);
|
||||
while (j--) {
|
||||
|
||||
@@ -30,7 +30,9 @@ export const NULL_CELL_DATA = Object.freeze(createCellData(DEFAULT_ATTR, NULL_CE
|
||||
|
||||
export class MockBufferService implements IBufferService {
|
||||
public serviceBrand: any;
|
||||
public get buffer(): IBuffer { return this.buffers.active; }
|
||||
public get buffer(): IBuffer {
|
||||
return this.buffers.active;
|
||||
}
|
||||
public buffers: IBufferSet = {} as any;
|
||||
public onResize: IEvent<IBufferResizeEvent> = new Emitter<IBufferResizeEvent>().event;
|
||||
public onScroll: IEvent<number> = new Emitter<number>().event;
|
||||
@@ -83,10 +85,16 @@ export class MockMouseStateService implements IMouseStateService {
|
||||
public addProtocol(name: string): void { }
|
||||
public reset(): void { }
|
||||
public onProtocolChange: IEvent<CoreMouseEventType> = new Emitter<CoreMouseEventType>().event;
|
||||
public restrictMouseEvent(event: ICoreMouseEvent): boolean { return true; }
|
||||
public encodeMouseEvent(event: ICoreMouseEvent): string { return ''; }
|
||||
public restrictMouseEvent(event: ICoreMouseEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
public encodeMouseEvent(event: ICoreMouseEvent): string {
|
||||
return '';
|
||||
}
|
||||
public setCustomWheelEventHandler(customWheelEventHandler: ((event: WheelEvent) => boolean) | undefined): void { }
|
||||
public allowCustomWheelEvent(ev: WheelEvent): boolean { return true; }
|
||||
public allowCustomWheelEvent(ev: WheelEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class MockCharsetService implements ICharsetService {
|
||||
@@ -233,10 +241,14 @@ export class MockUnicodeService implements IUnicodeService {
|
||||
|
||||
export class MockDecorationService implements IDecorationService {
|
||||
public serviceBrand: any;
|
||||
public get decorations(): IterableIterator<IInternalDecoration> { return [].values(); }
|
||||
public get decorations(): IterableIterator<IInternalDecoration> {
|
||||
return [].values();
|
||||
}
|
||||
public onDecorationRegistered = new Emitter<IInternalDecoration>().event;
|
||||
public onDecorationRemoved = new Emitter<IInternalDecoration>().event;
|
||||
public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined { return undefined; }
|
||||
public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {
|
||||
return undefined;
|
||||
}
|
||||
public reset(): void { }
|
||||
public forEachDecorationAtCell(x: number, line: number, layer: 'bottom' | 'top' | undefined, callback: (decoration: IInternalDecoration) => void): void { }
|
||||
public dispose(): void { }
|
||||
|
||||
@@ -33,32 +33,68 @@ export class AttributeData implements IAttributeData {
|
||||
public extended: IExtendedAttrs = new ExtendedAttrs();
|
||||
|
||||
// flags
|
||||
public isInverse(): number { return this.fg & FgFlags.INVERSE; }
|
||||
public isBold(): number { return this.fg & FgFlags.BOLD; }
|
||||
public isInverse(): number {
|
||||
return this.fg & FgFlags.INVERSE;
|
||||
}
|
||||
public isBold(): number {
|
||||
return this.fg & FgFlags.BOLD;
|
||||
}
|
||||
public isUnderline(): number {
|
||||
if (this.hasExtendedAttrs() && this.extended.underlineStyle !== UnderlineStyle.NONE) {
|
||||
return 1;
|
||||
}
|
||||
return this.fg & FgFlags.UNDERLINE;
|
||||
}
|
||||
public isBlink(): number { return this.fg & FgFlags.BLINK; }
|
||||
public isInvisible(): number { return this.fg & FgFlags.INVISIBLE; }
|
||||
public isItalic(): number { return this.bg & BgFlags.ITALIC; }
|
||||
public isDim(): number { return this.bg & BgFlags.DIM; }
|
||||
public isStrikethrough(): number { return this.fg & FgFlags.STRIKETHROUGH; }
|
||||
public isProtected(): number { return this.bg & BgFlags.PROTECTED; }
|
||||
public isOverline(): number { return this.bg & BgFlags.OVERLINE; }
|
||||
public isBlink(): number {
|
||||
return this.fg & FgFlags.BLINK;
|
||||
}
|
||||
public isInvisible(): number {
|
||||
return this.fg & FgFlags.INVISIBLE;
|
||||
}
|
||||
public isItalic(): number {
|
||||
return this.bg & BgFlags.ITALIC;
|
||||
}
|
||||
public isDim(): number {
|
||||
return this.bg & BgFlags.DIM;
|
||||
}
|
||||
public isStrikethrough(): number {
|
||||
return this.fg & FgFlags.STRIKETHROUGH;
|
||||
}
|
||||
public isProtected(): number {
|
||||
return this.bg & BgFlags.PROTECTED;
|
||||
}
|
||||
public isOverline(): number {
|
||||
return this.bg & BgFlags.OVERLINE;
|
||||
}
|
||||
|
||||
// color modes
|
||||
public getFgColorMode(): number { return this.fg & Attributes.CM_MASK; }
|
||||
public getBgColorMode(): number { return this.bg & Attributes.CM_MASK; }
|
||||
public isFgRGB(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_RGB; }
|
||||
public isBgRGB(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_RGB; }
|
||||
public isFgPalette(): boolean { return (this.fg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.fg & Attributes.CM_MASK) === Attributes.CM_P256; }
|
||||
public isBgPalette(): boolean { return (this.bg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.bg & Attributes.CM_MASK) === Attributes.CM_P256; }
|
||||
public isFgDefault(): boolean { return (this.fg & Attributes.CM_MASK) === 0; }
|
||||
public isBgDefault(): boolean { return (this.bg & Attributes.CM_MASK) === 0; }
|
||||
public isAttributeDefault(): boolean { return this.fg === 0 && this.bg === 0; }
|
||||
public getFgColorMode(): number {
|
||||
return this.fg & Attributes.CM_MASK;
|
||||
}
|
||||
public getBgColorMode(): number {
|
||||
return this.bg & Attributes.CM_MASK;
|
||||
}
|
||||
public isFgRGB(): boolean {
|
||||
return (this.fg & Attributes.CM_MASK) === Attributes.CM_RGB;
|
||||
}
|
||||
public isBgRGB(): boolean {
|
||||
return (this.bg & Attributes.CM_MASK) === Attributes.CM_RGB;
|
||||
}
|
||||
public isFgPalette(): boolean {
|
||||
return (this.fg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.fg & Attributes.CM_MASK) === Attributes.CM_P256;
|
||||
}
|
||||
public isBgPalette(): boolean {
|
||||
return (this.bg & Attributes.CM_MASK) === Attributes.CM_P16 || (this.bg & Attributes.CM_MASK) === Attributes.CM_P256;
|
||||
}
|
||||
public isFgDefault(): boolean {
|
||||
return (this.fg & Attributes.CM_MASK) === 0;
|
||||
}
|
||||
public isBgDefault(): boolean {
|
||||
return (this.bg & Attributes.CM_MASK) === 0;
|
||||
}
|
||||
public isAttributeDefault(): boolean {
|
||||
return this.fg === 0 && this.bg === 0;
|
||||
}
|
||||
|
||||
// colors
|
||||
public getFgColor(): number {
|
||||
@@ -147,7 +183,9 @@ export class ExtendedAttrs implements IExtendedAttrs {
|
||||
}
|
||||
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
|
||||
|
||||
@@ -62,8 +62,7 @@ export class CellData extends AttributeData implements ICellData {
|
||||
// surrogates and combined strings need special treatment
|
||||
if (value[CHAR_DATA_CHAR_INDEX].length > 2) {
|
||||
combined = true;
|
||||
}
|
||||
else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {
|
||||
} else if (value[CHAR_DATA_CHAR_INDEX].length === 2) {
|
||||
const code = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0);
|
||||
// if the 2-char string is a surrogate create single codepoint
|
||||
// everything else is combined
|
||||
@@ -71,16 +70,13 @@ export class CellData extends AttributeData implements ICellData {
|
||||
const second = value[CHAR_DATA_CHAR_INDEX].charCodeAt(1);
|
||||
if (0xDC00 <= second && second <= 0xDFFF) {
|
||||
this.content = ((code - 0xD800) * 0x400 + second - 0xDC00 + 0x10000) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
combined = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
combined = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.content = value[CHAR_DATA_CHAR_INDEX].charCodeAt(0) | (value[CHAR_DATA_WIDTH_INDEX] << Content.WIDTH_SHIFT);
|
||||
}
|
||||
if (combined) {
|
||||
|
||||
@@ -14,7 +14,9 @@ export class Marker implements IMarker {
|
||||
private readonly _disposables: IDisposable[] = [];
|
||||
|
||||
private readonly _id: number = Marker._nextId++;
|
||||
public get id(): number { return this._id; }
|
||||
public get id(): number {
|
||||
return this._id;
|
||||
}
|
||||
|
||||
private readonly _onDispose = this.register(new Emitter<void>());
|
||||
public readonly onDispose = this._onDispose.event;
|
||||
|
||||
@@ -58,22 +58,19 @@ export function evaluateKeyboardEvent(
|
||||
} else {
|
||||
result.key = C0.ESC + '[A';
|
||||
}
|
||||
}
|
||||
else if (ev.key === 'UIKeyInputLeftArrow') {
|
||||
} else if (ev.key === 'UIKeyInputLeftArrow') {
|
||||
if (applicationCursorMode) {
|
||||
result.key = C0.ESC + 'OD';
|
||||
} else {
|
||||
result.key = C0.ESC + '[D';
|
||||
}
|
||||
}
|
||||
else if (ev.key === 'UIKeyInputRightArrow') {
|
||||
} else if (ev.key === 'UIKeyInputRightArrow') {
|
||||
if (applicationCursorMode) {
|
||||
result.key = C0.ESC + 'OC';
|
||||
} else {
|
||||
result.key = C0.ESC + '[C';
|
||||
}
|
||||
}
|
||||
else if (ev.key === 'UIKeyInputDownArrow') {
|
||||
} else if (ev.key === 'UIKeyInputDownArrow') {
|
||||
if (applicationCursorMode) {
|
||||
result.key = C0.ESC + 'OB';
|
||||
} else {
|
||||
|
||||
@@ -230,8 +230,7 @@ export class Utf8ToUtf32 {
|
||||
&& !((byte1 = input[i]) & 0x80)
|
||||
&& !((byte2 = input[i + 1]) & 0x80)
|
||||
&& !((byte3 = input[i + 2]) & 0x80)
|
||||
&& !((byte4 = input[i + 3]) & 0x80))
|
||||
{
|
||||
&& !((byte4 = input[i + 3]) & 0x80)) {
|
||||
target[size++] = byte1;
|
||||
target[size++] = byte2;
|
||||
target[size++] = byte3;
|
||||
|
||||
@@ -24,14 +24,20 @@ describe('WriteBuffer', () => {
|
||||
beforeEach(() => {
|
||||
stack = [];
|
||||
cbStack = [];
|
||||
wb = new WriteBuffer(data => { stack.push(data); });
|
||||
wb = new WriteBuffer(data => {
|
||||
stack.push(data);
|
||||
});
|
||||
});
|
||||
describe('write input', () => {
|
||||
it('string', done => {
|
||||
wb.write('a._');
|
||||
wb.write('b.x', () => { cbStack.push('b'); });
|
||||
wb.write('b.x', () => {
|
||||
cbStack.push('b');
|
||||
});
|
||||
wb.write('c._');
|
||||
wb.write('d.x', () => { cbStack.push('d'); });
|
||||
wb.write('d.x', () => {
|
||||
cbStack.push('d');
|
||||
});
|
||||
wb.write('e', () => {
|
||||
assert.deepEqual(stack, ['a._', 'b.x', 'c._', 'd.x', 'e']);
|
||||
assert.deepEqual(cbStack, ['b', 'd']);
|
||||
@@ -40,9 +46,13 @@ describe('WriteBuffer', () => {
|
||||
});
|
||||
it('bytes', done => {
|
||||
wb.write(toBytes('a._'));
|
||||
wb.write(toBytes('b.x'), () => { cbStack.push('b'); });
|
||||
wb.write(toBytes('b.x'), () => {
|
||||
cbStack.push('b');
|
||||
});
|
||||
wb.write(toBytes('c._'));
|
||||
wb.write(toBytes('d.x'), () => { cbStack.push('d'); });
|
||||
wb.write(toBytes('d.x'), () => {
|
||||
cbStack.push('d');
|
||||
});
|
||||
wb.write(toBytes('e'), () => {
|
||||
assert.deepEqual(stack.map(val => typeof val === 'string' ? '' : fromBytes(val)), ['a._', 'b.x', 'c._', 'd.x', 'e']);
|
||||
assert.deepEqual(cbStack, ['b', 'd']);
|
||||
@@ -51,9 +61,13 @@ describe('WriteBuffer', () => {
|
||||
});
|
||||
it('string/bytes mixed', done => {
|
||||
wb.write('a._');
|
||||
wb.write('b.x', () => { cbStack.push('b'); });
|
||||
wb.write('b.x', () => {
|
||||
cbStack.push('b');
|
||||
});
|
||||
wb.write(toBytes('c._'));
|
||||
wb.write(toBytes('d.x'), () => { cbStack.push('d'); });
|
||||
wb.write(toBytes('d.x'), () => {
|
||||
cbStack.push('d');
|
||||
});
|
||||
wb.write(toBytes('e'), () => {
|
||||
assert.deepEqual(stack.map(val => typeof val === 'string' ? val : fromBytes(val)), ['a._', 'b.x', 'c._', 'd.x', 'e']);
|
||||
assert.deepEqual(cbStack, ['b', 'd']);
|
||||
@@ -61,10 +75,18 @@ describe('WriteBuffer', () => {
|
||||
});
|
||||
});
|
||||
it('write callback works for empty chunks', done => {
|
||||
wb.write('a', () => { cbStack.push('a'); });
|
||||
wb.write('', () => { cbStack.push('b'); });
|
||||
wb.write(toBytes('c'), () => { cbStack.push('c'); });
|
||||
wb.write(new Uint8Array(0), () => { cbStack.push('d'); });
|
||||
wb.write('a', () => {
|
||||
cbStack.push('a');
|
||||
});
|
||||
wb.write('', () => {
|
||||
cbStack.push('b');
|
||||
});
|
||||
wb.write(toBytes('c'), () => {
|
||||
cbStack.push('c');
|
||||
});
|
||||
wb.write(new Uint8Array(0), () => {
|
||||
cbStack.push('d');
|
||||
});
|
||||
wb.write('e', () => {
|
||||
assert.deepEqual(stack.map(val => typeof val === 'string' ? val : fromBytes(val)), ['a', '', 'c', '', 'e']);
|
||||
assert.deepEqual(cbStack, ['a', 'b', 'c', 'd']);
|
||||
@@ -72,13 +94,21 @@ describe('WriteBuffer', () => {
|
||||
});
|
||||
});
|
||||
it('writeSync', done => {
|
||||
wb.write('a', () => { cbStack.push('a'); });
|
||||
wb.write('b', () => { cbStack.push('b'); });
|
||||
wb.write('c', () => { cbStack.push('c'); });
|
||||
wb.write('a', () => {
|
||||
cbStack.push('a');
|
||||
});
|
||||
wb.write('b', () => {
|
||||
cbStack.push('b');
|
||||
});
|
||||
wb.write('c', () => {
|
||||
cbStack.push('c');
|
||||
});
|
||||
wb.writeSync('d');
|
||||
assert.deepEqual(stack, ['a', 'b', 'c', 'd']);
|
||||
assert.deepEqual(cbStack, ['a', 'b', 'c']);
|
||||
wb.write('x', () => { cbStack.push('x'); });
|
||||
wb.write('x', () => {
|
||||
cbStack.push('x');
|
||||
});
|
||||
wb.write('', () => {
|
||||
assert.deepEqual(stack, ['a', 'b', 'c', 'd', 'x', '']);
|
||||
assert.deepEqual(cbStack, ['a', 'b', 'c', 'x']);
|
||||
@@ -107,13 +137,21 @@ describe('WriteBuffer', () => {
|
||||
assert.equal(last, '11'); // 1 + 10 sub calls = 11
|
||||
});
|
||||
it('flushSync processes all pending writes', done => {
|
||||
wb.write('a', () => { cbStack.push('a'); });
|
||||
wb.write('b', () => { cbStack.push('b'); });
|
||||
wb.write('c', () => { cbStack.push('c'); });
|
||||
wb.write('a', () => {
|
||||
cbStack.push('a');
|
||||
});
|
||||
wb.write('b', () => {
|
||||
cbStack.push('b');
|
||||
});
|
||||
wb.write('c', () => {
|
||||
cbStack.push('c');
|
||||
});
|
||||
wb.flushSync();
|
||||
assert.deepEqual(stack, ['a', 'b', 'c']);
|
||||
assert.deepEqual(cbStack, ['a', 'b', 'c']);
|
||||
wb.write('x', () => { cbStack.push('x'); });
|
||||
wb.write('x', () => {
|
||||
cbStack.push('x');
|
||||
});
|
||||
wb.write('', () => {
|
||||
assert.deepEqual(stack, ['a', 'b', 'c', 'x', '']);
|
||||
assert.deepEqual(cbStack, ['a', 'b', 'c', 'x']);
|
||||
|
||||
@@ -244,7 +244,9 @@ export class WriteBuffer extends Disposable {
|
||||
// 2. spawn a promise immediately resolving to `true`
|
||||
// (executed on the same queue, thus properly aligned before continuation happens)
|
||||
result.catch(err => {
|
||||
queueMicrotask(() => {throw err;});
|
||||
queueMicrotask(() => {
|
||||
throw err;
|
||||
});
|
||||
return Promise.resolve(false);
|
||||
}).then(continuation);
|
||||
return;
|
||||
|
||||
@@ -185,7 +185,9 @@ describe('ApcParser', () => {
|
||||
});
|
||||
|
||||
it('should be called once on end(true)', () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => { reports.push(data); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => {
|
||||
reports.push(data); return true;
|
||||
}));
|
||||
parser.start(identifier({intermediates: '+', final: 'p'}));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -195,7 +197,9 @@ describe('ApcParser', () => {
|
||||
assert.deepEqual(reports, ['Here comes the mouse!']);
|
||||
});
|
||||
it('should not be called on end(false)', () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => { reports.push(data); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => {
|
||||
reports.push(data); return true;
|
||||
}));
|
||||
parser.start(identifier({intermediates: '+', final: 'p'}));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -205,8 +209,12 @@ describe('ApcParser', () => {
|
||||
assert.deepEqual(reports, []);
|
||||
});
|
||||
it('should be disposable', () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => { reports.push(['one', data]); return true; }));
|
||||
const dispo = parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => { reports.push(['two', data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => {
|
||||
reports.push(['one', data]); return true;
|
||||
}));
|
||||
const dispo = parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => {
|
||||
reports.push(['two', data]); return true;
|
||||
}));
|
||||
parser.start(identifier({intermediates: '+', final: 'p'}));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -224,8 +232,12 @@ describe('ApcParser', () => {
|
||||
assert.deepEqual(reports, [['two', 'Here comes the mouse!'], ['one', 'some other data']]);
|
||||
});
|
||||
it('should respect return false', () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => { reports.push(['one', data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => { reports.push(['two', data]); return false; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => {
|
||||
reports.push(['one', data]); return true;
|
||||
}));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => {
|
||||
reports.push(['two', data]); return false;
|
||||
}));
|
||||
parser.start(identifier({intermediates: '+', final: 'p'}));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -236,7 +248,9 @@ describe('ApcParser', () => {
|
||||
});
|
||||
it('should work up to payload limit', function(): void {
|
||||
this.timeout(30000);
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => { reports.push(data); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => {
|
||||
reports.push(data); return true;
|
||||
}));
|
||||
parser.start(identifier({intermediates: '+', final: 'p'}));
|
||||
const data = toUtf32('A'.repeat(CHUNK_SIZE));
|
||||
for (let i = 0; i < TEST_PAYLOAD_LIMIT; i += CHUNK_SIZE) {
|
||||
@@ -247,7 +261,9 @@ describe('ApcParser', () => {
|
||||
});
|
||||
it('should abort for payload limit +1', function(): void {
|
||||
this.timeout(30000);
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => { reports.push(data); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(data => {
|
||||
reports.push(data); return true;
|
||||
}));
|
||||
parser.start(identifier({intermediates: '+', final: 'p'}));
|
||||
let data = toUtf32('A'.repeat(CHUNK_SIZE));
|
||||
for (let i = 0; i < TEST_PAYLOAD_LIMIT; i += CHUNK_SIZE) {
|
||||
@@ -408,7 +424,9 @@ describe('ApcParser - async tests', () => {
|
||||
});
|
||||
describe('ApcHandlerFactory', () => {
|
||||
it('should be called once on end(true)', async () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => { reports.push(data); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => {
|
||||
reports.push(data); return true;
|
||||
}));
|
||||
parser.start(identifier({intermediates: '+', final: 'p'}));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -418,7 +436,9 @@ describe('ApcParser - async tests', () => {
|
||||
assert.deepEqual(reports, ['Here comes the mouse!']);
|
||||
});
|
||||
it('should not be called on end(false)', async () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => { reports.push(data); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => {
|
||||
reports.push(data); return true;
|
||||
}));
|
||||
parser.start(identifier({intermediates: '+', final: 'p'}));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -428,8 +448,12 @@ describe('ApcParser - async tests', () => {
|
||||
assert.deepEqual(reports, []);
|
||||
});
|
||||
it('should be disposable', async () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => { reports.push(['one', data]); return true; }));
|
||||
const dispo = parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => { reports.push(['two', data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => {
|
||||
reports.push(['one', data]); return true;
|
||||
}));
|
||||
const dispo = parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => {
|
||||
reports.push(['two', data]); return true;
|
||||
}));
|
||||
parser.start(identifier({intermediates: '+', final: 'p'}));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -447,8 +471,12 @@ describe('ApcParser - async tests', () => {
|
||||
assert.deepEqual(reports, [['two', 'Here comes the mouse!'], ['one', 'some other data']]);
|
||||
});
|
||||
it('should respect return false', async () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => { reports.push(['one', data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => { reports.push(['two', data]); return false; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => {
|
||||
reports.push(['one', data]); return true;
|
||||
}));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new ApcHandler(async data => {
|
||||
reports.push(['two', data]); return false;
|
||||
}));
|
||||
parser.start(identifier({intermediates: '+', final: 'p'}));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
|
||||
@@ -191,7 +191,9 @@ describe('DcsParser', () => {
|
||||
});
|
||||
|
||||
it('should be called once on end(true)', () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => { reports.push([params.toArray(), data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => {
|
||||
reports.push([params.toArray(), data]); return true;
|
||||
}));
|
||||
parser.hook(identifier({intermediates: '+', final: 'p'}), Params.fromArray([1, 2, 3]));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -201,7 +203,9 @@ describe('DcsParser', () => {
|
||||
assert.deepEqual(reports, [[[1, 2, 3], 'Here comes the mouse!']]);
|
||||
});
|
||||
it('should not be called on end(false)', () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => { reports.push([params.toArray(), data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => {
|
||||
reports.push([params.toArray(), data]); return true;
|
||||
}));
|
||||
parser.hook(identifier({intermediates: '+', final: 'p'}), Params.fromArray([1, 2, 3]));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -211,8 +215,12 @@ describe('DcsParser', () => {
|
||||
assert.deepEqual(reports, []);
|
||||
});
|
||||
it('should be disposable', () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => { reports.push(['one', params.toArray(), data]); return true; }));
|
||||
const dispo = parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => { reports.push(['two', params.toArray(), data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => {
|
||||
reports.push(['one', params.toArray(), data]); return true;
|
||||
}));
|
||||
const dispo = parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => {
|
||||
reports.push(['two', params.toArray(), data]); return true;
|
||||
}));
|
||||
parser.hook(identifier({intermediates: '+', final: 'p'}), Params.fromArray([1, 2, 3]));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -230,8 +238,12 @@ describe('DcsParser', () => {
|
||||
assert.deepEqual(reports, [['two', [1, 2, 3], 'Here comes the mouse!'], ['one', [1, 2, 3], 'some other data']]);
|
||||
});
|
||||
it('should respect return false', () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => { reports.push(['one', params.toArray(), data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => { reports.push(['two', params.toArray(), data]); return false; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => {
|
||||
reports.push(['one', params.toArray(), data]); return true;
|
||||
}));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => {
|
||||
reports.push(['two', params.toArray(), data]); return false;
|
||||
}));
|
||||
parser.hook(identifier({intermediates: '+', final: 'p'}), Params.fromArray([1, 2, 3]));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -242,7 +254,9 @@ describe('DcsParser', () => {
|
||||
});
|
||||
it('should work up to payload limit', function(): void {
|
||||
this.timeout(30000);
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => { reports.push([params.toArray(), data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => {
|
||||
reports.push([params.toArray(), data]); return true;
|
||||
}));
|
||||
parser.hook(identifier({intermediates: '+', final: 'p'}), Params.fromArray([1, 2, 3]));
|
||||
const data = toUtf32('A'.repeat(CHUNK_SIZE));
|
||||
for (let i = 0; i < TEST_PAYLOAD_LIMIT; i += CHUNK_SIZE) {
|
||||
@@ -253,7 +267,9 @@ describe('DcsParser', () => {
|
||||
});
|
||||
it('should abort for payload limit +1', function(): void {
|
||||
this.timeout(30000);
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => { reports.push([params.toArray(), data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler((data, params) => {
|
||||
reports.push([params.toArray(), data]); return true;
|
||||
}));
|
||||
parser.hook(identifier({intermediates: '+', final: 'p'}), Params.fromArray([1, 2, 3]));
|
||||
let data = toUtf32('A'.repeat(CHUNK_SIZE));
|
||||
for (let i = 0; i < TEST_PAYLOAD_LIMIT; i += CHUNK_SIZE) {
|
||||
@@ -419,7 +435,9 @@ describe('DcsParser - async tests', () => {
|
||||
});
|
||||
describe('DcsHandlerFactory', () => {
|
||||
it('should be called once on end(true)', async () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => { reports.push([params.toArray(), data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => {
|
||||
reports.push([params.toArray(), data]); return true;
|
||||
}));
|
||||
parser.hook(identifier({intermediates: '+', final: 'p'}), Params.fromArray([1, 2, 3]));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -429,7 +447,9 @@ describe('DcsParser - async tests', () => {
|
||||
assert.deepEqual(reports, [[[1, 2, 3], 'Here comes the mouse!']]);
|
||||
});
|
||||
it('should not be called on end(false)', async () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => { reports.push([params.toArray(), data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => {
|
||||
reports.push([params.toArray(), data]); return true;
|
||||
}));
|
||||
parser.hook(identifier({intermediates: '+', final: 'p'}), Params.fromArray([1, 2, 3]));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -439,8 +459,12 @@ describe('DcsParser - async tests', () => {
|
||||
assert.deepEqual(reports, []);
|
||||
});
|
||||
it('should be disposable', async () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => { reports.push(['one', params.toArray(), data]); return true; }));
|
||||
const dispo = parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => { reports.push(['two', params.toArray(), data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => {
|
||||
reports.push(['one', params.toArray(), data]); return true;
|
||||
}));
|
||||
const dispo = parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => {
|
||||
reports.push(['two', params.toArray(), data]); return true;
|
||||
}));
|
||||
parser.hook(identifier({intermediates: '+', final: 'p'}), Params.fromArray([1, 2, 3]));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -458,8 +482,12 @@ describe('DcsParser - async tests', () => {
|
||||
assert.deepEqual(reports, [['two', [1, 2, 3], 'Here comes the mouse!'], ['one', [1, 2, 3], 'some other data']]);
|
||||
});
|
||||
it('should respect return false', async () => {
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => { reports.push(['one', params.toArray(), data]); return true; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => { reports.push(['two', params.toArray(), data]); return false; }));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => {
|
||||
reports.push(['one', params.toArray(), data]); return true;
|
||||
}));
|
||||
parser.registerHandler(identifier({intermediates: '+', final: 'p'}), new DcsHandler(async (data, params) => {
|
||||
reports.push(['two', params.toArray(), data]); return false;
|
||||
}));
|
||||
parser.hook(identifier({intermediates: '+', final: 'p'}), Params.fromArray([1, 2, 3]));
|
||||
let data = toUtf32('Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
|
||||
@@ -1451,49 +1451,83 @@ describe('EscapeSequenceParser', () => {
|
||||
});
|
||||
describe('ESC custom handlers', () => {
|
||||
it('prevent fallback', () => {
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('default - %G'); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('custom - %G'); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('default - %G'); return true;
|
||||
});
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('custom - %G'); return true;
|
||||
});
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(esc, ['custom - %G']);
|
||||
});
|
||||
it('allow fallback', () => {
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('default - %G'); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('custom - %G'); return false; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('default - %G'); return true;
|
||||
});
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('custom - %G'); return false;
|
||||
});
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(esc, ['custom - %G', 'default - %G']);
|
||||
});
|
||||
it('Multiple custom handlers fallback once', () => {
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('default - %G'); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('custom - %G'); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('custom2 - %G'); return false; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('default - %G'); return true;
|
||||
});
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('custom - %G'); return true;
|
||||
});
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('custom2 - %G'); return false;
|
||||
});
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(esc, ['custom2 - %G', 'custom - %G']);
|
||||
});
|
||||
it('Multiple custom handlers no fallback', () => {
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('default - %G'); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('custom - %G'); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('custom2 - %G'); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('default - %G'); return true;
|
||||
});
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('custom - %G'); return true;
|
||||
});
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('custom2 - %G'); return true;
|
||||
});
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(esc, ['custom2 - %G']);
|
||||
});
|
||||
it('Execution order should go from latest handler down to the original', () => {
|
||||
const order: number[] = [];
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { order.push(1); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { order.push(2); return false; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { order.push(3); return false; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
order.push(1); return true;
|
||||
});
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
order.push(2); return false;
|
||||
});
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
order.push(3); return false;
|
||||
});
|
||||
parse(parser2, '\x1b%G');
|
||||
assert.deepEqual(order, [3, 2, 1]);
|
||||
});
|
||||
it('Dispose should work', () => {
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('default - %G'); return true; });
|
||||
const dispo = parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('custom - %G'); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('default - %G'); return true;
|
||||
});
|
||||
const dispo = parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('custom - %G'); return true;
|
||||
});
|
||||
dispo.dispose();
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(esc, ['default - %G']);
|
||||
});
|
||||
it('Should not corrupt the parser when dispose is called twice', () => {
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('default - %G'); return true; });
|
||||
const dispo = parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => { esc.push('custom - %G'); return true; });
|
||||
parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('default - %G'); return true;
|
||||
});
|
||||
const dispo = parser2.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
esc.push('custom - %G'); return true;
|
||||
});
|
||||
dispo.dispose();
|
||||
dispo.dispose();
|
||||
parse(parser2, INPUT);
|
||||
@@ -1516,16 +1550,24 @@ describe('EscapeSequenceParser', () => {
|
||||
describe('CSI custom handlers', () => {
|
||||
it('Prevent fallback', () => {
|
||||
const csiCustom: [string, ParamsArray, string][] = [];
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csi.push(['m', params.toArray(), '']); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csiCustom.push(['m', params.toArray(), '']); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csi.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csiCustom.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(csi, [], 'Should not fallback to original handler');
|
||||
assert.deepEqual(csiCustom, [['m', [1, 31], ''], ['m', [0], '']]);
|
||||
});
|
||||
it('Allow fallback', () => {
|
||||
const csiCustom: [string, ParamsArray, string][] = [];
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csi.push(['m', params.toArray(), '']); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csiCustom.push(['m', params.toArray(), '']); return false; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csi.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csiCustom.push(['m', params.toArray(), '']); return false;
|
||||
});
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(csi, [['m', [1, 31], ''], ['m', [0], '']], 'Should fallback to original handler');
|
||||
assert.deepEqual(csiCustom, [['m', [1, 31], ''], ['m', [0], '']]);
|
||||
@@ -1533,9 +1575,15 @@ describe('EscapeSequenceParser', () => {
|
||||
it('Multiple custom handlers fallback once', () => {
|
||||
const csiCustom: [string, ParamsArray, string][] = [];
|
||||
const csiCustom2: [string, ParamsArray, string][] = [];
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csi.push(['m', params.toArray(), '']); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csiCustom.push(['m', params.toArray(), '']); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csiCustom2.push(['m', params.toArray(), '']); return false; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csi.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csiCustom.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csiCustom2.push(['m', params.toArray(), '']); return false;
|
||||
});
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(csi, [], 'Should not fallback to original handler');
|
||||
assert.deepEqual(csiCustom, [['m', [1, 31], ''], ['m', [0], '']]);
|
||||
@@ -1544,9 +1592,15 @@ describe('EscapeSequenceParser', () => {
|
||||
it('Multiple custom handlers no fallback', () => {
|
||||
const csiCustom: [string, ParamsArray, string][] = [];
|
||||
const csiCustom2: [string, ParamsArray, string][] = [];
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csi.push(['m', params.toArray(), '']); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csiCustom.push(['m', params.toArray(), '']); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csiCustom2.push(['m', params.toArray(), '']); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csi.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csiCustom.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csiCustom2.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(csi, [], 'Should not fallback to original handler');
|
||||
assert.deepEqual(csiCustom, [], 'Should not fallback once');
|
||||
@@ -1554,16 +1608,26 @@ describe('EscapeSequenceParser', () => {
|
||||
});
|
||||
it('Execution order should go from latest handler down to the original', () => {
|
||||
const order: number[] = [];
|
||||
parser2.registerCsiHandler({ final: 'm' }, () => { order.push(1); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, () => { order.push(2); return false; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, () => { order.push(3); return false; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, () => {
|
||||
order.push(1); return true;
|
||||
});
|
||||
parser2.registerCsiHandler({ final: 'm' }, () => {
|
||||
order.push(2); return false;
|
||||
});
|
||||
parser2.registerCsiHandler({ final: 'm' }, () => {
|
||||
order.push(3); return false;
|
||||
});
|
||||
parse(parser2, '\x1b[0m');
|
||||
assert.deepEqual(order, [3, 2, 1]);
|
||||
});
|
||||
it('Dispose should work', () => {
|
||||
const csiCustom: [string, ParamsArray, string][] = [];
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csi.push(['m', params.toArray(), '']); return true; });
|
||||
const customHandler = parser2.registerCsiHandler({ final: 'm' }, params => { csiCustom.push(['m', params.toArray(), '']); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csi.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
const customHandler = parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csiCustom.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
customHandler.dispose();
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(csi, [['m', [1, 31], ''], ['m', [0], '']]);
|
||||
@@ -1571,8 +1635,12 @@ describe('EscapeSequenceParser', () => {
|
||||
});
|
||||
it('Should not corrupt the parser when dispose is called twice', () => {
|
||||
const csiCustom: [string, ParamsArray, string][] = [];
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => { csi.push(['m', params.toArray(), '']); return true; });
|
||||
const customHandler = parser2.registerCsiHandler({ final: 'm' }, params => { csiCustom.push(['m', params.toArray(), '']); return true; });
|
||||
parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csi.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
const customHandler = parser2.registerCsiHandler({ final: 'm' }, params => {
|
||||
csiCustom.push(['m', params.toArray(), '']); return true;
|
||||
});
|
||||
customHandler.dispose();
|
||||
customHandler.dispose();
|
||||
parse(parser2, INPUT);
|
||||
@@ -1613,16 +1681,24 @@ describe('EscapeSequenceParser', () => {
|
||||
describe('OSC custom handlers', () => {
|
||||
it('Prevent fallback', () => {
|
||||
const oscCustom: [number, string][] = [];
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { osc.push([1, data]); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { oscCustom.push([1, data]); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
osc.push([1, data]); return true;
|
||||
}));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
oscCustom.push([1, data]); return true;
|
||||
}));
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(osc, [], 'Should not fallback to original handler');
|
||||
assert.deepEqual(oscCustom, [[1, 'foo=bar']]);
|
||||
});
|
||||
it('Allow fallback', () => {
|
||||
const oscCustom: [number, string][] = [];
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { osc.push([1, data]); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { oscCustom.push([1, data]); return false; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
osc.push([1, data]); return true;
|
||||
}));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
oscCustom.push([1, data]); return false;
|
||||
}));
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(osc, [[1, 'foo=bar']], 'Should fallback to original handler');
|
||||
assert.deepEqual(oscCustom, [[1, 'foo=bar']]);
|
||||
@@ -1630,9 +1706,15 @@ describe('EscapeSequenceParser', () => {
|
||||
it('Multiple custom handlers fallback once', () => {
|
||||
const oscCustom: [number, string][] = [];
|
||||
const oscCustom2: [number, string][] = [];
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { osc.push([1, data]); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { oscCustom.push([1, data]); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { oscCustom2.push([1, data]); return false; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
osc.push([1, data]); return true;
|
||||
}));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
oscCustom.push([1, data]); return true;
|
||||
}));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
oscCustom2.push([1, data]); return false;
|
||||
}));
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(osc, [], 'Should not fallback to original handler');
|
||||
assert.deepEqual(oscCustom, [[1, 'foo=bar']]);
|
||||
@@ -1641,9 +1723,15 @@ describe('EscapeSequenceParser', () => {
|
||||
it('Multiple custom handlers no fallback', () => {
|
||||
const oscCustom: [number, string][] = [];
|
||||
const oscCustom2: [number, string][] = [];
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { osc.push([1, data]); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { oscCustom.push([1, data]); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { oscCustom2.push([1, data]); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
osc.push([1, data]); return true;
|
||||
}));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
oscCustom.push([1, data]); return true;
|
||||
}));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
oscCustom2.push([1, data]); return true;
|
||||
}));
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(osc, [], 'Should not fallback to original handler');
|
||||
assert.deepEqual(oscCustom, [], 'Should not fallback once');
|
||||
@@ -1651,16 +1739,26 @@ describe('EscapeSequenceParser', () => {
|
||||
});
|
||||
it('Execution order should go from latest handler down to the original', () => {
|
||||
const order: number[] = [];
|
||||
parser2.registerOscHandler(1, new OscHandler(() => { order.push(1); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(() => { order.push(2); return false; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(() => { order.push(3); return false; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(() => {
|
||||
order.push(1); return true;
|
||||
}));
|
||||
parser2.registerOscHandler(1, new OscHandler(() => {
|
||||
order.push(2); return false;
|
||||
}));
|
||||
parser2.registerOscHandler(1, new OscHandler(() => {
|
||||
order.push(3); return false;
|
||||
}));
|
||||
parse(parser2, '\x1b]1;foo=bar\x1b\\');
|
||||
assert.deepEqual(order, [3, 2, 1]);
|
||||
});
|
||||
it('Dispose should work', () => {
|
||||
const oscCustom: [number, string][] = [];
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { osc.push([1, data]); return true; }));
|
||||
const customHandler = parser2.registerOscHandler(1, new OscHandler(data => { oscCustom.push([1, data]); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
osc.push([1, data]); return true;
|
||||
}));
|
||||
const customHandler = parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
oscCustom.push([1, data]); return true;
|
||||
}));
|
||||
customHandler.dispose();
|
||||
parse(parser2, INPUT);
|
||||
assert.deepEqual(osc, [[1, 'foo=bar']]);
|
||||
@@ -1668,8 +1766,12 @@ describe('EscapeSequenceParser', () => {
|
||||
});
|
||||
it('Should not corrupt the parser when dispose is called twice', () => {
|
||||
const oscCustom: [number, string][] = [];
|
||||
parser2.registerOscHandler(1, new OscHandler(data => { osc.push([1, data]); return true; }));
|
||||
const customHandler = parser2.registerOscHandler(1, new OscHandler(data => { oscCustom.push([1, data]); return true; }));
|
||||
parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
osc.push([1, data]); return true;
|
||||
}));
|
||||
const customHandler = parser2.registerOscHandler(1, new OscHandler(data => {
|
||||
oscCustom.push([1, data]); return true;
|
||||
}));
|
||||
customHandler.dispose();
|
||||
customHandler.dispose();
|
||||
parse(parser2, INPUT);
|
||||
@@ -1712,54 +1814,88 @@ describe('EscapeSequenceParser', () => {
|
||||
const DCS_INPUT = '\x1bP1;2;3+pabc\x1b\\';
|
||||
it('Prevent fallback', () => {
|
||||
const dcsCustom: [string, (number | number[])[], string][] = [];
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['A', params.toArray(), data]); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['B', params.toArray(), data]); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['A', params.toArray(), data]); return true;
|
||||
}));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['B', params.toArray(), data]); return true;
|
||||
}));
|
||||
parse(parser2, DCS_INPUT);
|
||||
assert.deepEqual(dcsCustom, [['B', [1, 2, 3], 'abc']]);
|
||||
});
|
||||
it('Allow fallback', () => {
|
||||
const dcsCustom: [string, (number | number[])[], string][] = [];
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['A', params.toArray(), data]); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['B', params.toArray(), data]); return false; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['A', params.toArray(), data]); return true;
|
||||
}));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['B', params.toArray(), data]); return false;
|
||||
}));
|
||||
parse(parser2, DCS_INPUT);
|
||||
assert.deepEqual(dcsCustom, [['B', [1, 2, 3], 'abc'], ['A', [1, 2, 3], 'abc']]);
|
||||
});
|
||||
it('Multiple custom handlers fallback once', () => {
|
||||
const dcsCustom: [string, (number | number[])[], string][] = [];
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['A', params.toArray(), data]); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['B', params.toArray(), data]); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['C', params.toArray(), data]); return false; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['A', params.toArray(), data]); return true;
|
||||
}));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['B', params.toArray(), data]); return true;
|
||||
}));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['C', params.toArray(), data]); return false;
|
||||
}));
|
||||
parse(parser2, DCS_INPUT);
|
||||
assert.deepEqual(dcsCustom, [['C', [1, 2, 3], 'abc'], ['B', [1, 2, 3], 'abc']]);
|
||||
});
|
||||
it('Multiple custom handlers no fallback', () => {
|
||||
const dcsCustom: [string, (number | number[])[], string][] = [];
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['A', params.toArray(), data]); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['B', params.toArray(), data]); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['C', params.toArray(), data]); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['A', params.toArray(), data]); return true;
|
||||
}));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['B', params.toArray(), data]); return true;
|
||||
}));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['C', params.toArray(), data]); return true;
|
||||
}));
|
||||
parse(parser2, DCS_INPUT);
|
||||
assert.deepEqual(dcsCustom, [['C', [1, 2, 3], 'abc']]);
|
||||
});
|
||||
it('Execution order should go from latest handler down to the original', () => {
|
||||
const order: number[] = [];
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler(() => { order.push(1); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler(() => { order.push(2); return false; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler(() => { order.push(3); return false; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler(() => {
|
||||
order.push(1); return true;
|
||||
}));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler(() => {
|
||||
order.push(2); return false;
|
||||
}));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler(() => {
|
||||
order.push(3); return false;
|
||||
}));
|
||||
parse(parser2, DCS_INPUT);
|
||||
assert.deepEqual(order, [3, 2, 1]);
|
||||
});
|
||||
it('Dispose should work', () => {
|
||||
const dcsCustom: [string, (number | number[])[], string][] = [];
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['A', params.toArray(), data]); return true; }));
|
||||
const dispo = parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['B', params.toArray(), data]); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['A', params.toArray(), data]); return true;
|
||||
}));
|
||||
const dispo = parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['B', params.toArray(), data]); return true;
|
||||
}));
|
||||
dispo.dispose();
|
||||
parse(parser2, DCS_INPUT);
|
||||
assert.deepEqual(dcsCustom, [['A', [1, 2, 3], 'abc']]);
|
||||
});
|
||||
it('Should not corrupt the parser when dispose is called twice', () => {
|
||||
const dcsCustom: [string, (number | number[])[], string][] = [];
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['A', params.toArray(), data]); return true; }));
|
||||
const dispo = parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => { dcsCustom.push(['B', params.toArray(), data]); return true; }));
|
||||
parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['A', params.toArray(), data]); return true;
|
||||
}));
|
||||
const dispo = parser2.registerDcsHandler({ intermediates: '+', final: 'p' }, new DcsHandler((data, params) => {
|
||||
dcsCustom.push(['B', params.toArray(), data]); return true;
|
||||
}));
|
||||
dispo.dispose();
|
||||
dispo.dispose();
|
||||
parse(parser2, DCS_INPUT);
|
||||
@@ -1801,54 +1937,88 @@ describe('EscapeSequenceParser', () => {
|
||||
const APC_INPUT = '\x1b_+pabc\x1b\\';
|
||||
it('Prevent fallback', () => {
|
||||
const apcCustom: [string, string][] = [];
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['A', data]); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['B', data]); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['A', data]); return true;
|
||||
}));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['B', data]); return true;
|
||||
}));
|
||||
parse(parser2, APC_INPUT);
|
||||
assert.deepEqual(apcCustom, [['B', 'abc']]);
|
||||
});
|
||||
it('Allow fallback', () => {
|
||||
const apcCustom: [string, string][] = [];
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['A', data]); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['B', data]); return false; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['A', data]); return true;
|
||||
}));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['B', data]); return false;
|
||||
}));
|
||||
parse(parser2, APC_INPUT);
|
||||
assert.deepEqual(apcCustom, [['B', 'abc'], ['A', 'abc']]);
|
||||
});
|
||||
it('Multiple custom handlers fallback once', () => {
|
||||
const apcCustom: [string, string][] = [];
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['A', data]); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['B', data]); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['C', data]); return false; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['A', data]); return true;
|
||||
}));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['B', data]); return true;
|
||||
}));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['C', data]); return false;
|
||||
}));
|
||||
parse(parser2, APC_INPUT);
|
||||
assert.deepEqual(apcCustom, [['C', 'abc'], ['B', 'abc']]);
|
||||
});
|
||||
it('Multiple custom handlers no fallback', () => {
|
||||
const apcCustom: [string, string][] = [];
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['A', data]); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['B', data]); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['C', data]); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['A', data]); return true;
|
||||
}));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['B', data]); return true;
|
||||
}));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['C', data]); return true;
|
||||
}));
|
||||
parse(parser2, APC_INPUT);
|
||||
assert.deepEqual(apcCustom, [['C', 'abc']]);
|
||||
});
|
||||
it('Execution order should go from latest handler down to the original', () => {
|
||||
const order: number[] = [];
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(() => { order.push(1); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(() => { order.push(2); return false; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(() => { order.push(3); return false; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(() => {
|
||||
order.push(1); return true;
|
||||
}));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(() => {
|
||||
order.push(2); return false;
|
||||
}));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(() => {
|
||||
order.push(3); return false;
|
||||
}));
|
||||
parse(parser2, APC_INPUT);
|
||||
assert.deepEqual(order, [3, 2, 1]);
|
||||
});
|
||||
it('Dispose should work', () => {
|
||||
const apcCustom: [string, string][] = [];
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['A', data]); return true; }));
|
||||
const dispo = parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['B', data]); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['A', data]); return true;
|
||||
}));
|
||||
const dispo = parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['B', data]); return true;
|
||||
}));
|
||||
dispo.dispose();
|
||||
parse(parser2, APC_INPUT);
|
||||
assert.deepEqual(apcCustom, [['A', 'abc']]);
|
||||
});
|
||||
it('Should not corrupt the parser when dispose is called twice', () => {
|
||||
const apcCustom: [string, string][] = [];
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['A', data]); return true; }));
|
||||
const dispo = parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => { apcCustom.push(['B', data]); return true; }));
|
||||
parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['A', data]); return true;
|
||||
}));
|
||||
const dispo = parser2.registerApcHandler({ intermediates: '+', final: 'p' }, new ApcHandler(data => {
|
||||
apcCustom.push(['B', data]); return true;
|
||||
}));
|
||||
dispo.dispose();
|
||||
dispo.dispose();
|
||||
parse(parser2, APC_INPUT);
|
||||
@@ -1884,44 +2054,74 @@ describe('EscapeSequenceParser', () => {
|
||||
const c = String.fromCharCode(i);
|
||||
assert.equal(parser.identToString(parser.identifier({ prefix: c, final: 'z' })), c + 'z');
|
||||
}
|
||||
assert.throws(() => { parser.identifier({ prefix: '\x3b', final: 'z' }); }, 'prefix must be in range 0x3c .. 0x3f');
|
||||
assert.throws(() => { parser.identifier({ prefix: '\x40', final: 'z' }); }, 'prefix must be in range 0x3c .. 0x3f');
|
||||
assert.throws(() => { parser.identifier({ prefix: '??', final: 'z' }); }, 'only one byte as prefix supported');
|
||||
assert.throws(() => {
|
||||
parser.identifier({ prefix: '\x3b', final: 'z' });
|
||||
}, 'prefix must be in range 0x3c .. 0x3f');
|
||||
assert.throws(() => {
|
||||
parser.identifier({ prefix: '\x40', final: 'z' });
|
||||
}, 'prefix must be in range 0x3c .. 0x3f');
|
||||
assert.throws(() => {
|
||||
parser.identifier({ prefix: '??', final: 'z' });
|
||||
}, 'only one byte as prefix supported');
|
||||
});
|
||||
it('intermediates range 0x20 .. 0x2f, up to two bytes', () => {
|
||||
for (let i = 0x20; i <= 0x2f; ++i) {
|
||||
const c = String.fromCharCode(i);
|
||||
assert.equal(parser.identToString(parser.identifier({ intermediates: c + c, final: 'z' })), c + c + 'z');
|
||||
}
|
||||
assert.throws(() => { parser.identifier({ intermediates: '\x1f', final: 'z' }); }, 'intermediate must be in range 0x20 .. 0x2f');
|
||||
assert.throws(() => { parser.identifier({ intermediates: '\x30', final: 'z' }); }, 'intermediate must be in range 0x20 .. 0x2f');
|
||||
assert.throws(() => { parser.identifier({ intermediates: '!!!', final: 'z' }); }, 'only two bytes as intermediates are supported');
|
||||
assert.throws(() => {
|
||||
parser.identifier({ intermediates: '\x1f', final: 'z' });
|
||||
}, 'intermediate must be in range 0x20 .. 0x2f');
|
||||
assert.throws(() => {
|
||||
parser.identifier({ intermediates: '\x30', final: 'z' });
|
||||
}, 'intermediate must be in range 0x20 .. 0x2f');
|
||||
assert.throws(() => {
|
||||
parser.identifier({ intermediates: '!!!', final: 'z' });
|
||||
}, 'only two bytes as intermediates are supported');
|
||||
});
|
||||
it('final CSI/DCS range 0x40 .. 0x7e (default), one byte', () => {
|
||||
for (let i = 0x40; i <= 0x7e; ++i) {
|
||||
const c = String.fromCharCode(i);
|
||||
assert.equal(parser.identToString(parser.identifier({ final: c })), c);
|
||||
}
|
||||
assert.throws(() => { parser.identifier({ final: '\x3f' }); }, 'final must be in range 64 .. 126');
|
||||
assert.throws(() => { parser.identifier({ final: '\x7f' }); }, 'final must be in range 64 .. 126');
|
||||
assert.throws(() => { parser.identifier({ final: 'zz' }); }, 'final must be a single byte');
|
||||
assert.throws(() => {
|
||||
parser.identifier({ final: '\x3f' });
|
||||
}, 'final must be in range 64 .. 126');
|
||||
assert.throws(() => {
|
||||
parser.identifier({ final: '\x7f' });
|
||||
}, 'final must be in range 64 .. 126');
|
||||
assert.throws(() => {
|
||||
parser.identifier({ final: 'zz' });
|
||||
}, 'final must be a single byte');
|
||||
});
|
||||
it('final ESC + APC range 0x30 .. 0x7e, one byte', () => {
|
||||
for (let i = 0x30; i <= 0x7e; ++i) {
|
||||
const final = String.fromCharCode(i);
|
||||
let handler: IDisposable | undefined;
|
||||
assert.doesNotThrow(() => { handler = parser.registerEscHandler({ final }, () => true); }, 'final must be in range 48 .. 126');
|
||||
assert.doesNotThrow(() => {
|
||||
handler = parser.registerEscHandler({ final }, () => true);
|
||||
}, 'final must be in range 48 .. 126');
|
||||
if (handler) handler.dispose();
|
||||
assert.doesNotThrow(
|
||||
() => { handler = parser.registerApcHandler({ final }, {start: () => {}, put: ()=>{}, end: ()=>true}); },
|
||||
() => {
|
||||
handler = parser.registerApcHandler({ final }, {start: () => {}, put: ()=>{}, end: ()=>true});
|
||||
},
|
||||
'final must be in range 48 .. 126'
|
||||
);
|
||||
if (handler) handler.dispose();
|
||||
}
|
||||
assert.throws(() => { parser.registerEscHandler({ final: '\x2f' }, () => true); }, 'final must be in range 48 .. 126');
|
||||
assert.throws(() => { parser.registerEscHandler({ final: '\x7f' }, () => true); }, 'final must be in range 48 .. 126');
|
||||
assert.throws(() => { parser.registerApcHandler({ final: '\x2f' }, {start: () => {}, put: ()=>{}, end: ()=>true}); }, 'final must be in range 48 .. 126');
|
||||
assert.throws(() => { parser.registerApcHandler({ final: '\x7f' }, {start: () => {}, put: ()=>{}, end: ()=>true}); }, 'final must be in range 48 .. 126');
|
||||
assert.throws(() => {
|
||||
parser.registerEscHandler({ final: '\x2f' }, () => true);
|
||||
}, 'final must be in range 48 .. 126');
|
||||
assert.throws(() => {
|
||||
parser.registerEscHandler({ final: '\x7f' }, () => true);
|
||||
}, 'final must be in range 48 .. 126');
|
||||
assert.throws(() => {
|
||||
parser.registerApcHandler({ final: '\x2f' }, {start: () => {}, put: ()=>{}, end: ()=>true});
|
||||
}, 'final must be in range 48 .. 126');
|
||||
assert.throws(() => {
|
||||
parser.registerApcHandler({ final: '\x7f' }, {start: () => {}, put: ()=>{}, end: ()=>true});
|
||||
}, 'final must be in range 48 .. 126');
|
||||
});
|
||||
it('id calculation - should stacking prefix -> intermediate -> final', () => {
|
||||
assert.equal(parser.identToString(parser.identifier({ final: 'z' })), 'z');
|
||||
@@ -1934,9 +2134,15 @@ describe('EscapeSequenceParser', () => {
|
||||
describe('identifier invocation', () => {
|
||||
it('ESC', () => {
|
||||
const callstack: string[] = [];
|
||||
const h1 = parser.registerEscHandler({ final: 'z' }, () => { callstack.push('z'); return true; });
|
||||
const h2 = parser.registerEscHandler({ intermediates: '!', final: 'z' }, () => { callstack.push('!z'); return true; });
|
||||
const h3 = parser.registerEscHandler({ intermediates: '!!', final: 'z' }, () => { callstack.push('!!z'); return true; });
|
||||
const h1 = parser.registerEscHandler({ final: 'z' }, () => {
|
||||
callstack.push('z'); return true;
|
||||
});
|
||||
const h2 = parser.registerEscHandler({ intermediates: '!', final: 'z' }, () => {
|
||||
callstack.push('!z'); return true;
|
||||
});
|
||||
const h3 = parser.registerEscHandler({ intermediates: '!!', final: 'z' }, () => {
|
||||
callstack.push('!!z'); return true;
|
||||
});
|
||||
parse(parser, '\x1bz\x1b!z\x1b!!z');
|
||||
h1.dispose();
|
||||
h2.dispose();
|
||||
@@ -1946,12 +2152,24 @@ describe('EscapeSequenceParser', () => {
|
||||
});
|
||||
it('CSI', () => {
|
||||
const callstack: any[] = [];
|
||||
const h1 = parser.registerCsiHandler({ final: 'z' }, params => { callstack.push(['z', params.toArray()]); return true; });
|
||||
const h2 = parser.registerCsiHandler({ intermediates: '!', final: 'z' }, params => { callstack.push(['!z', params.toArray()]); return true; });
|
||||
const h3 = parser.registerCsiHandler({ intermediates: '!!', final: 'z' }, params => { callstack.push(['!!z', params.toArray()]); return true; });
|
||||
const h4 = parser.registerCsiHandler({ prefix: '?', final: 'z' }, params => { callstack.push(['?z', params.toArray()]); return true; });
|
||||
const h5 = parser.registerCsiHandler({ prefix: '?', intermediates: '!', final: 'z' }, params => { callstack.push(['?!z', params.toArray()]); return true; });
|
||||
const h6 = parser.registerCsiHandler({ prefix: '?', intermediates: '!!', final: 'z' }, params => { callstack.push(['?!!z', params.toArray()]); return true; });
|
||||
const h1 = parser.registerCsiHandler({ final: 'z' }, params => {
|
||||
callstack.push(['z', params.toArray()]); return true;
|
||||
});
|
||||
const h2 = parser.registerCsiHandler({ intermediates: '!', final: 'z' }, params => {
|
||||
callstack.push(['!z', params.toArray()]); return true;
|
||||
});
|
||||
const h3 = parser.registerCsiHandler({ intermediates: '!!', final: 'z' }, params => {
|
||||
callstack.push(['!!z', params.toArray()]); return true;
|
||||
});
|
||||
const h4 = parser.registerCsiHandler({ prefix: '?', final: 'z' }, params => {
|
||||
callstack.push(['?z', params.toArray()]); return true;
|
||||
});
|
||||
const h5 = parser.registerCsiHandler({ prefix: '?', intermediates: '!', final: 'z' }, params => {
|
||||
callstack.push(['?!z', params.toArray()]); return true;
|
||||
});
|
||||
const h6 = parser.registerCsiHandler({ prefix: '?', intermediates: '!!', final: 'z' }, params => {
|
||||
callstack.push(['?!!z', params.toArray()]); return true;
|
||||
});
|
||||
parse(parser, '\x1b[1;z\x1b[1;!z\x1b[1;!!z\x1b[?1;z\x1b[?1;!z\x1b[?1;!!z');
|
||||
h1.dispose();
|
||||
h2.dispose();
|
||||
@@ -1967,12 +2185,24 @@ describe('EscapeSequenceParser', () => {
|
||||
});
|
||||
it('DCS', () => {
|
||||
const callstack: any[] = [];
|
||||
const h1 = parser.registerDcsHandler({ final: 'z' }, new DcsHandler((data, params) => { callstack.push(['z', params.toArray(), data]); return true; }));
|
||||
const h2 = parser.registerDcsHandler({ intermediates: '!', final: 'z' }, new DcsHandler((data, params) => { callstack.push(['!z', params.toArray(), data]); return true; }));
|
||||
const h3 = parser.registerDcsHandler({ intermediates: '!!', final: 'z' }, new DcsHandler((data, params) => { callstack.push(['!!z', params.toArray(), data]); return true; }));
|
||||
const h4 = parser.registerDcsHandler({ prefix: '?', final: 'z' }, new DcsHandler((data, params) => { callstack.push(['?z', params.toArray(), data]); return true; }));
|
||||
const h5 = parser.registerDcsHandler({ prefix: '?', intermediates: '!', final: 'z' }, new DcsHandler((data, params) => { callstack.push(['?!z', params.toArray(), data]); return true; }));
|
||||
const h6 = parser.registerDcsHandler({ prefix: '?', intermediates: '!!', final: 'z' }, new DcsHandler((data, params) => { callstack.push(['?!!z', params.toArray(), data]); return true; }));
|
||||
const h1 = parser.registerDcsHandler({ final: 'z' }, new DcsHandler((data, params) => {
|
||||
callstack.push(['z', params.toArray(), data]); return true;
|
||||
}));
|
||||
const h2 = parser.registerDcsHandler({ intermediates: '!', final: 'z' }, new DcsHandler((data, params) => {
|
||||
callstack.push(['!z', params.toArray(), data]); return true;
|
||||
}));
|
||||
const h3 = parser.registerDcsHandler({ intermediates: '!!', final: 'z' }, new DcsHandler((data, params) => {
|
||||
callstack.push(['!!z', params.toArray(), data]); return true;
|
||||
}));
|
||||
const h4 = parser.registerDcsHandler({ prefix: '?', final: 'z' }, new DcsHandler((data, params) => {
|
||||
callstack.push(['?z', params.toArray(), data]); return true;
|
||||
}));
|
||||
const h5 = parser.registerDcsHandler({ prefix: '?', intermediates: '!', final: 'z' }, new DcsHandler((data, params) => {
|
||||
callstack.push(['?!z', params.toArray(), data]); return true;
|
||||
}));
|
||||
const h6 = parser.registerDcsHandler({ prefix: '?', intermediates: '!!', final: 'z' }, new DcsHandler((data, params) => {
|
||||
callstack.push(['?!!z', params.toArray(), data]); return true;
|
||||
}));
|
||||
parse(parser, '\x1bP1;zAB\x1b\\\x1bP1;!zAB\x1b\\\x1bP1;!!zAB\x1b\\\x1bP?1;zAB\x1b\\\x1bP?1;!zAB\x1b\\\x1bP?1;!!zAB\x1b\\');
|
||||
h1.dispose();
|
||||
h2.dispose();
|
||||
@@ -1995,9 +2225,15 @@ describe('EscapeSequenceParser', () => {
|
||||
});
|
||||
it('APC', () => {
|
||||
const callstack: any[] = [];
|
||||
const h1 = parser.registerApcHandler({ final: 'z' }, new ApcHandler(data => { callstack.push(['z', data]); return true; }));
|
||||
const h2 = parser.registerApcHandler({ intermediates: '!', final: 'z' }, new ApcHandler(data => { callstack.push(['!z', data]); return true; }));
|
||||
const h3 = parser.registerApcHandler({ intermediates: '!!', final: 'z' }, new ApcHandler(data => { callstack.push(['!!z', data]); return true; }));
|
||||
const h1 = parser.registerApcHandler({ final: 'z' }, new ApcHandler(data => {
|
||||
callstack.push(['z', data]); return true;
|
||||
}));
|
||||
const h2 = parser.registerApcHandler({ intermediates: '!', final: 'z' }, new ApcHandler(data => {
|
||||
callstack.push(['!z', data]); return true;
|
||||
}));
|
||||
const h3 = parser.registerApcHandler({ intermediates: '!!', final: 'z' }, new ApcHandler(data => {
|
||||
callstack.push(['!!z', data]); return true;
|
||||
}));
|
||||
parse(parser, '\x1b_zAB\x1b\\\x1b_!zAB\x1b\\\x1b_!!zAB\x1b\\');
|
||||
h1.dispose();
|
||||
h2.dispose();
|
||||
@@ -2106,14 +2342,30 @@ describe('EscapeSequenceParser - async', () => {
|
||||
}
|
||||
callstack.push(['PRINT', result]);
|
||||
});
|
||||
parser.registerCsiHandler({ final: 'm' }, params => { callstack.push(['SGR', params.toArray()]); return true; });
|
||||
parser.registerEscHandler({ intermediates: '%', final: 'G' }, () => { callstack.push(['ESC %G']); return true; });
|
||||
parser.registerEscHandler({ final: 'E' }, () => { callstack.push(['ESC E']); return true; });
|
||||
parser.setExecuteHandler('\r', () => { callstack.push(['EXE \r']); return true; });
|
||||
parser.setExecuteHandler('\n', () => { callstack.push(['EXE \n']); return true; });
|
||||
parser.registerOscHandler(1, new OscHandler(data => { callstack.push(['OSC 1', data]); return true; }));
|
||||
parser.registerDcsHandler({ final: 'a' }, new DcsHandler((data, params) => { callstack.push(['DCS a', [data, params.toArray()]]); return true; }));
|
||||
parser.registerApcHandler({ final: 'X' }, new ApcHandler(data => { callstack.push(['APC X', data]); return true; }));
|
||||
parser.registerCsiHandler({ final: 'm' }, params => {
|
||||
callstack.push(['SGR', params.toArray()]); return true;
|
||||
});
|
||||
parser.registerEscHandler({ intermediates: '%', final: 'G' }, () => {
|
||||
callstack.push(['ESC %G']); return true;
|
||||
});
|
||||
parser.registerEscHandler({ final: 'E' }, () => {
|
||||
callstack.push(['ESC E']); return true;
|
||||
});
|
||||
parser.setExecuteHandler('\r', () => {
|
||||
callstack.push(['EXE \r']); return true;
|
||||
});
|
||||
parser.setExecuteHandler('\n', () => {
|
||||
callstack.push(['EXE \n']); return true;
|
||||
});
|
||||
parser.registerOscHandler(1, new OscHandler(data => {
|
||||
callstack.push(['OSC 1', data]); return true;
|
||||
}));
|
||||
parser.registerDcsHandler({ final: 'a' }, new DcsHandler((data, params) => {
|
||||
callstack.push(['DCS a', [data, params.toArray()]]); return true;
|
||||
}));
|
||||
parser.registerApcHandler({ final: 'X' }, new ApcHandler(data => {
|
||||
callstack.push(['APC X', data]); return true;
|
||||
}));
|
||||
});
|
||||
|
||||
it('sync handlers keep being parsed in sync mode', () => {
|
||||
@@ -2142,14 +2394,30 @@ describe('EscapeSequenceParser - async', () => {
|
||||
}
|
||||
callstack.push(['PRINT', result]);
|
||||
});
|
||||
parser.registerCsiHandler({ final: 'm' }, async params => { callstack.push(['SGR', params.toArray()]); return true; });
|
||||
parser.registerEscHandler({ intermediates: '%', final: 'G' }, async () => { callstack.push(['ESC %G']); return true; });
|
||||
parser.registerEscHandler({ final: 'E' }, async () => { callstack.push(['ESC E']); return true; });
|
||||
parser.setExecuteHandler('\r', () => { callstack.push(['EXE \r']); return true; });
|
||||
parser.setExecuteHandler('\n', () => { callstack.push(['EXE \n']); return true; });
|
||||
parser.registerOscHandler(1, new OscHandler(async data => { callstack.push(['OSC 1', data]); return true; }));
|
||||
parser.registerDcsHandler({ final: 'a' }, new DcsHandler(async (data, params) => { callstack.push(['DCS a', [data, params.toArray()]]); return true; }));
|
||||
parser.registerApcHandler({ final: 'X' }, new ApcHandler(async data => { callstack.push(['APC X', data]); return true; }));
|
||||
parser.registerCsiHandler({ final: 'm' }, async params => {
|
||||
callstack.push(['SGR', params.toArray()]); return true;
|
||||
});
|
||||
parser.registerEscHandler({ intermediates: '%', final: 'G' }, async () => {
|
||||
callstack.push(['ESC %G']); return true;
|
||||
});
|
||||
parser.registerEscHandler({ final: 'E' }, async () => {
|
||||
callstack.push(['ESC E']); return true;
|
||||
});
|
||||
parser.setExecuteHandler('\r', () => {
|
||||
callstack.push(['EXE \r']); return true;
|
||||
});
|
||||
parser.setExecuteHandler('\n', () => {
|
||||
callstack.push(['EXE \n']); return true;
|
||||
});
|
||||
parser.registerOscHandler(1, new OscHandler(async data => {
|
||||
callstack.push(['OSC 1', data]); return true;
|
||||
}));
|
||||
parser.registerDcsHandler({ final: 'a' }, new DcsHandler(async (data, params) => {
|
||||
callstack.push(['DCS a', [data, params.toArray()]]); return true;
|
||||
}));
|
||||
parser.registerApcHandler({ final: 'X' }, new ApcHandler(async data => {
|
||||
callstack.push(['APC X', data]); return true;
|
||||
}));
|
||||
});
|
||||
|
||||
it('sync parse call does not work anymore', () => {
|
||||
@@ -2239,7 +2507,9 @@ describe('EscapeSequenceParser - async', () => {
|
||||
});
|
||||
it('multiple async SGR handlers', async () => {
|
||||
// register with fallback
|
||||
const SGR2 = parser.registerCsiHandler({ final: 'm' }, async params => { callstack.push(['2# SGR', params.toArray()]); return false; });
|
||||
const SGR2 = parser.registerCsiHandler({ final: 'm' }, async params => {
|
||||
callstack.push(['2# SGR', params.toArray()]); return false;
|
||||
});
|
||||
await parseP(parser, INPUT);
|
||||
// should contain [2# SGR, SGR] call pairs
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
@@ -2274,7 +2544,9 @@ describe('EscapeSequenceParser - async', () => {
|
||||
clearAccu();
|
||||
|
||||
// register without fallback
|
||||
const SGR22 = parser.registerCsiHandler({ final: 'm' }, async params => { callstack.push(['2# SGR', params.toArray()]); return true; });
|
||||
const SGR22 = parser.registerCsiHandler({ final: 'm' }, async params => {
|
||||
callstack.push(['2# SGR', params.toArray()]); return true;
|
||||
});
|
||||
await parseP(parser, INPUT);
|
||||
// should only contain 2# SGR
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
@@ -2307,7 +2579,9 @@ describe('EscapeSequenceParser - async', () => {
|
||||
});
|
||||
it('multiple async ESC handlers', async () => {
|
||||
// register with fallback
|
||||
const ESC2 = parser.registerEscHandler({ final: 'E' }, async () => { callstack.push(['2# ESC E']); return false; });
|
||||
const ESC2 = parser.registerEscHandler({ final: 'E' }, async () => {
|
||||
callstack.push(['2# ESC E']); return false;
|
||||
});
|
||||
await parseP(parser, INPUT);
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
const entry = callstack[i];
|
||||
@@ -2340,7 +2614,9 @@ describe('EscapeSequenceParser - async', () => {
|
||||
clearAccu();
|
||||
|
||||
// register without fallback
|
||||
const ESC22 = parser.registerEscHandler({ final: 'E' }, async () => { callstack.push(['2# ESC E']); return true; });
|
||||
const ESC22 = parser.registerEscHandler({ final: 'E' }, async () => {
|
||||
callstack.push(['2# ESC E']); return true;
|
||||
});
|
||||
await parseP(parser, INPUT);
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
const entry = callstack[i];
|
||||
@@ -2372,9 +2648,13 @@ describe('EscapeSequenceParser - async', () => {
|
||||
});
|
||||
it('sync/async SGR mixed', async () => {
|
||||
// sync with fallback
|
||||
const SGR2 = parser.registerCsiHandler({ final: 'm' }, params => { callstack.push(['2# SGR', params.toArray()]); return false; });
|
||||
const SGR2 = parser.registerCsiHandler({ final: 'm' }, params => {
|
||||
callstack.push(['2# SGR', params.toArray()]); return false;
|
||||
});
|
||||
// async with fallback
|
||||
const SGR3 = parser.registerCsiHandler({ final: 'm' }, async params => { callstack.push(['3# SGR', params.toArray()]); return false; });
|
||||
const SGR3 = parser.registerCsiHandler({ final: 'm' }, async params => {
|
||||
callstack.push(['3# SGR', params.toArray()]); return false;
|
||||
});
|
||||
await parseP(parser, INPUT);
|
||||
// should contain [3# SGR, 2# SGR, SGR] call triples
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
@@ -2434,7 +2714,9 @@ describe('EscapeSequenceParser - async', () => {
|
||||
});
|
||||
it('multiple async OSC handlers', async () => {
|
||||
// register with fallback
|
||||
const OSC2 = parser.registerOscHandler(1, new OscHandler(async data => { callstack.push(['2# OSC 1', data]); return false; }));
|
||||
const OSC2 = parser.registerOscHandler(1, new OscHandler(async data => {
|
||||
callstack.push(['2# OSC 1', data]); return false;
|
||||
}));
|
||||
await parseP(parser, INPUT);
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
const entry = callstack[i];
|
||||
@@ -2467,7 +2749,9 @@ describe('EscapeSequenceParser - async', () => {
|
||||
clearAccu();
|
||||
|
||||
// register without fallback
|
||||
const OSC22 = parser.registerOscHandler(1, new OscHandler(async data => { callstack.push(['2# OSC 1', data]); return true; }));
|
||||
const OSC22 = parser.registerOscHandler(1, new OscHandler(async data => {
|
||||
callstack.push(['2# OSC 1', data]); return true;
|
||||
}));
|
||||
await parseP(parser, INPUT);
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
const entry = callstack[i];
|
||||
@@ -2500,7 +2784,9 @@ describe('EscapeSequenceParser - async', () => {
|
||||
});
|
||||
it('multiple async DCS handlers', async () => {
|
||||
// register with fallback
|
||||
const DCS2 = parser.registerDcsHandler({ final: 'a' }, new DcsHandler(async (data, params) => { callstack.push(['#2 DCS a', [data, params.toArray()]]); return false; }));
|
||||
const DCS2 = parser.registerDcsHandler({ final: 'a' }, new DcsHandler(async (data, params) => {
|
||||
callstack.push(['#2 DCS a', [data, params.toArray()]]); return false;
|
||||
}));
|
||||
await parseP(parser, INPUT);
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
const entry = callstack[i];
|
||||
@@ -2533,7 +2819,9 @@ describe('EscapeSequenceParser - async', () => {
|
||||
clearAccu();
|
||||
|
||||
// register without fallback
|
||||
const DCS22 = parser.registerDcsHandler({ final: 'a' }, new DcsHandler(async (data, params) => { callstack.push(['#2 DCS a', [data, params.toArray()]]); return true; }));
|
||||
const DCS22 = parser.registerDcsHandler({ final: 'a' }, new DcsHandler(async (data, params) => {
|
||||
callstack.push(['#2 DCS a', [data, params.toArray()]]); return true;
|
||||
}));
|
||||
await parseP(parser, INPUT);
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
const entry = callstack[i];
|
||||
@@ -2566,7 +2854,9 @@ describe('EscapeSequenceParser - async', () => {
|
||||
});
|
||||
it('multiple async APC handlers', async () => {
|
||||
// register with fallback
|
||||
const APC2 = parser.registerApcHandler({ final: 'X' }, new ApcHandler(async data => { callstack.push(['#2 APC X', data]); return false; }));
|
||||
const APC2 = parser.registerApcHandler({ final: 'X' }, new ApcHandler(async data => {
|
||||
callstack.push(['#2 APC X', data]); return false;
|
||||
}));
|
||||
await parseP(parser, INPUT);
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
const entry = callstack[i];
|
||||
@@ -2599,7 +2889,9 @@ describe('EscapeSequenceParser - async', () => {
|
||||
clearAccu();
|
||||
|
||||
// register without fallback
|
||||
const APC22 = parser.registerApcHandler({ final: 'X' }, new ApcHandler(async data => { callstack.push(['#2 APC X', data]); return true; }));
|
||||
const APC22 = parser.registerApcHandler({ final: 'X' }, new ApcHandler(async data => {
|
||||
callstack.push(['#2 APC X', data]); return true;
|
||||
}));
|
||||
await parseP(parser, INPUT);
|
||||
for (let i = 0; i < callstack.length; ++i) {
|
||||
const entry = callstack[i];
|
||||
|
||||
@@ -185,7 +185,9 @@ describe('OscParser', () => {
|
||||
});
|
||||
|
||||
it('should be called once on end(true)', () => {
|
||||
parser.registerHandler(1234, new OscHandler(data => { reports.push([1234, data]); return true; }));
|
||||
parser.registerHandler(1234, new OscHandler(data => {
|
||||
reports.push([1234, data]); return true;
|
||||
}));
|
||||
parser.start();
|
||||
let data = toUtf32('1234;Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -195,7 +197,9 @@ describe('OscParser', () => {
|
||||
assert.deepEqual(reports, [[1234, 'Here comes the mouse!']]);
|
||||
});
|
||||
it('should not be called on end(false)', () => {
|
||||
parser.registerHandler(1234, new OscHandler(data => { reports.push([1234, data]); return true; }));
|
||||
parser.registerHandler(1234, new OscHandler(data => {
|
||||
reports.push([1234, data]); return true;
|
||||
}));
|
||||
parser.start();
|
||||
let data = toUtf32('1234;Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -205,8 +209,12 @@ describe('OscParser', () => {
|
||||
assert.deepEqual(reports, []);
|
||||
});
|
||||
it('should be disposable', () => {
|
||||
parser.registerHandler(1234, new OscHandler(data => { reports.push(['one', data]); return true; }));
|
||||
const dispo = parser.registerHandler(1234, new OscHandler(data => { reports.push(['two', data]); return true; }));
|
||||
parser.registerHandler(1234, new OscHandler(data => {
|
||||
reports.push(['one', data]); return true;
|
||||
}));
|
||||
const dispo = parser.registerHandler(1234, new OscHandler(data => {
|
||||
reports.push(['two', data]); return true;
|
||||
}));
|
||||
parser.start();
|
||||
let data = toUtf32('1234;Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -224,8 +232,12 @@ describe('OscParser', () => {
|
||||
assert.deepEqual(reports, [['two', 'Here comes the mouse!'], ['one', 'some other data']]);
|
||||
});
|
||||
it('should respect return false', () => {
|
||||
parser.registerHandler(1234, new OscHandler(data => { reports.push(['one', data]); return true; }));
|
||||
parser.registerHandler(1234, new OscHandler(data => { reports.push(['two', data]); return false; }));
|
||||
parser.registerHandler(1234, new OscHandler(data => {
|
||||
reports.push(['one', data]); return true;
|
||||
}));
|
||||
parser.registerHandler(1234, new OscHandler(data => {
|
||||
reports.push(['two', data]); return false;
|
||||
}));
|
||||
parser.start();
|
||||
let data = toUtf32('1234;Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -236,7 +248,9 @@ describe('OscParser', () => {
|
||||
});
|
||||
it('should work up to payload limit', function(): void {
|
||||
this.timeout(30000);
|
||||
parser.registerHandler(1234, new OscHandler(data => { reports.push([1234, data]); return true; }));
|
||||
parser.registerHandler(1234, new OscHandler(data => {
|
||||
reports.push([1234, data]); return true;
|
||||
}));
|
||||
parser.start();
|
||||
let data = toUtf32('1234;');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -249,7 +263,9 @@ describe('OscParser', () => {
|
||||
});
|
||||
it('should abort for payload limit +1', function(): void {
|
||||
this.timeout(30000);
|
||||
parser.registerHandler(1234, new OscHandler(data => { reports.push([1234, data]); return true; }));
|
||||
parser.registerHandler(1234, new OscHandler(data => {
|
||||
reports.push([1234, data]); return true;
|
||||
}));
|
||||
parser.start();
|
||||
let data = toUtf32('1234;');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -412,7 +428,9 @@ describe('OscParser - async tests', () => {
|
||||
});
|
||||
describe('OscHandlerFactory', () => {
|
||||
it('should be called once on end(true)', async () => {
|
||||
parser.registerHandler(1234, new OscHandler(async data => { reports.push([1234, data]); return true; }));
|
||||
parser.registerHandler(1234, new OscHandler(async data => {
|
||||
reports.push([1234, data]); return true;
|
||||
}));
|
||||
parser.start();
|
||||
let data = toUtf32('1234;Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -423,7 +441,9 @@ describe('OscParser - async tests', () => {
|
||||
assert.deepEqual(reports, [[1234, 'Here comes the mouse!']]);
|
||||
});
|
||||
it('should not be called on end(false)', async () => {
|
||||
parser.registerHandler(1234, new OscHandler(async data => { reports.push([1234, data]); return true; }));
|
||||
parser.registerHandler(1234, new OscHandler(async data => {
|
||||
reports.push([1234, data]); return true;
|
||||
}));
|
||||
parser.start();
|
||||
let data = toUtf32('1234;Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -433,8 +453,12 @@ describe('OscParser - async tests', () => {
|
||||
assert.deepEqual(reports, []);
|
||||
});
|
||||
it('should be disposable', async () => {
|
||||
parser.registerHandler(1234, new OscHandler(async data => { reports.push(['one', data]); return true; }));
|
||||
const dispo = parser.registerHandler(1234, new OscHandler(async data => { reports.push(['two', data]); return true; }));
|
||||
parser.registerHandler(1234, new OscHandler(async data => {
|
||||
reports.push(['one', data]); return true;
|
||||
}));
|
||||
const dispo = parser.registerHandler(1234, new OscHandler(async data => {
|
||||
reports.push(['two', data]); return true;
|
||||
}));
|
||||
parser.start();
|
||||
let data = toUtf32('1234;Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
@@ -452,8 +476,12 @@ describe('OscParser - async tests', () => {
|
||||
assert.deepEqual(reports, [['two', 'Here comes the mouse!'], ['one', 'some other data']]);
|
||||
});
|
||||
it('should respect return false', async () => {
|
||||
parser.registerHandler(1234, new OscHandler(async data => { reports.push(['one', data]); return true; }));
|
||||
parser.registerHandler(1234, new OscHandler(async data => { reports.push(['two', data]); return false; }));
|
||||
parser.registerHandler(1234, new OscHandler(async data => {
|
||||
reports.push(['one', data]); return true;
|
||||
}));
|
||||
parser.registerHandler(1234, new OscHandler(async data => {
|
||||
reports.push(['two', data]); return false;
|
||||
}));
|
||||
parser.start();
|
||||
let data = toUtf32('1234;Here comes');
|
||||
parser.put(data, 0, data.length);
|
||||
|
||||
@@ -40,7 +40,9 @@ describe('AddonManager', () => {
|
||||
let called = 0;
|
||||
class Addon implements ITerminalAddon {
|
||||
public activate(): void {}
|
||||
public dispose(): void { called++; }
|
||||
public dispose(): void {
|
||||
called++;
|
||||
}
|
||||
}
|
||||
manager.loadAddon(null!, new Addon());
|
||||
manager.loadAddon(null!, new Addon());
|
||||
|
||||
@@ -19,11 +19,21 @@ export class BufferApiView implements IBufferApi {
|
||||
return this;
|
||||
}
|
||||
|
||||
public get cursorY(): number { return this._buffer.y; }
|
||||
public get cursorX(): number { return this._buffer.x; }
|
||||
public get viewportY(): number { return this._buffer.ydisp; }
|
||||
public get baseY(): number { return this._buffer.ybase; }
|
||||
public get length(): number { return this._buffer.lines.length; }
|
||||
public get cursorY(): number {
|
||||
return this._buffer.y;
|
||||
}
|
||||
public get cursorX(): number {
|
||||
return this._buffer.x;
|
||||
}
|
||||
public get viewportY(): number {
|
||||
return this._buffer.ydisp;
|
||||
}
|
||||
public get baseY(): number {
|
||||
return this._buffer.ybase;
|
||||
}
|
||||
public get length(): number {
|
||||
return this._buffer.lines.length;
|
||||
}
|
||||
public getLine(y: number): IBufferLineApi | undefined {
|
||||
const line = this._buffer.lines.get(y);
|
||||
if (!line) {
|
||||
@@ -31,5 +41,7 @@ export class BufferApiView implements IBufferApi {
|
||||
}
|
||||
return new BufferLineApiView(line);
|
||||
}
|
||||
public getNullCell(): IBufferCellApi { return new CellData(); }
|
||||
public getNullCell(): IBufferCellApi {
|
||||
return new CellData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,12 @@ import { IBufferCell as IBufferCellApi, IBufferLine as IBufferLineApi } from '@x
|
||||
export class BufferLineApiView implements IBufferLineApi {
|
||||
constructor(private _line: IBufferLine) { }
|
||||
|
||||
public get isWrapped(): boolean { return this._line.isWrapped; }
|
||||
public get length(): number { return this._line.length; }
|
||||
public get isWrapped(): boolean {
|
||||
return this._line.isWrapped;
|
||||
}
|
||||
public get length(): number {
|
||||
return this._line.length;
|
||||
}
|
||||
public getCell(x: number, cell?: IBufferCellApi): IBufferCellApi | undefined {
|
||||
if (x < 0 || x >= this._line.length) {
|
||||
return undefined;
|
||||
|
||||
@@ -23,8 +23,12 @@ export class BufferNamespaceApi extends Disposable implements IBufferNamespaceAp
|
||||
this._core.buffers.onBufferActivate(() => this._onBufferChange.fire(this.active));
|
||||
}
|
||||
public get active(): IBufferApi {
|
||||
if (this._core.buffers.active === this._core.buffers.normal) { return this.normal; }
|
||||
if (this._core.buffers.active === this._core.buffers.alt) { return this.alternate; }
|
||||
if (this._core.buffers.active === this._core.buffers.normal) {
|
||||
return this.normal;
|
||||
}
|
||||
if (this._core.buffers.active === this._core.buffers.alt) {
|
||||
return this.alternate;
|
||||
}
|
||||
throw new Error('Active buffer is neither normal nor alternate');
|
||||
}
|
||||
public get normal(): IBufferApi {
|
||||
|
||||
@@ -29,7 +29,9 @@ export class BufferService extends Disposable implements IBufferService {
|
||||
private readonly _onScroll = this._register(new Emitter<number>());
|
||||
public readonly onScroll = this._onScroll.event;
|
||||
|
||||
public get buffer(): IBuffer { return this.buffers.active; }
|
||||
public get buffer(): IBuffer {
|
||||
return this.buffers.active;
|
||||
}
|
||||
|
||||
/** An IBufferline to clone/copy from for new blank lines */
|
||||
private _cachedBlankLine: IBufferLine | undefined;
|
||||
|
||||
@@ -32,7 +32,9 @@ export class DecorationService extends Disposable implements IDecorationService
|
||||
private readonly _onDecorationRemoved = this._register(new Emitter<IInternalDecoration>());
|
||||
public readonly onDecorationRemoved = this._onDecorationRemoved.event;
|
||||
|
||||
public get decorations(): IterableIterator<IInternalDecoration> { return this._decorations.values(); }
|
||||
public get decorations(): IterableIterator<IInternalDecoration> {
|
||||
return this._decorations.values();
|
||||
}
|
||||
|
||||
constructor(@ILogService private readonly _logService: ILogService) {
|
||||
super();
|
||||
|
||||
@@ -35,7 +35,9 @@ export class LogService extends Disposable implements ILogService {
|
||||
public serviceBrand: any;
|
||||
|
||||
private _logLevel: LogLevelEnum = LogLevelEnum.OFF;
|
||||
public get logLevel(): LogLevelEnum { return this._logLevel; }
|
||||
public get logLevel(): LogLevelEnum {
|
||||
return this._logLevel;
|
||||
}
|
||||
|
||||
constructor(
|
||||
@IOptionsService private readonly _optionsService: IOptionsService
|
||||
|
||||
@@ -40,8 +40,12 @@ describe('MouseStateService', () => {
|
||||
cms.reset();
|
||||
assert.equal(cms.activeEncoding, 'DEFAULT');
|
||||
assert.equal(cms.activeProtocol, 'NONE');
|
||||
assert.throws(() => { cms.activeEncoding = 'xyz'; }, 'unknown encoding "xyz"');
|
||||
assert.throws(() => { cms.activeProtocol = 'xyz'; }, 'unknown protocol "xyz"');
|
||||
assert.throws(() => {
|
||||
cms.activeEncoding = 'xyz';
|
||||
}, 'unknown encoding "xyz"');
|
||||
assert.throws(() => {
|
||||
cms.activeProtocol = 'xyz';
|
||||
}, 'unknown protocol "xyz"');
|
||||
});
|
||||
it('addEncoding', () => {
|
||||
const cms = new MouseStateService();
|
||||
|
||||
@@ -25,11 +25,15 @@ describe('unicode provider', () => {
|
||||
it('default to V6', () => {
|
||||
assert.equal(us.activeVersion, '6');
|
||||
assert.deepEqual(us.versions, ['6']);
|
||||
assert.doesNotThrow(() => { us.activeVersion = '6'; }, `unknown Unicode version "6"`);
|
||||
assert.doesNotThrow(() => {
|
||||
us.activeVersion = '6';
|
||||
}, `unknown Unicode version "6"`);
|
||||
assert.equal(us.getStringCellWidth('hello'), 5);
|
||||
});
|
||||
it('activate should throw for unknown version', () => {
|
||||
assert.throws(() => { us.activeVersion = '55'; }, 'unknown Unicode version "55"');
|
||||
assert.throws(() => {
|
||||
us.activeVersion = '55';
|
||||
}, 'unknown Unicode version "55"');
|
||||
});
|
||||
it('should notify about version change', () => {
|
||||
const notes: string[] = [];
|
||||
|
||||
@@ -35,8 +35,12 @@ describe('Headless API Tests', function (): void {
|
||||
it('write with callback', async () => {
|
||||
let result: string | undefined;
|
||||
await new Promise<void>(r => {
|
||||
term.write('foo', () => { result = 'a'; });
|
||||
term.write('bar', () => { result += 'b'; });
|
||||
term.write('foo', () => {
|
||||
result = 'a';
|
||||
});
|
||||
term.write('bar', () => {
|
||||
result += 'b';
|
||||
});
|
||||
term.write('文', () => {
|
||||
result += 'c';
|
||||
r();
|
||||
@@ -56,8 +60,12 @@ describe('Headless API Tests', function (): void {
|
||||
it('write - bytes (UTF8) with callback', async () => {
|
||||
let result: string | undefined;
|
||||
await new Promise<void>(r => {
|
||||
term.write(new Uint8Array([102, 111, 111]), () => { result = 'A'; }); // foo
|
||||
term.write(new Uint8Array([98, 97, 114]), () => { result += 'B'; }); // bar
|
||||
term.write(new Uint8Array([102, 111, 111]), () => {
|
||||
result = 'A';
|
||||
}); // foo
|
||||
term.write(new Uint8Array([98, 97, 114]), () => {
|
||||
result += 'B';
|
||||
}); // bar
|
||||
term.write(new Uint8Array([230, 150, 135]), () => { // 文
|
||||
result += 'C';
|
||||
r();
|
||||
@@ -79,8 +87,12 @@ describe('Headless API Tests', function (): void {
|
||||
it('writeln with callback', async () => {
|
||||
let result: string | undefined;
|
||||
await new Promise<void>(r => {
|
||||
term.writeln('foo', () => { result = '1'; });
|
||||
term.writeln('bar', () => { result += '2'; });
|
||||
term.writeln('foo', () => {
|
||||
result = '1';
|
||||
});
|
||||
term.writeln('bar', () => {
|
||||
result += '2';
|
||||
});
|
||||
term.writeln('文', () => {
|
||||
result += '3';
|
||||
r();
|
||||
|
||||
@@ -72,16 +72,36 @@ export class Terminal extends Disposable implements ITerminalApi {
|
||||
}
|
||||
}
|
||||
|
||||
public get onBell(): IEvent<void> { return this._core.onBell; }
|
||||
public get onBinary(): IEvent<string> { return this._core.onBinary; }
|
||||
public get onCursorMove(): IEvent<void> { return this._core.onCursorMove; }
|
||||
public get onData(): IEvent<string> { return this._core.onData; }
|
||||
public get onLineFeed(): IEvent<void> { return this._core.onLineFeed; }
|
||||
public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }
|
||||
public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }
|
||||
public get onScroll(): IEvent<number> { return this._core.onScroll; }
|
||||
public get onTitleChange(): IEvent<string> { return this._core.onTitleChange; }
|
||||
public get onWriteParsed(): IEvent<void> { return this._core.onWriteParsed; }
|
||||
public get onBell(): IEvent<void> {
|
||||
return this._core.onBell;
|
||||
}
|
||||
public get onBinary(): IEvent<string> {
|
||||
return this._core.onBinary;
|
||||
}
|
||||
public get onCursorMove(): IEvent<void> {
|
||||
return this._core.onCursorMove;
|
||||
}
|
||||
public get onData(): IEvent<string> {
|
||||
return this._core.onData;
|
||||
}
|
||||
public get onLineFeed(): IEvent<void> {
|
||||
return this._core.onLineFeed;
|
||||
}
|
||||
public get onRender(): IEvent<{ start: number, end: number }> {
|
||||
return this._core.onRender;
|
||||
}
|
||||
public get onResize(): IEvent<{ cols: number, rows: number }> {
|
||||
return this._core.onResize;
|
||||
}
|
||||
public get onScroll(): IEvent<number> {
|
||||
return this._core.onScroll;
|
||||
}
|
||||
public get onTitleChange(): IEvent<string> {
|
||||
return this._core.onTitleChange;
|
||||
}
|
||||
public get onWriteParsed(): IEvent<void> {
|
||||
return this._core.onWriteParsed;
|
||||
}
|
||||
|
||||
public get parser(): IParser {
|
||||
this._parser ??= new ParserApi(this._core);
|
||||
@@ -91,8 +111,12 @@ export class Terminal extends Disposable implements ITerminalApi {
|
||||
this._checkProposedApi();
|
||||
return new UnicodeApi(this._core);
|
||||
}
|
||||
public get rows(): number { return this._core.rows; }
|
||||
public get cols(): number { return this._core.cols; }
|
||||
public get rows(): number {
|
||||
return this._core.rows;
|
||||
}
|
||||
public get cols(): number {
|
||||
return this._core.cols;
|
||||
}
|
||||
public get buffer(): IBufferNamespaceApi {
|
||||
this._buffer ??= this._register(new BufferNamespaceApi(this._core));
|
||||
return this._buffer;
|
||||
|
||||
@@ -24,19 +24,25 @@ function toUtf32(s: string): Uint32Array {
|
||||
class FastDcsHandler implements IDcsHandler {
|
||||
public hook(params: IParams): void {}
|
||||
public put(data: Uint32Array, start: number, end: number): void {}
|
||||
public unhook(success: boolean): boolean { return true; }
|
||||
public unhook(success: boolean): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class FastOscHandler implements IOscHandler {
|
||||
public start(): void {}
|
||||
public put(data: Uint32Array, start: number, end: number): void {}
|
||||
public end(success: boolean): boolean { return true; }
|
||||
public end(success: boolean): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class FastApcHandler implements IApcHandler {
|
||||
public start(): void {}
|
||||
public put(data: Uint32Array, start: number, end: number): void {}
|
||||
public end(success: boolean): boolean { return true; }
|
||||
public end(success: boolean): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,9 @@ perfContext('Emitter.fire()', () => {
|
||||
let sum = 0;
|
||||
before(() => {
|
||||
emitter = new Emitter<number>();
|
||||
emitter.event(e => { sum += e; });
|
||||
emitter.event(e => {
|
||||
sum += e;
|
||||
});
|
||||
});
|
||||
new RuntimeCase('', () => {
|
||||
for (let i = 0; i < ITERATIONS; i++) {
|
||||
@@ -42,8 +44,12 @@ perfContext('Emitter.fire()', () => {
|
||||
let sum = 0;
|
||||
before(() => {
|
||||
emitter = new Emitter<number>();
|
||||
emitter.event(e => { sum += e; });
|
||||
emitter.event(e => { sum += e * 2; });
|
||||
emitter.event(e => {
|
||||
sum += e;
|
||||
});
|
||||
emitter.event(e => {
|
||||
sum += e * 2;
|
||||
});
|
||||
});
|
||||
new RuntimeCase('', () => {
|
||||
for (let i = 0; i < ITERATIONS; i++) {
|
||||
@@ -59,7 +65,9 @@ perfContext('Emitter.fire()', () => {
|
||||
before(() => {
|
||||
emitter = new Emitter<number>();
|
||||
for (let j = 0; j < 5; j++) {
|
||||
emitter.event(e => { sum += e; });
|
||||
emitter.event(e => {
|
||||
sum += e;
|
||||
});
|
||||
}
|
||||
});
|
||||
new RuntimeCase('', () => {
|
||||
|
||||
+243
-81
@@ -202,76 +202,156 @@ export class TerminalProxy implements ITerminalProxyCustomMethods, PlaywrightApi
|
||||
|
||||
// #region Events
|
||||
private _onBell = new EventEmitter<void>();
|
||||
public get onBell(): IEvent<void> { return this._onBell.event; }
|
||||
public get onBell(): IEvent<void> {
|
||||
return this._onBell.event;
|
||||
}
|
||||
private _onBinary = new EventEmitter<string>();
|
||||
public get onBinary(): IEvent<string> { return this._onBinary.event; }
|
||||
public get onBinary(): IEvent<string> {
|
||||
return this._onBinary.event;
|
||||
}
|
||||
private _onCursorMove = new EventEmitter<void>();
|
||||
public get onCursorMove(): IEvent<void> { return this._onCursorMove.event; }
|
||||
public get onCursorMove(): IEvent<void> {
|
||||
return this._onCursorMove.event;
|
||||
}
|
||||
private _onData = new EventEmitter<string>();
|
||||
public get onData(): IEvent<string> { return this._onData.event; }
|
||||
public get onData(): IEvent<string> {
|
||||
return this._onData.event;
|
||||
}
|
||||
private _onKey = new EventEmitter<{ key: string, domEvent: KeyboardEvent }>();
|
||||
public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._onKey.event; }
|
||||
public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> {
|
||||
return this._onKey.event;
|
||||
}
|
||||
private _onLineFeed = new EventEmitter<void>();
|
||||
public get onLineFeed(): IEvent<void> { return this._onLineFeed.event; }
|
||||
public get onLineFeed(): IEvent<void> {
|
||||
return this._onLineFeed.event;
|
||||
}
|
||||
private _onRender = new EventEmitter<{ start: number, end: number }>();
|
||||
public get onRender(): IEvent<{ start: number, end: number }> { return this._onRender.event; }
|
||||
public get onRender(): IEvent<{ start: number, end: number }> {
|
||||
return this._onRender.event;
|
||||
}
|
||||
private _onResize = new EventEmitter<{ cols: number, rows: number }>();
|
||||
public get onResize(): IEvent<{ cols: number, rows: number }> { return this._onResize.event; }
|
||||
public get onResize(): IEvent<{ cols: number, rows: number }> {
|
||||
return this._onResize.event;
|
||||
}
|
||||
private _onScroll = new EventEmitter<number>();
|
||||
public get onScroll(): IEvent<number> { return this._onScroll.event; }
|
||||
public get onScroll(): IEvent<number> {
|
||||
return this._onScroll.event;
|
||||
}
|
||||
private _onDimensionsChange = new EventEmitter<IRenderDimensions>();
|
||||
public get onDimensionsChange(): IEvent<IRenderDimensions> { return this._onDimensionsChange.event; }
|
||||
public get onDimensionsChange(): IEvent<IRenderDimensions> {
|
||||
return this._onDimensionsChange.event;
|
||||
}
|
||||
private _onSelectionChange = new EventEmitter<void>();
|
||||
public get onSelectionChange(): IEvent<void> { return this._onSelectionChange.event; }
|
||||
public get onSelectionChange(): IEvent<void> {
|
||||
return this._onSelectionChange.event;
|
||||
}
|
||||
private _onTitleChange = new EventEmitter<string>();
|
||||
public get onTitleChange(): IEvent<string> { return this._onTitleChange.event; }
|
||||
public get onTitleChange(): IEvent<string> {
|
||||
return this._onTitleChange.event;
|
||||
}
|
||||
private _onWriteParsed = new EventEmitter<void>();
|
||||
public get onWriteParsed(): IEvent<void> { return this._onWriteParsed.event; }
|
||||
public get onWriteParsed(): IEvent<void> {
|
||||
return this._onWriteParsed.event;
|
||||
}
|
||||
// #endregion
|
||||
|
||||
// #region Simple properties
|
||||
public get cols(): Promise<number> { return this.evaluate(([term]) => term.cols); }
|
||||
public get rows(): Promise<number> { return this.evaluate(([term]) => term.rows); }
|
||||
public get modes(): Promise<IModes> { return this.evaluate(([term]) => term.modes); }
|
||||
public get dimensions(): Promise<IRenderDimensions | undefined> { return this.evaluate(([term]) => term.dimensions); }
|
||||
public get cols(): Promise<number> {
|
||||
return this.evaluate(([term]) => term.cols);
|
||||
}
|
||||
public get rows(): Promise<number> {
|
||||
return this.evaluate(([term]) => term.rows);
|
||||
}
|
||||
public get modes(): Promise<IModes> {
|
||||
return this.evaluate(([term]) => term.modes);
|
||||
}
|
||||
public get dimensions(): Promise<IRenderDimensions | undefined> {
|
||||
return this.evaluate(([term]) => term.dimensions);
|
||||
}
|
||||
// #endregion
|
||||
|
||||
// #region Complex properties
|
||||
public get buffer(): TerminalBufferNamespaceProxy { return new TerminalBufferNamespaceProxy(this._page, this); }
|
||||
public get buffer(): TerminalBufferNamespaceProxy {
|
||||
return new TerminalBufferNamespaceProxy(this._page, this);
|
||||
}
|
||||
/**
|
||||
* Exposes somewhat unsafe access to internals for testing things difficult to do with the regular
|
||||
* API
|
||||
*/
|
||||
public get core(): TerminalCoreProxy { return new TerminalCoreProxy(this._page, this); }
|
||||
public get core(): TerminalCoreProxy {
|
||||
return new TerminalCoreProxy(this._page, this);
|
||||
}
|
||||
// #endregion
|
||||
|
||||
// #region Proxied methods
|
||||
public async dispose(): Promise<void> { return this.evaluate(([term]) => term.dispose()); }
|
||||
public async reset(): Promise<void> { return this.evaluate(([term]) => term.reset()); }
|
||||
public async clear(): Promise<void> { return this.evaluate(([term]) => term.clear()); }
|
||||
public async focus(): Promise<void> { return this.evaluate(([term]) => term.focus()); }
|
||||
public async blur(): Promise<void> { return this.evaluate(([term]) => term.blur()); }
|
||||
public async hasSelection(): Promise<boolean> { return this.evaluate(([term]) => term.hasSelection()); }
|
||||
public async getSelection(): Promise<string> { return this.evaluate(([term]) => term.getSelection()); }
|
||||
public async getSelectionPosition(): Promise<IBufferRange | undefined> { return this.evaluate(([term]) => term.getSelectionPosition()); }
|
||||
public async selectAll(): Promise<void> { return this.evaluate(([term]) => term.selectAll()); }
|
||||
public async selectLines(start: number, end: number): Promise<void> { return this._page.evaluate(([term, start, end]) => term.selectLines(start, end), [await this.getHandle(), start, end] as const); }
|
||||
public async clearSelection(): Promise<void> { return this.evaluate(([term]) => term.clearSelection()); }
|
||||
public async select(column: number, row: number, length: number): Promise<void> { return this._page.evaluate(([term, column, row, length]) => term.select(column, row, length), [await this.getHandle(), column, row, length] as const); }
|
||||
public async paste(data: string): Promise<void> { return this._page.evaluate(([term, data]) => term.paste(data), [await this.getHandle(), data] as const); }
|
||||
public async refresh(start: number, end: number): Promise<void> { return this._page.evaluate(([term, start, end]) => term.refresh(start, end), [await this.getHandle(), start, end] as const); }
|
||||
public async getOption<T extends keyof ITerminalOptions>(key: T): Promise<ITerminalOptions[T]> { return this._page.evaluate(([term, key]) => term.options[key as T], [await this.getHandle(), key] as const); }
|
||||
public async setOption<T extends keyof ITerminalOptions>(key: T, value: ITerminalOptions[T]): Promise<any> { return this._page.evaluate(([term, key, value]) => term.options[key as T] = (value as ITerminalOptions[T]), [await this.getHandle(), key, value] as const); }
|
||||
public async dispose(): Promise<void> {
|
||||
return this.evaluate(([term]) => term.dispose());
|
||||
}
|
||||
public async reset(): Promise<void> {
|
||||
return this.evaluate(([term]) => term.reset());
|
||||
}
|
||||
public async clear(): Promise<void> {
|
||||
return this.evaluate(([term]) => term.clear());
|
||||
}
|
||||
public async focus(): Promise<void> {
|
||||
return this.evaluate(([term]) => term.focus());
|
||||
}
|
||||
public async blur(): Promise<void> {
|
||||
return this.evaluate(([term]) => term.blur());
|
||||
}
|
||||
public async hasSelection(): Promise<boolean> {
|
||||
return this.evaluate(([term]) => term.hasSelection());
|
||||
}
|
||||
public async getSelection(): Promise<string> {
|
||||
return this.evaluate(([term]) => term.getSelection());
|
||||
}
|
||||
public async getSelectionPosition(): Promise<IBufferRange | undefined> {
|
||||
return this.evaluate(([term]) => term.getSelectionPosition());
|
||||
}
|
||||
public async selectAll(): Promise<void> {
|
||||
return this.evaluate(([term]) => term.selectAll());
|
||||
}
|
||||
public async selectLines(start: number, end: number): Promise<void> {
|
||||
return this._page.evaluate(([term, start, end]) => term.selectLines(start, end), [await this.getHandle(), start, end] as const);
|
||||
}
|
||||
public async clearSelection(): Promise<void> {
|
||||
return this.evaluate(([term]) => term.clearSelection());
|
||||
}
|
||||
public async select(column: number, row: number, length: number): Promise<void> {
|
||||
return this._page.evaluate(([term, column, row, length]) => term.select(column, row, length), [await this.getHandle(), column, row, length] as const);
|
||||
}
|
||||
public async paste(data: string): Promise<void> {
|
||||
return this._page.evaluate(([term, data]) => term.paste(data), [await this.getHandle(), data] as const);
|
||||
}
|
||||
public async refresh(start: number, end: number): Promise<void> {
|
||||
return this._page.evaluate(([term, start, end]) => term.refresh(start, end), [await this.getHandle(), start, end] as const);
|
||||
}
|
||||
public async getOption<T extends keyof ITerminalOptions>(key: T): Promise<ITerminalOptions[T]> {
|
||||
return this._page.evaluate(([term, key]) => term.options[key as T], [await this.getHandle(), key] as const);
|
||||
}
|
||||
public async setOption<T extends keyof ITerminalOptions>(key: T, value: ITerminalOptions[T]): Promise<any> {
|
||||
return this._page.evaluate(([term, key, value]) => term.options[key as T] = (value as ITerminalOptions[T]), [await this.getHandle(), key, value] as const);
|
||||
}
|
||||
public async setOptions(value: Partial<ITerminalOptions>): Promise<any> {
|
||||
return this._page.evaluate(([term, value]) => {
|
||||
term.options = value;
|
||||
}, [await this.getHandle(), value] as const);
|
||||
}
|
||||
public async scrollToTop(): Promise<void> { return this.evaluate(([term]) => term.scrollToTop()); }
|
||||
public async scrollToBottom(): Promise<void> { return this.evaluate(([term]) => term.scrollToBottom()); }
|
||||
public async scrollPages(pageCount: number): Promise<void> { return this._page.evaluate(([term, pageCount]) => term.scrollPages(pageCount), [await this.getHandle(), pageCount] as const); }
|
||||
public async scrollToLine(line: number): Promise<void> { return this._page.evaluate(([term, line]) => term.scrollToLine(line), [await this.getHandle(), line] as const); }
|
||||
public async scrollLines(amount: number): Promise<void> { return this._page.evaluate(([term, amount]) => term.scrollLines(amount), [await this.getHandle(), amount] as const); }
|
||||
public async scrollToTop(): Promise<void> {
|
||||
return this.evaluate(([term]) => term.scrollToTop());
|
||||
}
|
||||
public async scrollToBottom(): Promise<void> {
|
||||
return this.evaluate(([term]) => term.scrollToBottom());
|
||||
}
|
||||
public async scrollPages(pageCount: number): Promise<void> {
|
||||
return this._page.evaluate(([term, pageCount]) => term.scrollPages(pageCount), [await this.getHandle(), pageCount] as const);
|
||||
}
|
||||
public async scrollToLine(line: number): Promise<void> {
|
||||
return this._page.evaluate(([term, line]) => term.scrollToLine(line), [await this.getHandle(), line] as const);
|
||||
}
|
||||
public async scrollLines(amount: number): Promise<void> {
|
||||
return this._page.evaluate(([term, amount]) => term.scrollLines(amount), [await this.getHandle(), amount] as const);
|
||||
}
|
||||
public async write(data: string | Uint8Array): Promise<void> {
|
||||
return this._page.evaluate(([term, data]) => {
|
||||
return new Promise(r => term.write(typeof data === 'string' ? data : new Uint8Array(data), r));
|
||||
@@ -282,11 +362,21 @@ export class TerminalProxy implements ITerminalProxyCustomMethods, PlaywrightApi
|
||||
return new Promise(r => term.writeln(typeof data === 'string' ? data : new Uint8Array(data), r));
|
||||
}, [await this.getHandle(), typeof data === 'string' ? data : Array.from(data)] as const);
|
||||
}
|
||||
public async input(data: string, wasUserInput: boolean = true): Promise<void> { return this.evaluate(([term]) => term.input(data, wasUserInput)); }
|
||||
public async resize(cols: number, rows: number): Promise<void> { return this._page.evaluate(([term, cols, rows]) => term.resize(cols, rows), [await this.getHandle(), cols, rows] as const); }
|
||||
public async registerMarker(y?: number | undefined): Promise<IMarker> { return this._page.evaluate(([term, y]) => term.registerMarker(y), [await this.getHandle(), y] as const); }
|
||||
public async registerDecoration(decorationOptions: IDecorationOptions): Promise<IDecoration | undefined> { return this._page.evaluate(([term, decorationOptions]) => term.registerDecoration(decorationOptions), [await this.getHandle(), decorationOptions] as const); }
|
||||
public async clearTextureAtlas(): Promise<void> { return this.evaluate(([term]) => term.clearTextureAtlas()); }
|
||||
public async input(data: string, wasUserInput: boolean = true): Promise<void> {
|
||||
return this.evaluate(([term]) => term.input(data, wasUserInput));
|
||||
}
|
||||
public async resize(cols: number, rows: number): Promise<void> {
|
||||
return this._page.evaluate(([term, cols, rows]) => term.resize(cols, rows), [await this.getHandle(), cols, rows] as const);
|
||||
}
|
||||
public async registerMarker(y?: number | undefined): Promise<IMarker> {
|
||||
return this._page.evaluate(([term, y]) => term.registerMarker(y), [await this.getHandle(), y] as const);
|
||||
}
|
||||
public async registerDecoration(decorationOptions: IDecorationOptions): Promise<IDecoration | undefined> {
|
||||
return this._page.evaluate(([term, decorationOptions]) => term.registerDecoration(decorationOptions), [await this.getHandle(), decorationOptions] as const);
|
||||
}
|
||||
public async clearTextureAtlas(): Promise<void> {
|
||||
return this.evaluate(([term]) => term.clearTextureAtlas());
|
||||
}
|
||||
// #endregion
|
||||
|
||||
public async evaluate<T>(pageFunction: PageFunction<Terminal[], T>): Promise<T> {
|
||||
@@ -314,9 +404,15 @@ class TerminalBufferNamespaceProxy implements PlaywrightApiProxy<IBufferNamespac
|
||||
|
||||
}
|
||||
|
||||
public get active(): TerminalBufferProxy { return new TerminalBufferProxy(this._page, this._proxy, this._proxy.evaluateHandle(([term]) => term.buffer.active)); }
|
||||
public get normal(): TerminalBufferProxy { return new TerminalBufferProxy(this._page, this._proxy, this._proxy.evaluateHandle(([term]) => term.buffer.normal)); }
|
||||
public get alternate(): TerminalBufferProxy { return new TerminalBufferProxy(this._page, this._proxy, this._proxy.evaluateHandle(([term]) => term.buffer.alternate)); }
|
||||
public get active(): TerminalBufferProxy {
|
||||
return new TerminalBufferProxy(this._page, this._proxy, this._proxy.evaluateHandle(([term]) => term.buffer.active));
|
||||
}
|
||||
public get normal(): TerminalBufferProxy {
|
||||
return new TerminalBufferProxy(this._page, this._proxy, this._proxy.evaluateHandle(([term]) => term.buffer.normal));
|
||||
}
|
||||
public get alternate(): TerminalBufferProxy {
|
||||
return new TerminalBufferProxy(this._page, this._proxy, this._proxy.evaluateHandle(([term]) => term.buffer.alternate));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Adopt PlaywrightApiProxy
|
||||
@@ -328,12 +424,24 @@ class TerminalBufferProxy /* implements EnsureAsyncProperties<IBuffer>*/ {
|
||||
) {
|
||||
}
|
||||
|
||||
public get type(): Promise<'normal' | 'alternate'> { return this.evaluate(([buffer]) => buffer.type); }
|
||||
public get cursorY(): Promise<number> { return this.evaluate(([buffer]) => buffer.cursorY); }
|
||||
public get cursorX(): Promise<number> { return this.evaluate(([buffer]) => buffer.cursorX); }
|
||||
public get viewportY(): Promise<number> { return this.evaluate(([buffer]) => buffer.viewportY); }
|
||||
public get baseY(): Promise<number> { return this.evaluate(([buffer]) => buffer.baseY); }
|
||||
public get length(): Promise<number> { return this.evaluate(([buffer]) => buffer.length); }
|
||||
public get type(): Promise<'normal' | 'alternate'> {
|
||||
return this.evaluate(([buffer]) => buffer.type);
|
||||
}
|
||||
public get cursorY(): Promise<number> {
|
||||
return this.evaluate(([buffer]) => buffer.cursorY);
|
||||
}
|
||||
public get cursorX(): Promise<number> {
|
||||
return this.evaluate(([buffer]) => buffer.cursorX);
|
||||
}
|
||||
public get viewportY(): Promise<number> {
|
||||
return this.evaluate(([buffer]) => buffer.viewportY);
|
||||
}
|
||||
public get baseY(): Promise<number> {
|
||||
return this.evaluate(([buffer]) => buffer.baseY);
|
||||
}
|
||||
public get length(): Promise<number> {
|
||||
return this.evaluate(([buffer]) => buffer.length);
|
||||
}
|
||||
public async getLine(y: number): Promise<TerminalBufferLine | undefined> {
|
||||
const lineHandle = await this._page.evaluateHandle(([buffer, y]) => buffer.getLine(y), [await this._handle, y] as const);
|
||||
const value = await lineHandle.jsonValue();
|
||||
@@ -356,8 +464,12 @@ class TerminalBufferLine {
|
||||
) {
|
||||
}
|
||||
|
||||
public get length(): Promise<number> { return this.evaluate(([bufferLine]) => bufferLine.length); }
|
||||
public get isWrapped(): Promise<boolean> { return this.evaluate(([bufferLine]) => bufferLine.isWrapped); }
|
||||
public get length(): Promise<number> {
|
||||
return this.evaluate(([bufferLine]) => bufferLine.length);
|
||||
}
|
||||
public get isWrapped(): Promise<boolean> {
|
||||
return this.evaluate(([bufferLine]) => bufferLine.isWrapped);
|
||||
}
|
||||
|
||||
public translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): Promise<string> {
|
||||
return this._page.evaluate(([bufferLine, trimRight, startColumn, endColumn]) => {
|
||||
@@ -387,33 +499,79 @@ class TerminalBufferCell {
|
||||
) {
|
||||
}
|
||||
|
||||
public getWidth(): Promise<number> { return this.evaluate(([cell]) => cell.getWidth()); }
|
||||
public getChars(): Promise<string> { return this.evaluate(([cell]) => cell.getChars()); }
|
||||
public getCode(): Promise<number> { return this.evaluate(([cell]) => cell.getCode()); }
|
||||
public getWidth(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.getWidth());
|
||||
}
|
||||
public getChars(): Promise<string> {
|
||||
return this.evaluate(([cell]) => cell.getChars());
|
||||
}
|
||||
public getCode(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.getCode());
|
||||
}
|
||||
|
||||
public getFgColorMode(): Promise<number> { return this.evaluate(([cell]) => cell.getFgColorMode()); }
|
||||
public getBgColorMode(): Promise<number> { return this.evaluate(([cell]) => cell.getBgColorMode()); }
|
||||
public getFgColor(): Promise<number> { return this.evaluate(([cell]) => cell.getFgColor()); }
|
||||
public getBgColor(): Promise<number> { return this.evaluate(([cell]) => cell.getBgColor()); }
|
||||
public getFgColorMode(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.getFgColorMode());
|
||||
}
|
||||
public getBgColorMode(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.getBgColorMode());
|
||||
}
|
||||
public getFgColor(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.getFgColor());
|
||||
}
|
||||
public getBgColor(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.getBgColor());
|
||||
}
|
||||
|
||||
public isBold(): Promise<number> { return this.evaluate(([cell]) => cell.isBold()); }
|
||||
public isItalic(): Promise<number> { return this.evaluate(([cell]) => cell.isItalic()); }
|
||||
public isDim(): Promise<number> { return this.evaluate(([cell]) => cell.isDim()); }
|
||||
public isUnderline(): Promise<number> { return this.evaluate(([cell]) => cell.isUnderline()); }
|
||||
public isBlink(): Promise<number> { return this.evaluate(([cell]) => cell.isBlink()); }
|
||||
public isInverse(): Promise<number> { return this.evaluate(([cell]) => cell.isInverse()); }
|
||||
public isInvisible(): Promise<number> { return this.evaluate(([cell]) => cell.isInvisible()); }
|
||||
public isStrikethrough(): Promise<number> { return this.evaluate(([cell]) => cell.isStrikethrough()); }
|
||||
public isOverline(): Promise<number> { return this.evaluate(([cell]) => cell.isOverline()); }
|
||||
public isBold(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.isBold());
|
||||
}
|
||||
public isItalic(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.isItalic());
|
||||
}
|
||||
public isDim(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.isDim());
|
||||
}
|
||||
public isUnderline(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.isUnderline());
|
||||
}
|
||||
public isBlink(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.isBlink());
|
||||
}
|
||||
public isInverse(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.isInverse());
|
||||
}
|
||||
public isInvisible(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.isInvisible());
|
||||
}
|
||||
public isStrikethrough(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.isStrikethrough());
|
||||
}
|
||||
public isOverline(): Promise<number> {
|
||||
return this.evaluate(([cell]) => cell.isOverline());
|
||||
}
|
||||
|
||||
public isFgRGB(): Promise<boolean> { return this.evaluate(([cell]) => cell.isFgRGB()); }
|
||||
public isBgRGB(): Promise<boolean> { return this.evaluate(([cell]) => cell.isBgRGB()); }
|
||||
public isFgPalette(): Promise<boolean> { return this.evaluate(([cell]) => cell.isFgPalette()); }
|
||||
public isBgPalette(): Promise<boolean> { return this.evaluate(([cell]) => cell.isBgPalette()); }
|
||||
public isFgDefault(): Promise<boolean> { return this.evaluate(([cell]) => cell.isFgDefault()); }
|
||||
public isBgDefault(): Promise<boolean> { return this.evaluate(([cell]) => cell.isBgDefault()); }
|
||||
public isFgRGB(): Promise<boolean> {
|
||||
return this.evaluate(([cell]) => cell.isFgRGB());
|
||||
}
|
||||
public isBgRGB(): Promise<boolean> {
|
||||
return this.evaluate(([cell]) => cell.isBgRGB());
|
||||
}
|
||||
public isFgPalette(): Promise<boolean> {
|
||||
return this.evaluate(([cell]) => cell.isFgPalette());
|
||||
}
|
||||
public isBgPalette(): Promise<boolean> {
|
||||
return this.evaluate(([cell]) => cell.isBgPalette());
|
||||
}
|
||||
public isFgDefault(): Promise<boolean> {
|
||||
return this.evaluate(([cell]) => cell.isFgDefault());
|
||||
}
|
||||
public isBgDefault(): Promise<boolean> {
|
||||
return this.evaluate(([cell]) => cell.isBgDefault());
|
||||
}
|
||||
|
||||
public isAttributeDefault(): Promise<boolean> { return this.evaluate(([cell]) => cell.isAttributeDefault()); }
|
||||
public isAttributeDefault(): Promise<boolean> {
|
||||
return this.evaluate(([cell]) => cell.isAttributeDefault());
|
||||
}
|
||||
|
||||
public async evaluate<T>(pageFunction: PageFunction<IBufferCell[], T>): Promise<T> {
|
||||
return this._page.evaluate(pageFunction, [this._handle]);
|
||||
@@ -427,8 +585,12 @@ class TerminalCoreProxy {
|
||||
) {
|
||||
}
|
||||
|
||||
public get isDisposed(): Promise<boolean> { return this.evaluate(([core]) => (core as any)._isDisposed); }
|
||||
public get renderDimensions(): Promise<IRenderDimensionsInternal> { return this.evaluate(([core]) => ((core as any)._renderService as IRenderService).dimensions); }
|
||||
public get isDisposed(): Promise<boolean> {
|
||||
return this.evaluate(([core]) => (core as any)._isDisposed);
|
||||
}
|
||||
public get renderDimensions(): Promise<IRenderDimensionsInternal> {
|
||||
return this.evaluate(([core]) => ((core as any)._renderService as IRenderService).dimensions);
|
||||
}
|
||||
|
||||
public async triggerBinaryEvent(data: string): Promise<void> {
|
||||
return this._page.evaluate(([core, data]) => core.coreService.triggerBinaryEvent(data), [await this._getCoreHandle(), data] as const);
|
||||
|
||||
Reference in New Issue
Block a user