mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
+5
-2
@@ -91,8 +91,6 @@
|
||||
}
|
||||
|
||||
.xterm .xterm-viewport {
|
||||
/* On OS X this is required in order for the scroll bar to appear fully opaque */
|
||||
background-color: #000;
|
||||
overflow-y: scroll;
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
@@ -102,6 +100,11 @@
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.xterm:not(.allow-transparency) .xterm-viewport {
|
||||
/* On OS X this is required in order for the scroll bar to appear fully opaque */
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ function createTerminal(): Terminal {
|
||||
buildNumber: 22621
|
||||
} : undefined,
|
||||
fontFamily: '"Fira Code", monospace, "Powerline Extra Symbols"',
|
||||
theme: xtermjsTheme
|
||||
theme: { ...xtermjsTheme }
|
||||
} as ITerminalOptions);
|
||||
|
||||
// Load addons
|
||||
@@ -419,8 +419,11 @@ function runFakeTerminal(): void {
|
||||
}
|
||||
|
||||
function updateTerminalContainerBackground(): void {
|
||||
const bg = term.options.theme?.background ?? '#000000';
|
||||
terminalContainer.style.backgroundColor = bg;
|
||||
if (term.options.allowTransparency) {
|
||||
terminalContainer.style.background = 'repeating-conic-gradient(#000000 0% 25%, #101010 0% 50%) 50% / 20px 20px';
|
||||
} else {
|
||||
terminalContainer.style.background = term.options.theme?.background ?? '#000000';
|
||||
}
|
||||
}
|
||||
|
||||
function initAddons(term: Terminal): void {
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { Terminal, ITheme } from '@xterm/xterm';
|
||||
import type { IControlWindow } from '../controlBar';
|
||||
import type { AddonCollection } from 'types';
|
||||
|
||||
const xtermjsTheme: ITheme = {
|
||||
const xtermjsTheme: ITheme = Object.freeze({
|
||||
foreground: '#F8F8F8',
|
||||
background: '#2D2E2C',
|
||||
selectionBackground: '#5DA5D533',
|
||||
@@ -29,7 +29,52 @@ const xtermjsTheme: ITheme = {
|
||||
brightCyan: '#72F0FF',
|
||||
white: '#F8F8F8',
|
||||
brightWhite: '#FFFFFF'
|
||||
};
|
||||
});
|
||||
const sapphireTheme: ITheme = Object.freeze({
|
||||
background: '#1c2431',
|
||||
foreground: '#cccccc',
|
||||
selectionBackground: '#399ef440',
|
||||
black: '#666666',
|
||||
blue: '#399ef4',
|
||||
brightBlack: '#666666',
|
||||
brightBlue: '#399ef4',
|
||||
brightCyan: '#21c5c7',
|
||||
brightGreen: '#4eb071',
|
||||
brightMagenta: '#b168df',
|
||||
brightRed: '#da6771',
|
||||
brightWhite: '#efefef',
|
||||
brightYellow: '#fff099',
|
||||
cyan: '#21c5c7',
|
||||
green: '#4eb071',
|
||||
magenta: '#b168df',
|
||||
red: '#da6771',
|
||||
white: '#efefef',
|
||||
yellow: '#fff099'
|
||||
});
|
||||
const lightTheme: ITheme = Object.freeze({
|
||||
background: '#ffffff',
|
||||
foreground: '#333333',
|
||||
cursor: '#333333',
|
||||
cursorAccent: '#ffffff',
|
||||
selectionBackground: '#add6ff',
|
||||
overviewRulerBorder: '#aaaaaa',
|
||||
black: '#000000',
|
||||
blue: '#0451a5',
|
||||
brightBlack: '#666666',
|
||||
brightBlue: '#0451a5',
|
||||
brightCyan: '#0598bc',
|
||||
brightGreen: '#14ce14',
|
||||
brightMagenta: '#bc05bc',
|
||||
brightRed: '#cd3131',
|
||||
brightWhite: '#a5a5a5',
|
||||
brightYellow: '#b5ba00',
|
||||
cyan: '#0598bc',
|
||||
green: '#00bc00',
|
||||
magenta: '#bc05bc',
|
||||
red: '#cd3131',
|
||||
white: '#555555',
|
||||
yellow: '#949800'
|
||||
});
|
||||
|
||||
export class OptionsWindow extends BaseWindow implements IControlWindow {
|
||||
public readonly id = 'options';
|
||||
@@ -136,6 +181,10 @@ export class OptionsWindow extends BaseWindow implements IControlWindow {
|
||||
addDomListener(input, 'change', () => {
|
||||
console.log('change', o, input.checked);
|
||||
this._terminal.options[o] = input.checked;
|
||||
if (o ==='allowTransparency') {
|
||||
this._terminal.options.theme = this._getTheme();
|
||||
this._handlers.updateTerminalContainerBackground();
|
||||
}
|
||||
});
|
||||
});
|
||||
numberOptions.forEach(o => {
|
||||
@@ -171,63 +220,7 @@ export class OptionsWindow extends BaseWindow implements IControlWindow {
|
||||
this._handlers.updateTerminalSize();
|
||||
}
|
||||
} else if (o === 'theme') {
|
||||
switch (input.value) {
|
||||
case 'default':
|
||||
value = undefined;
|
||||
break;
|
||||
case 'xtermjs':
|
||||
value = xtermjsTheme;
|
||||
break;
|
||||
case 'sapphire':
|
||||
value = {
|
||||
background: '#1c2431',
|
||||
foreground: '#cccccc',
|
||||
selectionBackground: '#399ef440',
|
||||
black: '#666666',
|
||||
blue: '#399ef4',
|
||||
brightBlack: '#666666',
|
||||
brightBlue: '#399ef4',
|
||||
brightCyan: '#21c5c7',
|
||||
brightGreen: '#4eb071',
|
||||
brightMagenta: '#b168df',
|
||||
brightRed: '#da6771',
|
||||
brightWhite: '#efefef',
|
||||
brightYellow: '#fff099',
|
||||
cyan: '#21c5c7',
|
||||
green: '#4eb071',
|
||||
magenta: '#b168df',
|
||||
red: '#da6771',
|
||||
white: '#efefef',
|
||||
yellow: '#fff099'
|
||||
};
|
||||
break;
|
||||
case 'light':
|
||||
value = {
|
||||
background: '#ffffff',
|
||||
foreground: '#333333',
|
||||
cursor: '#333333',
|
||||
cursorAccent: '#ffffff',
|
||||
selectionBackground: '#add6ff',
|
||||
overviewRulerBorder: '#aaaaaa',
|
||||
black: '#000000',
|
||||
blue: '#0451a5',
|
||||
brightBlack: '#666666',
|
||||
brightBlue: '#0451a5',
|
||||
brightCyan: '#0598bc',
|
||||
brightGreen: '#14ce14',
|
||||
brightMagenta: '#bc05bc',
|
||||
brightRed: '#cd3131',
|
||||
brightWhite: '#a5a5a5',
|
||||
brightYellow: '#b5ba00',
|
||||
cyan: '#0598bc',
|
||||
green: '#00bc00',
|
||||
magenta: '#bc05bc',
|
||||
red: '#cd3131',
|
||||
white: '#555555',
|
||||
yellow: '#949800'
|
||||
};
|
||||
break;
|
||||
}
|
||||
value = this._getTheme();
|
||||
}
|
||||
this._terminal.options[o] = value;
|
||||
if (o === 'theme') {
|
||||
@@ -244,4 +237,27 @@ export class OptionsWindow extends BaseWindow implements IControlWindow {
|
||||
public set autoResize(value: boolean) {
|
||||
this._autoResize = value;
|
||||
}
|
||||
|
||||
private _getTheme() {
|
||||
const input = document.querySelector<HTMLInputElement>('#opt-theme');
|
||||
let theme: ITheme;
|
||||
switch (input.value) {
|
||||
case 'default':
|
||||
theme = undefined;
|
||||
break;
|
||||
case 'xtermjs':
|
||||
theme = { ...xtermjsTheme };
|
||||
break;
|
||||
case 'sapphire':
|
||||
theme = { ...sapphireTheme };
|
||||
break;
|
||||
case 'light':
|
||||
theme = { ...lightTheme };
|
||||
break;
|
||||
}
|
||||
if (this._terminal.options.allowTransparency) {
|
||||
theme.background = 'transparent';
|
||||
}
|
||||
return theme;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,6 +436,8 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
||||
this.element.dir = 'ltr'; // xterm.css assumes LTR
|
||||
this.element.classList.add('terminal');
|
||||
this.element.classList.add('xterm');
|
||||
this.element.classList.toggle('allow-transparency', this.options.allowTransparency);
|
||||
this._register(this.optionsService.onSpecificOptionChange('allowTransparency', value => this.element!.classList.toggle('allow-transparency', value)));
|
||||
parent.appendChild(this.element);
|
||||
|
||||
// Performance: Use a document fragment to build the terminal
|
||||
|
||||
@@ -71,6 +71,7 @@ export class Viewport extends Disposable {
|
||||
|
||||
this._scrollableElement.setScrollDimensions({ height: 0, scrollHeight: 0 });
|
||||
this._register(Event.runAndSubscribe(themeService.onChangeColors, () => {
|
||||
element.style.backgroundColor = themeService.colors.background.css;
|
||||
this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css;
|
||||
}));
|
||||
element.appendChild(this._scrollableElement.getDomNode());
|
||||
|
||||
@@ -303,6 +303,9 @@ describe('Color', () => {
|
||||
assert.deepEqual(css.toColor('rgba(0, 0, 80, 0.5)'), { css: '#00005080', rgba: 0x00005080 });
|
||||
assert.deepEqual(css.toColor('rgba(255, 255, 255, 1)'), { css: '#ffffffff', rgba: 0xffffffff });
|
||||
});
|
||||
it('should convert "transparent" to an IColor', () => {
|
||||
assert.deepEqual(css.toColor('transparent'), { css: 'transparent', rgba: 0x00000000 });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -184,6 +184,14 @@ export namespace css {
|
||||
return channels.toColor($r, $g, $b, $a);
|
||||
}
|
||||
|
||||
// Handle the "transparent" keyword
|
||||
if (css === 'transparent') {
|
||||
return {
|
||||
css: 'transparent',
|
||||
rgba: 0x00000000
|
||||
};
|
||||
}
|
||||
|
||||
// Validate the context is available for canvas-based color parsing
|
||||
if (!$ctx || !$litmusColor) {
|
||||
throw new Error('css.toColor: Unsupported css format');
|
||||
|
||||
Reference in New Issue
Block a user