mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge pull request #2518 from Tyriar/2407_toggle_addons
Support check boxes in demo to toggle addons
This commit is contained in:
+76
-13
@@ -39,13 +39,39 @@ export interface IWindowWithTerminal extends Window {
|
||||
declare let window: IWindowWithTerminal;
|
||||
|
||||
let term;
|
||||
let fitAddon: FitAddon;
|
||||
let searchAddon: SearchAddon;
|
||||
let protocol;
|
||||
let socketURL;
|
||||
let socket;
|
||||
let pid;
|
||||
|
||||
type AddonType = 'attach' | 'fit' | 'search' | 'web-links' | 'webgl';
|
||||
|
||||
interface IDemoAddon<T extends AddonType> {
|
||||
name: T;
|
||||
canChange: boolean;
|
||||
ctor:
|
||||
T extends 'attach' ? typeof AttachAddon :
|
||||
T extends 'fit' ? typeof FitAddon :
|
||||
T extends 'search' ? typeof SearchAddon :
|
||||
T extends 'web-links' ? typeof WebLinksAddon :
|
||||
typeof WebglAddon;
|
||||
instance?:
|
||||
T extends 'attach' ? AttachAddon :
|
||||
T extends 'fit' ? FitAddon :
|
||||
T extends 'search' ? SearchAddon :
|
||||
T extends 'web-links' ? WebLinksAddon :
|
||||
T extends 'webgl' ? WebglAddon :
|
||||
never;
|
||||
}
|
||||
|
||||
const addons: { [T in AddonType]: IDemoAddon<T>} = {
|
||||
attach: { name: 'attach', ctor: AttachAddon, canChange: false },
|
||||
fit: { name: 'fit', ctor: FitAddon, canChange: false },
|
||||
search: { name: 'search', ctor: SearchAddon, canChange: true },
|
||||
'web-links': { name: 'web-links', ctor: WebLinksAddon, canChange: true },
|
||||
webgl: { name: 'webgl', ctor: WebglAddon, canChange: true }
|
||||
};
|
||||
|
||||
const terminalContainer = document.getElementById('terminal-container');
|
||||
const actionElements = {
|
||||
findNext: <HTMLInputElement>document.querySelector('#find-next'),
|
||||
@@ -92,7 +118,6 @@ if (document.location.pathname === '/test') {
|
||||
} else {
|
||||
createTerminal();
|
||||
document.getElementById('dispose').addEventListener('click', disposeRecreateButtonHandler);
|
||||
document.getElementById('webgl').addEventListener('click', () => term.loadAddon(new WebglAddon()));
|
||||
}
|
||||
|
||||
function createTerminal(): void {
|
||||
@@ -108,11 +133,12 @@ function createTerminal(): void {
|
||||
|
||||
// Load addons
|
||||
const typedTerm = term as TerminalType;
|
||||
typedTerm.loadAddon(new WebLinksAddon());
|
||||
searchAddon = new SearchAddon();
|
||||
typedTerm.loadAddon(searchAddon);
|
||||
fitAddon = new FitAddon();
|
||||
typedTerm.loadAddon(fitAddon);
|
||||
addons['web-links'].instance = new WebLinksAddon();
|
||||
addons.search.instance = new SearchAddon();
|
||||
addons.fit.instance = new FitAddon();
|
||||
typedTerm.loadAddon(addons['web-links'].instance);
|
||||
typedTerm.loadAddon(addons.search.instance);
|
||||
typedTerm.loadAddon(addons.fit.instance);
|
||||
|
||||
window.term = term; // Expose `term` to window for debugging purposes
|
||||
term.onResize((size: { cols: number, rows: number }) => {
|
||||
@@ -129,17 +155,17 @@ function createTerminal(): void {
|
||||
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/';
|
||||
|
||||
term.open(terminalContainer);
|
||||
fitAddon.fit();
|
||||
addons.fit.instance!.fit();
|
||||
term.focus();
|
||||
|
||||
addDomListener(paddingElement, 'change', setPadding);
|
||||
|
||||
addDomListener(actionElements.findNext, 'keyup', (e) => {
|
||||
searchAddon.findNext(actionElements.findNext.value, getSearchOptions(e));
|
||||
addons.search.instance.findNext(actionElements.findNext.value, getSearchOptions(e));
|
||||
});
|
||||
|
||||
addDomListener(actionElements.findPrevious, 'keyup', (e) => {
|
||||
searchAddon.findPrevious(actionElements.findPrevious.value, getSearchOptions(e));
|
||||
addons.search.instance.findPrevious(actionElements.findPrevious.value, getSearchOptions(e));
|
||||
});
|
||||
|
||||
// fit is called within a setTimeout, cols and rows need this.
|
||||
@@ -167,8 +193,10 @@ function createTerminal(): void {
|
||||
}
|
||||
|
||||
function runRealTerminal(): void {
|
||||
term.loadAddon(new AttachAddon(socket));
|
||||
addons.attach.instance = new AttachAddon(socket);
|
||||
term.loadAddon(addons.attach.instance);
|
||||
term._initialized = true;
|
||||
initAddons(term);
|
||||
}
|
||||
|
||||
function runFakeTerminal(): void {
|
||||
@@ -177,6 +205,7 @@ function runFakeTerminal(): void {
|
||||
}
|
||||
|
||||
term._initialized = true;
|
||||
initAddons(term);
|
||||
|
||||
term.prompt = () => {
|
||||
term.write('\r\n$ ');
|
||||
@@ -300,6 +329,40 @@ function initOptions(term: TerminalType): void {
|
||||
});
|
||||
}
|
||||
|
||||
function initAddons(term: TerminalType): void {
|
||||
const fragment = document.createDocumentFragment();
|
||||
Object.keys(addons).forEach((name: AddonType) => {
|
||||
const addon = addons[name];
|
||||
const checkbox = document.createElement('input') as HTMLInputElement;
|
||||
checkbox.type = 'checkbox';
|
||||
checkbox.checked = !!addon.instance;
|
||||
if (!addon.canChange) {
|
||||
checkbox.disabled = true;
|
||||
}
|
||||
checkbox.addEventListener('change', () => {
|
||||
if (checkbox.checked) {
|
||||
addon.instance = new addon.ctor();
|
||||
term.loadAddon(addon.instance);
|
||||
} else {
|
||||
addon.instance!.dispose();
|
||||
addon.instance = undefined;
|
||||
}
|
||||
});
|
||||
const label = document.createElement('label');
|
||||
label.classList.add('addon');
|
||||
if (!addon.canChange) {
|
||||
label.title = 'This addon is needed for the demo to operate';
|
||||
}
|
||||
label.appendChild(checkbox);
|
||||
label.appendChild(document.createTextNode(name));
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.classList.add('addon');
|
||||
wrapper.appendChild(label);
|
||||
fragment.appendChild(wrapper);
|
||||
});
|
||||
document.getElementById('addons-container').appendChild(fragment);
|
||||
}
|
||||
|
||||
function addDomListener(element: HTMLElement, type: string, handler: (...args: any[]) => any): void {
|
||||
element.addEventListener(type, handler);
|
||||
term._core.register({ dispose: () => element.removeEventListener(type, handler) });
|
||||
@@ -312,5 +375,5 @@ function updateTerminalSize(): void {
|
||||
const height = (rows * term._core._renderService.dimensions.actualCellHeight).toString() + 'px';
|
||||
terminalContainer.style.width = width;
|
||||
terminalContainer.style.height = height;
|
||||
fitAddon.fit();
|
||||
addons.fit.instance.fit();
|
||||
}
|
||||
|
||||
+5
-1
@@ -26,6 +26,11 @@
|
||||
<p>These options can be set in the <code>Terminal</code> constructor or using the <code>Terminal.setOption</code> function.</p>
|
||||
<div id="options-container"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Addons</h3>
|
||||
<p>Addons can be loaded and unloaded on a particular terminal to extend its functionality.</p>
|
||||
<div id="addons-container"></div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Style</h3>
|
||||
<div style="display: inline-block; margin-right: 16px;">
|
||||
@@ -36,7 +41,6 @@
|
||||
<hr/>
|
||||
<p><strong>Attention:</strong> The demo is a barebones implementation and is designed for the development and evaluation of xterm.js only. Exposing the demo to the public as is would introduce security risks for the host.</p>
|
||||
<button id="dispose" title="This is used to testing memory leaks">Dispose terminal</button>
|
||||
<button id="webgl">Enable WebGL Renderer</button>
|
||||
<script src="dist/client-bundle.js" defer ></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user