295 lines · 6.4 KB · JavaScript
RawDownload
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;    }  }};