fix(model_resolution_picker): refit on the next frame after a resize notification

- The ResizeObserver callback measured the panel and resized the node
  synchronously, which forces a layout while the stylesheet may still be
  applying; WebKit then reports "ResizeObserver loop completed with
  undelivered notifications" as a page error, and the browser fixture
  fails any test with a page error (CI WebKit job on PR #108).
- The callback now only schedules a single-flight requestAnimationFrame
  that measures and refits, so no observed box changes during delivery.
- Reproduced in the pinned Playwright WebKit image: the picker tests pass
  48/48 (16 tests × 3) with this change.
This commit is contained in:
Vito Sansevero
2026-10-27 14:54:11 -07:00
parent dfe11928b9
commit f04f2584a8
2 changed files with 17 additions and 7 deletions
+12 -3
View File
@@ -259,11 +259,20 @@ function mountPicker(node) {
// The stylesheet, fonts or a wrapped status line can change the content height after a render
// (the first fit may even see an unstyled panel): refit whenever a child's box changes. The
// children are created once by the view, so observing them at mount covers every render.
// The refit runs on the next frame, never inside the observer delivery: measuring there forces a
// layout while the stylesheet may be applying, and WebKit then reports an undelivered-notifications
// loop error for the observed children.
if (typeof ResizeObserver === 'function') {
let refitScheduled = false;
const observer = new ResizeObserver(() => {
if (scope.signal.aborted) return;
const measured = measurePanel();
if (measured && measured !== panelHeight) fitNodeHeight();
if (scope.signal.aborted || refitScheduled) return;
refitScheduled = true;
requestAnimationFrame(() => {
refitScheduled = false;
if (scope.signal.aborted) return;
const measured = measurePanel();
if (measured && measured !== panelHeight) fitNodeHeight();
});
});
for (const child of view.element.children) observer.observe(child);
scope.cleanup(() => observer.disconnect());
+5 -4
View File
@@ -128,10 +128,11 @@ render the extension sets the node height to the host's `computeSize()` while
keeping the width. The measurement is retried for up to 60 frames when the
element is not attached yet (fresh mount, workflow load), skipped while the
family table is still loading, and ignored when the panel is hidden by the
host. A `ResizeObserver` on the panel's children refits the node when their
boxes change later, for example when the stylesheet arrives after the first
render, so the panel children must carry no vertical margins (the stylesheet
zeroes them).
host. A `ResizeObserver` on the panel's children schedules a refit on the next
frame when their boxes change later, for example when the stylesheet arrives
after the first render; measuring inside the observer delivery would make WebKit
report an undelivered-notifications loop error. The panel children must carry no
vertical margins (the stylesheet zeroes them).
## Node Dimensions and modal dialogs