diff --git a/demo/index.html b/demo/index.html index 168f56e459..f374d99885 100644 --- a/demo/index.html +++ b/demo/index.html @@ -1,95 +1,37 @@ - - 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 682fc5a072..7465355108 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) { @@ -139,12 +78,13 @@ function createTerminal() { // fit is called within a setTimeout, cols and rows need this. setTimeout(function () { - colsElement.value = term.cols; - rowsElement.value = term.rows; + initOptions(term); + 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 - setTerminalSize(); + updateTerminalSize(); fetch('/terminals?cols=' + term.cols + '&rows=' + term.rows, {method: 'POST'}).then(function (res) { @@ -205,3 +145,98 @@ function runFakeTerminal() { term.write(data); }); } + +function initOptions(term) { + var blacklistedOptions = [ + // Internal only options + 'cancelEvents', + 'convertEol', + 'debug', + 'handler', + 'screenKeys', + 'termName', + 'useFlowControl', + // Complex option + 'theme', + // Only in constructor + 'rendererType' + ]; + var stringOptions = { + bellSound: null, + 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(o => { + switch (typeof term.getOption(o)) { + case 'boolean': + booleanOptions.push(o); + break; + case 'number': + numberOptions.push(o); + break; + default: + if (Object.keys(stringOptions).indexOf(o) === -1) { + console.warn(`Unrecognized option: "${o}"`); + } + } + }); + + var html = ''; + html += '
'; + booleanOptions.forEach(o => { + html += `
`; + }); + html += '
'; + numberOptions.forEach(o => { + html += `
`; + }); + html += '
'; + Object.keys(stringOptions).forEach(o => { + if (stringOptions[o]) { + html += `
`; + } else { + html += `
` + } + }); + html += '
'; + + var container = document.getElementById('options-container'); + container.innerHTML = html; + + // Attach listeners + booleanOptions.forEach(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 => { + var input = document.getElementById(`opt-${o}`); + input.addEventListener('change', () => { + console.log('change', 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/demo/style.css b/demo/style.css index 1ab5f61caf..b061dfcbbd 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; +} diff --git a/src/Terminal.ts b/src/Terminal.ts index 155c1a5286..af8fd21e88 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -95,6 +95,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', 'rendererType']; + const DEFAULT_OPTIONS: ITerminalOptions = { cols: 80, rows: 24, @@ -394,6 +399,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) {