(web) assets clean-up + termjs upgrade to its latest version

This commit is contained in:
Alexey Kontsevoy 2016-03-16 12:02:43 -04:00
parent 1a21339b07
commit 140014a92d
31 changed files with 6594 additions and 251 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -114,6 +114,54 @@ EventEmitter.prototype.listeners = function(type) {
return this._events[type] = this._events[type] || [];
};
/**
* Stream
*/
function Stream() {
EventEmitter.call(this);
}
inherits(Stream, EventEmitter);
Stream.prototype.pipe = function(dest, options) {
var src = this
, ondata
, onerror
, onend;
function unbind() {
src.removeListener('data', ondata);
src.removeListener('error', onerror);
src.removeListener('end', onend);
dest.removeListener('error', onerror);
dest.removeListener('close', unbind);
}
src.on('data', ondata = function(data) {
dest.write(data);
});
src.on('error', onerror = function(err) {
unbind();
if (!this.listeners('error').length) {
throw err;
}
});
src.on('end', onend = function() {
dest.end();
unbind();
});
dest.on('error', onerror);
dest.on('close', unbind);
dest.emit('pipe', src);
return dest;
};
/**
* States
*/
@ -124,7 +172,8 @@ var normal = 0
, osc = 3
, charset = 4
, dcs = 5
, ignore = 6;
, ignore = 6
, UDK = { type: 'udk' };
/**
* Terminal
@ -137,7 +186,7 @@ function Terminal(options) {
return new Terminal(arguments[0], arguments[1], arguments[2]);
}
EventEmitter.call(this);
Stream.call(this);
if (typeof options === 'number') {
options = {
@ -183,6 +232,13 @@ function Terminal(options) {
this.cols = options.cols || options.geometry[0];
this.rows = options.rows || options.geometry[1];
// Act as though we are a node TTY stream:
this.setRawMode;
this.isTTY = true;
this.isRaw = true;
this.columns = this.cols;
this.rows = this.rows;
if (options.handler) {
this.on('data', options.handler);
}
@ -268,13 +324,7 @@ function Terminal(options) {
this.setupStops();
}
inherits(Terminal, EventEmitter);
// back_color_erase feature for xterm.
Terminal.prototype.eraseAttr = function() {
// if (this.is('screen')) return this.defAttr;
return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);
};
inherits(Terminal, Stream);
/**
* Colors
@ -732,61 +782,77 @@ Terminal.prototype.open = function(parent) {
// Draw the screen.
this.refresh(0, this.rows - 1);
// Initialize global actions that
// need to be taken on the document.
this.initGlobal();
if (!('useEvents' in this.options) || this.options.useEvents) {
// Initialize global actions that
// need to be taken on the document.
this.initGlobal();
}
// Ensure there is a Terminal.focus.
this.focus();
if (!('useFocus' in this.options) || this.options.useFocus) {
// Ensure there is a Terminal.focus.
this.focus();
// Start blinking the cursor.
this.startBlink();
// Start blinking the cursor.
this.startBlink();
// Bind to DOM events related
// to focus and paste behavior.
on(this.element, 'focus', function() {
self.focus();
if (self.isMobile) {
Terminal._textarea.focus();
}
});
// Bind to DOM events related
// to focus and paste behavior.
on(this.element, 'focus', function() {
self.focus();
if (self.isMobile) {
Terminal._textarea.focus();
}
});
// This causes slightly funky behavior.
// on(this.element, 'blur', function() {
// self.blur();
// });
// This causes slightly funky behavior.
// on(this.element, 'blur', function() {
// self.blur();
// });
on(this.element, 'mousedown', function() {
self.focus();
});
on(this.element, 'mousedown', function() {
self.focus();
});
// Clickable paste workaround, using contentEditable.
// This probably shouldn't work,
// ... but it does. Firefox's paste
// event seems to only work for textareas?
on(this.element, 'mousedown', function(ev) {
var button = ev.button != null
? +ev.button
: ev.which != null
? ev.which - 1
: null;
// Clickable paste workaround, using contentEditable.
// This probably shouldn't work,
// ... but it does. Firefox's paste
// event seems to only work for textareas?
on(this.element, 'mousedown', function(ev) {
var button = ev.button != null
? +ev.button
: ev.which != null
? ev.which - 1
: null;
// Does IE9 do this?
if (self.isMSIE) {
button = button === 1 ? 0 : button === 4 ? 1 : button;
}
// Does IE9 do this?
if (self.isMSIE) {
button = button === 1 ? 0 : button === 4 ? 1 : button;
}
if (button !== 2) return;
if (button !== 2) return;
self.element.contentEditable = 'true';
setTimeout(function() {
self.element.contentEditable = 'inherit'; // 'false';
}, 1);
}, true);
self.element.contentEditable = 'true';
setTimeout(function() {
self.element.contentEditable = 'inherit'; // 'false';
}, 1);
}, true);
}
// Listen for mouse events and translate
// them into terminal mouse protocols.
this.bindMouse();
if (!('useMouse' in this.options) || this.options.useMouse) {
// Listen for mouse events and translate
// them into terminal mouse protocols.
this.bindMouse();
}
// this.emit('open');
if (!('useFocus' in this.options) || this.options.useFocus) {
// This can be useful for pasting,
// as well as the iPad fix.
setTimeout(function() {
self.element.focus();
}, 100);
}
// Figure out whether boldness affects
// the character width of monospace fonts.
@ -794,13 +860,11 @@ Terminal.prototype.open = function(parent) {
Terminal.brokenBold = isBoldBroken(this.document);
}
// this.emit('open');
this.emit('open');
};
// This can be useful for pasting,
// as well as the iPad fix.
setTimeout(function() {
self.element.focus();
}, 100);
Terminal.prototype.setRawMode = function(value) {
this.isRaw = !!value;
};
// XTerm mouse events
@ -1093,10 +1157,11 @@ Terminal.prototype.bindMouse = function() {
// fix for odd bug
//if (self.vt200Mouse && !self.normalMouse) {
if (self.vt200Mouse) {
sendButton({ __proto__: ev, type: 'mouseup' });
return cancel(ev);
}
// XXX This seems to break certain programs.
// if (self.vt200Mouse) {
// sendButton({ __proto__: ev, type: 'mouseup' });
// return cancel(ev);
// }
// bind events
if (self.normalMouse) on(self.document, 'mousemove', sendMove);
@ -1145,16 +1210,35 @@ Terminal.prototype.bindMouse = function() {
* Destroy Terminal
*/
Terminal.prototype.close =
Terminal.prototype.destroySoon =
Terminal.prototype.destroy = function() {
if (this.destroyed) {
return;
}
if (this._blink) {
clearInterval(this._blink);
delete this._blink;
}
this.readable = false;
this.writable = false;
this.destroyed = true;
this._events = {};
this.handler = function() {};
this.write = function() {};
this.end = function() {};
if (this.element.parentNode) {
this.element.parentNode.removeChild(this.element);
}
//this.emit('close');
this.emit('end');
this.emit('close');
this.emit('finish');
this.emit('destroy');
};
/**
@ -1358,7 +1442,7 @@ Terminal.prototype.startBlink = function() {
};
Terminal.prototype.refreshBlink = function() {
if (!this.cursorBlink) return;
if (!this.cursorBlink || !this._blink) return;
clearInterval(this._blink);
this._blink = setInterval(this._blinker, 500);
};
@ -1432,7 +1516,7 @@ Terminal.prototype.write = function(data) {
// this.log(JSON.stringify(data.replace(/\x1b/g, '^[')));
for (; i < l; i++) {
for (; i < l; i++, this.lch = ch) {
ch = data[i];
switch (this.state) {
case normal:
@ -1548,7 +1632,8 @@ Terminal.prototype.write = function(data) {
// ESC P Device Control String ( DCS is 0x90).
case 'P':
this.params = [];
this.currentParam = 0;
this.prefix = '';
this.currentParam = '';
this.state = dcs;
break;
@ -1771,8 +1856,14 @@ Terminal.prototype.write = function(data) {
// OSC Ps ; Pt ST
// OSC Ps ; Pt BEL
// Set Text Parameters.
if (ch === '\x1b' || ch === '\x07') {
if (ch === '\x1b') i++;
if ((this.lch === '\x1b' && ch === '\\') || ch === '\x07') {
if (this.lch === '\x1b') {
if (typeof this.currentParam === 'string') {
this.currentParam = this.currentParam.slice(0, -1);
} else if (typeof this.currentParam == 'number') {
this.currentParam = (this.currentParam - ('\x1b'.charCodeAt(0) - 48)) / 10;
}
}
this.params.push(this.currentParam);
@ -2304,94 +2395,158 @@ Terminal.prototype.write = function(data) {
break;
case dcs:
if (ch === '\x1b' || ch === '\x07') {
if (ch === '\x1b') i++;
if ((this.lch === '\x1b' && ch === '\\') || ch === '\x07') {
// Workarounds:
if (this.prefix === 'tmux;\x1b') {
// `DCS tmux; Pt ST` may contain a Pt with an ST
// XXX Does tmux work this way?
// if (this.lch === '\x1b' & data[i + 1] === '\x1b' && data[i + 2] === '\\') {
// this.currentParam += ch;
// continue;
// }
// Tmux only accepts ST, not BEL:
if (ch === '\x07') {
this.currentParam += ch;
continue;
}
}
if (this.lch === '\x1b') {
if (typeof this.currentParam === 'string') {
this.currentParam = this.currentParam.slice(0, -1);
} else if (typeof this.currentParam == 'number') {
this.currentParam = (this.currentParam - ('\x1b'.charCodeAt(0) - 48)) / 10;
}
}
this.params.push(this.currentParam);
var pt = this.params[this.params.length - 1];
switch (this.prefix) {
// User-Defined Keys (DECUDK).
case '':
// DCS Ps; Ps| Pt ST
case UDK:
this.emit('udk', {
clearAll: this.params[0] === 0,
eraseBelow: this.params[0] === 1,
lockKeys: this.params[1] === 0,
dontLockKeys: this.params[1] === 1,
keyList: (this.params[2] + '').split(';').map(function(part) {
part = part.split('/');
return {
keyCode: part[0],
hexKeyValue: part[1]
};
})
});
break;
// Request Status String (DECRQSS).
// DCS $ q Pt ST
// test: echo -e '\eP$q"p\e\\'
case '$q':
var pt = this.currentParam
, valid = false;
var valid = 0;
switch (pt) {
// DECSCA
// CSI Ps " q
case '"q':
pt = '0"q';
valid = 1;
break;
// DECSCL
// CSI Ps ; Ps " p
case '"p':
pt = '61"p';
pt = '61;0"p';
valid = 1;
break;
// DECSTBM
// CSI Ps ; Ps r
case 'r':
pt = ''
+ (this.scrollTop + 1)
+ ';'
+ (this.scrollBottom + 1)
+ 'r';
valid = 1;
break;
// SGR
// CSI Pm m
case 'm':
pt = '0m';
// TODO: Parse this.curAttr here.
// pt = '0m';
// valid = 1;
valid = 0; // Not implemented.
break;
default:
this.error('Unknown DCS Pt: %s.', pt);
pt = '';
valid = 0; // unimplemented
break;
}
this.send('\x1bP' + +valid + '$r' + pt + '\x1b\\');
this.send('\x1bP' + valid + '$r' + pt + '\x1b\\');
break;
// Set Termcap/Terminfo Data (xterm, experimental).
// DCS + p Pt ST
case '+p':
this.emit('set terminfo', {
name: this.params[0]
});
break;
// Request Termcap/Terminfo String (xterm, experimental)
// Regular xterm does not even respond to this sequence.
// This can cause a small glitch in vim.
// DCS + q Pt ST
// test: echo -ne '\eP+q6b64\e\\'
case '+q':
var pt = this.currentParam
, valid = false;
var valid = false;
this.send('\x1bP' + +valid + '+r' + pt + '\x1b\\');
break;
// Implement tmux sequence forwarding is
// someone uses term.js for a multiplexer.
// DCS tmux; ESC Pt ST
case 'tmux;\x1b':
this.emit('passthrough', pt);
break;
default:
this.error('Unknown DCS prefix: %s.', this.prefix);
this.error('Unknown DCS prefix: %s.', pt);
break;
}
this.currentParam = 0;
this.prefix = '';
this.state = normal;
} else if (!this.currentParam) {
if (!this.prefix && ch !== '$' && ch !== '+') {
this.currentParam = ch;
} else if (this.prefix.length === 2) {
this.currentParam = ch;
} else {
this.prefix += ch;
}
} else {
this.currentParam += ch;
if (!this.prefix) {
if (/^\d*;\d*\|/.test(this.currentParam)) {
this.prefix = UDK;
this.params = this.currentParam.split(/[;|]/).map(function(n) {
if (!n.length) return 0;
return +n;
}).slice(0, -1);
this.currentParam = '';
} else if (/^[$+][a-zA-Z]/.test(this.currentParam)
|| /^\w+;\x1b/.test(this.currentParam)) {
this.prefix = this.currentParam;
this.currentParam = '';
}
}
}
break;
case ignore:
// For PM and APC.
if (ch === '\x1b' || ch === '\x07') {
if (ch === '\x1b') i++;
if ((this.lch === '\x1b' && ch === '\\') || ch === '\x07') {
this.state = normal;
}
break;
@ -2400,10 +2555,29 @@ Terminal.prototype.write = function(data) {
this.updateRange(this.y);
this.refresh(this.refreshStart, this.refreshEnd);
return true;
};
Terminal.prototype.writeln = function(data) {
this.write(data + '\r\n');
return this.write(data + '\r\n');
};
Terminal.prototype.end = function(data) {
var ret = true;
if (data) {
ret = this.write(data);
}
this.destroySoon();
return ret;
};
Terminal.prototype.resume = function() {
;
};
Terminal.prototype.pause = function() {
;
};
// Key Resources:
@ -2415,6 +2589,10 @@ Terminal.prototype.keyDown = function(ev) {
switch (ev.keyCode) {
// backspace
case 8:
if (ev.altKey) {
key = '\x17';
break;
}
if (ev.shiftKey) {
key = '\x08'; // ^H
break;
@ -2437,6 +2615,10 @@ Terminal.prototype.keyDown = function(ev) {
case 27:
key = '\x1b';
break;
// space
case 32:
key = '\x20';
break;
// left-arrow
case 37:
if (this.applicationCursor) {
@ -2444,6 +2626,10 @@ Terminal.prototype.keyDown = function(ev) {
//key = '\x8fD'; // SS3 as 0x8f for 8-bit
break;
}
if (ev.ctrlKey) {
key = '\x1b[5D';
break;
}
key = '\x1b[D';
break;
// right-arrow
@ -2452,6 +2638,10 @@ Terminal.prototype.keyDown = function(ev) {
key = '\x1bOC';
break;
}
if (ev.ctrlKey) {
key = '\x1b[5C';
break;
}
key = '\x1b[C';
break;
// up-arrow
@ -2612,7 +2802,7 @@ Terminal.prototype.keyDown = function(ev) {
// ^] - group sep
key = String.fromCharCode(29);
}
} else if ((!this.isMac && ev.altKey) || (this.isMac && ev.metaKey)) {
} else if (ev.altKey) {
if (ev.keyCode >= 65 && ev.keyCode <= 90) {
key = '\x1b' + String.fromCharCode(ev.keyCode + 32);
} else if (ev.keyCode === 192) {
@ -2764,6 +2954,7 @@ Terminal.prototype.resize = function(x, y) {
}
this.setupStops(j);
this.cols = x;
this.columns = x;
// resize rows
j = this.rows;
@ -2807,6 +2998,9 @@ Terminal.prototype.resize = function(x, y) {
// screen buffer. just set it
// to null for now.
this.normal = null;
// Act as though we are a node TTY stream:
this.emit('resize');
};
Terminal.prototype.updateRange = function(y) {
@ -2856,6 +3050,12 @@ Terminal.prototype.nextStop = function(x) {
: x < 0 ? 0 : x;
};
// back_color_erase feature for xterm.
Terminal.prototype.eraseAttr = function() {
// if (this.is('screen')) return this.defAttr;
return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);
};
Terminal.prototype.eraseRight = function(x, y) {
var line = this.lines[this.ybase + y]
, ch = [this.eraseAttr(), ' ']; // xterm
@ -5652,13 +5852,18 @@ function inherits(child, parent) {
// use it in the terminal.
function isBoldBroken(document) {
var body = document.getElementsByTagName('body')[0];
var terminal = document.createElement('div');
terminal.className = 'terminal';
var line = document.createElement('div');
var el = document.createElement('span');
el.innerHTML = 'hello world';
body.appendChild(el);
line.appendChild(el);
terminal.appendChild(line);
body.appendChild(terminal);
var w1 = el.scrollWidth;
el.style.fontWeight = 'bold';
var w2 = el.scrollWidth;
body.removeChild(el);
body.removeChild(terminal);
return w1 !== w2;
}
@ -5755,6 +5960,7 @@ function keys(obj) {
*/
Terminal.EventEmitter = EventEmitter;
Terminal.Stream = Stream;
Terminal.inherits = inherits;
Terminal.on = on;
Terminal.off = off;

View file

@ -114,6 +114,54 @@ EventEmitter.prototype.listeners = function(type) {
return this._events[type] = this._events[type] || [];
};
/**
* Stream
*/
function Stream() {
EventEmitter.call(this);
}
inherits(Stream, EventEmitter);
Stream.prototype.pipe = function(dest, options) {
var src = this
, ondata
, onerror
, onend;
function unbind() {
src.removeListener('data', ondata);
src.removeListener('error', onerror);
src.removeListener('end', onend);
dest.removeListener('error', onerror);
dest.removeListener('close', unbind);
}
src.on('data', ondata = function(data) {
dest.write(data);
});
src.on('error', onerror = function(err) {
unbind();
if (!this.listeners('error').length) {
throw err;
}
});
src.on('end', onend = function() {
dest.end();
unbind();
});
dest.on('error', onerror);
dest.on('close', unbind);
dest.emit('pipe', src);
return dest;
};
/**
* States
*/
@ -124,7 +172,8 @@ var normal = 0
, osc = 3
, charset = 4
, dcs = 5
, ignore = 6;
, ignore = 6
, UDK = { type: 'udk' };
/**
* Terminal
@ -137,7 +186,7 @@ function Terminal(options) {
return new Terminal(arguments[0], arguments[1], arguments[2]);
}
EventEmitter.call(this);
Stream.call(this);
if (typeof options === 'number') {
options = {
@ -183,6 +232,13 @@ function Terminal(options) {
this.cols = options.cols || options.geometry[0];
this.rows = options.rows || options.geometry[1];
// Act as though we are a node TTY stream:
this.setRawMode;
this.isTTY = true;
this.isRaw = true;
this.columns = this.cols;
this.rows = this.rows;
if (options.handler) {
this.on('data', options.handler);
}
@ -268,13 +324,7 @@ function Terminal(options) {
this.setupStops();
}
inherits(Terminal, EventEmitter);
// back_color_erase feature for xterm.
Terminal.prototype.eraseAttr = function() {
// if (this.is('screen')) return this.defAttr;
return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);
};
inherits(Terminal, Stream);
/**
* Colors
@ -732,61 +782,77 @@ Terminal.prototype.open = function(parent) {
// Draw the screen.
this.refresh(0, this.rows - 1);
// Initialize global actions that
// need to be taken on the document.
this.initGlobal();
if (!('useEvents' in this.options) || this.options.useEvents) {
// Initialize global actions that
// need to be taken on the document.
this.initGlobal();
}
// Ensure there is a Terminal.focus.
this.focus();
if (!('useFocus' in this.options) || this.options.useFocus) {
// Ensure there is a Terminal.focus.
this.focus();
// Start blinking the cursor.
this.startBlink();
// Start blinking the cursor.
this.startBlink();
// Bind to DOM events related
// to focus and paste behavior.
on(this.element, 'focus', function() {
self.focus();
if (self.isMobile) {
Terminal._textarea.focus();
}
});
// Bind to DOM events related
// to focus and paste behavior.
on(this.element, 'focus', function() {
self.focus();
if (self.isMobile) {
Terminal._textarea.focus();
}
});
// This causes slightly funky behavior.
// on(this.element, 'blur', function() {
// self.blur();
// });
// This causes slightly funky behavior.
// on(this.element, 'blur', function() {
// self.blur();
// });
on(this.element, 'mousedown', function() {
self.focus();
});
on(this.element, 'mousedown', function() {
self.focus();
});
// Clickable paste workaround, using contentEditable.
// This probably shouldn't work,
// ... but it does. Firefox's paste
// event seems to only work for textareas?
on(this.element, 'mousedown', function(ev) {
var button = ev.button != null
? +ev.button
: ev.which != null
? ev.which - 1
: null;
// Clickable paste workaround, using contentEditable.
// This probably shouldn't work,
// ... but it does. Firefox's paste
// event seems to only work for textareas?
on(this.element, 'mousedown', function(ev) {
var button = ev.button != null
? +ev.button
: ev.which != null
? ev.which - 1
: null;
// Does IE9 do this?
if (self.isMSIE) {
button = button === 1 ? 0 : button === 4 ? 1 : button;
}
// Does IE9 do this?
if (self.isMSIE) {
button = button === 1 ? 0 : button === 4 ? 1 : button;
}
if (button !== 2) return;
if (button !== 2) return;
self.element.contentEditable = 'true';
setTimeout(function() {
self.element.contentEditable = 'inherit'; // 'false';
}, 1);
}, true);
self.element.contentEditable = 'true';
setTimeout(function() {
self.element.contentEditable = 'inherit'; // 'false';
}, 1);
}, true);
}
// Listen for mouse events and translate
// them into terminal mouse protocols.
this.bindMouse();
if (!('useMouse' in this.options) || this.options.useMouse) {
// Listen for mouse events and translate
// them into terminal mouse protocols.
this.bindMouse();
}
// this.emit('open');
if (!('useFocus' in this.options) || this.options.useFocus) {
// This can be useful for pasting,
// as well as the iPad fix.
setTimeout(function() {
self.element.focus();
}, 100);
}
// Figure out whether boldness affects
// the character width of monospace fonts.
@ -794,13 +860,11 @@ Terminal.prototype.open = function(parent) {
Terminal.brokenBold = isBoldBroken(this.document);
}
// this.emit('open');
this.emit('open');
};
// This can be useful for pasting,
// as well as the iPad fix.
setTimeout(function() {
self.element.focus();
}, 100);
Terminal.prototype.setRawMode = function(value) {
this.isRaw = !!value;
};
// XTerm mouse events
@ -1093,10 +1157,11 @@ Terminal.prototype.bindMouse = function() {
// fix for odd bug
//if (self.vt200Mouse && !self.normalMouse) {
if (self.vt200Mouse) {
sendButton({ __proto__: ev, type: 'mouseup' });
return cancel(ev);
}
// XXX This seems to break certain programs.
// if (self.vt200Mouse) {
// sendButton({ __proto__: ev, type: 'mouseup' });
// return cancel(ev);
// }
// bind events
if (self.normalMouse) on(self.document, 'mousemove', sendMove);
@ -1145,16 +1210,35 @@ Terminal.prototype.bindMouse = function() {
* Destroy Terminal
*/
Terminal.prototype.close =
Terminal.prototype.destroySoon =
Terminal.prototype.destroy = function() {
if (this.destroyed) {
return;
}
if (this._blink) {
clearInterval(this._blink);
delete this._blink;
}
this.readable = false;
this.writable = false;
this.destroyed = true;
this._events = {};
this.handler = function() {};
this.write = function() {};
this.end = function() {};
if (this.element.parentNode) {
this.element.parentNode.removeChild(this.element);
}
//this.emit('close');
this.emit('end');
this.emit('close');
this.emit('finish');
this.emit('destroy');
};
/**
@ -1358,7 +1442,7 @@ Terminal.prototype.startBlink = function() {
};
Terminal.prototype.refreshBlink = function() {
if (!this.cursorBlink) return;
if (!this.cursorBlink || !this._blink) return;
clearInterval(this._blink);
this._blink = setInterval(this._blinker, 500);
};
@ -1432,7 +1516,7 @@ Terminal.prototype.write = function(data) {
// this.log(JSON.stringify(data.replace(/\x1b/g, '^[')));
for (; i < l; i++) {
for (; i < l; i++, this.lch = ch) {
ch = data[i];
switch (this.state) {
case normal:
@ -1548,7 +1632,8 @@ Terminal.prototype.write = function(data) {
// ESC P Device Control String ( DCS is 0x90).
case 'P':
this.params = [];
this.currentParam = 0;
this.prefix = '';
this.currentParam = '';
this.state = dcs;
break;
@ -1771,8 +1856,14 @@ Terminal.prototype.write = function(data) {
// OSC Ps ; Pt ST
// OSC Ps ; Pt BEL
// Set Text Parameters.
if (ch === '\x1b' || ch === '\x07') {
if (ch === '\x1b') i++;
if ((this.lch === '\x1b' && ch === '\\') || ch === '\x07') {
if (this.lch === '\x1b') {
if (typeof this.currentParam === 'string') {
this.currentParam = this.currentParam.slice(0, -1);
} else if (typeof this.currentParam == 'number') {
this.currentParam = (this.currentParam - ('\x1b'.charCodeAt(0) - 48)) / 10;
}
}
this.params.push(this.currentParam);
@ -2304,94 +2395,158 @@ Terminal.prototype.write = function(data) {
break;
case dcs:
if (ch === '\x1b' || ch === '\x07') {
if (ch === '\x1b') i++;
if ((this.lch === '\x1b' && ch === '\\') || ch === '\x07') {
// Workarounds:
if (this.prefix === 'tmux;\x1b') {
// `DCS tmux; Pt ST` may contain a Pt with an ST
// XXX Does tmux work this way?
// if (this.lch === '\x1b' & data[i + 1] === '\x1b' && data[i + 2] === '\\') {
// this.currentParam += ch;
// continue;
// }
// Tmux only accepts ST, not BEL:
if (ch === '\x07') {
this.currentParam += ch;
continue;
}
}
if (this.lch === '\x1b') {
if (typeof this.currentParam === 'string') {
this.currentParam = this.currentParam.slice(0, -1);
} else if (typeof this.currentParam == 'number') {
this.currentParam = (this.currentParam - ('\x1b'.charCodeAt(0) - 48)) / 10;
}
}
this.params.push(this.currentParam);
var pt = this.params[this.params.length - 1];
switch (this.prefix) {
// User-Defined Keys (DECUDK).
case '':
// DCS Ps; Ps| Pt ST
case UDK:
this.emit('udk', {
clearAll: this.params[0] === 0,
eraseBelow: this.params[0] === 1,
lockKeys: this.params[1] === 0,
dontLockKeys: this.params[1] === 1,
keyList: (this.params[2] + '').split(';').map(function(part) {
part = part.split('/');
return {
keyCode: part[0],
hexKeyValue: part[1]
};
})
});
break;
// Request Status String (DECRQSS).
// DCS $ q Pt ST
// test: echo -e '\eP$q"p\e\\'
case '$q':
var pt = this.currentParam
, valid = false;
var valid = 0;
switch (pt) {
// DECSCA
// CSI Ps " q
case '"q':
pt = '0"q';
valid = 1;
break;
// DECSCL
// CSI Ps ; Ps " p
case '"p':
pt = '61"p';
pt = '61;0"p';
valid = 1;
break;
// DECSTBM
// CSI Ps ; Ps r
case 'r':
pt = ''
+ (this.scrollTop + 1)
+ ';'
+ (this.scrollBottom + 1)
+ 'r';
valid = 1;
break;
// SGR
// CSI Pm m
case 'm':
pt = '0m';
// TODO: Parse this.curAttr here.
// pt = '0m';
// valid = 1;
valid = 0; // Not implemented.
break;
default:
this.error('Unknown DCS Pt: %s.', pt);
pt = '';
valid = 0; // unimplemented
break;
}
this.send('\x1bP' + +valid + '$r' + pt + '\x1b\\');
this.send('\x1bP' + valid + '$r' + pt + '\x1b\\');
break;
// Set Termcap/Terminfo Data (xterm, experimental).
// DCS + p Pt ST
case '+p':
this.emit('set terminfo', {
name: this.params[0]
});
break;
// Request Termcap/Terminfo String (xterm, experimental)
// Regular xterm does not even respond to this sequence.
// This can cause a small glitch in vim.
// DCS + q Pt ST
// test: echo -ne '\eP+q6b64\e\\'
case '+q':
var pt = this.currentParam
, valid = false;
var valid = false;
this.send('\x1bP' + +valid + '+r' + pt + '\x1b\\');
break;
// Implement tmux sequence forwarding is
// someone uses term.js for a multiplexer.
// DCS tmux; ESC Pt ST
case 'tmux;\x1b':
this.emit('passthrough', pt);
break;
default:
this.error('Unknown DCS prefix: %s.', this.prefix);
this.error('Unknown DCS prefix: %s.', pt);
break;
}
this.currentParam = 0;
this.prefix = '';
this.state = normal;
} else if (!this.currentParam) {
if (!this.prefix && ch !== '$' && ch !== '+') {
this.currentParam = ch;
} else if (this.prefix.length === 2) {
this.currentParam = ch;
} else {
this.prefix += ch;
}
} else {
this.currentParam += ch;
if (!this.prefix) {
if (/^\d*;\d*\|/.test(this.currentParam)) {
this.prefix = UDK;
this.params = this.currentParam.split(/[;|]/).map(function(n) {
if (!n.length) return 0;
return +n;
}).slice(0, -1);
this.currentParam = '';
} else if (/^[$+][a-zA-Z]/.test(this.currentParam)
|| /^\w+;\x1b/.test(this.currentParam)) {
this.prefix = this.currentParam;
this.currentParam = '';
}
}
}
break;
case ignore:
// For PM and APC.
if (ch === '\x1b' || ch === '\x07') {
if (ch === '\x1b') i++;
if ((this.lch === '\x1b' && ch === '\\') || ch === '\x07') {
this.state = normal;
}
break;
@ -2400,10 +2555,29 @@ Terminal.prototype.write = function(data) {
this.updateRange(this.y);
this.refresh(this.refreshStart, this.refreshEnd);
return true;
};
Terminal.prototype.writeln = function(data) {
this.write(data + '\r\n');
return this.write(data + '\r\n');
};
Terminal.prototype.end = function(data) {
var ret = true;
if (data) {
ret = this.write(data);
}
this.destroySoon();
return ret;
};
Terminal.prototype.resume = function() {
;
};
Terminal.prototype.pause = function() {
;
};
// Key Resources:
@ -2415,6 +2589,10 @@ Terminal.prototype.keyDown = function(ev) {
switch (ev.keyCode) {
// backspace
case 8:
if (ev.altKey) {
key = '\x17';
break;
}
if (ev.shiftKey) {
key = '\x08'; // ^H
break;
@ -2437,6 +2615,10 @@ Terminal.prototype.keyDown = function(ev) {
case 27:
key = '\x1b';
break;
// space
case 32:
key = '\x20';
break;
// left-arrow
case 37:
if (this.applicationCursor) {
@ -2444,6 +2626,10 @@ Terminal.prototype.keyDown = function(ev) {
//key = '\x8fD'; // SS3 as 0x8f for 8-bit
break;
}
if (ev.ctrlKey) {
key = '\x1b[5D';
break;
}
key = '\x1b[D';
break;
// right-arrow
@ -2452,6 +2638,10 @@ Terminal.prototype.keyDown = function(ev) {
key = '\x1bOC';
break;
}
if (ev.ctrlKey) {
key = '\x1b[5C';
break;
}
key = '\x1b[C';
break;
// up-arrow
@ -2612,7 +2802,7 @@ Terminal.prototype.keyDown = function(ev) {
// ^] - group sep
key = String.fromCharCode(29);
}
} else if ((!this.isMac && ev.altKey) || (this.isMac && ev.metaKey)) {
} else if (ev.altKey) {
if (ev.keyCode >= 65 && ev.keyCode <= 90) {
key = '\x1b' + String.fromCharCode(ev.keyCode + 32);
} else if (ev.keyCode === 192) {
@ -2764,6 +2954,7 @@ Terminal.prototype.resize = function(x, y) {
}
this.setupStops(j);
this.cols = x;
this.columns = x;
// resize rows
j = this.rows;
@ -2807,6 +2998,9 @@ Terminal.prototype.resize = function(x, y) {
// screen buffer. just set it
// to null for now.
this.normal = null;
// Act as though we are a node TTY stream:
this.emit('resize');
};
Terminal.prototype.updateRange = function(y) {
@ -2856,6 +3050,12 @@ Terminal.prototype.nextStop = function(x) {
: x < 0 ? 0 : x;
};
// back_color_erase feature for xterm.
Terminal.prototype.eraseAttr = function() {
// if (this.is('screen')) return this.defAttr;
return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);
};
Terminal.prototype.eraseRight = function(x, y) {
var line = this.lines[this.ybase + y]
, ch = [this.eraseAttr(), ' ']; // xterm
@ -5652,13 +5852,18 @@ function inherits(child, parent) {
// use it in the terminal.
function isBoldBroken(document) {
var body = document.getElementsByTagName('body')[0];
var terminal = document.createElement('div');
terminal.className = 'terminal';
var line = document.createElement('div');
var el = document.createElement('span');
el.innerHTML = 'hello world';
body.appendChild(el);
line.appendChild(el);
terminal.appendChild(line);
body.appendChild(terminal);
var w1 = el.scrollWidth;
el.style.fontWeight = 'bold';
var w2 = el.scrollWidth;
body.removeChild(el);
body.removeChild(terminal);
return w1 !== w2;
}
@ -5755,6 +5960,7 @@ function keys(obj) {
*/
Terminal.EventEmitter = EventEmitter;
Terminal.Stream = Stream;
Terminal.inherits = inherits;
Terminal.on = on;
Terminal.off = off;

10
web/dist/index.html vendored
View file

@ -11,15 +11,15 @@
<script src="/web/app/assets/js/jquery-2.1.1.js"></script>
<script src="/web/app/assets/js/jquery-validate-1.14.0.js"></script>
<script src="/web/app/assets/js/underscore-1.8.3.js"></script>
<script src="/web/app/assets/js/bootstrap.js"></script>
<script src="/web/app/assets/js/term.js"></script>
<script src="/web/app/assets/js/bootstrap-3.3.6.js"></script>
<script src="/web/app/assets/js/term-0.0.7.js"></script>
<script src="/web/app/assets/js/bootstrap-datepicker-1.6.0.js"></script>
<script src="/web/app/vendor.js?ver=0.11458109567737"></script>
<script src="/web/app/styles.js?ver=0.11458109567737"></script>
<script src="/web/app/vendor.js?ver=0.11458143971205"></script>
<script src="/web/app/styles.js?ver=0.11458143971205"></script>
</head>
<body class="grv">
<div id="app"></div>
</body>
<script src="/web/app/app.js?ver=0.11458109567737"></script>
<script src="/web/app/app.js?ver=0.11458143971205"></script>
</html>

View file

@ -18,8 +18,8 @@ module.exports = function (config) {
files: [
'node_modules/phantomjs-polyfill/bind-polyfill.js',
'src/assets/js/jquery-2.1.1.js',
'src/assets/js/bootstrap.min.js',
'src/assets/js/term.js',
'src/assets/js/bootstrap-3.3.6.min.js',
'src/assets/js/term-0.0.7.js',
'src/assets/js/jquery-validate-1.14.0.js',
'tests.webpack.js'
],

View file

@ -6,8 +6,8 @@
"scripts": {
"inspector": "node-inspector --web-port=8081 --save-live-edit=true --preload=false",
"dev-debug": "node --debug-brk /usr/bin/gulp dev",
"build": "node node_modules/webpack/bin/webpack.js",
"dev": "gulp; node node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --content-base dist",
"build": "gulp",
"start": "gulp dev",
"lint": "node node_modules/eslint/bin/eslint src/**/*.js",
"test": "TELEPORT_NO_DEBUG=1 node node_modules/karma/bin/karma start --browsers PhantomJS --single-run",
"tdd": "node node_modules/karma/bin/karma start --browsers Chrome"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -11,8 +11,8 @@
<script src="/web/app/assets/js/jquery-2.1.1.js"></script>
<script src="/web/app/assets/js/jquery-validate-1.14.0.js"></script>
<script src="/web/app/assets/js/underscore-1.8.3.js"></script>
<script src="/web/app/assets/js/bootstrap.js"></script>
<script src="/web/app/assets/js/term.js"></script>
<script src="/web/app/assets/js/bootstrap-3.3.6.js"></script>
<script src="/web/app/assets/js/term-0.0.7.js"></script>
<script src="/web/app/assets/js/bootstrap-datepicker-1.6.0.js"></script>
<script src="/web/app/vendor.js?ver=[VERSION]"></script>
<script src="/web/app/styles.js?ver=[VERSION]"></script>