diff --git a/README.md b/README.md index b52404702..1833e7996 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

SnappyMail


- 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. to false - for(k in _MODIFIERS) assignKey[k] = false; - - const getScope = () => _scope || 'all'; - - // set the handlers globally on document - document.addEventListener('keydown', event => { - var key = event.keyCode, k, modifiersMatch, scope; - - if (!_downKeys.includes(key)) { - _downKeys.push(key); - } - - // if a modifier key, set the key. property to true and return - if(key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko - if(key in _mods) { - _mods[key] = true; - // 'assignKey' from inside this closure is exported to window.key - for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = true; - return; - } - for(k in _mods) _mods[k] = event[modifierMap[k]]; - - // see if we need to ignore the keypress (filter() can can be overridden) - // by default ignore key presses if a select, textarea, or input is focused - if(!assignKey.filter.call(this, event)) return; - - // abort if no potentially matching shortcuts found - if (!(key in _handlers)) return; - - scope = getScope(); - - // for each potential shortcut - _handlers[key].forEach(handler => { - // see if it's in the current scope - if(handler.scope == scope || handler.scope == 'all'){ - // check if modifiers match if any - modifiersMatch = handler.mods.length > 0; - for(k in _mods) - if((!_mods[k] && handler.mods.includes(+k)) || - (_mods[k] && !handler.mods.includes(+k))) modifiersMatch = false; - // call the handler and stop the event if neccessary - if((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch){ - if(handler.method(event, handler)===false){ - event.preventDefault(); - event.stopPropagation(); - } - } - } - }); - }); - - // unset modifier keys on keyup - document.addEventListener('keyup', event => { - var key = event.keyCode, k, - i = _downKeys.indexOf(key); - - // remove key from _downKeys - if (i >= 0) { - _downKeys.splice(i, 1); - } - - if(key == 93 || key == 224) key = 91; - if(key in _mods) { - _mods[key] = false; - for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = false; - } - }); - - // reset modifiers to false whenever the window is (re)focused. - addEventListener('focus', () => { - for(let k in _mods) _mods[k] = false; - for(let k in _MODIFIERS) assignKey[k] = false; - }); - - // set window.key and window.key.set/get, and the default filter - global.key = assignKey; - global.key.setScope = scope => { _scope = scope || 'all' }; - global.key.getScope = getScope; - global.key.filter = event => { - var tagName = event.target.tagName; - // ignore keypressed in any elements that support keyboard data input - return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA'); - }; - -})(this); diff --git a/vendors/keymaster/package.json b/vendors/keymaster/package.json deleted file mode 100644 index 68b4c7469..000000000 --- a/vendors/keymaster/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "keymaster", - "description": "library for defining and dispatching keyboard shortcuts", - "version": "1.6.2", - "author": "Thomas Fuchs (http://mir.aculo.us)", - "repository": { - "type": "git", - "url": "https://github.com/madrobby/keymaster" - }, - "main": "./keymaster.js" -}