UNPKG

horatio

Version:

A javascript compiler for the Shakespeare Programming Language

1,490 lines (1,356 loc) 48.5 kB
// Generated by CoffeeScript 1.6.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 = '<span/>'; EMPTY_DIV = '<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 "<span class=\"" + (this.getClasses()) + "\">" + text; }; Ansi.prototype._closeSpan = function(text) { return "" + text + "</span>"; }; 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 "<span class=\"" + klass + "\">" + (content || '') + "</span>"; }; JQConsole = (function() { function JQConsole(outer_container, header, prompt_label, prompt_continue_label) { 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.$container = $('<div/>').appendTo(outer_container); this.$container.css({ 'top': 0, 'left': 0, 'right': 0, 'bottom': 0, 'position': 'absolute', 'overflow': 'auto' }); this.$console = $('<pre class="jqconsole"/>').appendTo(this.$container); this.$console.css({ 'margin': 0, 'position': 'relative', 'min-height': '100%', 'box-sizing': 'border-box', '-moz-box-sizing': 'border-box', '-webkit-box-sizing': 'border-box' }); this.$console_focused = true; this.$input_container = $(EMPTY_DIV).appendTo(this.$container); this.$input_container.css({ position: 'absolute', width: 1, height: 0, overflow: 'hidden' }); this.$input_source = this.isAndroid ? $('<input/>') : $('<textarea/>'); this.$input_source.attr({ wrap: 'off', autocapitalize: 'off', autocorrect: 'off', spellcheck: 'false', autocomplete: 'off' }); this.$input_source.css({ position: 'absolute', width: 2 }); this.$input_source.appendTo(this.$input_container); this.$composition = $(EMPTY_DIV); this.$composition.addClass("" + CLASS_PREFIX + "composition"); this.$composition.css({ display: 'inline', position: 'relative' }); this.matchings = { openings: {}, closings: {}, clss: [] }; this.ansi = new Ansi(); this._InitPrompt(); this._SetupEvents(); this.Write(this.header, CLASS_HEADER); $(outer_container).data('jqconsole', this); } JQConsole.prototype.ResetHistory = function() { return this.SetHistory([]); }; JQConsole.prototype.ResetShortcuts = function() { return this.shortcuts = {}; }; JQConsole.prototype.ResetMatchings = function() { return this.matchings = { openings: {}, closings: {}, clss: [] }; }; JQConsole.prototype.Reset = function() { if (this.state !== STATE_OUTPUT) { this.ClearPromptText(true); } this.state = STATE_OUTPUT; this.input_queue = []; this.input_callback = null; this.multiline_callback = null; this.ResetHistory(); this.ResetShortcuts(); this.ResetMatchings(); this.$prompt.detach(); this.$input_container.detach(); this.$console.html(''); this.$prompt.appendTo(this.$console); this.$input_container.appendTo(this.$container); this.Write(this.header, CLASS_HEADER); return void 0; }; JQConsole.prototype.GetHistory = function() { return this.history; }; JQConsole.prototype.SetHistory = function(history) { this.history = history.slice(); return this.history_index = this.history.length; }; /*------------------------ Shortcut Methods -----------------------------*/ JQConsole.prototype._CheckKeyCode = function(key_code) { if (isNaN(key_code)) { key_code = key_code.charCodeAt(0); } else { key_code = parseInt(key_code, 10); } if (!((0 < key_code && key_code < 256)) || isNaN(key_code)) { throw new Error('Key code must be a number between 0 and 256 exclusive.'); } return key_code; }; JQConsole.prototype._LetterCaseHelper = function(key_code, callback) { callback(key_code); if ((65 <= key_code && key_code <= 90)) { callback(key_code + 32); } if ((97 <= key_code && key_code <= 122)) { return callback(key_code - 32); } }; JQConsole.prototype.RegisterShortcut = function(key_code, callback) { var addShortcut, _this = this; key_code = this._CheckKeyCode(key_code); if (typeof callback !== 'function') { throw new Error('Callback must be a function, not ' + callback + '.'); } addShortcut = function(key) { if (!(key in _this.shortcuts)) { _this.shortcuts[key] = []; } return _this.shortcuts[key].push(callback); }; this._LetterCaseHelper(key_code, addShortcut); return void 0; }; JQConsole.prototype.UnRegisterShortcut = function(key_code, handler) { var removeShortcut, _this = this; key_code = this._CheckKeyCode(key_code); removeShortcut = function(key) { if (key in _this.shortcuts) { if (handler) { return _this.shortcuts[key].splice(_this.shortcuts[key].indexOf(handler), 1); } else { return delete _this.shortcuts[key]; } } }; this._LetterCaseHelper(key_code, removeShortcut); return void 0; }; /*---------------------- END Shortcut Methods ---------------------------*/ JQConsole.prototype.GetColumn = function() { var lines; this.$prompt_right.detach(); this.$prompt_cursor.text(''); lines = this.$console.text().split(NEWLINE); this.$prompt_cursor.html('&nbsp;'); this.$prompt_cursor.after(this.$prompt_right); return lines[lines.length - 1].length; }; JQConsole.prototype.GetLine = function() { return this.$console.text().split(NEWLINE).length - 1; }; JQConsole.prototype.ClearPromptText = function(clear_label) { if (this.state === STATE_OUTPUT) { throw new Error('ClearPromptText() is not allowed in output state.'); } this.$prompt_before.html(''); this.$prompt_after.html(''); this.$prompt_label.text(clear_label ? '' : this._SelectPromptLabel(false)); this.$prompt_left.text(''); this.$prompt_right.text(''); return void 0; }; JQConsole.prototype.GetPromptText = function(full) { var after, before, current, getPromptLines, text; if (this.state === STATE_OUTPUT) { throw new Error('GetPromptText() is not allowed in output state.'); } if (full) { this.$prompt_cursor.text(''); text = this.$prompt.text(); this.$prompt_cursor.html('&nbsp;'); return text; } else { getPromptLines = function(node) { var buffer; buffer = []; node.children().each(function() { return buffer.push($(this).children().last().text()); }); return buffer.join(NEWLINE); }; before = getPromptLines(this.$prompt_before); if (before) { before += NEWLINE; } current = this.$prompt_left.text() + this.$prompt_right.text(); after = getPromptLines(this.$prompt_after); if (after) { after = NEWLINE + after; } return before + current + after; } }; JQConsole.prototype.SetPromptText = function(text) { if (this.state === STATE_OUTPUT) { throw new Error('SetPromptText() is not allowed in output state.'); } this.ClearPromptText(false); this._AppendPromptText(text); this._ScrollToEnd(); return void 0; }; JQConsole.prototype.SetPromptLabel = function(main_label, continue_label) { this.prompt_label_main = main_label; if (continue_label != null) { this.prompt_label_continue = continue_label; } return void 0; }; JQConsole.prototype.Write = function(text, cls, escape) { var span; if (escape == null) { escape = true; } if (escape) { text = this.ansi.stylize($(EMPTY_SPAN).text(text).html()); } span = $(EMPTY_SPAN).html(text); if (cls != null) { span.addClass(cls); } return this.Append(span); }; JQConsole.prototype.Append = function(node) { var $node; $node = $(node).insertBefore(this.$prompt); this._ScrollToEnd(); this.$prompt_cursor.detach().insertAfter(this.$prompt_left); return $node; }; JQConsole.prototype.Input = function(input_callback) { var current_async_multiline, current_history_active, current_input_callback, current_multiline_callback, _this = this; if (this.state === STATE_PROMPT) { current_input_callback = this.input_callback; current_multiline_callback = this.multiline_callback; current_history_active = this.history_active; current_async_multiline = this.async_multiline; this.AbortPrompt(); this.input_queue.unshift(function() { return _this.Prompt(current_history_active, current_input_callback, current_multiline_callback, current_async_multiline); }); } else if (this.state !== STATE_OUTPUT) { this.input_queue.push(function() { return _this.Input(input_callback); }); return; } this.history_active = false; this.input_callback = input_callback; this.multiline_callback = null; this.state = STATE_INPUT; this.$prompt.attr('class', CLASS_INPUT); this.$prompt_label.text(this._SelectPromptLabel(false)); this.Focus(); this._ScrollToEnd(); return void 0; }; JQConsole.prototype.Prompt = function(history_enabled, result_callback, multiline_callback, async_multiline) { var _this = this; if (this.state !== STATE_OUTPUT) { this.input_queue.push(function() { return _this.Prompt(history_enabled, result_callback, multiline_callback, async_multiline); }); return; } this.history_active = history_enabled; this.input_callback = result_callback; this.multiline_callback = multiline_callback; this.async_multiline = async_multiline; this.state = STATE_PROMPT; this.$prompt.attr('class', CLASS_PROMPT + ' ' + this.ansi.getClasses()); this.$prompt_label.text(this._SelectPromptLabel(false)); this.Focus(); this._ScrollToEnd(); return void 0; }; JQConsole.prototype.AbortPrompt = function() { if (this.state !== STATE_PROMPT) { throw new Error('Cannot abort prompt when not in prompt state.'); } this.Write(this.GetPromptText(true) + NEWLINE, CLASS_OLD_PROMPT); this.ClearPromptText(true); this.state = STATE_OUTPUT; this.input_callback = this.multiline_callback = null; this._CheckInputQueue(); return void 0; }; JQConsole.prototype.Focus = function() { if (!this.IsDisabled()) { this.$input_source.focus(); } return void 0; }; JQConsole.prototype.SetIndentWidth = function(width) { return this.indent_width = width; }; JQConsole.prototype.GetIndentWidth = function() { return this.indent_width; }; JQConsole.prototype.RegisterMatching = function(open, close, cls) { var match_config; match_config = { opening_char: open, closing_char: close, cls: cls }; this.matchings.clss.push(cls); this.matchings.openings[open] = match_config; return this.matchings.closings[close] = match_config; }; JQConsole.prototype.UnRegisterMatching = function(open, close) { var cls; cls = this.matchings.openings[open].cls; delete this.matchings.openings[open]; delete this.matchings.closings[close]; return this.matchings.clss.splice(this.matchings.clss.indexOf(cls), 1); }; JQConsole.prototype.Dump = function() { var $elems, elem; $elems = this.$console.find("." + CLASS_HEADER).nextUntil("." + CLASS_PROMPT).addBack(); return ((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = $elems.length; _i < _len; _i++) { elem = $elems[_i]; if ($(elem).is("." + CLASS_OLD_PROMPT)) { _results.push($(elem).text().replace(/^\s+/, '>>> ')); } else { _results.push($(elem).text()); } } return _results; })()).join(''); }; JQConsole.prototype.GetState = function() { if (this.state === STATE_INPUT) { return 'input'; } else if (this.state === STATE_OUTPUT) { return 'output'; } else { return 'prompt'; } }; JQConsole.prototype.Disable = function() { this.$input_source.attr('disabled', true); return this.$input_source.blur(); }; JQConsole.prototype.Enable = function() { return this.$input_source.attr('disabled', false); }; JQConsole.prototype.IsDisabled = function() { return Boolean(this.$input_source.attr('disabled')); }; JQConsole.prototype.MoveToStart = function(all_lines) { this._MoveTo(all_lines, true); return void 0; }; JQConsole.prototype.MoveToEnd = function(all_lines) { this._MoveTo(all_lines, false); return void 0; }; JQConsole.prototype.Clear = function() { this.$console.find("." + CLASS_HEADER).nextUntil("." + CLASS_PROMPT).addBack().text(''); this.$prompt_cursor.detach(); return this.$prompt_after.before(this.$prompt_cursor); }; /*------------------------ Private Methods -------------------------------*/ JQConsole.prototype._CheckInputQueue = function() { if (this.input_queue.length) { return this.input_queue.shift()(); } }; JQConsole.prototype._InitPrompt = function() { this.$prompt = $(spanHtml(CLASS_INPUT)).appendTo(this.$console); this.$prompt_before = $(EMPTY_SPAN).appendTo(this.$prompt); this.$prompt_current = $(EMPTY_SPAN).appendTo(this.$prompt); this.$prompt_after = $(EMPTY_SPAN).appendTo(this.$prompt); this.$prompt_label = $(EMPTY_SPAN).appendTo(this.$prompt_current); this.$prompt_left = $(EMPTY_SPAN).appendTo(this.$prompt_current); this.$prompt_right = $(EMPTY_SPAN).appendTo(this.$prompt_current); this.$prompt_right.css({ position: 'relative' }); this.$prompt_cursor = $(spanHtml(CLASS_CURSOR, '&nbsp;')); this.$prompt_cursor.insertBefore(this.$prompt_right); this.$prompt_cursor.css({ color: 'transparent', display: 'inline', zIndex: 0 }); if (!this.isMobile) { return this.$prompt_cursor.css('position', 'absolute'); } }; JQConsole.prototype._SetupEvents = function() { var _this = this; if (this.isMobile) { this.$console.click(function(e) { e.preventDefault(); return _this.Focus(); }); } else { this.$console.mouseup(function(e) { var fn; if (e.which === 2) { return _this.Focus(); } else { fn = function() { if (!window.getSelection().toString()) { e.preventDefault(); return _this.Focus(); } }; return setTimeout(fn, 0); } }); } this.$input_source.focus(function() { var hideTextInput, removeClass; _this._ScrollToEnd(); _this.$console_focused = true; _this.$console.removeClass(CLASS_BLURRED); removeClass = function() { if (_this.$console_focused) { return _this.$console.removeClass(CLASS_BLURRED); } }; setTimeout(removeClass, 100); hideTextInput = function() { if (_this.isIos && _this.$console_focused) { return _this.$input_source.hide(); } }; return setTimeout(hideTextInput, 500); }); this.$input_source.blur(function() { var addClass; _this.$console_focused = false; if (_this.isIos) { _this.$input_source.show(); } addClass = function() { if (!_this.$console_focused) { return _this.$console.addClass(CLASS_BLURRED); } }; return setTimeout(addClass, 100); }); this.$input_source.bind('paste', function() { var handlePaste; handlePaste = function() { if (_this.in_composition) { return; } _this._AppendPromptText(_this.$input_source.val()); _this.$input_source.val(''); return _this.Focus(); }; return setTimeout(handlePaste, 0); }); this.$input_source.keypress(this._HandleChar); this.$input_source.keydown(this._HandleKey); this.$input_source.keydown(this._CheckComposition); this.$input_source.bind('compositionstart', this._StartComposition); this.$input_source.bind('compositionend', function(e) { return setTimeout((function() { return _this._EndComposition(e); }), 0); }); if (this.isAndroid) { this.$input_source.bind('input', this._StartComposition); return this.$input_source.bind('input', this._UpdateComposition); } else { return this.$input_source.bind('text', this._UpdateComposition); } }; JQConsole.prototype._HandleChar = function(event) { var char_code; if (this.state === STATE_OUTPUT || event.metaKey || event.ctrlKey) { return true; } char_code = event.which; if (char_code === 8 || char_code === 9 || char_code === 13) { return false; } this.$prompt_left.text(this.$prompt_left.text() + String.fromCharCode(char_code)); this._ScrollToEnd(); return false; }; JQConsole.prototype._HandleKey = function(event) { var key; if (this.state === STATE_OUTPUT) { return true; } key = event.keyCode || event.which; setTimeout($.proxy(this._CheckMatchings, this), 0); if (event.altKey) { return true; } else if (event.ctrlKey || event.metaKey) { return this._HandleCtrlShortcut(key); } else if (event.shiftKey) { switch (key) { case KEY_ENTER: this._HandleEnter(true); break; case KEY_TAB: this._Unindent(); break; case KEY_UP: this._MoveUp(); break; case KEY_DOWN: this._MoveDown(); break; case KEY_PAGE_UP: this._ScrollPage('up'); break; case KEY_PAGE_DOWN: this._ScrollPage('down'); break; default: return true; } return false; } else { switch (key) { case KEY_ENTER: this._HandleEnter(false); break; case KEY_TAB: this._Indent(); break; case KEY_DELETE: this._Delete(false); break; case KEY_BACKSPACE: this._Backspace(false); break; case KEY_LEFT: this._MoveLeft(false); break; case KEY_RIGHT: this._MoveRight(false); break; case KEY_UP: this._HistoryPrevious(); break; case KEY_DOWN: this._HistoryNext(); break; case KEY_HOME: this.MoveToStart(false); break; case KEY_END: this.MoveToEnd(false); break; case KEY_PAGE_UP: this._ScrollPage('up'); break; case KEY_PAGE_DOWN: this._ScrollPage('down'); break; default: return true; } return false; } }; JQConsole.prototype._HandleCtrlShortcut = function(key) { var handler, _i, _len, _ref; switch (key) { case KEY_DELETE: this._Delete(true); break; case KEY_BACKSPACE: this._Backspace(true); break; case KEY_LEFT: this._MoveLeft(true); break; case KEY_RIGHT: this._MoveRight(true); break; case KEY_UP: this._MoveUp(); break; case KEY_DOWN: this._MoveDown(); break; case KEY_END: this.MoveToEnd(true); break; case KEY_HOME: this.MoveToStart(true); break; default: if (key in this.shortcuts) { _ref = this.shortcuts[key]; for (_i = 0, _len = _ref.length; _i < _len; _i++) { handler = _ref[_i]; handler.call(this); } return false; } else { return true; } } return false; }; JQConsole.prototype._HandleEnter = function(shift) { var continuation, text, _this = this; this._EndComposition(); if (shift) { return this._InsertNewLine(true); } else { text = this.GetPromptText(); continuation = function(indent) { var callback, cls_suffix, _, _i, _ref, _results; if (indent !== false) { _this.MoveToEnd(true); _this._InsertNewLine(true); _results = []; for (_ = _i = 0, _ref = Math.abs(indent); 0 <= _ref ? _i < _ref : _i > _ref; _ = 0 <= _ref ? ++_i : --_i) { if (indent > 0) { _results.push(_this._Indent()); } else { _results.push(_this._Unindent()); } } return _results; } else { cls_suffix = _this.state === STATE_INPUT ? 'input' : 'prompt'; _this.Write(_this.GetPromptText(true) + NEWLINE, ("" + CLASS_PREFIX + "old-") + cls_suffix); _this.ClearPromptText(true); if (_this.history_active) { if (!_this.history.length || _this.history[_this.history.length - 1] !== text) { _this.history.push(text); } _this.history_index = _this.history.length; } _this.state = STATE_OUTPUT; callback = _this.input_callback; _this.input_callback = null; if (callback) { callback(text); } return _this._CheckInputQueue(); } }; if (this.multiline_callback) { if (this.async_multiline) { return this.multiline_callback(text, continuation); } else { return continuation(this.multiline_callback(text)); } } else { return continuation(false); } } }; JQConsole.prototype._GetDirectionals = function(back) { var $prompt_opposite, $prompt_rel_opposite, $prompt_relative, $prompt_which, MoveDirection, MoveToLimit, where_append, which_end; $prompt_which = back ? this.$prompt_left : this.$prompt_right; $prompt_opposite = back ? this.$prompt_right : this.$prompt_left; $prompt_relative = back ? this.$prompt_before : this.$prompt_after; $prompt_rel_opposite = back ? this.$prompt_after : this.$prompt_before; MoveToLimit = back ? $.proxy(this.MoveToStart, this) : $.proxy(this.MoveToEnd, this); MoveDirection = back ? $.proxy(this._MoveLeft, this) : $.proxy(this._MoveRight, this); which_end = back ? 'last' : 'first'; where_append = back ? 'prependTo' : 'appendTo'; return { $prompt_which: $prompt_which, $prompt_opposite: $prompt_opposite, $prompt_relative: $prompt_relative, $prompt_rel_opposite: $prompt_rel_opposite, MoveToLimit: MoveToLimit, MoveDirection: MoveDirection, which_end: which_end, where_append: where_append }; }; JQConsole.prototype._VerticalMove = function(up) { var $prompt_opposite, $prompt_relative, $prompt_which, MoveDirection, MoveToLimit, pos, text, _ref; _ref = this._GetDirectionals(up), $prompt_which = _ref.$prompt_which, $prompt_opposite = _ref.$prompt_opposite, $prompt_relative = _ref.$prompt_relative, MoveToLimit = _ref.MoveToLimit, MoveDirection = _ref.MoveDirection; if ($prompt_relative.is(EMPTY_SELECTOR)) { return; } pos = this.$prompt_left.text().length; MoveToLimit(); MoveDirection(); text = $prompt_which.text(); $prompt_opposite.text(up ? text.slice(pos) : text.slice(0, pos)); return $prompt_which.text(up ? text.slice(0, pos) : text.slice(pos)); }; JQConsole.prototype._MoveUp = function() { return this._VerticalMove(true); }; JQConsole.prototype._MoveDown = function() { return this._VerticalMove(); }; JQConsole.prototype._HorizontalMove = function(whole_word, back) { var $opposite_line, $prompt_opposite, $prompt_rel_opposite, $prompt_relative, $prompt_which, $which_line, len, regexp, text, tmp, where_append, which_end, word, _ref; _ref = this._GetDirectionals(back), $prompt_which = _ref.$prompt_which, $prompt_opposite = _ref.$prompt_opposite, $prompt_relative = _ref.$prompt_relative, $prompt_rel_opposite = _ref.$prompt_rel_opposite, which_end = _ref.which_end, where_append = _ref.where_append; regexp = back ? /\w*\W*$/ : /^\w*\W*/; text = $prompt_which.text(); if (text) { if (whole_word) { word = text.match(regexp); if (!word) { return; } word = word[0]; tmp = $prompt_opposite.text(); $prompt_opposite.text(back ? word + tmp : tmp + word); len = word.length; return $prompt_which.text(back ? text.slice(0, -len) : text.slice(len)); } else { tmp = $prompt_opposite.text(); $prompt_opposite.text(back ? text.slice(-1) + tmp : tmp + text[0]); return $prompt_which.text(back ? text.slice(0, -1) : text.slice(1)); } } else if (!$prompt_relative.is(EMPTY_SELECTOR)) { $which_line = $(EMPTY_SPAN)[where_append]($prompt_rel_opposite); $which_line.append($(EMPTY_SPAN).text(this.$prompt_label.text())); $which_line.append($(EMPTY_SPAN).text($prompt_opposite.text())); $opposite_line = $prompt_relative.children()[which_end]().detach(); this.$prompt_label.text($opposite_line.children().first().text()); $prompt_which.text($opposite_line.children().last().text()); return $prompt_opposite.text(''); } }; JQConsole.prototype._MoveLeft = function(whole_word) { return this._HorizontalMove(whole_word, true); }; JQConsole.prototype._MoveRight = function(whole_word) { return this._HorizontalMove(whole_word); }; JQConsole.prototype._MoveTo = function(all_lines, back) { var $prompt_opposite, $prompt_relative, $prompt_which, MoveDirection, MoveToLimit, _ref, _results; _ref = this._GetDirectionals(back), $prompt_which = _ref.$prompt_which, $prompt_opposite = _ref.$prompt_opposite, $prompt_relative = _ref.$prompt_relative, MoveToLimit = _ref.MoveToLimit, MoveDirection = _ref.MoveDirection; if (all_lines) { _results = []; while (!($prompt_relative.is(EMPTY_SELECTOR) && $prompt_which.text() === '')) { MoveToLimit(false); _results.push(MoveDirection(false)); } return _results; } else { $prompt_opposite.text(this.$prompt_left.text() + this.$prompt_right.text()); return $prompt_which.text(''); } }; JQConsole.prototype._Delete = function(whole_word) { var $lower_line, text, word; text = this.$prompt_right.text(); if (text) { if (whole_word) { word = text.match(/^\w*\W*/); if (!word) { return; } word = word[0]; return this.$prompt_right.text(text.slice(word.length)); } else { return this.$prompt_right.text(text.slice(1)); } } else if (!this.$prompt_after.is(EMPTY_SELECTOR)) { $lower_line = this.$prompt_after.children().first().detach(); return this.$prompt_right.text($lower_line.children().last().text()); } }; JQConsole.prototype._Backspace = function(whole_word) { var $upper_line, text, word; setTimeout($.proxy(this._ScrollToEnd, this), 0); text = this.$prompt_left.text(); if (text) { if (whole_word) { word = text.match(/\w*\W*$/); if (!word) { return; } word = word[0]; return this.$prompt_left.text(text.slice(0, -word.length)); } else { return this.$prompt_left.text(text.slice(0, -1)); } } else if (!this.$prompt_before.is(EMPTY_SELECTOR)) { $upper_line = this.$prompt_before.children().last().detach(); this.$prompt_label.text($upper_line.children().first().text()); return this.$prompt_left.text($upper_line.children().last().text()); } }; JQConsole.prototype._Indent = function() { var _; return this.$prompt_left.prepend(((function() { var _i, _ref, _results; _results = []; for (_ = _i = 1, _ref = this.indent_width; 1 <= _ref ? _i <= _ref : _i >= _ref; _ = 1 <= _ref ? ++_i : --_i) { _results.push(' '); } return _results; }).call(this)).join('')); }; JQConsole.prototype._Unindent = function() { var line_text, _, _i, _ref, _results; line_text = this.$prompt_left.text() + this.$prompt_right.text(); _results = []; for (_ = _i = 1, _ref = this.indent_width; 1 <= _ref ? _i <= _ref : _i >= _ref; _ = 1 <= _ref ? ++_i : --_i) { if (!/^ /.test(line_text)) { break; } if (this.$prompt_left.text()) { this.$prompt_left.text(this.$prompt_left.text().slice(1)); } else { this.$prompt_right.text(this.$prompt_right.text().slice(1)); } _results.push(line_text = line_text.slice(1)); } return _results; }; JQConsole.prototype._InsertNewLine = function(indent) { var $old_line, match, old_prompt; if (indent == null) { indent = false; } old_prompt = this._SelectPromptLabel(!this.$prompt_before.is(EMPTY_SELECTOR)); $old_line = $(EMPTY_SPAN).appendTo(this.$prompt_before); $old_line.append($(EMPTY_SPAN).text(old_prompt)); $old_line.append($(EMPTY_SPAN).text(this.$prompt_left.text())); this.$prompt_label.text(this._SelectPromptLabel(true)); if (indent && (match = this.$prompt_left.text().match(/^\s+/))) { this.$prompt_left.text(match[0]); } else { this.$prompt_left.text(''); } return this._ScrollToEnd(); }; JQConsole.prototype._AppendPromptText = function(text) { var line, lines, _i, _len, _ref, _results; lines = text.split(NEWLINE); this.$prompt_left.text(this.$prompt_left.text() + lines[0]); _ref = lines.slice(1); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { line = _ref[_i]; this._InsertNewLine(); _results.push(this.$prompt_left.text(line)); } return _results; }; JQConsole.prototype._ScrollPage = function(dir) { var target; target = this.$container[0].scrollTop; if (dir === 'up') { target -= this.$container.height(); } else { target += this.$container.height(); } return this.$container.stop().animate({ scrollTop: target }, 'fast'); }; JQConsole.prototype._ScrollToEnd = function() { var pos; this.$container.scrollTop(this.$container[0].scrollHeight); pos = this.$prompt_cursor.position(); this.$input_container.css({ left: pos.left, top: pos.top }); return setTimeout(this.ScrollWindowToPrompt.bind(this), 50); }; JQConsole.prototype.ScrollWindowToPrompt = function() { var doc_height, line_height, optimal_pos, pos, screen_left, screen_top; line_height = this.$prompt_cursor.height(); screen_top = this.$window.scrollTop(); screen_left = this.$window.scrollLeft(); doc_height = document.documentElement.clientHeight; pos = this.$prompt_cursor.offset(); optimal_pos = pos.top - (2 * line_height); if (this.isMobile && (typeof orientation !== "undefined" && orientation !== null)) { if (screen_top < pos.top || screen_top > pos.top) { return this.$window.scrollTop(optimal_pos); } } else { if (screen_top + doc_height < pos.top) { return this.$window.scrollTop(pos.top - doc_height + line_height); } else if (screen_top > optimal_pos) { return this.$window.scrollTop(pos.top); } } }; JQConsole.prototype._SelectPromptLabel = function(continuation) { if (this.state === STATE_PROMPT) { if (continuation) { return ' \n' + this.prompt_label_continue; } else { return this.prompt_label_main; } } else { if (continuation) { return '\n '; } else { return ' '; } } }; JQConsole.prototype._Wrap = function($elem, index, cls) { var html, text; text = $elem.html(); html = text.slice(0, index) + spanHtml(cls, text[index]) + text.slice(index + 1); return $elem.html(html); }; JQConsole.prototype._WalkCharacters = function(text, char, opposing_char, current_count, back) { var ch, index, read_char; index = back ? text.length : 0; text = text.split(''); read_char = function() { var ret, _i, _ref, _ref1; if (back) { _ref = text, text = 2 <= _ref.length ? __slice.call(_ref, 0, _i = _ref.length - 1) : (_i = 0, []), ret = _ref[_i++]; } else { _ref1 = text, ret = _ref1[0], text = 2 <= _ref1.length ? __slice.call(_ref1, 1) : []; } if (ret) { index = index + (back ? -1 : +1); } return ret; }; while (ch = read_char()) { if (ch === char) { current_count++; } else if (ch === opposing_char) { current_count--; } if (current_count === 0) { return { index: index, current_count: current_count }; } } return { index: -1, current_count: current_count }; }; JQConsole.prototype._ProcessMatch = function(config, back, before_char) { var $collection, $prompt_relative, $prompt_which, char, current_count, found, index, opposing_char, text, _ref, _ref1, _ref2, _this = this; _ref = back ? [config['closing_char'], config['opening_char']] : [config['opening_char'], config['closing_char']], char = _ref[0], opposing_char = _ref[1]; _ref1 = this._GetDirectionals(back), $prompt_which = _ref1.$prompt_which, $prompt_relative = _ref1.$prompt_relative; current_count = 1; found = false; text = $prompt_which.html(); if (!back) { text = text.slice(1); } if (before_char && back) { text = text.slice(0, -1); } _ref2 = this._WalkCharacters(text, char, opposing_char, current_count, back), index = _ref2.index, current_count = _ref2.current_count; if (index > -1) { this._Wrap($prompt_which, index, config.cls); found = true; } else { $collection = $prompt_relative.children(); $collection = back ? Array.prototype.reverse.call($collection) : $collection; $collection.each(function(i, elem) { var $elem, _ref3; $elem = $(elem).children().last(); text = $elem.html(); _ref3 = _this._WalkCharacters(text, char, opposing_char, current_count, back), index = _ref3.index, current_count = _ref3.current_count; if (index > -1) { if (!back) { index--; } _this._Wrap($elem, index, config.cls); found = true; return false; } }); } return found; }; JQConsole.prototype._CheckMatchings = function(before_char) { var cls, config, current_char, found, _i, _len, _ref; current_char = before_char ? this.$prompt_left.text().slice(this.$prompt_left.text().length - 1) : this.$prompt_right.text()[0]; _ref = this.matchings.clss; for (_i = 0, _len = _ref.length; _i < _len; _i++) { cls = _ref[_i]; $('.' + cls, this.$console).contents().unwrap(); } if (config = this.matchings.closings[current_char]) { found = this._ProcessMatch(config, true, before_char); } else if (config = this.matchings.openings[current_char]) { found = this._ProcessMatch(config, false, before_char); } else if (!before_char) { this._CheckMatchings(true); } if (before_char) { if (found) { return this._Wrap(this.$prompt_left, this.$prompt_left.html().length - 1, config.cls); } } else { if (found) { return this._Wrap(this.$prompt_right, 0, config.cls); } } }; JQConsole.prototype._HistoryPrevious = function() { if (!this.history_active) { return; } if (this.history_index <= 0) { return; } if (this.history_index === this.history.length) { this.history_new = this.GetPromptText(); } return this.SetPromptText(this.history[--this.history_index]); }; JQConsole.prototype._HistoryNext = function() { if (!this.history_active) { return; } if (this.history_index >= this.history.length) { return; } if (this.history_index === this.history.length - 1) { this.history_index++; return this.SetPromptText(this.history_new); } else { return this.SetPromptText(this.history[++this.history_index]); } }; JQConsole.prototype._CheckComposition = function(e) { var key; key = e.keyCode || e.which; if (key === 229) { if (this.in_composition) { return this._UpdateComposition(); } else { return this._StartComposition(); } } }; JQConsole.prototype._StartComposition = function() { if (this.in_composition) { return; } this.in_composition = true; this._ShowComposition(); return setTimeout(this._UpdateComposition, 0); }; JQConsole.prototype._EndComposition = function() { if (!this.in_composition) { return; } this._HideComposition(); this.$prompt_left.text(this.$prompt_left.text() + this.$composition.text()); this.$composition.text(''); this.$input_source.val(''); return this.in_composition = false; }; JQConsole.prototype._UpdateComposition = function(e) { var cb, _this = this; cb = function() { if (!_this.in_composition) { return; } return _this.$composition.text(_this.$input_source.val()); }; return setTimeout(cb, 0); }; JQConsole.prototype._ShowComposition = function() { this.$composition.css('height', this.$prompt_cursor.height()); this.$composition.empty(); return this.$composition.appendTo(this.$prompt_left); }; JQConsole.prototype._HideComposition = function() { return this.$composition.detach(); }; return JQConsole; })(); $.fn.jqconsole = function(header, prompt_main, prompt_continue) { return new JQConsole(this, header, prompt_main, prompt_continue); }; $.fn.jqconsole.JQConsole = JQConsole; $.fn.jqconsole.Ansi = Ansi; }).call(this);