about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorThibG <thib@sitedethib.com>2020-04-21 15:13:26 +0200
committerGitHub <noreply@github.com>2020-04-21 15:13:26 +0200
commit80182eda622e1317bffb6729259b8a81d84251a2 (patch)
treedcce603b89f6a8867f6696d86382cbf940d12d16 /app
parentff32a25ee3d5032122b8b7af31e6e51304e1e703 (diff)
Fix and refactor keyboard navigation in dropdown menus (#13528)
Fixes #13527

- Fixes caught keyboard events being needlessly propagated
- Let up/down arrows wrap around like the tab key does
- Refactor common code
Diffstat (limited to 'app')
-rw-r--r--app/javascript/mastodon/components/dropdown_menu.js29
-rw-r--r--app/javascript/mastodon/features/compose/components/privacy_dropdown.js35
2 files changed, 19 insertions, 45 deletions
diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js
index a4f262285..31c02d735 100644
--- a/app/javascript/mastodon/components/dropdown_menu.js
+++ b/app/javascript/mastodon/components/dropdown_menu.js
@@ -68,20 +68,14 @@ class DropdownMenu extends React.PureComponent {
   handleKeyDown = e => {
     const items = Array.from(this.node.getElementsByTagName('a'));
     const index = items.indexOf(document.activeElement);
-    let element;
+    let element = null;
 
     switch(e.key) {
     case 'ArrowDown':
-      element = items[index+1];
-      if (element) {
-        element.focus();
-      }
+      element = items[index+1] || items[0];
       break;
     case 'ArrowUp':
-      element = items[index-1];
-      if (element) {
-        element.focus();
-      }
+      element = items[index-1] || items[items.length-1];
       break;
     case 'Tab':
       if (e.shiftKey) {
@@ -89,28 +83,23 @@ class DropdownMenu extends React.PureComponent {
       } else {
         element = items[index+1] || items[0];
       }
-      if (element) {
-        element.focus();
-        e.preventDefault();
-        e.stopPropagation();
-      }
       break;
     case 'Home':
       element = items[0];
-      if (element) {
-        element.focus();
-      }
       break;
     case 'End':
       element = items[items.length-1];
-      if (element) {
-        element.focus();
-      }
       break;
     case 'Escape':
       this.props.onClose();
       break;
     }
+
+    if (element) {
+      element.focus();
+      e.preventDefault();
+      e.stopPropagation();
+    }
   }
 
   handleItemKeyPress = e => {
diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
index de030b7a2..57588fe96 100644
--- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
@@ -50,7 +50,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
     const index = items.findIndex(item => {
       return (item.value === value);
     });
-    let element;
+    let element = null;
 
     switch(e.key) {
     case 'Escape':
@@ -60,18 +60,10 @@ class PrivacyDropdownMenu extends React.PureComponent {
       this.handleClick(e);
       break;
     case 'ArrowDown':
-      element = this.node.childNodes[index + 1];
-      if (element) {
-        element.focus();
-        this.props.onChange(element.getAttribute('data-index'));
-      }
+      element = this.node.childNodes[index + 1] || this.node.firstChild;
       break;
     case 'ArrowUp':
-      element = this.node.childNodes[index - 1];
-      if (element) {
-        element.focus();
-        this.props.onChange(element.getAttribute('data-index'));
-      }
+      element = this.node.childNodes[index - 1] || this.node.lastChild;
       break;
     case 'Tab':
       if (e.shiftKey) {
@@ -79,28 +71,21 @@ class PrivacyDropdownMenu extends React.PureComponent {
       } else {
         element = this.node.childNodes[index + 1] || this.node.firstChild;
       }
-      if (element) {
-        element.focus();
-        this.props.onChange(element.getAttribute('data-index'));
-        e.preventDefault();
-        e.stopPropagation();
-      }
       break;
     case 'Home':
       element = this.node.firstChild;
-      if (element) {
-        element.focus();
-        this.props.onChange(element.getAttribute('data-index'));
-      }
       break;
     case 'End':
       element = this.node.lastChild;
-      if (element) {
-        element.focus();
-        this.props.onChange(element.getAttribute('data-index'));
-      }
       break;
     }
+
+    if (element) {
+      element.focus();
+      this.props.onChange(element.getAttribute('data-index'));
+      e.preventDefault();
+      e.stopPropagation();
+    }
   }
 
   handleClick = e => {