usage: the Sessions calendar refits on the next frame, not inside its ResizeObserver's call — sessions-overview's WebKit en case failed about 2 runs in 3 with the page error "ResizeObserver loop completed with undelivered notifications". sessCalWidth called the chart's fitCal in the observer's own call; when the room for the weeks changed, the calendar was put again with more or fewer leading cells, the card's height moved (1028x187 → 1028x190, read from a probe that logged each observer's entries), and the observer was owed that change in the same frame, which WebKit reports as the loop error. The refit now waits for the next animation frame, once per chart however many sizes arrive; a calendar drawn or redrawn still fits at once (renderSessChart calls fitCal itself). sessions-overview passes 10/10 in WebKit and 10/10 in Chromium, en and zh (it failed 3 of 4 WebKit runs before); sessions-calendar-fill, sessions-today, sessions-overview and the other sessions-* tests and click-scroll pass in both, except sessions-talk's WebKit "opening Continue in moved the page" (179 vs 184), which fails the same on origin/main b45fe28c and is not this change.

This commit is contained in:
yetone committed 2026-10-06 14:03:10 +08:00
1 parent b45fe28c9d
commit 97c2fac127
1 file changed
+7 -1
+7 -1
View File
@@ -15964,7 +15964,13 @@ const SESS_WEEK = 20, SESS_WEEK_MAX = 24;
// wide card and left the rest empty. The weeks before the range come in as
// empty cells, GitHub's way, up to a year in all, and the cells grow a little
// to take what is left; a narrow card gets none and its cells shrink.
const sessCalWidth = new ResizeObserver((es) => { for (const e of es) e.target.fitCal?.(); });
// It fits on the next frame: a calendar put again changes the card's height,
// which this would be told of in the same call, a ResizeObserver loop.
const sessCalWidth = new ResizeObserver((es) => {
for (const { target: chart } of es) {
if (!chart.fitFrame) chart.fitFrame = requestAnimationFrame(() => { chart.fitFrame = 0; chart.fitCal?.(); });
}
});
function sessCalFit(chart, days, value, tip) {
const wrap = chart.querySelector(".sess-cal-wrap"), cal = wrap?.querySelector(".sess-cal");
if (!cal || !wrap.clientWidth) return;