Merge pull request #220 from sourcelair/improve-demo

Introduce resizing option in demo
This commit is contained in:
Paris Kasidiaris
2016-08-08 14:35:02 +01:00
committed by GitHub
4 changed files with 119 additions and 29 deletions
+43 -11
View File
@@ -4,6 +4,9 @@ var expressWs = require('express-ws')(app);
var os = require('os');
var pty = require('pty.js');
var terminals = {},
logs = {};
app.use('/src', express.static(__dirname + '/../src'));
app.use('/addons', express.static(__dirname + '/../addons'));
@@ -19,17 +22,43 @@ app.get('/main.js', function(req, res){
res.sendFile(__dirname + '/main.js');
});
app.ws('/bash', function(ws, req) {
/**
* Open bash terminal and attach it
*/
var term = pty.spawn(process.platform === 'win32' ? 'cmd.exe' : 'bash', [], {
name: 'xterm-color',
cols: 80,
rows: 24,
cwd: process.env.PWD,
env: process.env
app.post('/terminals', function (req, res) {
var cols = parseInt(req.query.cols),
rows = parseInt(req.query.rows),
term = pty.spawn(process.platform === 'win32' ? 'cmd.exe' : 'bash', [], {
name: 'xterm-color',
cols: cols || 80,
rows: rows || 24,
cwd: process.env.PWD,
env: process.env
});
console.log('Created terminal with PID: ' + term.pid);
terminals[term.pid] = term;
logs[term.pid] = '';
term.on('data', function(data) {
logs[term.pid] += data;
});
res.send(term.pid.toString());
res.end();
});
app.post('/terminals/:pid/size', function (req, res) {
var pid = parseInt(req.params.pid),
cols = parseInt(req.query.cols),
rows = parseInt(req.query.rows),
term = terminals[pid];
term.resize(cols, rows);
console.log('Resized terminal ' + pid + ' to ' + cols + ' cols and ' + rows + ' rows.');
res.end();
});
app.ws('/terminals/:pid', function (ws, req) {
var term = terminals[parseInt(req.params.pid)];
console.log('Connected to terminal ' + term.pid);
ws.send(logs[term.pid]);
term.on('data', function(data) {
try {
ws.send(data);
@@ -41,8 +70,11 @@ app.ws('/bash', function(ws, req) {
term.write(msg);
});
ws.on('close', function () {
console.log('close');
process.kill(term.pid);
console.log('Closed terminal ' + term.pid);
// Clean things up
delete terminals[term.pid];
delete logs[term.pid];
});
});
+16 -3
View File
@@ -5,20 +5,33 @@
<link rel="stylesheet" href="../src/xterm.css" />
<link rel="stylesheet" href="../addons/fullscreen/fullscreen.css" />
<link rel="stylesheet" href="style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/1.0.0/fetch.min.js"></script>
<script src="../src/xterm.js" ></script>
<script src="../addons/attach/attach.js" ></script>
<script src="../addons/fit/fit.js" ></script>
<script src="../addons/fullscreen/fullscreen.js" ></script>
</head>
<body>
<h1>
xterm.js: xterm, in the browser
</h1>
<h1>xterm.js: xterm, in the browser</h1>
<div id="terminal-container"></div>
<div>
<h2>Options</h2>
<label><input type="checkbox" id="option-cursor-blink"> cursorBlink</label>
<div>
<h3>Size</h3>
<div>
<div style="display: inline-block; margin-right: 16px;">
<label for="cols">Columns</label>
<input type="number" id="cols" />
</div>
<div style="display: inline-block; margin-right: 16px;">
<label for="rows">Rows</label>
<input type="number" id="rows" />
</div>
</div>
</div>
</div>
<p><strong>Attention:</strong> The demo should be used only for evaluation of xterm.js and not be exposed or shared to public, as this will introduce security risks for the host.</p>
<script src="main.js" defer ></script>
</body>
</html>
+58 -13
View File
@@ -1,34 +1,81 @@
var term,
protocol,
socketURL,
socket;
socket,
pid,
charWidth,
charHeight;
var terminalContainer = document.getElementById('terminal-container');
var optionElements = {
cursorBlink: document.querySelector('#option-cursor-blink')
};
var terminalContainer = document.getElementById('terminal-container'),
optionElements = {
cursorBlink: document.querySelector('#option-cursor-blink')
},
colsElement = document.getElementById('cols'),
rowsElement = document.getElementById('rows');
function setTerminalSize () {
var cols = parseInt(colsElement.value),
rows = parseInt(rowsElement.value),
width = (cols * charWidth).toString() + 'px',
height = (rows * charHeight).toString() + 'px';
terminalContainer.style.width = width;
terminalContainer.style.height = height;
term.resize(cols, rows);
}
colsElement.addEventListener('change', setTerminalSize);
rowsElement.addEventListener('change', setTerminalSize);
optionElements.cursorBlink.addEventListener('change', createTerminal);
createTerminal();
function createTerminal() {
// Clean terminal
while (terminalContainer.children.length) {
terminalContainer.removeChild(terminalContainer.children[0]);
}
term = new Terminal({
cursorBlink: optionElements.cursorBlink.checked
});
term.on('resize', function (size) {
if (!pid) {
return;
}
var cols = size.cols,
rows = size.rows,
url = '/terminals/' + pid + '/size?cols=' + cols + '&rows=' + rows;
fetch(url, {method: 'POST'});
});
protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/bash';
socket = new WebSocket(socketURL);
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/';
term.open(terminalContainer);
term.fit();
socket.onopen = runRealTerminal;
socket.onclose = runFakeTerminal;
socket.onerror = runFakeTerminal;
var initialGeometry = term.proposeGeometry(),
cols = initialGeometry.cols,
rows = initialGeometry.rows;
colsElement.value = cols;
rowsElement.value = rows;
fetch('/terminals?cols=' + cols + '&rows=' + rows, {method: 'POST'}).then(function (res) {
charWidth = Math.ceil(term.element.offsetWidth / cols);
charHeight = Math.ceil(term.element.offsetHeight / rows);
res.text().then(function (pid) {
window.pid = pid;
socketURL += pid;
socket = new WebSocket(socketURL);
socket.onopen = runRealTerminal;
socket.onclose = runFakeTerminal;
socket.onerror = runFakeTerminal;
});
});
}
@@ -64,9 +111,7 @@ function runFakeTerminal() {
if (ev.keyCode == 13) {
term.prompt();
} else if (ev.keyCode == 8) {
/*
* Do not delete the prompt
*/
// Do not delete the prompt
if (term.x > 2) {
term.write('\b \b');
}
+2 -2
View File
@@ -9,8 +9,8 @@ h1 {
}
#terminal-container {
width: 960px;
height: 600px;
width: 800px;
height: 450px;
margin: 0 auto;
padding: 2px;
}