From 4d5e305a25d2cc0e8ccbe2a58bc4955da0d17013 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 3 Jun 2018 10:37:20 +0100 Subject: [PATCH 1/6] Generate inputs for all options in demo --- demo/main.js | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/demo/main.js b/demo/main.js index 682fc5a0..db053ce6 100644 --- a/demo/main.js +++ b/demo/main.js @@ -117,6 +117,7 @@ function createTerminal() { tabStopWidth: parseInt(optionElements.tabstopwidth.value, 10), screenReaderMode: optionElements.screenReaderMode.checked }); + initOptions(term); window.term = term; // Expose `term` to window for debugging purposes term.on('resize', function (size) { if (!pid) { @@ -205,3 +206,55 @@ function runFakeTerminal() { term.write(data); }); } + +function initOptions(term) { + var blacklistedOptions = [ + 'cancelEvents', + 'convertEol', + 'debug', + 'handler', + 'screenKeys', + 'termName', + 'useFlowControl' + ]; + var stringOptions = { + bellStyle: ['none', 'sound'], + cursorStyle: ['block', 'underline', 'bar'], + experimentalCharAtlas: ['none', 'static', 'dynamic'], + fontFamily: null, + fontWeight: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], + fontWeightBold: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'] + }; + var options = Object.keys(term.options); + var booleanOptions = []; + var numberOptions = []; + options.filter(o => blacklistedOptions.indexOf(o) === -1).forEach(option => { + switch (typeof term.getOption(option)) { + case 'boolean': + booleanOptions.push(option); + break; + case 'number': + numberOptions.push(option); + break; + } + }); + + var html = '

Options

'; + booleanOptions.forEach(o => { + html += `
`; + }); + numberOptions.forEach(o => { + html += `
`; + }); + Object.keys(stringOptions).forEach(o => { + if (stringOptions[o]) { + html += `
`; + } else { + html += `
` + } + }); + + const container = document.createElement('div'); + container.innerHTML = html; + document.body.appendChild(container); +} From 5b04451b0566d49dd73ae0640ffba7905c6020bd Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 3 Jun 2018 11:02:39 +0100 Subject: [PATCH 2/6] console error on setting ctor only option via setOption --- demo/main.js | 42 ++++++++++++++++++++++++++++++++++-------- src/Terminal.ts | 8 ++++++++ 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/demo/main.js b/demo/main.js index db053ce6..da36ee98 100644 --- a/demo/main.js +++ b/demo/main.js @@ -117,7 +117,6 @@ function createTerminal() { tabStopWidth: parseInt(optionElements.tabstopwidth.value, 10), screenReaderMode: optionElements.screenReaderMode.checked }); - initOptions(term); window.term = term; // Expose `term` to window for debugging purposes term.on('resize', function (size) { if (!pid) { @@ -140,8 +139,10 @@ function createTerminal() { // fit is called within a setTimeout, cols and rows need this. setTimeout(function () { - colsElement.value = term.cols; - rowsElement.value = term.rows; + console.log(term.cols, term.getOption('cols')); + initOptions(term); + // colsElement.value = term.cols; + // rowsElement.value = term.rows; paddingElement.value = 0; // Set terminal size again to set the specific dimensions on the demo @@ -209,15 +210,19 @@ function runFakeTerminal() { function initOptions(term) { var blacklistedOptions = [ + // Internal only options 'cancelEvents', 'convertEol', 'debug', 'handler', 'screenKeys', 'termName', - 'useFlowControl' + 'useFlowControl', + // Complex option + 'theme' ]; var stringOptions = { + bellSound: null, bellStyle: ['none', 'sound'], cursorStyle: ['block', 'underline', 'bar'], experimentalCharAtlas: ['none', 'static', 'dynamic'], @@ -228,14 +233,18 @@ function initOptions(term) { var options = Object.keys(term.options); var booleanOptions = []; var numberOptions = []; - options.filter(o => blacklistedOptions.indexOf(o) === -1).forEach(option => { - switch (typeof term.getOption(option)) { + options.filter(o => blacklistedOptions.indexOf(o) === -1).forEach(o => { + switch (typeof term.getOption(o)) { case 'boolean': - booleanOptions.push(option); + booleanOptions.push(o); break; case 'number': - numberOptions.push(option); + numberOptions.push(o); break; + default: + if (Object.keys(stringOptions).indexOf(o) === -1) { + console.warn(`Unrecognized option: "${o}"`); + } } }); @@ -257,4 +266,21 @@ function initOptions(term) { const container = document.createElement('div'); container.innerHTML = html; document.body.appendChild(container); + + // Attach listeners + // var allOptions = booleanOptions.concat(numberOptions, Object.keys(stringOptions)); + booleanOptions.forEach(o => { + const input = document.getElementById(`opt-${o}`); + input.addEventListener('change', () => { + console.log('change', o, input.checked); + term.setOption(o, input.checked); + }); + }); + numberOptions.concat(Object.keys(stringOptions)).forEach(o => { + const input = document.getElementById(`opt-${o}`); + input.addEventListener('change', () => { + console.log('change', o, input.value); + term.setOption(o, input.value); + }); + }); } diff --git a/src/Terminal.ts b/src/Terminal.ts index 63f7efdb..02d0ff4a 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -94,6 +94,11 @@ const WRITE_BUFFER_PAUSE_THRESHOLD = 5; */ const WRITE_BATCH_SIZE = 300; +/** + * The set of options that only have an effect when set in the Terminal constructor. + */ +const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows', 'experimentalCharAtlas']; + const DEFAULT_OPTIONS: ITerminalOptions = { cols: 80, rows: 24, @@ -400,6 +405,9 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II if (!(key in DEFAULT_OPTIONS)) { throw new Error('No option with key "' + key + '"'); } + if (CONSTRUCTOR_ONLY_OPTIONS.indexOf(key) !== -1) { + console.error(`Option "${key}" can only be set in the constructor`); + } switch (key) { case 'bellStyle': if (!value) { From 2d786910c87e3696488b499ccaa3a18cc5801e73 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 3 Jun 2018 11:09:59 +0100 Subject: [PATCH 3/6] Correctly set cols/rows --- demo/main.js | 21 +++++++++++++++++---- src/Terminal.ts | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/demo/main.js b/demo/main.js index da36ee98..ef4a0437 100644 --- a/demo/main.js +++ b/demo/main.js @@ -139,10 +139,9 @@ function createTerminal() { // fit is called within a setTimeout, cols and rows need this. setTimeout(function () { - console.log(term.cols, term.getOption('cols')); initOptions(term); - // colsElement.value = term.cols; - // rowsElement.value = term.rows; + 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 @@ -280,7 +279,21 @@ function initOptions(term) { const input = document.getElementById(`opt-${o}`); input.addEventListener('change', () => { console.log('change', o, input.value); - term.setOption(o, input.value); + if (o === 'cols' || o === 'rows') { + updateTerminalSize(); + } else { + term.setOption(o, parseInt(input.value, 10)); + } }); }); } + +function updateTerminalSize() { + var cols = parseInt(document.getElementById(`opt-cols`).value, 10); + var rows = parseInt(document.getElementById(`opt-rows`).value, 10); + var width = (cols * term.renderer.dimensions.actualCellWidth + term.viewport.scrollBarWidth).toString() + 'px'; + var height = (rows * term.renderer.dimensions.actualCellHeight).toString() + 'px'; + terminalContainer.style.width = width; + terminalContainer.style.height = height; + term.fit(); +} diff --git a/src/Terminal.ts b/src/Terminal.ts index 02d0ff4a..7d4d9b46 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -97,7 +97,7 @@ const WRITE_BATCH_SIZE = 300; /** * The set of options that only have an effect when set in the Terminal constructor. */ -const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows', 'experimentalCharAtlas']; +const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows']; const DEFAULT_OPTIONS: ITerminalOptions = { cols: 80, From 908b06cfa783142bcff899b9e55378caa53323dc Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 3 Jun 2018 11:18:34 +0100 Subject: [PATCH 4/6] Some polish --- demo/index.html | 125 +++++++++++++----------------------------------- demo/main.js | 75 +++-------------------------- 2 files changed, 39 insertions(+), 161 deletions(-) diff --git a/demo/index.html b/demo/index.html index 168f56e4..41a77205 100644 --- a/demo/index.html +++ b/demo/index.html @@ -1,95 +1,36 @@ - - xterm.js demo - - - - - - - -

xterm.js: A terminal for the web

-
-
-

Actions

-

- - -

-
-
-

Options

-

- -

-

- -

-

- -

-

- -

-

- -

-

- -

-

- -

-

- -

-
-

Size

-
-
- - -
-
- - -
-
- - -
-
-
-
-

Accessibility

-

- -

-
-

Attention: 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.

- - + + xterm.js demo + + + + + + + +

xterm.js: A terminal for the web

+
+
+

Actions

+

+ + +

+
+
+

Options

+

These options can be set in the Terminal constructor or using the Terminal.setOption function.

+
+
+
+

Style

+
+ + +
+
+

Attention: 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.

+ + diff --git a/demo/main.js b/demo/main.js index ef4a0437..e4d0bb2b 100644 --- a/demo/main.js +++ b/demo/main.js @@ -26,38 +26,13 @@ var terminalContainer = document.getElementById('terminal-container'), findNext: document.querySelector('#find-next'), findPrevious: document.querySelector('#find-previous') }, - optionElements = { - cursorBlink: document.querySelector('#option-cursor-blink'), - cursorStyle: document.querySelector('#option-cursor-style'), - macOptionIsMeta: document.querySelector('#option-mac-option-is-meta'), - scrollback: document.querySelector('#option-scrollback'), - transparency: document.querySelector('#option-transparency'), - tabstopwidth: document.querySelector('#option-tabstopwidth'), - experimentalCharAtlas: document.querySelector('#option-experimental-char-atlas'), - bellStyle: document.querySelector('#option-bell-style'), - screenReaderMode: document.querySelector('#option-screen-reader-mode') - }, - colsElement = document.getElementById('cols'), - rowsElement = document.getElementById('rows'), paddingElement = document.getElementById('padding'); -function setTerminalSize() { - var cols = parseInt(colsElement.value, 10); - var rows = parseInt(rowsElement.value, 10); - var width = (cols * term.renderer.dimensions.actualCellWidth + term.viewport.scrollBarWidth).toString() + 'px'; - var height = (rows * term.renderer.dimensions.actualCellHeight).toString() + 'px'; - terminalContainer.style.width = width; - terminalContainer.style.height = height; - term.fit(); -} - function setPadding() { term.element.style.padding = parseInt(paddingElement.value, 10).toString() + 'px'; term.fit(); } -colsElement.addEventListener('change', setTerminalSize); -rowsElement.addEventListener('change', setTerminalSize); paddingElement.addEventListener('change', setPadding); actionElements.findNext.addEventListener('keypress', function (e) { @@ -73,36 +48,6 @@ actionElements.findPrevious.addEventListener('keypress', function (e) { } }); -optionElements.cursorBlink.addEventListener('change', function () { - term.setOption('cursorBlink', optionElements.cursorBlink.checked); -}); -optionElements.macOptionIsMeta.addEventListener('change', function () { - term.setOption('macOptionIsMeta', optionElements.macOptionIsMeta.checked); -}); -optionElements.transparency.addEventListener('change', function () { - var checked = optionElements.transparency.checked; - term.setOption('allowTransparency', checked); - term.setOption('theme', checked ? {background: 'rgba(0, 0, 0, .5)'} : {}); -}); -optionElements.cursorStyle.addEventListener('change', function () { - term.setOption('cursorStyle', optionElements.cursorStyle.value); -}); -optionElements.bellStyle.addEventListener('change', function () { - term.setOption('bellStyle', optionElements.bellStyle.value); -}); -optionElements.scrollback.addEventListener('change', function () { - term.setOption('scrollback', parseInt(optionElements.scrollback.value, 10)); -}); -optionElements.tabstopwidth.addEventListener('change', function () { - term.setOption('tabStopWidth', parseInt(optionElements.tabstopwidth.value, 10)); -}); -optionElements.experimentalCharAtlas.addEventListener('change', function () { - term.setOption('experimentalCharAtlas', optionElements.experimentalCharAtlas.value); -}); -optionElements.screenReaderMode.addEventListener('change', function () { - term.setOption('screenReaderMode', optionElements.screenReaderMode.checked); -}); - createTerminal(); function createTerminal() { @@ -110,13 +55,7 @@ function createTerminal() { while (terminalContainer.children.length) { terminalContainer.removeChild(terminalContainer.children[0]); } - term = new Terminal({ - macOptionIsMeta: optionElements.macOptionIsMeta.enabled, - cursorBlink: optionElements.cursorBlink.checked, - scrollback: parseInt(optionElements.scrollback.value, 10), - tabStopWidth: parseInt(optionElements.tabstopwidth.value, 10), - screenReaderMode: optionElements.screenReaderMode.checked - }); + term = new Terminal({}); window.term = term; // Expose `term` to window for debugging purposes term.on('resize', function (size) { if (!pid) { @@ -145,7 +84,7 @@ function createTerminal() { paddingElement.value = 0; // Set terminal size again to set the specific dimensions on the demo - setTerminalSize(); + updateTerminalSize(); fetch('/terminals?cols=' + term.cols + '&rows=' + term.rows, {method: 'POST'}).then(function (res) { @@ -247,7 +186,7 @@ function initOptions(term) { } }); - var html = '

Options

'; + var html = ''; booleanOptions.forEach(o => { html += `
`; }); @@ -262,21 +201,19 @@ function initOptions(term) { } }); - const container = document.createElement('div'); + var container = document.getElementById('options-container'); container.innerHTML = html; - document.body.appendChild(container); // Attach listeners - // var allOptions = booleanOptions.concat(numberOptions, Object.keys(stringOptions)); booleanOptions.forEach(o => { - const input = document.getElementById(`opt-${o}`); + var input = document.getElementById(`opt-${o}`); input.addEventListener('change', () => { console.log('change', o, input.checked); term.setOption(o, input.checked); }); }); numberOptions.concat(Object.keys(stringOptions)).forEach(o => { - const input = document.getElementById(`opt-${o}`); + var input = document.getElementById(`opt-${o}`); input.addEventListener('change', () => { console.log('change', o, input.value); if (o === 'cols' || o === 'rows') { From adb0cf41aba606cc05960261294ff5300a600d02 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 3 Jun 2018 15:37:01 +0200 Subject: [PATCH 5/6] Improve display of options --- demo/index.html | 1 + demo/main.js | 12 ++++++++---- demo/style.css | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/demo/index.html b/demo/index.html index 41a77205..f374d998 100644 --- a/demo/index.html +++ b/demo/index.html @@ -30,6 +30,7 @@
+

Attention: 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.

diff --git a/demo/main.js b/demo/main.js index e4d0bb2b..f765f3ce 100644 --- a/demo/main.js +++ b/demo/main.js @@ -187,19 +187,23 @@ function initOptions(term) { }); var html = ''; + html += '
'; booleanOptions.forEach(o => { - html += `
`; + html += `
`; }); + html += '
'; numberOptions.forEach(o => { - html += `
`; + html += `
`; }); + html += '
'; Object.keys(stringOptions).forEach(o => { if (stringOptions[o]) { - html += `
`; + html += `
`; } else { - html += `
` + html += `
` } }); + html += '
'; var container = document.getElementById('options-container'); container.innerHTML = html; diff --git a/demo/style.css b/demo/style.css index 1ab5f61c..b061dfcb 100644 --- a/demo/style.css +++ b/demo/style.css @@ -14,3 +14,19 @@ h1 { margin: 0 auto; padding: 2px; } + +p { + font-size: 0.9em; + font-style: italic +} + +#option-container { + display: flex; + justify-content: center; +} + +.option-group { + display: inline-block; + padding-left: 20px; + vertical-align: top; +} From c748b021118cb02da43ba94b1b09f1ff58d48182 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 3 Jun 2018 16:21:23 +0200 Subject: [PATCH 6/6] Add rendererType --- demo/main.js | 4 +++- src/Terminal.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/demo/main.js b/demo/main.js index f765f3ce..74653551 100644 --- a/demo/main.js +++ b/demo/main.js @@ -157,7 +157,9 @@ function initOptions(term) { 'termName', 'useFlowControl', // Complex option - 'theme' + 'theme', + // Only in constructor + 'rendererType' ]; var stringOptions = { bellSound: null, diff --git a/src/Terminal.ts b/src/Terminal.ts index bceeb9da..3d36890e 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -98,7 +98,7 @@ const WRITE_BATCH_SIZE = 300; /** * The set of options that only have an effect when set in the Terminal constructor. */ -const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows']; +const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows', 'rendererType']; const DEFAULT_OPTIONS: ITerminalOptions = { cols: 80,