Browse Source

Shortcut bugfix, documentation, and update.

A. Darian 9 years ago
parent
commit
23a26cca12
4 changed files with 62 additions and 18 deletions
  1. 2 0
      .gitignore
  2. 16 6
      src/filebrowser/plugin.ts
  3. 13 1
      src/help/plugin.ts
  4. 31 11
      src/shortcuts/plugin.ts

+ 2 - 0
.gitignore

@@ -7,6 +7,8 @@ test/build
 test/coverage
 lib/
 example/build
+example/untitled*
+example/Untitled*
 docs
 
 .ipynb_checkpoints

+ 16 - 6
src/filebrowser/plugin.ts

@@ -84,9 +84,8 @@ function activateFileBrowser(app: Application, manager: DocumentManager, provide
     {
       id: newTextFileId,
       handler: () => {
-        widget.newUntitled('file', '.txt').then(
-          contents => onOpenRequested(contents)
-        );
+        widget.newUntitled('file', '.txt')
+          .then(contents => onOpenRequested(contents));
       }
     }
   ]);
@@ -106,9 +105,8 @@ function activateFileBrowser(app: Application, manager: DocumentManager, provide
     {
       id: newNotebookId,
       handler: () => {
-        widget.newUntitled('notebook').then(
-          contents => onOpenRequested(contents)
-        );
+        widget.newUntitled('notebook')
+          .then(contents => onOpenRequested(contents));
       }
     }
   ]);
@@ -209,6 +207,10 @@ function activateFileBrowser(app: Application, manager: DocumentManager, provide
     {
       id: 'file-browser:hide',
       handler: hideBrowser
+    },
+    {
+      id: 'file-browser:toggle',
+      handler: toggleBrowser
     }
   ]);
 
@@ -231,6 +233,14 @@ function activateFileBrowser(app: Application, manager: DocumentManager, provide
   function hideBrowser(): void {
     if (!widget.isHidden) app.shell.collapseLeft();
   }
+
+  function toggleBrowser(): void {
+    if (widget.isHidden) {
+      showBrowser();
+    } else {
+      hideBrowser();
+    }
+  }
 }
 
 

+ 13 - 1
src/help/plugin.ts

@@ -93,7 +93,11 @@ function activateHelpHandler(app: Application): Promise<void> {
     {
       id: 'help-doc:hide',
       handler: hideHelp
-    }
+    },
+    {
+      id: 'help-doc:toggle',
+      handler: toggleHelp
+    },
   ]);
 
   let helpPaletteItems = COMMANDS.map(command => {
@@ -120,4 +124,12 @@ function activateHelpHandler(app: Application): Promise<void> {
   function hideHelp(): void {
     if (!widget.isHidden) app.shell.collapseRight();
   }
+
+  function toggleHelp(): void {
+    if (widget.isHidden) {
+      showHelp();
+    } else {
+      hideHelp();
+    }
+  }
 }

+ 31 - 11
src/shortcuts/plugin.ts

@@ -9,36 +9,56 @@ import {
 
 /**
  * The list of default application shortcuts.
+ *
+ * #### Notes
+ * When setting shortcut selectors, there are two concepts to consider:
+ * specificity and matchability. These two interact in sometimes
+ * counterintuitive ways. Keyboard events are triggered from an element and
+ * they propagate up the DOM until they reach the `documentElement` (`<body>`).
+ *
+ * When a registered shortcut sequence is fired, the shortcut manager checks
+ * the node that fired the event and each of its ancestors until a node matches
+ * one or more registered selectors. The *first* matching selector in the
+ * chain of ancestors will invoke the shortcut handler and the travelsal will
+ * end at that point. If a node matches more than one selector, the handler for
+ * whichever selector is more *specific* fires.
+ * @see https://www.w3.org/TR/css3-selectors/#specificity
+ *
+ * The practical consequence of this is that a very broadly matching selector,
+ * e.g. `'*'` or `'div'` may match and therefore invoke a handler *before* a
+ * more specific selector. The most common pitfall is to use the universal
+ * (`'*'`) selector. For almost any use case where a global keyboard shortcut is
+ * required, using the `'body'` selector is more appropriate.
  */
 const SHORTCUTS = [
   {
-    command: 'command-palette:activate',
-    selector: '*',
+    command: 'command-palette:toggle',
+    selector: 'body',
     sequence: ['Accel Shift P']
   },
   {
     command: 'command-palette:hide',
-    selector: '[data-left-area="command-palette"]',
+    selector: 'body[data-left-area="command-palette"]',
     sequence: ['Escape']
   },
   {
-    command: 'file-browser:activate',
-    selector: '*',
+    command: 'file-browser:toggle',
+    selector: 'body',
     sequence: ['Accel Shift F']
   },
   {
     command: 'file-browser:hide',
-    selector: '[data-left-area="file-browser"]',
+    selector: 'body[data-left-area="file-browser"]',
     sequence: ['Escape']
   },
   {
     command: 'file-operations:new-text-file',
-    selector: '*',
+    selector: 'body',
     sequence: ['Ctrl O']
   },
   {
     command: 'file-operations:new-notebook',
-    selector: '*',
+    selector: 'body',
     sequence: ['Ctrl Shift N']
   },
   {
@@ -62,13 +82,13 @@ const SHORTCUTS = [
     sequence: ['Shift Enter']
   },
   {
-    command: 'help-doc:activate',
-    selector: '*',
+    command: 'help-doc:toggle',
+    selector: 'body',
     sequence: ['Accel Shift H']
   },
   {
     command: 'help-doc:hide',
-    selector: '[data-right-area="help-doc"]',
+    selector: 'body[data-right-area="help-doc"]',
     sequence: ['Escape']
   }
 ];