Probably resolved issue #14

Could get some better improvements
This commit is contained in:
djmaze 2020-09-26 09:34:23 +02:00
parent 5e7f531c7f
commit 3a48cc8b7f
3 changed files with 60 additions and 58 deletions

View file

@ -9,11 +9,6 @@ export const $htmlCL = $html.classList;
*/
export const dropdownVisibility = ko.observable(false).extend({ rateLimit: 0 });
/**
* @type {boolean}
*/
export const useKeyboardShortcuts = ko.observable(true);
/**
* @type {boolean}
*/
@ -50,18 +45,8 @@ export const keyScopeFake = ko.observable(KeyState.All);
export const keyScope = ko.computed({
read: () => keyScopeFake(),
write: (value) => {
write: 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);
if (dropdownVisibility()) {
value = KeyState.Menu;
@ -72,12 +57,9 @@ export const keyScope = ko.computed({
}
});
keyScopeReal.subscribe((value) => {
// console.log('keyScope=' + sValue); // DEBUG
shortcuts.setScope(value);
});
keyScopeReal.subscribe(value => shortcuts.setScope(value));
dropdownVisibility.subscribe((value) => {
dropdownVisibility.subscribe(value => {
if (value) {
keyScope(KeyState.Menu);
} else if (KeyState.Menu === shortcuts.getScope()) {

2
dev/prototype.js vendored
View file

@ -1,7 +1,7 @@
(w=>{
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
w.moment = {

View file

@ -5,61 +5,79 @@
const
doc = document,
meta = /Mac OS X/.test(navigator.userAgent) ? 'meta' : 'ctrl',
actions = {},
toArray = v => Array.isArray(v) ? v : [v];
let
_scope = 'all';
_scopes = {},
toArray = v => Array.isArray(v) ? v : [v],
doc.addEventListener('keydown', event => {
const key = (event.key||event.code||'').toLowerCase();
if (actions[key] && win.shortcuts.filter(event)) {
fire = (actions, event) => {
let modifiers = [];
event.altKey && modifiers.push('alt');
event.ctrlKey && modifiers.push('ctrl');
event.metaKey && modifiers.push('meta');
event.shiftKey && modifiers.push('shift');
modifiers = modifiers.join('+');
if (actions[key][modifiers]) {
if (actions[modifiers]) {
// for each potential shortcut
actions[key][modifiers].forEach(cmd => {
// see if it's in the current scope
if (cmd.scope.includes(_scope) || cmd.scope == 'all') {
try {
// call the handler and stop the event if neccessary
if (cmd.method(event) === false) {
event.preventDefault();
event.stopPropagation();
}
} catch (e) {
console.error(e);
actions[modifiers].forEach(cmd => {
try {
// call the handler and stop the event if neccessary
if (!event.defaultPrevented && cmd(event) === false) {
event.preventDefault();
event.stopPropagation();
}
} 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 = {
add: (keys, modifiers, scope, method) => {
on: () => doc.addEventListener('keydown', keydown),
off: () => doc.removeEventListener('keydown', keydown),
add: (keys, modifiers, scopes, method) => {
if (method === undefined) {
method = scope;
scope = 'all';
method = scopes;
scopes = 'all';
}
toArray(keys).forEach(key => {
key = key.toLowerCase();
if (!actions[key]) {
actions[key] = {};
toArray(scopes).forEach(scope => {
if (!_scopes[scope]) {
_scopes[scope] = {};
}
modifiers = toArray(modifiers)
.map(key => 'meta' == key ? meta : key)
.unique().sort().join('+');
if (!actions[key][modifiers]) {
actions[key][modifiers] = [];
}
actions[key][modifiers].push({scope:toArray(scope), method:method});
toArray(keys).forEach(key => {
key = key.toLowerCase();
if (!_scopes[scope][key]) {
_scopes[scope][key] = {};
}
modifiers = toArray(modifiers)
.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,
getMetaKey: () => meta,
// 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]')))
};
win.shortcuts.on();
})(this);