mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
cleanup API
This commit is contained in:
@@ -223,6 +223,8 @@ jobs:
|
||||
run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-unicode-graphemes
|
||||
- name: Integration tests (addon-unicode11)
|
||||
run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-unicode11
|
||||
- name: Integration tests (addon-web-fonts)
|
||||
run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-web-fonts
|
||||
- name: Integration tests (addon-web-links)
|
||||
run: yarn test-integration-${{ matrix.browser }} --workers=50% --forbid-only --suite=addon-web-links
|
||||
- name: Integration tests (addon-webgl)
|
||||
|
||||
@@ -72,7 +72,7 @@ const webFontsAddon = new WebFontsAddon();
|
||||
terminal.loadAddon(webFontsAddon);
|
||||
|
||||
// wait for webfonts to be fully loaded
|
||||
WebFontsAddon.loadFonts(['Web Mono 1', 'Super Powerline']).then(() => {
|
||||
webFontsAddon.loadFonts(['Web Mono 1', 'Super Powerline']).then(() => {
|
||||
terminal.open(your_terminal_div_element);
|
||||
// more boostrapping goes here ...
|
||||
});
|
||||
@@ -83,13 +83,13 @@ on the initial document load (more precise - by the time this code runs).
|
||||
|
||||
Please note, that this code cannot run synchronous anymore, so you will have to split your
|
||||
bootstrapping code into several stages. If thats too much of a hassle, you can also move the whole
|
||||
bootstrapping under that waiting condition (`loadFonts` is actually a static method):
|
||||
bootstrapping under that waiting condition (import `loadFonts` for a static variant):
|
||||
```typescript
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { XYAddon } from '@xterm/addon-xy';
|
||||
import { WebFontsAddon } from '@xterm/addon-web-fonts';
|
||||
import { WebFontsAddon, loadFonts } from '@xterm/addon-web-fonts';
|
||||
|
||||
WebFontsAddon.loadFonts(['Web Mono 1', 'Super Powerline']).then(() => {
|
||||
loadFonts(['Web Mono 1', 'Super Powerline']).then(() => {
|
||||
// create a `Terminal` instance, now with webfonts
|
||||
const terminal = new Terminal({fontFamily: '"Web Mono 1", "Super Powerline", monospace'});
|
||||
const xyAddon = new XYAddon();
|
||||
@@ -112,7 +112,7 @@ That can be achieved like this:
|
||||
const ff1 = new FontFace('New Web Mono', url1, ...);
|
||||
const ff2 = new FontFace('New Web Mono', url2, ...);
|
||||
// and await their loading
|
||||
WebFontsAddon.loadFonts([ff1, ff2]).then(() => {
|
||||
loadFonts([ff1, ff2]).then(() => {
|
||||
// apply new webfont to terminal
|
||||
terminal.options.fontFamily = 'New Web Mono';
|
||||
// since the new font might have slighly different metrics,
|
||||
@@ -124,7 +124,7 @@ WebFontsAddon.loadFonts([ff1, ff2]).then(() => {
|
||||
document.styleSheets[0].insertRule(
|
||||
"@font-face { font-family: 'New Web Mono'; src: url(newfont.woff); }", 0);
|
||||
// and await the new font family name
|
||||
WebFontsAddon.loadFonts(['New Web Mono']).then(() => {
|
||||
loadFonts(['New Web Mono']).then(() => {
|
||||
// apply new webfont to terminal
|
||||
terminal.options.fontFamily = 'New Web Mono';
|
||||
// since the new font might have slighly different metrics,
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { WebFontsAddon as IWebFontsApi } from '@xterm/addon-web-fonts';
|
||||
|
||||
|
||||
/**
|
||||
* Unquote family name.
|
||||
* Unquote a font family name.
|
||||
*/
|
||||
function unquote(s: string): string {
|
||||
if (s[0] === '"' && s[s.length - 1] === '"') return s.slice(1, -1);
|
||||
@@ -18,7 +18,7 @@ function unquote(s: string): string {
|
||||
|
||||
|
||||
/**
|
||||
* Quote family name.
|
||||
* Quote a font family name conditionally.
|
||||
* @see https://mathiasbynens.be/notes/unquoted-font-family
|
||||
*/
|
||||
function quote(s: string): string {
|
||||
@@ -40,16 +40,46 @@ function createFamily(families: string[]): string {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hash a font face from it properties.
|
||||
* Used in `loadFonts` to avoid bloating
|
||||
* `document.fonts` from multiple calls.
|
||||
*/
|
||||
function hashFontFace(ff: FontFace): string {
|
||||
return JSON.stringify([
|
||||
unquote(ff.family),
|
||||
ff.stretch,
|
||||
ff.style,
|
||||
ff.unicodeRange,
|
||||
ff.weight
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wait for webfont resources to be loaded.
|
||||
*
|
||||
* Without any argument, all fonts currently listed in
|
||||
* `document.fonts` will be loaded.
|
||||
* For a more fine-grained loading strategy you can populate
|
||||
* the `fonts` argument with:
|
||||
* - font families : loads all fontfaces in `document.fonts`
|
||||
* matching the family names
|
||||
* - fontface objects : loads given fontfaces and adds them to
|
||||
* `document.fonts`
|
||||
*
|
||||
* The returned promise will resolve, when all loading is done.
|
||||
*/
|
||||
function _loadFonts(fonts?: (string | FontFace)[]): Promise<FontFace[]> {
|
||||
const ffs = Array.from(document.fonts);
|
||||
if (!fonts || !fonts.length) {
|
||||
return Promise.all(ffs.map(ff => ff.load()));
|
||||
}
|
||||
let toLoad: FontFace[] = [];
|
||||
const ffsHashed = ffs.map(ff => WebFontsAddon.hashFontFace(ff));
|
||||
const ffsHashed = ffs.map(ff => hashFontFace(ff));
|
||||
for (const font of fonts) {
|
||||
if (font instanceof FontFace) {
|
||||
const fontHashed = WebFontsAddon.hashFontFace(font);
|
||||
const fontHashed = hashFontFace(font);
|
||||
const idx = ffsHashed.indexOf(fontHashed);
|
||||
if (idx === -1) {
|
||||
document.fonts.add(font);
|
||||
@@ -72,85 +102,53 @@ function _loadFonts(fonts?: (string | FontFace)[]): Promise<FontFace[]> {
|
||||
}
|
||||
|
||||
|
||||
export async function loadFonts(fonts?: (string | FontFace)[]): Promise<FontFace[]> {
|
||||
await document.fonts.ready;
|
||||
return _loadFonts(fonts);
|
||||
}
|
||||
|
||||
|
||||
export class WebFontsAddon implements ITerminalAddon, IWebFontsApi {
|
||||
constructor(public forceInitialRelayout: boolean = true) { }
|
||||
public dispose(): void { }
|
||||
private _term: Terminal | undefined;
|
||||
|
||||
public activate(terminal: Terminal): void {
|
||||
constructor(public forceInitialRelayout: boolean = true) { }
|
||||
|
||||
public dispose(): void {
|
||||
this._term = undefined;
|
||||
}
|
||||
|
||||
public activate(term: Terminal): void {
|
||||
this._term = term;
|
||||
if (this.forceInitialRelayout) {
|
||||
document.fonts.ready.then(() => this.relayout(terminal));
|
||||
document.fonts.ready.then(() => this.relayout());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a terminal re-layout by altering `options.FontFamily`.
|
||||
*
|
||||
* Found webfonts in `fontFamily` are temporarily removed until the webfont
|
||||
* resources are fully loaded.
|
||||
*
|
||||
* This method is meant as a fallback fix for sloppy integrations,
|
||||
* that wrongly placed a webfont at the terminal contructor options.
|
||||
* It is likely to lead to terminal flickering in all browsers (FOUT).
|
||||
*
|
||||
* To avoid triggering this fallback in your integration, make sure to have
|
||||
* the needed webfonts loaded at the time `terminal.open` is called.
|
||||
*/
|
||||
public relayout(terminal: Terminal): void {
|
||||
const family = terminal.options.fontFamily;
|
||||
public async loadFonts(fonts?: (string | FontFace)[]): Promise<FontFace[]> {
|
||||
return loadFonts(fonts);
|
||||
}
|
||||
|
||||
public async relayout(): Promise<void> {
|
||||
if (!this._term) {
|
||||
return;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
const family = this._term.options.fontFamily;
|
||||
const families = splitFamily(family);
|
||||
const webFamilies = WebFontsAddon.getFontFamilies();
|
||||
const webFamilies = Array.from(new Set(Array.from(document.fonts).map(e => unquote(e.family))));
|
||||
const dirty: string[] = [];
|
||||
const clean: string[] = [];
|
||||
for (const fam of families) {
|
||||
(webFamilies.indexOf(fam) !== -1 ? dirty : clean).push(fam);
|
||||
}
|
||||
if (dirty.length) {
|
||||
_loadFonts(dirty).then(() => {
|
||||
terminal.options.fontFamily = clean.length ? createFamily(clean) : 'monospace';
|
||||
terminal.options.fontFamily = family;
|
||||
});
|
||||
if (!dirty.length) {
|
||||
return;
|
||||
}
|
||||
await _loadFonts(dirty);
|
||||
if (this._term) {
|
||||
this._term.options.fontFamily = clean.length ? createFamily(clean) : 'monospace';
|
||||
this._term.options.fontFamily = family;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash a font face from it properties.
|
||||
* Used in `loadFonts` to avoid bloating
|
||||
* `document.fonts` from multiple calls.
|
||||
*/
|
||||
public static hashFontFace(ff: FontFace): string {
|
||||
return JSON.stringify([
|
||||
unquote(ff.family),
|
||||
ff.stretch,
|
||||
ff.style,
|
||||
ff.unicodeRange,
|
||||
ff.weight
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return font families known in `document.fonts`.
|
||||
*/
|
||||
public static getFontFamilies(): string[] {
|
||||
return Array.from(new Set(Array.from(document.fonts).map(e => unquote(e.family))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for webfont resources to be loaded.
|
||||
*
|
||||
* Without any argument, all fonts currently listed in
|
||||
* `document.fonts` will be loaded.
|
||||
* For a more fine-grained loading strategy you can populate
|
||||
* the `fonts` argument with:
|
||||
* - font families : loads all fontfaces in `document.fonts`
|
||||
* matching the family names
|
||||
* - fontface objects : loads given fontfaces and adds them to
|
||||
* `document.fonts`
|
||||
*
|
||||
* The returned promise will resolve, when all loading is done.
|
||||
*/
|
||||
public static loadFonts(fonts?: (string | FontFace)[]): Promise<FontFace[]> {
|
||||
return document.fonts.ready.then(() => _loadFonts(fonts));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+52
-3
@@ -4,15 +4,64 @@
|
||||
*/
|
||||
|
||||
|
||||
import { Terminal, ITerminalAddon, IViewportRange } from '@xterm/xterm';
|
||||
import { Terminal, ITerminalAddon } from '@xterm/xterm';
|
||||
|
||||
declare module '@xterm/addon-web-fonts' {
|
||||
|
||||
/**
|
||||
* An xterm.js addon that enables web links.
|
||||
* Addon to use webfonts in xterm.js
|
||||
*/
|
||||
export class WebFontsAddon implements ITerminalAddon {
|
||||
constructor();
|
||||
/**
|
||||
* @param forceInitialRelayout Force an initial relayout, if a webfont was found.
|
||||
*/
|
||||
constructor(forceInitialRelayout?: boolean);
|
||||
public activate(terminal: Terminal): void;
|
||||
public dispose(): void;
|
||||
|
||||
/**
|
||||
* Wait for webfont resources to be loaded.
|
||||
*
|
||||
* Without any argument, all fonts currently listed in
|
||||
* `document.fonts` will be loaded.
|
||||
* For a more fine-grained loading strategy you can populate
|
||||
* the `fonts` argument with:
|
||||
* - font families : loads all fontfaces in `document.fonts`
|
||||
* matching the family names
|
||||
* - fontface objects : loads given fontfaces and adds them to
|
||||
* `document.fonts`
|
||||
*
|
||||
* The returned promise will resolve, when all loading is done.
|
||||
*/
|
||||
public loadFonts(fonts?: (string | FontFace)[]): Promise<FontFace[]>;
|
||||
|
||||
/**
|
||||
* Force a terminal relayout by altering `options.FontFamily`.
|
||||
*
|
||||
* Found webfonts in `fontFamily` are temporarily removed until the webfont
|
||||
* resources are fully loaded.
|
||||
*
|
||||
* Call this method, if a terminal with webfonts is stuck with broken
|
||||
* glyph metrics.
|
||||
*
|
||||
* Returns a promise on completion.
|
||||
*/
|
||||
public relayout(): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for webfont resources to be loaded.
|
||||
*
|
||||
* Without any argument, all fonts currently listed in
|
||||
* `document.fonts` will be loaded.
|
||||
* For a more fine-grained loading strategy you can populate
|
||||
* the `fonts` argument with:
|
||||
* - font families : loads all fontfaces in `document.fonts`
|
||||
* matching the family names
|
||||
* - fontface objects : loads given fontfaces and adds them to
|
||||
* `document.fonts`
|
||||
*
|
||||
* The returned promise will resolve, when all loading is done.
|
||||
*/
|
||||
function loadFonts(fonts?: (string | FontFace)[]): Promise<FontFace[]>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user