Add PDF state persistence

This commit is contained in:
2026-03-30 09:29:19 +02:00
parent d1bb79570d
commit 4613b8e5dd
15 changed files with 380 additions and 55 deletions

View File

@@ -23,8 +23,21 @@ export class ViewportTracker {
}
_observe(root, pageWrappers) {
const notify = () => {
this._onVisibilityChange(new Set(this._bufferSet), new Set(this._visibleSet));
// Both observers update their respective sets and then schedule a single
// notification via rAF. This prevents a stale notify when the two
// observers fire in separate microtasks for the same layout change —
// e.g. bufferObserver removes a page from bufferSet before visibleObserver
// has had a chance to also remove it from visibleSet, which would let
// reconcile() incorrectly tear down a still-visible canvas.
this._rafPending = null;
const scheduleNotify = () => {
if (this._rafPending !== null) return;
this._rafPending = requestAnimationFrame(() => {
this._rafPending = null;
// Hard invariant: every visible page must also be in the buffer.
for (const p of this._visibleSet) this._bufferSet.add(p);
this._onVisibilityChange(new Set(this._bufferSet), new Set(this._visibleSet));
});
};
this._visibleObserver = new IntersectionObserver(
@@ -34,7 +47,7 @@ export class ViewportTracker {
if (e.isIntersecting) this._visibleSet.add(page);
else this._visibleSet.delete(page);
}
notify();
scheduleNotify();
},
{ root, rootMargin: "0px", threshold: 0 }
);
@@ -46,7 +59,7 @@ export class ViewportTracker {
if (e.isIntersecting) this._bufferSet.add(page);
else this._bufferSet.delete(page);
}
notify();
scheduleNotify();
},
{ root, rootMargin: "200% 0px", threshold: 0 }
);