Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
webapp.scripts.lib.term.js Maven / Gradle / Ivy
/**
* term.js - an xterm emulator
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
* https://github.com/chjj/term.js
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Originally forked from (with the author's permission):
* Fabrice Bellard's javascript vt100 for jslinux:
* http://bellard.org/jslinux/
* Copyright (c) 2011 Fabrice Bellard
* The original design remains. The terminal itself
* has been extended to include xterm CSI codes, among
* other features.
*/
;(function() {
/**
* Terminal Emulation References:
* http://vt100.net/
* http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt
* http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
* http://invisible-island.net/vttest/
* http://www.inwap.com/pdp10/ansicode.txt
* http://linux.die.net/man/4/console_codes
* http://linux.die.net/man/7/urxvt
*/
'use strict';
/**
* Shared
*/
var window = this
, document = this.document;
/**
* EventEmitter
*/
function EventEmitter() {
this._events = this._events || {};
}
EventEmitter.prototype.addListener = function(type, listener) {
this._events[type] = this._events[type] || [];
this._events[type].push(listener);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.removeListener = function(type, listener) {
if (!this._events[type]) return;
var obj = this._events[type]
, i = obj.length;
while (i--) {
if (obj[i] === listener || obj[i].listener === listener) {
obj.splice(i, 1);
return;
}
}
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.removeAllListeners = function(type) {
if (this._events[type]) delete this._events[type];
};
EventEmitter.prototype.once = function(type, listener) {
function on() {
var args = Array.prototype.slice.call(arguments);
this.removeListener(type, on);
return listener.apply(this, args);
}
on.listener = listener;
return this.on(type, on);
};
EventEmitter.prototype.emit = function(type) {
if (!this._events[type]) return;
var args = Array.prototype.slice.call(arguments, 1)
, obj = this._events[type]
, l = obj.length
, i = 0;
for (; i < l; i++) {
obj[i].apply(this, args);
}
};
EventEmitter.prototype.listeners = function(type) {
return this._events[type] = this._events[type] || [];
};
/**
* States
*/
var normal = 0
, escaped = 1
, csi = 2
, osc = 3
, charset = 4
, dcs = 5
, ignore = 6;
/**
* Terminal
*/
function Terminal(options) {
var self = this;
if (!(this instanceof Terminal)) {
return new Terminal(arguments[0], arguments[1], arguments[2]);
}
EventEmitter.call(this);
if (typeof options === 'number') {
options = {
cols: arguments[0],
rows: arguments[1],
handler: arguments[2]
};
}
options = options || {};
each(keys(Terminal.defaults), function(key) {
if (options[key] == null) {
options[key] = Terminal.options[key];
// Legacy:
if (Terminal[key] !== Terminal.defaults[key]) {
options[key] = Terminal[key];
}
}
self[key] = options[key];
});
if (options.colors.length === 8) {
options.colors = options.colors.concat(Terminal._colors.slice(8));
} else if (options.colors.length === 16) {
options.colors = options.colors.concat(Terminal._colors.slice(16));
} else if (options.colors.length === 10) {
options.colors = options.colors.slice(0, -2).concat(
Terminal._colors.slice(8, -2), options.colors.slice(-2));
} else if (options.colors.length === 18) {
options.colors = options.colors.concat(
Terminal._colors.slice(16, -2), options.colors.slice(-2));
}
this.colors = options.colors;
this.options = options;
// this.context = options.context || window;
// this.document = options.document || document;
this.parent = options.body || options.parent
|| (document ? document.getElementsByTagName('body')[0] : null);
this.cols = options.cols || options.geometry[0];
this.rows = options.rows || options.geometry[1];
if (options.handler) {
this.on('data', options.handler);
}
this.ybase = 0;
this.ydisp = 0;
this.x = 0;
this.y = 0;
this.cursorState = 0;
this.cursorHidden = false;
this.convertEol;
this.state = 0;
this.queue = '';
this.scrollTop = 0;
this.scrollBottom = this.rows - 1;
// modes
this.applicationKeypad = false;
this.applicationCursor = false;
this.originMode = false;
this.insertMode = false;
this.wraparoundMode = false;
this.normal = null;
// select modes
this.prefixMode = false;
this.selectMode = false;
this.visualMode = false;
this.searchMode = false;
this.searchDown;
this.entry = '';
this.entryPrefix = 'Search: ';
this._real;
this._selected;
this._textarea;
// charset
this.charset = null;
this.gcharset = null;
this.glevel = 0;
this.charsets = [null];
// mouse properties
this.decLocator;
this.x10Mouse;
this.vt200Mouse;
this.vt300Mouse;
this.normalMouse;
this.mouseEvents;
this.sendFocus;
this.utfMouse;
this.sgrMouse;
this.urxvtMouse;
// misc
this.element;
this.children;
this.refreshStart;
this.refreshEnd;
this.savedX;
this.savedY;
this.savedCols;
// stream
this.readable = true;
this.writable = true;
this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);
this.curAttr = this.defAttr;
this.params = [];
this.currentParam = 0;
this.prefix = '';
this.postfix = '';
this.lines = [];
var i = this.rows;
while (i--) {
this.lines.push(this.blankLine());
}
this.tabs;
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);
};
/**
* Colors
*/
// Colors 0-15
Terminal.tangoColors = [
// dark:
'#2e3436',
'#cc0000',
'#4e9a06',
'#c4a000',
'#3465a4',
'#75507b',
'#06989a',
'#d3d7cf',
// bright:
'#555753',
'#ef2929',
'#8ae234',
'#fce94f',
'#729fcf',
'#ad7fa8',
'#34e2e2',
'#eeeeec'
];
Terminal.xtermColors = [
// dark:
'#000000', // black
'#cd0000', // red3
'#00cd00', // green3
'#cdcd00', // yellow3
'#0000ee', // blue2
'#cd00cd', // magenta3
'#00cdcd', // cyan3
'#e5e5e5', // gray90
// bright:
'#7f7f7f', // gray50
'#ff0000', // red
'#00ff00', // green
'#ffff00', // yellow
'#5c5cff', // rgb:5c/5c/ff
'#ff00ff', // magenta
'#00ffff', // cyan
'#ffffff' // white
];
// Colors 0-15 + 16-255
// Much thanks to TooTallNate for writing this.
Terminal.colors = (function() {
var colors = Terminal.tangoColors.slice()
, r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]
, i;
// 16-231
i = 0;
for (; i < 216; i++) {
out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);
}
// 232-255 (grey)
i = 0;
for (; i < 24; i++) {
r = 8 + i * 10;
out(r, r, r);
}
function out(r, g, b) {
colors.push('#' + hex(r) + hex(g) + hex(b));
}
function hex(c) {
c = c.toString(16);
return c.length < 2 ? '0' + c : c;
}
return colors;
})();
// Default BG/FG
Terminal.colors[256] = '#000000';
Terminal.colors[257] = '#f0f0f0';
Terminal._colors = Terminal.colors.slice();
Terminal.vcolors = (function() {
var out = []
, colors = Terminal.colors
, i = 0
, color;
for (; i < 256; i++) {
color = parseInt(colors[i].substring(1), 16);
out.push([
(color >> 16) & 0xff,
(color >> 8) & 0xff,
color & 0xff
]);
}
return out;
})();
/**
* Options
*/
Terminal.defaults = {
colors: Terminal.colors,
convertEol: false,
termName: 'xterm',
geometry: [80, 24],
cursorBlink: true,
visualBell: false,
popOnBell: false,
scrollback: 1000,
screenKeys: false,
debug: false,
useStyle: false
// programFeatures: false,
// focusKeys: false,
};
Terminal.options = {};
each(keys(Terminal.defaults), function(key) {
Terminal[key] = Terminal.defaults[key];
Terminal.options[key] = Terminal.defaults[key];
});
/**
* Focused Terminal
*/
Terminal.focus = null;
Terminal.prototype.focus = function() {
if (Terminal.focus === this) return;
if (Terminal.focus) {
Terminal.focus.blur();
}
if (this.sendFocus) this.send('\x1b[I');
this.showCursor();
// try {
// this.element.focus();
// } catch (e) {
// ;
// }
// this.emit('focus');
Terminal.focus = this;
};
Terminal.prototype.blur = function() {
if (Terminal.focus !== this) return;
this.cursorState = 0;
this.refresh(this.y, this.y);
if (this.sendFocus) this.send('\x1b[O');
// try {
// this.element.blur();
// } catch (e) {
// ;
// }
// this.emit('blur');
Terminal.focus = null;
};
/**
* Initialize global behavior
*/
Terminal.prototype.initGlobal = function() {
var document = this.document;
Terminal._boundDocs = Terminal._boundDocs || [];
if (~indexOf(Terminal._boundDocs, document)) {
return;
}
Terminal._boundDocs.push(document);
Terminal.bindPaste(document);
Terminal.bindKeys(document);
Terminal.bindCopy(document);
if (this.isIpad || this.isIphone) {
Terminal.fixIpad(document);
}
if (this.useStyle) {
Terminal.insertStyle(document, this.colors[256], this.colors[257]);
}
};
/**
* Bind to paste event
*/
Terminal.bindPaste = function(document) {
// This seems to work well for ctrl-V and middle-click,
// even without the contentEditable workaround.
var window = document.defaultView;
on(window, 'paste', function(ev) {
var term = Terminal.focus;
if (!term) return;
if (ev.clipboardData) {
term.send(ev.clipboardData.getData('text/plain'));
} else if (term.context.clipboardData) {
term.send(term.context.clipboardData.getData('Text'));
}
// Not necessary. Do it anyway for good measure.
term.element.contentEditable = 'inherit';
return cancel(ev);
});
};
/**
* Global Events for key handling
*/
Terminal.bindKeys = function(document) {
// We should only need to check `target === body` below,
// but we can check everything for good measure.
on(document, 'keydown', function(ev) {
if (!Terminal.focus) return;
var target = ev.target || ev.srcElement;
if (!target) return;
if (target === Terminal.focus.element
|| target === Terminal.focus.context
|| target === Terminal.focus.document
|| target === Terminal.focus.body
|| target === Terminal._textarea
|| target === Terminal.focus.parent) {
return Terminal.focus.keyDown(ev);
}
}, true);
on(document, 'keypress', function(ev) {
if (!Terminal.focus) return;
var target = ev.target || ev.srcElement;
if (!target) return;
if (target === Terminal.focus.element
|| target === Terminal.focus.context
|| target === Terminal.focus.document
|| target === Terminal.focus.body
|| target === Terminal._textarea
|| target === Terminal.focus.parent) {
return Terminal.focus.keyPress(ev);
}
}, true);
// If we click somewhere other than a
// terminal, unfocus the terminal.
on(document, 'mousedown', function(ev) {
if (!Terminal.focus) return;
var el = ev.target || ev.srcElement;
if (!el) return;
do {
if (el === Terminal.focus.element) return;
} while (el = el.parentNode);
Terminal.focus.blur();
});
};
/**
* Copy Selection w/ Ctrl-C (Select Mode)
*/
Terminal.bindCopy = function(document) {
var window = document.defaultView;
// if (!('onbeforecopy' in document)) {
// // Copies to *only* the clipboard.
// on(window, 'copy', function fn(ev) {
// var term = Terminal.focus;
// if (!term) return;
// if (!term._selected) return;
// var text = term.grabText(
// term._selected.x1, term._selected.x2,
// term._selected.y1, term._selected.y2);
// term.emit('copy', text);
// ev.clipboardData.setData('text/plain', text);
// });
// return;
// }
// Copies to primary selection *and* clipboard.
// NOTE: This may work better on capture phase,
// or using the `beforecopy` event.
on(window, 'copy', function(ev) {
var term = Terminal.focus;
if (!term) return;
if (!term._selected) return;
var textarea = term.getCopyTextarea();
var text = term.grabText(
term._selected.x1, term._selected.x2,
term._selected.y1, term._selected.y2);
term.emit('copy', text);
textarea.focus();
textarea.textContent = text;
textarea.value = text;
textarea.setSelectionRange(0, text.length);
setTimeout(function() {
term.element.focus();
term.focus();
}, 1);
});
};
/**
* Fix iPad - no idea if this works
*/
Terminal.fixIpad = function(document) {
var textarea = document.createElement('textarea');
textarea.style.position = 'absolute';
textarea.style.left = '-32000px';
textarea.style.top = '-32000px';
textarea.style.width = '0px';
textarea.style.height = '0px';
textarea.style.opacity = '0';
textarea.style.backgroundColor = 'transparent';
textarea.style.borderStyle = 'none';
textarea.style.outlineStyle = 'none';
textarea.autocapitalize = 'none';
textarea.autocorrect = 'off';
document.getElementsByTagName('body')[0].appendChild(textarea);
Terminal._textarea = textarea;
setTimeout(function() {
textarea.focus();
}, 1000);
};
/**
* Insert a default style
*/
Terminal.insertStyle = function(document, bg, fg) {
var style = document.getElementById('term-style');
if (style) return;
var head = document.getElementsByTagName('head')[0];
if (!head) return;
var style = document.createElement('style');
style.id = 'term-style';
// textContent doesn't work well with IE for