mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
parent
5e7f531c7f
commit
3a48cc8b7f
3 changed files with 60 additions and 58 deletions
|
|
@ -9,11 +9,6 @@ export const $htmlCL = $html.classList;
|
||||||
*/
|
*/
|
||||||
export const dropdownVisibility = ko.observable(false).extend({ rateLimit: 0 });
|
export const dropdownVisibility = ko.observable(false).extend({ rateLimit: 0 });
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
export const useKeyboardShortcuts = ko.observable(true);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
|
|
@ -50,18 +45,8 @@ export const keyScopeFake = ko.observable(KeyState.All);
|
||||||
|
|
||||||
export const keyScope = ko.computed({
|
export const keyScope = ko.computed({
|
||||||
read: () => keyScopeFake(),
|
read: () => keyScopeFake(),
|
||||||
write: (value) => {
|
write: value => {
|
||||||
if (KeyState.Menu !== value) {
|
if (KeyState.Menu !== value) {
|
||||||
if (KeyState.Compose === value) {
|
|
||||||
// disableKeyFilter
|
|
||||||
shortcuts.filter = () => useKeyboardShortcuts();
|
|
||||||
} else {
|
|
||||||
// restoreKeyFilter
|
|
||||||
shortcuts.filter = event => !(event.target.matches
|
|
||||||
&& (event.target.matches('input,select,textarea')
|
|
||||||
|| event.target.closest('[contenteditable]')));
|
|
||||||
}
|
|
||||||
|
|
||||||
keyScopeFake(value);
|
keyScopeFake(value);
|
||||||
if (dropdownVisibility()) {
|
if (dropdownVisibility()) {
|
||||||
value = KeyState.Menu;
|
value = KeyState.Menu;
|
||||||
|
|
@ -72,12 +57,9 @@ export const keyScope = ko.computed({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
keyScopeReal.subscribe((value) => {
|
keyScopeReal.subscribe(value => shortcuts.setScope(value));
|
||||||
// console.log('keyScope=' + sValue); // DEBUG
|
|
||||||
shortcuts.setScope(value);
|
|
||||||
});
|
|
||||||
|
|
||||||
dropdownVisibility.subscribe((value) => {
|
dropdownVisibility.subscribe(value => {
|
||||||
if (value) {
|
if (value) {
|
||||||
keyScope(KeyState.Menu);
|
keyScope(KeyState.Menu);
|
||||||
} else if (KeyState.Menu === shortcuts.getScope()) {
|
} else if (KeyState.Menu === shortcuts.getScope()) {
|
||||||
|
|
|
||||||
2
dev/prototype.js
vendored
2
dev/prototype.js
vendored
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
(w=>{
|
(w=>{
|
||||||
Array.isNotEmpty = array => Array.isArray(array) && array.length;
|
Array.isNotEmpty = array => Array.isArray(array) && array.length;
|
||||||
Array.prototype.unique((v, i, a) => a.indexOf(v) === i);
|
Array.prototype.unique = function() { return this.filter((v, i, a) => a.indexOf(v) === i); };
|
||||||
|
|
||||||
// Import momentjs locales function
|
// Import momentjs locales function
|
||||||
w.moment = {
|
w.moment = {
|
||||||
|
|
|
||||||
|
|
@ -5,61 +5,79 @@
|
||||||
const
|
const
|
||||||
doc = document,
|
doc = document,
|
||||||
meta = /Mac OS X/.test(navigator.userAgent) ? 'meta' : 'ctrl',
|
meta = /Mac OS X/.test(navigator.userAgent) ? 'meta' : 'ctrl',
|
||||||
actions = {},
|
_scopes = {},
|
||||||
toArray = v => Array.isArray(v) ? v : [v];
|
toArray = v => Array.isArray(v) ? v : [v],
|
||||||
let
|
|
||||||
_scope = 'all';
|
|
||||||
|
|
||||||
doc.addEventListener('keydown', event => {
|
fire = (actions, event) => {
|
||||||
const key = (event.key||event.code||'').toLowerCase();
|
|
||||||
if (actions[key] && win.shortcuts.filter(event)) {
|
|
||||||
let modifiers = [];
|
let modifiers = [];
|
||||||
event.altKey && modifiers.push('alt');
|
event.altKey && modifiers.push('alt');
|
||||||
event.ctrlKey && modifiers.push('ctrl');
|
event.ctrlKey && modifiers.push('ctrl');
|
||||||
event.metaKey && modifiers.push('meta');
|
event.metaKey && modifiers.push('meta');
|
||||||
event.shiftKey && modifiers.push('shift');
|
event.shiftKey && modifiers.push('shift');
|
||||||
modifiers = modifiers.join('+');
|
modifiers = modifiers.join('+');
|
||||||
if (actions[key][modifiers]) {
|
if (actions[modifiers]) {
|
||||||
// for each potential shortcut
|
// for each potential shortcut
|
||||||
actions[key][modifiers].forEach(cmd => {
|
actions[modifiers].forEach(cmd => {
|
||||||
// see if it's in the current scope
|
try {
|
||||||
if (cmd.scope.includes(_scope) || cmd.scope == 'all') {
|
// call the handler and stop the event if neccessary
|
||||||
try {
|
if (!event.defaultPrevented && cmd(event) === false) {
|
||||||
// call the handler and stop the event if neccessary
|
event.preventDefault();
|
||||||
if (cmd.method(event) === false) {
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
});
|
|
||||||
|
keydown = event => {
|
||||||
|
const key = (event.key||event.code||'').toLowerCase();
|
||||||
|
if (scope[key] && win.shortcuts.filter(event)) {
|
||||||
|
fire(scope[key], event);
|
||||||
|
}
|
||||||
|
if (!event.defaultPrevented && _scope !== 'all' && _scopes.all[key] && win.shortcuts.filter(event)) {
|
||||||
|
fire(_scopes.all[key], event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let
|
||||||
|
scope = {},
|
||||||
|
_scope = 'all';
|
||||||
|
|
||||||
|
doc.addEventListener('keydown', keydown);
|
||||||
|
|
||||||
win.shortcuts = {
|
win.shortcuts = {
|
||||||
add: (keys, modifiers, scope, method) => {
|
on: () => doc.addEventListener('keydown', keydown),
|
||||||
|
off: () => doc.removeEventListener('keydown', keydown),
|
||||||
|
add: (keys, modifiers, scopes, method) => {
|
||||||
if (method === undefined) {
|
if (method === undefined) {
|
||||||
method = scope;
|
method = scopes;
|
||||||
scope = 'all';
|
scopes = 'all';
|
||||||
}
|
}
|
||||||
toArray(keys).forEach(key => {
|
toArray(scopes).forEach(scope => {
|
||||||
key = key.toLowerCase();
|
if (!_scopes[scope]) {
|
||||||
if (!actions[key]) {
|
_scopes[scope] = {};
|
||||||
actions[key] = {};
|
|
||||||
}
|
}
|
||||||
modifiers = toArray(modifiers)
|
toArray(keys).forEach(key => {
|
||||||
.map(key => 'meta' == key ? meta : key)
|
key = key.toLowerCase();
|
||||||
.unique().sort().join('+');
|
if (!_scopes[scope][key]) {
|
||||||
if (!actions[key][modifiers]) {
|
_scopes[scope][key] = {};
|
||||||
actions[key][modifiers] = [];
|
}
|
||||||
}
|
modifiers = toArray(modifiers)
|
||||||
actions[key][modifiers].push({scope:toArray(scope), method:method});
|
.map(key => 'meta' == key ? meta : key)
|
||||||
|
.unique().sort().join('+');
|
||||||
|
if (!_scopes[scope][key][modifiers]) {
|
||||||
|
_scopes[scope][key][modifiers] = [];
|
||||||
|
}
|
||||||
|
_scopes[scope][key][modifiers].push(method);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setScope: scope => _scope = scope || 'all',
|
setScope: value => {
|
||||||
|
_scope = value || 'all';
|
||||||
|
scope = _scopes[_scope] || {};
|
||||||
|
},
|
||||||
getScope: () => _scope,
|
getScope: () => _scope,
|
||||||
getMetaKey: () => meta,
|
getMetaKey: () => meta,
|
||||||
// ignore keydown in any element that supports keyboard input
|
// ignore keydown in any element that supports keyboard input
|
||||||
|
|
@ -67,4 +85,6 @@ win.shortcuts = {
|
||||||
&& (event.target.matches('input,select,textarea') || event.target.closest('[contenteditable]')))
|
&& (event.target.matches('input,select,textarea') || event.target.closest('[contenteditable]')))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
win.shortcuts.on();
|
||||||
|
|
||||||
})(this);
|
})(this);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue