diff --git a/ChangeLog b/ChangeLog index 098303b0..e15e6c98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -49,6 +49,8 @@ keyStop: function(e, opt) { ``` * Updated socket.io to v0.9.13. +* Updated jquery-terminal to v0.4.22. + 2012.12.12, Version 0.1.8 diff --git a/lib/client/terminal/jquery-terminal/CHANGELOG b/lib/client/terminal/jquery-terminal/CHANGELOG index 2c53b6c6..305b1b9c 100644 --- a/lib/client/terminal/jquery-terminal/CHANGELOG +++ b/lib/client/terminal/jquery-terminal/CHANGELOG @@ -1,82 +1,88 @@ -0.4.17 fix IE formatting issue by adding cross-browser split -0.4.16 add reverse history search on CTRL+R - - fix cancel ajax call on CTRL+D -0.4.15 only one command from multiply commands is added to history - CTRL+D is handled even if exit is false -0.4.14 terminal don't add space after prompt (prompt need to add this space) - fix historyFilter - remove livequery -0.4.12 history return history object - add historyFilter - new event onCommandChange that execute scroll_to_bottom - add event onBeforeLogin -0.4.11 fix blank lines when echo longer strings -0.4.10 fix long line formatting and linebreak in the middle of formatting -0.4.9 fix wrap first line when prompt contain formatting -0.4.8 fix alt+d and ctrl+u -0.4.7 fix inserting special characters in Webkit on Windows -0.4.6 remove undocumented pipe operator - refreash prompt on resume -0.4.5 fix line wrapping when text contains tabulations -0.4.4 fix line wrapping with scrollbars -0.4.3 fix JSON-RPC when use without login -0.4.2 fix formatting when text contain empty lines -0.4.1 fix formatting when text contains newline characters -0.4 fix text formating when text splited into more then one line - you can pass nested objects as first argument - add tab completion with object passed as first argument -0.3.8 fix cursor manipulation when command contain new line characters -0.3.7 fix function terminal.login_name -0.3.6 fix switch between terminals - when terminal is not visible scroll to current terminal -0.3.5 fix scrolling in jQuery 1.6 -0.3.3 fixing PAGE UP/DOWN -0.3.2 fixing cursor in long lines -0.3.1 fixing small bugs, speed up resizing -0.3 fix resizing on start and issue with greetings - add formating strings to set style of text. - add to echo a function which will be called when terminal - is resized -0.3-RC2 fix manipulation of long line commands -0.3-RC1 add callbacks and new functions - you can now overwrite keyboard shortcuts - resizing recalculates lines lenght and redraw content - if you create plugin for elements that are not in the DOM - and then append it to DOM it's display corectly - put all dependencies in one file - Default greetings show terminal signature depending on - width of terminal - use Local Sorage for command line history if posible - remove access to command line (cmd plugin) and add interface - to allow interact with it - -0.2.3.9 fix append enter character (0x0D) to the command (thanks to marat - for reporting the bug) - -0.2.3.8 update mousewheel plugin which fix scrolling in Opera (Thanks for - Alexey Dubovtsev for reporting the bug) - -0.2.3.7 fix cursor in IE in tilda example - -0.2.3.6 fix json serialization in IE - -0.2.3.5 fix demos and clipboard textarea transparency in IE - -0.2.3.4 fix long lines in command line issue - -0.2.3.3 fix Terminal in Internet Exporer - -0.2.3.2 fix blank line issue (thanks to Chris Janicki for finding the - bug) and fix CTRL + Arrows scroll on CTRL+V - -0.2.3.1 allow CTRL+W CTRL+T - -0.2.3 fix for "(#$%.{" characters on Opera/Chrome, add cursor move - with CTRL+P, CTRL+N, CTRL+F, CTRL+B which also work in Chrome. - Fix Arrow Keys on Chrome (for cursor move and command line - history). Change License to LGPL3. - -0.2.2 fix down-arrow/open parentises issue in Opera and Chrome - -0.2.1 add support for paste from clipboard with CTRL+V (Copy to - clipboard is alway enabled on websites) +0.4.20 Add exec, greetings, onClear, onBlur, onFocus, onTerminalChange +0.4.19 add support for ANSI terminal formatting, fix cancelable ajax on + CTRL+D, replace emails with link mailto, remove formatting processing + from command line, add text glow option to formatting +0.4.18 fix scrollbar, better exceptions in chrome, replace urls with links + one style for font and color in root .terminal class +0.4.17 fix IE formatting issue by adding cross-browser split +0.4.16 add reverse history search on CTRL+R + + fix cancel ajax call on CTRL+D +0.4.15 only one command from multiply commands is added to history + CTRL+D is handled even if exit is false +0.4.14 terminal don't add space after prompt (prompt need to add this space) + fix historyFilter + remove livequery +0.4.12 history return history object + add historyFilter + new event onCommandChange that execute scroll_to_bottom + add event onBeforeLogin +0.4.11 fix blank lines when echo longer strings +0.4.10 fix long line formatting and linebreak in the middle of formatting +0.4.9 fix wrap first line when prompt contain formatting +0.4.8 fix alt+d and ctrl+u +0.4.7 fix inserting special characters in Webkit on Windows +0.4.6 remove undocumented pipe operator + refreash prompt on resume +0.4.5 fix line wrapping when text contains tabulations +0.4.4 fix line wrapping with scrollbars +0.4.3 fix JSON-RPC when use without login +0.4.2 fix formatting when text contain empty lines +0.4.1 fix formatting when text contains newline characters +0.4 fix text formating when text splited into more then one line + you can pass nested objects as first argument + add tab completion with object passed as first argument +0.3.8 fix cursor manipulation when command contain new line characters +0.3.7 fix function terminal.login_name +0.3.6 fix switch between terminals - when terminal is not visible scroll to current terminal +0.3.5 fix scrolling in jQuery 1.6 +0.3.3 fixing PAGE UP/DOWN +0.3.2 fixing cursor in long lines +0.3.1 fixing small bugs, speed up resizing +0.3 fix resizing on start and issue with greetings + add formating strings to set style of text. + add to echo a function which will be called when terminal + is resized +0.3-RC2 fix manipulation of long line commands +0.3-RC1 add callbacks and new functions + you can now overwrite keyboard shortcuts + resizing recalculates lines lenght and redraw content + if you create plugin for elements that are not in the DOM + and then append it to DOM it's display corectly + put all dependencies in one file + Default greetings show terminal signature depending on + width of terminal + use Local Sorage for command line history if posible + remove access to command line (cmd plugin) and add interface + to allow interact with it + +0.2.3.9 fix append enter character (0x0D) to the command (thanks to marat + for reporting the bug) + +0.2.3.8 update mousewheel plugin which fix scrolling in Opera (Thanks for + Alexey Dubovtsev for reporting the bug) + +0.2.3.7 fix cursor in IE in tilda example + +0.2.3.6 fix json serialization in IE + +0.2.3.5 fix demos and clipboard textarea transparency in IE + +0.2.3.4 fix long lines in command line issue + +0.2.3.3 fix Terminal in Internet Exporer + +0.2.3.2 fix blank line issue (thanks to Chris Janicki for finding the + bug) and fix CTRL + Arrows scroll on CTRL+V + +0.2.3.1 allow CTRL+W CTRL+T + +0.2.3 fix for "(#$%.{" characters on Opera/Chrome, add cursor move + with CTRL+P, CTRL+N, CTRL+F, CTRL+B which also work in Chrome. + Fix Arrow Keys on Chrome (for cursor move and command line + history). Change License to LGPL3. + +0.2.2 fix down-arrow/open parentises issue in Opera and Chrome + +0.2.1 add support for paste from clipboard with CTRL+V (Copy to + clipboard is alway enabled on websites) \ No newline at end of file diff --git a/lib/client/terminal/jquery-terminal/README b/lib/client/terminal/jquery-terminal/README index 6a31c538..16957789 100644 --- a/lib/client/terminal/jquery-terminal/README +++ b/lib/client/terminal/jquery-terminal/README @@ -1,69 +1,69 @@ - __ _____ ________ __ - / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / / - __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / - / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ - \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ - \/ /____/ version 0.4.18 - - -http://terminal.jcubic.pl - -Licensed under GNU LGPL Version 3 license http://www.gnu.org/licenses/lgpl.html -Copyright (c) 2011 Jakub Jankiewicz - -JQuery Terminal Emulator is a plugin for creating command line interpreters in -your applications. It can automatically call JSON-RPC service when user type -commands or you can provide you own function in which you can parse user -command. It's ideal if you want to provide additional functionality for power -users. It can also be used to debug your aplication. - -Features: - - * You can create interpreter for your JSON-RPC service with one line - of code. - - * Support for authentication (you can provide function when user enter - login and password or if you use JSON-RPC it can automatically call - login function on the server and pass token to all functions) - - * Stack of interpreters - you can create commands that trigger additional - interpreters (eg. you can use couple of JSON-RPC service and run them - when user type command) - - * Command Tree - you can use nested objects. Each command will invoke a - function, if the value is an object it will create new interpreter and - use function from that object as commands. You can use as much nested - object/commands as you like. If the value is a string it will create - JSON-RPC service. - - * Support for command line history it use Local Storage if posible - - * Support for tab completion if you create terminal from an object - - * Include keyboard shortcut from bash like CTRL+A, CTRL+D, CTRL+E etc. - - * Multiply terminals on one page (every terminal can have different - command, it's own authentication function and it's own command history) - - * It catch all exceptions and display error messages in terminal - (you can see errors in your javascript and php code in terminal if they - are in interpreter function) - - -Example of usage (javascript interpreter) - -jQuery(function($, undefined) { - $('#term_demo').terminal(function(command, term) { - if (command !== '') { - var result = window.eval(command); - if (result != undefined) { - term.echo(String(result)); - } - } - }, { - greetings: 'Javascript Interpreter', - name: 'js_demo', - height: 200, - width: 450, - prompt: 'js> '}); -}); + __ _____ ________ __ + / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / / + __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / + / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ + \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ + \/ /____/ version 0.4.22 + + +http://terminal.jcubic.pl + +Licensed under GNU LGPL Version 3 license http://www.gnu.org/licenses/lgpl.html +Copyright (c) 2011-2012 Jakub Jankiewicz + +JQuery Terminal Emulator is a plugin for creating command line interpreters in +your applications. It can automatically call JSON-RPC service when user type +commands or you can provide you own function in which you can parse user +command. It's ideal if you want to provide additional functionality for power +users. It can also be used to debug your aplication. + +Features: + + * You can create interpreter for your JSON-RPC service with one line + of code. + + * Support for authentication (you can provide function when user enter + login and password or if you use JSON-RPC it can automatically call + login function on the server and pass token to all functions) + + * Stack of interpreters - you can create commands that trigger additional + interpreters (eg. you can use couple of JSON-RPC service and run them + when user type command) + + * Command Tree - you can use nested objects. Each command will invoke a + function, if the value is an object it will create new interpreter and + use function from that object as commands. You can use as much nested + object/commands as you like. If the value is a string it will create + JSON-RPC service. + + * Support for command line history it use Local Storage if posible + + * Support for tab completion if you create terminal from an object + + * Include keyboard shortcut from bash like CTRL+A, CTRL+D, CTRL+E etc. + + * Multiply terminals on one page (every terminal can have different + command, it's own authentication function and it's own command history) + + * It catch all exceptions and display error messages in terminal + (you can see errors in your javascript and php code in terminal if they + are in interpreter function) + + +Example of usage (javascript interpreter) + +jQuery(function($, undefined) { + $('#term_demo').terminal(function(command, term) { + if (command !== '') { + var result = window.eval(command); + if (result != undefined) { + term.echo(String(result)); + } + } + }, { + greetings: 'Javascript Interpreter', + name: 'js_demo', + height: 200, + width: 450, + prompt: 'js> '}); +}); \ No newline at end of file diff --git a/lib/client/terminal/jquery-terminal/README.in b/lib/client/terminal/jquery-terminal/README.in deleted file mode 100644 index f7487dac..00000000 --- a/lib/client/terminal/jquery-terminal/README.in +++ /dev/null @@ -1,69 +0,0 @@ - __ _____ ________ __ - / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / / - __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / - / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ - \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ - \/ /____/ version {{VER}} - - -http://terminal.jcubic.pl - -Licensed under GNU LGPL Version 3 license http://www.gnu.org/licenses/lgpl.html -Copyright (c) 2011 Jakub Jankiewicz - -JQuery Terminal Emulator is a plugin for creating command line interpreters in -your applications. It can automatically call JSON-RPC service when user type -commands or you can provide you own function in which you can parse user -command. It's ideal if you want to provide additional functionality for power -users. It can also be used to debug your aplication. - -Features: - - * You can create interpreter for your JSON-RPC service with one line - of code. - - * Support for authentication (you can provide function when user enter - login and password or if you use JSON-RPC it can automatically call - login function on the server and pass token to all functions) - - * Stack of interpreters - you can create commands that trigger additional - interpreters (eg. you can use couple of JSON-RPC service and run them - when user type command) - - * Command Tree - you can use nested objects. Each command will invoke a - function, if the value is an object it will create new interpreter and - use function from that object as commands. You can use as much nested - object/commands as you like. If the value is a string it will create - JSON-RPC service. - - * Support for command line history it use Local Storage if posible - - * Support for tab completion if you create terminal from an object - - * Include keyboard shortcut from bash like CTRL+A, CTRL+D, CTRL+E etc. - - * Multiply terminals on one page (every terminal can have different - command, it's own authentication function and it's own command history) - - * It catch all exceptions and display error messages in terminal - (you can see errors in your javascript and php code in terminal if they - are in interpreter function) - - -Example of usage (javascript interpreter) - -jQuery(function($, undefined) { - $('#term_demo').terminal(function(command, term) { - if (command !== '') { - var result = window.eval(command); - if (result != undefined) { - term.echo(String(result)); - } - } - }, { - greetings: 'Javascript Interpreter', - name: 'js_demo', - height: 200, - width: 450, - prompt: 'js> '}); -}); diff --git a/lib/client/terminal/jquery-terminal/jquery.terminal.css b/lib/client/terminal/jquery-terminal/jquery.terminal.css index f4391f9c..03f6bfa2 100644 --- a/lib/client/terminal/jquery-terminal/jquery.terminal.css +++ b/lib/client/terminal/jquery-terminal/jquery.terminal.css @@ -1,67 +1,72 @@ -.terminal .clipboard { - position: absolute; - bottom: 0; - left: 0; - opacity: 0.01; - filter: alpha(opacity = 0.01); - filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.01); - width: 2px; -} -.cmd > .clipboard { - position: fixed; -} -.terminal { - position: relative; - overflow: hidden; -} -.cmd { - padding: 0; - margin: 0; - height: 1.3em; -} -.terminal .terminal-output div { - display: block; -} -.terminal { - font-family: FreeMono, monospace; - color: #aaa; - background-color: #000; - line-height: 16px; - /* removing breaking the lines */ - white-space: nowrap; - overflow:hidden; -} -.terminal .cmd span { - float: left; -} -.terminal .cmd span.inverted { - background-color: #aaa; - color: #000; -} -.terminal div::-moz-selection, .terminal span::-moz-selection { - background-color: #aaa; - color: #000; -} -.terminal div::selection, .terminal 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; -} +.terminal .clipboard { + position: absolute; + bottom: 0; + left: 0; + opacity: 0.01; + filter: alpha(opacity = 0.01); + filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.01); + width: 2px; +} +.cmd > .clipboard { + position: fixed; +} +.terminal { + padding: 10px; + position: relative; + overflow: hidden; +} +.cmd { + padding: 0; + margin: 0; + height: 1.3em; +} +.terminal .terminal-output div div, .terminal .prompt { + display: block; + line-height: 9px; + height: 14px; +} +.terminal { + font-family: FreeMono, monospace; + color: #aaa; + background-color: #000; + font-size: 12px; + line-height: 14px; +} +.terminal .terminal-output div span { + display: inline-block; +} +.terminal .cmd span { + display: inline-block; +} +.terminal .cmd span.inverted { + background-color: #aaa; + color: #000; +} +.terminal .terminal-output div div::-moz-selection, .terminal .terminal-output div span::-moz-selection { + background-color: #aaa; + color: #000; +} +.terminal .terminal-output div div::selection, .terminal .terminal-output div span::selection, +.terminal .cmd > span::selection, .terminal .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; +} \ No newline at end of file diff --git a/lib/client/terminal/jquery-terminal/jquery.terminal.js b/lib/client/terminal/jquery-terminal/jquery.terminal.js index 749c83fd..b8af09fe 100644 --- a/lib/client/terminal/jquery-terminal/jquery.terminal.js +++ b/lib/client/terminal/jquery-terminal/jquery.terminal.js @@ -4,11 +4,11 @@ *| __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / *| / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ *| \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ - *| \/ /____/ version 0.4.17 + *| \/ /____/ version 0.4.22 * http://terminal.jcubic.pl * * Licensed under GNU LGPL Version 3 license - * Copyright (c) 2011 Jakub Jankiewicz + * Copyright (c) 2011-2012 Jakub Jankiewicz * * Includes: * @@ -22,7 +22,7 @@ * Copyright 2007-2012 Steven Levithan * Available under the MIT License * - * Date: Sun, 24 Jun 2012 13:42:07 +0000 + * Date: Thu, 15 Nov 2012 07:12:21 +0000 */ /* @@ -47,29 +47,30 @@ disable */ -// return true if value is in array -Array.prototype.has = function(val) { - "use strict"; - for (var i = this.length; i--;) { - if (this[i] === val) { - return true; - } - } - return false; -}; -// debug function -function get_stack(caller) { - "use strict"; - if (caller) { - return [caller.toString().match(/.*\n.*\n/)].concat(get_stack(caller.caller)); - } else { - return []; - } -} + (function($, undefined) { "use strict"; + + // map object to object + $.omap = function(o, fn) { + var result = {}; + $.each(o, function(k, v) { + result[k] = fn.call(o, k, v); + }); + return result; + }; + // debug function + function get_stack(caller) { + "use strict"; + if (caller) { + return [caller.toString().match(/.*\n.*\n/)]. + concat(get_stack(caller.caller)); + } else { + return []; + } + } // ---------------------------------------- // START Storage plugin // ---------------------------------------- @@ -233,15 +234,15 @@ function get_stack(caller) { fn.$timerID = fn.$timerID || this.guid++; var handler = function() { - if (belay && this.inProgress) { + if (belay && handler.inProgress) { return; } - this.inProgress = true; + handler.inProgress = true; if ((++counter > times && times !== 0) || fn.call(element, counter) === false) { jQuery.timer.remove(element, label, fn); } - this.inProgress = false; + handler.inProgress = false; }; handler.$timerID = fn.$timerID; @@ -323,10 +324,13 @@ function get_stack(caller) { // START CROSS BROWSER SPLIT // ---------------------------------------- - var split; + (function(undef) { - // Avoid running twice; that would break the `nativeSplit` reference - split = split || function (undef) { + // prevent double include + + if (!String.prototype.split.toString().match(/\[native/)) { + return; + } var nativeSplit = String.prototype.split, compliantExecNpcg = /()??/.exec("")[1] === undef, // NPCG: nonparticipating capturing group @@ -406,7 +410,7 @@ function get_stack(caller) { return self; - }(); + })(); // ----------------------------------------------------------------------- /* @@ -437,151 +441,9 @@ function get_stack(caller) { // ----------------------------------------------------------------------- - var format_split_re = /(\[\[[bius]*;[^;]*;[^\]]*\][^\]\[]*\])/g; - var format_re = /\[\[([bius]*);([^;]*);([^\]]*)\]([^\]\[]*)\]/g; - var color_hex_re = /#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})/; - function encodeHTML(str) { - if (typeof str === 'string') { - // don't escape entities - str = str.replace(/&(?!#[0-9]+;|[a-zA-Z]+;)/g, '&'); - str = str.replace(//g, '>'); - // I don't think that it find \n - str = str.replace(/\n/g, '
'); - str = str.replace(/ /g, ' '); - str = str.replace(/\t/g, '    '); - //support for formating foo[[u;;]bar]baz[[b;#fff;]quux]zzz - var splited = str.split(format_split_re); - //console.log($.json_stringify(splited)); - if (splited.length > 1) { - str = $.map(splited, function(text) { - if (text === '') { - return text; - } else if (text.substring(0,1) === '[') { - // use substring for IE quirks mode - [0] don't work - return text.replace(format_re, function(s, - style, - color, - background, - text) { - if (text === '') { - return ' '; - } - var style_str = ''; - if (style.indexOf('b') !== -1) { - style_str += 'font-weight:bold;'; - } - var text_decoration = 'text-decoration:'; - if (style.indexOf('u') !== -1) { - text_decoration += 'underline '; - } - if (style.indexOf('s') !== -1) { - text_decoration += 'line-through'; - } - if (style.indexOf('s') !== -1 || - style.indexOf('u') !== -1) { - style_str += text_decoration + ';'; - } - if (style.indexOf('i') !== -1) { - style_str += 'font-style:italic; '; - } - if (color.match(color_hex_re)) { - style_str += 'color:' + color + ';'; - } - if (background.match(color_hex_re)) { - style_str += 'background-color:' + background; - } - str = '' + text + - ''; - return str; - }); - } else { - return '' + text + ''; - } - }).join(''); - } - return str; - } else { - return ''; - } - } - // ----------------------------------------------------------------------- - //split string to array of strings with the same length and keep formatting - function get_formatted_lines(str, length) { - var array = str.split(/\n/g); - var re_format = /(\[\[[bius]*;[^;]*;[^\]]*\][^\]\[]*\]?)/g; - var re_begin = /(\[\[[bius]*;[^;]*;[^\]]*\])/; - var re_last = /\[\[[bius]*;?[^;]*;?[^\]]*\]?$/; - var formatting = false; - var in_text = false; - var braket = 0; - var prev_format = ''; - var result = []; - for (var i = 0, len = array.length; i < len; ++i) { - if (prev_format !== '') { - if (array[i] === '') { - result.push(prev_format + ']'); - continue; - } else { - array[i] = prev_format + array[i]; - prev_format = ''; - } - } else { - if (array[i] === '') { - result.push(''); - continue; - } - } - var line = array[i]; - var first_index = 0; - var count = 0; - for (var j=0, jlen=line.length; j' + $.terminal.strip(string) + '').text().length; } // ----------------------------------------------------------------------- @@ -772,7 +634,7 @@ function get_stack(caller) { $.extend(this, { append: function(item) { - if (enabled && bc.current() !== item) { + if (enabled) { bc.append(item); $.Storage.set(name + 'commands', $.json_stringify(bc.data())); } @@ -875,7 +737,7 @@ function get_stack(caller) { function get_splited_command_line(string) { /* string = str_repeat('x', prompt_len) + string; - var result = get_formatted_lines(string); + var result = $.terminal.split_equal(string); result[0] = result[0].substring(prompt_len); return result; */ @@ -889,31 +751,31 @@ function get_stack(caller) { function draw_cursor_line(string, position) { var len = string.length; if (position === len) { - before.html(encodeHTML(string)); + before.html($.terminal.encode(string)); cursor.html(' '); after.html(''); } else if (position === 0) { before.html(''); //fix for tilda in IE - cursor.html(encodeHTML(string.slice(0, 1))); - //cursor.html(encodeHTML(string[0])); - after.html(encodeHTML(string.slice(1))); + cursor.html($.terminal.encode(string.slice(0, 1))); + //cursor.html($.terminal.encode(string[0])); + after.html($.terminal.encode(string.slice(1))); } else { - var before_str = encodeHTML(string.slice(0, position)); + var before_str = $.terminal.encode(string.slice(0, position)); before.html(before_str); //fix for tilda in IE var c = string.slice(position, position + 1); //cursor.html(string[position])); - cursor.html(c === ' ' ? ' ' : encodeHTML(c)); + cursor.html(c === ' ' ? ' ' : $.terminal.encode(c)); if (position === string.length - 1) { after.html(''); } else { - after.html(encodeHTML(string.slice(position + 1))); + after.html($.terminal.encode(string.slice(position + 1))); } } } function div(string) { - return '
' + encodeHTML(string) + '
'; + return '
' + $.terminal.encode(string) + '
'; } function lines_after(lines) { var last_ins = after; @@ -1005,11 +867,11 @@ function get_stack(caller) { } else { // in the middle if (num_lines === 3) { - before.before('
' + encodeHTML(array[0]) + + before.before('
' + $.terminal.encode(array[0]) + '
'); draw_cursor_line(array[1], position-first_len-1); after.after('
' + - encodeHTML(array[2]) + + $.terminal.encode(array[2]) + '
'); } else { // more lines, cursor in the middle @@ -1055,11 +917,11 @@ function get_stack(caller) { return function() { if (typeof prompt === 'string') { prompt_len = skipFormattingCount(prompt); - prompt_node.html(encodeHTML(prompt)); + prompt_node.html($.terminal.format(prompt)); } else { prompt(function(string) { prompt_len = skipFormattingCount(string); - prompt_node.html(encodeHTML(string)); + prompt_node.html($.terminal.format(string)); }); } //change_num_chars(); @@ -1276,7 +1138,8 @@ function get_stack(caller) { return false; } /*else { if ((e.altKey && e.which === 68) || - (e.ctrlKey && [65, 66, 68, 69, 80, 78, 70].has(e.which)) || + (e.ctrlKey && + $.inArray(e.which, [65, 66, 68, 69, 80, 78, 70]) > -1) || // 68 === D [35, 36, 37, 38, 39, 40].has(e.which)) { return false; @@ -1361,6 +1224,14 @@ function get_stack(caller) { return position; } }, + visible: (function() { + var visible = self.visible; + return function() { + visible.apply(self, []); + redraw(); + draw_prompt(); + }; + })(), show: (function() { var show = self.show; return function() { @@ -1428,7 +1299,7 @@ function get_stack(caller) { } if (result === undefined || result) { if (enabled) { - if ([38, 32, 13, 0, 8].has(e.which) && + if ($.inArray(e.which, [38, 32, 13, 0, 8]) > -1 && e.keyCode !== 123 && // for F12 which === 0 //!(e.which === 40 && e.shiftKey || !(e.which === 38 && e.shiftKey)) { @@ -1460,6 +1331,307 @@ function get_stack(caller) { // characters return self; }; + + // ------------------------------------------------------------------------- + // :: TOOLS + // ------------------------------------------------------------------------- + + var format_split_re = /(\[\[[gbius]*;[^;]*;[^\]]*\](?:[^\]\[]*|\[*(?!\[)[^\]]*\][^\]]*)\])/g; + var format_re = /\[\[([gbius]*);([^;]*);([^;\]]*;|[^\]]*);?([^\]]*)\]([^\]\[]*|[^\[]*\[(?!\[)*[^\]]*\][^\]]*)\]/g; + var color_hex_re = /#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})/; + var url_re = /(https?:((?!&[^;]+;)[^\s:"'<)])+)/g; + var email_regex = /((([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,})))/g; + $.terminal = { + // split text into lines with equal width and make each line be renderd + // separatly (text formating can be longer then a line). + split_equal: function(str, length) { + var array = str.split(/\n/g); + var re_format = /(\[\[[gbius]*;[^;]*;[^\]]*\][^\]\[]*\]?)/g; + var re_begin = /(\[\[[gbius]*;[^;]*;[^\]]*\])/; + var re_last = /\[\[[gbius]*;?[^;]*;?[^\]]*\]?$/; + var formatting = false; + var in_text = false; + var braket = 0; + var prev_format = ''; + var result = []; + for (var i = 0, len = array.length; i < len; ++i) { + if (prev_format !== '') { + if (array[i] === '') { + result.push(prev_format + ']'); + continue; + } else { + array[i] = prev_format + array[i]; + prev_format = ''; + } + } else { + if (array[i] === '') { + result.push(''); + continue; + } + } + var line = array[i]; + var first_index = 0; + var count = 0; + for (var j=0, jlen=line.length; j/g, '>') + // I don't think that it find \n + .replace(/\n/g, '
') + .replace(/ /g, ' ') + .replace(/\t/g, '    '); + }, + format: function(str) { + if (typeof str === 'string') { + str = $.terminal.encode($.terminal.from_ansi(str)); + //support for formating foo[[u;;]bar]baz[[b;#fff;]quux]zzz + var splited = str.split(format_split_re); + if (splited && splited.length > 1) { + str = $.map(splited, function(text) { + if (text === '') { + return text; + } else if (text.substring(0,1) === '[') { + // use substring for IE quirks mode - [0] don't work + return text.replace(format_re, function(s, + style, + color, + background, + _class, + text) { + if (text === '') { + return ' '; + } + var style_str = ''; + if (style.indexOf('b') !== -1) { + style_str += 'font-weight:bold;'; + } + var text_decoration = 'text-decoration:'; + if (style.indexOf('u') !== -1) { + text_decoration += 'underline '; + } + if (style.indexOf('s') !== -1) { + text_decoration += 'line-through'; + } + if (style.indexOf('s') !== -1 || + style.indexOf('u') !== -1) { + style_str += text_decoration + ';'; + } + if (style.indexOf('i') !== -1) { + style_str += 'font-style:italic;'; + } + if (color.match(color_hex_re)) { + style_str += 'color:' + color + ';'; + if (style.indexOf('g') !== -1) { + style_str += 'text-shadow: 0 0 5px ' + color + ';'; + } + } + if (background.match(color_hex_re)) { + style_str += 'background-color:' + background; + } + var result = '' + text + ''; + return result; + }); + } else { + return '' + text + ''; + } + }).join(''); + } + + return str.replace(url_re, function(link) { + var comma = link.match(/\.$/); + link = link.replace(/\.$/, ''); + return '' + link + '' + + (comma ? '.' : ''); + }).replace(email_regex, '$1'). + replace(/<\/span>/g, '
'); + } else { + return ''; + } + }, + // remove formatting from text + strip: function(str) { + return str.replace(format_re, '$5'); + }, + // return active terminal + active: function() { + return terminals.front(); + }, + ansi_colors: { + normal: { + black: '#000', + red: '#AA0000', + green: '#008400', + yellow: '#AA5500', + blue: '#0000AA', + magenta: '#AA00AA', + cyan: '#00AAAA', + white: '#fff' + }, + bold: { + white: '#fff', + red: '#FF5555', + green: '#44D544', + yellow: '#FFFF55', + blue: '#5555FF', + magenta: '#FF55FF', + cyan: '#55FFFF', + black: '#000' + } + }, + from_ansi: (function() { + var color = { + 30: 'black', + 31: 'red', + 32: 'green', + 33: 'yellow', + 34: 'blue', + 35: 'magenta', + 36: 'cyan', + 37: 'white' + }; + var background = { + 40: 'black', + 41: 'red', + 42: 'green', + 43: 'yellow', + 44: 'blue', + 45: 'magenta', + 46: 'cyan', + 47: 'white' + }; + function format_ansi(code) { + var controls = code.split(';'); + var num; + var styles = []; + var output_color = ''; + var output_background = ''; + for(var i in controls) { + num = parseInt(controls[i], 10); + if (num === 1) { + styles.push('b'); + } + if (num === 4) { + styles.push('u'); + } + if (background[num]) { + output_background = background[num]; + } + if (color[num]) { + output_color = color[num]; + } + } + var normal = $.terminal.ansi_colors.normal; + var colors = normal; + for (var i=styles.length;i--;) { + if (styles[i] == 'b') { + if (output_color == '') { + output_color = 'white'; + } + colors = $.terminal.ansi_colors.bold; + break; + } + } + return '[[' + [styles.join(''), + colors[output_color], + normal[output_background] + ].join(';') + ']'; + } + return function(input) { + var splitted = input.split(/(\[[0-9;]*m)/g); + if (splitted.length == 1) { + return input; + } + var output = []; + //skip closing at the begining + if (splitted.length > 3 && splitted.slice(0,3).join('') == '[0m') { + splitted = splitted.slice(3); + } + var inside = false; + for (var i=0; i/, '')], ['jQuery Terminal Emulator version ' + version_string, @@ -1521,31 +1693,35 @@ function get_stack(caller) { var terminal_id = terminals.length(); var num_chars; // numer of chars in line var command_list = []; // for tab completion - var settings = { + var settings = $.extend({ name: '', prompt: '> ', history: true, exit: true, clear: true, enabled: true, + displayExceptions: true, cancelableAjax: true, login: null, tabcompletion: null, historyFilter: null, - onInit: null, - onExit: null, - keypress: null, - keydown: null - }; - if (options) { - if (options.width) { - self.width(options.width); - } - if (options.height) { - self.height(options.height); - } - $.extend(settings, options); + onInit: $.noop, + onClear: $.noop, + onBlur: $.noop, + onFocus: $.noop, + onTerminalChange: $.noop, + onExit: $.noop, + keypress: $.noop, + keydown: $.noop + }, options || {}); + + if (settings.width) { + self.width(settings.width); } + if (settings.height) { + self.height(settings.height); + } + var pause = !settings.enabled; if (self.length === 0) { throw 'Sorry, but terminal said that "' + self.selector + @@ -1561,10 +1737,22 @@ function get_stack(caller) { } output = $('
').addClass('terminal-output').appendTo(self); self.addClass('terminal').append('
'); + self.click(function() { + self.find('textarea').focus(); + }); + /* + self.bind('touchstart.touchScroll', function() { + + }); + self.bind('touchmove.touchScroll', function() { + + }); + */ + //$('').hide().focus().appendTo(self); + //calculate numbers of characters function haveScrollbars() { return self.get(0).scrollHeight > self.innerHeight(); } - //calculate numbers of characters function get_num_chars() { var cursor = self.find('.cursor'); var cur_width = cursor.width(); @@ -1584,28 +1772,33 @@ function get_stack(caller) { // display Exception on terminal function display_exception(e, label) { - var message; - if (typeof e === 'string') { - message = e; - } else { - if (typeof e.fileName === 'string') { - message = e.fileName + ': ' + e.message; + if (settings.displayExceptions) { + var message; + if (typeof e === 'string') { + message = e; } else { - message = e.message; - } - } - self.error('[' + label + ']: ' + message); - self.pause(); - if (typeof e.fileName === 'string') { - //display filename and line which throw exeption - $.get(e.fileName, function(file) { - self.resume(); - var num = e.lineNumber - 1; - var line = file.split('\n')[num]; - if (line) { - self.error('[' + e.lineNumber + ']: ' + line); + if (typeof e.fileName === 'string') { + message = e.fileName + ': ' + e.message; + } else { + message = e.message; } - }); + } + self.error('[' + label + ']: ' + message); + if (typeof e.fileName === 'string') { + //display filename and line which throw exeption + self.pause(); + $.get(e.fileName, function(file) { + self.resume(); + var num = e.lineNumber - 1; + var line = file.split('\n')[num]; + if (line) { + self.error('[' + e.lineNumber + ']: ' + line); + } + }); + } + if (e.stack) { + self.error(e.stack); + } } } @@ -1628,7 +1821,6 @@ function get_stack(caller) { return true; } - function scroll_to_bottom() { var scrollHeight = self.prop ? self.prop('scrollHeight') : self.attr('scrollHeight'); @@ -1642,18 +1834,18 @@ function get_stack(caller) { // string can have line break //var array = string.split('\n'); // TODO: the way it should work - var array = get_formatted_lines(string, num_chars); + var array = $.terminal.split_equal(string, num_chars); div = $('
'); for (i = 0, len = array.length; i < len; ++i) { if (array[i] === '' || array[i] === '\r') { div.append('
 
'); } else { - $('
').html(encodeHTML(array[i])).appendTo(div); + $('
').html($.terminal.format(array[i])).appendTo(div); } } } else { - div = $('
').html(encodeHTML(string)); + div = $('
').html($.terminal.format(string)); } output.append(div); div.width('100%'); @@ -1683,31 +1875,57 @@ function get_stack(caller) { // TERMINAL METHODS // ---------------------------------------------------------- - $.extend(self, { + var dalyed_commands = []; + $.extend(self, $.omap({ clear: function() { output.html(''); command_line.set(''); lines = []; + try { + settings.onClear(self); + } catch (e) { + display_exception(e, 'onClear'); + throw e; + } self.attr({ scrollTop: 0}); return self; }, + exec: function(command, silent) { + if (pause) { + dalyed_commands.push([command, silent]); + } else { + commands(command, silent); + } + return self; + }, + commands: function() { + return interpreters.top().eval; + }, + greetings: function() { + show_greetings(); + return self; + }, paused: function() { return pause; }, pause: function() { if (command_line) { + pause = true; self.disable(); - command_line.hide(); + command_line.hidden(); } return self; }, resume: function() { - //console.log('resume on ' + options.prompt + '\n' + - // get_stack(arguments.callee.caller).join('')); if (command_line) { self.enable(); - command_line.show(); - + var original = dalyed_commands; + dalyed_commands = []; + while (original.length) { + var command = original.shift(); + self.exec.apply(self, command); + } + command_line.visible(); scroll_to_bottom(); } return self; @@ -1738,27 +1956,55 @@ function get_stack(caller) { // 100 provides buffer in viewport var x = next.offset().top - 50; $('html,body').animate({scrollTop: x}, 500); + try { + settings.onTerminalChange(next); + } catch (e) { + display_exception(e, 'onTerminalChange'); + throw e; + } return next; } } }, - focus: function(toggle) { - //console.log('focus on ' + options.prompt + '\n' + - // get_stack(arguments.callee.caller).join('')); - // TODO: one terminal should go out of focus - // TODO: add onFocus and onBlur + // silent used so events are not fired on init + focus: function(toggle, silent) { self.oneTime(1, function() { if (terminals.length() === 1) { if (toggle === false) { - self.disable(); + try { + if (!silent && settings.onBlur(self) !== false) { + self.disable(); + } + } catch (e) { + display_exception(e, 'onBlur'); + throw e; + } } else { - self.enable(); + try { + if (!silent && settings.onFocus(self) !== false) { + self.enable(); + } + } catch (e) { + display_exception(e, 'onFocus'); + throw e; + } } } else { if (toggle === false) { self.next(); } else { - terminals.front().disable(); + var front = terminals.front(); + if (front != self) { + front.disable(); + if (!silent) { + try { + settings.onTerminalChange(self); + } catch (e) { + display_exception(e, 'onTerminalChange'); + throw e; + } + } + } terminals.set(self); self.enable(); } @@ -1768,8 +2014,6 @@ function get_stack(caller) { return self; }, enable: function() { - //console.log('enable: ' + options.prompt + '\n' + - // get_stack(arguments.callee.caller).join('')); if (num_chars === undefined) { //enabling first time self.resize(); @@ -1818,7 +2062,7 @@ function get_stack(caller) { }, set_prompt: function(prompt) { if (validate('prompt', prompt)) { - if (prompt.constructor === Function) { + if (typeof prompt == 'function') { command_line.prompt(function(command) { prompt(command, self); }); @@ -1847,11 +2091,11 @@ function get_stack(caller) { return lines; } else { return $.map(lines, function(i, item) { - return typeof item === 'function' ? item() : item; - }).get().join('\n'); + return typeof item == 'function' ? item() : item; + }).join('\n'); } }, - resize: function(width, height) { + resize: function(width, height) { if (width && height) { self.width(width); self.height(height); @@ -1861,7 +2105,7 @@ function get_stack(caller) { var o = output.detach(); output.html(''); $.each(lines, function(i, line) { - draw_line(line && line.constructor === Function ? line() : line); + draw_line(line && typeof line == 'function' ? line() : line); }); self.prepend(o); scroll_to_bottom(); @@ -1869,14 +2113,17 @@ function get_stack(caller) { }, echo: function(line) { lines.push(line); - return draw_line(typeof line === 'function' ? line() : line); + draw_line(typeof line === 'function' ? line() : line); + on_scrollbar_show_resize(); + return self; }, error: function(message) { //echo red message - self.echo('[[;#f00;]' + escape_brackets(message) + ']'); + return self.echo('[[;#f00;]' + escape_brackets(message) + ']'); }, scroll: function(amount) { var pos; + amount = Math.round(amount); if (self.prop) { if (amount > self.prop('scrollTop') && amount > 0) { self.prop('scrollTop', 0); @@ -1905,16 +2152,16 @@ function get_stack(caller) { token: settings.login ? function() { var name = settings.name; return $.Storage.get('token' + (name ? '_' + name : '')); - } : null, + } : $.noop, login_name: settings.login ? function() { var name = settings.name; return $.Storage.get('login' + (name ? '_' + name : '')); - } : null, + } : $.noop, name: function() { return settings.name; }, push: function(_eval, options) { - if (!options.prompt || validate('prompt', options.prompt)) { + if (options && (!options.prompt || validate('prompt', options.prompt)) || !options) { if (typeof _eval === 'string') { _eval = make_json_rpc_eval_fun(options['eval'], self); } @@ -1923,6 +2170,13 @@ function get_stack(caller) { } return self; }, + reset: function() { + self.clear(); + while(interpreters.size() > 1) { + interpreters.pop(); + } + initialize(); + }, pop: function(string) { if (string !== undefined) { echo_command(string); @@ -1931,20 +2185,38 @@ function get_stack(caller) { if (settings.login) { logout(); if (typeof settings.onExit === 'function') { - settings.onExit(self); + try { + settings.onExit(self); + } catch (e) { + display_exception(e, 'onExit'); + throw e; + } } } } else { var current = interpreters.pop(); prepare_top_interpreter(); if (typeof current.onExit === 'function') { - current.onExit(self); + try { + current.onExit(self); + } catch (e) { + display_exception(e, 'onExit'); + throw e; + } } } return self; - } - }); + }, function(_, fun) { + // wrap all functions and display execptions + return function() { + try { + return fun.apply(this, Array.prototype.slice.apply(arguments)); + } catch(e) { + display_exception(e, 'TERMINAL'); + } + }; + })); //function constructor for eval function make_json_rpc_eval_fun(url, terminal) { @@ -2007,6 +2279,7 @@ function get_stack(caller) { //display prompt and last command function echo_command(command) { + command = command.replace(/\[/g, '[').replace(/\]/g, ']'); var prompt = command_line.prompt(); if (command_line.mask()) { command = command.replace(/./g, '*'); @@ -2022,24 +2295,27 @@ function get_stack(caller) { // wrapper over eval it implements exit and catch all exeptions // from user code and display them on terminal - function commands(command) { + function commands(command, silent) { try { var interpreter = interpreters.top(); - if (command === 'exit' && settings.exit) { if (interpreters.size() === 1) { if (settings.login) { logout(); } else { var msg = 'You can exit from main interpeter'; - echo_command(command); + if (!silent) { + echo_command(command); + } self.echo(msg); } } else { self.pop('exit'); } } else { - echo_command(command); + if (!silent) { + echo_command(command); + } if (command === 'clear' && settings.clear) { self.clear(); } else { @@ -2110,6 +2386,16 @@ function get_stack(caller) { //this function is call only when options.login function is defined //check for this is in self.pop method function logout() { + if (typeof settings.onBeforelogout === 'function') { + try { + if (settings.onBeforelogout(self) == false) { + return; + } + } catch (e) { + display_exception(e, 'onBeforelogout'); + throw e; + } + } var name = settings.name; name = (name ? '_' + name : ''); $.Storage.remove('token' + name, null); @@ -2118,6 +2404,14 @@ function get_stack(caller) { command_line.history().disable(); } login(); + if (typeof settings.onAfterlogout === 'function') { + try { + settings.onAfterlogout(self); + } catch (e) { + display_exception(e, 'onAfterlogout'); + throw e; + } + } } //function enable history, set prompt, run eval function @@ -2130,7 +2424,7 @@ function get_stack(caller) { } name += terminal_id; command_line.name(name); - if (interpreter.prompt.constructor === Function) { + if (typeof interpreter.prompt == 'function') { command_line.prompt(function(command) { interpreter.prompt(command, self); }); @@ -2149,26 +2443,43 @@ function get_stack(caller) { prepare_top_interpreter(); show_greetings(); if (typeof settings.onInit === 'function') { - settings.onInit(self); + try { + settings.onInit(self); + } catch (e) { + display_exception(e, 'OnInit'); + throw e; + } } } - var tab_count = 0; - var scrollBars = haveScrollbars(); - function key_down(e) { - var i; - // after text pasted into textarea in cmd plugin - self.oneTime(5, function() { + + // --------------------------------------------------------------------- + var on_scrollbar_show_resize = (function() { + var scrollBars = haveScrollbars(); + return function() { if (scrollBars !== haveScrollbars()) { // if scollbars appearance change we will have different // number of chars self.resize(); scrollBars = haveScrollbars(); } + }; + })(); + // --------------------------------------------------------------------- + // KEYDOWN EVENT HANDLER + // --------------------------------------------------------------------- + var tab_count = 0; + + function key_down(e) { + var i; + // after text pasted into textarea in cmd plugin + self.oneTime(5, function() { + on_scrollbar_show_resize(); }); + if (settings.keydown && settings.keydown(e, self) === false) { + return false; + } if (!self.paused()) { - if (settings.keydown && settings.keydown(e, self) === false) { - return false; - } + if (e.which !== 9) { // not a TAB tab_count = 0; } @@ -2228,34 +2539,38 @@ function get_stack(caller) { self.attr({scrollTop: self.attr('scrollHeight')}); } } else { - // cancel ajax requests - if (settings.cancelableAjax) { - if (e.which === 68 && e.ctrlKey) { // CTRL+D - for (i=requests.length; i--;) { - var r = requests[i]; - if (4 !== r.readyState) { - try { - r.abort(); - } catch(e) { - self.error('error in aborting ajax'); - } + if (e.which === 68 && e.ctrlKey) { // CTRL+D + for (i=requests.length; i--;) { + var r = requests[i]; + if (4 !== r.readyState) { + try { + r.abort(); + } catch(e) { + self.error('error in aborting ajax'); } } - self.resume(); - return false; } + self.resume(); + return false; } } } + // --------------------------------------------------------------------- // INIT CODE + // --------------------------------------------------------------------- var url; if (settings.login && typeof settings.onBeforeLogin === 'function') { - settings.onBeforeLogin(self); + try { + settings.onBeforeLogin(self); + } catch (e) { + display_exception(e, 'onBeforeLogin'); + throw e; + } } - if (init_eval.constructor === String) { + if (typeof init_eval == 'string') { url = init_eval; //url variable is use when making login function init_eval = make_json_rpc_eval_fun(init_eval, self); - } else if (init_eval.constructor === Array) { + } else if (typeof init_eval == 'object' && init_eval.constructor === Array) { throw "You can't use array as eval"; } else if (typeof init_eval === 'object') { // top commands @@ -2348,7 +2663,12 @@ function get_stack(caller) { } : null, onCommandChange: function(command) { if (typeof settings.onCommandChange === 'function') { - settings.onCommandChange(command, self); + try { + settings.onCommandChange(command, self); + } catch (e) { + display_exception(e, 'onCommandChange'); + throw e; + } } scroll_to_bottom(); }, @@ -2357,16 +2677,17 @@ function get_stack(caller) { //num_chars = get_num_chars(); terminals.append(self); if (settings.enabled === true) { - self.focus(); + self.focus(undefined, true); } else { self.disable(); } - $(window).resize(self.resize); self.click(function() { - self.focus(); + if (!(pause && terminals.length() > 1 && self === $.terminal.active())) { + self.focus(); + } }); - if (self.token && !self.token() && self.login_name && + if (options.login && self.token && !self.token() && self.login_name && !self.login_name()) { login(); } else { @@ -2388,5 +2709,4 @@ function get_stack(caller) { return self; }; //terminal plugin - })(jQuery); \ No newline at end of file