2017-05-21 23:16:24 +00:00
|
|
|
import * as bare from "xterm";
|
2017-08-26 07:53:17 +00:00
|
|
|
import { lib } from "libapps"
|
|
|
|
|
2017-05-21 23:16:24 +00:00
|
|
|
|
|
|
|
bare.loadAddon("fit");
|
|
|
|
|
2017-08-22 06:59:24 +00:00
|
|
|
export class Xterm {
|
2017-05-21 23:16:24 +00:00
|
|
|
elem: HTMLElement;
|
2017-08-26 07:53:17 +00:00
|
|
|
term: bare;
|
|
|
|
resizeListener: () => void;
|
|
|
|
decoder: lib.UTF8Decoder;
|
2017-05-21 23:16:24 +00:00
|
|
|
|
|
|
|
message: HTMLElement;
|
|
|
|
messageTimeout: number;
|
2021-04-16 13:49:17 +00:00
|
|
|
messageTimer: NodeJS.Timeout;
|
2017-05-21 23:16:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
constructor(elem: HTMLElement) {
|
|
|
|
this.elem = elem;
|
|
|
|
this.term = new bare();
|
|
|
|
|
|
|
|
this.message = elem.ownerDocument.createElement("div");
|
|
|
|
this.message.className = "xterm-overlay";
|
|
|
|
this.messageTimeout = 2000;
|
|
|
|
|
|
|
|
this.resizeListener = () => {
|
|
|
|
this.term.fit();
|
|
|
|
this.term.scrollToBottom();
|
|
|
|
this.showMessage(String(this.term.cols) + "x" + String(this.term.rows), this.messageTimeout);
|
|
|
|
};
|
|
|
|
|
|
|
|
this.term.on("open", () => {
|
|
|
|
this.resizeListener();
|
|
|
|
window.addEventListener("resize", () => { this.resizeListener(); });
|
|
|
|
});
|
|
|
|
|
|
|
|
this.term.open(elem, true);
|
2017-08-26 07:53:17 +00:00
|
|
|
|
|
|
|
this.decoder = new lib.UTF8Decoder()
|
2017-05-21 23:16:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
info(): { columns: number, rows: number } {
|
|
|
|
return { columns: this.term.cols, rows: this.term.rows };
|
|
|
|
};
|
|
|
|
|
|
|
|
output(data: string) {
|
2017-08-26 07:53:17 +00:00
|
|
|
this.term.write(this.decoder.decode(data));
|
2017-05-21 23:16:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
showMessage(message: string, timeout: number) {
|
|
|
|
this.message.textContent = message;
|
|
|
|
this.elem.appendChild(this.message);
|
|
|
|
|
|
|
|
if (this.messageTimer) {
|
|
|
|
clearTimeout(this.messageTimer);
|
|
|
|
}
|
|
|
|
if (timeout > 0) {
|
|
|
|
this.messageTimer = setTimeout(() => {
|
|
|
|
this.elem.removeChild(this.message);
|
|
|
|
}, timeout);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
removeMessage(): void {
|
|
|
|
if (this.message.parentNode == this.elem) {
|
|
|
|
this.elem.removeChild(this.message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setWindowTitle(title: string) {
|
|
|
|
document.title = title;
|
|
|
|
};
|
|
|
|
|
|
|
|
setPreferences(value: object) {
|
|
|
|
};
|
|
|
|
|
|
|
|
onInput(callback: (input: string) => void) {
|
|
|
|
this.term.on("data", (data) => {
|
|
|
|
callback(data);
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
onResize(callback: (colmuns: number, rows: number) => void) {
|
|
|
|
this.term.on("resize", (data) => {
|
|
|
|
callback(data.cols, data.rows);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
deactivate(): void {
|
|
|
|
this.term.off("data");
|
|
|
|
this.term.off("resize");
|
|
|
|
this.term.blur();
|
|
|
|
}
|
|
|
|
|
|
|
|
reset(): void {
|
|
|
|
this.removeMessage();
|
|
|
|
this.term.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
close(): void {
|
|
|
|
window.removeEventListener("resize", this.resizeListener);
|
|
|
|
this.term.destroy();
|
|
|
|
}
|
|
|
|
}
|