]> BookStack Code Mirror - bookstack/blobdiff - resources/js/components/shortcuts.js
Distributed shortcut actions to common ui elements
[bookstack] / resources / js / components / shortcuts.js
index 799f0e629e8ea3927dd236ddc39f921ac2ae9a9a..7feb9bed047f4c7f7fb480c305fa0b9fcbcf703b 100644 (file)
@@ -3,8 +3,31 @@
  * @type {Object<string, string>}
  */
 const defaultMap = {
-    "edit": "e",
+    // Header actions
+    "home": "1",
+    "shelves_view": "2",
+    "books_view": "3",
+    "settings_view": "4",
+    "favorites_view": "5",
+    "profile_view": "6",
     "global_search": "/",
+    "logout": "0",
+
+    // Generic actions
+    "edit": "e",
+    "new": "n",
+    "copy": "c",
+    "delete": "d",
+    "favorite": "f",
+    "export": "x",
+    "sort": "s",
+    "permissions": "p",
+    "move": "m",
+    "revisions": "r",
+
+    // Navigation
+    "next": "ArrowRight",
+    "prev": "ArrowLeft",
 };
 
 function reverseMap(map) {
@@ -26,10 +49,10 @@ class Shortcuts {
         this.mapByShortcut = reverseMap(this.mapById);
 
         this.hintsShowing = false;
+
+        this.hideHints = this.hideHints.bind(this);
         // TODO - Allow custom key maps
         // TODO - Allow turning off shortcuts
-        // TODO - Roll out to interface elements
-        // TODO - Hide hints on focus, scroll, click
 
         this.setupListeners();
     }
@@ -53,7 +76,6 @@ class Shortcuts {
         window.addEventListener('keydown', event => {
             if (event.key === '?') {
                 this.hintsShowing ? this.hideHints() : this.showHints();
-                this.hintsShowing = !this.hintsShowing;
             }
         });
     }
@@ -81,6 +103,12 @@ class Shortcuts {
             return true;
         }
 
+        if (el.matches('div[tabindex]')) {
+            el.click();
+            el.focus();
+            return true;
+        }
+
         console.error(`Shortcut attempted to be ran for element type that does not have handling setup`, el);
 
         return false;
@@ -88,11 +116,24 @@ class Shortcuts {
 
     showHints() {
         const shortcutEls = this.container.querySelectorAll('[data-shortcut]');
+        const displayedIds = new Set();
         for (const shortcutEl of shortcutEls) {
             const id = shortcutEl.getAttribute('data-shortcut');
+            if (displayedIds.has(id)) {
+                continue;
+            }
+
             const key = this.mapById[id];
             this.showHintLabel(shortcutEl, key);
+            displayedIds.add(id);
         }
+
+        window.addEventListener('scroll', this.hideHints);
+        window.addEventListener('focus', this.hideHints);
+        window.addEventListener('blur', this.hideHints);
+        window.addEventListener('click', this.hideHints);
+
+        this.hintsShowing = true;
     }
 
     showHintLabel(targetEl, key) {
@@ -113,6 +154,13 @@ class Shortcuts {
         for (const hint of hints) {
             hint.remove();
         }
+
+        window.removeEventListener('scroll', this.hideHints);
+        window.removeEventListener('focus', this.hideHints);
+        window.removeEventListener('blur', this.hideHints);
+        window.removeEventListener('click', this.hideHints);
+
+        this.hintsShowing = false;
     }
 }