diff --git a/demo/client.js b/demo/client.ts similarity index 67% rename from demo/client.js rename to demo/client.ts index 70544e38..e8173513 100644 --- a/demo/client.js +++ b/demo/client.ts @@ -6,6 +6,12 @@ import * as search from '../build/addons/search/search'; import * as webLinks from '../build/addons/webLinks/webLinks'; import * as winptyCompat from '../build/addons/winptyCompat/winptyCompat'; +export interface IWindowWithTerminal extends Window { + // TODO: Type me + term: any; +} +declare let window: IWindowWithTerminal; + Terminal.applyAddon(attach); Terminal.applyAddon(fit); @@ -15,20 +21,20 @@ Terminal.applyAddon(webLinks); Terminal.applyAddon(winptyCompat); -var term, - protocol, - socketURL, - socket, - pid; +let term; +let protocol; +let socketURL; +let socket; +let pid; -var terminalContainer = document.getElementById('terminal-container'), - actionElements = { - findNext: document.querySelector('#find-next'), - findPrevious: document.querySelector('#find-previous') - }, - paddingElement = document.getElementById('padding'); +const terminalContainer = document.getElementById('terminal-container'); +const actionElements = { + findNext: document.querySelector('#find-next'), + findPrevious: document.querySelector('#find-previous') +}; +const paddingElement = document.getElementById('padding'); -function setPadding() { +function setPadding(): void { term.element.style.padding = parseInt(paddingElement.value, 10).toString() + 'px'; term.fit(); } @@ -52,20 +58,20 @@ const disposeRecreateButtonHandler = () => { document.getElementById('dispose').addEventListener('click', disposeRecreateButtonHandler); -function createTerminal() { +function createTerminal(): void { // Clean terminal while (terminalContainer.children.length) { terminalContainer.removeChild(terminalContainer.children[0]); } term = new Terminal({}); window.term = term; // Expose `term` to window for debugging purposes - term.on('resize', function (size) { + term.on('resize', (size: { cols: number, rows: number }) => { if (!pid) { return; } - var cols = size.cols, - rows = size.rows, - url = '/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows; + const cols = size.cols; + const rows = size.rows; + const url = '/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows; fetch(url, {method: 'POST'}); }); @@ -80,32 +86,32 @@ function createTerminal() { addDomListener(paddingElement, 'change', setPadding); - addDomListener(actionElements.findNext, 'keypress', function (e) { - if (e.key === "Enter") { + addDomListener(actionElements.findNext, 'keypress', (e) => { + if (e.key === 'Enter') { e.preventDefault(); term.findNext(actionElements.findNext.value); } }); - addDomListener(actionElements.findPrevious, 'keypress', function (e) { - if (e.key === "Enter") { + addDomListener(actionElements.findPrevious, 'keypress', (e) => { + if (e.key === 'Enter') { e.preventDefault(); term.findPrevious(actionElements.findPrevious.value); } }); // fit is called within a setTimeout, cols and rows need this. - setTimeout(function () { + setTimeout(() => { initOptions(term); - document.getElementById(`opt-cols`).value = term.cols; - document.getElementById(`opt-rows`).value = term.rows; - paddingElement.value = 0; + // TODO: Clean this up, opt-cols/rows doesn't exist anymore + (document.getElementById(`opt-cols`)).value = term.cols; + (document.getElementById(`opt-rows`)).value = term.rows; + paddingElement.value = '0'; // Set terminal size again to set the specific dimensions on the demo updateTerminalSize(); - fetch('/terminals?cols=' + term.cols + '&rows=' + term.rows, {method: 'POST'}).then(function (res) { - - res.text().then(function (processId) { + fetch('/terminals?cols=' + term.cols + '&rows=' + term.rows, {method: 'POST'}).then((res) => { + res.text().then((processId) => { pid = processId; socketURL += processId; socket = new WebSocket(socketURL); @@ -117,22 +123,21 @@ function createTerminal() { }, 0); } -function runRealTerminal() { +function runRealTerminal(): void { term.attach(socket); term._initialized = true; } -function runFakeTerminal() { +// TODO: Maybe fake terminal should be removed? Not sure it's useful anymore +function runFakeTerminal(): void { if (term._initialized) { return; } term._initialized = true; - var shellprompt = '$ '; - - term.prompt = function () { - term.write('\r\n' + shellprompt); + term.prompt = () => { + term.write('\r\n$ '); }; term.writeln('Welcome to xterm.js'); @@ -141,14 +146,12 @@ function runFakeTerminal() { term.writeln(''); term.prompt(); - term._core.register(term.addDisposableListener('key', function (key, ev) { - var printable = ( - !ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey - ); + term._core.register(term.addDisposableListener('key', (key, ev) => { + const printable = !ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey; - if (ev.keyCode == 13) { + if (ev.keyCode === 13) { term.prompt(); - } else if (ev.keyCode == 8) { + } else if (ev.keyCode === 8) { // Do not delete the prompt if (term.x > 2) { term.write('\b \b'); @@ -158,13 +161,13 @@ function runFakeTerminal() { } })); - term._core.register(term.addDisposableListener('paste', function (data, ev) { + term._core.register(term.addDisposableListener('paste', (data, ev) => { term.write(data); })); } -function initOptions(term) { - var blacklistedOptions = [ +function initOptions(term: any): void { + const blacklistedOptions = [ // Internal only options 'cancelEvents', 'convertEol', @@ -176,7 +179,7 @@ function initOptions(term) { // Complex option 'theme' ]; - var stringOptions = { + const stringOptions = { bellSound: null, bellStyle: ['none', 'sound'], cursorStyle: ['block', 'underline', 'bar'], @@ -186,9 +189,9 @@ function initOptions(term) { fontWeightBold: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], rendererType: ['dom', 'canvas'] }; - var options = Object.keys(term._core.options); - var booleanOptions = []; - var numberOptions = []; + const options = Object.keys(term._core.options); + const booleanOptions = []; + const numberOptions = []; options.filter(o => blacklistedOptions.indexOf(o) === -1).forEach(o => { switch (typeof term.getOption(o)) { case 'boolean': @@ -204,7 +207,7 @@ function initOptions(term) { } }); - var html = ''; + let html = ''; html += '
'; booleanOptions.forEach(o => { html += `
`; @@ -218,24 +221,24 @@ function initOptions(term) { if (stringOptions[o]) { html += `
`; } else { - html += `
` + html += `
`; } }); html += '
'; - var container = document.getElementById('options-container'); + const container = document.getElementById('options-container'); container.innerHTML = html; // Attach listeners booleanOptions.forEach(o => { - var input = document.getElementById(`opt-${o}`); + const input = document.getElementById(`opt-${o}`); addDomListener(input, 'change', () => { console.log('change', o, input.checked); term.setOption(o, input.checked); }); }); numberOptions.forEach(o => { - var input = document.getElementById(`opt-${o}`); + const input = document.getElementById(`opt-${o}`); addDomListener(input, 'change', () => { console.log('change', o, input.value); if (o === 'cols' || o === 'rows') { @@ -246,7 +249,7 @@ function initOptions(term) { }); }); Object.keys(stringOptions).forEach(o => { - var input = document.getElementById(`opt-${o}`); + const input = document.getElementById(`opt-${o}`); addDomListener(input, 'change', () => { console.log('change', o, input.value); term.setOption(o, input.value); @@ -254,16 +257,16 @@ function initOptions(term) { }); } -function addDomListener(element, type, handler) { +function addDomListener(element: HTMLElement, type: string, handler: (...args: any[]) => any): void { element.addEventListener(type, handler); term._core.register({ dispose: () => element.removeEventListener(type, handler) }); } -function updateTerminalSize() { - var cols = parseInt(document.getElementById(`opt-cols`).value, 10); - var rows = parseInt(document.getElementById(`opt-rows`).value, 10); - var width = (cols * term._core.renderer.dimensions.actualCellWidth + term._core.viewport.scrollBarWidth).toString() + 'px'; - var height = (rows * term._core.renderer.dimensions.actualCellHeight).toString() + 'px'; +function updateTerminalSize(): void { + const cols = parseInt((document.getElementById(`opt-cols`)).value, 10); + const rows = parseInt((document.getElementById(`opt-rows`)).value, 10); + const width = (cols * term._core.renderer.dimensions.actualCellWidth + term._core.viewport.scrollBarWidth).toString() + 'px'; + const height = (rows * term._core.renderer.dimensions.actualCellHeight).toString() + 'px'; terminalContainer.style.width = width; terminalContainer.style.height = height; term.fit(); diff --git a/demo/start.js b/demo/start.js index 018eb985..ad9e9f2f 100644 --- a/demo/start.js +++ b/demo/start.js @@ -14,8 +14,20 @@ cp.spawn('node', [path.resolve(__dirname, 'server.js')], { stdio: 'inherit' }); // Build/watch client source const clientConfig = { - entry: path.resolve(__dirname, 'client.js'), + entry: path.resolve(__dirname, 'client.ts'), devtool: 'inline-source-map', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/ + } + ] + }, + resolve: { + extensions: [ '.tsx', '.ts', '.js' ] + }, output: { filename: 'client-bundle.js', path: path.resolve(__dirname, 'dist')