mousetrap-rails 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.md +1 -1
- data/README.md +15 -4
- data/lib/generators/mousetrap/install/templates/keybindings.js.coffee +8 -2
- data/lib/mousetrap-rails/version.rb +1 -1
- data/mousetrap-rails.gemspec +5 -4
- data/spec/spec_helper.rb +2 -0
- data/vendor/assets/javascripts/mousetrap.js +193 -102
- metadata +54 -65
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 510a6cd6f40ef2ba974a305bdf77d11292a13d3c
|
4
|
+
data.tar.gz: 4e080a4551b296c562d79807d0fbe9a38ee43798
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f7779a4ade4fb6ee4ad7871bb7bbd2eac1396fcb5282bf1225d5629f9b5a0d7513544ce1178c257f4d4662f4e760ea2b6dfffbdd9a352bb61fc48cc2fc8bce7c
|
7
|
+
data.tar.gz: 988ed39f05e62f268ad3f88f47a2f5f6909951956cc6017b9a68fd5b715a43b2effed1f78fabb8308b1471aa4b0d03e8ec4c168a258279ad1f62370d0b0a9f62
|
checksums.yaml.gz.sig
ADDED
data.tar.gz.sig
CHANGED
Binary file
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
data/LICENSE.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
### Gem mousetrap-rails
|
2
2
|
|
3
|
-
Copyright (c) 2012 Nick Kugaevsky
|
3
|
+
Copyright (c) 2012—2013 Nick Kugaevsky
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
6
|
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
# Mousetrap::Rails
|
1
|
+
# Mousetrap::Rails
|
2
|
+
[![Flattr this](http://api.flattr.com/button/flattr-badge-large.png)](http://flattr.com/thing/1233054/Mousetrap-rails-gem) [![endorse](http://api.coderwall.com/kugaevsky/endorsecount.png)](http://coderwall.com/kugaevsky) [![Dependency Status](https://gemnasium.com/kugaevsky/mousetrap-rails.png)](https://gemnasium.com/kugaevsky/mousetrap-rails) [![Code Climate](https://codeclimate.com/github/kugaevsky/mousetrap-rails.png)](https://codeclimate.com/github/kugaevsky/mousetrap-rails) [![Build Status](https://travis-ci.org/kugaevsky/mousetrap-rails.png?branch=master)](https://travis-ci.org/kugaevsky/mousetrap-rails) [![Coverage Status](https://coveralls.io/repos/kugaevsky/mousetrap-rails/badge.png?branch=master)](https://coveralls.io/r/kugaevsky/mousetrap-rails)
|
2
3
|
|
3
4
|
[Mousetrap](https://github.com/ccampbell/mousetrap) is a javascript library for handling keyboard shortcuts in your web applications written by [Craig Campbell](http://craig.is/).
|
4
5
|
|
5
|
-
The `mousetrap-rails` gem integrates Mousetrap javascript library with Rails
|
6
|
+
The `mousetrap-rails` gem integrates Mousetrap javascript library with Rails asset pipeline.
|
6
7
|
|
7
8
|
|
8
9
|
## Installation
|
@@ -27,7 +28,7 @@ $ bundle install
|
|
27
28
|
$ rails generate mousetrap:install
|
28
29
|
```
|
29
30
|
|
30
|
-
It will create sample `keybindings.js.coffee` file in `app/assets/javascripts` and insert mousetrap-rails files to manifests of
|
31
|
+
It will create a sample `keybindings.js.coffee` file in `app/assets/javascripts` and insert mousetrap-rails files to manifests of asset pipeline
|
31
32
|
|
32
33
|
```coffeescript
|
33
34
|
//= require mousetrap # ---> application.js
|
@@ -55,7 +56,7 @@ You can add keyboard navigation to your links by using `data-keybinding` attribu
|
|
55
56
|
= link_to 'About', about_path, data: { keybinding: '["a", "c"]' } # Press 'a' or 'c' to navigate to about
|
56
57
|
```
|
57
58
|
|
58
|
-
You can jump to input
|
59
|
+
You can jump to an input
|
59
60
|
|
60
61
|
```haml
|
61
62
|
= text_field_tag 'Username', nil, data: { keybinding: 'u' } # Press 'u' to focus username input field
|
@@ -99,6 +100,16 @@ You can find full documentation on [Mousetrap library page](http://craig.is/kill
|
|
99
100
|
|
100
101
|
You can display key binding hints near links with `data-keybinding` attribute by pressing `Alt+Shift+h`. Now it's just experimental feature for debugging purposes only.
|
101
102
|
|
103
|
+
## TODO
|
104
|
+
|
105
|
+
- [ ] Add moustrap extensions generator
|
106
|
+
|
107
|
+
## Contributing
|
108
|
+
|
109
|
+
Please submit all pull requests against latest `*.wip` branch. If your pull request contains new features, you **must** include relevant tests.
|
110
|
+
|
111
|
+
Thanks in advance!
|
112
|
+
|
102
113
|
|
103
114
|
## Changelog
|
104
115
|
|
@@ -2,7 +2,13 @@ $ ->
|
|
2
2
|
# Hotkey binding to links with 'data-keybinding' attribute
|
3
3
|
# Navigate link when hotkey pressed
|
4
4
|
$('a[data-keybinding]').each (i, el) ->
|
5
|
-
Mousetrap.bind $(el).data('keybinding'), (e) ->
|
5
|
+
Mousetrap.bind $(el).data('keybinding'), (e) ->
|
6
|
+
if typeof(Turbolinks) == 'undefined'
|
7
|
+
# Emulate click if turbolinks defined
|
8
|
+
el.click()
|
9
|
+
else
|
10
|
+
# Use turbolinks to go to URL
|
11
|
+
Turbolinks.visit(el.href)
|
6
12
|
|
7
13
|
# Hotkey binding to inputs with 'data-keybinding' attribute
|
8
14
|
# Focus input when hotkey pressed
|
@@ -17,7 +23,7 @@ $ ->
|
|
17
23
|
# Toggle show/hide hotkey hints
|
18
24
|
window.mouseTrapRails =
|
19
25
|
showOnLoad: false # Show/hide hotkey hints by default (on page load). Mostly for debugging purposes.
|
20
|
-
toggleKeys: 'alt+shift+h' #
|
26
|
+
toggleKeys: 'alt+shift+h' # Keys combo to toggle hints visibility.
|
21
27
|
keysShown: false
|
22
28
|
toggleHints: ->
|
23
29
|
$('a[data-keybinding]').each (i, el) ->
|
data/mousetrap-rails.gemspec
CHANGED
@@ -6,8 +6,8 @@ require 'mousetrap-rails/version'
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "mousetrap-rails"
|
8
8
|
gem.version = Mousetrap::Rails::VERSION
|
9
|
-
gem.authors =
|
10
|
-
gem.email =
|
9
|
+
gem.authors = "Nick Kugaevsky"
|
10
|
+
gem.email = "nick@kugaevsky.ru"
|
11
11
|
gem.description = %q{Mousetrap is a javascript library for handling keyboard shortcuts in your web applications. This gem integrates Mousetrap with Rails asset pipeline for easy of use.}
|
12
12
|
gem.summary = %q{Integrate Mousetrap javascript library with Rails Asset Pipeline}
|
13
13
|
gem.homepage = "http://kugaevsky.github.com/mousetrap-rails"
|
@@ -20,11 +20,12 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.signing_key = '/Users/nick/.ssh/gem-private_key.pem'
|
21
21
|
gem.cert_chain = ['gem-public_cert.pem']
|
22
22
|
|
23
|
-
gem.add_development_dependency 'rails', '~> 3.2.
|
23
|
+
gem.add_development_dependency 'rails', '~> 3.2.12'
|
24
24
|
gem.add_development_dependency 'sqlite3', '~> 1.3.5'
|
25
|
-
gem.add_development_dependency 'rspec-rails', '~> 2.
|
25
|
+
gem.add_development_dependency 'rspec-rails', '~> 2.13.0'
|
26
26
|
gem.add_development_dependency 'genspec', '~> 0.2.7'
|
27
27
|
gem.add_development_dependency 'sass', '~> 3.2.1'
|
28
|
+
gem.add_development_dependency 'coveralls'
|
28
29
|
|
29
30
|
gem.licenses = ['MIT', 'Apache']
|
30
31
|
gem.post_install_message = <<MSG
|
data/spec/spec_helper.rb
CHANGED
@@ -4,6 +4,8 @@ require File.expand_path("../dummy/config/environment", __FILE__)
|
|
4
4
|
require 'rspec/rails'
|
5
5
|
require 'rspec/autorun'
|
6
6
|
require 'genspec'
|
7
|
+
require 'coveralls'
|
8
|
+
Coveralls.wear!
|
7
9
|
|
8
10
|
# Require gem generators
|
9
11
|
Dir[Rails.root.join("../../lib/generators/mousetrap/**/*_generator.rb")].each {|f| require f}
|
@@ -1,5 +1,6 @@
|
|
1
|
+
/*global define:false */
|
1
2
|
/**
|
2
|
-
* Copyright
|
3
|
+
* Copyright 2013 Craig Campbell
|
3
4
|
*
|
4
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
6
|
* you may not use this file except in compliance with the License.
|
@@ -16,7 +17,7 @@
|
|
16
17
|
* Mousetrap is a simple keyboard shortcut library for Javascript with
|
17
18
|
* no external dependencies
|
18
19
|
*
|
19
|
-
* @version 1.
|
20
|
+
* @version 1.4.1
|
20
21
|
* @url craig.is/killing/mice
|
21
22
|
*/
|
22
23
|
(function() {
|
@@ -124,7 +125,8 @@
|
|
124
125
|
'option': 'alt',
|
125
126
|
'command': 'meta',
|
126
127
|
'return': 'enter',
|
127
|
-
'escape': 'esc'
|
128
|
+
'escape': 'esc',
|
129
|
+
'mod': /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? 'meta' : 'ctrl'
|
128
130
|
},
|
129
131
|
|
130
132
|
/**
|
@@ -178,7 +180,7 @@
|
|
178
180
|
*
|
179
181
|
* @type {boolean|string}
|
180
182
|
*/
|
181
|
-
|
183
|
+
_nextExpectedAction = false;
|
182
184
|
|
183
185
|
/**
|
184
186
|
* loop through the f keys, f1 to f19 and add them to the map
|
@@ -222,7 +224,22 @@
|
|
222
224
|
|
223
225
|
// for keypress events we should return the character as is
|
224
226
|
if (e.type == 'keypress') {
|
225
|
-
|
227
|
+
var character = String.fromCharCode(e.which);
|
228
|
+
|
229
|
+
// if the shift key is not pressed then it is safe to assume
|
230
|
+
// that we want the character to be lowercase. this means if
|
231
|
+
// you accidentally have caps lock on then your key bindings
|
232
|
+
// will continue to work
|
233
|
+
//
|
234
|
+
// the only side effect that might not be desired is if you
|
235
|
+
// bind something like 'A' cause you want to trigger an
|
236
|
+
// event when capital A is pressed caps lock will no longer
|
237
|
+
// trigger the event. shift+a will though.
|
238
|
+
if (!e.shiftKey) {
|
239
|
+
character = character.toLowerCase();
|
240
|
+
}
|
241
|
+
|
242
|
+
return character;
|
226
243
|
}
|
227
244
|
|
228
245
|
// for non keypress events the special maps are needed
|
@@ -235,6 +252,10 @@
|
|
235
252
|
}
|
236
253
|
|
237
254
|
// if it is not in the special map
|
255
|
+
|
256
|
+
// with keydown and keyup events the character seems to always
|
257
|
+
// come in as an uppercase character whether you are pressing shift
|
258
|
+
// or not. we should make sure it is always lowercase for comparisons
|
238
259
|
return String.fromCharCode(e.which).toLowerCase();
|
239
260
|
}
|
240
261
|
|
@@ -255,14 +276,14 @@
|
|
255
276
|
* @param {Object} doNotReset
|
256
277
|
* @returns void
|
257
278
|
*/
|
258
|
-
function _resetSequences(doNotReset
|
279
|
+
function _resetSequences(doNotReset) {
|
259
280
|
doNotReset = doNotReset || {};
|
260
281
|
|
261
282
|
var activeSequences = false,
|
262
283
|
key;
|
263
284
|
|
264
285
|
for (key in _sequenceLevels) {
|
265
|
-
if (doNotReset[key]
|
286
|
+
if (doNotReset[key]) {
|
266
287
|
activeSequences = true;
|
267
288
|
continue;
|
268
289
|
}
|
@@ -270,7 +291,7 @@
|
|
270
291
|
}
|
271
292
|
|
272
293
|
if (!activeSequences) {
|
273
|
-
|
294
|
+
_nextExpectedAction = false;
|
274
295
|
}
|
275
296
|
}
|
276
297
|
|
@@ -281,11 +302,12 @@
|
|
281
302
|
* @param {string} character
|
282
303
|
* @param {Array} modifiers
|
283
304
|
* @param {Event|Object} e
|
284
|
-
* @param {
|
305
|
+
* @param {string=} sequenceName - name of the sequence we are looking for
|
285
306
|
* @param {string=} combination
|
307
|
+
* @param {number=} level
|
286
308
|
* @returns {Array}
|
287
309
|
*/
|
288
|
-
function _getMatches(character, modifiers, e,
|
310
|
+
function _getMatches(character, modifiers, e, sequenceName, combination, level) {
|
289
311
|
var i,
|
290
312
|
callback,
|
291
313
|
matches = [],
|
@@ -306,9 +328,9 @@
|
|
306
328
|
for (i = 0; i < _callbacks[character].length; ++i) {
|
307
329
|
callback = _callbacks[character][i];
|
308
330
|
|
309
|
-
// if
|
310
|
-
// then move onto the next match
|
311
|
-
if (callback.seq && _sequenceLevels[callback.seq] != callback.level) {
|
331
|
+
// if a sequence name is not specified, but this is a sequence at
|
332
|
+
// the wrong level then move onto the next match
|
333
|
+
if (!sequenceName && callback.seq && _sequenceLevels[callback.seq] != callback.level) {
|
312
334
|
continue;
|
313
335
|
}
|
314
336
|
|
@@ -327,9 +349,14 @@
|
|
327
349
|
// firefox will fire a keypress if meta or control is down
|
328
350
|
if ((action == 'keypress' && !e.metaKey && !e.ctrlKey) || _modifiersMatch(modifiers, callback.modifiers)) {
|
329
351
|
|
330
|
-
//
|
331
|
-
//
|
332
|
-
|
352
|
+
// when you bind a combination or sequence a second time it
|
353
|
+
// should overwrite the first one. if a sequenceName or
|
354
|
+
// combination is specified in this call it does just that
|
355
|
+
//
|
356
|
+
// @todo make deleting its own method?
|
357
|
+
var deleteCombo = !sequenceName && callback.combo == combination;
|
358
|
+
var deleteSequence = sequenceName && callback.seq == sequenceName && callback.level == level;
|
359
|
+
if (deleteCombo || deleteSequence) {
|
333
360
|
_callbacks[character].splice(i, 1);
|
334
361
|
}
|
335
362
|
|
@@ -403,16 +430,24 @@
|
|
403
430
|
* handles a character key event
|
404
431
|
*
|
405
432
|
* @param {string} character
|
433
|
+
* @param {Array} modifiers
|
406
434
|
* @param {Event} e
|
407
435
|
* @returns void
|
408
436
|
*/
|
409
|
-
function
|
410
|
-
var callbacks = _getMatches(character,
|
437
|
+
function _handleKey(character, modifiers, e) {
|
438
|
+
var callbacks = _getMatches(character, modifiers, e),
|
411
439
|
i,
|
412
440
|
doNotReset = {},
|
413
441
|
maxLevel = 0,
|
414
442
|
processedSequenceCallback = false;
|
415
443
|
|
444
|
+
// Calculate the maxLevel for sequences so we can only execute the longest callback sequence
|
445
|
+
for (i = 0; i < callbacks.length; ++i) {
|
446
|
+
if (callbacks[i].seq) {
|
447
|
+
maxLevel = Math.max(maxLevel, callbacks[i].level);
|
448
|
+
}
|
449
|
+
}
|
450
|
+
|
416
451
|
// loop through matching callbacks for this key event
|
417
452
|
for (i = 0; i < callbacks.length; ++i) {
|
418
453
|
|
@@ -422,11 +457,20 @@
|
|
422
457
|
// callback for matching g cause otherwise you can only ever
|
423
458
|
// match the first one
|
424
459
|
if (callbacks[i].seq) {
|
425
|
-
processedSequenceCallback = true;
|
426
460
|
|
427
|
-
//
|
428
|
-
//
|
429
|
-
|
461
|
+
// only fire callbacks for the maxLevel to prevent
|
462
|
+
// subsequences from also firing
|
463
|
+
//
|
464
|
+
// for example 'a option b' should not cause 'option b' to fire
|
465
|
+
// even though 'option b' is part of the other sequence
|
466
|
+
//
|
467
|
+
// any sequences that do not match here will be discarded
|
468
|
+
// below by the _resetSequences call
|
469
|
+
if (callbacks[i].level != maxLevel) {
|
470
|
+
continue;
|
471
|
+
}
|
472
|
+
|
473
|
+
processedSequenceCallback = true;
|
430
474
|
|
431
475
|
// keep a list of which sequences were matches for later
|
432
476
|
doNotReset[callbacks[i].seq] = 1;
|
@@ -436,16 +480,24 @@
|
|
436
480
|
|
437
481
|
// if there were no sequence matches but we are still here
|
438
482
|
// that means this is a regular match so we should fire that
|
439
|
-
if (!processedSequenceCallback
|
483
|
+
if (!processedSequenceCallback) {
|
440
484
|
_fireCallback(callbacks[i].callback, e, callbacks[i].combo);
|
441
485
|
}
|
442
486
|
}
|
443
487
|
|
444
|
-
// if
|
445
|
-
//
|
446
|
-
// that were not matched by this
|
447
|
-
|
448
|
-
|
488
|
+
// if the key you pressed matches the type of sequence without
|
489
|
+
// being a modifier (ie "keyup" or "keypress") then we should
|
490
|
+
// reset all sequences that were not matched by this event
|
491
|
+
//
|
492
|
+
// this is so, for example, if you have the sequence "h a t" and you
|
493
|
+
// type "h e a r t" it does not match. in this case the "e" will
|
494
|
+
// cause the sequence to reset
|
495
|
+
//
|
496
|
+
// modifier keys are ignored because you can have a sequence
|
497
|
+
// that contains modifiers such as "enter ctrl+space" and in most
|
498
|
+
// cases the modifier key will be pressed before the next key
|
499
|
+
if (e.type == _nextExpectedAction && !_isModifier(character)) {
|
500
|
+
_resetSequences(doNotReset);
|
449
501
|
}
|
450
502
|
}
|
451
503
|
|
@@ -455,7 +507,7 @@
|
|
455
507
|
* @param {Event} e
|
456
508
|
* @returns void
|
457
509
|
*/
|
458
|
-
function
|
510
|
+
function _handleKeyEvent(e) {
|
459
511
|
|
460
512
|
// normalize e.which for key events
|
461
513
|
// @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion
|
@@ -475,7 +527,7 @@
|
|
475
527
|
return;
|
476
528
|
}
|
477
529
|
|
478
|
-
|
530
|
+
Mousetrap.handleKey(character, _eventModifiers(e), e);
|
479
531
|
}
|
480
532
|
|
481
533
|
/**
|
@@ -565,90 +617,89 @@
|
|
565
617
|
// and setting the level to 0
|
566
618
|
_sequenceLevels[combo] = 0;
|
567
619
|
|
568
|
-
// if there is no action pick the best one for the first key
|
569
|
-
// in the sequence
|
570
|
-
if (!action) {
|
571
|
-
action = _pickBestAction(keys[0], []);
|
572
|
-
}
|
573
|
-
|
574
620
|
/**
|
575
621
|
* callback to increase the sequence level for this sequence and reset
|
576
622
|
* all other sequences that were active
|
577
623
|
*
|
578
|
-
* @param {
|
579
|
-
* @returns
|
624
|
+
* @param {string} nextAction
|
625
|
+
* @returns {Function}
|
580
626
|
*/
|
581
|
-
|
582
|
-
|
627
|
+
function _increaseSequence(nextAction) {
|
628
|
+
return function() {
|
629
|
+
_nextExpectedAction = nextAction;
|
583
630
|
++_sequenceLevels[combo];
|
584
631
|
_resetSequenceTimer();
|
585
|
-
}
|
586
|
-
|
587
|
-
/**
|
588
|
-
* wraps the specified callback inside of another function in order
|
589
|
-
* to reset all sequence counters as soon as this sequence is done
|
590
|
-
*
|
591
|
-
* @param {Event} e
|
592
|
-
* @returns void
|
593
|
-
*/
|
594
|
-
_callbackAndReset = function(e) {
|
595
|
-
_fireCallback(callback, e, combo);
|
596
|
-
|
597
|
-
// we should ignore the next key up if the action is key down
|
598
|
-
// or keypress. this is so if you finish a sequence and
|
599
|
-
// release the key the final key will not trigger a keyup
|
600
|
-
if (action !== 'keyup') {
|
601
|
-
_ignoreNextKeyup = _characterFromEvent(e);
|
602
|
-
}
|
632
|
+
};
|
633
|
+
}
|
603
634
|
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
635
|
+
/**
|
636
|
+
* wraps the specified callback inside of another function in order
|
637
|
+
* to reset all sequence counters as soon as this sequence is done
|
638
|
+
*
|
639
|
+
* @param {Event} e
|
640
|
+
* @returns void
|
641
|
+
*/
|
642
|
+
function _callbackAndReset(e) {
|
643
|
+
_fireCallback(callback, e, combo);
|
644
|
+
|
645
|
+
// we should ignore the next key up if the action is key down
|
646
|
+
// or keypress. this is so if you finish a sequence and
|
647
|
+
// release the key the final key will not trigger a keyup
|
648
|
+
if (action !== 'keyup') {
|
649
|
+
_ignoreNextKeyup = _characterFromEvent(e);
|
650
|
+
}
|
651
|
+
|
652
|
+
// weird race condition if a sequence ends with the key
|
653
|
+
// another sequence begins with
|
654
|
+
setTimeout(_resetSequences, 10);
|
655
|
+
}
|
609
656
|
|
610
657
|
// loop through keys one at a time and bind the appropriate callback
|
611
658
|
// function. for any key leading up to the final one it should
|
612
659
|
// increase the sequence. after the final, it should reset all sequences
|
613
|
-
|
614
|
-
|
660
|
+
//
|
661
|
+
// if an action is specified in the original bind call then that will
|
662
|
+
// be used throughout. otherwise we will pass the action that the
|
663
|
+
// next key in the sequence should match. this allows a sequence
|
664
|
+
// to mix and match keypress and keydown events depending on which
|
665
|
+
// ones are better suited to the key provided
|
666
|
+
for (var i = 0; i < keys.length; ++i) {
|
667
|
+
var isFinal = i + 1 === keys.length;
|
668
|
+
var wrappedCallback = isFinal ? _callbackAndReset : _increaseSequence(action || _getKeyInfo(keys[i + 1]).action);
|
669
|
+
_bindSingle(keys[i], wrappedCallback, action, combo, i);
|
615
670
|
}
|
616
671
|
}
|
617
672
|
|
618
673
|
/**
|
619
|
-
*
|
674
|
+
* Converts from a string key combination to an array
|
620
675
|
*
|
621
|
-
* @param
|
622
|
-
* @
|
623
|
-
* @param {string=} action
|
624
|
-
* @param {string=} sequenceName - name of sequence if part of sequence
|
625
|
-
* @param {number=} level - what part of the sequence the command is
|
626
|
-
* @returns void
|
676
|
+
* @param {string} combination like "command+shift+l"
|
677
|
+
* @return {Array}
|
627
678
|
*/
|
628
|
-
function
|
629
|
-
|
630
|
-
|
631
|
-
|
679
|
+
function _keysFromString(combination) {
|
680
|
+
if (combination === '+') {
|
681
|
+
return ['+'];
|
682
|
+
}
|
632
683
|
|
633
|
-
|
634
|
-
|
684
|
+
return combination.split('+');
|
685
|
+
}
|
635
686
|
|
636
|
-
|
637
|
-
|
687
|
+
/**
|
688
|
+
* Gets info for a specific key combination
|
689
|
+
*
|
690
|
+
* @param {string} combination key combination ("command+s" or "a" or "*")
|
691
|
+
* @param {string=} action
|
692
|
+
* @returns {Object}
|
693
|
+
*/
|
694
|
+
function _getKeyInfo(combination, action) {
|
695
|
+
var keys,
|
638
696
|
key,
|
639
|
-
|
697
|
+
i,
|
640
698
|
modifiers = [];
|
641
699
|
|
642
|
-
// if this pattern is a sequence of keys then run through this method
|
643
|
-
// to reprocess each pattern one key at a time
|
644
|
-
if (sequence.length > 1) {
|
645
|
-
_bindSequence(combination, sequence, callback, action);
|
646
|
-
return;
|
647
|
-
}
|
648
|
-
|
649
700
|
// take the keys from this pattern and figure out what the actual
|
650
701
|
// pattern is all about
|
651
|
-
keys = combination
|
702
|
+
keys = _keysFromString(combination);
|
652
703
|
|
653
704
|
for (i = 0; i < keys.length; ++i) {
|
654
705
|
key = keys[i];
|
@@ -676,14 +727,49 @@
|
|
676
727
|
// we will try to pick the best event for it
|
677
728
|
action = _pickBestAction(key, modifiers, action);
|
678
729
|
|
730
|
+
return {
|
731
|
+
key: key,
|
732
|
+
modifiers: modifiers,
|
733
|
+
action: action
|
734
|
+
};
|
735
|
+
}
|
736
|
+
|
737
|
+
/**
|
738
|
+
* binds a single keyboard combination
|
739
|
+
*
|
740
|
+
* @param {string} combination
|
741
|
+
* @param {Function} callback
|
742
|
+
* @param {string=} action
|
743
|
+
* @param {string=} sequenceName - name of sequence if part of sequence
|
744
|
+
* @param {number=} level - what part of the sequence the command is
|
745
|
+
* @returns void
|
746
|
+
*/
|
747
|
+
function _bindSingle(combination, callback, action, sequenceName, level) {
|
748
|
+
|
749
|
+
// store a direct mapped reference for use with Mousetrap.trigger
|
750
|
+
_directMap[combination + ':' + action] = callback;
|
751
|
+
|
752
|
+
// make sure multiple spaces in a row become a single space
|
753
|
+
combination = combination.replace(/\s+/g, ' ');
|
754
|
+
|
755
|
+
var sequence = combination.split(' '),
|
756
|
+
info;
|
757
|
+
|
758
|
+
// if this pattern is a sequence of keys then run through this method
|
759
|
+
// to reprocess each pattern one key at a time
|
760
|
+
if (sequence.length > 1) {
|
761
|
+
_bindSequence(combination, sequence, callback, action);
|
762
|
+
return;
|
763
|
+
}
|
764
|
+
|
765
|
+
info = _getKeyInfo(combination, action);
|
766
|
+
|
679
767
|
// make sure to initialize array if this is the first time
|
680
768
|
// a callback is added for this key
|
681
|
-
|
682
|
-
_callbacks[key] = [];
|
683
|
-
}
|
769
|
+
_callbacks[info.key] = _callbacks[info.key] || [];
|
684
770
|
|
685
771
|
// remove an existing match if there is one
|
686
|
-
_getMatches(key, modifiers, {type: action},
|
772
|
+
_getMatches(info.key, info.modifiers, {type: info.action}, sequenceName, combination, level);
|
687
773
|
|
688
774
|
// add this call back to the array
|
689
775
|
// if it is a sequence put it at the beginning
|
@@ -691,10 +777,10 @@
|
|
691
777
|
//
|
692
778
|
// this is important because the way these are processed expects
|
693
779
|
// the sequence ones to come first
|
694
|
-
_callbacks[key][sequenceName ? 'unshift' : 'push']({
|
780
|
+
_callbacks[info.key][sequenceName ? 'unshift' : 'push']({
|
695
781
|
callback: callback,
|
696
|
-
modifiers: modifiers,
|
697
|
-
action: action,
|
782
|
+
modifiers: info.modifiers,
|
783
|
+
action: info.action,
|
698
784
|
seq: sequenceName,
|
699
785
|
level: level,
|
700
786
|
combo: combination
|
@@ -716,9 +802,9 @@
|
|
716
802
|
}
|
717
803
|
|
718
804
|
// start!
|
719
|
-
_addEvent(document, 'keypress',
|
720
|
-
_addEvent(document, 'keydown',
|
721
|
-
_addEvent(document, 'keyup',
|
805
|
+
_addEvent(document, 'keypress', _handleKeyEvent);
|
806
|
+
_addEvent(document, 'keydown', _handleKeyEvent);
|
807
|
+
_addEvent(document, 'keyup', _handleKeyEvent);
|
722
808
|
|
723
809
|
var Mousetrap = {
|
724
810
|
|
@@ -772,7 +858,7 @@
|
|
772
858
|
*/
|
773
859
|
trigger: function(keys, action) {
|
774
860
|
if (_directMap[keys + ':' + action]) {
|
775
|
-
_directMap[keys + ':' + action]();
|
861
|
+
_directMap[keys + ':' + action]({}, keys);
|
776
862
|
}
|
777
863
|
return this;
|
778
864
|
},
|
@@ -797,7 +883,7 @@
|
|
797
883
|
* @param {Element} element
|
798
884
|
* @return {boolean}
|
799
885
|
*/
|
800
|
-
stopCallback: function(e, element
|
886
|
+
stopCallback: function(e, element) {
|
801
887
|
|
802
888
|
// if the element has the class "mousetrap" then no need to stop
|
803
889
|
if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {
|
@@ -806,7 +892,12 @@
|
|
806
892
|
|
807
893
|
// stop for input, select, and textarea
|
808
894
|
return element.tagName == 'INPUT' || element.tagName == 'SELECT' || element.tagName == 'TEXTAREA' || (element.contentEditable && element.contentEditable == 'true');
|
809
|
-
}
|
895
|
+
},
|
896
|
+
|
897
|
+
/**
|
898
|
+
* exposes _handleKey publicly so it can be overwritten by extensions
|
899
|
+
*/
|
900
|
+
handleKey: _handleKey
|
810
901
|
};
|
811
902
|
|
812
903
|
// expose mousetrap to the global object
|
metadata
CHANGED
@@ -1,128 +1,124 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mousetrap-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.0.9
|
4
|
+
version: 0.0.10
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Nick Kugaevsky
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain:
|
12
|
-
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
S05uSXA2Umt6NnNwNFpoMmFxVEx0OEJERUE4NmtPKzB2NExhVkxxRkVtTFR5
|
35
|
-
cGY3QzU2OFJUWWxtCk44TGFSRVFNTTVZZHZDSVlXczVDNmlOUlZhRGhUOGJr
|
36
|
-
dVdOaHRCaXMwSDdZRkFmc1cxcm45bnA4T1E3blkyYXoKOGROUXJCbEt6Yy9S
|
37
|
-
THdHR0ZUMWdqelZsSWI3L3h0TmRNZEpRNkp3eWxqU0o3MFBiS0FBemdCUmRE
|
38
|
-
TFB0OUJXdAozQUg5bXc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
39
|
-
date: 2013-02-08 00:00:00.000000000 Z
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDMDCCAhigAwIBAgIBADANBgkqhkiG9w0BAQUFADA+MQ0wCwYDVQQDDARuaWNr
|
14
|
+
MRkwFwYKCZImiZPyLGQBGRYJa3VnYWV2c2t5MRIwEAYKCZImiZPyLGQBGRYCcnUw
|
15
|
+
HhcNMTMwMTMxMTgxMjMwWhcNMTQwMTMxMTgxMjMwWjA+MQ0wCwYDVQQDDARuaWNr
|
16
|
+
MRkwFwYKCZImiZPyLGQBGRYJa3VnYWV2c2t5MRIwEAYKCZImiZPyLGQBGRYCcnUw
|
17
|
+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3SS01rsI5N3EUG3bSnfI2
|
18
|
+
pr4Exx9gKCBS5IxV7Ot+pQ2psIiWoenaS4fS2fsmvle92ClEx3NbUqnxxGDES0Eb
|
19
|
+
FkNHyAH9VwO36vS0loNv/Ox2sSaleUNV3JdvcP1Gm3xGtn9KWNcpuAwPfMl5BSYg
|
20
|
+
K4WU8zIkbLlwmrO6h85IYZrDwqghb6OCOwhb56d4byjoJE25brUxETxGVdsuVCDr
|
21
|
+
EQroS+D2BiMAEdwJcn/PepMx3lt+teZrjUoei5UXIcnZ28UYSnmXjXnkySlPXzRV
|
22
|
+
siLwUMAgGu665huUE5S8idW7ohSHTJv/kH98BoiWi7gi9HFMz4OJMMeR5rZk76Ql
|
23
|
+
AgMBAAGjOTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFCdIKkB9lZ+com0wLBhLQDWe
|
24
|
+
YnbvMAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEANOubFddpzMXJflPv
|
25
|
+
vXXnWXYvZK2etSxzwewXXOhcbzwSxdU0T4NbKcrlhlFbjUDh/xF4Qzc1dB9OFG9r
|
26
|
+
ffIUKv0JtEyGM/mOaISsNp+oYUlXxXLNOsX8LT1r+337tQ627GoX/Z0RL5u8Mz6Q
|
27
|
+
KZUJhGQKNnIp6Rkz6sp4Zh2aqTLt8BDEA86kO+0v4LaVLqFEmLTypf7C568RTYlm
|
28
|
+
N8LaREQMM5YdvCIYWs5C6iNRVaDhT8bkuWNhtBis0H7YFAfsW1rn9np8OQ7nY2az
|
29
|
+
8dNQrBlKzc/RLwGGFT1gjzVlIb7/xtNdMdJQ6JwyljSJ70PbKAAzgBRdDLPt9BWt
|
30
|
+
3AH9mw==
|
31
|
+
-----END CERTIFICATE-----
|
32
|
+
date: 2013-06-02 00:00:00.000000000 Z
|
40
33
|
dependencies:
|
41
34
|
- !ruby/object:Gem::Dependency
|
42
35
|
name: rails
|
43
36
|
requirement: !ruby/object:Gem::Requirement
|
44
|
-
none: false
|
45
37
|
requirements:
|
46
38
|
- - ~>
|
47
39
|
- !ruby/object:Gem::Version
|
48
|
-
version: 3.2.
|
40
|
+
version: 3.2.12
|
49
41
|
type: :development
|
42
|
+
prerelease: false
|
50
43
|
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
none: false
|
52
44
|
requirements:
|
53
45
|
- - ~>
|
54
46
|
- !ruby/object:Gem::Version
|
55
|
-
version: 3.2.
|
56
|
-
prerelease: false
|
47
|
+
version: 3.2.12
|
57
48
|
- !ruby/object:Gem::Dependency
|
58
49
|
name: sqlite3
|
59
50
|
requirement: !ruby/object:Gem::Requirement
|
60
|
-
none: false
|
61
51
|
requirements:
|
62
52
|
- - ~>
|
63
53
|
- !ruby/object:Gem::Version
|
64
54
|
version: 1.3.5
|
65
55
|
type: :development
|
56
|
+
prerelease: false
|
66
57
|
version_requirements: !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
58
|
requirements:
|
69
59
|
- - ~>
|
70
60
|
- !ruby/object:Gem::Version
|
71
61
|
version: 1.3.5
|
72
|
-
prerelease: false
|
73
62
|
- !ruby/object:Gem::Dependency
|
74
63
|
name: rspec-rails
|
75
64
|
requirement: !ruby/object:Gem::Requirement
|
76
|
-
none: false
|
77
65
|
requirements:
|
78
66
|
- - ~>
|
79
67
|
- !ruby/object:Gem::Version
|
80
|
-
version: 2.
|
68
|
+
version: 2.13.0
|
81
69
|
type: :development
|
70
|
+
prerelease: false
|
82
71
|
version_requirements: !ruby/object:Gem::Requirement
|
83
|
-
none: false
|
84
72
|
requirements:
|
85
73
|
- - ~>
|
86
74
|
- !ruby/object:Gem::Version
|
87
|
-
version: 2.
|
88
|
-
prerelease: false
|
75
|
+
version: 2.13.0
|
89
76
|
- !ruby/object:Gem::Dependency
|
90
77
|
name: genspec
|
91
78
|
requirement: !ruby/object:Gem::Requirement
|
92
|
-
none: false
|
93
79
|
requirements:
|
94
80
|
- - ~>
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: 0.2.7
|
97
83
|
type: :development
|
84
|
+
prerelease: false
|
98
85
|
version_requirements: !ruby/object:Gem::Requirement
|
99
|
-
none: false
|
100
86
|
requirements:
|
101
87
|
- - ~>
|
102
88
|
- !ruby/object:Gem::Version
|
103
89
|
version: 0.2.7
|
104
|
-
prerelease: false
|
105
90
|
- !ruby/object:Gem::Dependency
|
106
91
|
name: sass
|
107
92
|
requirement: !ruby/object:Gem::Requirement
|
108
|
-
none: false
|
109
93
|
requirements:
|
110
94
|
- - ~>
|
111
95
|
- !ruby/object:Gem::Version
|
112
96
|
version: 3.2.1
|
113
97
|
type: :development
|
98
|
+
prerelease: false
|
114
99
|
version_requirements: !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
100
|
requirements:
|
117
101
|
- - ~>
|
118
102
|
- !ruby/object:Gem::Version
|
119
103
|
version: 3.2.1
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: coveralls
|
106
|
+
requirement: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
type: :development
|
120
112
|
prerelease: false
|
113
|
+
version_requirements: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
121
118
|
description: Mousetrap is a javascript library for handling keyboard shortcuts in
|
122
119
|
your web applications. This gem integrates Mousetrap with Rails asset pipeline for
|
123
120
|
easy of use.
|
124
|
-
email:
|
125
|
-
- nick@kugaevsky.ru
|
121
|
+
email: nick@kugaevsky.ru
|
126
122
|
executables: []
|
127
123
|
extensions: []
|
128
124
|
extra_rdoc_files: []
|
@@ -189,35 +185,28 @@ homepage: http://kugaevsky.github.com/mousetrap-rails
|
|
189
185
|
licenses:
|
190
186
|
- MIT
|
191
187
|
- Apache
|
192
|
-
|
193
|
-
|
194
|
-
|
188
|
+
metadata: {}
|
189
|
+
post_install_message: "\n\e[33mRemember to run generator to generate sample file and
|
190
|
+
include mousetrap-rails with Rails Asset Pipeline\e[0m\n\n \e[32m$ rails generate
|
191
|
+
mousetrap:install \e[0m\n\n"
|
195
192
|
rdoc_options: []
|
196
193
|
require_paths:
|
197
194
|
- lib
|
198
195
|
required_ruby_version: !ruby/object:Gem::Requirement
|
199
|
-
none: false
|
200
196
|
requirements:
|
201
|
-
- -
|
197
|
+
- - '>='
|
202
198
|
- !ruby/object:Gem::Version
|
203
|
-
segments:
|
204
|
-
- 0
|
205
|
-
hash: 3850591978535415950
|
206
199
|
version: '0'
|
207
200
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
208
|
-
none: false
|
209
201
|
requirements:
|
210
|
-
- -
|
202
|
+
- - '>='
|
211
203
|
- !ruby/object:Gem::Version
|
212
|
-
segments:
|
213
|
-
- 0
|
214
|
-
hash: 3850591978535415950
|
215
204
|
version: '0'
|
216
205
|
requirements: []
|
217
206
|
rubyforge_project:
|
218
|
-
rubygems_version:
|
207
|
+
rubygems_version: 2.0.3
|
219
208
|
signing_key:
|
220
|
-
specification_version:
|
209
|
+
specification_version: 4
|
221
210
|
summary: Integrate Mousetrap javascript library with Rails Asset Pipeline
|
222
211
|
test_files:
|
223
212
|
- spec/dummy/.rspec
|
metadata.gz.sig
CHANGED
Binary file
|