pdfjs-reader-core 0.5.9 → 0.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2031,6 +2031,22 @@ interface EngineDeps {
2031
2031
  * visually in a narration context. Default: 3500ms.
2032
2032
  */
2033
2033
  minOverlayDurationMs?: number;
2034
+ /**
2035
+ * When true, only ONE annotation overlay is on-screen at any time: every
2036
+ * new overlay-emitting step first clears all prior overlays and their
2037
+ * auto-removal timers.
2038
+ *
2039
+ * Defaults to `isIOSMobile()` — on iOS Safari/WebKit, stacking 2-3 overlays
2040
+ * (e.g. highlight + box + underline + callout) on the same anchor is the
2041
+ * single biggest remaining crash vector we've measured. The GPU
2042
+ * compositor rejects the layer combination long before the canvas cap
2043
+ * kicks in. Dropping to one overlay at a time sacrifices overlay chaining
2044
+ * on iOS for a hard stability guarantee.
2045
+ *
2046
+ * Pass `false` explicitly to force multi-overlay mode even on iOS (e.g.
2047
+ * for tests or a deliberate opt-out in the consumer).
2048
+ */
2049
+ singleActiveOverlay?: boolean;
2034
2050
  }
2035
2051
  declare class StoryboardEngine {
2036
2052
  private deps;
@@ -2049,6 +2065,13 @@ declare class StoryboardEngine {
2049
2065
  */
2050
2066
  private overlayRemovalTimers;
2051
2067
  private currentStoryboardId;
2068
+ /**
2069
+ * Resolved value of `deps.singleActiveOverlay`. Cached at construction so
2070
+ * each step dispatch is a single branch rather than a per-call
2071
+ * userAgent sniff, and so the policy stays stable for the engine's
2072
+ * lifetime (a viewport flip that recreates the engine will re-evaluate).
2073
+ */
2074
+ private readonly singleActiveOverlay;
2052
2075
  constructor(deps: EngineDeps);
2053
2076
  /**
2054
2077
  * Execute a new storyboard. Cancels in-flight steps from the previous storyboard
package/dist/index.d.ts CHANGED
@@ -2031,6 +2031,22 @@ interface EngineDeps {
2031
2031
  * visually in a narration context. Default: 3500ms.
2032
2032
  */
2033
2033
  minOverlayDurationMs?: number;
2034
+ /**
2035
+ * When true, only ONE annotation overlay is on-screen at any time: every
2036
+ * new overlay-emitting step first clears all prior overlays and their
2037
+ * auto-removal timers.
2038
+ *
2039
+ * Defaults to `isIOSMobile()` — on iOS Safari/WebKit, stacking 2-3 overlays
2040
+ * (e.g. highlight + box + underline + callout) on the same anchor is the
2041
+ * single biggest remaining crash vector we've measured. The GPU
2042
+ * compositor rejects the layer combination long before the canvas cap
2043
+ * kicks in. Dropping to one overlay at a time sacrifices overlay chaining
2044
+ * on iOS for a hard stability guarantee.
2045
+ *
2046
+ * Pass `false` explicitly to force multi-overlay mode even on iOS (e.g.
2047
+ * for tests or a deliberate opt-out in the consumer).
2048
+ */
2049
+ singleActiveOverlay?: boolean;
2034
2050
  }
2035
2051
  declare class StoryboardEngine {
2036
2052
  private deps;
@@ -2049,6 +2065,13 @@ declare class StoryboardEngine {
2049
2065
  */
2050
2066
  private overlayRemovalTimers;
2051
2067
  private currentStoryboardId;
2068
+ /**
2069
+ * Resolved value of `deps.singleActiveOverlay`. Cached at construction so
2070
+ * each step dispatch is a single branch rather than a per-call
2071
+ * userAgent sniff, and so the policy stays stable for the engine's
2072
+ * lifetime (a viewport flip that recreates the engine will re-evaluate).
2073
+ */
2074
+ private readonly singleActiveOverlay;
2052
2075
  constructor(deps: EngineDeps);
2053
2076
  /**
2054
2077
  * Execute a new storyboard. Cancels in-flight steps from the previous storyboard
package/dist/index.js CHANGED
@@ -1879,6 +1879,15 @@ function detectDeviceCapabilities() {
1879
1879
  screenSize
1880
1880
  };
1881
1881
  }
1882
+ function isIOSMobile() {
1883
+ if (typeof window === "undefined" || typeof navigator === "undefined") {
1884
+ return false;
1885
+ }
1886
+ const ua = navigator.userAgent || "";
1887
+ if (/iPhone|iPad|iPod/i.test(ua)) return true;
1888
+ const isAppleTouch = /Mac/i.test(ua) && typeof navigator.maxTouchPoints === "number" && navigator.maxTouchPoints > 1;
1889
+ return isAppleTouch;
1890
+ }
1882
1891
  function getRenderConfig(quality = "auto", capabilities) {
1883
1892
  const caps = capabilities ?? detectDeviceCapabilities();
1884
1893
  if (quality === "auto") {
@@ -13140,8 +13149,8 @@ var ACCENT_SOFT = "rgba(176, 74, 26, 0.18)";
13140
13149
  var ACCENT_GLOW = "rgba(176, 74, 26, 0.35)";
13141
13150
  var SERIF = "'Iowan Old Style', 'Palatino Linotype', Palatino, 'Book Antiqua', 'EB Garamond', 'Hoefler Text', Georgia, serif";
13142
13151
  var EASE_OUT_EXPO = [0.22, 1, 0.36, 1];
13143
- var PILL_FONT_CAPS = "clamp(10.5px, 0.55vw + 8.5px, 14.5px)";
13144
- var PILL_FONT_BODY = "clamp(12px, 0.6vw + 10px, 16.5px)";
13152
+ var PILL_FONT_CAPS = "clamp(9px, 0.55vw + 7px, 13px)";
13153
+ var PILL_FONT_BODY = "clamp(10.5px, 0.6vw + 8.5px, 15px)";
13145
13154
  var PILL_FONT_DISPLAY = "clamp(14px, 0.75vw + 12px, 19px)";
13146
13155
  var PILL_MAX_W_CAPS = "clamp(180px, 26vw, 380px)";
13147
13156
  var PILL_MAX_W_BODY = "clamp(200px, 28vw, 440px)";
@@ -13152,8 +13161,8 @@ function resolveMaxPillW(viewportWidthPx) {
13152
13161
  return clamp(0.26 * viewportWidthPx, 180, 380);
13153
13162
  }
13154
13163
  function resolveMaxPillH(viewportWidthPx) {
13155
- const font = clamp(55e-4 * viewportWidthPx + 8.5, 10.5, 14.5);
13156
- return clamp(font * 2.6, 28, 42);
13164
+ const font = clamp(55e-4 * viewportWidthPx + 7, 9, 13);
13165
+ return clamp(font * 2.6, 24, 36);
13157
13166
  }
13158
13167
  function clamp(v, lo, hi) {
13159
13168
  return Math.min(hi, Math.max(lo, v));
@@ -14409,13 +14418,14 @@ function StickyLabel({ screenAnchor, action }) {
14409
14418
  textTransform: "uppercase",
14410
14419
  fontWeight: 500,
14411
14420
  // Wrap instead of truncating with an ellipsis. Short labels stay
14412
- // single-line naturally; longer ones grow in height rather than
14413
- // losing their tail. `overflowWrap: 'anywhere'` keeps a stray
14414
- // long word from pushing the pill past `maxWidth` (normal word
14415
- // breaking stops at whitespace and can't break inside words).
14421
+ // single-line; longer ones grow in height rather than losing
14422
+ // their tail. `overflowWrap: 'break-word'` respects min-content
14423
+ // sizing so a single overflowing word mid-breaks at a safe
14424
+ // boundary unlike `anywhere`, which would collapse the pill
14425
+ // to 1-char min width and stack every letter on its own line.
14416
14426
  maxWidth: PILL_MAX_W_BODY,
14417
14427
  whiteSpace: "normal",
14418
- overflowWrap: "anywhere",
14428
+ overflowWrap: "break-word",
14419
14429
  // Warm two-layer shadow (matches GhostReference's palette).
14420
14430
  boxShadow: "0 1px 2px rgba(42, 36, 32, 0.12), 0 8px 18px -6px rgba(42, 36, 32, 0.22)",
14421
14431
  // Internal left accent rule — a 2px terracotta stripe.
@@ -14714,11 +14724,13 @@ function CalloutLabelPill({
14714
14724
  fontWeight: 500,
14715
14725
  // Wrap instead of truncating. Short labels stay single-line;
14716
14726
  // longer ones grow taller rather than losing their tail to an
14717
- // ellipsis. `overflowWrap: 'anywhere'` guards against a stray
14718
- // long word pushing the pill past `maxWidth`.
14727
+ // ellipsis. `overflowWrap: 'break-word'` respects min-content
14728
+ // sizing `anywhere` here caused the pill to collapse to 1-char
14729
+ // width and stack each letter on its own line when the clamped
14730
+ // maxWidth was narrow.
14719
14731
  maxWidth: PILL_MAX_W_CAPS,
14720
14732
  whiteSpace: "normal",
14721
- overflowWrap: "anywhere",
14733
+ overflowWrap: "break-word",
14722
14734
  boxShadow: "0 1px 2px rgba(42, 36, 32, 0.12), 0 8px 18px -6px rgba(42, 36, 32, 0.22)",
14723
14735
  // Accent rule on the "inward" edge (the one closest to the arrow).
14724
14736
  backgroundImage: spec.accentGradient,
@@ -14808,6 +14820,7 @@ function SubtitleBar({ text }) {
14808
14820
  // src/director/storyboard-engine.ts
14809
14821
  init_narration_store();
14810
14822
  init_camera_math();
14823
+ init_mobile_config();
14811
14824
  var DEFAULT_MIN_OVERLAY_MS = 3500;
14812
14825
  var StoryboardEngine = class {
14813
14826
  constructor(deps) {
@@ -14827,6 +14840,7 @@ var StoryboardEngine = class {
14827
14840
  this.overlayRemovalTimers = /* @__PURE__ */ new Map();
14828
14841
  this.currentStoryboardId = 0;
14829
14842
  this.deps = deps;
14843
+ this.singleActiveOverlay = deps.singleActiveOverlay ?? isIOSMobile();
14830
14844
  }
14831
14845
  /**
14832
14846
  * Execute a new storyboard. Cancels in-flight steps from the previous storyboard
@@ -14996,6 +15010,10 @@ var StoryboardEngine = class {
14996
15010
  createdAt: Date.now(),
14997
15011
  expiresAt: Date.now() + visibleMs
14998
15012
  };
15013
+ if (this.singleActiveOverlay) {
15014
+ this.cancelAllRemovalTimers();
15015
+ narrationStore.getState().clearOverlays();
15016
+ }
14999
15017
  narrationStore.getState().addOverlay(overlay);
15000
15018
  const timer = setTimeout(() => {
15001
15019
  narrationStore.getState().removeOverlay(overlay.id);