yetty 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +2 -0
  3. data/LICENSE +0 -0
  4. data/README.md +66 -0
  5. data/bin/yetty +9 -4
  6. data/lib/yetty.rb +15 -0
  7. data/lib/yetty/command.rb +136 -0
  8. data/lib/yetty/play.rb +23 -0
  9. data/lib/yetty/push.rb +44 -0
  10. data/lib/yetty/record.rb +73 -0
  11. data/lib/yetty/site.rb +23 -0
  12. data/lib/yetty/site/app.rb +91 -0
  13. data/lib/yetty/site/static/assets/term/bg-gradient.png +0 -0
  14. data/lib/yetty/site/static/config.rb +26 -0
  15. data/lib/yetty/site/static/css/fd-slider.css +1004 -0
  16. data/lib/yetty/site/static/css/fonts/bootstrap/glyphicons-halflings-regular.eot +0 -0
  17. data/lib/yetty/site/static/css/fonts/bootstrap/glyphicons-halflings-regular.svg +229 -0
  18. data/lib/yetty/site/static/css/fonts/bootstrap/glyphicons-halflings-regular.ttf +0 -0
  19. data/lib/yetty/site/static/css/fonts/bootstrap/glyphicons-halflings-regular.woff +0 -0
  20. data/lib/yetty/site/static/css/player.css +165 -0
  21. data/lib/yetty/site/static/css/styles.css +8035 -0
  22. data/lib/yetty/site/static/js/bootstrap.js +2323 -0
  23. data/lib/yetty/site/static/js/bootstrap.min.js +12 -0
  24. data/lib/yetty/site/static/js/config.json +429 -0
  25. data/lib/yetty/site/static/js/jquery-2.1.1.min.js +4 -0
  26. data/lib/yetty/site/static/js/nyan/runner.js +92 -0
  27. data/lib/yetty/site/static/js/nyan/three.min.js +724 -0
  28. data/lib/yetty/site/static/js/nyan/threex.nyancat.js +193 -0
  29. data/lib/yetty/site/static/js/nyan/threex.nyancatrainbow.js +89 -0
  30. data/lib/yetty/site/static/js/nyan/threex.nyancatsound.js +33 -0
  31. data/lib/yetty/site/static/js/nyan/threex.nyancatstars.js +116 -0
  32. data/lib/yetty/site/static/js/player/fd-slider.min.js +2 -0
  33. data/lib/yetty/site/static/js/player/player.js +371 -0
  34. data/lib/yetty/site/static/js/player/term.js +4177 -0
  35. data/lib/yetty/site/static/sass/_bootstrap-variables.scss +818 -0
  36. data/lib/yetty/site/static/sass/player.scss +139 -0
  37. data/lib/yetty/site/static/sass/styles.scss +3 -0
  38. data/lib/yetty/site/static/sounds/nyanlooped.mp3 +0 -0
  39. data/lib/yetty/site/static/sounds/nyanslow.mp3 +0 -0
  40. data/lib/yetty/site/views/about.haml +8 -0
  41. data/lib/yetty/site/views/index.haml +13 -0
  42. data/lib/yetty/site/views/layout.haml +33 -0
  43. data/lib/yetty/site/views/recording.haml +34 -0
  44. data/lib/yetty/site/views/recordings.haml +7 -0
  45. data/lib/yetty/site/views/user.haml +28 -0
  46. data/lib/yetty/site/views/users.haml +16 -0
  47. data/lib/yetty/ui.rb +103 -0
  48. data/lib/yetty/user.rb +42 -0
  49. data/lib/yetty/version.rb +4 -0
  50. data/yetty.gemspec +21 -0
  51. metadata +49 -16
@@ -0,0 +1,4177 @@
1
+ /**
2
+ * tty.js - an xterm emulator
3
+ * Christopher Jeffrey (https://github.com/chjj/tty.js)
4
+ *
5
+ * Originally forked from (with the author's permission):
6
+ *
7
+ * Fabrice Bellard's javascript vt100 for jslinux:
8
+ * http://bellard.org/jslinux/
9
+ * Copyright (c) 2011 Fabrice Bellard
10
+ * (Redistribution or commercial use is prohibited
11
+ * without the author's permission.)
12
+ *
13
+ * The original design remains. The terminal itself
14
+ * has been extended to include xterm CSI codes, among
15
+ * other features.
16
+ */
17
+
18
+ ;(function() {
19
+
20
+ /**
21
+ * Terminal Emulation References:
22
+ * http://vt100.net/
23
+ * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt
24
+ * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
25
+ * http://invisible-island.net/vttest/
26
+ * http://www.inwap.com/pdp10/ansicode.txt
27
+ * http://linux.die.net/man/4/console_codes
28
+ * http://linux.die.net/man/7/urxvt
29
+ */
30
+
31
+ 'use strict';
32
+
33
+ /**
34
+ * Shared
35
+ */
36
+
37
+ var window = this
38
+ , document = this.document;
39
+
40
+ /**
41
+ * EventEmitter
42
+ */
43
+
44
+ function EventEmitter() {
45
+ this._events = {};
46
+ }
47
+
48
+ EventEmitter.prototype.addListener = function(type, listener) {
49
+ this._events[type] = this._events[type] || [];
50
+ this._events[type].push(listener);
51
+ };
52
+
53
+ EventEmitter.prototype.on = EventEmitter.prototype.addListener;
54
+
55
+ EventEmitter.prototype.removeListener = function(type, listener) {
56
+ if (!this._events[type]) return;
57
+
58
+ var obj = this._events[type]
59
+ , i = obj.length;
60
+
61
+ while (i--) {
62
+ if (obj[i] === listener || obj[i].listener === listener) {
63
+ obj.splice(i, 1);
64
+ return;
65
+ }
66
+ }
67
+ };
68
+
69
+ EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
70
+
71
+ EventEmitter.prototype.removeAllListeners = function(type) {
72
+ if (this._events[type]) delete this._events[type];
73
+ };
74
+
75
+ EventEmitter.prototype.once = function(type, listener) {
76
+ function on() {
77
+ var args = Array.prototype.slice.call(arguments);
78
+ this.removeListener(type, on);
79
+ return listener.apply(this, args);
80
+ }
81
+ on.listener = listener;
82
+ return this.on(type, on);
83
+ };
84
+
85
+ EventEmitter.prototype.emit = function(type) {
86
+ if (!this._events[type]) return;
87
+
88
+ var args = Array.prototype.slice.call(arguments, 1)
89
+ , obj = this._events[type]
90
+ , l = obj.length
91
+ , i = 0;
92
+
93
+ for (; i < l; i++) {
94
+ obj[i].apply(this, args);
95
+ }
96
+ };
97
+
98
+ EventEmitter.prototype.listeners = function(type) {
99
+ return this._events[type] = this._events[type] || [];
100
+ };
101
+
102
+ /**
103
+ * States
104
+ */
105
+
106
+ var normal = 0
107
+ , escaped = 1
108
+ , csi = 2
109
+ , osc = 3
110
+ , charset = 4
111
+ , dcs = 5
112
+ , ignore = 6;
113
+
114
+ /**
115
+ * Terminal
116
+ */
117
+
118
+ function Terminal(cols, rows, handler) {
119
+ EventEmitter.call(this);
120
+
121
+ var options;
122
+ if (typeof cols === 'object') {
123
+ options = cols;
124
+ cols = options.cols;
125
+ rows = options.rows;
126
+ handler = options.handler;
127
+ }
128
+ this._options = options || {};
129
+
130
+ this.cols = cols || Terminal.geometry[0];
131
+ this.rows = rows || Terminal.geometry[1];
132
+
133
+ if (handler) {
134
+ this.on('data', handler);
135
+ }
136
+
137
+ this.ybase = 0;
138
+ this.ydisp = 0;
139
+ this.x = 0;
140
+ this.y = 0;
141
+ this.cursorState = 0;
142
+ this.cursorHidden = false;
143
+ this.convertEol = false;
144
+ this.state = 0;
145
+ this.queue = '';
146
+ this.scrollTop = 0;
147
+ this.scrollBottom = this.rows - 1;
148
+
149
+ // modes
150
+ this.applicationKeypad = false;
151
+ this.originMode = false;
152
+ this.insertMode = false;
153
+ this.wraparoundMode = false;
154
+ this.normal = null;
155
+
156
+ // charset
157
+ this.charset = null;
158
+ this.gcharset = null;
159
+ this.glevel = 0;
160
+ this.charsets = [null];
161
+
162
+ // mouse properties
163
+ this.decLocator;
164
+ this.x10Mouse;
165
+ this.vt200Mouse;
166
+ this.vt300Mouse;
167
+ this.normalMouse;
168
+ this.mouseEvents;
169
+ this.sendFocus;
170
+ this.utfMouse;
171
+ this.sgrMouse;
172
+ this.urxvtMouse;
173
+
174
+ // misc
175
+ this.element;
176
+ this.children;
177
+ this.refreshStart;
178
+ this.refreshEnd;
179
+ this.savedX;
180
+ this.savedY;
181
+ this.savedCols;
182
+
183
+ // stream
184
+ this.readable = true;
185
+ this.writable = true;
186
+
187
+ this.defAttr = (257 << 9) | 256;
188
+ this.curAttr = this.defAttr;
189
+
190
+ this.params = [];
191
+ this.currentParam = 0;
192
+ this.prefix = '';
193
+ this.postfix = '';
194
+
195
+ this.lines = [];
196
+ var i = this.rows;
197
+ while (i--) {
198
+ this.lines.push(this.blankLine());
199
+ }
200
+
201
+ this.tabs;
202
+ this.setupStops();
203
+ }
204
+
205
+ inherits(Terminal, EventEmitter);
206
+
207
+ /**
208
+ * Colors
209
+ */
210
+
211
+ // Colors 0-15
212
+ Terminal.colors = [
213
+ // dark:
214
+ '#2e3436',
215
+ '#cc0000',
216
+ '#4e9a06',
217
+ '#c4a000',
218
+ '#3465a4',
219
+ '#75507b',
220
+ '#06989a',
221
+ '#d3d7cf',
222
+ // bright:
223
+ '#555753',
224
+ '#ef2929',
225
+ '#8ae234',
226
+ '#fce94f',
227
+ '#729fcf',
228
+ '#ad7fa8',
229
+ '#34e2e2',
230
+ '#eeeeec'
231
+ ];
232
+
233
+ // Colors 16-255
234
+ // Much thanks to TooTallNate for writing this.
235
+ Terminal.colors = (function() {
236
+ var colors = Terminal.colors
237
+ , r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]
238
+ , i;
239
+
240
+ // 16-231
241
+ i = 0;
242
+ for (; i < 216; i++) {
243
+ out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]);
244
+ }
245
+
246
+ // 232-255 (grey)
247
+ i = 0;
248
+ for (; i < 24; i++) {
249
+ r = 8 + i * 10;
250
+ out(r, r, r);
251
+ }
252
+
253
+ function out(r, g, b) {
254
+ colors.push('#' + hex(r) + hex(g) + hex(b));
255
+ }
256
+
257
+ function hex(c) {
258
+ c = c.toString(16);
259
+ return c.length < 2 ? '0' + c : c;
260
+ }
261
+
262
+ return colors;
263
+ })();
264
+
265
+ // Default BG/FG
266
+ Terminal.defaultColors = {
267
+ bg: '#000000',
268
+ fg: '#f0f0f0'
269
+ };
270
+
271
+ Terminal.colors[256] = Terminal.defaultColors.bg;
272
+ Terminal.colors[257] = Terminal.defaultColors.fg;
273
+
274
+ /**
275
+ * Options
276
+ */
277
+
278
+ Terminal.termName = 'xterm';
279
+ Terminal.geometry = [80, 24];
280
+ Terminal.cursorBlink = true;
281
+ Terminal.visualBell = false;
282
+ Terminal.popOnBell = false;
283
+ Terminal.scrollback = 1000;
284
+ Terminal.screenKeys = false;
285
+ Terminal.programFeatures = false;
286
+ Terminal.debug = false;
287
+
288
+ /**
289
+ * Focused Terminal
290
+ */
291
+
292
+ Terminal.focus = null;
293
+
294
+ Terminal.prototype.focus = function() {
295
+ if (Terminal.focus === this) return;
296
+ if (Terminal.focus) {
297
+ Terminal.focus.cursorState = 0;
298
+ Terminal.focus.refresh(Terminal.focus.y, Terminal.focus.y);
299
+ if (Terminal.focus.sendFocus) Terminal.focus.send('\x1b[O');
300
+ }
301
+ Terminal.focus = this;
302
+ if (this.sendFocus) this.send('\x1b[I');
303
+ this.showCursor();
304
+ };
305
+
306
+ /**
307
+ * Global Events for key handling
308
+ */
309
+
310
+ Terminal.bindKeys = function() {
311
+ if (Terminal.focus) return;
312
+
313
+ // We could put an "if (Terminal.focus)" check
314
+ // here, but it shouldn't be necessary.
315
+ on(document, 'keydown', function(ev) {
316
+ return Terminal.focus.keyDown(ev);
317
+ }, true);
318
+
319
+ on(document, 'keypress', function(ev) {
320
+ return Terminal.focus.keyPress(ev);
321
+ }, true);
322
+ };
323
+
324
+ /**
325
+ * Open Terminal
326
+ */
327
+
328
+ Terminal.prototype.open = function(container) {
329
+ var self = this
330
+ , i = 0
331
+ , div;
332
+
333
+ this.element = document.createElement('div');
334
+ this.element.className = 'terminal';
335
+ this.children = [];
336
+
337
+ for (; i < this.rows; i++) {
338
+ div = document.createElement('div');
339
+ this.element.appendChild(div);
340
+ this.children.push(div);
341
+ }
342
+
343
+ container.appendChild(this.element)
344
+
345
+ this.refresh(0, this.rows - 1);
346
+
347
+ // Terminal.bindKeys();
348
+ this.focus();
349
+
350
+ this.startBlink();
351
+
352
+ on(this.element, 'mousedown', function() {
353
+ self.focus();
354
+ });
355
+
356
+ // This probably shouldn't work,
357
+ // ... but it does. Firefox's paste
358
+ // event seems to only work for textareas?
359
+ on(this.element, 'mousedown', function(ev) {
360
+ var button = ev.button != null
361
+ ? +ev.button
362
+ : ev.which != null
363
+ ? ev.which - 1
364
+ : null;
365
+
366
+ // Does IE9 do this?
367
+ if (~navigator.userAgent.indexOf('MSIE')) {
368
+ button = button === 1 ? 0 : button === 4 ? 1 : button;
369
+ }
370
+
371
+ if (button !== 2) return;
372
+
373
+ self.element.contentEditable = 'true';
374
+ setTimeout(function() {
375
+ self.element.contentEditable = 'inherit'; // 'false';
376
+ }, 1);
377
+ }, true);
378
+
379
+ on(this.element, 'paste', function(ev) {
380
+ if (ev.clipboardData) {
381
+ self.send(ev.clipboardData.getData('text/plain'));
382
+ } else if (window.clipboardData) {
383
+ self.send(window.clipboardData.getData('Text'));
384
+ }
385
+ // Not necessary. Do it anyway for good measure.
386
+ self.element.contentEditable = 'inherit';
387
+ return cancel(ev);
388
+ });
389
+
390
+ this.bindMouse();
391
+
392
+ // XXX - hack, move this somewhere else.
393
+ if (Terminal.brokenBold == null) {
394
+ Terminal.brokenBold = isBoldBroken();
395
+ }
396
+
397
+ // sync default bg/fg colors
398
+ this.element.style.backgroundColor = Terminal.defaultColors.bg;
399
+ this.element.style.color = Terminal.defaultColors.fg;
400
+
401
+ //this.emit('open');
402
+ };
403
+
404
+ // XTerm mouse events
405
+ // http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
406
+ // To better understand these
407
+ // the xterm code is very helpful:
408
+ // Relevant files:
409
+ // button.c, charproc.c, misc.c
410
+ // Relevant functions in xterm/button.c:
411
+ // BtnCode, EmitButtonCode, EditorButton, SendMousePosition
412
+ Terminal.prototype.bindMouse = function() {
413
+ var el = this.element
414
+ , self = this
415
+ , pressed = 32;
416
+
417
+ var wheelEvent = 'onmousewheel' in window
418
+ ? 'mousewheel'
419
+ : 'DOMMouseScroll';
420
+
421
+ // mouseup, mousedown, mousewheel
422
+ // left click: ^[[M 3<^[[M#3<
423
+ // mousewheel up: ^[[M`3>
424
+ function sendButton(ev) {
425
+ var button
426
+ , pos;
427
+
428
+ // get the xterm-style button
429
+ button = getButton(ev);
430
+
431
+ // get mouse coordinates
432
+ pos = getCoords(ev);
433
+ if (!pos) return;
434
+
435
+ sendEvent(button, pos);
436
+
437
+ switch (ev.type) {
438
+ case 'mousedown':
439
+ pressed = button;
440
+ break;
441
+ case 'mouseup':
442
+ // keep it at the left
443
+ // button, just in case.
444
+ pressed = 32;
445
+ break;
446
+ case wheelEvent:
447
+ // nothing. don't
448
+ // interfere with
449
+ // `pressed`.
450
+ break;
451
+ }
452
+ }
453
+
454
+ // motion example of a left click:
455
+ // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<
456
+ function sendMove(ev) {
457
+ var button = pressed
458
+ , pos;
459
+
460
+ pos = getCoords(ev);
461
+ if (!pos) return;
462
+
463
+ // buttons marked as motions
464
+ // are incremented by 32
465
+ button += 32;
466
+
467
+ sendEvent(button, pos);
468
+ }
469
+
470
+ // encode button and
471
+ // position to characters
472
+ function encode(data, ch) {
473
+ if (!self.utfMouse) {
474
+ if (ch === 255) return data.push(0);
475
+ if (ch > 127) ch = 127;
476
+ data.push(ch);
477
+ } else {
478
+ if (ch === 2047) return data.push(0);
479
+ if (ch < 127) {
480
+ data.push(ch);
481
+ } else {
482
+ if (ch > 2047) ch = 2047;
483
+ data.push(0xC0 | (ch >> 6));
484
+ data.push(0x80 | (ch & 0x3F));
485
+ }
486
+ }
487
+ }
488
+
489
+ // send a mouse event:
490
+ // regular/utf8: ^[[M Cb Cx Cy
491
+ // urxvt: ^[[ Cb ; Cx ; Cy M
492
+ // sgr: ^[[ Cb ; Cx ; Cy M/m
493
+ // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \r
494
+ // locator: CSI P e ; P b ; P r ; P c ; P p & w
495
+ function sendEvent(button, pos) {
496
+ // self.emit('mouse', {
497
+ // x: pos.x - 32,
498
+ // y: pos.x - 32,
499
+ // button: button
500
+ // });
501
+
502
+ if (self.vt300Mouse) {
503
+ // NOTE: Unstable.
504
+ // http://www.vt100.net/docs/vt3xx-gp/chapter15.html
505
+ button &= 3;
506
+ pos.x -= 32;
507
+ pos.y -= 32;
508
+ var data = '\x1b[24';
509
+ if (button === 0) data += '1';
510
+ else if (button === 1) data += '3';
511
+ else if (button === 2) data += '5';
512
+ else if (button === 3) return;
513
+ else data += '0';
514
+ data += '~[' + pos.x + ',' + pos.y + ']\r';
515
+ self.send(data);
516
+ return;
517
+ }
518
+
519
+ if (self.decLocator) {
520
+ // NOTE: Unstable.
521
+ button &= 3;
522
+ pos.x -= 32;
523
+ pos.y -= 32;
524
+ if (button === 0) button = 2;
525
+ else if (button === 1) button = 4;
526
+ else if (button === 2) button = 6;
527
+ else if (button === 3) button = 3;
528
+ self.send('\x1b['
529
+ + button
530
+ + ';'
531
+ + (button === 3 ? 4 : 0)
532
+ + ';'
533
+ + pos.y
534
+ + ';'
535
+ + pos.x
536
+ + ';'
537
+ + (pos.page || 0)
538
+ + '&w');
539
+ return;
540
+ }
541
+
542
+ if (self.urxvtMouse) {
543
+ pos.x -= 32;
544
+ pos.y -= 32;
545
+ pos.x++;
546
+ pos.y++;
547
+ self.send('\x1b[' + button + ';' + pos.x + ';' + pos.y + 'M');
548
+ return;
549
+ }
550
+
551
+ if (self.sgrMouse) {
552
+ pos.x -= 32;
553
+ pos.y -= 32;
554
+ self.send('\x1b[<'
555
+ + ((button & 3) === 3 ? button & ~3 : button)
556
+ + ';'
557
+ + pos.x
558
+ + ';'
559
+ + pos.y
560
+ + ((button & 3) === 3 ? 'm' : 'M'));
561
+ return;
562
+ }
563
+
564
+ var data = [];
565
+
566
+ encode(data, button);
567
+ encode(data, pos.x);
568
+ encode(data, pos.y);
569
+
570
+ self.send('\x1b[M' + String.fromCharCode.apply(String, data));
571
+ }
572
+
573
+ function getButton(ev) {
574
+ var button
575
+ , shift
576
+ , meta
577
+ , ctrl
578
+ , mod;
579
+
580
+ // two low bits:
581
+ // 0 = left
582
+ // 1 = middle
583
+ // 2 = right
584
+ // 3 = release
585
+ // wheel up/down:
586
+ // 1, and 2 - with 64 added
587
+ switch (ev.type) {
588
+ case 'mousedown':
589
+ button = ev.button != null
590
+ ? +ev.button
591
+ : ev.which != null
592
+ ? ev.which - 1
593
+ : null;
594
+
595
+ if (~navigator.userAgent.indexOf('MSIE')) {
596
+ button = button === 1 ? 0 : button === 4 ? 1 : button;
597
+ }
598
+ break;
599
+ case 'mouseup':
600
+ button = 3;
601
+ break;
602
+ case 'DOMMouseScroll':
603
+ button = ev.detail < 0
604
+ ? 64
605
+ : 65;
606
+ break;
607
+ case 'mousewheel':
608
+ button = ev.wheelDeltaY > 0
609
+ ? 64
610
+ : 65;
611
+ break;
612
+ }
613
+
614
+ // next three bits are the modifiers:
615
+ // 4 = shift, 8 = meta, 16 = control
616
+ shift = ev.shiftKey ? 4 : 0;
617
+ meta = ev.metaKey ? 8 : 0;
618
+ ctrl = ev.ctrlKey ? 16 : 0;
619
+ mod = shift | meta | ctrl;
620
+
621
+ // no mods
622
+ if (self.vt200Mouse) {
623
+ // ctrl only
624
+ mod &= ctrl;
625
+ } else if (!self.normalMouse) {
626
+ mod = 0;
627
+ }
628
+
629
+ // increment to SP
630
+ button = (32 + (mod << 2)) + button;
631
+
632
+ return button;
633
+ }
634
+
635
+ // mouse coordinates measured in cols/rows
636
+ function getCoords(ev) {
637
+ var x, y, w, h, el;
638
+
639
+ // ignore browsers without pageX for now
640
+ if (ev.pageX == null) return;
641
+
642
+ x = ev.pageX;
643
+ y = ev.pageY;
644
+ el = self.element;
645
+
646
+ // should probably check offsetParent
647
+ // but this is more portable
648
+ while (el !== document.documentElement) {
649
+ x -= el.offsetLeft;
650
+ y -= el.offsetTop;
651
+ el = el.parentNode;
652
+ }
653
+
654
+ // convert to cols/rows
655
+ w = self.element.clientWidth;
656
+ h = self.element.clientHeight;
657
+ x = ((x / w) * self.cols) | 0;
658
+ y = ((y / h) * self.rows) | 0;
659
+
660
+ // be sure to avoid sending
661
+ // bad positions to the program
662
+ if (x < 0) x = 0;
663
+ if (x > self.cols) x = self.cols;
664
+ if (y < 0) y = 0;
665
+ if (y > self.rows) y = self.rows;
666
+
667
+ // xterm sends raw bytes and
668
+ // starts at 32 (SP) for each.
669
+ x += 32;
670
+ y += 32;
671
+
672
+ return {
673
+ x: x,
674
+ y: y,
675
+ down: ev.type === 'mousedown',
676
+ up: ev.type === 'mouseup',
677
+ wheel: ev.type === wheelEvent,
678
+ move: ev.type === 'mousemove'
679
+ };
680
+ }
681
+
682
+ on(el, 'mousedown', function(ev) {
683
+ if (!self.mouseEvents) return;
684
+
685
+ // send the button
686
+ sendButton(ev);
687
+
688
+ // ensure focus
689
+ self.focus();
690
+
691
+ // fix for odd bug
692
+ if (self.vt200Mouse) {
693
+ sendButton({ __proto__: ev, type: 'mouseup' });
694
+ return cancel(ev);
695
+ }
696
+
697
+ // bind events
698
+ if (self.normalMouse) on(document, 'mousemove', sendMove);
699
+
700
+ // x10 compatibility mode can't send button releases
701
+ if (!self.x10Mouse) {
702
+ on(document, 'mouseup', function up(ev) {
703
+ sendButton(ev);
704
+ if (self.normalMouse) off(document, 'mousemove', sendMove);
705
+ off(document, 'mouseup', up);
706
+ return cancel(ev);
707
+ });
708
+ }
709
+
710
+ return cancel(ev);
711
+ });
712
+
713
+ on(el, wheelEvent, function(ev) {
714
+ if (!self.mouseEvents) return;
715
+ if (self.x10Mouse
716
+ || self.vt300Mouse
717
+ || self.decLocator) return;
718
+ sendButton(ev);
719
+ return cancel(ev);
720
+ });
721
+
722
+ // allow mousewheel scrolling in
723
+ // the shell for example
724
+ on(el, wheelEvent, function(ev) {
725
+ if (self.mouseEvents) return;
726
+ if (self.applicationKeypad) return;
727
+ if (ev.type === 'DOMMouseScroll') {
728
+ self.scrollDisp(ev.detail < 0 ? -5 : 5);
729
+ } else {
730
+ self.scrollDisp(ev.wheelDeltaY > 0 ? -5 : 5);
731
+ }
732
+ return cancel(ev);
733
+ });
734
+ };
735
+
736
+ /**
737
+ * Destroy Terminal
738
+ */
739
+
740
+ Terminal.prototype.destroy = function() {
741
+ this.readable = false;
742
+ this.writable = false;
743
+ this._events = {};
744
+ this.handler = function() {};
745
+ this.write = function() {};
746
+ //this.emit('close');
747
+ };
748
+
749
+ /**
750
+ * Rendering Engine
751
+ */
752
+
753
+ // In the screen buffer, each character
754
+ // is stored as a an array with a character
755
+ // and a 32-bit integer.
756
+ // First value: a utf-16 character.
757
+ // Second value:
758
+ // Next 9 bits: background color (0-511).
759
+ // Next 9 bits: foreground color (0-511).
760
+ // Next 14 bits: a mask for misc. flags:
761
+ // 1=bold, 2=underline, 4=inverse
762
+
763
+ Terminal.prototype.refresh = function(start, end) {
764
+ var x
765
+ , y
766
+ , i
767
+ , line
768
+ , out
769
+ , ch
770
+ , width
771
+ , data
772
+ , attr
773
+ , fgColor
774
+ , bgColor
775
+ , flags
776
+ , row
777
+ , parent;
778
+
779
+ if (end - start >= this.rows / 2) {
780
+ parent = this.element.parentNode;
781
+ if (parent) parent.removeChild(this.element);
782
+ }
783
+
784
+ width = this.cols;
785
+ y = start;
786
+
787
+ for (; y <= end; y++) {
788
+ row = y + this.ydisp;
789
+
790
+ line = this.lines[row];
791
+ out = '';
792
+
793
+ if (y === this.y
794
+ && this.cursorState
795
+ && this.ydisp === this.ybase
796
+ && !this.cursorHidden) {
797
+ x = this.x;
798
+ } else {
799
+ x = -1;
800
+ }
801
+
802
+ attr = this.defAttr;
803
+ i = 0;
804
+
805
+ for (; i < width; i++) {
806
+ data = line[i][0];
807
+ ch = line[i][1];
808
+
809
+ if (i === x) data = -1;
810
+
811
+ if (data !== attr) {
812
+ if (attr !== this.defAttr) {
813
+ out += '</span>';
814
+ }
815
+ if (data !== this.defAttr) {
816
+ if (data === -1) {
817
+ out += '<span class="reverse-video">';
818
+ } else {
819
+ out += '<span style="';
820
+
821
+ bgColor = data & 0x1ff;
822
+ fgColor = (data >> 9) & 0x1ff;
823
+ flags = data >> 18;
824
+
825
+ if (flags & 1) {
826
+ if (!Terminal.brokenBold) {
827
+ out += 'font-weight:bold;';
828
+ }
829
+ // see: XTerm*boldColors
830
+ if (fgColor < 8) fgColor += 8;
831
+ }
832
+
833
+ if (flags & 2) {
834
+ out += 'text-decoration:underline;';
835
+ }
836
+
837
+ if (bgColor !== 256) {
838
+ out += 'background-color:'
839
+ + Terminal.colors[bgColor]
840
+ + ';';
841
+ }
842
+
843
+ if (fgColor !== 257) {
844
+ out += 'color:'
845
+ + Terminal.colors[fgColor]
846
+ + ';';
847
+ }
848
+
849
+ out += '">';
850
+ }
851
+ }
852
+ }
853
+
854
+ switch (ch) {
855
+ case '&':
856
+ out += '&amp;';
857
+ break;
858
+ case '<':
859
+ out += '&lt;';
860
+ break;
861
+ case '>':
862
+ out += '&gt;';
863
+ break;
864
+ default:
865
+ if (ch <= ' ') {
866
+ out += '&nbsp;';
867
+ } else {
868
+ out += ch;
869
+ }
870
+ break;
871
+ }
872
+
873
+ attr = data;
874
+ }
875
+
876
+ if (attr !== this.defAttr) {
877
+ out += '</span>';
878
+ }
879
+
880
+ this.children[y].innerHTML = out;
881
+ }
882
+
883
+ if (parent) parent.appendChild(this.element);
884
+ };
885
+
886
+ Terminal.prototype.cursorBlink = function() {
887
+ if (Terminal.focus !== this) return;
888
+ this.cursorState ^= 1;
889
+ this.refresh(this.y, this.y);
890
+ };
891
+
892
+ Terminal.prototype.showCursor = function() {
893
+ if (!this.cursorState) {
894
+ this.cursorState = 1;
895
+ this.refresh(this.y, this.y);
896
+ } else {
897
+ // Temporarily disabled:
898
+ // this.refreshBlink();
899
+ }
900
+ };
901
+
902
+ Terminal.prototype.startBlink = function() {
903
+ if (!Terminal.cursorBlink) return;
904
+ var self = this;
905
+ this._blinker = function() {
906
+ self.cursorBlink();
907
+ };
908
+ this._blink = setInterval(this._blinker, 500);
909
+ };
910
+
911
+ Terminal.prototype.refreshBlink = function() {
912
+ if (!Terminal.cursorBlink) return;
913
+ clearInterval(this._blink);
914
+ this._blink = setInterval(this._blinker, 500);
915
+ };
916
+
917
+ Terminal.prototype.scroll = function() {
918
+ var row;
919
+
920
+ if (++this.ybase === Terminal.scrollback) {
921
+ this.ybase = this.ybase / 2 | 0;
922
+ this.lines = this.lines.slice(-(this.ybase + this.rows) + 1);
923
+ }
924
+
925
+ this.ydisp = this.ybase;
926
+
927
+ // last line
928
+ row = this.ybase + this.rows - 1;
929
+
930
+ // subtract the bottom scroll region
931
+ row -= this.rows - 1 - this.scrollBottom;
932
+
933
+ if (row === this.lines.length) {
934
+ // potential optimization:
935
+ // pushing is faster than splicing
936
+ // when they amount to the same
937
+ // behavior.
938
+ this.lines.push(this.blankLine());
939
+ } else {
940
+ // add our new line
941
+ this.lines.splice(row, 0, this.blankLine());
942
+ }
943
+
944
+ if (this.scrollTop !== 0) {
945
+ if (this.ybase !== 0) {
946
+ this.ybase--;
947
+ this.ydisp = this.ybase;
948
+ }
949
+ this.lines.splice(this.ybase + this.scrollTop, 1);
950
+ }
951
+
952
+ // this.maxRange();
953
+ this.updateRange(this.scrollTop);
954
+ this.updateRange(this.scrollBottom);
955
+ };
956
+
957
+ Terminal.prototype.scrollDisp = function(disp) {
958
+ this.ydisp += disp;
959
+
960
+ if (this.ydisp > this.ybase) {
961
+ this.ydisp = this.ybase;
962
+ } else if (this.ydisp < 0) {
963
+ this.ydisp = 0;
964
+ }
965
+
966
+ this.refresh(0, this.rows - 1);
967
+ };
968
+
969
+ Terminal.prototype.write = function(data) {
970
+ var l = data.length
971
+ , i = 0
972
+ , cs
973
+ , ch;
974
+
975
+ this.refreshStart = this.y;
976
+ this.refreshEnd = this.y;
977
+
978
+ if (this.ybase !== this.ydisp) {
979
+ this.ydisp = this.ybase;
980
+ this.maxRange();
981
+ }
982
+
983
+ // this.log(JSON.stringify(data.replace(/\x1b/g, '^[')));
984
+
985
+ for (; i < l; i++) {
986
+ ch = data[i];
987
+ switch (this.state) {
988
+ case normal:
989
+ switch (ch) {
990
+ // '\0'
991
+ // case '\0':
992
+ // break;
993
+
994
+ // '\a'
995
+ case '\x07':
996
+ this.bell();
997
+ break;
998
+
999
+ // '\n', '\v', '\f'
1000
+ case '\n':
1001
+ case '\x0b':
1002
+ case '\x0c':
1003
+ if (this.convertEol) {
1004
+ this.x = 0;
1005
+ }
1006
+ this.y++;
1007
+ if (this.y > this.scrollBottom) {
1008
+ this.y--;
1009
+ this.scroll();
1010
+ }
1011
+ break;
1012
+
1013
+ // '\r'
1014
+ case '\r':
1015
+ this.x = 0;
1016
+ break;
1017
+
1018
+ // '\b'
1019
+ case '\x08':
1020
+ if (this.x > 0) {
1021
+ this.x--;
1022
+ }
1023
+ break;
1024
+
1025
+ // '\t'
1026
+ case '\t':
1027
+ this.x = this.nextStop();
1028
+ break;
1029
+
1030
+ // shift out
1031
+ case '\x0e':
1032
+ this.setgLevel(1);
1033
+ break;
1034
+
1035
+ // shift in
1036
+ case '\x0f':
1037
+ this.setgLevel(0);
1038
+ break;
1039
+
1040
+ // '\e'
1041
+ case '\x1b':
1042
+ this.state = escaped;
1043
+ break;
1044
+
1045
+ default:
1046
+ // ' '
1047
+ if (ch >= ' ') {
1048
+ if (this.charset && this.charset[ch]) {
1049
+ ch = this.charset[ch];
1050
+ }
1051
+ if (this.x >= this.cols) {
1052
+ this.x = 0;
1053
+ this.y++;
1054
+ if (this.y > this.scrollBottom) {
1055
+ this.y--;
1056
+ this.scroll();
1057
+ }
1058
+ }
1059
+ this.lines[this.y + this.ybase][this.x] = [this.curAttr, ch];
1060
+ this.x++;
1061
+ this.updateRange(this.y);
1062
+ }
1063
+ break;
1064
+ }
1065
+ break;
1066
+ case escaped:
1067
+ switch (ch) {
1068
+ // ESC [ Control Sequence Introducer ( CSI is 0x9b).
1069
+ case '[':
1070
+ this.params = [];
1071
+ this.currentParam = 0;
1072
+ this.state = csi;
1073
+ break;
1074
+
1075
+ // ESC ] Operating System Command ( OSC is 0x9d).
1076
+ case ']':
1077
+ this.params = [];
1078
+ this.currentParam = 0;
1079
+ this.state = osc;
1080
+ break;
1081
+
1082
+ // ESC P Device Control String ( DCS is 0x90).
1083
+ case 'P':
1084
+ this.params = [];
1085
+ this.currentParam = 0;
1086
+ this.state = dcs;
1087
+ break;
1088
+
1089
+ // ESC _ Application Program Command ( APC is 0x9f).
1090
+ case '_':
1091
+ this.state = ignore;
1092
+ break;
1093
+
1094
+ // ESC ^ Privacy Message ( PM is 0x9e).
1095
+ case '^':
1096
+ this.state = ignore;
1097
+ break;
1098
+
1099
+ // ESC c Full Reset (RIS).
1100
+ case 'c':
1101
+ this.reset();
1102
+ break;
1103
+
1104
+ // ESC E Next Line ( NEL is 0x85).
1105
+ // ESC D Index ( IND is 0x84).
1106
+ case 'E':
1107
+ this.x = 0;
1108
+ ;
1109
+ case 'D':
1110
+ this.index();
1111
+ break;
1112
+
1113
+ // ESC M Reverse Index ( RI is 0x8d).
1114
+ case 'M':
1115
+ this.reverseIndex();
1116
+ break;
1117
+
1118
+ // ESC % Select default/utf-8 character set.
1119
+ // @ = default, G = utf-8
1120
+ case '%':
1121
+ //this.charset = null;
1122
+ this.setgLevel(0);
1123
+ this.setgCharset(0, Terminal.charsets.US);
1124
+ this.state = normal;
1125
+ i++;
1126
+ break;
1127
+
1128
+ // ESC (,),*,+,-,. Designate G0-G2 Character Set.
1129
+ case '(': // <-- this seems to get all the attention
1130
+ case ')':
1131
+ case '*':
1132
+ case '+':
1133
+ case '-':
1134
+ case '.':
1135
+ switch (ch) {
1136
+ case '(':
1137
+ this.gcharset = 0;
1138
+ break;
1139
+ case ')':
1140
+ this.gcharset = 1;
1141
+ break;
1142
+ case '*':
1143
+ this.gcharset = 2;
1144
+ break;
1145
+ case '+':
1146
+ this.gcharset = 3;
1147
+ break;
1148
+ case '-':
1149
+ this.gcharset = 1;
1150
+ break;
1151
+ case '.':
1152
+ this.gcharset = 2;
1153
+ break;
1154
+ }
1155
+ this.state = charset;
1156
+ break;
1157
+
1158
+ // Designate G3 Character Set (VT300).
1159
+ // A = ISO Latin-1 Supplemental.
1160
+ // Not implemented.
1161
+ case '/':
1162
+ this.gcharset = 3;
1163
+ this.state = charset;
1164
+ i--;
1165
+ break;
1166
+
1167
+ // ESC N
1168
+ // Single Shift Select of G2 Character Set
1169
+ // ( SS2 is 0x8e). This affects next character only.
1170
+ case 'N':
1171
+ break;
1172
+ // ESC O
1173
+ // Single Shift Select of G3 Character Set
1174
+ // ( SS3 is 0x8f). This affects next character only.
1175
+ case 'O':
1176
+ break;
1177
+ // ESC n
1178
+ // Invoke the G2 Character Set as GL (LS2).
1179
+ case 'n':
1180
+ this.setgLevel(2);
1181
+ break;
1182
+ // ESC o
1183
+ // Invoke the G3 Character Set as GL (LS3).
1184
+ case 'o':
1185
+ this.setgLevel(3);
1186
+ break;
1187
+ // ESC |
1188
+ // Invoke the G3 Character Set as GR (LS3R).
1189
+ case '|':
1190
+ this.setgLevel(3);
1191
+ break;
1192
+ // ESC }
1193
+ // Invoke the G2 Character Set as GR (LS2R).
1194
+ case '}':
1195
+ this.setgLevel(2);
1196
+ break;
1197
+ // ESC ~
1198
+ // Invoke the G1 Character Set as GR (LS1R).
1199
+ case '~':
1200
+ this.setgLevel(1);
1201
+ break;
1202
+
1203
+ // ESC 7 Save Cursor (DECSC).
1204
+ case '7':
1205
+ this.saveCursor();
1206
+ this.state = normal;
1207
+ break;
1208
+
1209
+ // ESC 8 Restore Cursor (DECRC).
1210
+ case '8':
1211
+ this.restoreCursor();
1212
+ this.state = normal;
1213
+ break;
1214
+
1215
+ // ESC # 3 DEC line height/width
1216
+ case '#':
1217
+ this.state = normal;
1218
+ i++;
1219
+ break;
1220
+
1221
+ // ESC H Tab Set (HTS is 0x88).
1222
+ case 'H':
1223
+ this.tabSet();
1224
+ break;
1225
+
1226
+ // ESC = Application Keypad (DECPAM).
1227
+ case '=':
1228
+ this.log('Serial port requested application keypad.');
1229
+ this.applicationKeypad = true;
1230
+ this.state = normal;
1231
+ break;
1232
+
1233
+ // ESC > Normal Keypad (DECPNM).
1234
+ case '>':
1235
+ this.log('Switching back to normal keypad.');
1236
+ this.applicationKeypad = false;
1237
+ this.state = normal;
1238
+ break;
1239
+
1240
+ default:
1241
+ this.state = normal;
1242
+ this.error('Unknown ESC control: %s.', ch);
1243
+ break;
1244
+ }
1245
+ break;
1246
+
1247
+ case charset:
1248
+ switch (ch) {
1249
+ case '0': // DEC Special Character and Line Drawing Set.
1250
+ cs = Terminal.charsets.SCLD;
1251
+ break;
1252
+ case 'A': // UK
1253
+ cs = Terminal.charsets.UK;
1254
+ break;
1255
+ case 'B': // United States (USASCII).
1256
+ cs = Terminal.charsets.US;
1257
+ break;
1258
+ case '4': // Dutch
1259
+ cs = Terminal.charsets.Dutch;
1260
+ break;
1261
+ case 'C': // Finnish
1262
+ case '5':
1263
+ cs = Terminal.charsets.Finnish;
1264
+ break;
1265
+ case 'R': // French
1266
+ cs = Terminal.charsets.French;
1267
+ break;
1268
+ case 'Q': // FrenchCanadian
1269
+ cs = Terminal.charsets.FrenchCanadian;
1270
+ break;
1271
+ case 'K': // German
1272
+ cs = Terminal.charsets.German;
1273
+ break;
1274
+ case 'Y': // Italian
1275
+ cs = Terminal.charsets.Italian;
1276
+ break;
1277
+ case 'E': // NorwegianDanish
1278
+ case '6':
1279
+ cs = Terminal.charsets.NorwegianDanish;
1280
+ break;
1281
+ case 'Z': // Spanish
1282
+ cs = Terminal.charsets.Spanish;
1283
+ break;
1284
+ case 'H': // Swedish
1285
+ case '7':
1286
+ cs = Terminal.charsets.Swedish;
1287
+ break;
1288
+ case '=': // Swiss
1289
+ cs = Terminal.charsets.Swiss;
1290
+ break;
1291
+ case '/': // ISOLatin (actually /A)
1292
+ cs = Terminal.charsets.ISOLatin;
1293
+ i++;
1294
+ break;
1295
+ default: // Default
1296
+ cs = Terminal.charsets.US;
1297
+ break;
1298
+ }
1299
+ this.setgCharset(this.gcharset, cs);
1300
+ this.gcharset = null;
1301
+ this.state = normal;
1302
+ break;
1303
+
1304
+ case osc:
1305
+ // OSC Ps ; Pt ST
1306
+ // OSC Ps ; Pt BEL
1307
+ // Set Text Parameters.
1308
+ if (ch === '\x1b' || ch === '\x07') {
1309
+ if (ch === '\x1b') i++;
1310
+
1311
+ this.params.push(this.currentParam);
1312
+
1313
+ switch (this.params[0]) {
1314
+ case 0:
1315
+ case 1:
1316
+ case 2:
1317
+ if (this.params[1]) {
1318
+ this.title = this.params[1];
1319
+ this.handleTitle(this.title);
1320
+ }
1321
+ break;
1322
+ case 3:
1323
+ // set X property
1324
+ break;
1325
+ case 4:
1326
+ case 5:
1327
+ // change dynamic colors
1328
+ break;
1329
+ case 10:
1330
+ case 11:
1331
+ case 12:
1332
+ case 13:
1333
+ case 14:
1334
+ case 15:
1335
+ case 16:
1336
+ case 17:
1337
+ case 18:
1338
+ case 19:
1339
+ // change dynamic ui colors
1340
+ break;
1341
+ case 46:
1342
+ // change log file
1343
+ break;
1344
+ case 50:
1345
+ // dynamic font
1346
+ break;
1347
+ case 51:
1348
+ // emacs shell
1349
+ break;
1350
+ case 52:
1351
+ // manipulate selection data
1352
+ break;
1353
+ case 104:
1354
+ case 105:
1355
+ case 110:
1356
+ case 111:
1357
+ case 112:
1358
+ case 113:
1359
+ case 114:
1360
+ case 115:
1361
+ case 116:
1362
+ case 117:
1363
+ case 118:
1364
+ // reset colors
1365
+ break;
1366
+ }
1367
+
1368
+ this.params = [];
1369
+ this.currentParam = 0;
1370
+ this.state = normal;
1371
+ } else {
1372
+ if (!this.params.length) {
1373
+ if (ch >= '0' && ch <= '9') {
1374
+ this.currentParam =
1375
+ this.currentParam * 10 + ch.charCodeAt(0) - 48;
1376
+ } else if (ch === ';') {
1377
+ this.params.push(this.currentParam);
1378
+ this.currentParam = '';
1379
+ }
1380
+ } else {
1381
+ this.currentParam += ch;
1382
+ }
1383
+ }
1384
+ break;
1385
+
1386
+ case csi:
1387
+ // '?', '>', '!'
1388
+ if (ch === '?' || ch === '>' || ch === '!') {
1389
+ this.prefix = ch;
1390
+ break;
1391
+ }
1392
+
1393
+ // 0 - 9
1394
+ if (ch >= '0' && ch <= '9') {
1395
+ this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48;
1396
+ break;
1397
+ }
1398
+
1399
+ // '$', '"', ' ', '\''
1400
+ if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') {
1401
+ this.postfix = ch;
1402
+ break;
1403
+ }
1404
+
1405
+ this.params.push(this.currentParam);
1406
+ this.currentParam = 0;
1407
+
1408
+ // ';'
1409
+ if (ch === ';') break;
1410
+
1411
+ this.state = normal;
1412
+
1413
+ switch (ch) {
1414
+ // CSI Ps A
1415
+ // Cursor Up Ps Times (default = 1) (CUU).
1416
+ case 'A':
1417
+ this.cursorUp(this.params);
1418
+ break;
1419
+
1420
+ // CSI Ps B
1421
+ // Cursor Down Ps Times (default = 1) (CUD).
1422
+ case 'B':
1423
+ this.cursorDown(this.params);
1424
+ break;
1425
+
1426
+ // CSI Ps C
1427
+ // Cursor Forward Ps Times (default = 1) (CUF).
1428
+ case 'C':
1429
+ this.cursorForward(this.params);
1430
+ break;
1431
+
1432
+ // CSI Ps D
1433
+ // Cursor Backward Ps Times (default = 1) (CUB).
1434
+ case 'D':
1435
+ this.cursorBackward(this.params);
1436
+ break;
1437
+
1438
+ // CSI Ps ; Ps H
1439
+ // Cursor Position [row;column] (default = [1,1]) (CUP).
1440
+ case 'H':
1441
+ this.cursorPos(this.params);
1442
+ break;
1443
+
1444
+ // CSI Ps J Erase in Display (ED).
1445
+ case 'J':
1446
+ this.eraseInDisplay(this.params);
1447
+ break;
1448
+
1449
+ // CSI Ps K Erase in Line (EL).
1450
+ case 'K':
1451
+ this.eraseInLine(this.params);
1452
+ break;
1453
+
1454
+ // CSI Pm m Character Attributes (SGR).
1455
+ case 'm':
1456
+ this.charAttributes(this.params);
1457
+ break;
1458
+
1459
+ // CSI Ps n Device Status Report (DSR).
1460
+ case 'n':
1461
+ this.deviceStatus(this.params);
1462
+ break;
1463
+
1464
+ /**
1465
+ * Additions
1466
+ */
1467
+
1468
+ // CSI Ps @
1469
+ // Insert Ps (Blank) Character(s) (default = 1) (ICH).
1470
+ case '@':
1471
+ this.insertChars(this.params);
1472
+ break;
1473
+
1474
+ // CSI Ps E
1475
+ // Cursor Next Line Ps Times (default = 1) (CNL).
1476
+ case 'E':
1477
+ this.cursorNextLine(this.params);
1478
+ break;
1479
+
1480
+ // CSI Ps F
1481
+ // Cursor Preceding Line Ps Times (default = 1) (CNL).
1482
+ case 'F':
1483
+ this.cursorPrecedingLine(this.params);
1484
+ break;
1485
+
1486
+ // CSI Ps G
1487
+ // Cursor Character Absolute [column] (default = [row,1]) (CHA).
1488
+ case 'G':
1489
+ this.cursorCharAbsolute(this.params);
1490
+ break;
1491
+
1492
+ // CSI Ps L
1493
+ // Insert Ps Line(s) (default = 1) (IL).
1494
+ case 'L':
1495
+ this.insertLines(this.params);
1496
+ break;
1497
+
1498
+ // CSI Ps M
1499
+ // Delete Ps Line(s) (default = 1) (DL).
1500
+ case 'M':
1501
+ this.deleteLines(this.params);
1502
+ break;
1503
+
1504
+ // CSI Ps P
1505
+ // Delete Ps Character(s) (default = 1) (DCH).
1506
+ case 'P':
1507
+ this.deleteChars(this.params);
1508
+ break;
1509
+
1510
+ // CSI Ps X
1511
+ // Erase Ps Character(s) (default = 1) (ECH).
1512
+ case 'X':
1513
+ this.eraseChars(this.params);
1514
+ break;
1515
+
1516
+ // CSI Pm ` Character Position Absolute
1517
+ // [column] (default = [row,1]) (HPA).
1518
+ case '`':
1519
+ this.charPosAbsolute(this.params);
1520
+ break;
1521
+
1522
+ // 141 61 a * HPR -
1523
+ // Horizontal Position Relative
1524
+ case 'a':
1525
+ this.HPositionRelative(this.params);
1526
+ break;
1527
+
1528
+ // CSI P s c
1529
+ // Send Device Attributes (Primary DA).
1530
+ // CSI > P s c
1531
+ // Send Device Attributes (Secondary DA)
1532
+ case 'c':
1533
+ this.sendDeviceAttributes(this.params);
1534
+ break;
1535
+
1536
+ // CSI Pm d
1537
+ // Line Position Absolute [row] (default = [1,column]) (VPA).
1538
+ case 'd':
1539
+ this.linePosAbsolute(this.params);
1540
+ break;
1541
+
1542
+ // 145 65 e * VPR - Vertical Position Relative
1543
+ case 'e':
1544
+ this.VPositionRelative(this.params);
1545
+ break;
1546
+
1547
+ // CSI Ps ; Ps f
1548
+ // Horizontal and Vertical Position [row;column] (default =
1549
+ // [1,1]) (HVP).
1550
+ case 'f':
1551
+ this.HVPosition(this.params);
1552
+ break;
1553
+
1554
+ // CSI Pm h Set Mode (SM).
1555
+ // CSI ? Pm h - mouse escape codes, cursor escape codes
1556
+ case 'h':
1557
+ this.setMode(this.params);
1558
+ break;
1559
+
1560
+ // CSI Pm l Reset Mode (RM).
1561
+ // CSI ? Pm l
1562
+ case 'l':
1563
+ this.resetMode(this.params);
1564
+ break;
1565
+
1566
+ // CSI Ps ; Ps r
1567
+ // Set Scrolling Region [top;bottom] (default = full size of win-
1568
+ // dow) (DECSTBM).
1569
+ // CSI ? Pm r
1570
+ case 'r':
1571
+ this.setScrollRegion(this.params);
1572
+ break;
1573
+
1574
+ // CSI s
1575
+ // Save cursor (ANSI.SYS).
1576
+ case 's':
1577
+ this.saveCursor(this.params);
1578
+ break;
1579
+
1580
+ // CSI u
1581
+ // Restore cursor (ANSI.SYS).
1582
+ case 'u':
1583
+ this.restoreCursor(this.params);
1584
+ break;
1585
+
1586
+ /**
1587
+ * Lesser Used
1588
+ */
1589
+
1590
+ // CSI Ps I
1591
+ // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).
1592
+ case 'I':
1593
+ this.cursorForwardTab(this.params);
1594
+ break;
1595
+
1596
+ // CSI Ps S Scroll up Ps lines (default = 1) (SU).
1597
+ case 'S':
1598
+ this.scrollUp(this.params);
1599
+ break;
1600
+
1601
+ // CSI Ps T Scroll down Ps lines (default = 1) (SD).
1602
+ // CSI Ps ; Ps ; Ps ; Ps ; Ps T
1603
+ // CSI > Ps; Ps T
1604
+ case 'T':
1605
+ // if (this.prefix === '>') {
1606
+ // this.resetTitleModes(this.params);
1607
+ // break;
1608
+ // }
1609
+ // if (this.params.length > 2) {
1610
+ // this.initMouseTracking(this.params);
1611
+ // break;
1612
+ // }
1613
+ if (this.params.length < 2 && !this.prefix) {
1614
+ this.scrollDown(this.params);
1615
+ }
1616
+ break;
1617
+
1618
+ // CSI Ps Z
1619
+ // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).
1620
+ case 'Z':
1621
+ this.cursorBackwardTab(this.params);
1622
+ break;
1623
+
1624
+ // CSI Ps b Repeat the preceding graphic character Ps times (REP).
1625
+ case 'b':
1626
+ this.repeatPrecedingCharacter(this.params);
1627
+ break;
1628
+
1629
+ // CSI Ps g Tab Clear (TBC).
1630
+ case 'g':
1631
+ this.tabClear(this.params);
1632
+ break;
1633
+
1634
+ // CSI Pm i Media Copy (MC).
1635
+ // CSI ? Pm i
1636
+ // case 'i':
1637
+ // this.mediaCopy(this.params);
1638
+ // break;
1639
+
1640
+ // CSI Pm m Character Attributes (SGR).
1641
+ // CSI > Ps; Ps m
1642
+ // case 'm': // duplicate
1643
+ // if (this.prefix === '>') {
1644
+ // this.setResources(this.params);
1645
+ // } else {
1646
+ // this.charAttributes(this.params);
1647
+ // }
1648
+ // break;
1649
+
1650
+ // CSI Ps n Device Status Report (DSR).
1651
+ // CSI > Ps n
1652
+ // case 'n': // duplicate
1653
+ // if (this.prefix === '>') {
1654
+ // this.disableModifiers(this.params);
1655
+ // } else {
1656
+ // this.deviceStatus(this.params);
1657
+ // }
1658
+ // break;
1659
+
1660
+ // CSI > Ps p Set pointer mode.
1661
+ // CSI ! p Soft terminal reset (DECSTR).
1662
+ // CSI Ps$ p
1663
+ // Request ANSI mode (DECRQM).
1664
+ // CSI ? Ps$ p
1665
+ // Request DEC private mode (DECRQM).
1666
+ // CSI Ps ; Ps " p
1667
+ case 'p':
1668
+ switch (this.prefix) {
1669
+ // case '>':
1670
+ // this.setPointerMode(this.params);
1671
+ // break;
1672
+ case '!':
1673
+ this.softReset(this.params);
1674
+ break;
1675
+ // case '?':
1676
+ // if (this.postfix === '$') {
1677
+ // this.requestPrivateMode(this.params);
1678
+ // }
1679
+ // break;
1680
+ // default:
1681
+ // if (this.postfix === '"') {
1682
+ // this.setConformanceLevel(this.params);
1683
+ // } else if (this.postfix === '$') {
1684
+ // this.requestAnsiMode(this.params);
1685
+ // }
1686
+ // break;
1687
+ }
1688
+ break;
1689
+
1690
+ // CSI Ps q Load LEDs (DECLL).
1691
+ // CSI Ps SP q
1692
+ // CSI Ps " q
1693
+ // case 'q':
1694
+ // if (this.postfix === ' ') {
1695
+ // this.setCursorStyle(this.params);
1696
+ // break;
1697
+ // }
1698
+ // if (this.postfix === '"') {
1699
+ // this.setCharProtectionAttr(this.params);
1700
+ // break;
1701
+ // }
1702
+ // this.loadLEDs(this.params);
1703
+ // break;
1704
+
1705
+ // CSI Ps ; Ps r
1706
+ // Set Scrolling Region [top;bottom] (default = full size of win-
1707
+ // dow) (DECSTBM).
1708
+ // CSI ? Pm r
1709
+ // CSI Pt; Pl; Pb; Pr; Ps$ r
1710
+ // case 'r': // duplicate
1711
+ // if (this.prefix === '?') {
1712
+ // this.restorePrivateValues(this.params);
1713
+ // } else if (this.postfix === '$') {
1714
+ // this.setAttrInRectangle(this.params);
1715
+ // } else {
1716
+ // this.setScrollRegion(this.params);
1717
+ // }
1718
+ // break;
1719
+
1720
+ // CSI s Save cursor (ANSI.SYS).
1721
+ // CSI ? Pm s
1722
+ // case 's': // duplicate
1723
+ // if (this.prefix === '?') {
1724
+ // this.savePrivateValues(this.params);
1725
+ // } else {
1726
+ // this.saveCursor(this.params);
1727
+ // }
1728
+ // break;
1729
+
1730
+ // CSI Ps ; Ps ; Ps t
1731
+ // CSI Pt; Pl; Pb; Pr; Ps$ t
1732
+ // CSI > Ps; Ps t
1733
+ // CSI Ps SP t
1734
+ // case 't':
1735
+ // if (this.postfix === '$') {
1736
+ // this.reverseAttrInRectangle(this.params);
1737
+ // } else if (this.postfix === ' ') {
1738
+ // this.setWarningBellVolume(this.params);
1739
+ // } else {
1740
+ // if (this.prefix === '>') {
1741
+ // this.setTitleModeFeature(this.params);
1742
+ // } else {
1743
+ // this.manipulateWindow(this.params);
1744
+ // }
1745
+ // }
1746
+ // break;
1747
+
1748
+ // CSI u Restore cursor (ANSI.SYS).
1749
+ // CSI Ps SP u
1750
+ // case 'u': // duplicate
1751
+ // if (this.postfix === ' ') {
1752
+ // this.setMarginBellVolume(this.params);
1753
+ // } else {
1754
+ // this.restoreCursor(this.params);
1755
+ // }
1756
+ // break;
1757
+
1758
+ // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v
1759
+ // case 'v':
1760
+ // if (this.postfix === '$') {
1761
+ // this.copyRectagle(this.params);
1762
+ // }
1763
+ // break;
1764
+
1765
+ // CSI Pt ; Pl ; Pb ; Pr ' w
1766
+ // case 'w':
1767
+ // if (this.postfix === '\'') {
1768
+ // this.enableFilterRectangle(this.params);
1769
+ // }
1770
+ // break;
1771
+
1772
+ // CSI Ps x Request Terminal Parameters (DECREQTPARM).
1773
+ // CSI Ps x Select Attribute Change Extent (DECSACE).
1774
+ // CSI Pc; Pt; Pl; Pb; Pr$ x
1775
+ // case 'x':
1776
+ // if (this.postfix === '$') {
1777
+ // this.fillRectangle(this.params);
1778
+ // } else {
1779
+ // this.requestParameters(this.params);
1780
+ // //this.__(this.params);
1781
+ // }
1782
+ // break;
1783
+
1784
+ // CSI Ps ; Pu ' z
1785
+ // CSI Pt; Pl; Pb; Pr$ z
1786
+ // case 'z':
1787
+ // if (this.postfix === '\'') {
1788
+ // this.enableLocatorReporting(this.params);
1789
+ // } else if (this.postfix === '$') {
1790
+ // this.eraseRectangle(this.params);
1791
+ // }
1792
+ // break;
1793
+
1794
+ // CSI Pm ' {
1795
+ // CSI Pt; Pl; Pb; Pr$ {
1796
+ // case '{':
1797
+ // if (this.postfix === '\'') {
1798
+ // this.setLocatorEvents(this.params);
1799
+ // } else if (this.postfix === '$') {
1800
+ // this.selectiveEraseRectangle(this.params);
1801
+ // }
1802
+ // break;
1803
+
1804
+ // CSI Ps ' |
1805
+ // case '|':
1806
+ // if (this.postfix === '\'') {
1807
+ // this.requestLocatorPosition(this.params);
1808
+ // }
1809
+ // break;
1810
+
1811
+ // CSI P m SP }
1812
+ // Insert P s Column(s) (default = 1) (DECIC), VT420 and up.
1813
+ // case '}':
1814
+ // if (this.postfix === ' ') {
1815
+ // this.insertColumns(this.params);
1816
+ // }
1817
+ // break;
1818
+
1819
+ // CSI P m SP ~
1820
+ // Delete P s Column(s) (default = 1) (DECDC), VT420 and up
1821
+ // case '~':
1822
+ // if (this.postfix === ' ') {
1823
+ // this.deleteColumns(this.params);
1824
+ // }
1825
+ // break;
1826
+
1827
+ default:
1828
+ this.error('Unknown CSI code: %s.', ch);
1829
+ break;
1830
+ }
1831
+
1832
+ this.prefix = '';
1833
+ this.postfix = '';
1834
+ break;
1835
+
1836
+ case dcs:
1837
+ if (ch === '\x1b' || ch === '\x07') {
1838
+ if (ch === '\x1b') i++;
1839
+
1840
+ switch (this.prefix) {
1841
+ // User-Defined Keys (DECUDK).
1842
+ case '':
1843
+ break;
1844
+
1845
+ // Request Status String (DECRQSS).
1846
+ // test: echo -e '\eP$q"p\e\\'
1847
+ case '$q':
1848
+ var pt = this.currentParam
1849
+ , valid = false;
1850
+
1851
+ switch (pt) {
1852
+ // DECSCA
1853
+ case '"q':
1854
+ pt = '0"q';
1855
+ break;
1856
+
1857
+ // DECSCL
1858
+ case '"p':
1859
+ pt = '61"p';
1860
+ break;
1861
+
1862
+ // DECSTBM
1863
+ case 'r':
1864
+ pt = ''
1865
+ + (this.scrollTop + 1)
1866
+ + ';'
1867
+ + (this.scrollBottom + 1)
1868
+ + 'r';
1869
+ break;
1870
+
1871
+ // SGR
1872
+ case 'm':
1873
+ pt = '0m';
1874
+ break;
1875
+
1876
+ default:
1877
+ this.error('Unknown DCS Pt: %s.', pt);
1878
+ pt = '';
1879
+ break;
1880
+ }
1881
+
1882
+ this.send('\x1bP' + +valid + '$r' + pt + '\x1b\\');
1883
+ break;
1884
+
1885
+ // Set Termcap/Terminfo Data (xterm, experimental).
1886
+ case '+p':
1887
+ break;
1888
+
1889
+ // Request Termcap/Terminfo String (xterm, experimental)
1890
+ // Regular xterm does not even respond to this sequence.
1891
+ // This can cause a small glitch in vim.
1892
+ // test: echo -ne '\eP+q6b64\e\\'
1893
+ case '+q':
1894
+ var pt = this.currentParam
1895
+ , valid = false;
1896
+
1897
+ this.send('\x1bP' + +valid + '+r' + pt + '\x1b\\');
1898
+ break;
1899
+
1900
+ default:
1901
+ this.error('Unknown DCS prefix: %s.', this.prefix);
1902
+ break;
1903
+ }
1904
+
1905
+ this.currentParam = 0;
1906
+ this.prefix = '';
1907
+ this.state = normal;
1908
+ } else if (!this.currentParam) {
1909
+ if (!this.prefix && ch !== '$' && ch !== '+') {
1910
+ this.currentParam = ch;
1911
+ } else if (this.prefix.length === 2) {
1912
+ this.currentParam = ch;
1913
+ } else {
1914
+ this.prefix += ch;
1915
+ }
1916
+ } else {
1917
+ this.currentParam += ch;
1918
+ }
1919
+ break;
1920
+
1921
+ case ignore:
1922
+ // For PM and APC.
1923
+ if (ch === '\x1b' || ch === '\x07') {
1924
+ if (ch === '\x1b') i++;
1925
+ this.state = normal;
1926
+ }
1927
+ break;
1928
+ }
1929
+ }
1930
+
1931
+ this.updateRange(this.y);
1932
+ this.refresh(this.refreshStart, this.refreshEnd);
1933
+ };
1934
+
1935
+ Terminal.prototype.writeln = function(data) {
1936
+ this.write(data + '\r\n');
1937
+ };
1938
+
1939
+ Terminal.prototype.keyDown = function(ev) {
1940
+ var key;
1941
+
1942
+ switch (ev.keyCode) {
1943
+ // backspace
1944
+ case 8:
1945
+ if (ev.shiftKey) {
1946
+ key = '\x08'; // ^H
1947
+ break;
1948
+ }
1949
+ key = '\x7f'; // ^?
1950
+ break;
1951
+ // tab
1952
+ case 9:
1953
+ if (ev.shiftKey) {
1954
+ key = '\x1b[Z';
1955
+ break;
1956
+ }
1957
+ key = '\t';
1958
+ break;
1959
+ // return/enter
1960
+ case 13:
1961
+ key = '\r';
1962
+ break;
1963
+ // escape
1964
+ case 27:
1965
+ key = '\x1b';
1966
+ break;
1967
+ // left-arrow
1968
+ case 37:
1969
+ if (this.applicationKeypad) {
1970
+ key = '\x1bOD'; // SS3 as ^[O for 7-bit
1971
+ //key = '\x8fD'; // SS3 as 0x8f for 8-bit
1972
+ break;
1973
+ }
1974
+ key = '\x1b[D';
1975
+ break;
1976
+ // right-arrow
1977
+ case 39:
1978
+ if (this.applicationKeypad) {
1979
+ key = '\x1bOC';
1980
+ break;
1981
+ }
1982
+ key = '\x1b[C';
1983
+ break;
1984
+ // up-arrow
1985
+ case 38:
1986
+ if (this.applicationKeypad) {
1987
+ key = '\x1bOA';
1988
+ break;
1989
+ }
1990
+ if (ev.ctrlKey) {
1991
+ this.scrollDisp(-1);
1992
+ return cancel(ev);
1993
+ } else {
1994
+ key = '\x1b[A';
1995
+ }
1996
+ break;
1997
+ // down-arrow
1998
+ case 40:
1999
+ if (this.applicationKeypad) {
2000
+ key = '\x1bOB';
2001
+ break;
2002
+ }
2003
+ if (ev.ctrlKey) {
2004
+ this.scrollDisp(1);
2005
+ return cancel(ev);
2006
+ } else {
2007
+ key = '\x1b[B';
2008
+ }
2009
+ break;
2010
+ // delete
2011
+ case 46:
2012
+ key = '\x1b[3~';
2013
+ break;
2014
+ // insert
2015
+ case 45:
2016
+ key = '\x1b[2~';
2017
+ break;
2018
+ // home
2019
+ case 36:
2020
+ if (this.applicationKeypad) {
2021
+ key = '\x1bOH';
2022
+ break;
2023
+ }
2024
+ key = '\x1bOH';
2025
+ break;
2026
+ // end
2027
+ case 35:
2028
+ if (this.applicationKeypad) {
2029
+ key = '\x1bOF';
2030
+ break;
2031
+ }
2032
+ key = '\x1bOF';
2033
+ break;
2034
+ // page up
2035
+ case 33:
2036
+ if (ev.shiftKey) {
2037
+ this.scrollDisp(-(this.rows - 1));
2038
+ return cancel(ev);
2039
+ } else {
2040
+ key = '\x1b[5~';
2041
+ }
2042
+ break;
2043
+ // page down
2044
+ case 34:
2045
+ if (ev.shiftKey) {
2046
+ this.scrollDisp(this.rows - 1);
2047
+ return cancel(ev);
2048
+ } else {
2049
+ key = '\x1b[6~';
2050
+ }
2051
+ break;
2052
+ // F1
2053
+ case 112:
2054
+ key = '\x1bOP';
2055
+ break;
2056
+ // F2
2057
+ case 113:
2058
+ key = '\x1bOQ';
2059
+ break;
2060
+ // F3
2061
+ case 114:
2062
+ key = '\x1bOR';
2063
+ break;
2064
+ // F4
2065
+ case 115:
2066
+ key = '\x1bOS';
2067
+ break;
2068
+ // F5
2069
+ case 116:
2070
+ key = '\x1b[15~';
2071
+ break;
2072
+ // F6
2073
+ case 117:
2074
+ key = '\x1b[17~';
2075
+ break;
2076
+ // F7
2077
+ case 118:
2078
+ key = '\x1b[18~';
2079
+ break;
2080
+ // F8
2081
+ case 119:
2082
+ key = '\x1b[19~';
2083
+ break;
2084
+ // F9
2085
+ case 120:
2086
+ key = '\x1b[20~';
2087
+ break;
2088
+ // F10
2089
+ case 121:
2090
+ key = '\x1b[21~';
2091
+ break;
2092
+ // F11
2093
+ case 122:
2094
+ key = '\x1b[23~';
2095
+ break;
2096
+ // F12
2097
+ case 123:
2098
+ key = '\x1b[24~';
2099
+ break;
2100
+ default:
2101
+ // a-z and space
2102
+ if (ev.ctrlKey) {
2103
+ if (ev.keyCode >= 65 && ev.keyCode <= 90) {
2104
+ key = String.fromCharCode(ev.keyCode - 64);
2105
+ } else if (ev.keyCode === 32) {
2106
+ // NUL
2107
+ key = String.fromCharCode(0);
2108
+ } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {
2109
+ // escape, file sep, group sep, record sep, unit sep
2110
+ key = String.fromCharCode(ev.keyCode - 51 + 27);
2111
+ } else if (ev.keyCode === 56) {
2112
+ // delete
2113
+ key = String.fromCharCode(127);
2114
+ } else if (ev.keyCode === 219) {
2115
+ // ^[ - escape
2116
+ key = String.fromCharCode(27);
2117
+ } else if (ev.keyCode === 221) {
2118
+ // ^] - group sep
2119
+ key = String.fromCharCode(29);
2120
+ }
2121
+ } else if ((!isMac && ev.altKey) || (isMac && ev.metaKey)) {
2122
+ if (ev.keyCode >= 65 && ev.keyCode <= 90) {
2123
+ key = '\x1b' + String.fromCharCode(ev.keyCode + 32);
2124
+ } else if (ev.keyCode === 192) {
2125
+ key = '\x1b`';
2126
+ } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {
2127
+ key = '\x1b' + (ev.keyCode - 48);
2128
+ }
2129
+ }
2130
+ break;
2131
+ }
2132
+
2133
+ this.emit('keydown', ev);
2134
+
2135
+ if (key) {
2136
+ this.emit('key', key, ev);
2137
+
2138
+ this.showCursor();
2139
+ this.handler(key);
2140
+
2141
+ return cancel(ev);
2142
+ }
2143
+
2144
+ return true;
2145
+ };
2146
+
2147
+ Terminal.prototype.setgLevel = function(g) {
2148
+ this.glevel = g;
2149
+ this.charset = this.charsets[g];
2150
+ };
2151
+
2152
+ Terminal.prototype.setgCharset = function(g, charset) {
2153
+ this.charsets[g] = charset;
2154
+ if (this.glevel === g) {
2155
+ this.charset = charset;
2156
+ }
2157
+ };
2158
+
2159
+ Terminal.prototype.keyPress = function(ev) {
2160
+ var key;
2161
+
2162
+ cancel(ev);
2163
+
2164
+ if (ev.charCode) {
2165
+ key = ev.charCode;
2166
+ } else if (ev.which == null) {
2167
+ key = ev.keyCode;
2168
+ } else if (ev.which !== 0 && ev.charCode !== 0) {
2169
+ key = ev.which;
2170
+ } else {
2171
+ return false;
2172
+ }
2173
+
2174
+ if (!key || ev.ctrlKey || ev.altKey || ev.metaKey) return false;
2175
+
2176
+ key = String.fromCharCode(key);
2177
+
2178
+ this.emit('keypress', key, ev);
2179
+ this.emit('key', key, ev);
2180
+
2181
+ this.showCursor();
2182
+ this.handler(key);
2183
+
2184
+ return false;
2185
+ };
2186
+
2187
+ Terminal.prototype.send = function(data) {
2188
+ var self = this;
2189
+
2190
+ if (!this.queue) {
2191
+ setTimeout(function() {
2192
+ self.handler(self.queue);
2193
+ self.queue = '';
2194
+ }, 1);
2195
+ }
2196
+
2197
+ this.queue += data;
2198
+ };
2199
+
2200
+ Terminal.prototype.bell = function() {
2201
+ if (!Terminal.visualBell) return;
2202
+ var self = this;
2203
+ this.element.style.borderColor = 'white';
2204
+ setTimeout(function() {
2205
+ self.element.style.borderColor = '';
2206
+ }, 10);
2207
+ if (Terminal.popOnBell) this.focus();
2208
+ };
2209
+
2210
+ Terminal.prototype.log = function() {
2211
+ if (!Terminal.debug) return;
2212
+ if (!window.console || !window.console.log) return;
2213
+ var args = Array.prototype.slice.call(arguments);
2214
+ window.console.log.apply(window.console, args);
2215
+ };
2216
+
2217
+ Terminal.prototype.error = function() {
2218
+ if (!Terminal.debug) return;
2219
+ if (!window.console || !window.console.error) return;
2220
+ var args = Array.prototype.slice.call(arguments);
2221
+ window.console.error.apply(window.console, args);
2222
+ };
2223
+
2224
+ Terminal.prototype.resize = function(x, y) {
2225
+ var line
2226
+ , el
2227
+ , i
2228
+ , j
2229
+ , ch;
2230
+
2231
+ if (x < 1) x = 1;
2232
+ if (y < 1) y = 1;
2233
+
2234
+ // resize cols
2235
+ j = this.cols;
2236
+ if (j < x) {
2237
+ ch = [this.defAttr, ' '];
2238
+ i = this.lines.length;
2239
+ while (i--) {
2240
+ while (this.lines[i].length < x) {
2241
+ this.lines[i].push(ch);
2242
+ }
2243
+ }
2244
+ } else if (j > x) {
2245
+ i = this.lines.length;
2246
+ while (i--) {
2247
+ while (this.lines[i].length > x) {
2248
+ this.lines[i].pop();
2249
+ }
2250
+ }
2251
+ }
2252
+ this.setupStops(j);
2253
+ this.cols = x;
2254
+
2255
+ // resize rows
2256
+ j = this.rows;
2257
+ if (j < y) {
2258
+ el = this.element;
2259
+ while (j++ < y) {
2260
+ if (this.lines.length < y + this.ybase) {
2261
+ this.lines.push(this.blankLine());
2262
+ }
2263
+ if (this.children.length < y) {
2264
+ line = document.createElement('div');
2265
+ el.appendChild(line);
2266
+ this.children.push(line);
2267
+ }
2268
+ }
2269
+ } else if (j > y) {
2270
+ while (j-- > y) {
2271
+ if (this.lines.length > y + this.ybase) {
2272
+ this.lines.pop();
2273
+ }
2274
+ if (this.children.length > y) {
2275
+ el = this.children.pop();
2276
+ if (!el) continue;
2277
+ el.parentNode.removeChild(el);
2278
+ }
2279
+ }
2280
+ }
2281
+ this.rows = y;
2282
+
2283
+ // make sure the cursor stays on screen
2284
+ if (this.y >= y) this.y = y - 1;
2285
+ if (this.x >= x) this.x = x - 1;
2286
+
2287
+ this.scrollTop = 0;
2288
+ this.scrollBottom = y - 1;
2289
+
2290
+ this.refresh(0, this.rows - 1);
2291
+
2292
+ // it's a real nightmare trying
2293
+ // to resize the original
2294
+ // screen buffer. just set it
2295
+ // to null for now.
2296
+ this.normal = null;
2297
+ };
2298
+
2299
+ Terminal.prototype.updateRange = function(y) {
2300
+ if (y < this.refreshStart) this.refreshStart = y;
2301
+ if (y > this.refreshEnd) this.refreshEnd = y;
2302
+ };
2303
+
2304
+ Terminal.prototype.maxRange = function() {
2305
+ this.refreshStart = 0;
2306
+ this.refreshEnd = this.rows - 1;
2307
+ };
2308
+
2309
+ Terminal.prototype.setupStops = function(i) {
2310
+ if (i != null) {
2311
+ if (!this.tabs[i]) {
2312
+ i = this.prevStop(i);
2313
+ }
2314
+ } else {
2315
+ this.tabs = {};
2316
+ i = 0;
2317
+ }
2318
+
2319
+ for (; i < this.cols; i += 8) {
2320
+ this.tabs[i] = true;
2321
+ }
2322
+ };
2323
+
2324
+ Terminal.prototype.prevStop = function(x) {
2325
+ if (x == null) x = this.x;
2326
+ while (!this.tabs[--x] && x > 0);
2327
+ return x >= this.cols
2328
+ ? this.cols - 1
2329
+ : x < 0 ? 0 : x;
2330
+ };
2331
+
2332
+ Terminal.prototype.nextStop = function(x) {
2333
+ if (x == null) x = this.x;
2334
+ while (!this.tabs[++x] && x < this.cols);
2335
+ return x >= this.cols
2336
+ ? this.cols - 1
2337
+ : x < 0 ? 0 : x;
2338
+ };
2339
+
2340
+ Terminal.prototype.eraseRight = function(x, y) {
2341
+ var line = this.lines[this.ybase + y]
2342
+ , ch = [this.curAttr, ' ']; // xterm
2343
+
2344
+ for (; x < this.cols; x++) {
2345
+ line[x] = ch;
2346
+ }
2347
+
2348
+ this.updateRange(y);
2349
+ };
2350
+
2351
+ Terminal.prototype.eraseLeft = function(x, y) {
2352
+ var line = this.lines[this.ybase + y]
2353
+ , ch = [this.curAttr, ' ']; // xterm
2354
+
2355
+ x++;
2356
+ while (x--) line[x] = ch;
2357
+
2358
+ this.updateRange(y);
2359
+ };
2360
+
2361
+ Terminal.prototype.eraseLine = function(y) {
2362
+ this.eraseRight(0, y);
2363
+ };
2364
+
2365
+ Terminal.prototype.blankLine = function(cur) {
2366
+ var attr = cur
2367
+ ? this.curAttr
2368
+ : this.defAttr;
2369
+
2370
+ var ch = [attr, ' ']
2371
+ , line = []
2372
+ , i = 0;
2373
+
2374
+ for (; i < this.cols; i++) {
2375
+ line[i] = ch;
2376
+ }
2377
+
2378
+ return line;
2379
+ };
2380
+
2381
+ Terminal.prototype.ch = function(cur) {
2382
+ return cur
2383
+ ? [this.curAttr, ' ']
2384
+ : [this.defAttr, ' '];
2385
+ };
2386
+
2387
+ Terminal.prototype.is = function(term) {
2388
+ var name = this.termName || Terminal.termName;
2389
+ return (name + '').indexOf(term) === 0;
2390
+ };
2391
+
2392
+ Terminal.prototype.handler = function(data) {
2393
+ this.emit('data', data);
2394
+ };
2395
+
2396
+ Terminal.prototype.handleTitle = function(title) {
2397
+ this.emit('title', title);
2398
+ };
2399
+
2400
+ /**
2401
+ * ESC
2402
+ */
2403
+
2404
+ // ESC D Index (IND is 0x84).
2405
+ Terminal.prototype.index = function() {
2406
+ this.y++;
2407
+ if (this.y > this.scrollBottom) {
2408
+ this.y--;
2409
+ this.scroll();
2410
+ }
2411
+ this.state = normal;
2412
+ };
2413
+
2414
+ // ESC M Reverse Index (RI is 0x8d).
2415
+ Terminal.prototype.reverseIndex = function() {
2416
+ var j;
2417
+ this.y--;
2418
+ if (this.y < this.scrollTop) {
2419
+ this.y++;
2420
+ // possibly move the code below to term.reverseScroll();
2421
+ // test: echo -ne '\e[1;1H\e[44m\eM\e[0m'
2422
+ // blankLine(true) is xterm/linux behavior
2423
+ this.lines.splice(this.y + this.ybase, 0, this.blankLine(true));
2424
+ j = this.rows - 1 - this.scrollBottom;
2425
+ this.lines.splice(this.rows - 1 + this.ybase - j + 1, 1);
2426
+ // this.maxRange();
2427
+ this.updateRange(this.scrollTop);
2428
+ this.updateRange(this.scrollBottom);
2429
+ }
2430
+ this.state = normal;
2431
+ };
2432
+
2433
+ // ESC c Full Reset (RIS).
2434
+ Terminal.prototype.reset = function() {
2435
+ Terminal.call(this, this.cols, this.rows);
2436
+ this.refresh(0, this.rows - 1);
2437
+ };
2438
+
2439
+ // ESC H Tab Set (HTS is 0x88).
2440
+ Terminal.prototype.tabSet = function() {
2441
+ this.tabs[this.x] = true;
2442
+ this.state = normal;
2443
+ };
2444
+
2445
+ /**
2446
+ * CSI
2447
+ */
2448
+
2449
+ // CSI Ps A
2450
+ // Cursor Up Ps Times (default = 1) (CUU).
2451
+ Terminal.prototype.cursorUp = function(params) {
2452
+ var param = params[0];
2453
+ if (param < 1) param = 1;
2454
+ this.y -= param;
2455
+ if (this.y < 0) this.y = 0;
2456
+ };
2457
+
2458
+ // CSI Ps B
2459
+ // Cursor Down Ps Times (default = 1) (CUD).
2460
+ Terminal.prototype.cursorDown = function(params) {
2461
+ var param = params[0];
2462
+ if (param < 1) param = 1;
2463
+ this.y += param;
2464
+ if (this.y >= this.rows) {
2465
+ this.y = this.rows - 1;
2466
+ }
2467
+ };
2468
+
2469
+ // CSI Ps C
2470
+ // Cursor Forward Ps Times (default = 1) (CUF).
2471
+ Terminal.prototype.cursorForward = function(params) {
2472
+ var param = params[0];
2473
+ if (param < 1) param = 1;
2474
+ this.x += param;
2475
+ if (this.x >= this.cols) {
2476
+ this.x = this.cols - 1;
2477
+ }
2478
+ };
2479
+
2480
+ // CSI Ps D
2481
+ // Cursor Backward Ps Times (default = 1) (CUB).
2482
+ Terminal.prototype.cursorBackward = function(params) {
2483
+ var param = params[0];
2484
+ if (param < 1) param = 1;
2485
+ this.x -= param;
2486
+ if (this.x < 0) this.x = 0;
2487
+ };
2488
+
2489
+ // CSI Ps ; Ps H
2490
+ // Cursor Position [row;column] (default = [1,1]) (CUP).
2491
+ Terminal.prototype.cursorPos = function(params) {
2492
+ var row, col;
2493
+
2494
+ row = params[0] - 1;
2495
+
2496
+ if (params.length >= 2) {
2497
+ col = params[1] - 1;
2498
+ } else {
2499
+ col = 0;
2500
+ }
2501
+
2502
+ if (row < 0) {
2503
+ row = 0;
2504
+ } else if (row >= this.rows) {
2505
+ row = this.rows - 1;
2506
+ }
2507
+
2508
+ if (col < 0) {
2509
+ col = 0;
2510
+ } else if (col >= this.cols) {
2511
+ col = this.cols - 1;
2512
+ }
2513
+
2514
+ this.x = col;
2515
+ this.y = row;
2516
+ };
2517
+
2518
+ // CSI Ps J Erase in Display (ED).
2519
+ // Ps = 0 -> Erase Below (default).
2520
+ // Ps = 1 -> Erase Above.
2521
+ // Ps = 2 -> Erase All.
2522
+ // Ps = 3 -> Erase Saved Lines (xterm).
2523
+ // CSI ? Ps J
2524
+ // Erase in Display (DECSED).
2525
+ // Ps = 0 -> Selective Erase Below (default).
2526
+ // Ps = 1 -> Selective Erase Above.
2527
+ // Ps = 2 -> Selective Erase All.
2528
+ Terminal.prototype.eraseInDisplay = function(params) {
2529
+ var j;
2530
+ switch (params[0]) {
2531
+ case 0:
2532
+ this.eraseRight(this.x, this.y);
2533
+ j = this.y + 1;
2534
+ for (; j < this.rows; j++) {
2535
+ this.eraseLine(j);
2536
+ }
2537
+ break;
2538
+ case 1:
2539
+ this.eraseLeft(this.x, this.y);
2540
+ j = this.y;
2541
+ while (j--) {
2542
+ this.eraseLine(j);
2543
+ }
2544
+ break;
2545
+ case 2:
2546
+ j = this.rows;
2547
+ while (j--) this.eraseLine(j);
2548
+ break;
2549
+ case 3:
2550
+ ; // no saved lines
2551
+ break;
2552
+ }
2553
+ };
2554
+
2555
+ // CSI Ps K Erase in Line (EL).
2556
+ // Ps = 0 -> Erase to Right (default).
2557
+ // Ps = 1 -> Erase to Left.
2558
+ // Ps = 2 -> Erase All.
2559
+ // CSI ? Ps K
2560
+ // Erase in Line (DECSEL).
2561
+ // Ps = 0 -> Selective Erase to Right (default).
2562
+ // Ps = 1 -> Selective Erase to Left.
2563
+ // Ps = 2 -> Selective Erase All.
2564
+ Terminal.prototype.eraseInLine = function(params) {
2565
+ switch (params[0]) {
2566
+ case 0:
2567
+ this.eraseRight(this.x, this.y);
2568
+ break;
2569
+ case 1:
2570
+ this.eraseLeft(this.x, this.y);
2571
+ break;
2572
+ case 2:
2573
+ this.eraseLine(this.y);
2574
+ break;
2575
+ }
2576
+ };
2577
+
2578
+ // CSI Pm m Character Attributes (SGR).
2579
+ // Ps = 0 -> Normal (default).
2580
+ // Ps = 1 -> Bold.
2581
+ // Ps = 4 -> Underlined.
2582
+ // Ps = 5 -> Blink (appears as Bold).
2583
+ // Ps = 7 -> Inverse.
2584
+ // Ps = 8 -> Invisible, i.e., hidden (VT300).
2585
+ // Ps = 2 2 -> Normal (neither bold nor faint).
2586
+ // Ps = 2 4 -> Not underlined.
2587
+ // Ps = 2 5 -> Steady (not blinking).
2588
+ // Ps = 2 7 -> Positive (not inverse).
2589
+ // Ps = 2 8 -> Visible, i.e., not hidden (VT300).
2590
+ // Ps = 3 0 -> Set foreground color to Black.
2591
+ // Ps = 3 1 -> Set foreground color to Red.
2592
+ // Ps = 3 2 -> Set foreground color to Green.
2593
+ // Ps = 3 3 -> Set foreground color to Yellow.
2594
+ // Ps = 3 4 -> Set foreground color to Blue.
2595
+ // Ps = 3 5 -> Set foreground color to Magenta.
2596
+ // Ps = 3 6 -> Set foreground color to Cyan.
2597
+ // Ps = 3 7 -> Set foreground color to White.
2598
+ // Ps = 3 9 -> Set foreground color to default (original).
2599
+ // Ps = 4 0 -> Set background color to Black.
2600
+ // Ps = 4 1 -> Set background color to Red.
2601
+ // Ps = 4 2 -> Set background color to Green.
2602
+ // Ps = 4 3 -> Set background color to Yellow.
2603
+ // Ps = 4 4 -> Set background color to Blue.
2604
+ // Ps = 4 5 -> Set background color to Magenta.
2605
+ // Ps = 4 6 -> Set background color to Cyan.
2606
+ // Ps = 4 7 -> Set background color to White.
2607
+ // Ps = 4 9 -> Set background color to default (original).
2608
+
2609
+ // If 16-color support is compiled, the following apply. Assume
2610
+ // that xterm's resources are set so that the ISO color codes are
2611
+ // the first 8 of a set of 16. Then the aixterm colors are the
2612
+ // bright versions of the ISO colors:
2613
+ // Ps = 9 0 -> Set foreground color to Black.
2614
+ // Ps = 9 1 -> Set foreground color to Red.
2615
+ // Ps = 9 2 -> Set foreground color to Green.
2616
+ // Ps = 9 3 -> Set foreground color to Yellow.
2617
+ // Ps = 9 4 -> Set foreground color to Blue.
2618
+ // Ps = 9 5 -> Set foreground color to Magenta.
2619
+ // Ps = 9 6 -> Set foreground color to Cyan.
2620
+ // Ps = 9 7 -> Set foreground color to White.
2621
+ // Ps = 1 0 0 -> Set background color to Black.
2622
+ // Ps = 1 0 1 -> Set background color to Red.
2623
+ // Ps = 1 0 2 -> Set background color to Green.
2624
+ // Ps = 1 0 3 -> Set background color to Yellow.
2625
+ // Ps = 1 0 4 -> Set background color to Blue.
2626
+ // Ps = 1 0 5 -> Set background color to Magenta.
2627
+ // Ps = 1 0 6 -> Set background color to Cyan.
2628
+ // Ps = 1 0 7 -> Set background color to White.
2629
+
2630
+ // If xterm is compiled with the 16-color support disabled, it
2631
+ // supports the following, from rxvt:
2632
+ // Ps = 1 0 0 -> Set foreground and background color to
2633
+ // default.
2634
+
2635
+ // If 88- or 256-color support is compiled, the following apply.
2636
+ // Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second
2637
+ // Ps.
2638
+ // Ps = 4 8 ; 5 ; Ps -> Set background color to the second
2639
+ // Ps.
2640
+ Terminal.prototype.charAttributes = function(params) {
2641
+ var l = params.length
2642
+ , i = 0
2643
+ , bg
2644
+ , fg
2645
+ , p;
2646
+
2647
+ for (; i < l; i++) {
2648
+ p = params[i];
2649
+ if (p >= 30 && p <= 37) {
2650
+ // fg color 8
2651
+ this.curAttr = (this.curAttr & ~(0x1ff << 9)) | ((p - 30) << 9);
2652
+ } else if (p >= 40 && p <= 47) {
2653
+ // bg color 8
2654
+ this.curAttr = (this.curAttr & ~0x1ff) | (p - 40);
2655
+ } else if (p >= 90 && p <= 97) {
2656
+ // fg color 16
2657
+ p += 8;
2658
+ this.curAttr = (this.curAttr & ~(0x1ff << 9)) | ((p - 90) << 9);
2659
+ } else if (p >= 100 && p <= 107) {
2660
+ // bg color 16
2661
+ p += 8;
2662
+ this.curAttr = (this.curAttr & ~0x1ff) | (p - 100);
2663
+ } else if (p === 0) {
2664
+ // default
2665
+ this.curAttr = this.defAttr;
2666
+ } else if (p === 1) {
2667
+ // bold text
2668
+ this.curAttr = this.curAttr | (1 << 18);
2669
+ } else if (p === 4) {
2670
+ // underlined text
2671
+ this.curAttr = this.curAttr | (2 << 18);
2672
+ } else if (p === 7 || p === 27) {
2673
+ // inverse and positive
2674
+ // test with: echo -e '\e[31m\e[42mhello\e[7mworld\e[27mhi\e[m'
2675
+ if (p === 7) {
2676
+ if ((this.curAttr >> 18) & 4) continue;
2677
+ this.curAttr = this.curAttr | (4 << 18);
2678
+ } else if (p === 27) {
2679
+ if (~(this.curAttr >> 18) & 4) continue;
2680
+ this.curAttr = this.curAttr & ~(4 << 18);
2681
+ }
2682
+
2683
+ bg = this.curAttr & 0x1ff;
2684
+ fg = (this.curAttr >> 9) & 0x1ff;
2685
+
2686
+ this.curAttr = (this.curAttr & ~0x3ffff) | ((bg << 9) | fg);
2687
+ } else if (p === 22) {
2688
+ // not bold
2689
+ this.curAttr = this.curAttr & ~(1 << 18);
2690
+ } else if (p === 24) {
2691
+ // not underlined
2692
+ this.curAttr = this.curAttr & ~(2 << 18);
2693
+ } else if (p === 39) {
2694
+ // reset fg
2695
+ this.curAttr = this.curAttr & ~(0x1ff << 9);
2696
+ this.curAttr = this.curAttr | (((this.defAttr >> 9) & 0x1ff) << 9);
2697
+ } else if (p === 49) {
2698
+ // reset bg
2699
+ this.curAttr = this.curAttr & ~0x1ff;
2700
+ this.curAttr = this.curAttr | (this.defAttr & 0x1ff);
2701
+ } else if (p === 38) {
2702
+ // fg color 256
2703
+ if (params[i+1] !== 5) continue;
2704
+ i += 2;
2705
+ p = params[i] & 0xff;
2706
+ // convert 88 colors to 256
2707
+ // if (this.is('rxvt-unicode') && p < 88) p = p * 2.9090 | 0;
2708
+ this.curAttr = (this.curAttr & ~(0x1ff << 9)) | (p << 9);
2709
+ } else if (p === 48) {
2710
+ // bg color 256
2711
+ if (params[i+1] !== 5) continue;
2712
+ i += 2;
2713
+ p = params[i] & 0xff;
2714
+ // convert 88 colors to 256
2715
+ // if (this.is('rxvt-unicode') && p < 88) p = p * 2.9090 | 0;
2716
+ this.curAttr = (this.curAttr & ~0x1ff) | p;
2717
+ }
2718
+ }
2719
+ };
2720
+
2721
+ // CSI Ps n Device Status Report (DSR).
2722
+ // Ps = 5 -> Status Report. Result (``OK'') is
2723
+ // CSI 0 n
2724
+ // Ps = 6 -> Report Cursor Position (CPR) [row;column].
2725
+ // Result is
2726
+ // CSI r ; c R
2727
+ // CSI ? Ps n
2728
+ // Device Status Report (DSR, DEC-specific).
2729
+ // Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI
2730
+ // ? r ; c R (assumes page is zero).
2731
+ // Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).
2732
+ // or CSI ? 1 1 n (not ready).
2733
+ // Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)
2734
+ // or CSI ? 2 1 n (locked).
2735
+ // Ps = 2 6 -> Report Keyboard status as
2736
+ // CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).
2737
+ // The last two parameters apply to VT400 & up, and denote key-
2738
+ // board ready and LK01 respectively.
2739
+ // Ps = 5 3 -> Report Locator status as
2740
+ // CSI ? 5 3 n Locator available, if compiled-in, or
2741
+ // CSI ? 5 0 n No Locator, if not.
2742
+ Terminal.prototype.deviceStatus = function(params) {
2743
+ if (!this.prefix) {
2744
+ switch (params[0]) {
2745
+ case 5:
2746
+ // status report
2747
+ this.send('\x1b[0n');
2748
+ break;
2749
+ case 6:
2750
+ // cursor position
2751
+ this.send('\x1b['
2752
+ + (this.y + 1)
2753
+ + ';'
2754
+ + (this.x + 1)
2755
+ + 'R');
2756
+ break;
2757
+ }
2758
+ } else if (this.prefix === '?') {
2759
+ // modern xterm doesnt seem to
2760
+ // respond to any of these except ?6, 6, and 5
2761
+ switch (params[0]) {
2762
+ case 6:
2763
+ // cursor position
2764
+ this.send('\x1b[?'
2765
+ + (this.y + 1)
2766
+ + ';'
2767
+ + (this.x + 1)
2768
+ + 'R');
2769
+ break;
2770
+ case 15:
2771
+ // no printer
2772
+ // this.send('\x1b[?11n');
2773
+ break;
2774
+ case 25:
2775
+ // dont support user defined keys
2776
+ // this.send('\x1b[?21n');
2777
+ break;
2778
+ case 26:
2779
+ // north american keyboard
2780
+ // this.send('\x1b[?27;1;0;0n');
2781
+ break;
2782
+ case 53:
2783
+ // no dec locator/mouse
2784
+ // this.send('\x1b[?50n');
2785
+ break;
2786
+ }
2787
+ }
2788
+ };
2789
+
2790
+ /**
2791
+ * Additions
2792
+ */
2793
+
2794
+ // CSI Ps @
2795
+ // Insert Ps (Blank) Character(s) (default = 1) (ICH).
2796
+ Terminal.prototype.insertChars = function(params) {
2797
+ var param, row, j, ch;
2798
+
2799
+ param = params[0];
2800
+ if (param < 1) param = 1;
2801
+
2802
+ row = this.y + this.ybase;
2803
+ j = this.x;
2804
+ ch = [this.curAttr, ' ']; // xterm
2805
+
2806
+ while (param-- && j < this.cols) {
2807
+ this.lines[row].splice(j++, 0, ch);
2808
+ this.lines[row].pop();
2809
+ }
2810
+ };
2811
+
2812
+ // CSI Ps E
2813
+ // Cursor Next Line Ps Times (default = 1) (CNL).
2814
+ // same as CSI Ps B ?
2815
+ Terminal.prototype.cursorNextLine = function(params) {
2816
+ var param = params[0];
2817
+ if (param < 1) param = 1;
2818
+ this.y += param;
2819
+ if (this.y >= this.rows) {
2820
+ this.y = this.rows - 1;
2821
+ }
2822
+ this.x = 0;
2823
+ };
2824
+
2825
+ // CSI Ps F
2826
+ // Cursor Preceding Line Ps Times (default = 1) (CNL).
2827
+ // reuse CSI Ps A ?
2828
+ Terminal.prototype.cursorPrecedingLine = function(params) {
2829
+ var param = params[0];
2830
+ if (param < 1) param = 1;
2831
+ this.y -= param;
2832
+ if (this.y < 0) this.y = 0;
2833
+ this.x = 0;
2834
+ };
2835
+
2836
+ // CSI Ps G
2837
+ // Cursor Character Absolute [column] (default = [row,1]) (CHA).
2838
+ Terminal.prototype.cursorCharAbsolute = function(params) {
2839
+ var param = params[0];
2840
+ if (param < 1) param = 1;
2841
+ this.x = param - 1;
2842
+ };
2843
+
2844
+ // CSI Ps L
2845
+ // Insert Ps Line(s) (default = 1) (IL).
2846
+ Terminal.prototype.insertLines = function(params) {
2847
+ var param, row, j;
2848
+
2849
+ param = params[0];
2850
+ if (param < 1) param = 1;
2851
+ row = this.y + this.ybase;
2852
+
2853
+ j = this.rows - 1 - this.scrollBottom;
2854
+ j = this.rows - 1 + this.ybase - j + 1;
2855
+
2856
+ while (param--) {
2857
+ // test: echo -e '\e[44m\e[1L\e[0m'
2858
+ // blankLine(true) - xterm/linux behavior
2859
+ this.lines.splice(row, 0, this.blankLine(true));
2860
+ this.lines.splice(j, 1);
2861
+ }
2862
+
2863
+ // this.maxRange();
2864
+ this.updateRange(this.y);
2865
+ this.updateRange(this.scrollBottom);
2866
+ };
2867
+
2868
+ // CSI Ps M
2869
+ // Delete Ps Line(s) (default = 1) (DL).
2870
+ Terminal.prototype.deleteLines = function(params) {
2871
+ var param, row, j;
2872
+
2873
+ param = params[0];
2874
+ if (param < 1) param = 1;
2875
+ row = this.y + this.ybase;
2876
+
2877
+ j = this.rows - 1 - this.scrollBottom;
2878
+ j = this.rows - 1 + this.ybase - j;
2879
+
2880
+ while (param--) {
2881
+ // test: echo -e '\e[44m\e[1M\e[0m'
2882
+ // blankLine(true) - xterm/linux behavior
2883
+ this.lines.splice(j + 1, 0, this.blankLine(true));
2884
+ this.lines.splice(row, 1);
2885
+ }
2886
+
2887
+ // this.maxRange();
2888
+ this.updateRange(this.y);
2889
+ this.updateRange(this.scrollBottom);
2890
+ };
2891
+
2892
+ // CSI Ps P
2893
+ // Delete Ps Character(s) (default = 1) (DCH).
2894
+ Terminal.prototype.deleteChars = function(params) {
2895
+ var param, row, ch;
2896
+
2897
+ param = params[0];
2898
+ if (param < 1) param = 1;
2899
+
2900
+ row = this.y + this.ybase;
2901
+ ch = [this.curAttr, ' ']; // xterm
2902
+
2903
+ while (param--) {
2904
+ this.lines[row].splice(this.x, 1);
2905
+ this.lines[row].push(ch);
2906
+ }
2907
+ };
2908
+
2909
+ // CSI Ps X
2910
+ // Erase Ps Character(s) (default = 1) (ECH).
2911
+ Terminal.prototype.eraseChars = function(params) {
2912
+ var param, row, j, ch;
2913
+
2914
+ param = params[0];
2915
+ if (param < 1) param = 1;
2916
+
2917
+ row = this.y + this.ybase;
2918
+ j = this.x;
2919
+ ch = [this.curAttr, ' ']; // xterm
2920
+
2921
+ while (param-- && j < this.cols) {
2922
+ this.lines[row][j++] = ch;
2923
+ }
2924
+ };
2925
+
2926
+ // CSI Pm ` Character Position Absolute
2927
+ // [column] (default = [row,1]) (HPA).
2928
+ Terminal.prototype.charPosAbsolute = function(params) {
2929
+ var param = params[0];
2930
+ if (param < 1) param = 1;
2931
+ this.x = param - 1;
2932
+ if (this.x >= this.cols) {
2933
+ this.x = this.cols - 1;
2934
+ }
2935
+ };
2936
+
2937
+ // 141 61 a * HPR -
2938
+ // Horizontal Position Relative
2939
+ // reuse CSI Ps C ?
2940
+ Terminal.prototype.HPositionRelative = function(params) {
2941
+ var param = params[0];
2942
+ if (param < 1) param = 1;
2943
+ this.x += param;
2944
+ if (this.x >= this.cols) {
2945
+ this.x = this.cols - 1;
2946
+ }
2947
+ };
2948
+
2949
+ // CSI Ps c Send Device Attributes (Primary DA).
2950
+ // Ps = 0 or omitted -> request attributes from terminal. The
2951
+ // response depends on the decTerminalID resource setting.
2952
+ // -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')
2953
+ // -> CSI ? 1 ; 0 c (``VT101 with No Options'')
2954
+ // -> CSI ? 6 c (``VT102'')
2955
+ // -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')
2956
+ // The VT100-style response parameters do not mean anything by
2957
+ // themselves. VT220 parameters do, telling the host what fea-
2958
+ // tures the terminal supports:
2959
+ // Ps = 1 -> 132-columns.
2960
+ // Ps = 2 -> Printer.
2961
+ // Ps = 6 -> Selective erase.
2962
+ // Ps = 8 -> User-defined keys.
2963
+ // Ps = 9 -> National replacement character sets.
2964
+ // Ps = 1 5 -> Technical characters.
2965
+ // Ps = 2 2 -> ANSI color, e.g., VT525.
2966
+ // Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).
2967
+ // CSI > Ps c
2968
+ // Send Device Attributes (Secondary DA).
2969
+ // Ps = 0 or omitted -> request the terminal's identification
2970
+ // code. The response depends on the decTerminalID resource set-
2971
+ // ting. It should apply only to VT220 and up, but xterm extends
2972
+ // this to VT100.
2973
+ // -> CSI > Pp ; Pv ; Pc c
2974
+ // where Pp denotes the terminal type
2975
+ // Pp = 0 -> ``VT100''.
2976
+ // Pp = 1 -> ``VT220''.
2977
+ // and Pv is the firmware version (for xterm, this was originally
2978
+ // the XFree86 patch number, starting with 95). In a DEC termi-
2979
+ // nal, Pc indicates the ROM cartridge registration number and is
2980
+ // always zero.
2981
+ // More information:
2982
+ // xterm/charproc.c - line 2012, for more information.
2983
+ // vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)
2984
+ Terminal.prototype.sendDeviceAttributes = function(params) {
2985
+ if (params[0] > 0) return;
2986
+
2987
+ if (!this.prefix) {
2988
+ if (this.is('xterm')
2989
+ || this.is('rxvt-unicode')
2990
+ || this.is('screen')) {
2991
+ this.send('\x1b[?1;2c');
2992
+ } else if (this.is('linux')) {
2993
+ this.send('\x1b[?6c');
2994
+ }
2995
+ } else if (this.prefix === '>') {
2996
+ // xterm and urxvt
2997
+ // seem to spit this
2998
+ // out around ~370 times (?).
2999
+ if (this.is('xterm')) {
3000
+ this.send('\x1b[>0;276;0c');
3001
+ } else if (this.is('rxvt-unicode')) {
3002
+ this.send('\x1b[>85;95;0c');
3003
+ } else if (this.is('linux')) {
3004
+ // not supported by linux console.
3005
+ // linux console echoes parameters.
3006
+ this.send(params[0] + 'c');
3007
+ } else if (this.is('screen')) {
3008
+ this.send('\x1b[>83;40003;0c');
3009
+ }
3010
+ }
3011
+ };
3012
+
3013
+ // CSI Pm d
3014
+ // Line Position Absolute [row] (default = [1,column]) (VPA).
3015
+ Terminal.prototype.linePosAbsolute = function(params) {
3016
+ var param = params[0];
3017
+ if (param < 1) param = 1;
3018
+ this.y = param - 1;
3019
+ if (this.y >= this.rows) {
3020
+ this.y = this.rows - 1;
3021
+ }
3022
+ };
3023
+
3024
+ // 145 65 e * VPR - Vertical Position Relative
3025
+ // reuse CSI Ps B ?
3026
+ Terminal.prototype.VPositionRelative = function(params) {
3027
+ var param = params[0];
3028
+ if (param < 1) param = 1;
3029
+ this.y += param;
3030
+ if (this.y >= this.rows) {
3031
+ this.y = this.rows - 1;
3032
+ }
3033
+ };
3034
+
3035
+ // CSI Ps ; Ps f
3036
+ // Horizontal and Vertical Position [row;column] (default =
3037
+ // [1,1]) (HVP).
3038
+ Terminal.prototype.HVPosition = function(params) {
3039
+ if (params[0] < 1) params[0] = 1;
3040
+ if (params[1] < 1) params[1] = 1;
3041
+
3042
+ this.y = params[0] - 1;
3043
+ if (this.y >= this.rows) {
3044
+ this.y = this.rows - 1;
3045
+ }
3046
+
3047
+ this.x = params[1] - 1;
3048
+ if (this.x >= this.cols) {
3049
+ this.x = this.cols - 1;
3050
+ }
3051
+ };
3052
+
3053
+ // CSI Pm h Set Mode (SM).
3054
+ // Ps = 2 -> Keyboard Action Mode (AM).
3055
+ // Ps = 4 -> Insert Mode (IRM).
3056
+ // Ps = 1 2 -> Send/receive (SRM).
3057
+ // Ps = 2 0 -> Automatic Newline (LNM).
3058
+ // CSI ? Pm h
3059
+ // DEC Private Mode Set (DECSET).
3060
+ // Ps = 1 -> Application Cursor Keys (DECCKM).
3061
+ // Ps = 2 -> Designate USASCII for character sets G0-G3
3062
+ // (DECANM), and set VT100 mode.
3063
+ // Ps = 3 -> 132 Column Mode (DECCOLM).
3064
+ // Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).
3065
+ // Ps = 5 -> Reverse Video (DECSCNM).
3066
+ // Ps = 6 -> Origin Mode (DECOM).
3067
+ // Ps = 7 -> Wraparound Mode (DECAWM).
3068
+ // Ps = 8 -> Auto-repeat Keys (DECARM).
3069
+ // Ps = 9 -> Send Mouse X & Y on button press. See the sec-
3070
+ // tion Mouse Tracking.
3071
+ // Ps = 1 0 -> Show toolbar (rxvt).
3072
+ // Ps = 1 2 -> Start Blinking Cursor (att610).
3073
+ // Ps = 1 8 -> Print form feed (DECPFF).
3074
+ // Ps = 1 9 -> Set print extent to full screen (DECPEX).
3075
+ // Ps = 2 5 -> Show Cursor (DECTCEM).
3076
+ // Ps = 3 0 -> Show scrollbar (rxvt).
3077
+ // Ps = 3 5 -> Enable font-shifting functions (rxvt).
3078
+ // Ps = 3 8 -> Enter Tektronix Mode (DECTEK).
3079
+ // Ps = 4 0 -> Allow 80 -> 132 Mode.
3080
+ // Ps = 4 1 -> more(1) fix (see curses resource).
3081
+ // Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-
3082
+ // RCM).
3083
+ // Ps = 4 4 -> Turn On Margin Bell.
3084
+ // Ps = 4 5 -> Reverse-wraparound Mode.
3085
+ // Ps = 4 6 -> Start Logging. This is normally disabled by a
3086
+ // compile-time option.
3087
+ // Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-
3088
+ // abled by the titeInhibit resource).
3089
+ // Ps = 6 6 -> Application keypad (DECNKM).
3090
+ // Ps = 6 7 -> Backarrow key sends backspace (DECBKM).
3091
+ // Ps = 1 0 0 0 -> Send Mouse X & Y on button press and
3092
+ // release. See the section Mouse Tracking.
3093
+ // Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.
3094
+ // Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.
3095
+ // Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.
3096
+ // Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.
3097
+ // Ps = 1 0 0 5 -> Enable Extended Mouse Mode.
3098
+ // Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).
3099
+ // Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).
3100
+ // Ps = 1 0 3 4 -> Interpret "meta" key, sets eighth bit.
3101
+ // (enables the eightBitInput resource).
3102
+ // Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-
3103
+ // Lock keys. (This enables the numLock resource).
3104
+ // Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This
3105
+ // enables the metaSendsEscape resource).
3106
+ // Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete
3107
+ // key.
3108
+ // Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This
3109
+ // enables the altSendsEscape resource).
3110
+ // Ps = 1 0 4 0 -> Keep selection even if not highlighted.
3111
+ // (This enables the keepSelection resource).
3112
+ // Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables
3113
+ // the selectToClipboard resource).
3114
+ // Ps = 1 0 4 2 -> Enable Urgency window manager hint when
3115
+ // Control-G is received. (This enables the bellIsUrgent
3116
+ // resource).
3117
+ // Ps = 1 0 4 3 -> Enable raising of the window when Control-G
3118
+ // is received. (enables the popOnBell resource).
3119
+ // Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be
3120
+ // disabled by the titeInhibit resource).
3121
+ // Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-
3122
+ // abled by the titeInhibit resource).
3123
+ // Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate
3124
+ // Screen Buffer, clearing it first. (This may be disabled by
3125
+ // the titeInhibit resource). This combines the effects of the 1
3126
+ // 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based
3127
+ // applications rather than the 4 7 mode.
3128
+ // Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.
3129
+ // Ps = 1 0 5 1 -> Set Sun function-key mode.
3130
+ // Ps = 1 0 5 2 -> Set HP function-key mode.
3131
+ // Ps = 1 0 5 3 -> Set SCO function-key mode.
3132
+ // Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).
3133
+ // Ps = 1 0 6 1 -> Set VT220 keyboard emulation.
3134
+ // Ps = 2 0 0 4 -> Set bracketed paste mode.
3135
+ // Modes:
3136
+ // http://vt100.net/docs/vt220-rm/chapter4.html
3137
+ Terminal.prototype.setMode = function(params) {
3138
+ if (typeof params === 'object') {
3139
+ var l = params.length
3140
+ , i = 0;
3141
+
3142
+ for (; i < l; i++) {
3143
+ this.setMode(params[i]);
3144
+ }
3145
+
3146
+ return;
3147
+ }
3148
+
3149
+ if (!this.prefix) {
3150
+ switch (params) {
3151
+ case 4:
3152
+ this.insertMode = true;
3153
+ break;
3154
+ case 20:
3155
+ //this.convertEol = true;
3156
+ break;
3157
+ }
3158
+ } else if (this.prefix === '?') {
3159
+ switch (params) {
3160
+ case 1:
3161
+ this.applicationKeypad = true;
3162
+ break;
3163
+ case 2:
3164
+ this.setgCharset(0, Terminal.charsets.US);
3165
+ this.setgCharset(1, Terminal.charsets.US);
3166
+ this.setgCharset(2, Terminal.charsets.US);
3167
+ this.setgCharset(3, Terminal.charsets.US);
3168
+ // set VT100 mode here
3169
+ break;
3170
+ case 3: // 132 col mode
3171
+ this.savedCols = this.cols;
3172
+ this.resize(132, this.rows);
3173
+ break;
3174
+ case 6:
3175
+ this.originMode = true;
3176
+ break;
3177
+ case 7:
3178
+ this.wraparoundMode = true;
3179
+ break;
3180
+ case 12:
3181
+ // this.cursorBlink = true;
3182
+ break;
3183
+ case 9: // X10 Mouse
3184
+ // no release, no motion, no wheel, no modifiers.
3185
+ case 1000: // vt200 mouse
3186
+ // no motion.
3187
+ // no modifiers, except control on the wheel.
3188
+ case 1002: // button event mouse
3189
+ case 1003: // any event mouse
3190
+ // any event - sends motion events,
3191
+ // even if there is no button held down.
3192
+ this.x10Mouse = params === 9;
3193
+ this.vt200Mouse = params === 1000;
3194
+ this.normalMouse = params > 1000;
3195
+ this.mouseEvents = true;
3196
+ this.element.style.cursor = 'default';
3197
+ this.log('Binding to mouse events.');
3198
+ break;
3199
+ case 1004: // send focusin/focusout events
3200
+ // focusin: ^[[I
3201
+ // focusout: ^[[O
3202
+ this.sendFocus = true;
3203
+ break;
3204
+ case 1005: // utf8 ext mode mouse
3205
+ this.utfMouse = true;
3206
+ // for wide terminals
3207
+ // simply encodes large values as utf8 characters
3208
+ break;
3209
+ case 1006: // sgr ext mode mouse
3210
+ this.sgrMouse = true;
3211
+ // for wide terminals
3212
+ // does not add 32 to fields
3213
+ // press: ^[[<b;x;yM
3214
+ // release: ^[[<b;x;ym
3215
+ break;
3216
+ case 1015: // urxvt ext mode mouse
3217
+ this.urxvtMouse = true;
3218
+ // for wide terminals
3219
+ // numbers for fields
3220
+ // press: ^[[b;x;yM
3221
+ // motion: ^[[b;x;yT
3222
+ break;
3223
+ case 25: // show cursor
3224
+ this.cursorHidden = false;
3225
+ break;
3226
+ case 1049: // alt screen buffer cursor
3227
+ //this.saveCursor();
3228
+ ; // FALL-THROUGH
3229
+ case 47: // alt screen buffer
3230
+ case 1047: // alt screen buffer
3231
+ if (!this.normal) {
3232
+ var normal = {
3233
+ lines: this.lines,
3234
+ ybase: this.ybase,
3235
+ ydisp: this.ydisp,
3236
+ x: this.x,
3237
+ y: this.y,
3238
+ scrollTop: this.scrollTop,
3239
+ scrollBottom: this.scrollBottom,
3240
+ tabs: this.tabs
3241
+ // XXX save charset(s) here?
3242
+ // charset: this.charset,
3243
+ // glevel: this.glevel,
3244
+ // charsets: this.charsets
3245
+ };
3246
+ this.reset();
3247
+ this.normal = normal;
3248
+ this.showCursor();
3249
+ }
3250
+ break;
3251
+ }
3252
+ }
3253
+ };
3254
+
3255
+ // CSI Pm l Reset Mode (RM).
3256
+ // Ps = 2 -> Keyboard Action Mode (AM).
3257
+ // Ps = 4 -> Replace Mode (IRM).
3258
+ // Ps = 1 2 -> Send/receive (SRM).
3259
+ // Ps = 2 0 -> Normal Linefeed (LNM).
3260
+ // CSI ? Pm l
3261
+ // DEC Private Mode Reset (DECRST).
3262
+ // Ps = 1 -> Normal Cursor Keys (DECCKM).
3263
+ // Ps = 2 -> Designate VT52 mode (DECANM).
3264
+ // Ps = 3 -> 80 Column Mode (DECCOLM).
3265
+ // Ps = 4 -> Jump (Fast) Scroll (DECSCLM).
3266
+ // Ps = 5 -> Normal Video (DECSCNM).
3267
+ // Ps = 6 -> Normal Cursor Mode (DECOM).
3268
+ // Ps = 7 -> No Wraparound Mode (DECAWM).
3269
+ // Ps = 8 -> No Auto-repeat Keys (DECARM).
3270
+ // Ps = 9 -> Don't send Mouse X & Y on button press.
3271
+ // Ps = 1 0 -> Hide toolbar (rxvt).
3272
+ // Ps = 1 2 -> Stop Blinking Cursor (att610).
3273
+ // Ps = 1 8 -> Don't print form feed (DECPFF).
3274
+ // Ps = 1 9 -> Limit print to scrolling region (DECPEX).
3275
+ // Ps = 2 5 -> Hide Cursor (DECTCEM).
3276
+ // Ps = 3 0 -> Don't show scrollbar (rxvt).
3277
+ // Ps = 3 5 -> Disable font-shifting functions (rxvt).
3278
+ // Ps = 4 0 -> Disallow 80 -> 132 Mode.
3279
+ // Ps = 4 1 -> No more(1) fix (see curses resource).
3280
+ // Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-
3281
+ // NRCM).
3282
+ // Ps = 4 4 -> Turn Off Margin Bell.
3283
+ // Ps = 4 5 -> No Reverse-wraparound Mode.
3284
+ // Ps = 4 6 -> Stop Logging. (This is normally disabled by a
3285
+ // compile-time option).
3286
+ // Ps = 4 7 -> Use Normal Screen Buffer.
3287
+ // Ps = 6 6 -> Numeric keypad (DECNKM).
3288
+ // Ps = 6 7 -> Backarrow key sends delete (DECBKM).
3289
+ // Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and
3290
+ // release. See the section Mouse Tracking.
3291
+ // Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.
3292
+ // Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.
3293
+ // Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.
3294
+ // Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.
3295
+ // Ps = 1 0 0 5 -> Disable Extended Mouse Mode.
3296
+ // Ps = 1 0 1 0 -> Don't scroll to bottom on tty output
3297
+ // (rxvt).
3298
+ // Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).
3299
+ // Ps = 1 0 3 4 -> Don't interpret "meta" key. (This disables
3300
+ // the eightBitInput resource).
3301
+ // Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-
3302
+ // Lock keys. (This disables the numLock resource).
3303
+ // Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.
3304
+ // (This disables the metaSendsEscape resource).
3305
+ // Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad
3306
+ // Delete key.
3307
+ // Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.
3308
+ // (This disables the altSendsEscape resource).
3309
+ // Ps = 1 0 4 0 -> Do not keep selection when not highlighted.
3310
+ // (This disables the keepSelection resource).
3311
+ // Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables
3312
+ // the selectToClipboard resource).
3313
+ // Ps = 1 0 4 2 -> Disable Urgency window manager hint when
3314
+ // Control-G is received. (This disables the bellIsUrgent
3315
+ // resource).
3316
+ // Ps = 1 0 4 3 -> Disable raising of the window when Control-
3317
+ // G is received. (This disables the popOnBell resource).
3318
+ // Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen
3319
+ // first if in the Alternate Screen. (This may be disabled by
3320
+ // the titeInhibit resource).
3321
+ // Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be
3322
+ // disabled by the titeInhibit resource).
3323
+ // Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor
3324
+ // as in DECRC. (This may be disabled by the titeInhibit
3325
+ // resource). This combines the effects of the 1 0 4 7 and 1 0
3326
+ // 4 8 modes. Use this with terminfo-based applications rather
3327
+ // than the 4 7 mode.
3328
+ // Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.
3329
+ // Ps = 1 0 5 1 -> Reset Sun function-key mode.
3330
+ // Ps = 1 0 5 2 -> Reset HP function-key mode.
3331
+ // Ps = 1 0 5 3 -> Reset SCO function-key mode.
3332
+ // Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).
3333
+ // Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.
3334
+ // Ps = 2 0 0 4 -> Reset bracketed paste mode.
3335
+ Terminal.prototype.resetMode = function(params) {
3336
+ if (typeof params === 'object') {
3337
+ var l = params.length
3338
+ , i = 0;
3339
+
3340
+ for (; i < l; i++) {
3341
+ this.resetMode(params[i]);
3342
+ }
3343
+
3344
+ return;
3345
+ }
3346
+
3347
+ if (!this.prefix) {
3348
+ switch (params) {
3349
+ case 4:
3350
+ this.insertMode = false;
3351
+ break;
3352
+ case 20:
3353
+ //this.convertEol = false;
3354
+ break;
3355
+ }
3356
+ } else if (this.prefix === '?') {
3357
+ switch (params) {
3358
+ case 1:
3359
+ this.applicationKeypad = false;
3360
+ break;
3361
+ case 3:
3362
+ if (this.cols === 132 && this.savedCols) {
3363
+ this.resize(this.savedCols, this.rows);
3364
+ }
3365
+ delete this.savedCols;
3366
+ break;
3367
+ case 6:
3368
+ this.originMode = false;
3369
+ break;
3370
+ case 7:
3371
+ this.wraparoundMode = false;
3372
+ break;
3373
+ case 12:
3374
+ // this.cursorBlink = false;
3375
+ break;
3376
+ case 9: // X10 Mouse
3377
+ case 1000: // vt200 mouse
3378
+ case 1002: // button event mouse
3379
+ case 1003: // any event mouse
3380
+ this.x10Mouse = false;
3381
+ this.vt200Mouse = false;
3382
+ this.normalMouse = false;
3383
+ this.mouseEvents = false;
3384
+ this.element.style.cursor = '';
3385
+ break;
3386
+ case 1004: // send focusin/focusout events
3387
+ this.sendFocus = false;
3388
+ break;
3389
+ case 1005: // utf8 ext mode mouse
3390
+ this.utfMouse = false;
3391
+ break;
3392
+ case 1006: // sgr ext mode mouse
3393
+ this.sgrMouse = false;
3394
+ break;
3395
+ case 1015: // urxvt ext mode mouse
3396
+ this.urxvtMouse = false;
3397
+ break;
3398
+ case 25: // hide cursor
3399
+ this.cursorHidden = true;
3400
+ break;
3401
+ case 1049: // alt screen buffer cursor
3402
+ ; // FALL-THROUGH
3403
+ case 47: // normal screen buffer
3404
+ case 1047: // normal screen buffer - clearing it first
3405
+ if (this.normal) {
3406
+ this.lines = this.normal.lines;
3407
+ this.ybase = this.normal.ybase;
3408
+ this.ydisp = this.normal.ydisp;
3409
+ this.x = this.normal.x;
3410
+ this.y = this.normal.y;
3411
+ this.scrollTop = this.normal.scrollTop;
3412
+ this.scrollBottom = this.normal.scrollBottom;
3413
+ this.tabs = this.normal.tabs;
3414
+ this.normal = null;
3415
+ // if (params === 1049) {
3416
+ // this.x = this.savedX;
3417
+ // this.y = this.savedY;
3418
+ // }
3419
+ this.refresh(0, this.rows - 1);
3420
+ this.showCursor();
3421
+ }
3422
+ break;
3423
+ }
3424
+ }
3425
+ };
3426
+
3427
+ // CSI Ps ; Ps r
3428
+ // Set Scrolling Region [top;bottom] (default = full size of win-
3429
+ // dow) (DECSTBM).
3430
+ // CSI ? Pm r
3431
+ Terminal.prototype.setScrollRegion = function(params) {
3432
+ if (this.prefix) return;
3433
+ this.scrollTop = (params[0] || 1) - 1;
3434
+ this.scrollBottom = (params[1] || this.rows) - 1;
3435
+ this.x = 0;
3436
+ this.y = 0;
3437
+ };
3438
+
3439
+ // CSI s
3440
+ // Save cursor (ANSI.SYS).
3441
+ Terminal.prototype.saveCursor = function(params) {
3442
+ this.savedX = this.x;
3443
+ this.savedY = this.y;
3444
+ };
3445
+
3446
+ // CSI u
3447
+ // Restore cursor (ANSI.SYS).
3448
+ Terminal.prototype.restoreCursor = function(params) {
3449
+ this.x = this.savedX || 0;
3450
+ this.y = this.savedY || 0;
3451
+ };
3452
+
3453
+ /**
3454
+ * Lesser Used
3455
+ */
3456
+
3457
+ // CSI Ps I
3458
+ // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).
3459
+ Terminal.prototype.cursorForwardTab = function(params) {
3460
+ var param = params[0] || 1;
3461
+ while (param--) {
3462
+ this.x = this.nextStop();
3463
+ }
3464
+ };
3465
+
3466
+ // CSI Ps S Scroll up Ps lines (default = 1) (SU).
3467
+ Terminal.prototype.scrollUp = function(params) {
3468
+ var param = params[0] || 1;
3469
+ while (param--) {
3470
+ this.lines.splice(this.ybase + this.scrollTop, 1);
3471
+ this.lines.splice(this.ybase + this.scrollBottom, 0, this.blankLine());
3472
+ }
3473
+ // this.maxRange();
3474
+ this.updateRange(this.scrollTop);
3475
+ this.updateRange(this.scrollBottom);
3476
+ };
3477
+
3478
+ // CSI Ps T Scroll down Ps lines (default = 1) (SD).
3479
+ Terminal.prototype.scrollDown = function(params) {
3480
+ var param = params[0] || 1;
3481
+ while (param--) {
3482
+ this.lines.splice(this.ybase + this.scrollBottom, 1);
3483
+ this.lines.splice(this.ybase + this.scrollTop, 0, this.blankLine());
3484
+ }
3485
+ // this.maxRange();
3486
+ this.updateRange(this.scrollTop);
3487
+ this.updateRange(this.scrollBottom);
3488
+ };
3489
+
3490
+ // CSI Ps ; Ps ; Ps ; Ps ; Ps T
3491
+ // Initiate highlight mouse tracking. Parameters are
3492
+ // [func;startx;starty;firstrow;lastrow]. See the section Mouse
3493
+ // Tracking.
3494
+ Terminal.prototype.initMouseTracking = function(params) {
3495
+ // Relevant: DECSET 1001
3496
+ };
3497
+
3498
+ // CSI > Ps; Ps T
3499
+ // Reset one or more features of the title modes to the default
3500
+ // value. Normally, "reset" disables the feature. It is possi-
3501
+ // ble to disable the ability to reset features by compiling a
3502
+ // different default for the title modes into xterm.
3503
+ // Ps = 0 -> Do not set window/icon labels using hexadecimal.
3504
+ // Ps = 1 -> Do not query window/icon labels using hexadeci-
3505
+ // mal.
3506
+ // Ps = 2 -> Do not set window/icon labels using UTF-8.
3507
+ // Ps = 3 -> Do not query window/icon labels using UTF-8.
3508
+ // (See discussion of "Title Modes").
3509
+ Terminal.prototype.resetTitleModes = function(params) {
3510
+ ;
3511
+ };
3512
+
3513
+ // CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).
3514
+ Terminal.prototype.cursorBackwardTab = function(params) {
3515
+ var param = params[0] || 1;
3516
+ while (param--) {
3517
+ this.x = this.prevStop();
3518
+ }
3519
+ };
3520
+
3521
+ // CSI Ps b Repeat the preceding graphic character Ps times (REP).
3522
+ Terminal.prototype.repeatPrecedingCharacter = function(params) {
3523
+ var param = params[0] || 1
3524
+ , line = this.lines[this.ybase + this.y]
3525
+ , ch = line[this.x - 1] || [this.defAttr, ' '];
3526
+
3527
+ while (param--) line[this.x++] = ch;
3528
+ };
3529
+
3530
+ // CSI Ps g Tab Clear (TBC).
3531
+ // Ps = 0 -> Clear Current Column (default).
3532
+ // Ps = 3 -> Clear All.
3533
+ // Potentially:
3534
+ // Ps = 2 -> Clear Stops on Line.
3535
+ // http://vt100.net/annarbor/aaa-ug/section6.html
3536
+ Terminal.prototype.tabClear = function(params) {
3537
+ var param = params[0];
3538
+ if (param <= 0) {
3539
+ delete this.tabs[this.x];
3540
+ } else if (param === 3) {
3541
+ this.tabs = {};
3542
+ }
3543
+ };
3544
+
3545
+ // CSI Pm i Media Copy (MC).
3546
+ // Ps = 0 -> Print screen (default).
3547
+ // Ps = 4 -> Turn off printer controller mode.
3548
+ // Ps = 5 -> Turn on printer controller mode.
3549
+ // CSI ? Pm i
3550
+ // Media Copy (MC, DEC-specific).
3551
+ // Ps = 1 -> Print line containing cursor.
3552
+ // Ps = 4 -> Turn off autoprint mode.
3553
+ // Ps = 5 -> Turn on autoprint mode.
3554
+ // Ps = 1 0 -> Print composed display, ignores DECPEX.
3555
+ // Ps = 1 1 -> Print all pages.
3556
+ Terminal.prototype.mediaCopy = function(params) {
3557
+ ;
3558
+ };
3559
+
3560
+ // CSI > Ps; Ps m
3561
+ // Set or reset resource-values used by xterm to decide whether
3562
+ // to construct escape sequences holding information about the
3563
+ // modifiers pressed with a given key. The first parameter iden-
3564
+ // tifies the resource to set/reset. The second parameter is the
3565
+ // value to assign to the resource. If the second parameter is
3566
+ // omitted, the resource is reset to its initial value.
3567
+ // Ps = 1 -> modifyCursorKeys.
3568
+ // Ps = 2 -> modifyFunctionKeys.
3569
+ // Ps = 4 -> modifyOtherKeys.
3570
+ // If no parameters are given, all resources are reset to their
3571
+ // initial values.
3572
+ Terminal.prototype.setResources = function(params) {
3573
+ ;
3574
+ };
3575
+
3576
+ // CSI > Ps n
3577
+ // Disable modifiers which may be enabled via the CSI > Ps; Ps m
3578
+ // sequence. This corresponds to a resource value of "-1", which
3579
+ // cannot be set with the other sequence. The parameter identi-
3580
+ // fies the resource to be disabled:
3581
+ // Ps = 1 -> modifyCursorKeys.
3582
+ // Ps = 2 -> modifyFunctionKeys.
3583
+ // Ps = 4 -> modifyOtherKeys.
3584
+ // If the parameter is omitted, modifyFunctionKeys is disabled.
3585
+ // When modifyFunctionKeys is disabled, xterm uses the modifier
3586
+ // keys to make an extended sequence of functions rather than
3587
+ // adding a parameter to each function key to denote the modi-
3588
+ // fiers.
3589
+ Terminal.prototype.disableModifiers = function(params) {
3590
+ ;
3591
+ };
3592
+
3593
+ // CSI > Ps p
3594
+ // Set resource value pointerMode. This is used by xterm to
3595
+ // decide whether to hide the pointer cursor as the user types.
3596
+ // Valid values for the parameter:
3597
+ // Ps = 0 -> never hide the pointer.
3598
+ // Ps = 1 -> hide if the mouse tracking mode is not enabled.
3599
+ // Ps = 2 -> always hide the pointer. If no parameter is
3600
+ // given, xterm uses the default, which is 1 .
3601
+ Terminal.prototype.setPointerMode = function(params) {
3602
+ ;
3603
+ };
3604
+
3605
+ // CSI ! p Soft terminal reset (DECSTR).
3606
+ // http://vt100.net/docs/vt220-rm/table4-10.html
3607
+ Terminal.prototype.softReset = function(params) {
3608
+ this.cursorHidden = false;
3609
+ this.insertMode = false;
3610
+ this.originMode = false;
3611
+ this.wraparoundMode = false; // autowrap
3612
+ this.applicationKeypad = false; // ?
3613
+ this.scrollTop = 0;
3614
+ this.scrollBottom = this.rows - 1;
3615
+ this.curAttr = this.defAttr;
3616
+ this.x = this.y = 0; // ?
3617
+ this.charset = null;
3618
+ this.glevel = 0; // ??
3619
+ this.charsets = [null]; // ??
3620
+ };
3621
+
3622
+ // CSI Ps$ p
3623
+ // Request ANSI mode (DECRQM). For VT300 and up, reply is
3624
+ // CSI Ps; Pm$ y
3625
+ // where Ps is the mode number as in RM, and Pm is the mode
3626
+ // value:
3627
+ // 0 - not recognized
3628
+ // 1 - set
3629
+ // 2 - reset
3630
+ // 3 - permanently set
3631
+ // 4 - permanently reset
3632
+ Terminal.prototype.requestAnsiMode = function(params) {
3633
+ ;
3634
+ };
3635
+
3636
+ // CSI ? Ps$ p
3637
+ // Request DEC private mode (DECRQM). For VT300 and up, reply is
3638
+ // CSI ? Ps; Pm$ p
3639
+ // where Ps is the mode number as in DECSET, Pm is the mode value
3640
+ // as in the ANSI DECRQM.
3641
+ Terminal.prototype.requestPrivateMode = function(params) {
3642
+ ;
3643
+ };
3644
+
3645
+ // CSI Ps ; Ps " p
3646
+ // Set conformance level (DECSCL). Valid values for the first
3647
+ // parameter:
3648
+ // Ps = 6 1 -> VT100.
3649
+ // Ps = 6 2 -> VT200.
3650
+ // Ps = 6 3 -> VT300.
3651
+ // Valid values for the second parameter:
3652
+ // Ps = 0 -> 8-bit controls.
3653
+ // Ps = 1 -> 7-bit controls (always set for VT100).
3654
+ // Ps = 2 -> 8-bit controls.
3655
+ Terminal.prototype.setConformanceLevel = function(params) {
3656
+ ;
3657
+ };
3658
+
3659
+ // CSI Ps q Load LEDs (DECLL).
3660
+ // Ps = 0 -> Clear all LEDS (default).
3661
+ // Ps = 1 -> Light Num Lock.
3662
+ // Ps = 2 -> Light Caps Lock.
3663
+ // Ps = 3 -> Light Scroll Lock.
3664
+ // Ps = 2 1 -> Extinguish Num Lock.
3665
+ // Ps = 2 2 -> Extinguish Caps Lock.
3666
+ // Ps = 2 3 -> Extinguish Scroll Lock.
3667
+ Terminal.prototype.loadLEDs = function(params) {
3668
+ ;
3669
+ };
3670
+
3671
+ // CSI Ps SP q
3672
+ // Set cursor style (DECSCUSR, VT520).
3673
+ // Ps = 0 -> blinking block.
3674
+ // Ps = 1 -> blinking block (default).
3675
+ // Ps = 2 -> steady block.
3676
+ // Ps = 3 -> blinking underline.
3677
+ // Ps = 4 -> steady underline.
3678
+ Terminal.prototype.setCursorStyle = function(params) {
3679
+ ;
3680
+ };
3681
+
3682
+ // CSI Ps " q
3683
+ // Select character protection attribute (DECSCA). Valid values
3684
+ // for the parameter:
3685
+ // Ps = 0 -> DECSED and DECSEL can erase (default).
3686
+ // Ps = 1 -> DECSED and DECSEL cannot erase.
3687
+ // Ps = 2 -> DECSED and DECSEL can erase.
3688
+ Terminal.prototype.setCharProtectionAttr = function(params) {
3689
+ ;
3690
+ };
3691
+
3692
+ // CSI ? Pm r
3693
+ // Restore DEC Private Mode Values. The value of Ps previously
3694
+ // saved is restored. Ps values are the same as for DECSET.
3695
+ Terminal.prototype.restorePrivateValues = function(params) {
3696
+ ;
3697
+ };
3698
+
3699
+ // CSI Pt; Pl; Pb; Pr; Ps$ r
3700
+ // Change Attributes in Rectangular Area (DECCARA), VT400 and up.
3701
+ // Pt; Pl; Pb; Pr denotes the rectangle.
3702
+ // Ps denotes the SGR attributes to change: 0, 1, 4, 5, 7.
3703
+ // NOTE: xterm doesn't enable this code by default.
3704
+ Terminal.prototype.setAttrInRectangle = function(params) {
3705
+ var t = params[0]
3706
+ , l = params[1]
3707
+ , b = params[2]
3708
+ , r = params[3]
3709
+ , attr = params[4];
3710
+
3711
+ var line
3712
+ , i;
3713
+
3714
+ for (; t < b + 1; t++) {
3715
+ line = this.lines[this.ybase + t];
3716
+ for (i = l; i < r; i++) {
3717
+ line[i] = [attr, line[i][1]];
3718
+ }
3719
+ }
3720
+
3721
+ // this.maxRange();
3722
+ this.updateRange(params[0]);
3723
+ this.updateRange(params[2]);
3724
+ };
3725
+
3726
+ // CSI ? Pm s
3727
+ // Save DEC Private Mode Values. Ps values are the same as for
3728
+ // DECSET.
3729
+ Terminal.prototype.savePrivateValues = function(params) {
3730
+ ;
3731
+ };
3732
+
3733
+ // CSI Ps ; Ps ; Ps t
3734
+ // Window manipulation (from dtterm, as well as extensions).
3735
+ // These controls may be disabled using the allowWindowOps
3736
+ // resource. Valid values for the first (and any additional
3737
+ // parameters) are:
3738
+ // Ps = 1 -> De-iconify window.
3739
+ // Ps = 2 -> Iconify window.
3740
+ // Ps = 3 ; x ; y -> Move window to [x, y].
3741
+ // Ps = 4 ; height ; width -> Resize the xterm window to
3742
+ // height and width in pixels.
3743
+ // Ps = 5 -> Raise the xterm window to the front of the stack-
3744
+ // ing order.
3745
+ // Ps = 6 -> Lower the xterm window to the bottom of the
3746
+ // stacking order.
3747
+ // Ps = 7 -> Refresh the xterm window.
3748
+ // Ps = 8 ; height ; width -> Resize the text area to
3749
+ // [height;width] in characters.
3750
+ // Ps = 9 ; 0 -> Restore maximized window.
3751
+ // Ps = 9 ; 1 -> Maximize window (i.e., resize to screen
3752
+ // size).
3753
+ // Ps = 1 0 ; 0 -> Undo full-screen mode.
3754
+ // Ps = 1 0 ; 1 -> Change to full-screen.
3755
+ // Ps = 1 1 -> Report xterm window state. If the xterm window
3756
+ // is open (non-iconified), it returns CSI 1 t . If the xterm
3757
+ // window is iconified, it returns CSI 2 t .
3758
+ // Ps = 1 3 -> Report xterm window position. Result is CSI 3
3759
+ // ; x ; y t
3760
+ // Ps = 1 4 -> Report xterm window in pixels. Result is CSI
3761
+ // 4 ; height ; width t
3762
+ // Ps = 1 8 -> Report the size of the text area in characters.
3763
+ // Result is CSI 8 ; height ; width t
3764
+ // Ps = 1 9 -> Report the size of the screen in characters.
3765
+ // Result is CSI 9 ; height ; width t
3766
+ // Ps = 2 0 -> Report xterm window's icon label. Result is
3767
+ // OSC L label ST
3768
+ // Ps = 2 1 -> Report xterm window's title. Result is OSC l
3769
+ // label ST
3770
+ // Ps = 2 2 ; 0 -> Save xterm icon and window title on
3771
+ // stack.
3772
+ // Ps = 2 2 ; 1 -> Save xterm icon title on stack.
3773
+ // Ps = 2 2 ; 2 -> Save xterm window title on stack.
3774
+ // Ps = 2 3 ; 0 -> Restore xterm icon and window title from
3775
+ // stack.
3776
+ // Ps = 2 3 ; 1 -> Restore xterm icon title from stack.
3777
+ // Ps = 2 3 ; 2 -> Restore xterm window title from stack.
3778
+ // Ps >= 2 4 -> Resize to Ps lines (DECSLPP).
3779
+ Terminal.prototype.manipulateWindow = function(params) {
3780
+ ;
3781
+ };
3782
+
3783
+ // CSI Pt; Pl; Pb; Pr; Ps$ t
3784
+ // Reverse Attributes in Rectangular Area (DECRARA), VT400 and
3785
+ // up.
3786
+ // Pt; Pl; Pb; Pr denotes the rectangle.
3787
+ // Ps denotes the attributes to reverse, i.e., 1, 4, 5, 7.
3788
+ // NOTE: xterm doesn't enable this code by default.
3789
+ Terminal.prototype.reverseAttrInRectangle = function(params) {
3790
+ ;
3791
+ };
3792
+
3793
+ // CSI > Ps; Ps t
3794
+ // Set one or more features of the title modes. Each parameter
3795
+ // enables a single feature.
3796
+ // Ps = 0 -> Set window/icon labels using hexadecimal.
3797
+ // Ps = 1 -> Query window/icon labels using hexadecimal.
3798
+ // Ps = 2 -> Set window/icon labels using UTF-8.
3799
+ // Ps = 3 -> Query window/icon labels using UTF-8. (See dis-
3800
+ // cussion of "Title Modes")
3801
+ Terminal.prototype.setTitleModeFeature = function(params) {
3802
+ ;
3803
+ };
3804
+
3805
+ // CSI Ps SP t
3806
+ // Set warning-bell volume (DECSWBV, VT520).
3807
+ // Ps = 0 or 1 -> off.
3808
+ // Ps = 2 , 3 or 4 -> low.
3809
+ // Ps = 5 , 6 , 7 , or 8 -> high.
3810
+ Terminal.prototype.setWarningBellVolume = function(params) {
3811
+ ;
3812
+ };
3813
+
3814
+ // CSI Ps SP u
3815
+ // Set margin-bell volume (DECSMBV, VT520).
3816
+ // Ps = 1 -> off.
3817
+ // Ps = 2 , 3 or 4 -> low.
3818
+ // Ps = 0 , 5 , 6 , 7 , or 8 -> high.
3819
+ Terminal.prototype.setMarginBellVolume = function(params) {
3820
+ ;
3821
+ };
3822
+
3823
+ // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v
3824
+ // Copy Rectangular Area (DECCRA, VT400 and up).
3825
+ // Pt; Pl; Pb; Pr denotes the rectangle.
3826
+ // Pp denotes the source page.
3827
+ // Pt; Pl denotes the target location.
3828
+ // Pp denotes the target page.
3829
+ // NOTE: xterm doesn't enable this code by default.
3830
+ Terminal.prototype.copyRectangle = function(params) {
3831
+ ;
3832
+ };
3833
+
3834
+ // CSI Pt ; Pl ; Pb ; Pr ' w
3835
+ // Enable Filter Rectangle (DECEFR), VT420 and up.
3836
+ // Parameters are [top;left;bottom;right].
3837
+ // Defines the coordinates of a filter rectangle and activates
3838
+ // it. Anytime the locator is detected outside of the filter
3839
+ // rectangle, an outside rectangle event is generated and the
3840
+ // rectangle is disabled. Filter rectangles are always treated
3841
+ // as "one-shot" events. Any parameters that are omitted default
3842
+ // to the current locator position. If all parameters are omit-
3843
+ // ted, any locator motion will be reported. DECELR always can-
3844
+ // cels any prevous rectangle definition.
3845
+ Terminal.prototype.enableFilterRectangle = function(params) {
3846
+ ;
3847
+ };
3848
+
3849
+ // CSI Ps x Request Terminal Parameters (DECREQTPARM).
3850
+ // if Ps is a "0" (default) or "1", and xterm is emulating VT100,
3851
+ // the control sequence elicits a response of the same form whose
3852
+ // parameters describe the terminal:
3853
+ // Ps -> the given Ps incremented by 2.
3854
+ // Pn = 1 <- no parity.
3855
+ // Pn = 1 <- eight bits.
3856
+ // Pn = 1 <- 2 8 transmit 38.4k baud.
3857
+ // Pn = 1 <- 2 8 receive 38.4k baud.
3858
+ // Pn = 1 <- clock multiplier.
3859
+ // Pn = 0 <- STP flags.
3860
+ Terminal.prototype.requestParameters = function(params) {
3861
+ ;
3862
+ };
3863
+
3864
+ // CSI Ps x Select Attribute Change Extent (DECSACE).
3865
+ // Ps = 0 -> from start to end position, wrapped.
3866
+ // Ps = 1 -> from start to end position, wrapped.
3867
+ // Ps = 2 -> rectangle (exact).
3868
+ Terminal.prototype.selectChangeExtent = function(params) {
3869
+ ;
3870
+ };
3871
+
3872
+ // CSI Pc; Pt; Pl; Pb; Pr$ x
3873
+ // Fill Rectangular Area (DECFRA), VT420 and up.
3874
+ // Pc is the character to use.
3875
+ // Pt; Pl; Pb; Pr denotes the rectangle.
3876
+ // NOTE: xterm doesn't enable this code by default.
3877
+ Terminal.prototype.fillRectangle = function(params) {
3878
+ var ch = params[0]
3879
+ , t = params[1]
3880
+ , l = params[2]
3881
+ , b = params[3]
3882
+ , r = params[4];
3883
+
3884
+ var line
3885
+ , i;
3886
+
3887
+ for (; t < b + 1; t++) {
3888
+ line = this.lines[this.ybase + t];
3889
+ for (i = l; i < r; i++) {
3890
+ line[i] = [line[i][0], String.fromCharCode(ch)];
3891
+ }
3892
+ }
3893
+
3894
+ // this.maxRange();
3895
+ this.updateRange(params[1]);
3896
+ this.updateRange(params[3]);
3897
+ };
3898
+
3899
+ // CSI Ps ; Pu ' z
3900
+ // Enable Locator Reporting (DECELR).
3901
+ // Valid values for the first parameter:
3902
+ // Ps = 0 -> Locator disabled (default).
3903
+ // Ps = 1 -> Locator enabled.
3904
+ // Ps = 2 -> Locator enabled for one report, then disabled.
3905
+ // The second parameter specifies the coordinate unit for locator
3906
+ // reports.
3907
+ // Valid values for the second parameter:
3908
+ // Pu = 0 <- or omitted -> default to character cells.
3909
+ // Pu = 1 <- device physical pixels.
3910
+ // Pu = 2 <- character cells.
3911
+ Terminal.prototype.enableLocatorReporting = function(params) {
3912
+ var val = params[0] > 0;
3913
+ //this.mouseEvents = val;
3914
+ //this.decLocator = val;
3915
+ };
3916
+
3917
+ // CSI Pt; Pl; Pb; Pr$ z
3918
+ // Erase Rectangular Area (DECERA), VT400 and up.
3919
+ // Pt; Pl; Pb; Pr denotes the rectangle.
3920
+ // NOTE: xterm doesn't enable this code by default.
3921
+ Terminal.prototype.eraseRectangle = function(params) {
3922
+ var t = params[0]
3923
+ , l = params[1]
3924
+ , b = params[2]
3925
+ , r = params[3];
3926
+
3927
+ var line
3928
+ , i
3929
+ , ch;
3930
+
3931
+ ch = [this.curAttr, ' ']; // xterm?
3932
+
3933
+ for (; t < b + 1; t++) {
3934
+ line = this.lines[this.ybase + t];
3935
+ for (i = l; i < r; i++) {
3936
+ line[i] = ch;
3937
+ }
3938
+ }
3939
+
3940
+ // this.maxRange();
3941
+ this.updateRange(params[0]);
3942
+ this.updateRange(params[2]);
3943
+ };
3944
+
3945
+ // CSI Pm ' {
3946
+ // Select Locator Events (DECSLE).
3947
+ // Valid values for the first (and any additional parameters)
3948
+ // are:
3949
+ // Ps = 0 -> only respond to explicit host requests (DECRQLP).
3950
+ // (This is default). It also cancels any filter
3951
+ // rectangle.
3952
+ // Ps = 1 -> report button down transitions.
3953
+ // Ps = 2 -> do not report button down transitions.
3954
+ // Ps = 3 -> report button up transitions.
3955
+ // Ps = 4 -> do not report button up transitions.
3956
+ Terminal.prototype.setLocatorEvents = function(params) {
3957
+ ;
3958
+ };
3959
+
3960
+ // CSI Pt; Pl; Pb; Pr$ {
3961
+ // Selective Erase Rectangular Area (DECSERA), VT400 and up.
3962
+ // Pt; Pl; Pb; Pr denotes the rectangle.
3963
+ Terminal.prototype.selectiveEraseRectangle = function(params) {
3964
+ ;
3965
+ };
3966
+
3967
+ // CSI Ps ' |
3968
+ // Request Locator Position (DECRQLP).
3969
+ // Valid values for the parameter are:
3970
+ // Ps = 0 , 1 or omitted -> transmit a single DECLRP locator
3971
+ // report.
3972
+
3973
+ // If Locator Reporting has been enabled by a DECELR, xterm will
3974
+ // respond with a DECLRP Locator Report. This report is also
3975
+ // generated on button up and down events if they have been
3976
+ // enabled with a DECSLE, or when the locator is detected outside
3977
+ // of a filter rectangle, if filter rectangles have been enabled
3978
+ // with a DECEFR.
3979
+
3980
+ // -> CSI Pe ; Pb ; Pr ; Pc ; Pp & w
3981
+
3982
+ // Parameters are [event;button;row;column;page].
3983
+ // Valid values for the event:
3984
+ // Pe = 0 -> locator unavailable - no other parameters sent.
3985
+ // Pe = 1 -> request - xterm received a DECRQLP.
3986
+ // Pe = 2 -> left button down.
3987
+ // Pe = 3 -> left button up.
3988
+ // Pe = 4 -> middle button down.
3989
+ // Pe = 5 -> middle button up.
3990
+ // Pe = 6 -> right button down.
3991
+ // Pe = 7 -> right button up.
3992
+ // Pe = 8 -> M4 button down.
3993
+ // Pe = 9 -> M4 button up.
3994
+ // Pe = 1 0 -> locator outside filter rectangle.
3995
+ // ``button'' parameter is a bitmask indicating which buttons are
3996
+ // pressed:
3997
+ // Pb = 0 <- no buttons down.
3998
+ // Pb & 1 <- right button down.
3999
+ // Pb & 2 <- middle button down.
4000
+ // Pb & 4 <- left button down.
4001
+ // Pb & 8 <- M4 button down.
4002
+ // ``row'' and ``column'' parameters are the coordinates of the
4003
+ // locator position in the xterm window, encoded as ASCII deci-
4004
+ // mal.
4005
+ // The ``page'' parameter is not used by xterm, and will be omit-
4006
+ // ted.
4007
+ Terminal.prototype.requestLocatorPosition = function(params) {
4008
+ ;
4009
+ };
4010
+
4011
+ // CSI P m SP }
4012
+ // Insert P s Column(s) (default = 1) (DECIC), VT420 and up.
4013
+ // NOTE: xterm doesn't enable this code by default.
4014
+ Terminal.prototype.insertColumns = function() {
4015
+ var param = params[0]
4016
+ , l = this.ybase + this.rows
4017
+ , ch = [this.curAttr, ' '] // xterm?
4018
+ , i;
4019
+
4020
+ while (param--) {
4021
+ for (i = this.ybase; i < l; i++) {
4022
+ this.lines[i].splice(this.x + 1, 0, ch);
4023
+ this.lines[i].pop();
4024
+ }
4025
+ }
4026
+
4027
+ this.maxRange();
4028
+ };
4029
+
4030
+ // CSI P m SP ~
4031
+ // Delete P s Column(s) (default = 1) (DECDC), VT420 and up
4032
+ // NOTE: xterm doesn't enable this code by default.
4033
+ Terminal.prototype.deleteColumns = function() {
4034
+ var param = params[0]
4035
+ , l = this.ybase + this.rows
4036
+ , ch = [this.curAttr, ' '] // xterm?
4037
+ , i;
4038
+
4039
+ while (param--) {
4040
+ for (i = this.ybase; i < l; i++) {
4041
+ this.lines[i].splice(this.x, 1);
4042
+ this.lines[i].push(ch);
4043
+ }
4044
+ }
4045
+
4046
+ this.maxRange();
4047
+ };
4048
+
4049
+ /**
4050
+ * Character Sets
4051
+ */
4052
+
4053
+ Terminal.charsets = {};
4054
+
4055
+ // DEC Special Character and Line Drawing Set.
4056
+ // http://vt100.net/docs/vt102-ug/table5-13.html
4057
+ // A lot of curses apps use this if they see TERM=xterm.
4058
+ // testing: echo -e '\e(0a\e(B'
4059
+ // The xterm output sometimes seems to conflict with the
4060
+ // reference above. xterm seems in line with the reference
4061
+ // when running vttest however.
4062
+ // The table below now uses xterm's output from vttest.
4063
+ Terminal.charsets.SCLD = { // (0
4064
+ '`': '\u25c6', // '◆'
4065
+ 'a': '\u2592', // '▒'
4066
+ 'b': '\u0009', // '\t'
4067
+ 'c': '\u000c', // '\f'
4068
+ 'd': '\u000d', // '\r'
4069
+ 'e': '\u000a', // '\n'
4070
+ 'f': '\u00b0', // '°'
4071
+ 'g': '\u00b1', // '±'
4072
+ 'h': '\u2424', // '\u2424' (NL)
4073
+ 'i': '\u000b', // '\v'
4074
+ 'j': '\u2518', // '┘'
4075
+ 'k': '\u2510', // '┐'
4076
+ 'l': '\u250c', // '┌'
4077
+ 'm': '\u2514', // '└'
4078
+ 'n': '\u253c', // '┼'
4079
+ 'o': '\u23ba', // '⎺'
4080
+ 'p': '\u23bb', // '⎻'
4081
+ 'q': '\u2500', // '─'
4082
+ 'r': '\u23bc', // '⎼'
4083
+ 's': '\u23bd', // '⎽'
4084
+ 't': '\u251c', // '├'
4085
+ 'u': '\u2524', // '┤'
4086
+ 'v': '\u2534', // '┴'
4087
+ 'w': '\u252c', // '┬'
4088
+ 'x': '\u2502', // '│'
4089
+ 'y': '\u2264', // '≤'
4090
+ 'z': '\u2265', // '≥'
4091
+ '{': '\u03c0', // 'π'
4092
+ '|': '\u2260', // '≠'
4093
+ '}': '\u00a3', // '£'
4094
+ '~': '\u00b7' // '·'
4095
+ };
4096
+
4097
+ Terminal.charsets.UK = null; // (A
4098
+ Terminal.charsets.US = null; // (B (USASCII)
4099
+ Terminal.charsets.Dutch = null; // (4
4100
+ Terminal.charsets.Finnish = null; // (C or (5
4101
+ Terminal.charsets.French = null; // (R
4102
+ Terminal.charsets.FrenchCanadian = null; // (Q
4103
+ Terminal.charsets.German = null; // (K
4104
+ Terminal.charsets.Italian = null; // (Y
4105
+ Terminal.charsets.NorwegianDanish = null; // (E or (6
4106
+ Terminal.charsets.Spanish = null; // (Z
4107
+ Terminal.charsets.Swedish = null; // (H or (7
4108
+ Terminal.charsets.Swiss = null; // (=
4109
+ Terminal.charsets.ISOLatin = null; // /A
4110
+
4111
+ /**
4112
+ * Helpers
4113
+ */
4114
+
4115
+ function on(el, type, handler, capture) {
4116
+ el.addEventListener(type, handler, capture || false);
4117
+ }
4118
+
4119
+ function off(el, type, handler, capture) {
4120
+ el.removeEventListener(type, handler, capture || false);
4121
+ }
4122
+
4123
+ function cancel(ev) {
4124
+ if (ev.preventDefault) ev.preventDefault();
4125
+ ev.returnValue = false;
4126
+ if (ev.stopPropagation) ev.stopPropagation();
4127
+ ev.cancelBubble = true;
4128
+ return false;
4129
+ }
4130
+
4131
+ function inherits(child, parent) {
4132
+ function f() {
4133
+ this.constructor = child;
4134
+ }
4135
+ f.prototype = parent.prototype;
4136
+ child.prototype = new f;
4137
+ }
4138
+
4139
+ var isMac = ~navigator.userAgent.indexOf('Mac');
4140
+
4141
+ // if bold is broken, we can't
4142
+ // use it in the terminal.
4143
+ function isBoldBroken() {
4144
+ var el = document.createElement('span');
4145
+ el.innerHTML = 'hello world';
4146
+ document.body.appendChild(el);
4147
+ var w1 = el.scrollWidth;
4148
+ el.style.fontWeight = 'bold';
4149
+ var w2 = el.scrollWidth;
4150
+ document.body.removeChild(el);
4151
+ return w1 !== w2;
4152
+ }
4153
+
4154
+ var String = this.String;
4155
+ var setTimeout = this.setTimeout;
4156
+ var setInterval = this.setInterval;
4157
+
4158
+ /**
4159
+ * Expose
4160
+ */
4161
+
4162
+ Terminal.EventEmitter = EventEmitter;
4163
+ Terminal.isMac = isMac;
4164
+ Terminal.inherits = inherits;
4165
+ Terminal.on = on;
4166
+ Terminal.off = off;
4167
+ Terminal.cancel = cancel;
4168
+
4169
+ if (typeof module !== 'undefined') {
4170
+ module.exports = Terminal;
4171
+ } else {
4172
+ this.Terminal = Terminal;
4173
+ }
4174
+
4175
+ }).call(function() {
4176
+ return this || (typeof window !== 'undefined' ? window : global);
4177
+ }());