Ignore small height-only viewport resizes in the fx renderer

Mobile browser toolbar transitions change the viewport height by a
fraction mid-gesture; re-rendering the PDF for that races with
active text selections and can blank the canvas (the old canvas is
cleared for the re-render, and the async pdf.js render can fail or
get interrupted by the next resize). Only re-render for real layout
changes — same threshold as the paginator.
This commit is contained in:
John O'Keefe
2026-09-16 17:23:59 -04:00
parent 94bb38453d
commit 1305a5280c
+18 -1
View File
@@ -25,7 +25,24 @@ const getViewport = (doc, viewport) => {
export class FixedLayout extends HTMLElement { export class FixedLayout extends HTMLElement {
static observedAttributes = ["zoom", "interaction-mode", "spread"]; static observedAttributes = ["zoom", "interaction-mode", "spread"];
#root = this.attachShadow({ mode: "closed" }); #root = this.attachShadow({ mode: "closed" });
#observer = new ResizeObserver(() => this.#onResize()); #observer = new ResizeObserver((entries) => {
// Mobile browsers grow/shrink the viewport by ~7-17% when the
// toolbar hides/shows mid-gesture; re-rendering the PDF for that
// races with active selections and can blank the canvas. Only
// re-render for real layout changes: any width change, or a
// height change large enough to be a rotation, keyboard, or
// split-screen.
const rect = entries?.[entries.length - 1]?.contentRect;
if (rect && rect.width && rect.height && this.#lastSize) {
const [w, h] = this.#lastSize;
if (Math.abs(rect.width - w) < 1 && Math.abs(rect.height - h) / h < 0.25)
return;
}
if (rect && rect.width && rect.height)
this.#lastSize = [rect.width, rect.height];
this.#onResize();
});
#lastSize;
#spreads; #spreads;
#index = -1; #index = -1;
defaultViewport; defaultViewport;