From aa7befc2388434fc72ab5228fb8319fe89f3109f Mon Sep 17 00:00:00 2001 From: coderaiser Date: Thu, 20 Sep 2012 10:36:02 -0400 Subject: [PATCH] setted up jquery-terminal plagin --- lib/client/terminal/jquery-terminal/CHANGELOG | 82 + lib/client/terminal/jquery-terminal/README | 69 + lib/client/terminal/jquery-terminal/README.in | 69 + lib/client/terminal/jquery-terminal/dterm.js | 63 + .../terminal/jquery-terminal/index.html | 17 + .../jquery-terminal/jquery.mousewheel.js | 84 + .../jquery-terminal/jquery.terminal.css | 66 + .../jquery-terminal/jquery.terminal.js | 2391 +++++++++++++++++ 8 files changed, 2841 insertions(+) create mode 100644 lib/client/terminal/jquery-terminal/CHANGELOG create mode 100644 lib/client/terminal/jquery-terminal/README create mode 100644 lib/client/terminal/jquery-terminal/README.in create mode 100644 lib/client/terminal/jquery-terminal/dterm.js create mode 100644 lib/client/terminal/jquery-terminal/index.html create mode 100644 lib/client/terminal/jquery-terminal/jquery.mousewheel.js create mode 100644 lib/client/terminal/jquery-terminal/jquery.terminal.css create mode 100644 lib/client/terminal/jquery-terminal/jquery.terminal.js diff --git a/lib/client/terminal/jquery-terminal/CHANGELOG b/lib/client/terminal/jquery-terminal/CHANGELOG new file mode 100644 index 00000000..2c53b6c6 --- /dev/null +++ b/lib/client/terminal/jquery-terminal/CHANGELOG @@ -0,0 +1,82 @@ +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) diff --git a/lib/client/terminal/jquery-terminal/README b/lib/client/terminal/jquery-terminal/README new file mode 100644 index 00000000..6a31c538 --- /dev/null +++ b/lib/client/terminal/jquery-terminal/README @@ -0,0 +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> '}); +}); diff --git a/lib/client/terminal/jquery-terminal/README.in b/lib/client/terminal/jquery-terminal/README.in new file mode 100644 index 00000000..f7487dac --- /dev/null +++ b/lib/client/terminal/jquery-terminal/README.in @@ -0,0 +1,69 @@ + __ _____ ________ __ + / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / / + __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / + / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ + \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ + \/ /____/ 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/dterm.js b/lib/client/terminal/jquery-terminal/dterm.js new file mode 100644 index 00000000..7506d2fc --- /dev/null +++ b/lib/client/terminal/jquery-terminal/dterm.js @@ -0,0 +1,63 @@ +/*! + * Example plugin using JQuery Terminal Emulator + * Copyright (C) 2010 Jakub Jankiewicz + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +(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(eval, options) { + var op = $.extend_if_has({}, options, + ['greetings', 'prompt', 'onInit', + 'onExit', 'clear', + 'login', 'name', 'exit']); + op.enabled = false; + var terminal = this.terminal(eval, 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; + var dialog = 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); diff --git a/lib/client/terminal/jquery-terminal/index.html b/lib/client/terminal/jquery-terminal/index.html new file mode 100644 index 00000000..1ae8ae4b --- /dev/null +++ b/lib/client/terminal/jquery-terminal/index.html @@ -0,0 +1,17 @@ + + + + + +
+ \ No newline at end of file diff --git a/lib/client/terminal/jquery-terminal/jquery.mousewheel.js b/lib/client/terminal/jquery-terminal/jquery.mousewheel.js new file mode 100644 index 00000000..c7b28217 --- /dev/null +++ b/lib/client/terminal/jquery-terminal/jquery.mousewheel.js @@ -0,0 +1,84 @@ +/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) + * Licensed under the MIT License (LICENSE.txt). + * + * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. + * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. + * Thanks to: Seamus Leahy for adding deltaX and deltaY + * + * Version: 3.0.6 + * + * Requires: 1.2.2+ + */ + +(function($) { + +var types = ['DOMMouseScroll', 'mousewheel']; + +if ($.event.fixHooks) { + for ( var i=types.length; i; ) { + $.event.fixHooks[ types[--i] ] = $.event.mouseHooks; + } +} + +$.event.special.mousewheel = { + setup: function() { + if ( this.addEventListener ) { + for ( var i=types.length; i; ) { + this.addEventListener( types[--i], handler, false ); + } + } else { + this.onmousewheel = handler; + } + }, + + teardown: function() { + if ( this.removeEventListener ) { + for ( var i=types.length; i; ) { + this.removeEventListener( types[--i], handler, false ); + } + } else { + this.onmousewheel = null; + } + } +}; + +$.fn.extend({ + mousewheel: function(fn) { + return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); + }, + + unmousewheel: function(fn) { + return this.unbind("mousewheel", fn); + } +}); + + +function handler(event) { + var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; + event = $.event.fix(orgEvent); + event.type = "mousewheel"; + + // Old school scrollwheel delta + if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; } + if ( orgEvent.detail ) { delta = -orgEvent.detail/3; } + + // New school multidimensional scroll (touchpads) deltas + deltaY = delta; + + // Gecko + if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { + deltaY = 0; + deltaX = -1*delta; + } + + // Webkit + if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } + if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } + + // Add event and delta to the front of the arguments + args.unshift(event, delta, deltaX, deltaY); + + return ($.event.dispatch || $.event.handle).apply(this, args); +} + +})(jQuery); \ No newline at end of file diff --git a/lib/client/terminal/jquery-terminal/jquery.terminal.css b/lib/client/terminal/jquery-terminal/jquery.terminal.css new file mode 100644 index 00000000..e3178958 --- /dev/null +++ b/lib/client/terminal/jquery-terminal/jquery.terminal.css @@ -0,0 +1,66 @@ +.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 { + display: block; +} +.terminal { + font-family: FreeMono, monospace; + color: #aaa; + background-color: #000; + font-size: 12px; + line-height: 14px; +} +.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; +} diff --git a/lib/client/terminal/jquery-terminal/jquery.terminal.js b/lib/client/terminal/jquery-terminal/jquery.terminal.js new file mode 100644 index 00000000..31abe6d8 --- /dev/null +++ b/lib/client/terminal/jquery-terminal/jquery.terminal.js @@ -0,0 +1,2391 @@ +/**@license + *| __ _____ ________ __ + *| / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / / + *| __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / + *| / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ + *| \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ + *| \/ /____/ version 0.4.17 + * http://terminal.jcubic.pl + * + * Licensed under GNU LGPL Version 3 license + * Copyright (c) 2011 Jakub Jankiewicz + * + * Includes: + * + * Storage plugin Distributed under the MIT License + * Copyright (c) 2010 Dave Schindler + * + * jQuery Timers licenced with the WTFPL + * + * + * Cross-Browser Split 1.1.1 + * Copyright 2007-2012 Steven Levithan + * Available under the MIT License + * + * Date: Sun, 24 Jun 2012 13:42:07 +0000 + */ + +/* + + TODO: + add destroy method to terminal (cmd alrady have it) + + add support for - $(...).each(function() { ... }); + + $.fn.pluginname = function(options) { + var settings = $.extend({}, $.fn.pluginname.defaultOptions, options); + + return this.each(function() { + var $this = $(this); + }); + $.fn.pluginname.defaultOptions = { + }; + }; + + distinguish between paused and disabled + paused should block keydown in terminal it should disable command line + 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"; + // ---------------------------------------- + // START Storage plugin + // ---------------------------------------- + // Private data + var isLS = typeof window.localStorage !== 'undefined'; + // Private functions + function wls(n, v) { + var c; + if (typeof n === 'string' && typeof v === 'string') { + localStorage[n] = v; + return true; + } else if (typeof n === 'object' && typeof v === 'undefined') { + for (c in n) { + if (n.hasOwnProperty(c)) { + localStorage[c] = n[c]; + } + } + return true; + } + return false; + } + function wc(n, v) { + var dt, e, c; + dt = new Date(); + dt.setTime(dt.getTime() + 31536000000); + e = '; expires=' + dt.toGMTString(); + if (typeof n === 'string' && typeof v === 'string') { + document.cookie = n + '=' + v + e + '; path=/'; + return true; + } else if (typeof n === 'object' && typeof v === 'undefined') { + for (c in n) { + if (n.hasOwnProperty(c)) { + document.cookie = c + '=' + n[c] + e + '; path=/'; + } + } + return true; + } + return false; + } + function rls(n) { + return localStorage[n]; + } + function rc(n) { + var nn, ca, i, c; + nn = n + '='; + ca = document.cookie.split(';'); + for (i = 0; i < ca.length; i++) { + c = ca[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nn) === 0) { + return c.substring(nn.length, c.length); + } + } + return null; + } + function dls(n) { + return delete localStorage[n]; + } + function dc(n) { + return wc(n, '', -1); + } + /** + * Public API + * $.Storage.set("name", "value") + * $.Storage.set({"name1":"value1", "name2":"value2", etc}) + * $.Storage.get("name") + * $.Storage.remove("name") + */ + $.extend({ + Storage: { + set: isLS ? wls : wc, + get: isLS ? rls : rc, + remove: isLS ? dls : dc + } + }); + // ---------------------------------------- + // END Storage plugin + // ---------------------------------------- + // START jQuery Timers + // ---------------------------------------- + jQuery.fn.extend({ + everyTime: function(interval, label, fn, times, belay) { + return this.each(function() { + jQuery.timer.add(this, interval, label, fn, times, belay); + }); + }, + oneTime: function(interval, label, fn) { + return this.each(function() { + jQuery.timer.add(this, interval, label, fn, 1); + }); + }, + stopTime: function(label, fn) { + return this.each(function() { + jQuery.timer.remove(this, label, fn); + }); + } + }); + + jQuery.extend({ + timer: { + guid: 1, + global: {}, + regex: /^([0-9]+)\s*(.*s)?$/, + powers: { + // Yeah this is major overkill... + 'ms': 1, + 'cs': 10, + 'ds': 100, + 's': 1000, + 'das': 10000, + 'hs': 100000, + 'ks': 1000000 + }, + timeParse: function(value) { + if (value === undefined || value === null) { + return null; + } + var result = this.regex.exec(jQuery.trim(value.toString())); + if (result[2]) { + var num = parseInt(result[1], 10); + var mult = this.powers[result[2]] || 1; + return num * mult; + } else { + return value; + } + }, + add: function(element, interval, label, fn, times, belay) { + var counter = 0; + + if (jQuery.isFunction(label)) { + if (!times) { + times = fn; + } + fn = label; + label = interval; + } + + interval = jQuery.timer.timeParse(interval); + + if (typeof interval !== 'number' || + isNaN(interval) || + interval <= 0) { + return; + } + if (times && times.constructor !== Number) { + belay = !!times; + times = 0; + } + + times = times || 0; + belay = belay || false; + + if (!element.$timers) { + element.$timers = {}; + } + if (!element.$timers[label]) { + element.$timers[label] = {}; + } + fn.$timerID = fn.$timerID || this.guid++; + + var handler = function() { + if (belay && this.inProgress) { + return; + } + this.inProgress = true; + if ((++counter > times && times !== 0) || + fn.call(element, counter) === false) { + jQuery.timer.remove(element, label, fn); + } + this.inProgress = false; + }; + + handler.$timerID = fn.$timerID; + + if (!element.$timers[label][fn.$timerID]) { + element.$timers[label][fn.$timerID] = window.setInterval(handler, interval); + } + + if (!this.global[label]) { + this.global[label] = []; + } + this.global[label].push(element); + + }, + remove: function(element, label, fn) { + var timers = element.$timers, ret; + + if (timers) { + + if (!label) { + for (var lab in timers) { + if (timers.hasOwnProperty(lab)) { + this.remove(element, lab, fn); + } + } + } else if (timers[label]) { + if (fn) { + if (fn.$timerID) { + window.clearInterval(timers[label][fn.$timerID]); + delete timers[label][fn.$timerID]; + } + } else { + for (var _fn in timers[label]) { + if (timers[label].hasOwnProperty(_fn)) { + window.clearInterval(timers[label][_fn]); + delete timers[label][_fn]; + } + } + } + + for (ret in timers[label]) { + if (timers[label].hasOwnProperty(ret)) { + break; + } + } + if (!ret) { + ret = null; + delete timers[label]; + } + } + + for (ret in timers) { + if (timers.hasOwnProperty(ret)) { + break; + } + } + if (!ret) { + element.$timers = null; + } + } + } + } + }); + + if (jQuery.browser.msie) { + jQuery(window).one('unload', function() { + var global = jQuery.timer.global; + for (var label in global) { + if (global.hasOwnProperty(label)) { + var els = global[label], i = els.length; + while (--i) { + jQuery.timer.remove(els[i], label); + } + } + } + }); + } + // ---------------------------------------- + // START CROSS BROWSER SPLIT + // ---------------------------------------- + + var split; + + // Avoid running twice; that would break the `nativeSplit` reference + split = split || function (undef) { + + var nativeSplit = String.prototype.split, + compliantExecNpcg = /()??/.exec("")[1] === undef, // NPCG: nonparticipating capturing group + self; + + self = function (str, separator, limit) { + // If `separator` is not a regex, use `nativeSplit` + if (Object.prototype.toString.call(separator) !== "[object RegExp]") { + return nativeSplit.call(str, separator, limit); + } + var output = [], + flags = (separator.ignoreCase ? "i" : "") + + (separator.multiline ? "m" : "") + + (separator.extended ? "x" : "") + // Proposed for ES6 + (separator.sticky ? "y" : ""), // Firefox 3+ + lastLastIndex = 0, + // Make `global` and avoid `lastIndex` issues by working with a copy + separator2, match, lastIndex, lastLength; + separator = new RegExp(separator.source, flags + "g"); + str += ""; // Type-convert + if (!compliantExecNpcg) { + // Doesn't need flags gy, but they don't hurt + separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags); + } + /* Values for `limit`, per the spec: + * If undefined: 4294967295 // Math.pow(2, 32) - 1 + * If 0, Infinity, or NaN: 0 + * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; + * If negative number: 4294967296 - Math.floor(Math.abs(limit)) + * If other: Type-convert, then use the above rules + */ + // ? Math.pow(2, 32) - 1 : ToUint32(limit) + limit = limit === undef ? -1 >>> 0 : limit >>> 0; + while (match = separator.exec(str)) { + // `separator.lastIndex` is not reliable cross-browser + lastIndex = match.index + match[0].length; + if (lastIndex > lastLastIndex) { + output.push(str.slice(lastLastIndex, match.index)); + // Fix browsers whose `exec` methods don't consistently return `undefined` for + // nonparticipating capturing groups + if (!compliantExecNpcg && match.length > 1) { + match[0].replace(separator2, function () { + for (var i = 1; i < arguments.length - 2; i++) { + if (arguments[i] === undef) { + match[i] = undef; + } + } + }); + } + if (match.length > 1 && match.index < str.length) { + Array.prototype.push.apply(output, match.slice(1)); + } + lastLength = match[0].length; + lastLastIndex = lastIndex; + if (output.length >= limit) { + break; + } + } + if (separator.lastIndex === match.index) { + separator.lastIndex++; // Avoid an infinite loop + } + } + if (lastLastIndex === str.length) { + if (lastLength || !separator.test("")) { + output.push(""); + } + } else { + output.push(str.slice(lastLastIndex)); + } + return output.length > limit ? output.slice(0, limit) : output; + }; + + // For convenience + String.prototype.split = function (separator, limit) { + return self(this, separator, limit); + }; + + return self; + + }(); + + // ----------------------------------------------------------------------- + /* + function decodeHTML(str) { + if (typeof str === 'string') { + str = str.replace(/&/g, '&'); + str = str.replace(/</g, '<').replace(/>/g, '>'); + str = str.replace(/ /g, '\t'); + str = str.replace(//g, '\n').replace(/ /g, ' '); + return str; + } else { + return ''; + } + } + */ + //split string to array of strings with the same length + function str_parts(str, length) { + var result = []; + var len = str.length; + if (len < length) { + return [str]; + } + for (var i = 0; i < len; i += length) { + result.push(str.substring(i, i + length)); + } + return result; + } + + + // ----------------------------------------------------------------------- + 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 0 ? data[data.length - 1] : null; + } + }); + } + // serialize object myself (biwascheme or prototype library do something + // wiked with JSON serialization for Arrays) + $.json_stringify = function(object, level) { + var result = '', i; + level = level === undefined ? 1 : level; + var type = typeof object; + switch (type) { + case 'function': + result += object; + break; + case 'boolean': + result += object ? 'true' : 'false'; + break; + case 'object': + if (object === null) { + result += 'null'; + } else if (object instanceof Array) { + result += '['; + var len = object.length; + for (i = 0; i < len - 1; ++i) { + result += $.json_stringify(object[i], level + 1); + } + result += $.json_stringify(object[len - 1], level + 1) + ']'; + } else { + result += '{'; + for (var property in object) { + if (object.hasOwnProperty(property)) { + result += '"' + property + '":' + + $.json_stringify(object[property], level + 1); + } + } + result += '}'; + } + break; + case 'string': + var str = object; + var repl = { + '\\\\': '\\\\', + '"': '\\"', + '/': '\\/', + '\\n': '\\n', + '\\r': '\\r', + '\\t': '\\t'}; + for (i in repl) { + if (repl.hasOwnProperty(i)) { + str = str.replace(new RegExp(i, 'g'), repl[i]); + } + } + result += '"' + str + '"'; + break; + case 'number': + result += String(object); + break; + } + result += (level > 1 ? ',' : ''); + // quick hacks below + if (level === 1) { + // fix last comma + result = result.replace(/,([\]}])/g, '$1'); + } + // fix comma before array or object + return result.replace(/([\[{]),/g, '$1'); + }; + // ----------------------------------------------------------------------- + // :: HISTORY CLASS + // ----------------------------------------------------------------------- + function History(name) { + var enabled = true; + if (typeof name === 'string' && name !== '') { + name += '_'; + } + var data = $.Storage.get(name + 'commands'); + var bc = new BCycle(data ? eval('(' + data + ')') : ['']); + + $.extend(this, { + append: function(item) { + if (enabled && bc.current() !== item) { + bc.append(item); + $.Storage.set(name + 'commands', $.json_stringify(bc.data())); + } + }, + data: function() { + return bc.data(); + }, + next: function() { + return bc.right(); + }, + last: function() { + bc.reset(); + }, + previous: function() { + return bc.left(); + }, + clear: function() { + bc = new BCycle(); + $.Storage.remove(name + 'commands'); + }, + enable: function() { + enabled = true; + }, + disable: function() { + enabled = false; + } + }); + } + // ----------------------------------------------------------------------- + // :: COMMAND LINE PLUGIN + // ----------------------------------------------------------------------- + $.fn.cmd = function(options) { + var self = this; + self.addClass('cmd'); + self.append('' + + ' '); + var clip = $('