mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
cleanup & docs for OSC 10/11
This commit is contained in:
@@ -55,8 +55,8 @@ class TestInputHandler extends InputHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public parseXColorName(data: string): void | [number, number, number] {
|
||||
return this._parseXColorName(data);
|
||||
public parseColorSpec(data: string): void | [number, number, number] {
|
||||
return this._parseColorSpec(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1872,54 +1872,54 @@ describe('InputHandler', () => {
|
||||
describe('parse xcolor names', () => {
|
||||
it('rgb:<r>/<g>/<b> scheme in 4/8/12/16 bit', () => {
|
||||
// 4 bit
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:0/0/0'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:f/f/f'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:1/2/3'), [17, 34, 51]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:0/0/0'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:f/f/f'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:1/2/3'), [17, 34, 51]);
|
||||
// 8 bit
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:00/00/00'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:ff/ff/ff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:11/22/33'), [17, 34, 51]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:00/00/00'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:ff/ff/ff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:11/22/33'), [17, 34, 51]);
|
||||
// 12 bit
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:000/000/000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:fff/fff/fff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:111/222/333'), [17, 34, 51]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:000/000/000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:fff/fff/fff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:111/222/333'), [17, 34, 51]);
|
||||
// 16 bit
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:0000/0000/0000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:ffff/ffff/ffff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('rgb:1111/2222/3333'), [17, 34, 51]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:0000/0000/0000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:ffff/ffff/ffff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('rgb:1111/2222/3333'), [17, 34, 51]);
|
||||
});
|
||||
it('#RGB scheme in 4/8/12/16 bit', () => {
|
||||
// 4 bit
|
||||
assert.deepEqual(inputHandler.parseXColorName('#000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('#fff'), [240, 240, 240]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('#123'), [16, 32, 48]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#fff'), [240, 240, 240]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#123'), [16, 32, 48]);
|
||||
// 8 bit
|
||||
assert.deepEqual(inputHandler.parseXColorName('#000000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('#ffffff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('#112233'), [17, 34, 51]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#000000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#ffffff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#112233'), [17, 34, 51]);
|
||||
// 12 bit
|
||||
assert.deepEqual(inputHandler.parseXColorName('#000000000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('#fffffffff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('#111222333'), [17, 34, 51]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#000000000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#fffffffff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#111222333'), [17, 34, 51]);
|
||||
// 16 bit
|
||||
assert.deepEqual(inputHandler.parseXColorName('#000000000000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('#ffffffffffff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('#111122223333'), [17, 34, 51]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#000000000000'), [0, 0, 0]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#ffffffffffff'), [255, 255, 255]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#111122223333'), [17, 34, 51]);
|
||||
});
|
||||
it('supports upper case', () => {
|
||||
assert.deepEqual(inputHandler.parseXColorName('RGB:0/A/F'), [0, 170, 255]);
|
||||
assert.deepEqual(inputHandler.parseXColorName('#FFF'), [240, 240, 240]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('RGB:0/A/F'), [0, 170, 255]);
|
||||
assert.deepEqual(inputHandler.parseColorSpec('#FFF'), [240, 240, 240]);
|
||||
});
|
||||
it('does not parse illegal combinations', () => {
|
||||
// shifting bit width
|
||||
assert.equal(inputHandler.parseXColorName('rgb:0/11/222'), undefined);
|
||||
assert.equal(inputHandler.parseColorSpec('rgb:0/11/222'), undefined);
|
||||
// unsupported scheme
|
||||
assert.equal(inputHandler.parseXColorName('rgbi:00/11/22'), undefined);
|
||||
assert.equal(inputHandler.parseColorSpec('rgbi:00/11/22'), undefined);
|
||||
// broken # specifier
|
||||
assert.equal(inputHandler.parseXColorName('#aabbbcc'), undefined);
|
||||
assert.equal(inputHandler.parseColorSpec('#aabbbcc'), undefined);
|
||||
// out of range
|
||||
assert.equal(inputHandler.parseXColorName('#aabbgg'), undefined);
|
||||
assert.equal(inputHandler.parseXColorName('rgb:aa/bb/gg'), undefined);
|
||||
assert.equal(inputHandler.parseColorSpec('#aabbgg'), undefined);
|
||||
assert.equal(inputHandler.parseColorSpec('rgb:aa/bb/gg'), undefined);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+35
-25
@@ -2866,7 +2866,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse xcolor name to RGB values (8 bit per channel).
|
||||
* Parse color spec to RGB values (8 bit per channel).
|
||||
* See `man xparsecolor` for details about certain format specifications.
|
||||
*
|
||||
* Supported formats:
|
||||
@@ -2876,7 +2876,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* All other formats like rgbi: or device-independent string specifications
|
||||
* with float numbering are not supported.
|
||||
*/
|
||||
protected _parseXColorName(data: string): [number, number, number] | void {
|
||||
protected _parseColorSpec(data: string): [number, number, number] | void {
|
||||
// also handle uppercases
|
||||
data = data.toLowerCase();
|
||||
if (data.indexOf('rgb:') === 0) {
|
||||
@@ -2898,19 +2898,12 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
const rex = /^[\da-f]+$/;
|
||||
if (rex.exec(data) && [3, 6, 9, 12].includes(data.length)) {
|
||||
const adv = data.length / 3;
|
||||
const r = parseInt(data.slice(0, adv), 16);
|
||||
const g = parseInt(data.slice(adv, 2 * adv), 16);
|
||||
const b = parseInt(data.slice(2 * adv, 3 * adv), 16);
|
||||
switch (adv) {
|
||||
case 1:
|
||||
return [r << 4, g << 4, b << 4];
|
||||
case 2:
|
||||
return [r, g, b];
|
||||
case 3:
|
||||
return [r >> 4, g >> 4, b >> 4];
|
||||
case 4:
|
||||
return [r >> 8, g >> 8, b >> 8];
|
||||
const result: [number, number, number] = [0, 0, 0];
|
||||
for (let i = 0; i < 3; ++i) {
|
||||
const c = parseInt(data.slice(adv * i, adv * i + adv), 16);
|
||||
result[i] = adv === 1 ? c << 4 : adv === 2 ? c : adv === 3 ? c >> 4 : c >> 8;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2933,20 +2926,36 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* OSC 10 ; <xcolor name>|<?> ST - set or query default foreground color
|
||||
*
|
||||
* @vt: #Y OSC 10 "Set or query default foreground color" "OSC 10 ; Pt BEL" "Set or query default foreground color."
|
||||
* To set the color, the following color specification formats are supported:
|
||||
* - `rgb:<red>/<green>/<blue>` for `<red>, <green>, <blue>` in `h | hh | hhh | hhhh`, where
|
||||
* `h` is a single hexadecimal digit (case insignificant). The different widths scale
|
||||
* from 4 bit (`h`) to 16 bit (`hhhh`) and get converted to 8 bit (`hh`).
|
||||
* - `#RGB` - 4 bits per channel, expanded to `#R0G0B0`
|
||||
* - `#RRGGBB` - 8 bits per channel
|
||||
* - `#RRRGGGBBB` - 12 bits per channel, truncated to `#RRGGBB`
|
||||
* - `#RRRRGGGGBBBB` - 16 bits per channel, truncated to `#RRGGBB`
|
||||
*
|
||||
* If `Pt` contains `?` instead of a color specification, the terminal
|
||||
* returns a sequence with the current default foreground color
|
||||
* (use that sequence to restore the color after changes).
|
||||
*
|
||||
* **Note:** Other than xterm, xterm.js does not support OSC 12 - 19.
|
||||
* Therefore stacking multiple `Pt` separated by `;` only works for the first two entries.
|
||||
*/
|
||||
public queryOrSetFgColor(data: string): boolean {
|
||||
// note: data may contain multiple ? or color names separated with ;
|
||||
// Multiple values will map through to OSC 10 - 19, but we only support 10 and 11 currently,
|
||||
// thus truncate to max. 2 occurences.
|
||||
// thus truncate to max. 2 entries.
|
||||
const slots = data.split(';').slice(0, 2);
|
||||
if (slots[0] === '?') {
|
||||
// TODO: query FG color
|
||||
console.log('query FG');
|
||||
this._onColor.fire({ requests: [{ index: 256, color: '?' }] });
|
||||
} else {
|
||||
const color = this._parseXColorName(slots[0]);
|
||||
const color = this._parseColorSpec(slots[0]);
|
||||
if (color) {
|
||||
// set new FG color
|
||||
console.log('set FG', color);
|
||||
this._onColor.fire({ requests: [{ index: 256, color }] });
|
||||
}
|
||||
}
|
||||
@@ -2956,17 +2965,18 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* OSC 11 ; <xcolor name>|<?> ST - set or query default background color
|
||||
*
|
||||
* @vt: #Y OSC 11 "Set or query default background color" "OSC 11 ; Pt BEL" "Same as OSC 10, but for default background."
|
||||
*/
|
||||
public queryOrSetBgColor(data: string): boolean {
|
||||
const slots = data.split(';').slice(0, 1);
|
||||
if (slots[0] === '?') {
|
||||
// TODO: query BG color
|
||||
console.log('query BG');
|
||||
this._onColor.fire({ requests: [{ index: 257, color: '?' }] });
|
||||
} else {
|
||||
const color = this._parseXColorName(slots[0]);
|
||||
const color = this._parseColorSpec(slots[0]);
|
||||
if (color) {
|
||||
// set new BG color
|
||||
console.log('set BG', color);
|
||||
this._onColor.fire({ requests: [{ index: 257, color }] });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user