opal-irb 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.gitignore +3 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +14 -0
  5. data/Gemfile.lock +113 -0
  6. data/Guardfile +5 -0
  7. data/LICENSE +21 -0
  8. data/README.md +175 -0
  9. data/Rakefile +65 -0
  10. data/Roadmap.org +17 -0
  11. data/app/assets/stylesheets/opal-irb/jqconsole.css +263 -0
  12. data/compiled/app-embeddable.js +39765 -0
  13. data/compiled/app-jqconsole.js +39767 -0
  14. data/compiled/application.js +27399 -0
  15. data/css/ansi.css +172 -0
  16. data/css/opal_irb_jqconsole.css +79 -0
  17. data/css/show-hint.css +38 -0
  18. data/doc/presentations/opal_irb_overview.html +678 -0
  19. data/doc/presentations/opal_irb_overview.org +448 -0
  20. data/examples/app-embeddable.rb +8 -0
  21. data/examples/app-jqconsole.rb +10 -0
  22. data/examples/application.rb +8 -0
  23. data/index-embeddable.html +29 -0
  24. data/index-homebrew.html +115 -0
  25. data/index-jq.html +80 -0
  26. data/js/anyword-hint.js +44 -0
  27. data/js/jqconsole.js +1583 -0
  28. data/js/nodeutil.js +546 -0
  29. data/js/ruby.js +285 -0
  30. data/js/show-hint.js +383 -0
  31. data/lib/opal-irb/rails_engine.rb +3 -0
  32. data/lib/opal-irb/version.rb +3 -0
  33. data/lib/opal-irb-rails.rb +2 -0
  34. data/lib/opal-irb.rb +44 -0
  35. data/opal/object_extensions.rb +20 -0
  36. data/opal/opal_irb/completion_engine.rb +202 -0
  37. data/opal/opal_irb/completion_formatter.rb +49 -0
  38. data/opal/opal_irb/completion_results.rb +88 -0
  39. data/opal/opal_irb.rb +88 -0
  40. data/opal/opal_irb_homebrew_console.rb +398 -0
  41. data/opal/opal_irb_jqconsole.rb +517 -0
  42. data/opal/opal_irb_jqconsole_css.rb +259 -0
  43. data/opal/opal_irb_log_redirector.rb +32 -0
  44. data/opal/opal_phantomjs.rb +49 -0
  45. data/opal-irb.gemspec +20 -0
  46. data/spec/code_link_handler_spec.rb +30 -0
  47. data/spec/jquery.js +5 -0
  48. data/spec/object_extensions_spec.rb +32 -0
  49. data/spec/opal_irb/completion_engine_spec.rb +204 -0
  50. data/spec/opal_irb/completion_results_spec.rb +32 -0
  51. data/spec/opal_irb_log_director_spec.rb +19 -0
  52. data/spec/opal_irb_spec.rb +19 -0
  53. data/spec/spec_helper.rb +1 -0
  54. metadata +151 -0
data/js/jqconsole.js ADDED
@@ -0,0 +1,1583 @@
1
+ // Generated by CoffeeScript 1.7.1
2
+
3
+ /*
4
+ Copyrights 2011, the repl.it project.
5
+ Licensed under the MIT license
6
+ */
7
+
8
+ (function() {
9
+ 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,
10
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
11
+ __slice = [].slice;
12
+
13
+ $ = jQuery;
14
+
15
+ STATE_INPUT = 0;
16
+
17
+ STATE_OUTPUT = 1;
18
+
19
+ STATE_PROMPT = 2;
20
+
21
+ KEY_ENTER = 13;
22
+
23
+ KEY_TAB = 9;
24
+
25
+ KEY_DELETE = 46;
26
+
27
+ KEY_BACKSPACE = 8;
28
+
29
+ KEY_LEFT = 37;
30
+
31
+ KEY_RIGHT = 39;
32
+
33
+ KEY_UP = 38;
34
+
35
+ KEY_DOWN = 40;
36
+
37
+ KEY_HOME = 36;
38
+
39
+ KEY_END = 35;
40
+
41
+ KEY_PAGE_UP = 33;
42
+
43
+ KEY_PAGE_DOWN = 34;
44
+
45
+ CLASS_PREFIX = 'jqconsole-';
46
+
47
+ CLASS_CURSOR = "" + CLASS_PREFIX + "cursor";
48
+
49
+ CLASS_HEADER = "" + CLASS_PREFIX + "header";
50
+
51
+ CLASS_PROMPT = "" + CLASS_PREFIX + "prompt";
52
+
53
+ CLASS_OLD_PROMPT = "" + CLASS_PREFIX + "old-prompt";
54
+
55
+ CLASS_INPUT = "" + CLASS_PREFIX + "input";
56
+
57
+ CLASS_BLURRED = "" + CLASS_PREFIX + "blurred";
58
+
59
+ E_KEYPRESS = 'keypress';
60
+
61
+ EMPTY_SPAN = '<span/>';
62
+
63
+ EMPTY_DIV = '<div/>';
64
+
65
+ EMPTY_SELECTOR = ':empty';
66
+
67
+ NEWLINE = '\n';
68
+
69
+ DEFAULT_PROMPT_LABEL = '>>> ';
70
+
71
+ DEFAULT_PROMPT_CONINUE_LABEL = '... ';
72
+
73
+ DEFAULT_INDENT_WIDTH = 2;
74
+
75
+ CLASS_ANSI = "" + CLASS_PREFIX + "ansi-";
76
+
77
+ ESCAPE_CHAR = '\x1B';
78
+
79
+ ESCAPE_SYNTAX = /\[(\d*)(?:;(\d*))*m/;
80
+
81
+ Ansi = (function() {
82
+ Ansi.prototype.COLORS = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
83
+
84
+ function Ansi() {
85
+ this.stylize = __bind(this.stylize, this);
86
+ this._closeSpan = __bind(this._closeSpan, this);
87
+ this._openSpan = __bind(this._openSpan, this);
88
+ this.getClasses = __bind(this.getClasses, this);
89
+ this._style = __bind(this._style, this);
90
+ this._color = __bind(this._color, this);
91
+ this._remove = __bind(this._remove, this);
92
+ this._append = __bind(this._append, this);
93
+ this.klasses = [];
94
+ }
95
+
96
+ Ansi.prototype._append = function(klass) {
97
+ klass = "" + CLASS_ANSI + klass;
98
+ if (this.klasses.indexOf(klass) === -1) {
99
+ return this.klasses.push(klass);
100
+ }
101
+ };
102
+
103
+ Ansi.prototype._remove = function() {
104
+ var cls, klass, klasses, _i, _len, _results;
105
+ klasses = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
106
+ _results = [];
107
+ for (_i = 0, _len = klasses.length; _i < _len; _i++) {
108
+ klass = klasses[_i];
109
+ if (klass === 'fonts' || klass === 'color' || klass === 'background-color') {
110
+ _results.push(this.klasses = (function() {
111
+ var _j, _len1, _ref, _results1;
112
+ _ref = this.klasses;
113
+ _results1 = [];
114
+ for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
115
+ cls = _ref[_j];
116
+ if (cls.indexOf(klass) !== CLASS_ANSI.length) {
117
+ _results1.push(cls);
118
+ }
119
+ }
120
+ return _results1;
121
+ }).call(this));
122
+ } else {
123
+ klass = "" + CLASS_ANSI + klass;
124
+ _results.push(this.klasses = (function() {
125
+ var _j, _len1, _ref, _results1;
126
+ _ref = this.klasses;
127
+ _results1 = [];
128
+ for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
129
+ cls = _ref[_j];
130
+ if (cls !== klass) {
131
+ _results1.push(cls);
132
+ }
133
+ }
134
+ return _results1;
135
+ }).call(this));
136
+ }
137
+ }
138
+ return _results;
139
+ };
140
+
141
+ Ansi.prototype._color = function(i) {
142
+ return this.COLORS[i];
143
+ };
144
+
145
+ Ansi.prototype._style = function(code) {
146
+ if (code === '') {
147
+ code = 0;
148
+ }
149
+ code = parseInt(code);
150
+ if (isNaN(code)) {
151
+ return;
152
+ }
153
+ switch (code) {
154
+ case 0:
155
+ return this.klasses = [];
156
+ case 1:
157
+ return this._append('bold');
158
+ case 2:
159
+ return this._append('lighter');
160
+ case 3:
161
+ return this._append('italic');
162
+ case 4:
163
+ return this._append('underline');
164
+ case 5:
165
+ return this._append('blink');
166
+ case 6:
167
+ return this._append('blink-rapid');
168
+ case 8:
169
+ return this._append('hidden');
170
+ case 9:
171
+ return this._append('line-through');
172
+ case 10:
173
+ return this._remove('fonts');
174
+ case 11:
175
+ case 12:
176
+ case 13:
177
+ case 14:
178
+ case 15:
179
+ case 16:
180
+ case 17:
181
+ case 18:
182
+ case 19:
183
+ this._remove('fonts');
184
+ return this._append("fonts-" + (code - 10));
185
+ case 20:
186
+ return this._append('fraktur');
187
+ case 21:
188
+ return this._remove('bold', 'lighter');
189
+ case 22:
190
+ return this._remove('bold', 'lighter');
191
+ case 23:
192
+ return this._remove('italic', 'fraktur');
193
+ case 24:
194
+ return this._remove('underline');
195
+ case 25:
196
+ return this._remove('blink', 'blink-rapid');
197
+ case 28:
198
+ return this._remove('hidden');
199
+ case 29:
200
+ return this._remove('line-through');
201
+ case 30:
202
+ case 31:
203
+ case 32:
204
+ case 33:
205
+ case 34:
206
+ case 35:
207
+ case 36:
208
+ case 37:
209
+ this._remove('color');
210
+ return this._append('color-' + this._color(code - 30));
211
+ case 39:
212
+ return this._remove('color');
213
+ case 40:
214
+ case 41:
215
+ case 42:
216
+ case 43:
217
+ case 44:
218
+ case 45:
219
+ case 46:
220
+ case 47:
221
+ this._remove('background-color');
222
+ return this._append('background-color-' + this._color(code - 40));
223
+ case 49:
224
+ return this._remove('background-color');
225
+ case 51:
226
+ return this._append('framed');
227
+ case 53:
228
+ return this._append('overline');
229
+ case 54:
230
+ return this._remove('framed');
231
+ case 55:
232
+ return this._remove('overline');
233
+ }
234
+ };
235
+
236
+ Ansi.prototype.getClasses = function() {
237
+ return this.klasses.join(' ');
238
+ };
239
+
240
+ Ansi.prototype._openSpan = function(text) {
241
+ return "<span class=\"" + (this.getClasses()) + "\">" + text;
242
+ };
243
+
244
+ Ansi.prototype._closeSpan = function(text) {
245
+ return "" + text + "</span>";
246
+ };
247
+
248
+ Ansi.prototype.stylize = function(text) {
249
+ var code, d, i, _i, _len, _ref;
250
+ text = this._openSpan(text);
251
+ i = 0;
252
+ while ((i = text.indexOf(ESCAPE_CHAR, i)) && i !== -1) {
253
+ if (d = text.slice(i).match(ESCAPE_SYNTAX)) {
254
+ _ref = d.slice(1);
255
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
256
+ code = _ref[_i];
257
+ this._style(code);
258
+ }
259
+ text = this._closeSpan(text.slice(0, i)) + this._openSpan(text.slice(i + 1 + d[0].length));
260
+ } else {
261
+ i++;
262
+ }
263
+ }
264
+ return this._closeSpan(text);
265
+ };
266
+
267
+ return Ansi;
268
+
269
+ })();
270
+
271
+ spanHtml = function(klass, content) {
272
+ return "<span class=\"" + klass + "\">" + (content || '') + "</span>";
273
+ };
274
+
275
+ JQConsole = (function() {
276
+ function JQConsole(outer_container, header, prompt_label, prompt_continue_label) {
277
+ this._HideComposition = __bind(this._HideComposition, this);
278
+ this._ShowComposition = __bind(this._ShowComposition, this);
279
+ this._UpdateComposition = __bind(this._UpdateComposition, this);
280
+ this._EndComposition = __bind(this._EndComposition, this);
281
+ this._StartComposition = __bind(this._StartComposition, this);
282
+ this._CheckComposition = __bind(this._CheckComposition, this);
283
+ this._ProcessMatch = __bind(this._ProcessMatch, this);
284
+ this._HandleKey = __bind(this._HandleKey, this);
285
+ this._HandleChar = __bind(this._HandleChar, this);
286
+ this.isMobile = !!navigator.userAgent.match(/iPhone|iPad|iPod|Android/i);
287
+ this.isIos = !!navigator.userAgent.match(/iPhone|iPad|iPod/i);
288
+ this.isAndroid = !!navigator.userAgent.match(/Android/i);
289
+ this.$window = $(window);
290
+ this.header = header || '';
291
+ this.prompt_label_main = typeof prompt_label === 'string' ? prompt_label : DEFAULT_PROMPT_LABEL;
292
+ this.prompt_label_continue = prompt_continue_label || DEFAULT_PROMPT_CONINUE_LABEL;
293
+ this.indent_width = DEFAULT_INDENT_WIDTH;
294
+ this.state = STATE_OUTPUT;
295
+ this.input_queue = [];
296
+ this.input_callback = null;
297
+ this.multiline_callback = null;
298
+ this.history = [];
299
+ this.history_index = 0;
300
+ this.history_new = '';
301
+ this.history_active = false;
302
+ this.shortcuts = {};
303
+ this.altShortcuts = {};
304
+ this.tabHandler = null;
305
+ this.$container = $('<div/>').appendTo(outer_container);
306
+ this.$container.css({
307
+ 'top': 0,
308
+ 'left': 0,
309
+ 'right': 0,
310
+ 'bottom': 0,
311
+ 'position': 'absolute',
312
+ 'overflow': 'auto'
313
+ });
314
+ this.$console = $('<pre class="jqconsole"/>').appendTo(this.$container);
315
+ this.$console.css({
316
+ 'margin': 0,
317
+ 'position': 'relative',
318
+ 'min-height': '100%',
319
+ 'box-sizing': 'border-box',
320
+ '-moz-box-sizing': 'border-box',
321
+ '-webkit-box-sizing': 'border-box'
322
+ });
323
+ this.$console_focused = true;
324
+ this.$input_container = $(EMPTY_DIV).appendTo(this.$container);
325
+ this.$input_container.css({
326
+ position: 'absolute',
327
+ width: 1,
328
+ height: 0,
329
+ overflow: 'hidden'
330
+ });
331
+ this.$input_source = this.isAndroid ? $('<input/>') : $('<textarea/>');
332
+ this.$input_source.attr({
333
+ wrap: 'off',
334
+ autocapitalize: 'off',
335
+ autocorrect: 'off',
336
+ spellcheck: 'false',
337
+ autocomplete: 'off'
338
+ });
339
+ this.$input_source.css({
340
+ position: 'absolute',
341
+ width: 2
342
+ });
343
+ this.$input_source.appendTo(this.$input_container);
344
+ this.$composition = $(EMPTY_DIV);
345
+ this.$composition.addClass("" + CLASS_PREFIX + "composition");
346
+ this.$composition.css({
347
+ display: 'inline',
348
+ position: 'relative'
349
+ });
350
+ this.matchings = {
351
+ openings: {},
352
+ closings: {},
353
+ clss: []
354
+ };
355
+ this.ansi = new Ansi();
356
+ this._InitPrompt();
357
+ this._SetupEvents();
358
+ this.Write(this.header, CLASS_HEADER);
359
+ $(outer_container).data('jqconsole', this);
360
+ }
361
+
362
+ JQConsole.prototype.ResetHistory = function() {
363
+ return this.SetHistory([]);
364
+ };
365
+
366
+ JQConsole.prototype.ResetShortcuts = function() {
367
+ return this.shortcuts = {};
368
+ };
369
+
370
+ JQConsole.prototype.ResetMatchings = function() {
371
+ return this.matchings = {
372
+ openings: {},
373
+ closings: {},
374
+ clss: []
375
+ };
376
+ };
377
+
378
+ JQConsole.prototype.Reset = function() {
379
+ if (this.state !== STATE_OUTPUT) {
380
+ this.ClearPromptText(true);
381
+ }
382
+ this.state = STATE_OUTPUT;
383
+ this.input_queue = [];
384
+ this.input_callback = null;
385
+ this.multiline_callback = null;
386
+ this.ResetHistory();
387
+ this.ResetShortcuts();
388
+ this.ResetMatchings();
389
+ this.$prompt.detach();
390
+ this.$input_container.detach();
391
+ this.$console.html('');
392
+ this.$prompt.appendTo(this.$console);
393
+ this.$input_container.appendTo(this.$container);
394
+ this.Write(this.header, CLASS_HEADER);
395
+ return void 0;
396
+ };
397
+
398
+ JQConsole.prototype.GetHistory = function() {
399
+ return this.history;
400
+ };
401
+
402
+ JQConsole.prototype.SetHistory = function(history) {
403
+ this.history = history.slice();
404
+ return this.history_index = this.history.length;
405
+ };
406
+
407
+
408
+ /*------------------------ Shortcut Methods ----------------------------- */
409
+
410
+ JQConsole.prototype._CheckKeyCode = function(key_code) {
411
+ if (isNaN(key_code)) {
412
+ key_code = key_code.charCodeAt(0);
413
+ } else {
414
+ key_code = parseInt(key_code, 10);
415
+ }
416
+ if (!((0 < key_code && key_code < 256)) || isNaN(key_code)) {
417
+ throw new Error('Key code must be a number between 0 and 256 exclusive.');
418
+ }
419
+ return key_code;
420
+ };
421
+
422
+ JQConsole.prototype._LetterCaseHelper = function(key_code, callback) {
423
+ callback(key_code);
424
+ if ((65 <= key_code && key_code <= 90)) {
425
+ callback(key_code + 32);
426
+ }
427
+ if ((97 <= key_code && key_code <= 122)) {
428
+ return callback(key_code - 32);
429
+ }
430
+ };
431
+
432
+ JQConsole.prototype.RegisterAltShortcut = function(key_code, callback) {
433
+ var addShortcut;
434
+ key_code = this._CheckKeyCode(key_code);
435
+ if (typeof callback !== 'function') {
436
+ throw new Error('Callback must be a function, not ' + callback + '.');
437
+ }
438
+ addShortcut = (function(_this) {
439
+ return function(key) {
440
+ if (!(key in _this.altShortcuts)) {
441
+ _this.altShortcuts[key] = [];
442
+ }
443
+ return _this.altShortcuts[key].push(callback);
444
+ };
445
+ })(this);
446
+ this._LetterCaseHelper(key_code, addShortcut);
447
+ return void 0;
448
+ };
449
+
450
+ JQConsole.prototype.UnRegisterAltShortcut = function(key_code, handler) {
451
+ var removeShortcut;
452
+ key_code = this._CheckKeyCode(key_code);
453
+ removeShortcut = (function(_this) {
454
+ return function(key) {
455
+ if (key in _this.shortcuts) {
456
+ if (handler) {
457
+ return _this.altShortcuts[key].splice(_this.altShortcuts[key].indexOf(handler), 1);
458
+ } else {
459
+ return delete _this.altShortcuts[key];
460
+ }
461
+ }
462
+ };
463
+ })(this);
464
+ this._LetterCaseHelper(key_code, removeShortcut);
465
+ return void 0;
466
+ };
467
+
468
+ JQConsole.prototype.RegisterTabHandler = function(callback) {
469
+ return this.tabHandler = callback;
470
+ };
471
+
472
+ JQConsole.prototype.RegisterShortcut = function(key_code, callback) {
473
+ var addShortcut;
474
+ key_code = this._CheckKeyCode(key_code);
475
+ if (typeof callback !== 'function') {
476
+ throw new Error('Callback must be a function, not ' + callback + '.');
477
+ }
478
+ addShortcut = (function(_this) {
479
+ return function(key) {
480
+ if (!(key in _this.shortcuts)) {
481
+ _this.shortcuts[key] = [];
482
+ }
483
+ return _this.shortcuts[key].push(callback);
484
+ };
485
+ })(this);
486
+ this._LetterCaseHelper(key_code, addShortcut);
487
+ return void 0;
488
+ };
489
+
490
+ JQConsole.prototype.UnRegisterShortcut = function(key_code, handler) {
491
+ var removeShortcut;
492
+ key_code = this._CheckKeyCode(key_code);
493
+ removeShortcut = (function(_this) {
494
+ return function(key) {
495
+ if (key in _this.shortcuts) {
496
+ if (handler) {
497
+ return _this.shortcuts[key].splice(_this.shortcuts[key].indexOf(handler), 1);
498
+ } else {
499
+ return delete _this.shortcuts[key];
500
+ }
501
+ }
502
+ };
503
+ })(this);
504
+ this._LetterCaseHelper(key_code, removeShortcut);
505
+ return void 0;
506
+ };
507
+
508
+
509
+ /*---------------------- END Shortcut Methods --------------------------- */
510
+
511
+ JQConsole.prototype.GetColumn = function() {
512
+ var lines;
513
+ this.$prompt_right.detach();
514
+ this.$prompt_cursor.text('');
515
+ lines = this.$console.text().split(NEWLINE);
516
+ this.$prompt_cursor.html('&nbsp;');
517
+ this.$prompt_cursor.after(this.$prompt_right);
518
+ return lines[lines.length - 1].length;
519
+ };
520
+
521
+ JQConsole.prototype.GetLine = function() {
522
+ return this.$console.text().split(NEWLINE).length - 1;
523
+ };
524
+
525
+ JQConsole.prototype.ClearPromptText = function(clear_label) {
526
+ if (this.state === STATE_OUTPUT) {
527
+ throw new Error('ClearPromptText() is not allowed in output state.');
528
+ }
529
+ this.$prompt_before.html('');
530
+ this.$prompt_after.html('');
531
+ this.$prompt_label.text(clear_label ? '' : this._SelectPromptLabel(false));
532
+ this.$prompt_left.text('');
533
+ this.$prompt_right.text('');
534
+ return void 0;
535
+ };
536
+
537
+ JQConsole.prototype.GetPromptText = function(full) {
538
+ var after, before, current, getPromptLines, text;
539
+ if (this.state === STATE_OUTPUT) {
540
+ throw new Error('GetPromptText() is not allowed in output state.');
541
+ }
542
+ if (full) {
543
+ this.$prompt_cursor.text('');
544
+ text = this.$prompt.text();
545
+ this.$prompt_cursor.html('&nbsp;');
546
+ return text;
547
+ } else {
548
+ getPromptLines = function(node) {
549
+ var buffer;
550
+ buffer = [];
551
+ node.children().each(function() {
552
+ return buffer.push($(this).children().last().text());
553
+ });
554
+ return buffer.join(NEWLINE);
555
+ };
556
+ before = getPromptLines(this.$prompt_before);
557
+ if (before) {
558
+ before += NEWLINE;
559
+ }
560
+ current = this.$prompt_left.text() + this.$prompt_right.text();
561
+ after = getPromptLines(this.$prompt_after);
562
+ if (after) {
563
+ after = NEWLINE + after;
564
+ }
565
+ return before + current + after;
566
+ }
567
+ };
568
+
569
+ JQConsole.prototype.SetPromptText = function(text) {
570
+ if (this.state === STATE_OUTPUT) {
571
+ throw new Error('SetPromptText() is not allowed in output state.');
572
+ }
573
+ this.ClearPromptText(false);
574
+ this._AppendPromptText(text);
575
+ this._ScrollToEnd();
576
+ return void 0;
577
+ };
578
+
579
+ JQConsole.prototype.SetPromptLabel = function(main_label, continue_label) {
580
+ this.prompt_label_main = main_label;
581
+ if (continue_label != null) {
582
+ this.prompt_label_continue = continue_label;
583
+ }
584
+ return void 0;
585
+ };
586
+
587
+ JQConsole.prototype.Write = function(text, cls, escape) {
588
+ var span;
589
+ if (escape == null) {
590
+ escape = true;
591
+ }
592
+ if (escape) {
593
+ text = this.ansi.stylize($(EMPTY_SPAN).text(text).html());
594
+ }
595
+ span = $(EMPTY_SPAN).html(text);
596
+ if (cls != null) {
597
+ span.addClass(cls);
598
+ }
599
+ return this.Append(span);
600
+ };
601
+
602
+ JQConsole.prototype.Append = function(node) {
603
+ var $node;
604
+ $node = $(node).insertBefore(this.$prompt);
605
+ this._ScrollToEnd();
606
+ this.$prompt_cursor.detach().insertAfter(this.$prompt_left);
607
+ return $node;
608
+ };
609
+
610
+ JQConsole.prototype.Input = function(input_callback) {
611
+ var current_async_multiline, current_history_active, current_input_callback, current_multiline_callback;
612
+ if (this.state === STATE_PROMPT) {
613
+ current_input_callback = this.input_callback;
614
+ current_multiline_callback = this.multiline_callback;
615
+ current_history_active = this.history_active;
616
+ current_async_multiline = this.async_multiline;
617
+ this.AbortPrompt();
618
+ this.input_queue.unshift((function(_this) {
619
+ return function() {
620
+ return _this.Prompt(current_history_active, current_input_callback, current_multiline_callback, current_async_multiline);
621
+ };
622
+ })(this));
623
+ } else if (this.state !== STATE_OUTPUT) {
624
+ this.input_queue.push((function(_this) {
625
+ return function() {
626
+ return _this.Input(input_callback);
627
+ };
628
+ })(this));
629
+ return;
630
+ }
631
+ this.history_active = false;
632
+ this.input_callback = input_callback;
633
+ this.multiline_callback = null;
634
+ this.state = STATE_INPUT;
635
+ this.$prompt.attr('class', CLASS_INPUT);
636
+ this.$prompt_label.text(this._SelectPromptLabel(false));
637
+ this.Focus();
638
+ this._ScrollToEnd();
639
+ return void 0;
640
+ };
641
+
642
+ JQConsole.prototype.Prompt = function(history_enabled, result_callback, multiline_callback, async_multiline) {
643
+ if (this.state !== STATE_OUTPUT) {
644
+ this.input_queue.push((function(_this) {
645
+ return function() {
646
+ return _this.Prompt(history_enabled, result_callback, multiline_callback, async_multiline);
647
+ };
648
+ })(this));
649
+ return;
650
+ }
651
+ this.history_active = history_enabled;
652
+ this.input_callback = result_callback;
653
+ this.multiline_callback = multiline_callback;
654
+ this.async_multiline = async_multiline;
655
+ this.state = STATE_PROMPT;
656
+ this.$prompt.attr('class', CLASS_PROMPT + ' ' + this.ansi.getClasses());
657
+ this.$prompt_label.text(this._SelectPromptLabel(false));
658
+ this.Focus();
659
+ this._ScrollToEnd();
660
+ return void 0;
661
+ };
662
+
663
+ JQConsole.prototype.AbortPrompt = function() {
664
+ if (this.state !== STATE_PROMPT) {
665
+ throw new Error('Cannot abort prompt when not in prompt state.');
666
+ }
667
+ this.Write(this.GetPromptText(true) + NEWLINE, CLASS_OLD_PROMPT);
668
+ this.ClearPromptText(true);
669
+ this.state = STATE_OUTPUT;
670
+ this.input_callback = this.multiline_callback = null;
671
+ this._CheckInputQueue();
672
+ return void 0;
673
+ };
674
+
675
+ JQConsole.prototype.Focus = function() {
676
+ if (!this.IsDisabled()) {
677
+ this.$input_source.focus();
678
+ }
679
+ return void 0;
680
+ };
681
+
682
+ JQConsole.prototype.SetIndentWidth = function(width) {
683
+ return this.indent_width = width;
684
+ };
685
+
686
+ JQConsole.prototype.GetIndentWidth = function() {
687
+ return this.indent_width;
688
+ };
689
+
690
+ JQConsole.prototype.RegisterMatching = function(open, close, cls) {
691
+ var match_config;
692
+ match_config = {
693
+ opening_char: open,
694
+ closing_char: close,
695
+ cls: cls
696
+ };
697
+ this.matchings.clss.push(cls);
698
+ this.matchings.openings[open] = match_config;
699
+ return this.matchings.closings[close] = match_config;
700
+ };
701
+
702
+ JQConsole.prototype.UnRegisterMatching = function(open, close) {
703
+ var cls;
704
+ cls = this.matchings.openings[open].cls;
705
+ delete this.matchings.openings[open];
706
+ delete this.matchings.closings[close];
707
+ return this.matchings.clss.splice(this.matchings.clss.indexOf(cls), 1);
708
+ };
709
+
710
+ JQConsole.prototype.Dump = function() {
711
+ var $elems, elem;
712
+ $elems = this.$console.find("." + CLASS_HEADER).nextUntil("." + CLASS_PROMPT).addBack();
713
+ return ((function() {
714
+ var _i, _len, _results;
715
+ _results = [];
716
+ for (_i = 0, _len = $elems.length; _i < _len; _i++) {
717
+ elem = $elems[_i];
718
+ if ($(elem).is("." + CLASS_OLD_PROMPT)) {
719
+ _results.push($(elem).text().replace(/^\s+/, '>>> '));
720
+ } else {
721
+ _results.push($(elem).text());
722
+ }
723
+ }
724
+ return _results;
725
+ })()).join('');
726
+ };
727
+
728
+ JQConsole.prototype.GetState = function() {
729
+ if (this.state === STATE_INPUT) {
730
+ return 'input';
731
+ } else if (this.state === STATE_OUTPUT) {
732
+ return 'output';
733
+ } else {
734
+ return 'prompt';
735
+ }
736
+ };
737
+
738
+ JQConsole.prototype.Disable = function() {
739
+ this.$input_source.attr('disabled', true);
740
+ return this.$input_source.blur();
741
+ };
742
+
743
+ JQConsole.prototype.Enable = function() {
744
+ return this.$input_source.attr('disabled', false);
745
+ };
746
+
747
+ JQConsole.prototype.IsDisabled = function() {
748
+ return Boolean(this.$input_source.attr('disabled'));
749
+ };
750
+
751
+ JQConsole.prototype.MoveToStart = function(all_lines) {
752
+ this._MoveTo(all_lines, true);
753
+ return void 0;
754
+ };
755
+
756
+ JQConsole.prototype.MoveToEnd = function(all_lines) {
757
+ this._MoveTo(all_lines, false);
758
+ return void 0;
759
+ };
760
+
761
+ JQConsole.prototype.Clear = function() {
762
+ this.$console.find("." + CLASS_HEADER).nextUntil("." + CLASS_PROMPT).addBack().text('');
763
+ this.$prompt_cursor.detach();
764
+ return this.$prompt_right.before(this.$prompt_cursor);
765
+ };
766
+
767
+
768
+ /*------------------------ Private Methods ------------------------------- */
769
+
770
+ JQConsole.prototype._CheckInputQueue = function() {
771
+ if (this.input_queue.length) {
772
+ return this.input_queue.shift()();
773
+ }
774
+ };
775
+
776
+ JQConsole.prototype._InitPrompt = function() {
777
+ this.$prompt = $(spanHtml(CLASS_INPUT)).appendTo(this.$console);
778
+ this.$prompt_before = $(EMPTY_SPAN).appendTo(this.$prompt);
779
+ this.$prompt_current = $(EMPTY_SPAN).appendTo(this.$prompt);
780
+ this.$prompt_after = $(EMPTY_SPAN).appendTo(this.$prompt);
781
+ this.$prompt_label = $(EMPTY_SPAN).appendTo(this.$prompt_current);
782
+ this.$prompt_left = $(EMPTY_SPAN).appendTo(this.$prompt_current);
783
+ this.$prompt_right = $(EMPTY_SPAN).appendTo(this.$prompt_current);
784
+ this.$prompt_right.css({
785
+ position: 'relative'
786
+ });
787
+ this.$prompt_cursor = $(spanHtml(CLASS_CURSOR, '&nbsp;'));
788
+ this.$prompt_cursor.insertBefore(this.$prompt_right);
789
+ this.$prompt_cursor.css({
790
+ color: 'transparent',
791
+ display: 'inline',
792
+ zIndex: 0
793
+ });
794
+ if (!this.isMobile) {
795
+ return this.$prompt_cursor.css('position', 'absolute');
796
+ }
797
+ };
798
+
799
+ JQConsole.prototype._SetupEvents = function() {
800
+ if (this.isMobile) {
801
+ this.$console.click((function(_this) {
802
+ return function(e) {
803
+ e.preventDefault();
804
+ return _this.Focus();
805
+ };
806
+ })(this));
807
+ } else {
808
+ this.$console.mouseup((function(_this) {
809
+ return function(e) {
810
+ var fn;
811
+ if (e.which === 2) {
812
+ return _this.Focus();
813
+ } else {
814
+ fn = function() {
815
+ if (!window.getSelection().toString()) {
816
+ e.preventDefault();
817
+ return _this.Focus();
818
+ }
819
+ };
820
+ return setTimeout(fn, 0);
821
+ }
822
+ };
823
+ })(this));
824
+ }
825
+ this.$input_source.focus((function(_this) {
826
+ return function() {
827
+ var hideTextInput, removeClass;
828
+ _this._ScrollToEnd();
829
+ _this.$console_focused = true;
830
+ _this.$console.removeClass(CLASS_BLURRED);
831
+ removeClass = function() {
832
+ if (_this.$console_focused) {
833
+ return _this.$console.removeClass(CLASS_BLURRED);
834
+ }
835
+ };
836
+ setTimeout(removeClass, 100);
837
+ hideTextInput = function() {
838
+ if (_this.isIos && _this.$console_focused) {
839
+ return _this.$input_source.hide();
840
+ }
841
+ };
842
+ return setTimeout(hideTextInput, 500);
843
+ };
844
+ })(this));
845
+ this.$input_source.blur((function(_this) {
846
+ return function() {
847
+ var addClass;
848
+ _this.$console_focused = false;
849
+ if (_this.isIos) {
850
+ _this.$input_source.show();
851
+ }
852
+ addClass = function() {
853
+ if (!_this.$console_focused) {
854
+ return _this.$console.addClass(CLASS_BLURRED);
855
+ }
856
+ };
857
+ return setTimeout(addClass, 100);
858
+ };
859
+ })(this));
860
+ this.$input_source.bind('paste', (function(_this) {
861
+ return function() {
862
+ var handlePaste;
863
+ handlePaste = function() {
864
+ if (_this.in_composition) {
865
+ return;
866
+ }
867
+ _this._AppendPromptText(_this.$input_source.val());
868
+ _this.$input_source.val('');
869
+ return _this.Focus();
870
+ };
871
+ return setTimeout(handlePaste, 0);
872
+ };
873
+ })(this));
874
+ this.$input_source.keypress(this._HandleChar);
875
+ this.$input_source.keydown(this._HandleKey);
876
+ this.$input_source.keydown(this._CheckComposition);
877
+ this.$input_source.bind('compositionstart', this._StartComposition);
878
+ this.$input_source.bind('compositionend', (function(_this) {
879
+ return function(e) {
880
+ return setTimeout((function() {
881
+ return _this._EndComposition(e);
882
+ }), 0);
883
+ };
884
+ })(this));
885
+ if (this.isAndroid) {
886
+ this.$input_source.bind('input', this._StartComposition);
887
+ return this.$input_source.bind('input', this._UpdateComposition);
888
+ } else {
889
+ return this.$input_source.bind('text', this._UpdateComposition);
890
+ }
891
+ };
892
+
893
+ JQConsole.prototype._HandleChar = function(event) {
894
+ var char_code;
895
+ if (this.state === STATE_OUTPUT || event.metaKey || event.ctrlKey || event.altKey) {
896
+ return true;
897
+ }
898
+ char_code = event.which;
899
+ if (char_code === 8 || char_code === 9 || char_code === 13) {
900
+ return false;
901
+ }
902
+ this.$prompt_left.text(this.$prompt_left.text() + String.fromCharCode(char_code));
903
+ this._ScrollToEnd();
904
+ return false;
905
+ };
906
+
907
+ JQConsole.prototype._HandleKey = function(event) {
908
+ var key;
909
+ if (this.state === STATE_OUTPUT) {
910
+ return true;
911
+ }
912
+ key = event.keyCode || event.which;
913
+ setTimeout($.proxy(this._CheckMatchings, this), 0);
914
+ if (event.altKey) {
915
+ return this._HandleAltShortcut(key);
916
+ } else if (event.ctrlKey || event.metaKey) {
917
+ return this._HandleCtrlShortcut(key);
918
+ } else if (event.shiftKey) {
919
+ switch (key) {
920
+ case KEY_ENTER:
921
+ this._HandleEnter(true);
922
+ break;
923
+ case KEY_TAB:
924
+ this._Unindent();
925
+ break;
926
+ case KEY_UP:
927
+ this._MoveUp();
928
+ break;
929
+ case KEY_DOWN:
930
+ this._MoveDown();
931
+ break;
932
+ case KEY_PAGE_UP:
933
+ this._ScrollPage('up');
934
+ break;
935
+ case KEY_PAGE_DOWN:
936
+ this._ScrollPage('down');
937
+ break;
938
+ default:
939
+ return true;
940
+ }
941
+ return false;
942
+ } else {
943
+ switch (key) {
944
+ case KEY_ENTER:
945
+ this._HandleEnter(false);
946
+ break;
947
+ case KEY_TAB:
948
+ this._HandleTab();
949
+ break;
950
+ case KEY_DELETE:
951
+ this._Delete(false);
952
+ break;
953
+ case KEY_BACKSPACE:
954
+ this._Backspace(false);
955
+ break;
956
+ case KEY_LEFT:
957
+ this._MoveLeft(false);
958
+ break;
959
+ case KEY_RIGHT:
960
+ this._MoveRight(false);
961
+ break;
962
+ case KEY_UP:
963
+ this._HistoryPrevious();
964
+ break;
965
+ case KEY_DOWN:
966
+ this._HistoryNext();
967
+ break;
968
+ case KEY_HOME:
969
+ this.MoveToStart(false);
970
+ break;
971
+ case KEY_END:
972
+ this.MoveToEnd(false);
973
+ break;
974
+ case KEY_PAGE_UP:
975
+ this._ScrollPage('up');
976
+ break;
977
+ case KEY_PAGE_DOWN:
978
+ this._ScrollPage('down');
979
+ break;
980
+ default:
981
+ return true;
982
+ }
983
+ return false;
984
+ }
985
+ };
986
+
987
+ JQConsole.prototype._HandleCtrlShortcut = function(key) {
988
+ var handler, _i, _len, _ref;
989
+ switch (key) {
990
+ case KEY_DELETE:
991
+ this._Delete(true);
992
+ break;
993
+ case KEY_BACKSPACE:
994
+ this._Backspace(true);
995
+ break;
996
+ case KEY_LEFT:
997
+ this._MoveLeft(true);
998
+ break;
999
+ case KEY_RIGHT:
1000
+ this._MoveRight(true);
1001
+ break;
1002
+ case KEY_UP:
1003
+ this._MoveUp();
1004
+ break;
1005
+ case KEY_DOWN:
1006
+ this._MoveDown();
1007
+ break;
1008
+ case KEY_END:
1009
+ this.MoveToEnd(true);
1010
+ break;
1011
+ case KEY_HOME:
1012
+ this.MoveToStart(true);
1013
+ break;
1014
+ default:
1015
+ if (key in this.shortcuts) {
1016
+ _ref = this.shortcuts[key];
1017
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1018
+ handler = _ref[_i];
1019
+ handler.call(this);
1020
+ }
1021
+ return false;
1022
+ } else {
1023
+ return true;
1024
+ }
1025
+ }
1026
+ return false;
1027
+ };
1028
+
1029
+ JQConsole.prototype._HandleAltShortcut = function(key) {
1030
+ var handler, _i, _len, _ref;
1031
+ if (key in this.altShortcuts) {
1032
+ _ref = this.altShortcuts[key];
1033
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1034
+ handler = _ref[_i];
1035
+ handler.call(this);
1036
+ }
1037
+ return false;
1038
+ } else {
1039
+ return true;
1040
+ }
1041
+ };
1042
+
1043
+ JQConsole.prototype._HandleEnter = function(shift) {
1044
+ var continuation, text;
1045
+ this._EndComposition();
1046
+ if (shift) {
1047
+ return this._InsertNewLine(true);
1048
+ } else {
1049
+ text = this.GetPromptText();
1050
+ continuation = (function(_this) {
1051
+ return function(indent) {
1052
+ var callback, cls_suffix, _, _i, _ref, _results;
1053
+ if (indent !== false) {
1054
+ _this.MoveToEnd(true);
1055
+ _this._InsertNewLine(true);
1056
+ _results = [];
1057
+ for (_ = _i = 0, _ref = Math.abs(indent); 0 <= _ref ? _i < _ref : _i > _ref; _ = 0 <= _ref ? ++_i : --_i) {
1058
+ if (indent > 0) {
1059
+ _results.push(_this._Indent());
1060
+ } else {
1061
+ _results.push(_this._Unindent());
1062
+ }
1063
+ }
1064
+ return _results;
1065
+ } else {
1066
+ cls_suffix = _this.state === STATE_INPUT ? 'input' : 'prompt';
1067
+ _this.Write(_this.GetPromptText(true) + NEWLINE, ("" + CLASS_PREFIX + "old-") + cls_suffix);
1068
+ _this.ClearPromptText(true);
1069
+ if (_this.history_active) {
1070
+ if (!_this.history.length || _this.history[_this.history.length - 1] !== text) {
1071
+ _this.history.push(text);
1072
+ }
1073
+ _this.history_index = _this.history.length;
1074
+ }
1075
+ _this.state = STATE_OUTPUT;
1076
+ callback = _this.input_callback;
1077
+ _this.input_callback = null;
1078
+ if (callback) {
1079
+ callback(text);
1080
+ }
1081
+ return _this._CheckInputQueue();
1082
+ }
1083
+ };
1084
+ })(this);
1085
+ if (this.multiline_callback) {
1086
+ if (this.async_multiline) {
1087
+ return this.multiline_callback(text, continuation);
1088
+ } else {
1089
+ return continuation(this.multiline_callback(text));
1090
+ }
1091
+ } else {
1092
+ return continuation(false);
1093
+ }
1094
+ }
1095
+ };
1096
+
1097
+ JQConsole.prototype._GetDirectionals = function(back) {
1098
+ var $prompt_opposite, $prompt_rel_opposite, $prompt_relative, $prompt_which, MoveDirection, MoveToLimit, where_append, which_end;
1099
+ $prompt_which = back ? this.$prompt_left : this.$prompt_right;
1100
+ $prompt_opposite = back ? this.$prompt_right : this.$prompt_left;
1101
+ $prompt_relative = back ? this.$prompt_before : this.$prompt_after;
1102
+ $prompt_rel_opposite = back ? this.$prompt_after : this.$prompt_before;
1103
+ MoveToLimit = back ? $.proxy(this.MoveToStart, this) : $.proxy(this.MoveToEnd, this);
1104
+ MoveDirection = back ? $.proxy(this._MoveLeft, this) : $.proxy(this._MoveRight, this);
1105
+ which_end = back ? 'last' : 'first';
1106
+ where_append = back ? 'prependTo' : 'appendTo';
1107
+ return {
1108
+ $prompt_which: $prompt_which,
1109
+ $prompt_opposite: $prompt_opposite,
1110
+ $prompt_relative: $prompt_relative,
1111
+ $prompt_rel_opposite: $prompt_rel_opposite,
1112
+ MoveToLimit: MoveToLimit,
1113
+ MoveDirection: MoveDirection,
1114
+ which_end: which_end,
1115
+ where_append: where_append
1116
+ };
1117
+ };
1118
+
1119
+ JQConsole.prototype._VerticalMove = function(up) {
1120
+ var $prompt_opposite, $prompt_relative, $prompt_which, MoveDirection, MoveToLimit, pos, text, _ref;
1121
+ _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;
1122
+ if ($prompt_relative.is(EMPTY_SELECTOR)) {
1123
+ return;
1124
+ }
1125
+ pos = this.$prompt_left.text().length;
1126
+ MoveToLimit();
1127
+ MoveDirection();
1128
+ text = $prompt_which.text();
1129
+ $prompt_opposite.text(up ? text.slice(pos) : text.slice(0, pos));
1130
+ return $prompt_which.text(up ? text.slice(0, pos) : text.slice(pos));
1131
+ };
1132
+
1133
+ JQConsole.prototype._MoveUp = function() {
1134
+ return this._VerticalMove(true);
1135
+ };
1136
+
1137
+ JQConsole.prototype._MoveDown = function() {
1138
+ return this._VerticalMove();
1139
+ };
1140
+
1141
+ JQConsole.prototype._HorizontalMove = function(whole_word, back) {
1142
+ var $opposite_line, $prompt_opposite, $prompt_rel_opposite, $prompt_relative, $prompt_which, $which_line, len, regexp, text, tmp, where_append, which_end, word, _ref;
1143
+ _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;
1144
+ regexp = back ? /\w*\W*$/ : /^\w*\W*/;
1145
+ text = $prompt_which.text();
1146
+ if (text) {
1147
+ if (whole_word) {
1148
+ word = text.match(regexp);
1149
+ if (!word) {
1150
+ return;
1151
+ }
1152
+ word = word[0];
1153
+ tmp = $prompt_opposite.text();
1154
+ $prompt_opposite.text(back ? word + tmp : tmp + word);
1155
+ len = word.length;
1156
+ return $prompt_which.text(back ? text.slice(0, -len) : text.slice(len));
1157
+ } else {
1158
+ tmp = $prompt_opposite.text();
1159
+ $prompt_opposite.text(back ? text.slice(-1) + tmp : tmp + text[0]);
1160
+ return $prompt_which.text(back ? text.slice(0, -1) : text.slice(1));
1161
+ }
1162
+ } else if (!$prompt_relative.is(EMPTY_SELECTOR)) {
1163
+ $which_line = $(EMPTY_SPAN)[where_append]($prompt_rel_opposite);
1164
+ $which_line.append($(EMPTY_SPAN).text(this.$prompt_label.text()));
1165
+ $which_line.append($(EMPTY_SPAN).text($prompt_opposite.text()));
1166
+ $opposite_line = $prompt_relative.children()[which_end]().detach();
1167
+ this.$prompt_label.text($opposite_line.children().first().text());
1168
+ $prompt_which.text($opposite_line.children().last().text());
1169
+ return $prompt_opposite.text('');
1170
+ }
1171
+ };
1172
+
1173
+ JQConsole.prototype._MoveLeft = function(whole_word) {
1174
+ return this._HorizontalMove(whole_word, true);
1175
+ };
1176
+
1177
+ JQConsole.prototype._MoveRight = function(whole_word) {
1178
+ return this._HorizontalMove(whole_word);
1179
+ };
1180
+
1181
+ JQConsole.prototype._MoveTo = function(all_lines, back) {
1182
+ var $prompt_opposite, $prompt_relative, $prompt_which, MoveDirection, MoveToLimit, _ref, _results;
1183
+ _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;
1184
+ if (all_lines) {
1185
+ _results = [];
1186
+ while (!($prompt_relative.is(EMPTY_SELECTOR) && $prompt_which.text() === '')) {
1187
+ MoveToLimit(false);
1188
+ _results.push(MoveDirection(false));
1189
+ }
1190
+ return _results;
1191
+ } else {
1192
+ $prompt_opposite.text(this.$prompt_left.text() + this.$prompt_right.text());
1193
+ return $prompt_which.text('');
1194
+ }
1195
+ };
1196
+
1197
+ JQConsole.prototype.Kill = function() {
1198
+ var text;
1199
+ text = this.$prompt_right.text();
1200
+ if (text) {
1201
+ return this.$prompt_right.text("");
1202
+ }
1203
+ };
1204
+
1205
+ JQConsole.prototype._Delete = function(whole_word) {
1206
+ var $lower_line, text, word;
1207
+ text = this.$prompt_right.text();
1208
+ if (text) {
1209
+ if (whole_word) {
1210
+ word = text.match(/^\w*\W*/);
1211
+ if (!word) {
1212
+ return;
1213
+ }
1214
+ word = word[0];
1215
+ return this.$prompt_right.text(text.slice(word.length));
1216
+ } else {
1217
+ return this.$prompt_right.text(text.slice(1));
1218
+ }
1219
+ } else if (!this.$prompt_after.is(EMPTY_SELECTOR)) {
1220
+ $lower_line = this.$prompt_after.children().first().detach();
1221
+ return this.$prompt_right.text($lower_line.children().last().text());
1222
+ }
1223
+ };
1224
+
1225
+ JQConsole.prototype._Backspace = function(whole_word) {
1226
+ var $upper_line, text, word;
1227
+ setTimeout($.proxy(this._ScrollToEnd, this), 0);
1228
+ text = this.$prompt_left.text();
1229
+ if (text) {
1230
+ if (whole_word) {
1231
+ word = text.match(/\w*\W*$/);
1232
+ if (!word) {
1233
+ return;
1234
+ }
1235
+ word = word[0];
1236
+ return this.$prompt_left.text(text.slice(0, -word.length));
1237
+ } else {
1238
+ return this.$prompt_left.text(text.slice(0, -1));
1239
+ }
1240
+ } else if (!this.$prompt_before.is(EMPTY_SELECTOR)) {
1241
+ $upper_line = this.$prompt_before.children().last().detach();
1242
+ this.$prompt_label.text($upper_line.children().first().text());
1243
+ return this.$prompt_left.text($upper_line.children().last().text());
1244
+ }
1245
+ };
1246
+
1247
+ JQConsole.prototype._HandleTab = function() {
1248
+ if (this.tabHandler) {
1249
+ if (this.tabHandler(this.$prompt_left.text())) {
1250
+ return this._Indent();
1251
+ }
1252
+ } else {
1253
+ return this._Indent();
1254
+ }
1255
+ };
1256
+
1257
+ JQConsole.prototype._Indent = function() {
1258
+ var _;
1259
+ return this.$prompt_left.prepend(((function() {
1260
+ var _i, _ref, _results;
1261
+ _results = [];
1262
+ for (_ = _i = 1, _ref = this.indent_width; 1 <= _ref ? _i <= _ref : _i >= _ref; _ = 1 <= _ref ? ++_i : --_i) {
1263
+ _results.push(' ');
1264
+ }
1265
+ return _results;
1266
+ }).call(this)).join(''));
1267
+ };
1268
+
1269
+ JQConsole.prototype._Unindent = function() {
1270
+ var line_text, _, _i, _ref, _results;
1271
+ line_text = this.$prompt_left.text() + this.$prompt_right.text();
1272
+ _results = [];
1273
+ for (_ = _i = 1, _ref = this.indent_width; 1 <= _ref ? _i <= _ref : _i >= _ref; _ = 1 <= _ref ? ++_i : --_i) {
1274
+ if (!/^ /.test(line_text)) {
1275
+ break;
1276
+ }
1277
+ if (this.$prompt_left.text()) {
1278
+ this.$prompt_left.text(this.$prompt_left.text().slice(1));
1279
+ } else {
1280
+ this.$prompt_right.text(this.$prompt_right.text().slice(1));
1281
+ }
1282
+ _results.push(line_text = line_text.slice(1));
1283
+ }
1284
+ return _results;
1285
+ };
1286
+
1287
+ JQConsole.prototype._InsertNewLine = function(indent) {
1288
+ var $old_line, match, old_prompt;
1289
+ if (indent == null) {
1290
+ indent = false;
1291
+ }
1292
+ old_prompt = this._SelectPromptLabel(!this.$prompt_before.is(EMPTY_SELECTOR));
1293
+ $old_line = $(EMPTY_SPAN).appendTo(this.$prompt_before);
1294
+ $old_line.append($(EMPTY_SPAN).text(old_prompt));
1295
+ $old_line.append($(EMPTY_SPAN).text(this.$prompt_left.text()));
1296
+ this.$prompt_label.text(this._SelectPromptLabel(true));
1297
+ if (indent && (match = this.$prompt_left.text().match(/^\s+/))) {
1298
+ this.$prompt_left.text(match[0]);
1299
+ } else {
1300
+ this.$prompt_left.text('');
1301
+ }
1302
+ return this._ScrollToEnd();
1303
+ };
1304
+
1305
+ JQConsole.prototype._AppendPromptText = function(text) {
1306
+ var line, lines, _i, _len, _ref, _results;
1307
+ lines = text.split(NEWLINE);
1308
+ this.$prompt_left.text(this.$prompt_left.text() + lines[0]);
1309
+ _ref = lines.slice(1);
1310
+ _results = [];
1311
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1312
+ line = _ref[_i];
1313
+ this._InsertNewLine();
1314
+ _results.push(this.$prompt_left.text(line));
1315
+ }
1316
+ return _results;
1317
+ };
1318
+
1319
+ JQConsole.prototype._ScrollPage = function(dir) {
1320
+ var target;
1321
+ target = this.$container[0].scrollTop;
1322
+ if (dir === 'up') {
1323
+ target -= this.$container.height();
1324
+ } else {
1325
+ target += this.$container.height();
1326
+ }
1327
+ return this.$container.stop().animate({
1328
+ scrollTop: target
1329
+ }, 'fast');
1330
+ };
1331
+
1332
+ JQConsole.prototype._ScrollToEnd = function() {
1333
+ var pos;
1334
+ this.$container.scrollTop(this.$container[0].scrollHeight);
1335
+ pos = this.$prompt_cursor.position();
1336
+ this.$input_container.css({
1337
+ left: pos.left,
1338
+ top: pos.top
1339
+ });
1340
+ return setTimeout(this.ScrollWindowToPrompt.bind(this), 50);
1341
+ };
1342
+
1343
+ JQConsole.prototype.ScrollWindowToPrompt = function() {
1344
+ var doc_height, line_height, optimal_pos, pos, screen_left, screen_top;
1345
+ line_height = this.$prompt_cursor.height();
1346
+ screen_top = this.$window.scrollTop();
1347
+ screen_left = this.$window.scrollLeft();
1348
+ doc_height = document.documentElement.clientHeight;
1349
+ pos = this.$prompt_cursor.offset();
1350
+ optimal_pos = pos.top - (2 * line_height);
1351
+ if (this.isMobile && (typeof orientation !== "undefined" && orientation !== null)) {
1352
+ if (screen_top < pos.top || screen_top > pos.top) {
1353
+ return this.$window.scrollTop(optimal_pos);
1354
+ }
1355
+ } else {
1356
+ if (screen_top + doc_height < pos.top) {
1357
+ return this.$window.scrollTop(pos.top - doc_height + line_height);
1358
+ } else if (screen_top > optimal_pos) {
1359
+ return this.$window.scrollTop(pos.top);
1360
+ }
1361
+ }
1362
+ };
1363
+
1364
+ JQConsole.prototype._SelectPromptLabel = function(continuation) {
1365
+ if (this.state === STATE_PROMPT) {
1366
+ if (continuation) {
1367
+ return ' \n' + this.prompt_label_continue;
1368
+ } else {
1369
+ return this.prompt_label_main;
1370
+ }
1371
+ } else {
1372
+ if (continuation) {
1373
+ return '\n ';
1374
+ } else {
1375
+ return ' ';
1376
+ }
1377
+ }
1378
+ };
1379
+
1380
+ JQConsole.prototype._Wrap = function($elem, index, cls) {
1381
+ var html, text;
1382
+ text = $elem.html();
1383
+ html = text.slice(0, index) + spanHtml(cls, text[index]) + text.slice(index + 1);
1384
+ return $elem.html(html);
1385
+ };
1386
+
1387
+ JQConsole.prototype._WalkCharacters = function(text, char, opposing_char, current_count, back) {
1388
+ var ch, index, read_char;
1389
+ index = back ? text.length : 0;
1390
+ text = text.split('');
1391
+ read_char = function() {
1392
+ var ret, _i, _ref, _ref1;
1393
+ if (back) {
1394
+ _ref = text, text = 2 <= _ref.length ? __slice.call(_ref, 0, _i = _ref.length - 1) : (_i = 0, []), ret = _ref[_i++];
1395
+ } else {
1396
+ _ref1 = text, ret = _ref1[0], text = 2 <= _ref1.length ? __slice.call(_ref1, 1) : [];
1397
+ }
1398
+ if (ret) {
1399
+ index = index + (back ? -1 : +1);
1400
+ }
1401
+ return ret;
1402
+ };
1403
+ while (ch = read_char()) {
1404
+ if (ch === char) {
1405
+ current_count++;
1406
+ } else if (ch === opposing_char) {
1407
+ current_count--;
1408
+ }
1409
+ if (current_count === 0) {
1410
+ return {
1411
+ index: index,
1412
+ current_count: current_count
1413
+ };
1414
+ }
1415
+ }
1416
+ return {
1417
+ index: -1,
1418
+ current_count: current_count
1419
+ };
1420
+ };
1421
+
1422
+ JQConsole.prototype._ProcessMatch = function(config, back, before_char) {
1423
+ var $collection, $prompt_relative, $prompt_which, char, current_count, found, index, opposing_char, text, _ref, _ref1, _ref2;
1424
+ _ref = back ? [config['closing_char'], config['opening_char']] : [config['opening_char'], config['closing_char']], char = _ref[0], opposing_char = _ref[1];
1425
+ _ref1 = this._GetDirectionals(back), $prompt_which = _ref1.$prompt_which, $prompt_relative = _ref1.$prompt_relative;
1426
+ current_count = 1;
1427
+ found = false;
1428
+ text = $prompt_which.html();
1429
+ if (!back) {
1430
+ text = text.slice(1);
1431
+ }
1432
+ if (before_char && back) {
1433
+ text = text.slice(0, -1);
1434
+ }
1435
+ _ref2 = this._WalkCharacters(text, char, opposing_char, current_count, back), index = _ref2.index, current_count = _ref2.current_count;
1436
+ if (index > -1) {
1437
+ this._Wrap($prompt_which, index, config.cls);
1438
+ found = true;
1439
+ } else {
1440
+ $collection = $prompt_relative.children();
1441
+ $collection = back ? Array.prototype.reverse.call($collection) : $collection;
1442
+ $collection.each((function(_this) {
1443
+ return function(i, elem) {
1444
+ var $elem, _ref3;
1445
+ $elem = $(elem).children().last();
1446
+ text = $elem.html();
1447
+ _ref3 = _this._WalkCharacters(text, char, opposing_char, current_count, back), index = _ref3.index, current_count = _ref3.current_count;
1448
+ if (index > -1) {
1449
+ if (!back) {
1450
+ index--;
1451
+ }
1452
+ _this._Wrap($elem, index, config.cls);
1453
+ found = true;
1454
+ return false;
1455
+ }
1456
+ };
1457
+ })(this));
1458
+ }
1459
+ return found;
1460
+ };
1461
+
1462
+ JQConsole.prototype._CheckMatchings = function(before_char) {
1463
+ var cls, config, current_char, found, _i, _len, _ref;
1464
+ current_char = before_char ? this.$prompt_left.text().slice(this.$prompt_left.text().length - 1) : this.$prompt_right.text()[0];
1465
+ _ref = this.matchings.clss;
1466
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1467
+ cls = _ref[_i];
1468
+ $('.' + cls, this.$console).contents().unwrap();
1469
+ }
1470
+ if (config = this.matchings.closings[current_char]) {
1471
+ found = this._ProcessMatch(config, true, before_char);
1472
+ } else if (config = this.matchings.openings[current_char]) {
1473
+ found = this._ProcessMatch(config, false, before_char);
1474
+ } else if (!before_char) {
1475
+ this._CheckMatchings(true);
1476
+ }
1477
+ if (before_char) {
1478
+ if (found) {
1479
+ return this._Wrap(this.$prompt_left, this.$prompt_left.html().length - 1, config.cls);
1480
+ }
1481
+ } else {
1482
+ if (found) {
1483
+ return this._Wrap(this.$prompt_right, 0, config.cls);
1484
+ }
1485
+ }
1486
+ };
1487
+
1488
+ JQConsole.prototype._HistoryPrevious = function() {
1489
+ if (!this.history_active) {
1490
+ return;
1491
+ }
1492
+ if (this.history_index <= 0) {
1493
+ return;
1494
+ }
1495
+ if (this.history_index === this.history.length) {
1496
+ this.history_new = this.GetPromptText();
1497
+ }
1498
+ return this.SetPromptText(this.history[--this.history_index]);
1499
+ };
1500
+
1501
+ JQConsole.prototype._HistoryNext = function() {
1502
+ if (!this.history_active) {
1503
+ return;
1504
+ }
1505
+ if (this.history_index >= this.history.length) {
1506
+ return;
1507
+ }
1508
+ if (this.history_index === this.history.length - 1) {
1509
+ this.history_index++;
1510
+ return this.SetPromptText(this.history_new);
1511
+ } else {
1512
+ return this.SetPromptText(this.history[++this.history_index]);
1513
+ }
1514
+ };
1515
+
1516
+ JQConsole.prototype._CheckComposition = function(e) {
1517
+ var key;
1518
+ key = e.keyCode || e.which;
1519
+ if (key === 229) {
1520
+ if (this.in_composition) {
1521
+ return this._UpdateComposition();
1522
+ } else {
1523
+ return this._StartComposition();
1524
+ }
1525
+ }
1526
+ };
1527
+
1528
+ JQConsole.prototype._StartComposition = function() {
1529
+ if (this.in_composition) {
1530
+ return;
1531
+ }
1532
+ this.in_composition = true;
1533
+ this._ShowComposition();
1534
+ return setTimeout(this._UpdateComposition, 0);
1535
+ };
1536
+
1537
+ JQConsole.prototype._EndComposition = function() {
1538
+ if (!this.in_composition) {
1539
+ return;
1540
+ }
1541
+ this._HideComposition();
1542
+ this.$prompt_left.text(this.$prompt_left.text() + this.$composition.text());
1543
+ this.$composition.text('');
1544
+ this.$input_source.val('');
1545
+ return this.in_composition = false;
1546
+ };
1547
+
1548
+ JQConsole.prototype._UpdateComposition = function(e) {
1549
+ var cb;
1550
+ cb = (function(_this) {
1551
+ return function() {
1552
+ if (!_this.in_composition) {
1553
+ return;
1554
+ }
1555
+ return _this.$composition.text(_this.$input_source.val());
1556
+ };
1557
+ })(this);
1558
+ return setTimeout(cb, 0);
1559
+ };
1560
+
1561
+ JQConsole.prototype._ShowComposition = function() {
1562
+ this.$composition.css('height', this.$prompt_cursor.height());
1563
+ this.$composition.empty();
1564
+ return this.$composition.appendTo(this.$prompt_left);
1565
+ };
1566
+
1567
+ JQConsole.prototype._HideComposition = function() {
1568
+ return this.$composition.detach();
1569
+ };
1570
+
1571
+ return JQConsole;
1572
+
1573
+ })();
1574
+
1575
+ $.fn.jqconsole = function(header, prompt_main, prompt_continue) {
1576
+ return new JQConsole(this, header, prompt_main, prompt_continue);
1577
+ };
1578
+
1579
+ $.fn.jqconsole.JQConsole = JQConsole;
1580
+
1581
+ $.fn.jqconsole.Ansi = Ansi;
1582
+
1583
+ }).call(this);