about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2020-10-30 13:34:30 -0700
committerMichael Howell <michael@notriddle.com>2020-10-30 13:34:30 -0700
commitac3a434ed947058635fbe1f09b1da8bd6f1ea242 (patch)
treee3825cbfbf9c4b85d5757ce7b26d67ed714607d5
parent300362e0e4e30439bd2f55f3dc94596ab197607e (diff)
downloadrust-ac3a434ed947058635fbe1f09b1da8bd6f1ea242.tar.gz
rust-ac3a434ed947058635fbe1f09b1da8bd6f1ea242.zip
Allow the theme picker to work with arrow keys
This is mostly motivated by docs.rs. It's really weird
when arrow keys work in the top dropdown menu, but don't work
in other dropdown menus on the same page.
-rw-r--r--src/librustdoc/html/render/mod.rs48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 0621eafd913..8d07f479b6e 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -798,17 +798,61 @@ function handleThemeButtonsBlur(e) {{
     var active = document.activeElement;
     var related = e.relatedTarget;
 
-    if (active.id !== "themePicker" &&
+    if (active.id !== "theme-picker" &&
         (!active.parentNode || active.parentNode.id !== "theme-choices") &&
         (!related ||
-         (related.id !== "themePicker" &&
+         (related.id !== "theme-picker" &&
           (!related.parentNode || related.parentNode.id !== "theme-choices")))) {{
         hideThemeButtonState();
     }}
 }}
 
+function handleThemeKeyPress(e) {{
+    if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {{ return; }}
+    if (!themePicker.parentNode.contains(e.target)) {{ return; }}
+    var active = document.activeElement;
+    switch (e.key) {{
+        case "ArrowUp":
+            e.preventDefault();
+            if (active.previousElementSibling && e.target.id !== "theme-picker") {{
+                active.previousElementSibling.focus();
+            }} else {{
+                showThemeButtonState();
+                themes.lastElementChild.focus();
+            }}
+            break;
+        case "ArrowDown":
+            e.preventDefault();
+            if (active.nextElementSibling && e.target.id !== "theme-picker") {{
+                active.nextElementSibling.focus();
+            }} else {{
+                showThemeButtonState();
+                themes.firstElementChild.focus();
+            }}
+            break;
+        case "Enter":
+        case "Return":
+        case "Space":
+            if (e.target.id === "theme-picker" && themes.style.display === "none") {{
+                e.preventDefault();
+                showThemeButtonState();
+                themes.firstElementChild.focus();
+            }}
+            break;
+        case "Home":
+            e.preventDefault();
+            themes.firstElementChild.focus();
+            break;
+        case "End":
+            e.preventDefault();
+            themes.lastElementChild.focus();
+            break;
+    }}
+}};
+
 themePicker.onclick = switchThemeButtonState;
 themePicker.onblur = handleThemeButtonsBlur;
+document.addEventListener("keydown", handleThemeKeyPress);
 {}.forEach(function(item) {{
     var but = document.createElement("button");
     but.textContent = item;