diff --git a/README.md b/README.md index b52404702..1833e7996 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
- Simple, modern & fast web-based email client. + Simple, modern, lightweight & fast web-based email client.
The drastically upgraded & secured fork of RainLoop Webmail Community edition.
@@ -85,6 +85,7 @@ Things might work in Edge 18, Firefox 50-62 and Chrome 54-68 due to one polyfill
* Replaced knockout-sortable with native HTML5 drag&drop
* Replaced simplestatemanager with @media
* Replaced inputosaurus to native
+* Replaced keymaster with own shortcuts handler
* Removed pikaday
* Removed underscore
* Removed polyfills
@@ -102,22 +103,22 @@ Things might work in Edge 18, Firefox 50-62 and Chrome 54-68 due to one polyfill
|js/* |1.14.0 |native |
|----------- |--------: |--------: |
-|admin.js |2.130.942 | 850.202 |
-|app.js |4.184.455 |2.488.837 |
+|admin.js |2.130.942 | 844.753 |
+|app.js |4.184.455 |2.487.401 |
|boot.js | 671.522 | 5.285 |
-|libs.js | 647.614 | 250.948 |
+|libs.js | 647.614 | 246.085 |
|polyfills.js | 325.834 | 0 |
-|TOTAL |7.960.367 |3.595.272 |
+|TOTAL |7.960.367 |3.583.524 |
|js/min/* |1.14.0 |native |gzip 1.14 |gzip |brotli |
|--------------- |--------: |--------: |--------: |--------: |--------: |
-|admin.min.js | 252.147 | 116.626 | 73.657 | 33.343 | 28.869 |
-|app.min.js | 511.202 | 339.176 |140.462 | 89.271 | 72.393 |
+|admin.min.js | 252.147 | 116.068 | 73.657 | 33.279 | 28.711 |
+|app.min.js | 511.202 | 339.263 |140.462 | 89.051 | 72.194 |
|boot.min.js | 66.007 | 2.935 | 22.567 | 1.510 | 1.285 |
-|libs.min.js | 572.545 | 148.303 |176.720 | 52.206 | 46.472 |
+|libs.min.js | 572.545 | 147.019 |176.720 | 51.583 | 45.825 |
|polyfills.min.js | 32.452 | 0 | 11.312 | 0 | 0 |
-|TOTAL |1.434.353 | 607.040 |424.718 |176.330 |149.019 |
-|TOTAL (no admin) |1.182.206 | 490.414 |351.061 |142.987 |120.150 |
+|TOTAL |1.434.353 | 605.285 |424.718 |175.423 |148.015 |
+|TOTAL (no admin) |1.182.206 | 489.217 |351.061 |142.144 |119.304 |
For a user its around 58% smaller and faster than traditional RainLoop.
@@ -144,8 +145,8 @@ For a user its around 58% smaller and faster than traditional RainLoop.
|css/* |1.14.0 |native |gzip 1.14 |gzip |brotli |
|-------------- |-------: |-------: |------: |------: |------: |
-|app.css | 340.334 | 190.855 | 46,959 | 29.156 | 24.561 |
-|app.min.css | 274.791 | 157.619 | 39.618 | 26.336 | 22.667 |
+|app.css | 340.334 | 190.086 | 46,959 | 29.415 | 24.717 |
+|app.min.css | 274.791 | 156.076 | 39.618 | 26.034 | 22.418 |
|boot.css | | 2.534 | | 837 | 668 |
|boot.min.css | | 2.055 | | 732 | 560 |
diff --git a/dev/App/Abstract.js b/dev/App/Abstract.js
index 9918a6106..6877e64e3 100644
--- a/dev/App/Abstract.js
+++ b/dev/App/Abstract.js
@@ -42,7 +42,7 @@ class AbstractApp {
$doc.addEventListener('keypress', fn);
$doc.addEventListener('click', fn);
- shortcuts.add(['escape','enter'], '', KeyState.All, () => rl.Dropdowns.detectVisibility());
+ shortcuts.add('escape,enter', '', KeyState.All, () => rl.Dropdowns.detectVisibility());
}
remote() {
diff --git a/dev/Common/Selector.js b/dev/Common/Selector.js
index e8d12f93c..8a684f81c 100644
--- a/dev/Common/Selector.js
+++ b/dev/Common/Selector.js
@@ -286,11 +286,11 @@ class Selector {
shortcuts.add('arrowup', 'meta', keyScope, () => false);
shortcuts.add('arrowdown', 'meta', keyScope, () => false);
- shortcuts.add(['arrowup','arrowdown'], 'shift', keyScope, event => {
+ shortcuts.add('arrowup,arrowdown', 'shift', keyScope, event => {
this.newSelectPosition(event.key, true);
return false;
});
- shortcuts.add(['arrowup','arrowdown','home','end','pageup','pagedown','insert','space'], '', keyScope, event => {
+ shortcuts.add('arrowup,arrowdown,home,end,pageup,pagedown,insert,space', '', keyScope, event => {
this.newSelectPosition(event.key, false);
return false;
});
diff --git a/dev/View/Admin/Settings/Menu.js b/dev/View/Admin/Settings/Menu.js
index ca8bdb2e1..5eb1c838f 100644
--- a/dev/View/Admin/Settings/Menu.js
+++ b/dev/View/Admin/Settings/Menu.js
@@ -26,7 +26,7 @@ class MenuSettingsAdminView extends AbstractViewNext {
}
onBuild(dom) {
- shortcuts.add(['arrowup','arrowdown'], '', KeyState.Settings,
+ shortcuts.add('arrowup,arrowdown', '', KeyState.Settings,
settingsMenuKeysHandler(dom.querySelectorAll('.b-admin-menu .e-item')));
}
}
diff --git a/dev/View/Popup/Ask.js b/dev/View/Popup/Ask.js
index 786f9c6c8..911929cf9 100644
--- a/dev/View/Popup/Ask.js
+++ b/dev/View/Popup/Ask.js
@@ -87,7 +87,7 @@ class AskPopupView extends AbstractViewNext {
onBuild() {
// shortcuts.add('tab', 'shift', KeyState.PopupAsk, () => {
- shortcuts.add(['tab','arrowright','arrowleft'], '', KeyState.PopupAsk, () => {
+ shortcuts.add('tab,arrowright,arrowleft', '', KeyState.PopupAsk, () => {
let btn = this.querySelector('.buttonYes');
if (btn.matches(':focus')) {
btn = this.querySelector('.buttonNo');
diff --git a/dev/View/Popup/ComposeOpenPgp.js b/dev/View/Popup/ComposeOpenPgp.js
index 125f41ce6..26168b2e2 100644
--- a/dev/View/Popup/ComposeOpenPgp.js
+++ b/dev/View/Popup/ComposeOpenPgp.js
@@ -303,7 +303,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
}
onBuild() {
-// shortcuts.add(('tab', 'shift', KeyState.PopupComposeOpenPGP, () => {
+// shortcuts.add('tab', 'shift', KeyState.PopupComposeOpenPGP, () => {
shortcuts.add('tab', '', KeyState.PopupComposeOpenPGP, () => {
let btn = this.querySelector('.inputPassword');
if (btn.matches(':focus')) {
diff --git a/dev/View/Popup/Contacts.js b/dev/View/Popup/Contacts.js
index 8cbd898e4..1850b2e19 100644
--- a/dev/View/Popup/Contacts.js
+++ b/dev/View/Popup/Contacts.js
@@ -611,7 +611,7 @@ class ContactsPopupView extends AbstractViewNext {
return false;
});
- shortcuts.add(['c','w'], '', KeyState.ContactList, () => {
+ shortcuts.add('c,w', '', KeyState.ContactList, () => {
this.newMessageCommand();
return false;
});
diff --git a/dev/View/Popup/KeyboardShortcutsHelp.js b/dev/View/Popup/KeyboardShortcutsHelp.js
index 1e234b93a..be327e1b3 100644
--- a/dev/View/Popup/KeyboardShortcutsHelp.js
+++ b/dev/View/Popup/KeyboardShortcutsHelp.js
@@ -17,7 +17,7 @@ class KeyboardShortcutsHelpPopupView extends AbstractViewNext {
dom.querySelectorAll('a[data-toggle="tab"]').forEach(node => node.Tab || new BSN.Tab(node));
// shortcuts.add('tab', 'shift',
- shortcuts.add(['tab','arrowleft','arrowright'], '',
+ shortcuts.add('tab,arrowleft,arrowright', '',
KeyState.PopupKeyboardShortcutsHelp,
((event, handler)=>{
if (event && handler) {
diff --git a/dev/View/Popup/MessageOpenPgp.js b/dev/View/Popup/MessageOpenPgp.js
index 62a7dab5f..eb6e4b09c 100644
--- a/dev/View/Popup/MessageOpenPgp.js
+++ b/dev/View/Popup/MessageOpenPgp.js
@@ -79,7 +79,7 @@ class MessageOpenPgpPopupView extends AbstractViewNext {
}
onBuild(oDom) {
-// shortcuts.add('tab','shift', KeyState.PopupMessageOpenPGP, () => {
+// shortcuts.add('tab', 'shift', KeyState.PopupMessageOpenPGP, () => {
shortcuts.add('tab', '', KeyState.PopupMessageOpenPGP, () => {
let btn = this.querySelector('.inputPassword');
if (btn.matches(':focus')) {
diff --git a/dev/View/User/MailBox/FolderList.js b/dev/View/User/MailBox/FolderList.js
index 9b655c973..145b6e2f8 100644
--- a/dev/View/User/MailBox/FolderList.js
+++ b/dev/View/User/MailBox/FolderList.js
@@ -121,7 +121,7 @@ class FolderListMailBoxUserView extends AbstractViewNext {
el && fSelectFolder(el, event, false);
});
- shortcuts.add(['arrowup','arrowdown'], '', KeyState.FolderList, event => {
+ shortcuts.add('arrowup,arrowdown', '', KeyState.FolderList, event => {
let items = [], index = 0;
dom.querySelectorAll('.b-folders .e-item .e-link:not(.hidden)').forEach(node => {
if (node.offsetHeight || node.getClientRects().length) {
@@ -168,7 +168,7 @@ class FolderListMailBoxUserView extends AbstractViewNext {
});
// shortcuts.add('tab', 'shift', KeyState.FolderList, () => {
- shortcuts.add(['escape','tab','arrowright'], '', KeyState.FolderList, () => {
+ shortcuts.add('escape,tab,arrowright', '', KeyState.FolderList, () => {
AppStore.focusedState(Focused.MessageList);
moveAction(false);
return false;
diff --git a/dev/View/User/MailBox/MessageList.js b/dev/View/User/MailBox/MessageList.js
index 068c265f7..8cec129c3 100644
--- a/dev/View/User/MailBox/MessageList.js
+++ b/dev/View/User/MailBox/MessageList.js
@@ -786,7 +786,7 @@ class MessageListMailBoxUserView extends AbstractViewNext {
if (Settings.capa(Capa.Composer)) {
// write/compose (open compose popup)
- shortcuts.add(['w','c'], '', [KeyState.MessageList, KeyState.MessageView], () => {
+ shortcuts.add('w,c', '', [KeyState.MessageList, KeyState.MessageView], () => {
showScreenPopup(require('View/Popup/Compose'));
return false;
});
@@ -877,7 +877,7 @@ class MessageListMailBoxUserView extends AbstractViewNext {
AppStore.focusedState(Focused.FolderList);
return false;
});
- shortcuts.add(['tab','arrowright'], '', KeyState.MessageList, () => {
+ shortcuts.add('tab,arrowright', '', KeyState.MessageList, () => {
this.message() && AppStore.focusedState(Focused.MessageView);
return false;
});
diff --git a/dev/View/User/MailBox/MessageView.js b/dev/View/User/MailBox/MessageView.js
index c12374a28..352232826 100644
--- a/dev/View/User/MailBox/MessageView.js
+++ b/dev/View/User/MailBox/MessageView.js
@@ -547,7 +547,7 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
initShortcuts() {
// exit fullscreen, back
- shortcuts.add(['escape','backspace'], '', KeyState.MessageView, this.escShortcuts.bind(this));
+ shortcuts.add('escape,backspace', '', KeyState.MessageView, this.escShortcuts.bind(this));
// fullscreen
shortcuts.add('enter', '', KeyState.MessageView, () => {
@@ -602,12 +602,12 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
return true;
});
- shortcuts.add(['arrowup','arrowleft'], 'meta', [KeyState.MessageList, KeyState.MessageView], () => {
+ shortcuts.add('arrowup,arrowleft', 'meta', [KeyState.MessageList, KeyState.MessageView], () => {
this.goUpCommand();
return false;
});
- shortcuts.add(['arrowdown','arrowright'], 'meta', [KeyState.MessageList, KeyState.MessageView], () => {
+ shortcuts.add('arrowdown,arrowright', 'meta', [KeyState.MessageList, KeyState.MessageView], () => {
this.goDownCommand();
return false;
});
diff --git a/dev/View/User/Settings/Menu.js b/dev/View/User/Settings/Menu.js
index 72dfd767b..299b65186 100644
--- a/dev/View/User/Settings/Menu.js
+++ b/dev/View/User/Settings/Menu.js
@@ -32,7 +32,7 @@ class MenuSettingsUserView extends AbstractViewNext {
);
}
- shortcuts.add(['ArrowUp','ArrowDown'], '', KeyState.Settings,
+ shortcuts.add('arrowup,arrowdown', '', KeyState.Settings,
settingsMenuKeysHandler(dom.querySelectorAll('.b-settings-menu .e-item')));
}
diff --git a/dev/shortcuts.js b/dev/shortcuts.js
index 54f46410d..59e56d850 100644
--- a/dev/shortcuts.js
+++ b/dev/shortcuts.js
@@ -6,7 +6,7 @@ const
doc = document,
meta = /Mac OS X/.test(navigator.userAgent) ? 'meta' : 'ctrl',
_scopes = {},
- toArray = v => Array.isArray(v) ? v : [v],
+ toArray = v => Array.isArray(v) ? v : v.split(/\s*,\s*/),
fire = (actions, event) => {
let modifiers = [];
@@ -20,7 +20,7 @@ const
actions[modifiers].forEach(cmd => {
try {
// call the handler and stop the event if neccessary
- if (!event.defaultPrevented && cmd(event) === false) {
+ if (!event.defaultPrevented && cmd(event) === false) {
event.preventDefault();
event.stopPropagation();
}
diff --git a/vendors/keymaster/.code-changed b/vendors/keymaster/.code-changed
deleted file mode 100644
index e69de29bb..000000000
diff --git a/vendors/keymaster/MIT-LICENSE b/vendors/keymaster/MIT-LICENSE
deleted file mode 100644
index c60af2808..000000000
--- a/vendors/keymaster/MIT-LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2011-2013 Thomas Fuchs
-
-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:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendors/keymaster/README.markdown b/vendors/keymaster/README.markdown
deleted file mode 100644
index b2586247f..000000000
--- a/vendors/keymaster/README.markdown
+++ /dev/null
@@ -1,212 +0,0 @@
-# keymaster.js
-
-Keymaster is a simple micro-library for defining and
-dispatching keyboard shortcuts in web applications.
-
-It has no dependencies.
-
-*It’s a work in progress (e.g. beta), so spare me your nerdrage and instead
-contribute! Patches are welcome, but they are not guaranteed to make
-it in.*
-
-## Usage
-
-Include `keymaster.js` in your web app*, by loading it as usual:
-
-```html
-
-```
-
-Keymaster has no dependencies and can be used completely standalone.
-It should not interfere with any JavaScript libraries or frameworks.
-
-_*Preferably use a minified version that fits your workflow. You can
-run `make` to have UglifyJS (if you have it installed) create a
-`keymaster.min.js` file for you._
-
-## Defining shortcuts
-
-One global method is exposed, `key` which defines shortcuts when
-called directly.
-
-```javascript
-// define short of 'a'
-key('a', function(){ alert('you pressed a!') });
-
-// returning false stops the event and prevents default browser events
-key('ctrl+r', function(){ alert('stopped reload!'); return false });
-
-// multiple shortcuts that do the same thing
-key('⌘+r, ctrl+r', function(){ });
-```
-
-The handler method is called with two arguments set, the keydown `event` fired, and
-an object containing, among others, the following two properties:
-
-`shortcut`: a string that contains the shortcut used, e.g. `ctrl+r`
-`scope`: a string describing the scope (or `all`)
-
-```javascript
-key('⌘+r, ctrl+r', function(event, handler){
- console.log(handler.shortcut, handler.scope);
-});
-
-// "ctrl+r", "all"
-```
-
-
-## Supported keys
-
-Keymaster understands the following modifiers:
-`⇧`, `shift`, `option`, `⌥`, `alt`, `ctrl`, `control`, `command`, and `⌘`.
-
-The following special keys can be used for shortcuts:
-`backspace`, `tab`, `clear`, `enter`, `return`, `esc`, `escape`, `space`,
-`up`, `down`, `left`, `right`, `home`, `end`, `pageup`, `pagedown`, `del`, `delete`
-and `f1` through `f19`.
-
-
-## Modifier key queries
-
-At any point in time (even in code other than key shortcut handlers),
-you can query the `key` object for the state of any keys. This
-allows easy implementation of things like shift+click handlers. For example,
-`key.shift` is `true` if the shift key is currently pressed.
-
-```javascript
-if(key.shift) alert('shift is pressed, OMGZ!');
-```
-
-
-## Other key queries
-
-At any point in time (even in code other than key shortcut handlers),
-you can query the `key` object for the state of any key. This
-is very helpful for game development using a game loop. For example,
-`key.isPressed(77)` is `true` if the M key is currently pressed.
-
-```javascript
-if(key.isPressed("M")) alert('M key is pressed, can ya believe it!?');
-if(key.isPressed(77)) alert('M key is pressed, can ya believe it!?');
-```
-
-You can also get these as an array using...
-```javascript
-key.getPressedKeyCodes() // returns an array of key codes currently pressed
-```
-
-
-## Scopes
-
-If you want to reuse the same shortcut for separate areas in your single page app,
-Keymaster supports switching between scopes. Use the `key.setScope` method to set scope.
-
-```javascript
-// define shortcuts with a scope
-key('o, enter', 'issues', function(){ /* do something */ });
-key('o, enter', 'files', function(){ /* do something else */ });
-
-// set the scope (only 'all' and 'issues' shortcuts will be honored)
-key.setScope('issues'); // default scope is 'all'
-```
-
-
-## Filter key presses
-
-By default, when an `INPUT`, `SELECT` or `TEXTAREA` element is focused, Keymaster doesn't process any shortcuts.
-
-You can change this by overwriting `key.filter` with a new function. This function is called before
-Keymaster processes shortcuts, with the keydown event as argument.
-
-If your function returns false, then the no shortcuts will be processed.
-
-Here's the default implementation for reference:
-
-```javascript
-function filter(event){
- var tagName = (event.target || event.srcElement).tagName;
- return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');
-}
-```
-
-If you only want _some_ shortcuts to work while in an input element, you can change the scope in the
-`key.filter` function. Here's an example implementation, setting the scope to either `'input'` or `'other'`.
-Don't forget to return `true` so the any shortcuts get processed.
-
-```javascript
-key.filter = function(event){
- var tagName = (event.target || event.srcElement).tagName;
- key.setScope(/^(INPUT|TEXTAREA|SELECT)$/.test(tagName) ? 'input' : 'other');
- return true;
-}
-```
-
-However a more robust way to handle this is to use proper
-focus and blur event handlers on your input element, and change scopes there as you see fit.
-
-
-## noConflict mode
-
-You can call ```key.noConflict``` to remove the ```key``` function from global scope and restore whatever ```key``` was defined to before Keymaster was loaded. Calling ```key.noConflict``` will return the Keymaster ```key``` function.
-
-```javascript
-var k = key.noConflict();
-k('a', function() { /* ... */ });
-
-key()
-// --> TypeError: 'undefined' is not a function
-```
-
-
-## Unbinding shortcuts
-
-Similar to defining shortcuts, they can be unbound using `key.unbind`.
-
-```javascript
-// unbind 'a' handler
-key.unbind('a');
-
-// unbind a key only for a single scope
-// when no scope is specified it defaults to the current scope (key.getScope())
-key.unbind('o, enter', 'issues');
-key.unbind('o, enter', 'files');
-```
-
-
-## Notes
-
-Keymaster should work with any browser that fires `keyup` and `keydown` events,
-and is tested with IE (6+), Safari, Firefox and Chrome.
-
-See [http://madrobby.github.com/keymaster/](http://madrobby.github.com/keymaster/) for a live demo.
-
-
-## CoffeeScript
-
-If you're using CoffeeScript, configuring key shortcuts couldn't be simpler:
-
-```coffeescript
-key 'a', -> alert('you pressed a!')
-
-key '⌘+r, ctrl+r', ->
- alert 'stopped reload!'
- off
-
-key 'o, enter', 'issues', ->
- whatevs()
-
-alert 'shift is pressed, OMGZ!' if key.shift
-```
-
-
-## Contributing
-
-To contribute, please fork Keymaster, add your patch and tests for it (in the `test/` folder) and
-submit a pull request.
-
-## TODOs
-
-* Finish test suite
-
-Keymaster is (c) 2011-2013 Thomas Fuchs and may be freely distributed under the MIT license.
-See the `MIT-LICENSE` file.
diff --git a/vendors/keymaster/keymaster.js b/vendors/keymaster/keymaster.js
deleted file mode 100644
index 836376a38..000000000
--- a/vendors/keymaster/keymaster.js
+++ /dev/null
@@ -1,167 +0,0 @@
-// keymaster.js
-// (c) 2011-2013 Thomas Fuchs
-// keymaster.js may be freely distributed under the MIT license.
-
-(global=>{
- var k,
- _handlers = {},
- _mods = { 16: false, 18: false, 17: false, 91: false },
- _scope = 'all',
- // modifier keys
- _MODIFIERS = {
- '⇧': 16, shift: 16,
- '⌥': 18, alt: 18, option: 18,
- '⌃': 17, ctrl: 17, control: 17,
- '⌘': 91, command: 91
- },
- // special keys
- _MAP = {
- backspace: 8, tab: 9, clear: 12,
- enter: 13, 'return': 13,
- esc: 27, escape: 27, space: 32,
- left: 37, up: 38,
- right: 39, down: 40,
- insert: 45,
- del: 46, 'delete': 46,
- home: 36, end: 35,
- pageup: 33, pagedown: 34,
- ',': 188, '.': 190, '/': 191,
- '`': 192, '-': 189, '=': 187,
- ';': 186, '\'': 222,
- '[': 219, ']': 221, '\\': 220
- },
- code = x => _MAP[x] || x.toUpperCase().charCodeAt(0),
- _downKeys = [];
-
- for(k=1;k<20;k++) _MAP['f'+k] = 111+k;
-
- var modifierMap = {
- 16:'shiftKey',
- 18:'altKey',
- 17:'ctrlKey',
- 91:'metaKey'
- };
-
- // parse and assign shortcut
- function assignKey(key, scope, method){
- key = key.replace(/\s/g, '');
- var keys = key.split(','), mods;
- if ((keys[keys.length - 1]) == '') {
- keys[keys.length - 2] += ',';
- }
- if (method === undefined) {
- method = scope;
- scope = 'all';
- }
-
- // for each shortcut
- for (var i = 0; i < keys.length; i++) {
- // set modifier keys if any
- mods = [];
- key = keys[i].split('+');
- if (key.length > 1){
- mods = key.slice(0, key.length - 1);
- mods.forEach((mod, mi) => mods[mi] = _MODIFIERS[mod]);
- key = [key[key.length-1]];
- }
- // convert to keycode and...
- key = code(key[0]);
- // ...store handler
- if (!(key in _handlers)) _handlers[key] = [];
-
- if (typeof scope !== 'string' && scope.length && typeof scope[0] === 'string') {
- scope.forEach(item => {
- _handlers[key].push({ shortcut: keys[i], scope: item, method: method, key: keys[i], mods: mods });
- });
- } else {
- _handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods });
- }
- }
- }
-
- // initialize key.