add term
This commit is contained in:
BIN
static/term/pkg/jquery.terminal/bin/yuicompressor-2.4.8.jar
Normal file
BIN
static/term/pkg/jquery.terminal/bin/yuicompressor-2.4.8.jar
Normal file
Binary file not shown.
249
static/term/pkg/jquery.terminal/css/jquery.terminal.css
Normal file
249
static/term/pkg/jquery.terminal/css/jquery.terminal.css
Normal file
@ -0,0 +1,249 @@
|
||||
/*!
|
||||
* __ _____ ________ __
|
||||
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
|
||||
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
|
||||
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
|
||||
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
|
||||
* \/ /____/ version 0.10.8
|
||||
* http://terminal.jcubic.pl
|
||||
*
|
||||
* This file is part of jQuery Terminal.
|
||||
*
|
||||
* Copyright (c) 2011-2016 Jakub Jankiewicz <http://jcubic.pl>
|
||||
* Released under the MIT license
|
||||
*
|
||||
* Date: Tue, 17 May 2016 09:01:55 +0000
|
||||
*/
|
||||
.terminal .terminal-output .format, .cmd .format,
|
||||
.cmd .prompt, .cmd .prompt div, .terminal .terminal-output div div{
|
||||
display: inline-block;
|
||||
}
|
||||
.terminal h1, .terminal h2, .terminal h3, .terminal h4, .terminal h5, .terminal h6, .terminal pre, .cmd {
|
||||
margin: 0;
|
||||
}
|
||||
.terminal h1, .terminal h2, .terminal h3, .terminal h4, .terminal h5, .terminal h6 {
|
||||
line-height: 1.2em;
|
||||
}
|
||||
/*
|
||||
.cmd .mask {
|
||||
width: 10px;
|
||||
height: 11px;
|
||||
background: black;
|
||||
z-index: 100;
|
||||
}
|
||||
*/
|
||||
.cmd .clipboard {
|
||||
position: absolute;
|
||||
height: 16px;
|
||||
left: -6px;
|
||||
/* this seems to work after all on Android */
|
||||
/*left: -99999px;
|
||||
clip: rect(1px,1px,1px,1px);
|
||||
/* on desktop textarea appear when paste */
|
||||
/*
|
||||
opacity: 0.01;
|
||||
filter: alpha(opacity = 0.01);
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.01);
|
||||
*/
|
||||
width: 5px; /* textarea need to have width or it will not work on Android */
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: transparent;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
resize: none;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.terminal .error {
|
||||
color: #f00;
|
||||
}
|
||||
.terminal {
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
/*overflow: hidden;*/
|
||||
overflow: auto;
|
||||
}
|
||||
.cmd {
|
||||
padding: 0;
|
||||
height: 1.3em;
|
||||
position: relative;
|
||||
/*margin-top: 3px; */
|
||||
}
|
||||
.terminal .inverted, .cmd .inverted, .cmd .cursor.blink {
|
||||
background-color: #aaa;
|
||||
color: #000;
|
||||
}
|
||||
.cmd .cursor.blink {
|
||||
-webkit-animation: terminal-blink 1s infinite steps(1, start);
|
||||
-moz-animation: terminal-blink 1s infinite steps(1, start);
|
||||
-ms-animation: terminal-blink 1s infinite steps(1, start);
|
||||
animation: terminal-blink 1s infinite steps(1, start);
|
||||
}
|
||||
@-webkit-keyframes terminal-blink {
|
||||
0%, 100% {
|
||||
background-color: #000;
|
||||
color: #aaa;
|
||||
}
|
||||
50% {
|
||||
background-color: #bbb;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
@-ms-keyframes terminal-blink {
|
||||
0%, 100% {
|
||||
background-color: #000;
|
||||
color: #aaa;
|
||||
}
|
||||
50% {
|
||||
background-color: #bbb;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes terminal-blink {
|
||||
0%, 100% {
|
||||
background-color: #000;
|
||||
color: #aaa;
|
||||
}
|
||||
50% {
|
||||
background-color: #bbb;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
@keyframes terminal-blink {
|
||||
0%, 100% {
|
||||
background-color: #000;
|
||||
color: #aaa;
|
||||
}
|
||||
50% {
|
||||
background-color: #bbb; /* not #aaa because it's seems there is Google Chrome bug */
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.terminal .terminal-output div div, .cmd .prompt {
|
||||
display: block;
|
||||
line-height: 14px;
|
||||
height: auto;
|
||||
}
|
||||
.cmd .prompt {
|
||||
float: left;
|
||||
}
|
||||
.terminal, .cmd {
|
||||
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;
|
||||
color: #aaa;
|
||||
background-color: #000;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
padding-bottom:3px;
|
||||
}
|
||||
.terminal-output > div {
|
||||
/*padding-top: 3px;*/
|
||||
min-height: 14px;
|
||||
}
|
||||
.terminal .terminal-output div span {
|
||||
display: inline-block;
|
||||
}
|
||||
.cmd span {
|
||||
float: left;
|
||||
/*display: inline-block; */
|
||||
}
|
||||
/* fix double style of selecting text in terminal */
|
||||
.terminal-output span, .terminal-output a, .cmd div, .cmd span, .terminal td,
|
||||
.terminal pre, .terminal h1, .terminal h2, .terminal h3, .terminal h4,
|
||||
.terminal h5, .terminal h6 {
|
||||
-webkit-touch-callout: initial;
|
||||
-webkit-user-select: initial;
|
||||
-khtml-user-select: initial;
|
||||
-moz-user-select: initial;
|
||||
-ms-user-select: initial;
|
||||
user-select: initial;
|
||||
}
|
||||
.terminal, .terminal-output, .terminal-output div {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
/* firefox hack */
|
||||
@-moz-document url-prefix() {
|
||||
.terminal, .terminal-output, .terminal-output div {
|
||||
-webkit-touch-callout: initial;
|
||||
-webkit-user-select: initial;
|
||||
-khtml-user-select: initial;
|
||||
-moz-user-select: initial;
|
||||
-ms-user-select: initial;
|
||||
user-select: initial;
|
||||
}
|
||||
}
|
||||
.terminal table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.terminal td {
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
.terminal h1::-moz-selection,
|
||||
.terminal h2::-moz-selection,
|
||||
.terminal h3::-moz-selection,
|
||||
.terminal h4::-moz-selection,
|
||||
.terminal h5::-moz-selection,
|
||||
.terminal h6::-moz-selection,
|
||||
.terminal pre::-moz-selection,
|
||||
.terminal td::-moz-selection,
|
||||
.terminal .terminal-output div div::-moz-selection,
|
||||
.terminal .terminal-output div span::-moz-selection,
|
||||
.terminal .terminal-output div div a::-moz-selection,
|
||||
.cmd div::-moz-selection,
|
||||
.cmd > span::-moz-selection,
|
||||
.cmd .prompt span::-moz-selection {
|
||||
background-color: #aaa;
|
||||
color: #000;
|
||||
}
|
||||
/* this don't work in Chrome
|
||||
.terminal tr td::-moz-selection {
|
||||
border-color: #000;
|
||||
}
|
||||
.terminal tr td::selection {
|
||||
border-color: #000;
|
||||
}
|
||||
*/
|
||||
.terminal h1::selection,
|
||||
.terminal h2::selection,
|
||||
.terminal h3::selection,
|
||||
.terminal h4::selection,
|
||||
.terminal h5::selection,
|
||||
.terminal h6::selection,
|
||||
.terminal pre::selection,
|
||||
.terminal td::selection,
|
||||
.terminal .terminal-output div div::selection,
|
||||
.terminal .terminal-output div div a::selection,
|
||||
.terminal .terminal-output div span::selection,
|
||||
.cmd div::selection,
|
||||
.cmd > span::selection,
|
||||
.cmd .prompt span::selection {
|
||||
background-color: #aaa;
|
||||
color: #000;
|
||||
}
|
||||
.terminal .terminal-output div.error, .terminal .terminal-output div.error div {
|
||||
color: red;
|
||||
}
|
||||
.tilda {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 1100;
|
||||
}
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
.terminal a {
|
||||
color: #0F60FF;
|
||||
}
|
||||
.terminal a:hover {
|
||||
color: red;
|
||||
}
|
1
static/term/pkg/jquery.terminal/css/jquery.terminal.min.css
vendored
Normal file
1
static/term/pkg/jquery.terminal/css/jquery.terminal.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.terminal .terminal-output .format,.cmd .format,.cmd .prompt,.cmd .prompt div,.terminal .terminal-output div div{display:inline-block}.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6,.terminal pre,.cmd{margin:0}.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6{line-height:1.2em}.cmd .clipboard{position:absolute;height:16px;left:-6px;width:5px;background:transparent;border:0;color:transparent;outline:0;padding:0;resize:none;z-index:0;overflow:hidden}.terminal .error{color:red}.terminal{padding:10px;position:relative;overflow:auto}.cmd{padding:0;height:1.3em;position:relative}.terminal .inverted,.cmd .inverted,.cmd .cursor.blink{background-color:#aaa;color:#000}.cmd .cursor.blink{-webkit-animation:terminal-blink 1s infinite steps(1,start);-moz-animation:terminal-blink 1s infinite steps(1,start);-ms-animation:terminal-blink 1s infinite steps(1,start);animation:terminal-blink 1s infinite steps(1,start)}@-webkit-keyframes terminal-blink{0,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@-ms-keyframes terminal-blink{0,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@-moz-keyframes terminal-blink{0,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@keyframes terminal-blink{0,100%{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}.terminal .terminal-output div div,.cmd .prompt{display:block;line-height:14px;height:auto}.cmd .prompt{float:left}.terminal,.cmd{font-family:monospace;color:#aaa;background-color:#000;font-size:12px;line-height:14px}.terminal-output>div{min-height:14px}.terminal .terminal-output div span{display:inline-block}.cmd span{float:left}.terminal-output span,.terminal-output a,.cmd div,.cmd span,.terminal td,.terminal pre,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6{-webkit-touch-callout:initial;-webkit-user-select:initial;-khtml-user-select:initial;-moz-user-select:initial;-ms-user-select:initial;user-select:initial}.terminal,.terminal-output,.terminal-output div{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}@-moz-document url-prefix(){.terminal,.terminal-output,.terminal-output div{-webkit-touch-callout:initial;-webkit-user-select:initial;-khtml-user-select:initial;-moz-user-select:initial;-ms-user-select:initial;user-select:initial}}.terminal table{border-collapse:collapse}.terminal td{border:1px solid #aaa}.terminal h1::-moz-selection,.terminal h2::-moz-selection,.terminal h3::-moz-selection,.terminal h4::-moz-selection,.terminal h5::-moz-selection,.terminal h6::-moz-selection,.terminal pre::-moz-selection,.terminal td::-moz-selection,.terminal .terminal-output div div::-moz-selection,.terminal .terminal-output div span::-moz-selection,.terminal .terminal-output div div a::-moz-selection,.cmd div::-moz-selection,.cmd>span::-moz-selection,.cmd .prompt span::-moz-selection{background-color:#aaa;color:#000}.terminal h1::selection,.terminal h2::selection,.terminal h3::selection,.terminal h4::selection,.terminal h5::selection,.terminal h6::selection,.terminal pre::selection,.terminal td::selection,.terminal .terminal-output div div::selection,.terminal .terminal-output div div a::selection,.terminal .terminal-output div span::selection,.cmd div::selection,.cmd>span::selection,.cmd .prompt span::selection{background-color:#aaa;color:#000}.terminal .terminal-output div.error,.terminal .terminal-output div.error div{color:red}.tilda{position:fixed;top:0;left:0;width:100%;z-index:1100}.clear{clear:both}.terminal a{color:#0f60ff}.terminal a:hover{color:red}
|
113
static/term/pkg/jquery.terminal/js/ascii_table.js
Normal file
113
static/term/pkg/jquery.terminal/js/ascii_table.js
Normal file
@ -0,0 +1,113 @@
|
||||
/**@license
|
||||
* __ _____ ________ __
|
||||
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
|
||||
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
|
||||
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
|
||||
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
|
||||
* \/ /____/
|
||||
* http://terminal.jcubic.pl
|
||||
*
|
||||
* utility that renders simple ascii table, like the one from mysql cli tool
|
||||
* it was first created for leash shell https://leash.jcubic.pl
|
||||
*
|
||||
* usage:
|
||||
*
|
||||
* var arr = [[1,2,3,4,5], ["lorem", "ipsum", "dolor", "sit", "amet"]];
|
||||
* term.echo(ascii_table(arr));
|
||||
* // or
|
||||
* term.echo(ascii_table(arr, true)); // this will render first row as header
|
||||
*
|
||||
* Copyright (c) 2018-2019 Jakub Jankiewicz <https://jcubic.pl/me>
|
||||
* Released under the MIT license
|
||||
*
|
||||
*/
|
||||
/* global define, module, global, wcwidth, require */
|
||||
(function(factory) {
|
||||
var root = typeof window !== 'undefined' ? window : global;
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['wcwidth'], function(wcwidth) {
|
||||
return (root.ascii_table = factory(wcwidth));
|
||||
});
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// Node/CommonJS
|
||||
module.exports = factory(require('wcwidth'));
|
||||
} else {
|
||||
root.ascii_table = factory(root.wcwidth);
|
||||
}
|
||||
})(function(wcwidth, undefined) {
|
||||
var strlen = (function() {
|
||||
if (typeof wcwidth === 'undefined') {
|
||||
return function(string) {
|
||||
return string.length;
|
||||
};
|
||||
} else {
|
||||
return wcwidth;
|
||||
}
|
||||
})();
|
||||
function ascii_table(array, header) {
|
||||
if (!array.length) {
|
||||
return '';
|
||||
}
|
||||
for (var i = array.length - 1; i >= 0; i--) {
|
||||
var row = array[i];
|
||||
var stacks = [];
|
||||
for (var j = 0; j < row.length; j++) {
|
||||
var new_lines = row[j].toString().replace(/\r/g).split("\n");
|
||||
row[j] = new_lines.shift();
|
||||
stacks.push(new_lines);
|
||||
}
|
||||
var stack_lengths = stacks.map(function(column) {
|
||||
return column.length;
|
||||
});
|
||||
var new_rows_count = Math.max.apply(Math, stack_lengths);
|
||||
for (var k = new_rows_count - 1; k >= 0; k--) {
|
||||
array.splice(i + 1, 0, stacks.map(function(column) {
|
||||
return column[k] || "";
|
||||
}));
|
||||
}
|
||||
}
|
||||
var lengths = array[0].map(function(_, i) {
|
||||
var col = array.map(function(row) {
|
||||
if (row[i] != undefined) {
|
||||
var len = strlen(row[i]);
|
||||
if (row[i].match(/\t/g)) {
|
||||
// tab is 4 spaces
|
||||
len += row[i].match(/\t/g).length*3;
|
||||
}
|
||||
return len;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
return Math.max.apply(Math, col);
|
||||
});
|
||||
// column padding
|
||||
array = array.map(function(row) {
|
||||
return '| ' + row.map(function(item, i) {
|
||||
var size = strlen(item);
|
||||
if (item.match(/\t/g)) {
|
||||
// tab is 4 spaces
|
||||
size += item.match(/\t/g).length*3;
|
||||
}
|
||||
if (size < lengths[i]) {
|
||||
item += new Array(lengths[i] - size + 1).join(' ');
|
||||
}
|
||||
return item;
|
||||
}).join(' | ') + ' |';
|
||||
});
|
||||
array = array.map(function(line) {
|
||||
return line.replace(/&(?![^;]+;)/g, '&');
|
||||
});
|
||||
var sep = '+' + lengths.map(function(length) {
|
||||
return new Array(length + 3).join('-');
|
||||
}).join('+') + '+';
|
||||
if (header) {
|
||||
return sep + '\n' + array[0] + '\n' + sep + '\n' +
|
||||
array.slice(1).join('\n') + '\n' + sep;
|
||||
} else {
|
||||
return sep + '\n' + array.join('\n') + '\n' + sep;
|
||||
}
|
||||
}
|
||||
return ascii_table;
|
||||
});
|
69
static/term/pkg/jquery.terminal/js/dterm.js
Normal file
69
static/term/pkg/jquery.terminal/js/dterm.js
Normal file
@ -0,0 +1,69 @@
|
||||
/*!
|
||||
* Example plugin using JQuery Terminal Emulator
|
||||
* Copyright (C) 2010-2016 Jakub Jankiewicz <http://jcubic.pl>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
(function($) {
|
||||
$.extend_if_has = function(desc, source, array) {
|
||||
for (var i=array.length;i--;) {
|
||||
if (typeof source[array[i]] != 'undefined') {
|
||||
desc[array[i]] = source[array[i]];
|
||||
}
|
||||
}
|
||||
return desc;
|
||||
};
|
||||
$.fn.dterm = function(interpreter, options) {
|
||||
var op = $.extend_if_has({}, options,
|
||||
['greetings', 'prompt', 'onInit',
|
||||
'onExit', 'clear',
|
||||
'login', 'name', 'exit']);
|
||||
op.enabled = false;
|
||||
var terminal = this.terminal(interpreter, op).css('overflow', 'hidden');
|
||||
if (!options.title) {
|
||||
options.title = 'JQuery Terminal Emulator';
|
||||
}
|
||||
if (options.logoutOnClose) {
|
||||
options.close = function(e, ui) {
|
||||
terminal.logout();
|
||||
terminal.clear();
|
||||
};
|
||||
} else {
|
||||
options.close = function(e, ui) {
|
||||
terminal.disable();
|
||||
};
|
||||
}
|
||||
var self = this;
|
||||
this.dialog($.extend(options, {
|
||||
resizeStop: function(e, ui) {
|
||||
var content = self.find('.ui-dialog-content');
|
||||
terminal.resize(content.width(), content.height());
|
||||
},
|
||||
open: function(e, ui) {
|
||||
terminal.focus();
|
||||
terminal.resize();
|
||||
},
|
||||
show: 'fade',
|
||||
closeOnEscape: false
|
||||
}));
|
||||
self.terminal = terminal;
|
||||
return self;
|
||||
};
|
||||
})(jQuery);
|
2
static/term/pkg/jquery.terminal/js/jquery.mousewheel-min.js
vendored
Normal file
2
static/term/pkg/jquery.terminal/js/jquery.mousewheel-min.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
(function(c){function g(a){var b=a||window.event,i=[].slice.call(arguments,1),e=0,h=0,f=0;a=c.event.fix(b);a.type="mousewheel";if(b.wheelDelta)e=b.wheelDelta/120;if(b.detail)e=-b.detail/3;f=e;if(b.axis!==undefined&&b.axis===b.HORIZONTAL_AXIS){f=0;h=-1*e}if(b.wheelDeltaY!==undefined)f=b.wheelDeltaY/120;if(b.wheelDeltaX!==undefined)h=-1*b.wheelDeltaX/120;i.unshift(a,e,h,f);return(c.event.dispatch||c.event.handle).apply(this,i)}var d=["DOMMouseScroll","mousewheel"];if(c.event.fixHooks)for(var j=d.length;j;)c.event.fixHooks[d[--j]]=
|
||||
c.event.mouseHooks;c.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=d.length;a;)this.addEventListener(d[--a],g,false);else this.onmousewheel=g},teardown:function(){if(this.removeEventListener)for(var a=d.length;a;)this.removeEventListener(d[--a],g,false);else this.onmousewheel=null}};c.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
|
37
static/term/pkg/jquery.terminal/js/jquery.terminal.min.js
vendored
Normal file
37
static/term/pkg/jquery.terminal/js/jquery.terminal.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
317
static/term/pkg/jquery.terminal/js/unix_formatting.js
Normal file
317
static/term/pkg/jquery.terminal/js/unix_formatting.js
Normal file
@ -0,0 +1,317 @@
|
||||
/**@license
|
||||
* __ _____ ________ __
|
||||
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
|
||||
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
|
||||
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
|
||||
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
|
||||
* \/ /____/
|
||||
* http://terminal.jcubic.pl
|
||||
*
|
||||
* This is example of how to create custom formatter for jQuery Terminal
|
||||
*
|
||||
* Copyright (c) 2014-2016 Jakub Jankiewicz <http://jcubic.pl>
|
||||
* Released under the MIT license
|
||||
*
|
||||
*/
|
||||
(function($) {
|
||||
if (!$.terminal) {
|
||||
throw new Error('$.terminal is not defined');
|
||||
}
|
||||
// ---------------------------------------------------------------------
|
||||
// :: Replace overtyping (from man) formatting with terminal formatting
|
||||
// ---------------------------------------------------------------------
|
||||
$.terminal.overtyping = function(string) {
|
||||
return string.replace(/((?:_\x08.|.\x08_)+)/g, function(full, g) {
|
||||
var striped = full.replace(/_x08|\x08_|_\u0008|\u0008_/g, '');
|
||||
return '[[u;;]' + striped + ']';
|
||||
}).replace(/((?:.\x08.)+)/g, function(full, g) {
|
||||
return '[[b;#fff;]' + full.replace(/(.)(?:\x08|\u0008)(.)/g,
|
||||
function(full, g1, g2) {
|
||||
return g2;
|
||||
}) + ']';
|
||||
});
|
||||
};
|
||||
// ---------------------------------------------------------------------
|
||||
// :: Html colors taken from ANSI formatting in Linux Terminal
|
||||
// ---------------------------------------------------------------------
|
||||
$.terminal.ansi_colors = {
|
||||
normal: {
|
||||
black: '#000',
|
||||
red: '#A00',
|
||||
green: '#008400',
|
||||
yellow: '#A50',
|
||||
blue: '#00A',
|
||||
magenta: '#A0A',
|
||||
cyan: '#0AA',
|
||||
white: '#AAA'
|
||||
},
|
||||
faited: {
|
||||
black: '#000',
|
||||
red: '#640000',
|
||||
green: '#006100',
|
||||
yellow: '#737300',
|
||||
blue: '#000087',
|
||||
magenta: '#650065',
|
||||
cyan: '#008787',
|
||||
white: '#818181'
|
||||
},
|
||||
bold: {
|
||||
black: '#000',
|
||||
red: '#F55',
|
||||
green: '#44D544',
|
||||
yellow: '#FF5',
|
||||
blue: '#55F',
|
||||
magenta: '#F5F',
|
||||
cyan: '#5FF',
|
||||
white: '#FFF'
|
||||
},
|
||||
// XTerm 8-bit pallete
|
||||
palette: [
|
||||
'#000000', '#AA0000', '#00AA00', '#AA5500', '#0000AA', '#AA00AA',
|
||||
'#00AAAA', '#AAAAAA', '#555555', '#FF5555', '#55FF55', '#FFFF55',
|
||||
'#5555FF', '#FF55FF', '#55FFFF', '#FFFFFF', '#000000', '#00005F',
|
||||
'#000087', '#0000AF', '#0000D7', '#0000FF', '#005F00', '#005F5F',
|
||||
'#005F87', '#005FAF', '#005FD7', '#005FFF', '#008700', '#00875F',
|
||||
'#008787', '#0087AF', '#0087D7', '#0087FF', '#00AF00', '#00AF5F',
|
||||
'#00AF87', '#00AFAF', '#00AFD7', '#00AFFF', '#00D700', '#00D75F',
|
||||
'#00D787', '#00D7AF', '#00D7D7', '#00D7FF', '#00FF00', '#00FF5F',
|
||||
'#00FF87', '#00FFAF', '#00FFD7', '#00FFFF', '#5F0000', '#5F005F',
|
||||
'#5F0087', '#5F00AF', '#5F00D7', '#5F00FF', '#5F5F00', '#5F5F5F',
|
||||
'#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF', '#5F8700', '#5F875F',
|
||||
'#5F8787', '#5F87AF', '#5F87D7', '#5F87FF', '#5FAF00', '#5FAF5F',
|
||||
'#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF', '#5FD700', '#5FD75F',
|
||||
'#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF', '#5FFF00', '#5FFF5F',
|
||||
'#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF', '#870000', '#87005F',
|
||||
'#870087', '#8700AF', '#8700D7', '#8700FF', '#875F00', '#875F5F',
|
||||
'#875F87', '#875FAF', '#875FD7', '#875FFF', '#878700', '#87875F',
|
||||
'#878787', '#8787AF', '#8787D7', '#8787FF', '#87AF00', '#87AF5F',
|
||||
'#87AF87', '#87AFAF', '#87AFD7', '#87AFFF', '#87D700', '#87D75F',
|
||||
'#87D787', '#87D7AF', '#87D7D7', '#87D7FF', '#87FF00', '#87FF5F',
|
||||
'#87FF87', '#87FFAF', '#87FFD7', '#87FFFF', '#AF0000', '#AF005F',
|
||||
'#AF0087', '#AF00AF', '#AF00D7', '#AF00FF', '#AF5F00', '#AF5F5F',
|
||||
'#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF', '#AF8700', '#AF875F',
|
||||
'#AF8787', '#AF87AF', '#AF87D7', '#AF87FF', '#AFAF00', '#AFAF5F',
|
||||
'#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF', '#AFD700', '#AFD75F',
|
||||
'#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF', '#AFFF00', '#AFFF5F',
|
||||
'#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF', '#D70000', '#D7005F',
|
||||
'#D70087', '#D700AF', '#D700D7', '#D700FF', '#D75F00', '#D75F5F',
|
||||
'#D75F87', '#D75FAF', '#D75FD7', '#D75FFF', '#D78700', '#D7875F',
|
||||
'#D78787', '#D787AF', '#D787D7', '#D787FF', '#D7AF00', '#D7AF5F',
|
||||
'#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF', '#D7D700', '#D7D75F',
|
||||
'#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF', '#D7FF00', '#D7FF5F',
|
||||
'#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF', '#FF0000', '#FF005F',
|
||||
'#FF0087', '#FF00AF', '#FF00D7', '#FF00FF', '#FF5F00', '#FF5F5F',
|
||||
'#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF', '#FF8700', '#FF875F',
|
||||
'#FF8787', '#FF87AF', '#FF87D7', '#FF87FF', '#FFAF00', '#FFAF5F',
|
||||
'#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF', '#FFD700', '#FFD75F',
|
||||
'#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF', '#FFFF00', '#FFFF5F',
|
||||
'#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF', '#080808', '#121212',
|
||||
'#1C1C1C', '#262626', '#303030', '#3A3A3A', '#444444', '#4E4E4E',
|
||||
'#585858', '#626262', '#6C6C6C', '#767676', '#808080', '#8A8A8A',
|
||||
'#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', '#BCBCBC', '#C6C6C6',
|
||||
'#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
|
||||
]
|
||||
};
|
||||
// ---------------------------------------------------------------------
|
||||
// :: Replace ANSI formatting with terminal formatting
|
||||
// ---------------------------------------------------------------------
|
||||
$.terminal.from_ansi = (function() {
|
||||
var color_list = {
|
||||
30: 'black',
|
||||
31: 'red',
|
||||
32: 'green',
|
||||
33: 'yellow',
|
||||
34: 'blue',
|
||||
35: 'magenta',
|
||||
36: 'cyan',
|
||||
37: 'white',
|
||||
|
||||
39: 'inherit' // default color
|
||||
};
|
||||
var background_list = {
|
||||
40: 'black',
|
||||
41: 'red',
|
||||
42: 'green',
|
||||
43: 'yellow',
|
||||
44: 'blue',
|
||||
45: 'magenta',
|
||||
46: 'cyan',
|
||||
47: 'white',
|
||||
|
||||
49: 'transparent' // default background
|
||||
};
|
||||
function format_ansi(code) {
|
||||
var controls = code.split(';');
|
||||
var num;
|
||||
var faited = false;
|
||||
var reverse = false;
|
||||
var bold = false;
|
||||
var styles = [];
|
||||
var output_color = '';
|
||||
var output_background = '';
|
||||
var _8bit_color = false;
|
||||
var _8bit_background = false;
|
||||
var process_8bit = false;
|
||||
var palette = $.terminal.ansi_colors.palette;
|
||||
for(var i in controls) {
|
||||
if (controls.hasOwnProperty(i)) {
|
||||
num = parseInt(controls[i], 10);
|
||||
if (process_8bit && (_8bit_background || _8bit_color)) {
|
||||
if (_8bit_color && palette[num]) {
|
||||
output_color = palette[num];
|
||||
}
|
||||
if (_8bit_background && palette[num]) {
|
||||
output_background = palette[num];
|
||||
}
|
||||
} else {
|
||||
switch(num) {
|
||||
case 1:
|
||||
styles.push('b');
|
||||
bold = true;
|
||||
faited = false;
|
||||
break;
|
||||
case 4:
|
||||
styles.push('u');
|
||||
break;
|
||||
case 3:
|
||||
styles.push('i');
|
||||
break;
|
||||
case 5:
|
||||
process_8bit = true;
|
||||
break;
|
||||
case 38:
|
||||
_8bit_color = true;
|
||||
break;
|
||||
case 48:
|
||||
_8bit_background = true;
|
||||
break;
|
||||
case 2:
|
||||
faited = true;
|
||||
bold = false;
|
||||
break;
|
||||
case 7:
|
||||
reverse = true;
|
||||
break;
|
||||
default:
|
||||
if (controls.indexOf('5') == -1) {
|
||||
if (color_list[num]) {
|
||||
output_color = color_list[num];
|
||||
}
|
||||
if (background_list[num]) {
|
||||
output_background = background_list[num];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (reverse) {
|
||||
if (output_color || output_background) {
|
||||
var tmp = output_background;
|
||||
output_background = output_color;
|
||||
output_color = tmp;
|
||||
} else {
|
||||
output_color = 'black';
|
||||
output_background = 'white';
|
||||
}
|
||||
}
|
||||
var colors, color, background, backgrounds;
|
||||
if (bold) {
|
||||
colors = backgrounds = $.terminal.ansi_colors.bold;
|
||||
} else if (faited) {
|
||||
colors = backgrounds = $.terminal.ansi_colors.faited;
|
||||
} else {
|
||||
colors = backgrounds = $.terminal.ansi_colors.normal;
|
||||
}
|
||||
if (_8bit_color) {
|
||||
color = output_color;
|
||||
} else if (output_color == 'inherit') {
|
||||
color = output_color;
|
||||
} else {
|
||||
color = colors[output_color];
|
||||
}
|
||||
if (_8bit_background) {
|
||||
background = output_background;
|
||||
} else if (output_background == 'transparent') {
|
||||
background = output_background;
|
||||
} else {
|
||||
background = backgrounds[output_background];
|
||||
}
|
||||
return [styles.join(''), color, background];
|
||||
}
|
||||
return function(input) {
|
||||
//merge multiple codes
|
||||
/*input = input.replace(/((?:\x1B\[[0-9;]*[A-Za-z])*)/g, function(group) {
|
||||
return group.replace(/m\x1B\[/g, ';');
|
||||
});*/
|
||||
var splitted = input.split(/(\x1B\[[0-9;]*[A-Za-z])/g);
|
||||
if (splitted.length == 1) {
|
||||
return input;
|
||||
}
|
||||
var output = [];
|
||||
//skip closing at the begining
|
||||
if (splitted.length > 3) {
|
||||
var str = splitted.slice(0,3).join('');
|
||||
if (str == '[0m' || str == '[m') {
|
||||
splitted = splitted.slice(3);
|
||||
}
|
||||
}
|
||||
var next, prev_color, prev_background, code, match;
|
||||
var inside = false;
|
||||
for (var i=0; i<splitted.length; ++i) {
|
||||
match = splitted[i].match(/^\x1B\[([0-9;]*)([A-Za-z])$/);
|
||||
if (match) {
|
||||
switch (match[2]) {
|
||||
case 'm':
|
||||
if (match[1] !== '0') {
|
||||
code = format_ansi(match[1]);
|
||||
}
|
||||
if (inside) {
|
||||
output.push(']');
|
||||
if (match[1] === '0' || match[1] === '') {
|
||||
//just closing
|
||||
inside = false;
|
||||
prev_color = prev_background = '';
|
||||
} else {
|
||||
// someone forget to close - move to next
|
||||
code[1] = code[1] || prev_color;
|
||||
code[2] = code[2] || prev_background;
|
||||
output.push('[[' + code.join(';') + ']');
|
||||
// store colors to next use
|
||||
if (code[1]) {
|
||||
prev_color = code[1];
|
||||
}
|
||||
if (code[2]) {
|
||||
prev_background = code[2];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (match[1] != '0') {
|
||||
inside = true;
|
||||
code[1] = code[1] || prev_color;
|
||||
code[2] = code[2] || prev_background;
|
||||
output.push('[[' + code.join(';') + ']');
|
||||
// store colors to next use
|
||||
if (code[1]) {
|
||||
prev_color = code[1];
|
||||
}
|
||||
if (code[2]) {
|
||||
prev_background = code[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
output.push(splitted[i]);
|
||||
}
|
||||
}
|
||||
if (inside) {
|
||||
output.push(']');
|
||||
}
|
||||
return output.join(''); //.replace(/\[\[[^\]]+\]\]/g, '');
|
||||
};
|
||||
})();
|
||||
$.terminal.defaults.formatters.push($.terminal.overtyping);
|
||||
$.terminal.defaults.formatters.push($.terminal.from_ansi);
|
||||
})(jQuery);
|
48
static/term/pkg/jquery.terminal/js/xml_formatting.js
Normal file
48
static/term/pkg/jquery.terminal/js/xml_formatting.js
Normal file
@ -0,0 +1,48 @@
|
||||
/**@license
|
||||
* __ _____ ________ __
|
||||
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
|
||||
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
|
||||
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
|
||||
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
|
||||
* \/ /____/
|
||||
* http://terminal.jcubic.pl
|
||||
*
|
||||
* This is example of how to create custom formatter for jQuery Terminal
|
||||
*
|
||||
* Copyright (c) 2014-2016 Jakub Jankiewicz <http://jcubic.pl>
|
||||
* Released under the MIT license
|
||||
*
|
||||
*/
|
||||
(function($) {
|
||||
if (!$.terminal) {
|
||||
throw new Error('$.terminal is not defined');
|
||||
}
|
||||
// this formatter allow to echo xml where tags are colors like:
|
||||
// <red>hello <navy>blue</navy> world</red>
|
||||
$.terminal.defaults.formatters.push(function(string) {
|
||||
var stack = [];
|
||||
var output = [];
|
||||
var parts = string.split(/(<\/?[a-zA-Z]+>)/);
|
||||
for (var i=0; i<parts.length; ++i) {
|
||||
if (parts[i][0] == '<') {
|
||||
if (parts[i][1] == '/') {
|
||||
if (stack.length) {
|
||||
stack.pop();
|
||||
}
|
||||
} else {
|
||||
stack.push(parts[i].replace(/^<|>$/g, ''));
|
||||
}
|
||||
} else {
|
||||
if (stack.length) {
|
||||
// top of the stack
|
||||
output.push('[[;' + stack[stack.length-1] + ';]');
|
||||
}
|
||||
output.push(parts[i]);
|
||||
if (stack.length) {
|
||||
output.push(']');
|
||||
}
|
||||
}
|
||||
}
|
||||
return output.join('');
|
||||
});
|
||||
})(jQuery);
|
688
static/term/pkg/jquery.terminal/spec/terminalSpec.js
Normal file
688
static/term/pkg/jquery.terminal/spec/terminalSpec.js
Normal file
@ -0,0 +1,688 @@
|
||||
if (typeof window === 'undefined') {
|
||||
var node = true;
|
||||
var jsdom = require("jsdom");
|
||||
global.document = jsdom.jsdom();
|
||||
global.window = global.document.parentWindow;
|
||||
var navigator = {userAgent: "node-js", platform: "Linux i686"};
|
||||
global.window.navigator = global.navigator = navigator;
|
||||
global.jQuery = global.$ = require("jquery");
|
||||
require('../js/jquery.terminal-src');
|
||||
require('../js/unix_formatting');
|
||||
}
|
||||
describe('Terminal utils', function() {
|
||||
var command = 'test "foo bar" baz /^asd [x]/ str\\ str 10 1e10';
|
||||
var args = '"foo bar" baz /^asd [x]/ str\\ str 10 1e10';
|
||||
describe('$.terminal.split_arguments', function() {
|
||||
it('should create array of arguments', function() {
|
||||
expect($.terminal.split_arguments(args)).toEqual([
|
||||
'foo bar',
|
||||
'baz',
|
||||
'/^asd [x]/',
|
||||
'str str',
|
||||
'10',
|
||||
'1e10'
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe('$.terminal.parse_arguments', function() {
|
||||
it('should create array of arguments and convert types', function() {
|
||||
expect($.terminal.parse_arguments(args)).toEqual([
|
||||
'foo bar',
|
||||
'baz',
|
||||
/^asd [x]/,
|
||||
'str str',
|
||||
10,
|
||||
1e10
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe('$.terminal.split_command', function() {
|
||||
it('Should split command', function() {
|
||||
var cmd = jQuery.terminal.split_command(command);
|
||||
expect(cmd).toEqual({
|
||||
command: command,
|
||||
name: 'test',
|
||||
args: [
|
||||
'foo bar',
|
||||
'baz',
|
||||
'/^asd [x]/',
|
||||
'str str',
|
||||
'10',
|
||||
'1e10'
|
||||
],
|
||||
rest: '"foo bar" baz /^asd [x]/ str\\ str 10 1e10'
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('$.terminal.parse_command', function() {
|
||||
it('should split and parse command', function() {
|
||||
var cmd = jQuery.terminal.parse_command(command);
|
||||
expect(cmd).toEqual({
|
||||
command: command,
|
||||
name: 'test',
|
||||
args: [
|
||||
'foo bar',
|
||||
'baz',
|
||||
/^asd [x]/,
|
||||
'str str',
|
||||
10,
|
||||
1e10
|
||||
],
|
||||
rest: '"foo bar" baz /^asd [x]/ str\\ str 10 1e10'
|
||||
});
|
||||
});
|
||||
});
|
||||
var ansi_string = '\x1b[2;31;46mFoo\x1b[1;3;4;32;45mBar\x1b[0m\x1b[7mBaz';
|
||||
describe('$.terminal.from_ansi', function() {
|
||||
it('should convert ansi to terminal formatting', function() {
|
||||
var string = $.terminal.from_ansi(ansi_string);
|
||||
expect(string).toEqual('[[;#640000;#008787]Foo][[biu;#44D544;#F5F]'+
|
||||
'Bar][[;#000;#AAA]Baz]');
|
||||
});
|
||||
});
|
||||
describe('$.terminal.overtyping', function() {
|
||||
var string = 'HELLO TERMINAL'.replace(/./g, function(chr) {
|
||||
return chr == ' ' ? chr : chr + '\x08' + chr;
|
||||
});
|
||||
var result = '[[b;#fff;]HELLO] [[b;#fff;]TERMINAL]';
|
||||
it('should convert to terminal formatting', function() {
|
||||
expect($.terminal.overtyping(string)).toEqual(result);
|
||||
});
|
||||
});
|
||||
describe('$.terminal.escape_brackets', function() {
|
||||
var string = '[[jQuery]] [[Terminal]]';
|
||||
var result = '[[jQuery]] [[Terminal]]';
|
||||
it('should replace [ and ] with html entities', function() {
|
||||
expect($.terminal.escape_brackets(string)).toEqual(result);
|
||||
});
|
||||
});
|
||||
describe('$.terminal.encode', function() {
|
||||
var tags = '<hello> </hello>\t<world> </world>';
|
||||
var tags_result = '<hello> </hello> '+
|
||||
' <world> </world>';
|
||||
it('should convert < > space and tabs', function() {
|
||||
expect($.terminal.encode(tags)).toEqual(tags_result);
|
||||
});
|
||||
var entites = '& & & &64; = [';
|
||||
//'& & & &64; = ['
|
||||
var ent_result = '& & & &64; ='+
|
||||
' &#91';
|
||||
it('it should convert & but not when used with entities', function() {
|
||||
expect($.terminal.encode(entites)).toEqual(ent_result);
|
||||
});
|
||||
});
|
||||
describe('$.terminal.format_split', function() {
|
||||
});
|
||||
describe('$.terminal.is_formatting', function() {
|
||||
|
||||
it('should detect terminal formatting', function() {
|
||||
var formattings = [
|
||||
'[[;;]Te[xt]',
|
||||
'[[;;]Te\\]xt]',
|
||||
'[[;;]]',
|
||||
'[[gui;;;class]Text]',
|
||||
'[[b;#fff;]Text]',
|
||||
'[[b;red;blue]Text]'];
|
||||
var not_formattings = [
|
||||
'[[;;]Text[',
|
||||
'[[Text]]',
|
||||
'[[Text[[',
|
||||
'[[;]Text]',
|
||||
'Text]',
|
||||
'[[Text',
|
||||
'[;;]Text]'];
|
||||
formattings.forEach(function(formatting) {
|
||||
expect($.terminal.is_formatting(formatting)).toEqual(true);
|
||||
});
|
||||
not_formattings.forEach(function(formatting) {
|
||||
expect($.terminal.is_formatting(formatting)).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('$.terminal.escape_regex', function() {
|
||||
it('should escape regex special characters', function() {
|
||||
var safe = "\\\\\\^\\*\\+\\?\\.\\$\\[\\]\\{\\}\\(\\)";
|
||||
expect($.terminal.escape_regex('\\^*+?.$[]{}()')).toEqual(safe);
|
||||
});
|
||||
});
|
||||
describe('$.terminal.have_formatting', function() {
|
||||
var formattings = [
|
||||
'some text [[;;]Te[xt] and formatting',
|
||||
'some text [[;;]Te\\]xt] and formatting',
|
||||
'some text [[;;]] and formatting',
|
||||
'some text [[gui;;;class]Text] and formatting',
|
||||
'some text [[b;#fff;]Text] and formatting',
|
||||
'some text [[b;red;blue]Text] and formatting'];
|
||||
var not_formattings = [
|
||||
'some text [[;;]Text[ and formatting',
|
||||
'some text [[Text]] and formatting',
|
||||
'some text [[Text[[ and formatting',
|
||||
'some text [[;]Text] and formatting',
|
||||
'some text Text] and formatting',
|
||||
'some text [[Text and formatting',
|
||||
'some text [;;]Text] and formatting'];
|
||||
it('should detect terminal formatting', function() {
|
||||
formattings.forEach(function(formatting) {
|
||||
expect($.terminal.have_formatting(formatting)).toEqual(true);
|
||||
});
|
||||
not_formattings.forEach(function(formatting) {
|
||||
expect($.terminal.have_formatting(formatting)).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('$.terminal.valid_color', function() {
|
||||
it('should mark hex color as valid', function() {
|
||||
var valid_colors = ['#fff', '#fab', '#ffaacc', 'red', 'blue'];
|
||||
valid_colors.forEach(function(color) {
|
||||
expect($.terminal.valid_color(color)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('$.terminal.format', function() {
|
||||
var format = '[[biugs;#fff;#000]Foo][[i;;;foo]Bar][[ous;;]Baz]';
|
||||
it('should create html span tags with style and classes', function() {
|
||||
var string = $.terminal.format(format);
|
||||
expect(string).toEqual('<span style="font-weight:bold;text-decorat'+
|
||||
'ion:underline line-through;font-style:ital'+
|
||||
'ic;color:#fff;text-shadow:0 0 5px #fff;bac'+
|
||||
'kground-color:#000" data-text="Foo">Foo</s'+
|
||||
'pan><span style="font-style:italic;" class'+
|
||||
'="foo" data-text="Bar">Bar</span><span sty'+
|
||||
'le="text-decoration:underline line-through'+
|
||||
' overline;" data-text="Baz">Baz</span>');
|
||||
});
|
||||
});
|
||||
describe('$.terminal.strip', function() {
|
||||
var formatting = '-_-[[biugs;#fff;#000]Foo]-_-[[i;;;foo]Bar]-_-[[ous;;'+
|
||||
']Baz]-_-';
|
||||
var result = '-_-Foo-_-Bar-_-Baz-_-';
|
||||
it('should remove formatting', function() {
|
||||
expect($.terminal.strip(formatting)).toEqual(result);
|
||||
});
|
||||
});
|
||||
describe('$.terminal.split_equal', function() {
|
||||
var text = ['[[bui;#fff;]Lorem ipsum dolor sit amet, consectetur adipi',
|
||||
'scing elit. Nulla sed dolor nisl, in suscipit justo. Donec a enim',
|
||||
' et est porttitor semper at vitae augue. Proin at nulla at dui ma',
|
||||
'ttis mattis. Nam a volutpat ante. Aliquam consequat dui eu sem co',
|
||||
'nvallis ullamcorper. Nulla suscipit, massa vitae suscipit ornare,',
|
||||
' tellus] est [[b;;#f00]consequat nunc, quis blandit elit odio eu ',
|
||||
'arcu. Nam a urna nec nisl varius sodales. Mauris iaculis tincidun',
|
||||
't orci id commodo. Aliquam] non magna quis [[i;;]tortor malesuada',
|
||||
' aliquam] eget ut lacus. Nam ut vestibulum est. Praesent volutpat',
|
||||
' tellus in eros dapibus elementum. Nam laoreet risus non nulla mo',
|
||||
'llis ac luctus [[ub;#fff;]felis dapibus. Pellentesque mattis elem',
|
||||
'entum augue non sollicitudin. Nullam lobortis fermentum elit ac m',
|
||||
'ollis. Nam ac varius risus. Cras faucibus euismod nulla, ac aucto',
|
||||
'r diam rutrum sit amet. Nulla vel odio erat], ac mattis enim.'
|
||||
].join('');
|
||||
it('should split text that into equal length chunks', function() {
|
||||
var cols = [10, 40, 60, 400];
|
||||
for (var i=cols.length; i--;) {
|
||||
var lines = $.terminal.split_equal(text, cols[i]);
|
||||
var success = true;
|
||||
for (var j=0; j<lines.length; ++j) {
|
||||
if ($.terminal.strip(lines[j]).length > cols[i]) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect(success).toEqual(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
function support_animations() {
|
||||
var animation = false,
|
||||
animationstring = 'animation',
|
||||
keyframeprefix = '',
|
||||
domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
|
||||
pfx = '',
|
||||
elm = document.createElement('div');
|
||||
if (elm.style.animationName) { animation = true; }
|
||||
if (animation === false) {
|
||||
for (var i = 0; i < domPrefixes.length; i++) {
|
||||
var name = domPrefixes[i] + 'AnimationName';
|
||||
if (elm.style[ name ] !== undefined) {
|
||||
pfx = domPrefixes[i];
|
||||
animationstring = pfx + 'Animation';
|
||||
keyframeprefix = '-' + pfx.toLowerCase() + '-';
|
||||
animation = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return animation;
|
||||
}
|
||||
function enter_text(text) {
|
||||
var e;
|
||||
var $root = $(document.documentElement || window);
|
||||
for (var i=0; i<text.length; ++i) {
|
||||
e = $.Event("keypress");
|
||||
e.which = e.keyCode = text.charCodeAt(i);
|
||||
e.ctrlKey = false;
|
||||
e.altKey = false;
|
||||
$root.trigger(e);
|
||||
}
|
||||
}
|
||||
function shortcut(ctrl, alt, shift, which) {
|
||||
var e = $.Event("keydown");
|
||||
e.ctrlKey = ctrl;
|
||||
e.altKey = alt;
|
||||
e.shiftKey = shift;
|
||||
e.which = e.keyCode = which;
|
||||
$(document.documentElement || window).trigger(e);
|
||||
}
|
||||
function enter_key() {
|
||||
shortcut(false, false, false, 13);
|
||||
}
|
||||
|
||||
function tests_on_ready() {
|
||||
describe('Terminal plugin', function() {
|
||||
describe('terminal create / terminal destroy', function() {
|
||||
var term = $('<div></div>').appendTo('body').terminal();
|
||||
it('should create terminal', function() {
|
||||
expect(term.length).toBe(1);
|
||||
});
|
||||
it('should have proper elements', function() {
|
||||
expect(term.hasClass('terminal')).toBe(true);
|
||||
expect(term.find('.terminal-output').length).toBe(1);
|
||||
expect(term.find('.cmd').length).toBe(1);
|
||||
var prompt = term.find('.prompt');
|
||||
expect(prompt.length).toBe(1);
|
||||
expect(prompt.is('span')).toBe(true);
|
||||
expect(prompt.children().length).toBe(1);
|
||||
var cursor = term.find('.cursor');
|
||||
expect(cursor.length).toBe(1);
|
||||
expect(cursor.is('span')).toBe(true);
|
||||
expect(cursor.prev().is('span')).toBe(true);
|
||||
expect(cursor.next().is('span')).toBe(true);
|
||||
term.focus(true);
|
||||
if (support_animations()) {
|
||||
expect(cursor.hasClass('blink')).toBe(true);
|
||||
}
|
||||
expect(term.find('.clipboard').length).toBe(1);
|
||||
});
|
||||
it('should have signature', function() {
|
||||
var sig = term.find('.terminal-output div div').map(function() { return $(this).text(); }).get().join('\n');
|
||||
expect(term.signature().replace(/ /g, '\xA0')).toEqual(sig);
|
||||
});
|
||||
it('should have default prompt', function() {
|
||||
var prompt = term.find('.prompt');
|
||||
expect(prompt.html()).toEqual("<span>> </span>");
|
||||
expect(prompt.text()).toEqual('>\xA0');
|
||||
});
|
||||
it('should destroy terminal', function() {
|
||||
term.destroy();
|
||||
expect(term.children().length).toBe(0);
|
||||
term.remove();
|
||||
});
|
||||
});
|
||||
describe('exec', function() {
|
||||
var interpreter = {
|
||||
foo: function() {
|
||||
}
|
||||
};
|
||||
|
||||
var term = $('<div></div>').appendTo('body').terminal(interpreter);
|
||||
|
||||
it('should execute function', function() {
|
||||
var spy = spyOn(interpreter, 'foo');
|
||||
if (spy.andCallThrough) {
|
||||
spy.andCallThrough();
|
||||
} else {
|
||||
spy.and.callThrough();
|
||||
}
|
||||
term.exec('foo').then(function() {
|
||||
expect(interpreter.foo).toHaveBeenCalled();
|
||||
term.destroy().remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('enter text', function() {
|
||||
var interpreter = {
|
||||
foo: function() {
|
||||
}
|
||||
};
|
||||
var term = $('<div></div>').appendTo('body').terminal(interpreter);
|
||||
it('text should appear and interpreter function should be called', function() {
|
||||
term.focus(true);
|
||||
var spy = spyOn(interpreter, 'foo');
|
||||
if (spy.andCallThrough) {
|
||||
spy.andCallThrough();
|
||||
} else {
|
||||
spy.and.callThrough();
|
||||
}
|
||||
enter_text('foo');
|
||||
enter_key();
|
||||
expect(interpreter.foo).toHaveBeenCalled();
|
||||
var last_div = term.find('.terminal-output > div:last-child');
|
||||
expect(last_div.hasClass('command')).toBe(true);
|
||||
expect(last_div.children().html()).toEqual('<span>> foo</span>');
|
||||
term.destroy().remove();
|
||||
});
|
||||
});
|
||||
describe('prompt', function() {
|
||||
var term = $('<div></div>').appendTo('body').terminal($.noop, {
|
||||
prompt: '>>> '
|
||||
});
|
||||
it('should return prompt', function() {
|
||||
expect(term.get_prompt()).toEqual('>>> ');
|
||||
expect(term.find('.prompt').html()).toEqual('<span>>>> </span>');
|
||||
});
|
||||
it('should set prompt', function() {
|
||||
term.set_prompt('||| ');
|
||||
expect(term.get_prompt()).toEqual('||| ');
|
||||
expect(term.find('.prompt').html()).toEqual('<span>||| </span>');
|
||||
function prompt(callback) {
|
||||
callback('>>> ');
|
||||
}
|
||||
term.set_prompt(prompt);
|
||||
expect(term.get_prompt()).toEqual(prompt);
|
||||
expect(term.find('.prompt').html()).toEqual('<span>>>> </span>');
|
||||
});
|
||||
it('should format prompt', function() {
|
||||
var prompt = '<span style="font-weight:bold;text-decoration:underline;color:#fff;" data-text=">>>">>>></span><span> </span>';
|
||||
term.set_prompt('[[ub;#fff;]>>>] ');
|
||||
expect(term.find('.prompt').html()).toEqual(prompt);
|
||||
term.set_prompt(function(callback) {
|
||||
callback('[[ub;#fff;]>>>] ');
|
||||
});
|
||||
expect(term.find('.prompt').html()).toEqual(prompt);
|
||||
term.destroy().remove();
|
||||
});
|
||||
});
|
||||
describe('cmd plugin', function() {
|
||||
var term = $('<div></div>').appendTo('body').css('overflow-y', 'scroll').terminal($.noop, {
|
||||
name: 'cmd',
|
||||
numChars: 150,
|
||||
numRows: 20
|
||||
});
|
||||
var string = '';
|
||||
for (var i=term.cols(); i--;) {
|
||||
term.insert('M');
|
||||
}
|
||||
var cmd = term.cmd();
|
||||
var line = cmd.find('.prompt').next();
|
||||
it('text should have 2 lines', function() {
|
||||
expect(line.is('div')).toBe(true);
|
||||
expect(line.text().length).toBe(term.cols()-2);
|
||||
});
|
||||
it('cmd plugin moving cursor', function() {
|
||||
cmd.position(-8, true);
|
||||
var before = cmd.find('.prompt').next();
|
||||
var cursor = cmd.find('.cursor');
|
||||
var after = cursor.next();
|
||||
expect(before.is('span')).toBe(true);
|
||||
expect(before.text().length).toBe(term.cols()-8);
|
||||
expect(after.next().text().length).toBe(2);
|
||||
expect(after.text().length).toBe(5);
|
||||
expect(cursor.text()).toBe('M');
|
||||
});
|
||||
it('should remove characters', function() {
|
||||
cmd['delete'](-10);
|
||||
var before = cmd.find('.prompt').next();
|
||||
var cursor = cmd.find('.cursor');
|
||||
var after = cursor.next();
|
||||
expect(before.text().length).toEqual(term.cols()-8-10);
|
||||
cmd['delete'](8);
|
||||
expect(cursor.text()).toEqual('\xA0');
|
||||
expect(after.text().length).toEqual(0);
|
||||
});
|
||||
var history = cmd.history()
|
||||
it('should have one entry in history', function() {
|
||||
cmd.purge();
|
||||
term.set_command('something').focus(true);
|
||||
enter_key();
|
||||
expect(history.data()).toEqual(['something']);
|
||||
});
|
||||
it('should not add item to history if history is disabled', function() {
|
||||
history.disable();
|
||||
term.set_command('something else');
|
||||
enter_key();
|
||||
expect(history.data()).toEqual(['something']);
|
||||
});
|
||||
it('should remove commands from history', function() {
|
||||
var spy = spyOn(history, 'purge');
|
||||
if (spy.andCallThrough) {
|
||||
spy.andCallThrough();
|
||||
} else {
|
||||
spy.and.callThrough();
|
||||
}
|
||||
cmd.purge();
|
||||
expect(history.purge).toHaveBeenCalled();
|
||||
expect(history.data()).toEqual([]);
|
||||
});
|
||||
it('should have name', function() {
|
||||
expect(cmd.name()).toEqual('cmd_4');
|
||||
});
|
||||
it('should return command', function() {
|
||||
cmd.set('foo');
|
||||
expect(cmd.get()).toEqual('foo');
|
||||
});
|
||||
it('should not move position', function() {
|
||||
var pos = cmd.position();
|
||||
cmd.insert('bar', true);
|
||||
expect(cmd.position()).toEqual(pos);
|
||||
});
|
||||
it('should return $.noop for commands', function() {
|
||||
expect($.terminal.active().commands()).toEqual($.noop);
|
||||
});
|
||||
it('should set position', function() {
|
||||
cmd.position(0);
|
||||
expect(cmd.position()).toEqual(0);
|
||||
});
|
||||
it('should set and remove mask', function() {
|
||||
cmd.mask('•');
|
||||
cmd.position(6);
|
||||
var before = cmd.find('.prompt').next();
|
||||
expect(before.text()).toEqual('••••••');
|
||||
expect(cmd.get()).toEqual('foobar');
|
||||
cmd.mask(false);
|
||||
expect(before.text()).toEqual('foobar');
|
||||
});
|
||||
it('should execute functions on shortcuts', function() {
|
||||
var spy;
|
||||
spy = spyOn(cmd, 'position');
|
||||
if (spy.andCallThrough) {
|
||||
spy.andCallThrough();
|
||||
} else {
|
||||
spy.and.callThrough();
|
||||
}
|
||||
shortcut(true, false, false, 65); // CTRL+A
|
||||
expect(cmd.position).toHaveBeenCalled();
|
||||
spy = spyOn(cmd, 'delete');
|
||||
if (spy.andCallThrough) {
|
||||
spy.andCallThrough();
|
||||
} else {
|
||||
spy.and.callThrough();
|
||||
}
|
||||
shortcut(true, false, false, 75); // CTRL+K
|
||||
expect(cmd['delete']).toHaveBeenCalled();
|
||||
spy = spyOn(cmd, 'insert');
|
||||
if (spy.andCallThrough) {
|
||||
spy.andCallThrough();
|
||||
} else {
|
||||
spy.and.callThrough();
|
||||
}
|
||||
shortcut(true, false, false, 89); // CTRL+Y
|
||||
expect(cmd.insert).toHaveBeenCalled();
|
||||
shortcut(true, false, false, 85); // CTRL+U
|
||||
expect(cmd.kill_text()).toEqual('foobar');
|
||||
shortcut(true, false, true, 13);
|
||||
expect(cmd.find('.prompt').next().text()).toEqual('\xA0');
|
||||
expect(cmd.get()).toEqual('\n');
|
||||
cmd.set('');
|
||||
shortcut(false, false, false, 9); // TAB
|
||||
expect(cmd.get()).toEqual('\t');
|
||||
history.enable();
|
||||
cmd.set('foo bar');
|
||||
enter_key();
|
||||
shortcut(false, false, false, 38); // UP ARROW
|
||||
expect(cmd.get()).toEqual('foo bar');
|
||||
shortcut(false, false, false, 40); // DOWN ARROW
|
||||
expect(cmd.get()).toEqual('');
|
||||
cmd.insert('hello');
|
||||
shortcut(false, false, false, 38);
|
||||
shortcut(false, false, false, 40);
|
||||
expect(cmd.get()).toEqual('hello');
|
||||
shortcut(true, false, false, 80); // CTRL+P
|
||||
expect(cmd.get()).toEqual('foo bar');
|
||||
shortcut(true, false, false, 78); // CTRL+N
|
||||
expect(cmd.get()).toEqual('hello');
|
||||
cmd.set('foo bar baz');
|
||||
shortcut(false, false, false, 37); // LEFT ARROW
|
||||
expect(cmd.position()).toEqual(10);
|
||||
shortcut(true, false, false, 37); // moving by words
|
||||
expect(cmd.position()).toEqual(8);
|
||||
shortcut(true, false, false, 37);
|
||||
expect(cmd.position()).toEqual(4);
|
||||
shortcut(true, false, false, 37);
|
||||
expect(cmd.position()).toEqual(0);
|
||||
shortcut(false, false, false, 39); // RIGHT ARROW
|
||||
expect(cmd.position()).toEqual(1);
|
||||
shortcut(true, false, false, 39);
|
||||
expect(cmd.position()).toEqual(3);
|
||||
shortcut(true, false, false, 39);
|
||||
expect(cmd.position()).toEqual(7);
|
||||
shortcut(true, false, false, 39);
|
||||
expect(cmd.position()).toEqual(11);
|
||||
shortcut(false, false, false, 36); // HOME
|
||||
expect(cmd.position()).toEqual(0);
|
||||
shortcut(false, false, false, 35); // END
|
||||
expect(cmd.position()).toEqual(cmd.get().length);
|
||||
shortcut(true, false, false, 82); // CTRL+R
|
||||
expect(cmd.prompt()).toEqual("(reverse-i-search)`': ");
|
||||
enter_text('foo');
|
||||
expect(cmd.get()).toEqual('foo bar');
|
||||
shortcut(true, false, false, 71); // CTRL+G
|
||||
expect(cmd.get()).toEqual('foo bar baz');
|
||||
cmd.purge();
|
||||
term.destroy();
|
||||
});
|
||||
});
|
||||
function JSONRPCMock(url, object) {
|
||||
var ajax = $.ajax;
|
||||
var system = {
|
||||
'sdversion': '1.0',
|
||||
'name': 'DemoService',
|
||||
'address': url,
|
||||
// md5('JSONRPCMock')
|
||||
'id': 'urn:md5:e1a975ac782ce4ed0a504ceb909abf44',
|
||||
'procs': []
|
||||
};
|
||||
for (var key in object) {
|
||||
var proc = {
|
||||
name: key
|
||||
};
|
||||
if ($.isFunction(object[key])) {
|
||||
var re = /function[^\(]+\(([^\)]+)\)/;
|
||||
var m = object[key].toString().match(re);
|
||||
if (m) {
|
||||
proc.params = m[1].split(/\s*,\s*/);
|
||||
}
|
||||
}
|
||||
system.procs.push(proc);
|
||||
}
|
||||
$.ajax = function(obj) {
|
||||
if (obj.url == url) {
|
||||
var defer = $.Deferred();
|
||||
try {
|
||||
var req = JSON.parse(obj.data);
|
||||
var resp;
|
||||
if (req.method == 'system.describe') {
|
||||
resp = system;
|
||||
} else {
|
||||
var error = null;
|
||||
var ret = null
|
||||
try {
|
||||
ret = object[req.method].apply(null, req.params);
|
||||
} catch (e) {
|
||||
error = {message: e.message};
|
||||
}
|
||||
resp = {
|
||||
id: req.id,
|
||||
jsonrpc: '1.1',
|
||||
result: ret,
|
||||
error: error
|
||||
};
|
||||
}
|
||||
resp = JSON.stringify(resp);
|
||||
if ($.isFunction(obj.success)) {
|
||||
obj.success(resp, 'OK', {
|
||||
getResponseHeader: function(header) {
|
||||
if (header == 'Content-Type') {
|
||||
return 'application/json';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
defer.resolve(resp);
|
||||
} catch (e) {
|
||||
throw new Error(e.message);
|
||||
}
|
||||
return defer.promise();
|
||||
} else {
|
||||
return ajax.apply($, arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
var object = {
|
||||
echo: function(token, str) {
|
||||
return str;
|
||||
},
|
||||
login: function(user, password) {
|
||||
if (user == 'demo' && password == 'demo') {
|
||||
return 'TOKEN';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
JSONRPCMock('/test', object);
|
||||
describe('JSON-RPC', function() {
|
||||
var term = $('<div></div>').appendTo('body').terminal('/test', {
|
||||
login: true
|
||||
});
|
||||
it('should call login', function() {
|
||||
term.focus();
|
||||
var spy = spyOn(object, 'login');
|
||||
if (spy.andCallThrough) {
|
||||
spy.andCallThrough();
|
||||
} else {
|
||||
spy.and.callThrough();
|
||||
}
|
||||
term.insert('test');
|
||||
enter_key();
|
||||
term.insert('test');
|
||||
enter_key();
|
||||
var last_div = term.find('.terminal-output > div:last-child');
|
||||
expect(last_div.text()).toEqual('Wrong password try again!');
|
||||
expect(object.login).toHaveBeenCalledWith('test', 'test');
|
||||
term.insert('demo');
|
||||
enter_key();
|
||||
term.insert('demo');
|
||||
enter_key();
|
||||
expect(object.login).toHaveBeenCalledWith('demo', 'demo');
|
||||
});
|
||||
it('should call a function', function() {
|
||||
term.focus();
|
||||
var spy = spyOn(object, 'echo');
|
||||
if (spy.andCallThrough) {
|
||||
spy.andCallThrough();
|
||||
} else {
|
||||
spy.and.callThrough();
|
||||
}
|
||||
term.insert('echo hello');
|
||||
enter_key();
|
||||
expect(object.echo).toHaveBeenCalledWith('TOKEN', 'hello');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
if (node) {
|
||||
tests_on_ready();
|
||||
} else {
|
||||
$(tests_on_ready);
|
||||
}
|
||||
|
Reference in New Issue
Block a user