app.Shortcuts = class Shortcuts extends Events { constructor() { super(); this.onKeydown = this.onKeydown.bind(this); this.onKeypress = this.onKeypress.bind(this); this.isMac = $.isMac(); this.start(); } start() { $.on(document, "keydown", this.onKeydown); $.on(document, "keypress", this.onKeypress); } stop() { $.off(document, "keydown", this.onKeydown); $.off(document, "keypress", this.onKeypress); } swapArrowKeysBehavior() { return app.settings.get("arrowScroll"); } spaceScroll() { return app.settings.get("spaceScroll"); } showTip() { app.showTip("KeyNav"); return (this.showTip = null); } spaceTimeout() { return app.settings.get("spaceTimeout"); } onKeydown(event) { if (this.buggyEvent(event)) { return; } const result = (() => { if (event.ctrlKey || event.metaKey) { if (!event.altKey && !event.shiftKey) { return this.handleKeydownSuperEvent(event); } } else if (event.shiftKey) { if (!event.altKey) { return this.handleKeydownShiftEvent(event); } } else if (event.altKey) { return this.handleKeydownAltEvent(event); } else { return this.handleKeydownEvent(event); } })(); if (result === false) { event.preventDefault(); } } onKeypress(event) { if ( this.buggyEvent(event) || (event.charCode === 63 && document.activeElement.tagName === "INPUT") ) { return; } if (!event.ctrlKey && !event.metaKey) { const result = this.handleKeypressEvent(event); if (result === false) { event.preventDefault(); } } } handleKeydownEvent(event, _force) { if ( !_force && [37, 38, 39, 40].includes(event.which) && this.swapArrowKeysBehavior() ) { return this.handleKeydownAltEvent(event, true); } if ( !event.target.form && ((48 <= event.which && event.which <= 57) || (65 <= event.which && event.which <= 90)) ) { this.trigger("typing"); return; } switch (event.which) { case 8: if (!event.target.form) { return this.trigger("typing"); } break; case 13: return this.trigger("enter"); case 27: this.trigger("escape"); return false; case 32: if ( event.target.type === "search" && this.spaceScroll() && (!this.lastKeypress || this.lastKeypress < Date.now() - this.spaceTimeout() * 1000) ) { this.trigger("pageDown"); return false; } break; case 33: return this.trigger("pageUp"); case 34: return this.trigger("pageDown"); case 35: if (!event.target.form) { return this.trigger("pageBottom"); } break; case 36: if (!event.target.form) { return this.trigger("pageTop"); } break; case 37: if (!event.target.value) { return this.trigger("left"); } break; case 38: this.trigger("up"); if (typeof this.showTip === "function") { this.showTip(); } return false; case 39: if (!event.target.value) { return this.trigger("right"); } break; case 40: this.trigger("down"); if (typeof this.showTip === "function") { this.showTip(); } return false; case 191: if (!event.target.form) { this.trigger("typing"); return false; } break; } } handleKeydownSuperEvent(event) { switch (event.which) { case 13: return this.trigger("superEnter"); case 37: if (this.isMac) { this.trigger("superLeft"); return false; } break; case 38: this.trigger("pageTop"); return false; case 39: if (this.isMac) { this.trigger("superRight"); return false; } break; case 40: this.trigger("pageBottom"); return false; case 188: this.trigger("preferences"); return false; } } handleKeydownShiftEvent(event, _force) { if ( !_force && [37, 38, 39, 40].includes(event.which) && this.swapArrowKeysBehavior() ) { return this.handleKeydownEvent(event, true); } if (!event.target.form && 65 <= event.which && event.which <= 90) { this.trigger("typing"); return; } switch (event.which) { case 32: this.trigger("pageUp"); return false; case 38: if (!getSelection()?.toString()) { this.trigger("altUp"); return false; } break; case 40: if (!getSelection()?.toString()) { this.trigger("altDown"); return false; } break; } } handleKeydownAltEvent(event, _force) { if ( !_force && [37, 38, 39, 40].includes(event.which) && this.swapArrowKeysBehavior() ) { return this.handleKeydownEvent(event, true); } switch (event.which) { case 9: return this.trigger("altRight", event); case 37: if (!this.isMac) { this.trigger("superLeft"); return false; } break; case 38: this.trigger("altUp"); return false; case 39: if (!this.isMac) { this.trigger("superRight"); return false; } break; case 40: this.trigger("altDown"); return false; case 67: this.trigger("altC"); return false; case 68: this.trigger("altD"); return false; case 70: return this.trigger("altF", event); case 71: this.trigger("altG"); return false; case 79: this.trigger("altO"); return false; case 82: this.trigger("altR"); return false; case 83: this.trigger("altS"); return false; } } handleKeypressEvent(event) { if (event.which === 63 && !event.target.value) { this.trigger("help"); return false; } else { return (this.lastKeypress = Date.now()); } } buggyEvent(event) { try { event.target; event.ctrlKey; event.which; return false; } catch (error) { return true; } }};
app.Shortcuts = class Shortcuts extends Events {
constructor() {
super();
this.onKeydown = this.onKeydown.bind(this);
this.onKeypress = this.onKeypress.bind(this);
this.isMac = $.isMac();
this.start();
}
start() {
$.on(document, "keydown", this.onKeydown);
$.on(document, "keypress", this.onKeypress);
}
stop() {
$.off(document, "keydown", this.onKeydown);
$.off(document, "keypress", this.onKeypress);
}
swapArrowKeysBehavior() {
return app.settings.get("arrowScroll");
}
spaceScroll() {
return app.settings.get("spaceScroll");
}
showTip() {
app.showTip("KeyNav");
return (this.showTip = null);
}
spaceTimeout() {
return app.settings.get("spaceTimeout");
}
onKeydown(event) {
if (this.buggyEvent(event)) {
return;
}
const result = (() => {
if (event.ctrlKey || event.metaKey) {
if (!event.altKey && !event.shiftKey) {
return this.handleKeydownSuperEvent(event);
}
} else if (event.shiftKey) {
if (!event.altKey) {
return this.handleKeydownShiftEvent(event);
}
} else if (event.altKey) {
return this.handleKeydownAltEvent(event);
} else {
return this.handleKeydownEvent(event);
}
})();
if (result === false) {
event.preventDefault();
}
}
onKeypress(event) {
if (
this.buggyEvent(event) ||
(event.charCode === 63 && document.activeElement.tagName === "INPUT")
) {
return;
}
if (!event.ctrlKey && !event.metaKey) {
const result = this.handleKeypressEvent(event);
if (result === false) {
event.preventDefault();
}
}
}
handleKeydownEvent(event, _force) {
if (
!_force &&
[37, 38, 39, 40].includes(event.which) &&
this.swapArrowKeysBehavior()
) {
return this.handleKeydownAltEvent(event, true);
}
if (
!event.target.form &&
((48 <= event.which && event.which <= 57) ||
(65 <= event.which && event.which <= 90))
) {
this.trigger("typing");
return;
}
switch (event.which) {
case 8:
if (!event.target.form) {
return this.trigger("typing");
}
break;
case 13:
return this.trigger("enter");
case 27:
this.trigger("escape");
return false;
case 32:
if (
event.target.type === "search" &&
this.spaceScroll() &&
(!this.lastKeypress ||
this.lastKeypress < Date.now() - this.spaceTimeout() * 1000)
) {
this.trigger("pageDown");
return false;
}
break;
case 33:
return this.trigger("pageUp");
case 34:
return this.trigger("pageDown");
case 35:
if (!event.target.form) {
return this.trigger("pageBottom");
}
break;
case 36:
if (!event.target.form) {
return this.trigger("pageTop");
}
break;
case 37:
if (!event.target.value) {
return this.trigger("left");
}
break;
case 38:
this.trigger("up");
if (typeof this.showTip === "function") {
this.showTip();
}
return false;
case 39:
if (!event.target.value) {
return this.trigger("right");
}
break;
case 40:
this.trigger("down");
if (typeof this.showTip === "function") {
this.showTip();
}
return false;
case 191:
if (!event.target.form) {
this.trigger("typing");
return false;
}
break;
}
}
handleKeydownSuperEvent(event) {
switch (event.which) {
case 13:
return this.trigger("superEnter");
case 37:
if (this.isMac) {
this.trigger("superLeft");
return false;
}
break;
case 38:
this.trigger("pageTop");
return false;
case 39:
if (this.isMac) {
this.trigger("superRight");
return false;
}
break;
case 40:
this.trigger("pageBottom");
return false;
case 188:
this.trigger("preferences");
return false;
}
}
handleKeydownShiftEvent(event, _force) {
if (
!_force &&
[37, 38, 39, 40].includes(event.which) &&
this.swapArrowKeysBehavior()
) {
return this.handleKeydownEvent(event, true);
}
if (!event.target.form && 65 <= event.which && event.which <= 90) {
this.trigger("typing");
return;
}
switch (event.which) {
case 32:
this.trigger("pageUp");
return false;
case 38:
if (!getSelection()?.toString()) {
this.trigger("altUp");
return false;
}
break;
case 40:
if (!getSelection()?.toString()) {
this.trigger("altDown");
return false;
}
break;
}
}
handleKeydownAltEvent(event, _force) {
if (
!_force &&
[37, 38, 39, 40].includes(event.which) &&
this.swapArrowKeysBehavior()
) {
return this.handleKeydownEvent(event, true);
}
switch (event.which) {
case 9:
return this.trigger("altRight", event);
case 37:
if (!this.isMac) {
this.trigger("superLeft");
return false;
}
break;
case 38:
this.trigger("altUp");
return false;
case 39:
if (!this.isMac) {
this.trigger("superRight");
return false;
}
break;
case 40:
this.trigger("altDown");
return false;
case 67:
this.trigger("altC");
return false;
case 68:
this.trigger("altD");
return false;
case 70:
return this.trigger("altF", event);
case 71:
this.trigger("altG");
return false;
case 79:
this.trigger("altO");
return false;
case 82:
this.trigger("altR");
return false;
case 83:
this.trigger("altS");
return false;
}
}
handleKeypressEvent(event) {
if (event.which === 63 && !event.target.value) {
this.trigger("help");
return false;
} else {
return (this.lastKeypress = Date.now());
}
}
buggyEvent(event) {
try {
event.target;
event.ctrlKey;
event.which;
return false;
} catch (error) {
return true;
}
}
};