character_editor 0.0.9 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1063 @@
1
+ // Generated by CoffeeScript 1.6.3
2
+ /*
3
+ Copyright 2014 David Mauro
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+
17
+ Keypress is a robust keyboard input capturing Javascript utility
18
+ focused on input for games.
19
+
20
+ version 2.0.1
21
+ */
22
+
23
+
24
+ /*
25
+ Combo options available and their defaults:
26
+ keys : [] - An array of the keys pressed together to activate combo.
27
+ count : 0 - The number of times a counting combo has been pressed. Reset on release.
28
+ is_unordered : false - Unless this is set to true, the keys can be pressed down in any order.
29
+ is_counting : false - Makes this a counting combo (see documentation).
30
+ is_exclusive : false - This combo will replace other exclusive combos when true.
31
+ is_solitary : false - This combo will only fire if ONLY it's keys are pressed down.
32
+ is_sequence : false - Rather than a key combo, this is an ordered key sequence.
33
+ prevent_default : false - Prevent default behavior for all component key keypresses.
34
+ prevent_repeat : false - Prevent the combo from repeating when keydown is held.
35
+ on_keydown : null - A function that is called when the combo is pressed.
36
+ on_keyup : null - A function that is called when the combo is released.
37
+ on_release : null - A function that is called when all keys in the combo are released.
38
+ this : undefined - Defines the scope for your callback functions.
39
+ */
40
+
41
+
42
+ (function() {
43
+ var Combo, _change_keycodes_by_browser, _compare_arrays, _compare_arrays_sorted, _convert_key_to_readable, _convert_to_shifted_key, _decide_meta_key, _factory_defaults, _filter_array, _is_array_in_array, _is_array_in_array_sorted, _key_is_valid, _keycode_alternate_names, _keycode_dictionary, _keycode_shifted_keys, _log_error, _metakey, _modifier_event_mapping, _modifier_keys, _validate_combo,
44
+ __hasProp = {}.hasOwnProperty,
45
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
46
+
47
+ _factory_defaults = {
48
+ is_unordered: false,
49
+ is_counting: false,
50
+ is_exclusive: false,
51
+ is_solitary: false,
52
+ prevent_default: false,
53
+ prevent_repeat: false
54
+ };
55
+
56
+ _modifier_keys = ["meta", "alt", "option", "ctrl", "shift", "cmd"];
57
+
58
+ _metakey = "ctrl";
59
+
60
+ window.keypress = {};
61
+
62
+ keypress.debug = false;
63
+
64
+ Combo = (function() {
65
+ function Combo(dictionary) {
66
+ var property, value;
67
+ for (property in dictionary) {
68
+ if (!__hasProp.call(dictionary, property)) continue;
69
+ value = dictionary[property];
70
+ if (value !== false) {
71
+ this[property] = value;
72
+ }
73
+ }
74
+ this.keys = this.keys || [];
75
+ this.count = this.count || 0;
76
+ }
77
+
78
+ Combo.prototype.allows_key_repeat = function() {
79
+ return !this.prevent_repeat && typeof this.on_keydown === "function";
80
+ };
81
+
82
+ Combo.prototype.reset = function() {
83
+ this.count = 0;
84
+ return this.keyup_fired = null;
85
+ };
86
+
87
+ return Combo;
88
+
89
+ })();
90
+
91
+ keypress.Listener = (function() {
92
+ function Listener(element, defaults) {
93
+ var attach_handler, property, value,
94
+ _this = this;
95
+ this.should_suppress_event_defaults = false;
96
+ this.should_force_event_defaults = false;
97
+ this.sequence_delay = 800;
98
+ this._registered_combos = [];
99
+ this._keys_down = [];
100
+ this._active_combos = [];
101
+ this._sequence = [];
102
+ this._sequence_timer = null;
103
+ this._prevent_capture = false;
104
+ this._defaults = defaults || {};
105
+ for (property in _factory_defaults) {
106
+ if (!__hasProp.call(_factory_defaults, property)) continue;
107
+ value = _factory_defaults[property];
108
+ this._defaults[property] = this._defaults[property] || value;
109
+ }
110
+ element = element || document.body;
111
+ attach_handler = function(target, event, handler) {
112
+ if (target.addEventListener) {
113
+ return target.addEventListener(event, handler);
114
+ } else if (target.attachEvent) {
115
+ return target.attachEvent("on" + event, handler);
116
+ }
117
+ };
118
+ attach_handler(element, "keydown", function(e) {
119
+ e = e || window.event;
120
+ _this._receive_input(e, true);
121
+ return _this._bug_catcher(e);
122
+ });
123
+ attach_handler(element, "keyup", function(e) {
124
+ e = e || window.event;
125
+ return _this._receive_input(e, false);
126
+ });
127
+ attach_handler(window, "blur", function() {
128
+ var key, _i, _len, _ref;
129
+ _ref = _this._keys_down;
130
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
131
+ key = _ref[_i];
132
+ _this._key_up(key, {});
133
+ }
134
+ return _this._keys_down = [];
135
+ });
136
+ }
137
+
138
+ Listener.prototype._bug_catcher = function(e) {
139
+ var _ref;
140
+ if (_metakey === "cmd" && __indexOf.call(this._keys_down, "cmd") >= 0 && ((_ref = _convert_key_to_readable(e.keyCode)) !== "cmd" && _ref !== "shift" && _ref !== "alt" && _ref !== "caps" && _ref !== "tab")) {
141
+ return this._receive_input(e, false);
142
+ }
143
+ };
144
+
145
+ Listener.prototype._cmd_bug_check = function(combo_keys) {
146
+ if (_metakey === "cmd" && __indexOf.call(this._keys_down, "cmd") >= 0 && __indexOf.call(combo_keys, "cmd") < 0) {
147
+ return false;
148
+ }
149
+ return true;
150
+ };
151
+
152
+ Listener.prototype._prevent_default = function(e, should_prevent) {
153
+ if ((should_prevent || this.should_suppress_event_defaults) && !this.should_force_event_defaults) {
154
+ if (e.preventDefault) {
155
+ e.preventDefault();
156
+ } else {
157
+ e.returnValue = false;
158
+ }
159
+ if (e.stopPropagation) {
160
+ return e.stopPropagation();
161
+ }
162
+ }
163
+ };
164
+
165
+ Listener.prototype._get_active_combos = function(key) {
166
+ var active_combos, keys_down,
167
+ _this = this;
168
+ active_combos = [];
169
+ keys_down = _filter_array(this._keys_down, function(down_key) {
170
+ return down_key !== key;
171
+ });
172
+ keys_down.push(key);
173
+ this._match_combo_arrays(keys_down, function(match) {
174
+ if (_this._cmd_bug_check(match.keys)) {
175
+ return active_combos.push(match);
176
+ }
177
+ });
178
+ this._fuzzy_match_combo_arrays(keys_down, function(match) {
179
+ if (__indexOf.call(active_combos, match) >= 0) {
180
+ return;
181
+ }
182
+ if (!(match.is_solitary || !_this._cmd_bug_check(match.keys))) {
183
+ return active_combos.push(match);
184
+ }
185
+ });
186
+ return active_combos;
187
+ };
188
+
189
+ Listener.prototype._get_potential_combos = function(key) {
190
+ var combo, potentials, _i, _len, _ref;
191
+ potentials = [];
192
+ _ref = this._registered_combos;
193
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
194
+ combo = _ref[_i];
195
+ if (combo.is_sequence) {
196
+ continue;
197
+ }
198
+ if (__indexOf.call(combo.keys, key) >= 0 && this._cmd_bug_check(combo.keys)) {
199
+ potentials.push(combo);
200
+ }
201
+ }
202
+ return potentials;
203
+ };
204
+
205
+ Listener.prototype._add_to_active_combos = function(combo) {
206
+ var active_combo, active_key, active_keys, already_replaced, combo_key, i, should_prepend, should_replace, _i, _j, _k, _len, _len1, _ref, _ref1;
207
+ should_replace = false;
208
+ should_prepend = true;
209
+ already_replaced = false;
210
+ if (__indexOf.call(this._active_combos, combo) >= 0) {
211
+ return true;
212
+ } else if (this._active_combos.length) {
213
+ for (i = _i = 0, _ref = this._active_combos.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
214
+ active_combo = this._active_combos[i];
215
+ if (!(active_combo && active_combo.is_exclusive && combo.is_exclusive)) {
216
+ continue;
217
+ }
218
+ active_keys = active_combo.keys;
219
+ if (!should_replace) {
220
+ for (_j = 0, _len = active_keys.length; _j < _len; _j++) {
221
+ active_key = active_keys[_j];
222
+ should_replace = true;
223
+ if (__indexOf.call(combo.keys, active_key) < 0) {
224
+ should_replace = false;
225
+ break;
226
+ }
227
+ }
228
+ }
229
+ if (should_prepend && !should_replace) {
230
+ _ref1 = combo.keys;
231
+ for (_k = 0, _len1 = _ref1.length; _k < _len1; _k++) {
232
+ combo_key = _ref1[_k];
233
+ should_prepend = false;
234
+ if (__indexOf.call(active_keys, combo_key) < 0) {
235
+ should_prepend = true;
236
+ break;
237
+ }
238
+ }
239
+ }
240
+ if (should_replace) {
241
+ if (already_replaced) {
242
+ active_combo = this._active_combos.splice(i, 1)[0];
243
+ if (active_combo != null) {
244
+ active_combo.reset();
245
+ }
246
+ } else {
247
+ active_combo = this._active_combos.splice(i, 1, combo)[0];
248
+ if (active_combo != null) {
249
+ active_combo.reset();
250
+ }
251
+ already_replaced = true;
252
+ }
253
+ should_prepend = false;
254
+ }
255
+ }
256
+ }
257
+ if (should_prepend) {
258
+ this._active_combos.unshift(combo);
259
+ }
260
+ return should_replace || should_prepend;
261
+ };
262
+
263
+ Listener.prototype._remove_from_active_combos = function(combo) {
264
+ var active_combo, i, _i, _ref;
265
+ for (i = _i = 0, _ref = this._active_combos.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
266
+ active_combo = this._active_combos[i];
267
+ if (active_combo === combo) {
268
+ combo = this._active_combos.splice(i, 1)[0];
269
+ combo.reset();
270
+ break;
271
+ }
272
+ }
273
+ };
274
+
275
+ Listener.prototype._get_possible_sequences = function() {
276
+ var combo, i, j, match, matches, sequence, _i, _j, _k, _len, _ref, _ref1, _ref2;
277
+ matches = [];
278
+ _ref = this._registered_combos;
279
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
280
+ combo = _ref[_i];
281
+ for (j = _j = 1, _ref1 = this._sequence.length; 1 <= _ref1 ? _j <= _ref1 : _j >= _ref1; j = 1 <= _ref1 ? ++_j : --_j) {
282
+ sequence = this._sequence.slice(-j);
283
+ if (!combo.is_sequence) {
284
+ continue;
285
+ }
286
+ if (__indexOf.call(combo.keys, "shift") < 0) {
287
+ sequence = _filter_array(sequence, function(key) {
288
+ return key !== "shift";
289
+ });
290
+ if (!sequence.length) {
291
+ continue;
292
+ }
293
+ }
294
+ for (i = _k = 0, _ref2 = sequence.length; 0 <= _ref2 ? _k < _ref2 : _k > _ref2; i = 0 <= _ref2 ? ++_k : --_k) {
295
+ if (combo.keys[i] === sequence[i]) {
296
+ match = true;
297
+ } else {
298
+ match = false;
299
+ break;
300
+ }
301
+ }
302
+ if (match) {
303
+ matches.push(combo);
304
+ }
305
+ }
306
+ }
307
+ return matches;
308
+ };
309
+
310
+ Listener.prototype._add_key_to_sequence = function(key, e) {
311
+ var combo, sequence_combos, _i, _len;
312
+ this._sequence.push(key);
313
+ sequence_combos = this._get_possible_sequences();
314
+ if (sequence_combos.length) {
315
+ for (_i = 0, _len = sequence_combos.length; _i < _len; _i++) {
316
+ combo = sequence_combos[_i];
317
+ this._prevent_default(e, combo.prevent_default);
318
+ }
319
+ if (this._sequence_timer) {
320
+ clearTimeout(this._sequence_timer);
321
+ }
322
+ if (this.sequence_delay > -1) {
323
+ this._sequence_timer = setTimeout(function() {
324
+ return this._sequence = [];
325
+ }, this.sequence_delay);
326
+ }
327
+ } else {
328
+ this._sequence = [];
329
+ }
330
+ };
331
+
332
+ Listener.prototype._get_sequence = function(key) {
333
+ var combo, i, j, match, seq_key, sequence, _i, _j, _k, _len, _ref, _ref1, _ref2;
334
+ _ref = this._registered_combos;
335
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
336
+ combo = _ref[_i];
337
+ if (!combo.is_sequence) {
338
+ continue;
339
+ }
340
+ for (j = _j = 1, _ref1 = this._sequence.length; 1 <= _ref1 ? _j <= _ref1 : _j >= _ref1; j = 1 <= _ref1 ? ++_j : --_j) {
341
+ sequence = (_filter_array(this._sequence, function(seq_key) {
342
+ if (__indexOf.call(combo.keys, "shift") >= 0) {
343
+ return true;
344
+ }
345
+ return seq_key !== "shift";
346
+ })).slice(-j);
347
+ if (combo.keys.length !== sequence.length) {
348
+ continue;
349
+ }
350
+ for (i = _k = 0, _ref2 = sequence.length; 0 <= _ref2 ? _k < _ref2 : _k > _ref2; i = 0 <= _ref2 ? ++_k : --_k) {
351
+ seq_key = sequence[i];
352
+ if (__indexOf.call(combo.keys, "shift") < 0 ? seq_key === "shift" : void 0) {
353
+ continue;
354
+ }
355
+ if (key === "shift" && __indexOf.call(combo.keys, "shift") < 0) {
356
+ continue;
357
+ }
358
+ if (combo.keys[i] === seq_key) {
359
+ match = true;
360
+ } else {
361
+ match = false;
362
+ break;
363
+ }
364
+ }
365
+ }
366
+ if (match) {
367
+ return combo;
368
+ }
369
+ }
370
+ return false;
371
+ };
372
+
373
+ Listener.prototype._receive_input = function(e, is_keydown) {
374
+ var key;
375
+ if (this._prevent_capture) {
376
+ if (this._keys_down.length) {
377
+ this._keys_down = [];
378
+ }
379
+ return;
380
+ }
381
+ key = _convert_key_to_readable(e.keyCode);
382
+ if (!is_keydown && !this._keys_down.length && (key === "alt" || key === _metakey)) {
383
+ return;
384
+ }
385
+ if (!key) {
386
+ return;
387
+ }
388
+ if (is_keydown) {
389
+ return this._key_down(key, e);
390
+ } else {
391
+ return this._key_up(key, e);
392
+ }
393
+ };
394
+
395
+ Listener.prototype._fire = function(event, combo, key_event, is_autorepeat) {
396
+ if (typeof combo["on_" + event] === "function") {
397
+ this._prevent_default(key_event, combo["on_" + event].call(combo["this"], key_event, combo.count, is_autorepeat) !== true);
398
+ }
399
+ if (event === "release") {
400
+ combo.count = 0;
401
+ }
402
+ if (event === "keyup") {
403
+ return combo.keyup_fired = true;
404
+ }
405
+ };
406
+
407
+ Listener.prototype._match_combo_arrays = function(potential_match, match_handler) {
408
+ var source_combo, _i, _len, _ref;
409
+ _ref = this._registered_combos;
410
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
411
+ source_combo = _ref[_i];
412
+ if ((!source_combo.is_unordered && _compare_arrays_sorted(potential_match, source_combo.keys)) || (source_combo.is_unordered && _compare_arrays(potential_match, source_combo.keys))) {
413
+ match_handler(source_combo);
414
+ }
415
+ }
416
+ };
417
+
418
+ Listener.prototype._fuzzy_match_combo_arrays = function(potential_match, match_handler) {
419
+ var source_combo, _i, _len, _ref;
420
+ _ref = this._registered_combos;
421
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
422
+ source_combo = _ref[_i];
423
+ if ((!source_combo.is_unordered && _is_array_in_array_sorted(source_combo.keys, potential_match)) || (source_combo.is_unordered && _is_array_in_array(source_combo.keys, potential_match))) {
424
+ match_handler(source_combo);
425
+ }
426
+ }
427
+ };
428
+
429
+ Listener.prototype._keys_remain = function(combo) {
430
+ var key, keys_remain, _i, _len, _ref;
431
+ _ref = combo.keys;
432
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
433
+ key = _ref[_i];
434
+ if (__indexOf.call(this._keys_down, key) >= 0) {
435
+ keys_remain = true;
436
+ break;
437
+ }
438
+ }
439
+ return keys_remain;
440
+ };
441
+
442
+ Listener.prototype._key_down = function(key, e) {
443
+ var combo, combos, event_mod, i, mod, potential, potential_combos, sequence_combo, shifted_key, _i, _j, _k, _len, _len1, _ref;
444
+ shifted_key = _convert_to_shifted_key(key, e);
445
+ if (shifted_key) {
446
+ key = shifted_key;
447
+ }
448
+ this._add_key_to_sequence(key, e);
449
+ sequence_combo = this._get_sequence(key);
450
+ if (sequence_combo) {
451
+ this._fire("keydown", sequence_combo, e);
452
+ }
453
+ for (mod in _modifier_event_mapping) {
454
+ event_mod = _modifier_event_mapping[mod];
455
+ if (!e[event_mod]) {
456
+ continue;
457
+ }
458
+ if (mod === key || __indexOf.call(this._keys_down, mod) >= 0) {
459
+ continue;
460
+ }
461
+ this._keys_down.push(mod);
462
+ }
463
+ for (mod in _modifier_event_mapping) {
464
+ event_mod = _modifier_event_mapping[mod];
465
+ if (mod === key) {
466
+ continue;
467
+ }
468
+ if (__indexOf.call(this._keys_down, mod) >= 0 && !e[event_mod]) {
469
+ if (mod === "cmd" && _metakey !== "cmd") {
470
+ continue;
471
+ }
472
+ for (i = _i = 0, _ref = this._keys_down.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
473
+ if (this._keys_down[i] === mod) {
474
+ this._keys_down.splice(i, 1);
475
+ }
476
+ }
477
+ }
478
+ }
479
+ combos = this._get_active_combos(key);
480
+ potential_combos = this._get_potential_combos(key);
481
+ for (_j = 0, _len = combos.length; _j < _len; _j++) {
482
+ combo = combos[_j];
483
+ this._handle_combo_down(combo, potential_combos, key, e);
484
+ }
485
+ if (potential_combos.length) {
486
+ for (_k = 0, _len1 = potential_combos.length; _k < _len1; _k++) {
487
+ potential = potential_combos[_k];
488
+ this._prevent_default(e, potential.prevent_default);
489
+ }
490
+ }
491
+ if (__indexOf.call(this._keys_down, key) < 0) {
492
+ this._keys_down.push(key);
493
+ }
494
+ };
495
+
496
+ Listener.prototype._handle_combo_down = function(combo, potential_combos, key, e) {
497
+ var is_autorepeat, is_other_exclusive, potential_combo, result, _i, _len;
498
+ if (__indexOf.call(combo.keys, key) < 0) {
499
+ return false;
500
+ }
501
+ this._prevent_default(e, combo && combo.prevent_default);
502
+ is_autorepeat = false;
503
+ if (__indexOf.call(this._keys_down, key) >= 0) {
504
+ is_autorepeat = true;
505
+ if (!combo.allows_key_repeat()) {
506
+ return false;
507
+ }
508
+ }
509
+ result = this._add_to_active_combos(combo, key);
510
+ combo.keyup_fired = false;
511
+ is_other_exclusive = false;
512
+ if (combo.is_exclusive) {
513
+ for (_i = 0, _len = potential_combos.length; _i < _len; _i++) {
514
+ potential_combo = potential_combos[_i];
515
+ if (potential_combo.is_exclusive && potential_combo.keys.length > combo.keys.length) {
516
+ is_other_exclusive = true;
517
+ break;
518
+ }
519
+ }
520
+ }
521
+ if (!is_other_exclusive) {
522
+ if (combo.is_counting && typeof combo.on_keydown === "function") {
523
+ combo.count += 1;
524
+ }
525
+ if (result) {
526
+ return this._fire("keydown", combo, e, is_autorepeat);
527
+ }
528
+ }
529
+ };
530
+
531
+ Listener.prototype._key_up = function(key, e) {
532
+ var active_combo, active_combos_length, combo, combos, i, sequence_combo, shifted_key, unshifted_key, _i, _j, _k, _l, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
533
+ unshifted_key = key;
534
+ shifted_key = _convert_to_shifted_key(key, e);
535
+ if (shifted_key) {
536
+ key = shifted_key;
537
+ }
538
+ shifted_key = _keycode_shifted_keys[unshifted_key];
539
+ if (e.shiftKey) {
540
+ if (!(shifted_key && __indexOf.call(this._keys_down, shifted_key) >= 0)) {
541
+ key = unshifted_key;
542
+ }
543
+ } else {
544
+ if (!(unshifted_key && __indexOf.call(this._keys_down, unshifted_key) >= 0)) {
545
+ key = shifted_key;
546
+ }
547
+ }
548
+ sequence_combo = this._get_sequence(key);
549
+ if (sequence_combo) {
550
+ this._fire("keyup", sequence_combo, e);
551
+ }
552
+ if (__indexOf.call(this._keys_down, key) < 0) {
553
+ return false;
554
+ }
555
+ for (i = _i = 0, _ref = this._keys_down.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
556
+ if ((_ref1 = this._keys_down[i]) === key || _ref1 === shifted_key || _ref1 === unshifted_key) {
557
+ this._keys_down.splice(i, 1);
558
+ break;
559
+ }
560
+ }
561
+ active_combos_length = this._active_combos.length;
562
+ combos = [];
563
+ _ref2 = this._active_combos;
564
+ for (_j = 0, _len = _ref2.length; _j < _len; _j++) {
565
+ active_combo = _ref2[_j];
566
+ if (__indexOf.call(active_combo.keys, key) >= 0) {
567
+ combos.push(active_combo);
568
+ }
569
+ }
570
+ for (_k = 0, _len1 = combos.length; _k < _len1; _k++) {
571
+ combo = combos[_k];
572
+ this._handle_combo_up(combo, e, key);
573
+ }
574
+ if (active_combos_length > 1) {
575
+ _ref3 = this._active_combos;
576
+ for (_l = 0, _len2 = _ref3.length; _l < _len2; _l++) {
577
+ active_combo = _ref3[_l];
578
+ if (active_combo === void 0 || __indexOf.call(combos, active_combo) >= 0) {
579
+ continue;
580
+ }
581
+ if (!this._keys_remain(active_combo)) {
582
+ this._remove_from_active_combos(active_combo);
583
+ }
584
+ }
585
+ }
586
+ };
587
+
588
+ Listener.prototype._handle_combo_up = function(combo, e, key) {
589
+ var keys_down, keys_remaining;
590
+ this._prevent_default(e, combo && combo.prevent_default);
591
+ keys_remaining = this._keys_remain(combo);
592
+ if (!combo.keyup_fired) {
593
+ keys_down = this._keys_down.slice();
594
+ keys_down.push(key);
595
+ if (!combo.is_solitary || _compare_arrays(keys_down, combo.keys)) {
596
+ this._fire("keyup", combo, e);
597
+ if (combo.is_counting && typeof combo.on_keyup === "function" && typeof combo.on_keydown !== "function") {
598
+ combo.count += 1;
599
+ }
600
+ }
601
+ }
602
+ if (!keys_remaining) {
603
+ this._fire("release", combo, e);
604
+ this._remove_from_active_combos(combo);
605
+ }
606
+ };
607
+
608
+ Listener.prototype.simple_combo = function(keys, callback) {
609
+ return this.register_combo({
610
+ keys: keys,
611
+ on_keydown: callback
612
+ });
613
+ };
614
+
615
+ Listener.prototype.counting_combo = function(keys, count_callback) {
616
+ return this.register_combo({
617
+ keys: keys,
618
+ is_counting: true,
619
+ is_unordered: false,
620
+ on_keydown: count_callback
621
+ });
622
+ };
623
+
624
+ Listener.prototype.sequence_combo = function(keys, callback) {
625
+ return this.register_combo({
626
+ keys: keys,
627
+ on_keydown: callback,
628
+ is_sequence: true
629
+ });
630
+ };
631
+
632
+ Listener.prototype.register_combo = function(combo_dictionary) {
633
+ var combo, property, value, _ref;
634
+ if (typeof combo_dictionary["keys"] === "string") {
635
+ combo_dictionary["keys"] = combo_dictionary["keys"].split(" ");
636
+ }
637
+ _ref = this._defaults;
638
+ for (property in _ref) {
639
+ if (!__hasProp.call(_ref, property)) continue;
640
+ value = _ref[property];
641
+ if (combo_dictionary[property] === void 0) {
642
+ combo_dictionary[property] = value;
643
+ }
644
+ }
645
+ combo = new Combo(combo_dictionary);
646
+ if (_validate_combo(combo)) {
647
+ this._registered_combos.push(combo);
648
+ return true;
649
+ }
650
+ };
651
+
652
+ Listener.prototype.register_many = function(combo_array) {
653
+ var combo, _i, _len, _results;
654
+ _results = [];
655
+ for (_i = 0, _len = combo_array.length; _i < _len; _i++) {
656
+ combo = combo_array[_i];
657
+ _results.push(this.register_combo(combo));
658
+ }
659
+ return _results;
660
+ };
661
+
662
+ Listener.prototype.unregister_combo = function(keys_or_combo) {
663
+ var combo, unregister_combo, _i, _len, _ref,
664
+ _this = this;
665
+ if (!keys_or_combo) {
666
+ return false;
667
+ }
668
+ unregister_combo = function(combo) {
669
+ var i, _i, _ref, _results;
670
+ _results = [];
671
+ for (i = _i = 0, _ref = _this._registered_combos.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
672
+ if (combo === _this._registered_combos[i]) {
673
+ _this._registered_combos.splice(i, 1);
674
+ break;
675
+ } else {
676
+ _results.push(void 0);
677
+ }
678
+ }
679
+ return _results;
680
+ };
681
+ if (keys_or_combo.keys) {
682
+ return unregister_combo(keys_or_combo);
683
+ } else {
684
+ _ref = this._registered_combos;
685
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
686
+ combo = _ref[_i];
687
+ if (!combo) {
688
+ continue;
689
+ }
690
+ }
691
+ if (typeof keys_or_combo === "string") {
692
+ keys_or_combo = keys_or_combo.split(" ");
693
+ }
694
+ if ((combo.is_unordered && _compare_arrays(keys_or_combo, combo.keys)) || (!combo.is_unordered && _compare_arrays_sorted(keys_or_combo, combo.keys))) {
695
+ return unregister_combo(combo);
696
+ }
697
+ }
698
+ };
699
+
700
+ Listener.prototype.unregister_many = function(combo_array) {
701
+ var combo, _i, _len, _results;
702
+ _results = [];
703
+ for (_i = 0, _len = combo_array.length; _i < _len; _i++) {
704
+ combo = combo_array[_i];
705
+ _results.push(this.unregister_combo(combo));
706
+ }
707
+ return _results;
708
+ };
709
+
710
+ Listener.prototype.get_registered_combos = function() {
711
+ return this._registered_combos;
712
+ };
713
+
714
+ Listener.prototype.reset = function() {
715
+ return this._registered_combos = [];
716
+ };
717
+
718
+ Listener.prototype.listen = function() {
719
+ return this._prevent_capture = false;
720
+ };
721
+
722
+ Listener.prototype.stop_listening = function() {
723
+ return this._prevent_capture = true;
724
+ };
725
+
726
+ Listener.prototype.get_meta_key = function() {
727
+ return _metakey;
728
+ };
729
+
730
+ return Listener;
731
+
732
+ })();
733
+
734
+ _decide_meta_key = function() {
735
+ if (navigator.userAgent.indexOf("Mac OS X") !== -1) {
736
+ _metakey = "cmd";
737
+ }
738
+ };
739
+
740
+ _change_keycodes_by_browser = function() {
741
+ if (navigator.userAgent.indexOf("Opera") !== -1) {
742
+ _keycode_dictionary["17"] = "cmd";
743
+ }
744
+ };
745
+
746
+ _convert_key_to_readable = function(k) {
747
+ return _keycode_dictionary[k];
748
+ };
749
+
750
+ _filter_array = function(array, callback) {
751
+ var element;
752
+ if (array.filter) {
753
+ return array.filter(callback);
754
+ } else {
755
+ return (function() {
756
+ var _i, _len, _results;
757
+ _results = [];
758
+ for (_i = 0, _len = array.length; _i < _len; _i++) {
759
+ element = array[_i];
760
+ if (callback(element)) {
761
+ _results.push(element);
762
+ }
763
+ }
764
+ return _results;
765
+ })();
766
+ }
767
+ };
768
+
769
+ _compare_arrays = function(a1, a2) {
770
+ var item, _i, _len;
771
+ if (a1.length !== a2.length) {
772
+ return false;
773
+ }
774
+ for (_i = 0, _len = a1.length; _i < _len; _i++) {
775
+ item = a1[_i];
776
+ if (__indexOf.call(a2, item) >= 0) {
777
+ continue;
778
+ }
779
+ return false;
780
+ }
781
+ return true;
782
+ };
783
+
784
+ _compare_arrays_sorted = function(a1, a2) {
785
+ var i, _i, _ref;
786
+ if (a1.length !== a2.length) {
787
+ return false;
788
+ }
789
+ for (i = _i = 0, _ref = a1.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
790
+ if (a1[i] !== a2[i]) {
791
+ return false;
792
+ }
793
+ }
794
+ return true;
795
+ };
796
+
797
+ _is_array_in_array = function(a1, a2) {
798
+ var item, _i, _len;
799
+ for (_i = 0, _len = a1.length; _i < _len; _i++) {
800
+ item = a1[_i];
801
+ if (__indexOf.call(a2, item) < 0) {
802
+ return false;
803
+ }
804
+ }
805
+ return true;
806
+ };
807
+
808
+ _is_array_in_array_sorted = function(a1, a2) {
809
+ var index, item, prev, _i, _len;
810
+ prev = 0;
811
+ for (_i = 0, _len = a1.length; _i < _len; _i++) {
812
+ item = a1[_i];
813
+ index = a2.indexOf(item);
814
+ if (index >= prev) {
815
+ prev = index;
816
+ } else {
817
+ return false;
818
+ }
819
+ }
820
+ return true;
821
+ };
822
+
823
+ _log_error = function() {
824
+ if (keypress.debug) {
825
+ return console.log.apply(console, arguments);
826
+ }
827
+ };
828
+
829
+ _key_is_valid = function(key) {
830
+ var valid, valid_key, _;
831
+ valid = false;
832
+ for (_ in _keycode_dictionary) {
833
+ valid_key = _keycode_dictionary[_];
834
+ if (key === valid_key) {
835
+ valid = true;
836
+ break;
837
+ }
838
+ }
839
+ if (!valid) {
840
+ for (_ in _keycode_shifted_keys) {
841
+ valid_key = _keycode_shifted_keys[_];
842
+ if (key === valid_key) {
843
+ valid = true;
844
+ break;
845
+ }
846
+ }
847
+ }
848
+ return valid;
849
+ };
850
+
851
+ _validate_combo = function(combo) {
852
+ var alt_name, i, key, mod_key, non_modifier_keys, property, validated, value, _i, _j, _k, _len, _len1, _ref, _ref1;
853
+ validated = true;
854
+ if (!combo.keys.length) {
855
+ _log_error("You're trying to bind a combo with no keys:", combo);
856
+ }
857
+ for (i = _i = 0, _ref = combo.keys.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
858
+ key = combo.keys[i];
859
+ alt_name = _keycode_alternate_names[key];
860
+ if (alt_name) {
861
+ key = combo.keys[i] = alt_name;
862
+ }
863
+ if (key === "meta") {
864
+ combo.keys.splice(i, 1, _metakey);
865
+ }
866
+ if (key === "cmd") {
867
+ _log_error("Warning: use the \"meta\" key rather than \"cmd\" for Windows compatibility");
868
+ }
869
+ }
870
+ _ref1 = combo.keys;
871
+ for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
872
+ key = _ref1[_j];
873
+ if (!_key_is_valid(key)) {
874
+ _log_error("Do not recognize the key \"" + key + "\"");
875
+ validated = false;
876
+ }
877
+ }
878
+ if (__indexOf.call(combo.keys, "meta") >= 0 || __indexOf.call(combo.keys, "cmd") >= 0) {
879
+ non_modifier_keys = combo.keys.slice();
880
+ for (_k = 0, _len1 = _modifier_keys.length; _k < _len1; _k++) {
881
+ mod_key = _modifier_keys[_k];
882
+ if ((i = non_modifier_keys.indexOf(mod_key)) > -1) {
883
+ non_modifier_keys.splice(i, 1);
884
+ }
885
+ }
886
+ if (non_modifier_keys.length > 1) {
887
+ _log_error("META and CMD key combos cannot have more than 1 non-modifier keys", combo, non_modifier_keys);
888
+ validated = false;
889
+ }
890
+ }
891
+ for (property in combo) {
892
+ value = combo[property];
893
+ if (_factory_defaults[property] === "undefined") {
894
+ _log_error("The property " + property + " is not a valid combo property. Your combo has still been registered.");
895
+ }
896
+ }
897
+ return validated;
898
+ };
899
+
900
+ _convert_to_shifted_key = function(key, e) {
901
+ var k;
902
+ if (!e.shiftKey) {
903
+ return false;
904
+ }
905
+ k = _keycode_shifted_keys[key];
906
+ if (k != null) {
907
+ return k;
908
+ }
909
+ return false;
910
+ };
911
+
912
+ _modifier_event_mapping = {
913
+ "cmd": "metaKey",
914
+ "ctrl": "ctrlKey",
915
+ "shift": "shiftKey",
916
+ "alt": "altKey"
917
+ };
918
+
919
+ _keycode_alternate_names = {
920
+ "escape": "esc",
921
+ "control": "ctrl",
922
+ "command": "cmd",
923
+ "break": "pause",
924
+ "windows": "cmd",
925
+ "option": "alt",
926
+ "caps_lock": "caps",
927
+ "apostrophe": "\'",
928
+ "semicolon": ";",
929
+ "tilde": "~",
930
+ "accent": "`",
931
+ "scroll_lock": "scroll",
932
+ "num_lock": "num"
933
+ };
934
+
935
+ _keycode_shifted_keys = {
936
+ "/": "?",
937
+ ".": ">",
938
+ ",": "<",
939
+ "\'": "\"",
940
+ ";": ":",
941
+ "[": "{",
942
+ "]": "}",
943
+ "\\": "|",
944
+ "`": "~",
945
+ "=": "+",
946
+ "-": "_",
947
+ "1": "!",
948
+ "2": "@",
949
+ "3": "#",
950
+ "4": "$",
951
+ "5": "%",
952
+ "6": "^",
953
+ "7": "&",
954
+ "8": "*",
955
+ "9": "(",
956
+ "0": ")"
957
+ };
958
+
959
+ _keycode_dictionary = {
960
+ 0: "\\",
961
+ 8: "backspace",
962
+ 9: "tab",
963
+ 12: "num",
964
+ 13: "enter",
965
+ 16: "shift",
966
+ 17: "ctrl",
967
+ 18: "alt",
968
+ 19: "pause",
969
+ 20: "caps",
970
+ 27: "esc",
971
+ 32: "space",
972
+ 33: "pageup",
973
+ 34: "pagedown",
974
+ 35: "end",
975
+ 36: "home",
976
+ 37: "left",
977
+ 38: "up",
978
+ 39: "right",
979
+ 40: "down",
980
+ 44: "print",
981
+ 45: "insert",
982
+ 46: "delete",
983
+ 48: "0",
984
+ 49: "1",
985
+ 50: "2",
986
+ 51: "3",
987
+ 52: "4",
988
+ 53: "5",
989
+ 54: "6",
990
+ 55: "7",
991
+ 56: "8",
992
+ 57: "9",
993
+ 65: "a",
994
+ 66: "b",
995
+ 67: "c",
996
+ 68: "d",
997
+ 69: "e",
998
+ 70: "f",
999
+ 71: "g",
1000
+ 72: "h",
1001
+ 73: "i",
1002
+ 74: "j",
1003
+ 75: "k",
1004
+ 76: "l",
1005
+ 77: "m",
1006
+ 78: "n",
1007
+ 79: "o",
1008
+ 80: "p",
1009
+ 81: "q",
1010
+ 82: "r",
1011
+ 83: "s",
1012
+ 84: "t",
1013
+ 85: "u",
1014
+ 86: "v",
1015
+ 87: "w",
1016
+ 88: "x",
1017
+ 89: "y",
1018
+ 90: "z",
1019
+ 91: "cmd",
1020
+ 92: "cmd",
1021
+ 93: "cmd",
1022
+ 96: "num_0",
1023
+ 97: "num_1",
1024
+ 98: "num_2",
1025
+ 99: "num_3",
1026
+ 100: "num_4",
1027
+ 101: "num_5",
1028
+ 102: "num_6",
1029
+ 103: "num_7",
1030
+ 104: "num_8",
1031
+ 105: "num_9",
1032
+ 106: "num_multiply",
1033
+ 107: "num_add",
1034
+ 108: "num_enter",
1035
+ 109: "num_subtract",
1036
+ 110: "num_decimal",
1037
+ 111: "num_divide",
1038
+ 124: "print",
1039
+ 144: "num",
1040
+ 145: "scroll",
1041
+ 186: ";",
1042
+ 187: "=",
1043
+ 188: ",",
1044
+ 189: "-",
1045
+ 190: ".",
1046
+ 191: "/",
1047
+ 192: "`",
1048
+ 219: "[",
1049
+ 220: "\\",
1050
+ 221: "]",
1051
+ 222: "\'",
1052
+ 223: "`",
1053
+ 224: "cmd",
1054
+ 225: "alt",
1055
+ 57392: "ctrl",
1056
+ 63289: "num"
1057
+ };
1058
+
1059
+ _decide_meta_key();
1060
+
1061
+ _change_keycodes_by_browser();
1062
+
1063
+ }).call(this);