diff --git a/json/modules.json b/json/modules.json index ba9ec419..95fbefaa 100644 --- a/json/modules.json +++ b/json/modules.json @@ -3,7 +3,7 @@ "menu", "view", "help", - "console", + "jq_console", "terminal", { "name": "storage", "data": [{ diff --git a/lib/client/jq_console.js b/lib/client/jq_console.js new file mode 100644 index 00000000..b1afb060 --- /dev/null +++ b/lib/client/jq_console.js @@ -0,0 +1,130 @@ +var CloudCmd, Util, DOM, $; +(function(CloudCmd, Util, DOM){ + 'use strict'; + + CloudCmd.Jq_console = new ConsoleProto(CloudCmd, Util, DOM); + + function ConsoleProto(CloudCmd, Util, DOM){ + var Name = 'Console', + Key = CloudCmd.Key, + Images = DOM.Images, + Console = this; + + this.init = function(pCallBack){ + Util.loadOnLoad([ + Console.show, + load, + CloudCmd.View, + DOM.jqueryLoad, + ]); + + DOM.Events.addKey(listener); + + delete Console.init; + }; + + this.show = function(){ + var lElement, jqconsole; + + Images.showLoad({top:true}); + + lElement = DOM.anyload({ + name : 'div', + className : 'console' + }); + + jqconsole = $(lElement).jqconsole('header', 'JS> '); + + // Abort prompt on Ctrl+Z. + jqconsole.RegisterShortcut('Z', function() { + jqconsole.AbortPrompt(); + handler(); + }); + + // Move to line start Ctrl+A. + jqconsole.RegisterShortcut('A', function() { + jqconsole.MoveToStart(); + handler(); + }); + + // Move to line end Ctrl+E. + jqconsole.RegisterShortcut('E', function() { + jqconsole.MoveToEnd(); + handler(); + }); + + jqconsole.RegisterMatching('{', '}', 'brace'); + jqconsole.RegisterMatching('(', ')', 'paran'); + jqconsole.RegisterMatching('[', ']', 'bracket'); + // Handle a command. + var handler = function(command) { + if (command) { + try { + jqconsole.Write('==> ' + window.eval(command) + '\n'); + } catch (e) { + jqconsole.Write('ERROR: ' + e.message + '\n'); + } + } + jqconsole.Prompt(true, handler, function(command) { + // Continue line if can't compile the command. + try { + Function(command); + } catch (e) { + if (/[\[\{\(]$/.test(command)) { + return 1; + } else { + return 0; + } + } + return false; + }); + }; + + // Initiate the first prompt. + handler(); + + + CloudCmd.View.show(lElement); + }; + + + this.hide = function(){ + CloudCmd.View.hide(); + }; + + function load(pCallBack){ + Util.time(Name + ' load'); + + var lDir = CloudCmd.LIBDIRCLIENT + 'terminal/jq-console/', + lFiles = [ + lDir + 'jqconsole.js', + lDir + 'jqconsole.css', + CloudCmd.LIBDIRCLIENT + 'terminal/jquery-terminal/jquery-migrate-1.0.0.js' + ]; + + DOM.anyLoadInParallel(lFiles, function(){ + console.timeEnd(Name + ' load'); + + Util.exec(pCallBack); + }); + } + + function listener(pEvent){ + var lF10 = Key.F10, + lESC = Key.ESC, + lIsBind = Key.isBind(), + lKey = pEvent.keyCode; + + switch(lKey){ + case lF10: + Console.show(); + break; + case lESC: + Console.hide(); + break; + } + + } + } + +})(CloudCmd, Util, DOM); \ No newline at end of file diff --git a/lib/client/terminal/jq-console/jqconsole.css b/lib/client/terminal/jq-console/jqconsole.css new file mode 100644 index 00000000..b5fb0696 --- /dev/null +++ b/lib/client/terminal/jq-console/jqconsole.css @@ -0,0 +1,45 @@ +#console { + height: 400px; + width: 750px; + position:relative; + background-color: black; + border: 2px solid #CCC; + margin: 0 auto; + margin-top: 50px; +} +.jqconsole { + padding: 10px; + padding-bottom: 10px; +} +.jqconsole-cursor { + background-color: #999; +} +.jqconsole-blurred .jqconsole-cursor { + background-color: #666; +} +.jqconsole-prompt { + color: #0d0; +} +.jqconsole-old-prompt { + color: #0b0; + font-weight: normal; +} +.jqconsole-input { + color: #dd0; +} +.jqconsole-old-input { + color: #bb0; + font-weight: normal; +} +.brace { + color: #00FFFF; +} +.paran { + color: #FF00FF; +} +.bracket { + color: #FFFF00; +} +.jqconsole-composition { + background-color: red; +} \ No newline at end of file diff --git a/lib/client/terminal/jq-console/jqconsole.js b/lib/client/terminal/jq-console/jqconsole.js new file mode 100644 index 00000000..dc1c0bfb --- /dev/null +++ b/lib/client/terminal/jq-console/jqconsole.js @@ -0,0 +1,1512 @@ +// Generated by CoffeeScript 1.3.3 + +/* +Copyrights 2011, the repl.it project. +Licensed under the MIT license +*/ + + +(function() { + var $, Ansi, CLASS_ANSI, CLASS_BLURRED, CLASS_CURSOR, CLASS_HEADER, CLASS_INPUT, CLASS_OLD_PROMPT, CLASS_PREFIX, CLASS_PROMPT, DEFAULT_INDENT_WIDTH, DEFAULT_PROMPT_CONINUE_LABEL, DEFAULT_PROMPT_LABEL, EMPTY_DIV, EMPTY_SELECTOR, EMPTY_SPAN, ESCAPE_CHAR, ESCAPE_SYNTAX, E_KEYPRESS, JQConsole, KEY_BACKSPACE, KEY_DELETE, KEY_DOWN, KEY_END, KEY_ENTER, KEY_HOME, KEY_LEFT, KEY_PAGE_DOWN, KEY_PAGE_UP, KEY_RIGHT, KEY_TAB, KEY_UP, NEWLINE, STATE_INPUT, STATE_OUTPUT, STATE_PROMPT, spanHtml, + __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __slice = [].slice; + + $ = jQuery; + + STATE_INPUT = 0; + + STATE_OUTPUT = 1; + + STATE_PROMPT = 2; + + KEY_ENTER = 13; + + KEY_TAB = 9; + + KEY_DELETE = 46; + + KEY_BACKSPACE = 8; + + KEY_LEFT = 37; + + KEY_RIGHT = 39; + + KEY_UP = 38; + + KEY_DOWN = 40; + + KEY_HOME = 36; + + KEY_END = 35; + + KEY_PAGE_UP = 33; + + KEY_PAGE_DOWN = 34; + + CLASS_PREFIX = 'jqconsole-'; + + CLASS_CURSOR = "" + CLASS_PREFIX + "cursor"; + + CLASS_HEADER = "" + CLASS_PREFIX + "header"; + + CLASS_PROMPT = "" + CLASS_PREFIX + "prompt"; + + CLASS_OLD_PROMPT = "" + CLASS_PREFIX + "old-prompt"; + + CLASS_INPUT = "" + CLASS_PREFIX + "input"; + + CLASS_BLURRED = "" + CLASS_PREFIX + "blurred"; + + E_KEYPRESS = 'keypress'; + + EMPTY_SPAN = ''; + + EMPTY_DIV = '
'; + + EMPTY_SELECTOR = ':empty'; + + NEWLINE = '\n'; + + DEFAULT_PROMPT_LABEL = '>>> '; + + DEFAULT_PROMPT_CONINUE_LABEL = '... '; + + DEFAULT_INDENT_WIDTH = 2; + + CLASS_ANSI = "" + CLASS_PREFIX + "ansi-"; + + ESCAPE_CHAR = '\x1B'; + + ESCAPE_SYNTAX = /\[(\d*)(?:;(\d*))*m/; + + Ansi = (function() { + + Ansi.prototype.COLORS = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']; + + function Ansi() { + this.stylize = __bind(this.stylize, this); + + this._closeSpan = __bind(this._closeSpan, this); + + this._openSpan = __bind(this._openSpan, this); + + this.getClasses = __bind(this.getClasses, this); + + this._style = __bind(this._style, this); + + this._color = __bind(this._color, this); + + this._remove = __bind(this._remove, this); + + this._append = __bind(this._append, this); + this.klasses = []; + } + + Ansi.prototype._append = function(klass) { + klass = "" + CLASS_ANSI + klass; + if (this.klasses.indexOf(klass) === -1) { + return this.klasses.push(klass); + } + }; + + Ansi.prototype._remove = function() { + var cls, klass, klasses, _i, _len, _results; + klasses = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + _results = []; + for (_i = 0, _len = klasses.length; _i < _len; _i++) { + klass = klasses[_i]; + if (klass === 'fonts' || klass === 'color' || klass === 'background-color') { + _results.push(this.klasses = (function() { + var _j, _len1, _ref, _results1; + _ref = this.klasses; + _results1 = []; + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + cls = _ref[_j]; + if (cls.indexOf(klass) !== CLASS_ANSI.length) { + _results1.push(cls); + } + } + return _results1; + }).call(this)); + } else { + klass = "" + CLASS_ANSI + klass; + _results.push(this.klasses = (function() { + var _j, _len1, _ref, _results1; + _ref = this.klasses; + _results1 = []; + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + cls = _ref[_j]; + if (cls !== klass) { + _results1.push(cls); + } + } + return _results1; + }).call(this)); + } + } + return _results; + }; + + Ansi.prototype._color = function(i) { + return this.COLORS[i]; + }; + + Ansi.prototype._style = function(code) { + if (code === '') { + code = 0; + } + code = parseInt(code); + if (isNaN(code)) { + return; + } + switch (code) { + case 0: + return this.klasses = []; + case 1: + return this._append('bold'); + case 2: + return this._append('lighter'); + case 3: + return this._append('italic'); + case 4: + return this._append('underline'); + case 5: + return this._append('blink'); + case 6: + return this._append('blink-rapid'); + case 8: + return this._append('hidden'); + case 9: + return this._append('line-through'); + case 10: + return this._remove('fonts'); + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + this._remove('fonts'); + return this._append("fonts-" + (code - 10)); + case 20: + return this._append('fraktur'); + case 21: + return this._remove('bold', 'lighter'); + case 22: + return this._remove('bold', 'lighter'); + case 23: + return this._remove('italic', 'fraktur'); + case 24: + return this._remove('underline'); + case 25: + return this._remove('blink', 'blink-rapid'); + case 28: + return this._remove('hidden'); + case 29: + return this._remove('line-through'); + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + this._remove('color'); + return this._append('color-' + this._color(code - 30)); + case 39: + return this._remove('color'); + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + this._remove('background-color'); + return this._append('background-color-' + this._color(code - 40)); + case 49: + return this._remove('background-color'); + case 51: + return this._append('framed'); + case 53: + return this._append('overline'); + case 54: + return this._remove('framed'); + case 55: + return this._remove('overline'); + } + }; + + Ansi.prototype.getClasses = function() { + return this.klasses.join(' '); + }; + + Ansi.prototype._openSpan = function(text) { + return "" + text; + }; + + Ansi.prototype._closeSpan = function(text) { + return "" + text + ""; + }; + + Ansi.prototype.stylize = function(text) { + var code, d, i, _i, _len, _ref; + text = this._openSpan(text); + i = 0; + while ((i = text.indexOf(ESCAPE_CHAR, i)) && i !== -1) { + if (d = text.slice(i).match(ESCAPE_SYNTAX)) { + _ref = d.slice(1); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + code = _ref[_i]; + this._style(code); + } + text = this._closeSpan(text.slice(0, i)) + this._openSpan(text.slice(i + 1 + d[0].length)); + } else { + i++; + } + } + return this._closeSpan(text); + }; + + return Ansi; + + })(); + + spanHtml = function(klass, content) { + return "" + (content || '') + ""; + }; + + JQConsole = (function() { + + function JQConsole(container, header, prompt_label, prompt_continue_label) { + this.container = container; + this._HideComposition = __bind(this._HideComposition, this); + + this._ShowComposition = __bind(this._ShowComposition, this); + + this._UpdateComposition = __bind(this._UpdateComposition, this); + + this._EndComposition = __bind(this._EndComposition, this); + + this._StartComposition = __bind(this._StartComposition, this); + + this._CheckComposition = __bind(this._CheckComposition, this); + + this._ProcessMatch = __bind(this._ProcessMatch, this); + + this._HandleKey = __bind(this._HandleKey, this); + + this._HandleChar = __bind(this._HandleChar, this); + + this.isMobile = !!navigator.userAgent.match(/iPhone|iPad|iPod|Android/i); + this.isIos = !!navigator.userAgent.match(/iPhone|iPad|iPod/i); + this.isAndroid = !!navigator.userAgent.match(/Android/i); + this.$window = $(window); + this.header = header || ''; + this.prompt_label_main = typeof prompt_label === 'string' ? prompt_label : DEFAULT_PROMPT_LABEL; + this.prompt_label_continue = prompt_continue_label || DEFAULT_PROMPT_CONINUE_LABEL; + this.indent_width = DEFAULT_INDENT_WIDTH; + this.state = STATE_OUTPUT; + this.input_queue = []; + this.input_callback = null; + this.multiline_callback = null; + this.history = []; + this.history_index = 0; + this.history_new = ''; + this.history_active = false; + this.shortcuts = {}; + this.$console = $('
').appendTo(this.container);
+      this.$console.css({
+        position: 'absolute',
+        top: 0,
+        bottom: 0,
+        right: 0,
+        left: 0,
+        margin: 0,
+        overflow: 'auto'
+      });
+      this.$console_focused = true;
+      this.$input_container = $(EMPTY_DIV).appendTo(this.container);
+      this.$input_container.css({
+        position: 'relative',
+        width: 1,
+        height: 0,
+        overflow: 'hidden'
+      });
+      this.$input_source = $('