🦄 Sync 2026-09-13 19:17:01

This commit is contained in:
github-actions[bot] committed 2026-09-13 19:17:01 +08:00
1 parent 52a1584d3e
commit 20ded69afb
57 files changed
+2774 -6425

No files matched your search

@@ -853,6 +853,18 @@ function anchorRef() {
}
let _anchorPending = null;
/* WHY THE LAST ENGINE-OFF CORRECTION DID OR DID NOT WRITE — the `applyAnchor()` twin of `_lateWhy`,
* exported as `anchorWhy()` for the sweep. The engine-OFF cell of `/admin/network/dhcp @390 top
* compact` corrected at 1034 ms and 1885 ms on firefox with `theme said: null`, i.e. through this
* path and not `lateDrift()`, and `applyAnchor()` has five ways to return without a write that all
* read as "late" from outside. Named here so that finding says which. */
let _anchorWhy = null;
const _anchorTrail = [];
function awhy(w) {
_anchorWhy = w;
_anchorTrail.push(w + '@' + Math.round(performance.now()));
if (_anchorTrail.length > 8) _anchorTrail.shift();
}
let _anchorFrame = 0;
/* dev switch: `localStorage.fsAnchor = 'off'` stops the theme writing the scroll offset at all,
* which is the one thing here that can move a page nobody is touching */
@@ -886,7 +898,17 @@ let _lateFrame = 0;
* try from, or read the engine as having already done the job — and each guess cost a push. One
* short string, set at every exit, ends that: the finding names the line instead of the silence. */
let _lateWhy = null;
function why(w) { _lateWhy = w; }
/* THE LAST EIGHT, WITH THE CLOCK — task trail. One last word is ambiguous: a correction whose `settle`
* has not run yet and one that ran, exited, and was re-armed by a later mutation both read `armed` at
* the end of the sweep's window. Seen on firefox, /admin/network/dhcp @390 top large, engine on:
* `theme said: armed` with the correction landing at 1744 ms. `performance.now()`, the clock the sweep
* measures the refill on, so the gate can print each entry relative to it. */
const _lateTrail = [];
function why(w) {
_lateWhy = w;
_lateTrail.push(w + '@' + Math.round(performance.now()));
if (_lateTrail.length > 8) _lateTrail.shift();
}
function lateDrift(ref, grow, floorShrink) {
/* the reference from BEFORE this tick, captured by the caller: one taken after the mutation
@@ -1200,8 +1222,9 @@ function settleDeferredFloor(offsetBefore, shrink) {
}
function scheduleAnchor(ref) {
if (!ref || !anchorEnabled()) return;
if (_anchorPending) return;
if (!ref) return awhy('no-reference');
if (!anchorEnabled()) return awhy('anchoring-off');
if (_anchorPending) return awhy('pending-kept-first');
_anchorPending = ref;
if (_anchorFrame) return;
_anchorFrame = requestAnimationFrame(() => {
@@ -1234,7 +1257,7 @@ function applyAnchor(ref) {
* `sawClamp()` is the pixel `holdFloor()` watched the clamp land on, and it stands only while
* the offset has not left it — a reader who really is scrolling has moved off it by definition,
* so this reopens the guard for exactly one case and no other. */
if (scrolling() && !sawClamp()) return;
if (scrolling() && !sawClamp()) return awhy('refused-moving');
/* through scroller(), not a second probe: two copies of the same question can answer
* differently within one frame */
const sc = scroller();
@@ -1247,14 +1270,15 @@ function applyAnchor(ref) {
* collapse clamps the offset to zero, which is the worst version of this fault rather than the
* one case to sit out. */
if (ref.by != null) {
if (ref.by < 1) return;
if (ref.by < 1) return awhy('by-under-1');
writeOffset(sc, at + ref.by);
awhy('wrote-by-' + Math.round(ref.by));
return true;
}
if (at <= 0) return;
if (!ref.el.isConnected) return;
if (at <= 0) return awhy('at-top');
if (!ref.el.isConnected) return awhy('reference-gone');
const drift = ref.el.getBoundingClientRect().top - ref.top;
if (Math.abs(drift) < 1) return; /* nothing needed correcting here */
if (Math.abs(drift) < 1) return awhy('no-drift'); /* nothing needed correcting here */
/* A definite write is a definite miss — task trust: any recovery streak counted so far said
* nothing about THIS tick, and this tick just proved the engine did not do the job on its own.
* (Recovery evidence itself is gathered earlier, in the mutation callback — see TRUST_RECOVERY
@@ -1267,8 +1291,9 @@ function applyAnchor(ref) {
* is the most a single tick can honestly account for — where `innerHeight` is unreadable those
* 200px are the whole ceiling — plus whatever the engine is on record for having clamped away
* (`slack`, see anchorFor()). */
if (Math.abs(drift) > (window.innerHeight || 0) + 200 + (ref.slack || 0)) return;
if (Math.abs(drift) > (window.innerHeight || 0) + 200 + (ref.slack || 0)) return awhy('drift-too-big');
writeOffset(sc, at + drift);
awhy('wrote-' + Math.round(drift));
return true;
}
@@ -1437,9 +1462,17 @@ function observeContent() {
* win"). This is the discriminator that survives both: a batch that removed nodes, added none
* and left the floored box no taller is a removal, and a removal is not a page to correct
* against. A synchronous `dom.content()` — every real poll tick — delivers its removals and
* its additions in ONE batch and is untouched. */
* its additions in ONE batch and is untouched.
*
* AND ONLY WHERE THE FLOORED BOX DID NOT SHRINK. The first cut skipped every pure removal and
* that took out the correction REPEAT's pad removal between refills needs: the pad goes, the
* floor comes down with it, and `floorShrink` is carried into `lateDrift()` exactly so the clamp
* that follows gets put back. CI on cbcfd5d: `refill 2/3 left the reader -60px off, corrected
* never` on chromium and firefox, /admin/network/dhcp @390, both stands. The transient this
* guard is for is the empty half of a refill, where the floor HOLDS the box — so floorShrink
* is 0 there and non-zero on a real shrink. */
if (trustEngine) {
if (took && !gave && grew <= 0) why('emptying');
if (took && !gave && grew <= 0 && floorShrink <= 1) why('emptying');
else lateDrift(settled, grew, floorShrink);
}
else scheduleAnchor(ref);
@@ -1544,6 +1577,9 @@ return baseclass.extend({
scrolling,
/* unmarked, for tools/scroll-anchor.mjs — see `_lateWhy` */
lateWhy: () => _lateWhy,
lateTrail: () => _lateTrail.slice(),
anchorWhy: () => _anchorWhy,
anchorTrail: () => _anchorTrail.slice(),
deferMeasurement,
/* -> the offset this file last took a reference at, or null before it has taken one.