]>
Commit | Line | Data |
---|---|---|
e0c0fb69 DI |
1 | var term, |
2 | protocol, | |
3 | socketURL, | |
f57a40ee | 4 | socket, |
0f8fc63a PK |
5 | pid, |
6 | charWidth, | |
7 | charHeight; | |
8 | ||
9 | var terminalContainer = document.getElementById('terminal-container'), | |
c13b86a8 DI |
10 | actionElements = { |
11 | findNext: document.querySelector('#find-next'), | |
12 | findPrevious: document.querySelector('#find-previous') | |
13 | }, | |
0f8fc63a | 14 | optionElements = { |
5a932b2a | 15 | cursorBlink: document.querySelector('#option-cursor-blink'), |
46d62f49 | 16 | cursorStyle: document.querySelector('#option-cursor-style'), |
f4293a6d PK |
17 | scrollback: document.querySelector('#option-scrollback'), |
18 | tabstopwidth: document.querySelector('#option-tabstopwidth') | |
0f8fc63a PK |
19 | }, |
20 | colsElement = document.getElementById('cols'), | |
21 | rowsElement = document.getElementById('rows'); | |
22 | ||
23 | function setTerminalSize () { | |
6e1628bc PK |
24 | var cols = parseInt(colsElement.value, 10), |
25 | rows = parseInt(rowsElement.value, 10), | |
0f8fc63a PK |
26 | width = (cols * charWidth).toString() + 'px', |
27 | height = (rows * charHeight).toString() + 'px'; | |
28 | ||
29 | terminalContainer.style.width = width; | |
30 | terminalContainer.style.height = height; | |
31 | term.resize(cols, rows); | |
32 | } | |
e0c0fb69 | 33 | |
0f8fc63a PK |
34 | colsElement.addEventListener('change', setTerminalSize); |
35 | rowsElement.addEventListener('change', setTerminalSize); | |
e0c0fb69 | 36 | |
c13b86a8 DI |
37 | actionElements.findNext.addEventListener('keypress', function (e) { |
38 | if (e.key === "Enter") { | |
39 | e.preventDefault(); | |
40 | term.findNext(actionElements.findNext.value); | |
41 | } | |
42 | }); | |
43 | actionElements.findPrevious.addEventListener('keypress', function (e) { | |
44 | if (e.key === "Enter") { | |
45 | e.preventDefault(); | |
46 | term.findPrevious(actionElements.findPrevious.value); | |
47 | } | |
48 | }); | |
49 | ||
7679475b DI |
50 | optionElements.cursorBlink.addEventListener('change', function () { |
51 | term.setOption('cursorBlink', optionElements.cursorBlink.checked); | |
52 | }); | |
46d62f49 DI |
53 | optionElements.cursorStyle.addEventListener('change', function () { |
54 | term.setOption('cursorStyle', optionElements.cursorStyle.value); | |
55 | }); | |
5a932b2a | 56 | optionElements.scrollback.addEventListener('change', function () { |
f4293a6d PK |
57 | term.setOption('scrollback', parseInt(optionElements.scrollback.value, 10)); |
58 | }); | |
59 | optionElements.tabstopwidth.addEventListener('change', function () { | |
6e1628bc | 60 | term.setOption('tabStopWidth', parseInt(optionElements.tabstopwidth.value, 10)); |
5a932b2a | 61 | }); |
e0c0fb69 DI |
62 | |
63 | createTerminal(); | |
64 | ||
65 | function createTerminal() { | |
f57a40ee | 66 | // Clean terminal |
e0c0fb69 DI |
67 | while (terminalContainer.children.length) { |
68 | terminalContainer.removeChild(terminalContainer.children[0]); | |
69 | } | |
70 | term = new Terminal({ | |
5a932b2a | 71 | cursorBlink: optionElements.cursorBlink.checked, |
f4293a6d | 72 | scrollback: parseInt(optionElements.scrollback.value, 10), |
6e1628bc | 73 | tabStopWidth: parseInt(optionElements.tabstopwidth.value, 10) |
e0c0fb69 | 74 | }); |
f57a40ee PK |
75 | term.on('resize', function (size) { |
76 | if (!pid) { | |
77 | return; | |
78 | } | |
0f8fc63a PK |
79 | var cols = size.cols, |
80 | rows = size.rows, | |
81 | url = '/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows; | |
82 | ||
83 | fetch(url, {method: 'POST'}); | |
f57a40ee | 84 | }); |
e0c0fb69 | 85 | protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://'; |
f57a40ee | 86 | socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/'; |
e0c0fb69 DI |
87 | |
88 | term.open(terminalContainer); | |
0f8fc63a | 89 | term.fit(); |
e0c0fb69 | 90 | |
f57a40ee PK |
91 | var initialGeometry = term.proposeGeometry(), |
92 | cols = initialGeometry.cols, | |
93 | rows = initialGeometry.rows; | |
94 | ||
0f8fc63a PK |
95 | colsElement.value = cols; |
96 | rowsElement.value = rows; | |
97 | ||
f57a40ee | 98 | fetch('/terminals?cols=' + cols + '&rows=' + rows, {method: 'POST'}).then(function (res) { |
0f8fc63a PK |
99 | |
100 | charWidth = Math.ceil(term.element.offsetWidth / cols); | |
101 | charHeight = Math.ceil(term.element.offsetHeight / rows); | |
102 | ||
f57a40ee PK |
103 | res.text().then(function (pid) { |
104 | window.pid = pid; | |
105 | socketURL += pid; | |
106 | socket = new WebSocket(socketURL); | |
107 | socket.onopen = runRealTerminal; | |
108 | socket.onclose = runFakeTerminal; | |
109 | socket.onerror = runFakeTerminal; | |
110 | }); | |
111 | }); | |
e0c0fb69 | 112 | } |
dc3946f6 | 113 | |
53e8df40 PK |
114 | function runRealTerminal() { |
115 | term.attach(socket); | |
116 | term._initialized = true; | |
117 | } | |
c5ae1cea | 118 | |
53e8df40 PK |
119 | function runFakeTerminal() { |
120 | if (term._initialized) { | |
121 | return; | |
122 | } | |
123 | ||
124 | term._initialized = true; | |
125 | ||
126 | var shellprompt = '$ '; | |
127 | ||
128 | term.prompt = function () { | |
129 | term.write('\r\n' + shellprompt); | |
130 | }; | |
c5ae1cea | 131 | |
53e8df40 PK |
132 | term.writeln('Welcome to xterm.js'); |
133 | term.writeln('This is a local terminal emulation, without a real terminal in the back-end.'); | |
134 | term.writeln('Type some keys and commands to play around.'); | |
135 | term.writeln(''); | |
136 | term.prompt(); | |
46bb446e | 137 | |
53e8df40 PK |
138 | term.on('key', function (key, ev) { |
139 | var printable = ( | |
140 | !ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey | |
141 | ); | |
142 | ||
143 | if (ev.keyCode == 13) { | |
144 | term.prompt(); | |
145 | } else if (ev.keyCode == 8) { | |
0f8fc63a | 146 | // Do not delete the prompt |
53e8df40 PK |
147 | if (term.x > 2) { |
148 | term.write('\b \b'); | |
149 | } | |
150 | } else if (printable) { | |
151 | term.write(key); | |
567b39dc | 152 | } |
53e8df40 PK |
153 | }); |
154 | ||
155 | term.on('paste', function (data, ev) { | |
156 | term.write(data); | |
157 | }); | |
158 | } |