diff --git a/README.md b/README.md
index 22598bd..9e88d2f 100644
--- a/README.md
+++ b/README.md
@@ -287,32 +287,49 @@ None.
## Supported browser engines
+There are three main fully functional modes:
+
+1. Main simple offline-based JS-only mode, using modern web standards;
+2. More elaborate (almost) offline-based (almost) JS-only mode (game works offline,
+ but demo counters on the top of the page (separate from the game) only work online
+ because I don't have the motivation to redesign `ReactiveButton` and `ReactiveSpan`),
+ using modern web standards _without_ custom built-in elements
+ (which means old, but not too old Blink-based browsers like Chromium 54-66,
+ and all modern WebKit-based browsers like Safari 10.1+);
+3. Online-based (plain old client-server) mode available in most browsers even with JS disabled.
+
The main required features are:
-* Custom elements: https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define
- (this demo will fall back to client-server mode if `window.customElements.define` is not available).
-* Custom build-in elements: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is
- (again, this demo will fall back to client-server mode if this is not supported).
-* ES modules: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type.
-* Also CSS grid for nice presentation: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template
- (presentation is less nice on small screens, should be easy to make layout responsive, but I already spent too much time on this project).
-* And `:not` CSS selector for critical UI features,
+* ES modules: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type,
+ without them no JS will load, and this demo will fall back to `mode 3`
+ (can be worked around by using bundlers, but this will only affect Chromium-based browsers from 54 (2016) to 60 (2017),
+ so it's not worth it to change the entire build setup just for better UX in these browsers).
+* Custom elements: https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define,
+ without them this demo will fall back to `mode 3`.
+* Custom built-in elements: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is,
+ without them this demo will fall back to `mode 2`.
+* `:scope` CSS selector, needed in `mode 2` only:
+ https://developer.mozilla.org/en-US/docs/Web/CSS/:scope
+* `MutationObserver`, needed in `mode 2` only:
+ https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
+* `:not` CSS selector for critical UI features, needed in all modes
(hiding and showing different messages and buttons depending on the game state):
https://developer.mozilla.org/en-US/docs/Web/CSS/:not.
+* Also CSS grid for nice presentation: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template
+ (presentation is less nice on small screens, should be easy to make layout responsive, but I already spent too much time on this project).
Therefore, for desktop browsers:
-* Gecko (Firefox): checked and works in v132, both with JS enabled (offline mode) and with JS disabled (plain old client-server mode).
- Should work in offline mode starting with Firefox 63 (2018); should fall back plain old client-server mode in all versions,
+* Gecko (Firefox): checked and works in v132, both with JS enabled (`mode 1`) and with JS disabled (`mode 3`).
+ Should work in `mode 1` starting with Firefox 63 (2018); should fall back plain old client-server mode in all versions,
although the design in Firefox 51 (2017) and older will probably not look very good due to the lack of the recent CSS features.
-* Blink (e.g. Chromium and Chromium-based browsers): superficially checked in Chromium 130, basic functionality seems to work.
- Should work in offline mode starting with Chrome 67 (2018); should fall back to plain old client-server mode in all versions,
+* Blink (e.g. Chromium and Chromium-based browsers): superficially checked in Chromium 130, basic functionality seems to work in `mode 1`.
+ Should work in `mode 1` starting with Chrome 67 (2018); should fall back to `mode 2` in Chrome plain old client-server mode in all versions,
although the design in Chrome 56 (2017) and older will probably not look very good due to the lack of the recent CSS features.
-* WebKit (e.g. qutebrowser, Konqueror, Epiphany and notably Safari): not checked; should **not** work in offline mode,
- because WebKit does not fully implement decade-old standard which Gecko and Blink supported since 2018:
- https://github.com/WebKit/standards-positions/issues/97.
- Everything should still work in online mode, falling back on client-server communication,
- except that the design in Safari before 10.1 (2017) will not look very good (but will still be functional),
+* WebKit (e.g. qutebrowser, Konqueror, Epiphany and notably Safari): superficialy checked in [BadWolf](https://hacktivis.me/projects/badwolf) 1.3 / webkit2gtk-4.1 2.46.3,
+ basic functionality seems to work both with JS enabled (in `mode 2`) and with JS disabled (in `mode 3`).
+ Should work with JS enabled in `mode 2` in all browsers supporting custom elements (e.g. in Safari 10.1 (2017) and newer);
+ should fall back to `mode 3` in older browsers, except that the design in Safari before 10.1 (2017) will not look very good (but will still be functional),
and will probably become disfunctional in Safari before 3.1 (2008).
* Servo: checked, does **not** work in nightly as of 2024-11-20 and as of 2024-11-25 (even progressive form doesn't work),
and its developer tools host seemingly crashes on this page
@@ -323,9 +340,9 @@ Therefore, for desktop browsers:
3. Gating offline JS mode for non-servo browsers only will mean that in the future, when servo is fixed,
this demo will only work in client-server mode, just because servo once had a bug. Not ideal.
(Also not even attempting to use dynamic features in servo will make it more difficult to debug the problem in it.)
-* EdgeHTML (classic MS Edge before they migrated to Chromium): not checked, should fall back to client-server mode in all versions,
+* EdgeHTML (classic MS Edge before they migrated to Chromium): not checked, should fall back to `mode 3` in all versions,
but the page will not look very pretty in Edge before 16 (2017).
-* Trident (Internet Explorer): not checked, should fall back to client-server mode,
+* Trident (Internet Explorer): not checked, should fall back to `mode 3`,
UI should be functional (not pretty) in IE8+ (2008) and dysfunctional in IE7 and lower
(fixable by refactoring the approach to displaying/hiding elements to avoid the usage of `:not` selector,
but this is outside the scope of the task).
@@ -350,22 +367,15 @@ Therefore, for desktop browsers:
So presumably, according to caniuse.com,
-* Offline JS mode should work in 88% desktop browsers and 80% total browsers
+* `mode 1` should work in 88% desktop browsers and 80% total browsers
(with Safari being the notable exception contributing 9% on desktop and 18% overall);
-* The demo should at least fall back to functional client-server model with the same UI
- in at least 98% desktop and at least 96% overall (and likely in at least 98% overall)
- (with IE lacking support for grids contributing ~1% on desktop and ~0.5% overall,
- and UC Browser and QQ Browser with unknown status of support for grids contributing further 2% overall);
-* This demo should at least fall back to functional client-server model with at least functional (but not neccessary pretty) UI
- in 99.9% desktop and at least 97% overall browsers (and likely at least 99% overall)
- (with older versions of IE lacking support for `:not` selectors contributing 0.1% on desktop,
- and UC Browser and QQ Browser with unknown status contributing 2% overall;
- it is highly likely that they do actually support `:not` selectors).
+* Fallback to `mode 2` should bring the total to at least 96% overall (98% on desktop; for some less popular mobile browsers support status is unknown);
+* The demo should at least fall back to functional `mode 3` (client-server) with the functional UI
+ in 99.9% desktop and presumably 99.9% overall browsers,
+ with Internet Explorer being the main offender.
## Known issues and quirks
-* The game does not work offline fully on client (i.e. without falling back on client-server communication)
- in WebKit-based browsers (such as qutebrowser or Safari), see above.
* Playing against the computer opponent is only supported for boards under 12 squares (i.e. 4x3 or 3x4 max).
* The computer player moves might be counterintuitive at times,
and it might be difficult for a human player to get to lose the game,
@@ -380,11 +390,6 @@ So presumably, according to caniuse.com,
* Use HTML ``s for rendering state messages,
instead of having them all in HTML and then hiding irrelevant with CSS,
for better graceful degradation in browsers that don't support complex CSS queries with `:not`.
-* Implement custom progressive form wrapper element (use `MutationObserver` to find when forms are added/removed),
- use it instead of custom built-in element in browsers not supporting custom built-in elements
- (i.e. all modern WebKit browsers including Safari 10.1+, and Chrome 54 to 66),
- so that these browsers will get offline client-only support too,
- instead of falling back to client-server mode.
* Implement error handling and handling of incorrect / malformed game states (since they come from the client).
* Improve UI for large boards (disable autoplayers when board is too large,
hide "enable autoplayer" buttons, provide clear indication to the user instead).
diff --git a/src/backend/components/boardgame.tsx b/src/backend/components/boardgame.tsx
index 9d5a95b..883c760 100644
--- a/src/backend/components/boardgame.tsx
+++ b/src/backend/components/boardgame.tsx
@@ -53,74 +53,76 @@ export const getBoardgameHtml = (key: string, gameState: BoardgameStateType, gam
return (
It works both with JS and without JS; it does not require network connection when JS is used; and it
supports history navigation (you can go back & forward and see how the state changes).
+
+ Note that, for simplicity reasons, this falls back to client-server mode in WebKit-based browsers (e.g.
+ Safari).