update 2026-10-03 07:30:26

This commit is contained in:
action committed 2026-10-03 07:30:26 +08:00
1 parent e14489bd54
commit ba8090b29d
28 files changed
+1589 -160

No files matched your search

@@ -282,8 +282,8 @@ function fitChrome() {
* 123px on owrt2512 at 767px — 107px of growth a floor never sees, on top of the shrink it does
* — each step landing between two of the poll's own separate section refreshes, so the browser
* paints in between and the reader is moved by exactly as much, on Chromium and Firefox as well
* as Safari (`tools/fit-quiet.mjs`, `../tmp/task-toplayout/pass-probe.mjs`). `min-height` alone
* was measured to `accc451`'s WebKit-only diagnosis instead — WebKit's own scroll anchoring
* as Safari (`tools/fit-quiet.mjs`, plus a probe that pauses the layout mid-pass). `min-height`
* alone was measured to `accc451`'s WebKit-only diagnosis instead — WebKit's own scroll anchoring
* looked like the whole story only because it is the one engine with no anchoring at all to hide
* this walk behind; Chromium and Firefox absorb it the same way they absorb any other layout
* change, which is not the same as not producing it.
@@ -585,8 +585,8 @@ return baseclass.extend({
* resize is exactly what starts that window (fs-fit.js's resize observer feeds the same
* motion sampler `scrolling()` reads). A caller landing in that window, most of all
* fs-select's, got the width the PREVIOUS viewport had: at 568px settling to 390px, model
* stayed 568 for up to 220ms of the 400 (measured: −178px, exactly 568−390;
* ../tmp/task-vnstat/probe2.mjs, probe3.mjs; live-audit's `geometry|fs-content` finding on
* stayed 568 for up to 220ms of the 400 (measured: −178px, exactly 568−390, against a probe
* resizing the window mid-settle, and live-audit's `geometry|fs-content` finding on
* owrt2410, CI run 34364446910).
*
* So the window's own width is compared fresh on every call, not only when `_shellOuter`
@@ -485,10 +485,10 @@ function restoreScroll(pos, gen) {
* anywhere in the document, while THIS one is still waiting for its content to grow tall enough —
* used to read as "the reader scrolled" and cancel the whole restore, killing the axis that WAS
* legitimately pending over one that was never being restored at all. Reproduced without a real
* router (`../tmp/task-back/repro2.mjs`): a bare `window.scrollTo(0, 111)` from an unrelated
* script while the sidebar layout's `#maincontent` restore was still pending left the reader at 0
* for the rest of the 5 s window instead of the parked 3000; scoping the check to the axis `pos`
* carries fixes it, samples unchanged (3000).
* router: a bare `window.scrollTo(0, 111)` from an unrelated script while the sidebar layout's
* `#maincontent` restore was still pending left the reader at 0 for the rest of the 5 s window
* instead of the parked 3000; scoping the check to the axis `pos` carries fixes it, samples
* unchanged (3000).
*
* A SAME-axis false alarm survives that fix: the browser's OWN traversal restore lands on the
* scroller BEFORE this handler swaps `#view` (see the comment above the function), and the swap
@@ -1235,9 +1235,9 @@ function navigate(pathname, push, kbd) {
* than at the click, where it used to sit — means the reader keeps reading the
* OUTGOING page from wherever they were for the whole staging window instead of
* being thrown to its top the moment they click. Measured with the require held open
* (1.2 s, ../tmp/task-navflash/navflash-slow.mjs): `y` used to hit 0 within 12 ms of
* the click and stay there through the swap; moved here it stays at the reader's own
* offset for the whole window and reaches 0 in the same frame the new page appears.
* (1.2 s): `y` used to hit 0 within 12 ms of the click and stay there through the
* swap; moved here it stays at the reader's own offset for the whole window and
* reaches 0 in the same frame the new page appears.
* docs/anchoring.md, "The scroll reset". */
if (push) {
window.scrollTo(0, 0);
@@ -30,15 +30,20 @@ fi
# The pattern is deliberately NOT symlinked into /www: an SVG is a document, and served as one
# through a plain same-origin URL it runs as a script with the admin's session (OpenWrt forum
# thread 251930). It is instead read by cgi-bin/luci-theme-footstrap-pattern, which answers with
# CSP 'none' + sandbox and nosniff — headers uhttpd cannot attach to a static file. The login
# background stays a plain symlink: fs-assets.js re-encodes every upload to a JPEG on a canvas
# first, so there is no script grammar left in the bytes for a direct hit to run.
# CSP 'none' + sandbox and nosniff — headers uhttpd cannot attach to a static file. It needs its
# .svg name to paint at all, so octet-stream is not open to it.
#
# The login background stays a plain symlink, and NOT because of what the browser did to the
# bytes: the ACL authorises the cgi-upload POST whatever wrote it, so fs-assets.js's canvas
# re-encode is compression and EXIF removal, not a boundary (it says so itself). What keeps a
# direct open inert is the extension-less name — uhttpd types the response by extension and
# answers application/octet-stream, which a browser downloads instead of running as a document.
mkdir -p /etc/footstrap
if [ -d /www/luci-static/footstrap ]; then
ln -sf /etc/footstrap/login-bg /www/luci-static/footstrap/bg
ln -sfn /etc/footstrap/fonts /www/luci-static/footstrap/fonts
fi
# Clean up a pre-0.15 install's stale pattern symlink — see the header comment above for why this
# Clean up a pre-0.14.11 install's stale pattern symlink — see the header comment above for why this
# is the one migration this script makes. `-L` only: never remove a real file some other install
# step could have left at that path.
[ -L /www/luci-static/footstrap/pattern.svg ] && rm -f /www/luci-static/footstrap/pattern.svg
@@ -42,6 +42,8 @@
* 14 h3 on live 24.10.8 — not dead there, that release has no hide/show control */
:is(.cbi-title h3, .cbi-section > h3)[role="button"] {
cursor: pointer;
-webkit-user-select: none; /* every shipped Safari/iOS reads only the prefixed form */
user-select: none; /* rapid header clicks read as a double-click and select the card */
border-radius: var(--fs-radius-sm);
}
:is(.cbi-title h3, .cbi-section > h3)[role="button"]:focus-visible {