shithub: puzzles

Download patch

ref: 8445f07827eb13db005aa38b7f665f8154e3918c
parent: 52cd58043ac144eeafb92fd962662420506283c1
author: Ben Harris <bjh21@bjh21.me.uk>
date: Mon Nov 14 17:16:03 EST 2022

js: Replace :focus-within with JS-maintained .focus-within

Old browsers (like KaiOS 2.5) don't have :focus-within, but it's pretty
easy to replace the pseudo-class with a real .focus-within class
maintained by JavaScript event handlers.  This is made only marginally
fiddlier by the odd fact that "focus" and "blur" events don't bubble.

--- a/emccpre.js
+++ b/emccpre.js
@@ -525,6 +525,25 @@
             command(4);
     });
 
+    // Event handlers to fake :focus-within on browsers too old for
+    // it (like KaiOS 2.5).  Browsers without :focus-within are also
+    // too old for focusin/out events, so we have to use focus and
+    // which don't bubble but can be captured.
+    menuform.addEventListener("focus", function(event) {
+        var elem = event.target;
+        while (elem && elem !== menuform) {
+            elem.classList.add("focus-within");
+            elem = elem.parentElement;
+        }
+    }, true);
+    menuform.addEventListener("blur", function(event) {
+        var elem = event.target;
+        while (elem && !elem.contains(event.relatedTarget)) {
+            elem.classList.remove("focus-within");
+            elem = elem.parentElement;
+        }
+    }, true);
+
     // Set up the function pointers we haven't already grabbed. 
     dlg_return_sval = Module.cwrap('dlg_return_sval', 'void',
                                    ['number','string']);
--- a/html/jspage.pl
+++ b/html/jspage.pl
@@ -128,7 +128,7 @@
 }
 
 #gamemenu li > :hover:not(:disabled),
-#gamemenu li > :focus-within {
+#gamemenu li > .focus-within {
     /* When the mouse is over a menu item, highlight it */
     background: rgba(0,0,0,0.3);
 }
@@ -186,7 +186,7 @@
 }
 
 #gamemenu :hover > ul,
-#gamemenu :focus-within > ul {
+#gamemenu .focus-within > ul {
     /* Last but by no means least, the all-important line that makes
      * submenus be displayed! Any <ul> whose parent <li> is being
      * hovered over gets display:flex overriding the display:none