@prose-reader/core 1.132.0 → 1.134.0

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.
@@ -13,14 +13,82 @@
13
13
  };
14
14
  containerElement.addEventListener(`scroll`, onScroll);
15
15
  });
16
- reader.hookManager.register(`item.onDocumentLoad`, ({ layers }) => {
17
- var _a, _b;
18
- const frame = (_a = layers[0]) == null ? void 0 : _a.element;
19
- if (!(frame instanceof HTMLIFrameElement)) return;
20
- (_b = frame.contentDocument) == null ? void 0 : _b.body.setAttribute(`tabindex`, `-1`);
16
+ reader.hookManager.register(`item.onDocumentLoad`, ({ itemId }) => {
17
+ var _a;
18
+ const item = reader.spineItemsManager.get(itemId);
19
+ const frame = item == null ? void 0 : item.renderer.getDocumentFrame();
20
+ if (!frame) return;
21
+ (_a = frame.contentDocument) == null ? void 0 : _a.body.setAttribute(`tabindex`, `-1`);
21
22
  });
22
23
  return reader;
23
24
  };
25
+ const mapKeysTo = (keys) => {
26
+ return operators.map((obj) => {
27
+ return Object.entries(obj).reduce(
28
+ (acc, [key, entry]) => {
29
+ if (keys.includes(key)) {
30
+ return {
31
+ ...acc,
32
+ [key]: entry
33
+ };
34
+ }
35
+ return acc;
36
+ },
37
+ {}
38
+ );
39
+ });
40
+ };
41
+ function observeResize(element) {
42
+ return new rxjs.Observable((observer) => {
43
+ const resizeObserver = new ResizeObserver((entries) => {
44
+ observer.next(entries);
45
+ });
46
+ resizeObserver.observe(element);
47
+ return () => {
48
+ resizeObserver.disconnect();
49
+ };
50
+ });
51
+ }
52
+ const waitForSwitch = (waitForStream) => (stream) => stream.pipe(
53
+ operators.switchMap(
54
+ (value) => waitForStream.pipe(
55
+ operators.first(),
56
+ operators.map(() => value)
57
+ )
58
+ )
59
+ );
60
+ const deferNextResult = (stream) => {
61
+ let value;
62
+ const sub = stream.subscribe((result) => {
63
+ value = { result };
64
+ });
65
+ return () => {
66
+ sub.unsubscribe();
67
+ if (value) {
68
+ return rxjs.of(value.result);
69
+ }
70
+ return stream;
71
+ };
72
+ };
73
+ function idle() {
74
+ return new rxjs.Observable((observer) => {
75
+ if (window.requestIdleCallback) {
76
+ const handle = window.requestIdleCallback(() => {
77
+ observer.next();
78
+ observer.complete();
79
+ });
80
+ return () => cancelIdleCallback(handle);
81
+ }
82
+ const timeout = setTimeout(() => {
83
+ observer.next();
84
+ observer.complete();
85
+ }, 1);
86
+ return () => clearTimeout(timeout);
87
+ });
88
+ }
89
+ function deferIdle(callback) {
90
+ return rxjs.defer(() => idle().pipe(operators.switchMap(callback)));
91
+ }
24
92
  class SettingsManagerOverload {
25
93
  constructor(initialSettings, settingsManager) {
26
94
  this.settingsManager = settingsManager;
@@ -75,6 +143,12 @@
75
143
  ...this.outputSettings
76
144
  };
77
145
  }
146
+ watch(keys) {
147
+ return this.values$.pipe(
148
+ mapKeysTo(keys),
149
+ operators.distinctUntilChanged(shared.isShallowEqual)
150
+ );
151
+ }
78
152
  destroy() {
79
153
  this.outputSettingsUpdateSubject.complete();
80
154
  }
@@ -216,12 +290,11 @@
216
290
  `;
217
291
  const applyChangeToSpineItems = (requireLayout) => {
218
292
  reader.spineItemsManager.items.forEach((item) => {
219
- if (item.item.renditionLayout !== `pre-paginated`) {
220
- item.renderer.layers.forEach((layer) => {
221
- if (layer.element instanceof HTMLIFrameElement) {
222
- upsertCSS(layer.element, `prose-reader-fonts`, getStyle());
223
- }
224
- });
293
+ if (item.renditionLayout !== `pre-paginated`) {
294
+ const frame = item.renderer.getDocumentFrame();
295
+ if (frame) {
296
+ upsertCSS(frame, `prose-reader-fonts`, getStyle());
297
+ }
225
298
  }
226
299
  });
227
300
  if (requireLayout) {
@@ -230,12 +303,11 @@
230
303
  };
231
304
  reader.hookManager.register(`item.onDocumentLoad`, ({ itemId }) => {
232
305
  const item = reader.spineItemsManager.get(itemId);
233
- if ((item == null ? void 0 : item.item.renditionLayout) !== `pre-paginated`) {
234
- item == null ? void 0 : item.renderer.layers.forEach((layer) => {
235
- if (layer.element instanceof HTMLIFrameElement) {
236
- upsertCSS(layer.element, `prose-reader-fonts`, getStyle());
237
- }
238
- });
306
+ if ((item == null ? void 0 : item.renditionLayout) !== `pre-paginated`) {
307
+ const frame = item == null ? void 0 : item.renderer.getDocumentFrame();
308
+ if (frame) {
309
+ upsertCSS(frame, `prose-reader-fonts`, getStyle());
310
+ }
239
311
  }
240
312
  });
241
313
  const shouldRequireLayout = (source) => source.pipe(
@@ -292,8 +364,7 @@
292
364
  ...spineItems.map(
293
365
  (item) => item.loaded$.pipe(
294
366
  rxjs.switchMap(() => {
295
- var _a;
296
- const element = (_a = item.renderer.layers[0]) == null ? void 0 : _a.element;
367
+ const element = item.renderer.getDocumentFrame();
297
368
  return element instanceof HTMLIFrameElement && (element == null ? void 0 : element.contentDocument) ? navigateOnKey(element.contentDocument) : rxjs.EMPTY;
298
369
  })
299
370
  )
@@ -358,85 +429,17 @@
358
429
  );
359
430
  return rxjs.merge(updateOverlayElement$, handleViewportLock$);
360
431
  };
361
- const mapKeysTo = (keys) => {
362
- return operators.map((obj) => {
363
- return Object.entries(obj).reduce(
364
- (acc, [key, entry]) => {
365
- if (keys.includes(key)) {
366
- return {
367
- ...acc,
368
- [key]: entry
369
- };
370
- }
371
- return acc;
372
- },
373
- {}
374
- );
375
- });
376
- };
377
- function observeResize(element) {
378
- return new rxjs.Observable((observer) => {
379
- const resizeObserver = new ResizeObserver((entries) => {
380
- observer.next(entries);
381
- });
382
- resizeObserver.observe(element);
383
- return () => {
384
- resizeObserver.disconnect();
385
- };
386
- });
387
- }
388
- const waitForSwitch = (waitForStream) => (stream) => stream.pipe(
389
- operators.switchMap(
390
- (value) => waitForStream.pipe(
391
- operators.first(),
392
- operators.map(() => value)
393
- )
394
- )
395
- );
396
- const deferNextResult = (stream) => {
397
- let value;
398
- const sub = stream.subscribe((result) => {
399
- value = { result };
400
- });
401
- return () => {
402
- sub.unsubscribe();
403
- if (value) {
404
- return rxjs.of(value.result);
405
- }
406
- return stream;
407
- };
408
- };
409
- function idle() {
410
- return new rxjs.Observable((observer) => {
411
- if (window.requestIdleCallback) {
412
- const handle = window.requestIdleCallback(() => {
413
- observer.next();
414
- observer.complete();
415
- });
416
- return () => cancelIdleCallback(handle);
417
- }
418
- const timeout = setTimeout(() => {
419
- observer.next();
420
- observer.complete();
421
- }, 1);
422
- return () => clearTimeout(timeout);
423
- });
424
- }
425
- function deferIdle(callback) {
426
- return rxjs.defer(() => idle().pipe(operators.switchMap(callback)));
427
- }
428
432
  const fixReflowable = (reader) => {
429
433
  reader.hookManager.register(
430
434
  `item.onAfterLayout`,
431
435
  ({ item, blankPagePosition, minimumWidth }) => {
432
- var _a, _b;
433
436
  const spineItem = reader.spineItemsManager.get(item.id);
434
- const element = (_a = spineItem == null ? void 0 : spineItem.renderer.layers[0]) == null ? void 0 : _a.element;
435
- if (!((spineItem == null ? void 0 : spineItem.item.renditionLayout) === `reflowable`) || !(element instanceof HTMLIFrameElement))
437
+ const element = spineItem == null ? void 0 : spineItem.renderer.getDocumentFrame();
438
+ if (!((spineItem == null ? void 0 : spineItem.renditionLayout) === `reflowable`) || !(element instanceof HTMLIFrameElement))
436
439
  return;
437
440
  const { hasViewport } = getFrameViewportInfo(element);
438
441
  const { width: pageWidth } = reader.context.getPageSize();
439
- const frameElement = (_b = spineItem == null ? void 0 : spineItem.renderer.layers[0]) == null ? void 0 : _b.element;
442
+ const frameElement = spineItem == null ? void 0 : spineItem.renderer.getDocumentFrame();
440
443
  if (hasViewport) {
441
444
  const spineManagerWantAFullWidthItem = pageWidth < minimumWidth;
442
445
  const noBlankPageAsked = blankPagePosition === `none`;
@@ -503,8 +506,7 @@
503
506
  reader.hookManager.register(`onViewportOffsetAdjust`, () => {
504
507
  let hasRedrawn = false;
505
508
  reader.spineItemsManager.items.forEach((item) => {
506
- var _a;
507
- const frame = (_a = item.renderer.layers[0]) == null ? void 0 : _a.element;
509
+ const frame = item.renderer.getDocumentFrame();
508
510
  if (!hasRedrawn && frame) {
509
511
  void frame.getBoundingClientRect().left;
510
512
  hasRedrawn = true;
@@ -517,7 +519,7 @@
517
519
  const isImageType = !!(mimeType == null ? void 0 : mimeType.startsWith(`image/`));
518
520
  const { pageHorizontalMargin: pageHorizontalMargin2 = 0, pageVerticalMargin: pageVerticalMargin2 = 0 } = settingsManager.values;
519
521
  const pageSize = reader.context.getPageSize();
520
- if ((spineItem == null ? void 0 : spineItem.item.renditionLayout) === `reflowable` && !isImageType) {
522
+ if ((spineItem == null ? void 0 : spineItem.renditionLayout) === `reflowable` && !isImageType) {
521
523
  let columnWidth = pageSize.width - pageHorizontalMargin2 * 2;
522
524
  const columnHeight = pageSize.height - pageVerticalMargin2 * 2;
523
525
  let width = pageSize.width - pageHorizontalMargin2 * 2;
@@ -527,12 +529,12 @@
527
529
  columnWidth = columnHeight;
528
530
  columnGap = pageVerticalMargin2 * 2;
529
531
  }
530
- spineItem == null ? void 0 : spineItem.renderer.layers.forEach((layer) => {
531
- if (layer.element instanceof HTMLIFrameElement) {
532
- upsertCSS(
533
- layer.element,
534
- `prose-layout-enhancer-css`,
535
- `
532
+ const frame = spineItem == null ? void 0 : spineItem.renderer.getDocumentFrame();
533
+ if (frame) {
534
+ upsertCSS(
535
+ frame,
536
+ `prose-layout-enhancer-css`,
537
+ `
536
538
  body {
537
539
  width: ${width}px !important;
538
540
  margin: ${pageVerticalMargin2}px ${pageHorizontalMargin2}px !important;
@@ -541,8 +543,8 @@
541
543
  height: ${columnHeight}px !important;
542
544
  }
543
545
  img, video, audio, object, svg {
544
- max-width: ${columnWidth}px !important;
545
- max-height: ${columnHeight}px !important;
546
+ -max-width: ${columnWidth}px !important;
547
+ -max-height: ${columnHeight}px !important;
546
548
  }
547
549
  table {
548
550
  max-width: ${columnWidth}px !important;
@@ -551,9 +553,8 @@
551
553
  max-width: ${columnWidth}px;
552
554
  }
553
555
  `
554
- );
555
- }
556
- });
556
+ );
557
+ }
557
558
  }
558
559
  });
559
560
  fixReflowable(reader);
@@ -601,9 +602,7 @@
601
602
  })
602
603
  );
603
604
  const movingSafePan$ = createMovingSafePan$(reader);
604
- settingsManager.values$.pipe(
605
- mapKeysTo([`pageHorizontalMargin`, `pageVerticalMargin`]),
606
- operators.distinctUntilChanged(shared.isShallowEqual),
605
+ settingsManager.watch([`pageHorizontalMargin`, `pageVerticalMargin`]).pipe(
607
606
  operators.skip(1),
608
607
  operators.tap(() => {
609
608
  reader.layout();
@@ -681,6 +680,16 @@
681
680
  else console.info(wrap(ROOT_NAMESPACE), ...data);
682
681
  }
683
682
  },
683
+ debug: namespace ? Function.prototype.bind.call(
684
+ console.debug,
685
+ console,
686
+ wrap(`${ROOT_NAMESPACE}`),
687
+ wrap(namespace)
688
+ ) : Function.prototype.bind.call(
689
+ console.debug,
690
+ console,
691
+ wrap(`${ROOT_NAMESPACE}`)
692
+ ),
684
693
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
685
694
  error: (...data) => {
686
695
  console.error(...data);
@@ -739,10 +748,10 @@
739
748
  }
740
749
  return false;
741
750
  };
742
- reader.hookManager.register(`item.onDocumentLoad`, ({ layers }) => {
743
- var _a;
744
- const frame = (_a = layers[0]) == null ? void 0 : _a.element;
745
- if (!(frame instanceof HTMLIFrameElement)) return;
751
+ reader.hookManager.register(`item.onDocumentLoad`, ({ itemId }) => {
752
+ const item = reader.spineItemsManager.get(itemId);
753
+ const frame = item == null ? void 0 : item.renderer.getDocumentFrame();
754
+ if (!frame) return;
746
755
  if (frame == null ? void 0 : frame.contentDocument) {
747
756
  Array.from(frame.contentDocument.querySelectorAll(`a`)).forEach(
748
757
  (element) => element.addEventListener(`click`, (e) => {
@@ -991,6 +1000,7 @@
991
1000
  }
992
1001
  return navigationResolver.getAdjustedPositionForSpread(navigation);
993
1002
  };
1003
+ const report$4 = Report.namespace(`navigation`);
994
1004
  class ManualNavigator {
995
1005
  constructor(reader) {
996
1006
  this.reader = reader;
@@ -1149,6 +1159,12 @@
1149
1159
  pageIndex,
1150
1160
  spineItemId
1151
1161
  });
1162
+ report$4.debug(`.goToPageOfSpineItem()`, {
1163
+ pageIndex,
1164
+ spineItemId,
1165
+ ...rest,
1166
+ position
1167
+ });
1152
1168
  this.reader.navigation.navigate({
1153
1169
  position,
1154
1170
  ...rest
@@ -1161,6 +1177,11 @@
1161
1177
  const foundInfo = this.reader.spine.locator.getSpineInfoFromAbsolutePageIndex({
1162
1178
  absolutePageIndex
1163
1179
  });
1180
+ report$4.debug(`.goToAbsolutePageIndex()`, {
1181
+ absolutePageIndex,
1182
+ ...rest,
1183
+ foundInfo
1184
+ });
1164
1185
  if (foundInfo) {
1165
1186
  const position = this.reader.navigation.navigationResolver.getNavigationForSpineItemPage(
1166
1187
  {
@@ -1520,7 +1541,7 @@
1520
1541
  const { itemIndex } = reader.cfi.parseCfi(item.cfi);
1521
1542
  const spineItem = reader.spineItemsManager.get(itemIndex);
1522
1543
  if (!spineItem) return rxjs.of({ ...item, meta: { ...item.meta, itemIndex } });
1523
- if (spineItem.item.renditionLayout === `pre-paginated`) {
1544
+ if (spineItem.renditionLayout === `pre-paginated`) {
1524
1545
  itemPageIndex = 0;
1525
1546
  }
1526
1547
  return idle().pipe(
@@ -1529,7 +1550,7 @@
1529
1550
  var _a2, _b, _c;
1530
1551
  let range = void 0;
1531
1552
  const { node: startNode, offset: startOffset } = reader.cfi.resolveCfi({ cfi: item.cfi }) ?? {};
1532
- if (spineItem.item.renditionLayout !== `pre-paginated` && startNode) {
1553
+ if (spineItem.renditionLayout !== `pre-paginated` && startNode) {
1533
1554
  itemPageIndex = reader.spine.locator.spineItemLocator.getSpineItemPageIndexFromNode(
1534
1555
  startNode,
1535
1556
  startOffset ?? 0,
@@ -1568,13 +1589,7 @@
1568
1589
  };
1569
1590
  const createLocator = (reader) => (resources) => {
1570
1591
  return deferIdle(() => {
1571
- if (!resources.length)
1572
- return rxjs.of({ isStale: false, data: resources });
1573
- const StaleSymbol = Symbol("stale");
1574
- const markStale$ = reader.layout$.pipe(
1575
- rxjs.startWith(null),
1576
- rxjs.map(() => StaleSymbol)
1577
- );
1592
+ if (!resources.length) return rxjs.of(resources);
1578
1593
  const consolidate$ = reader.layout$.pipe(
1579
1594
  rxjs.debounceTime(10),
1580
1595
  rxjs.startWith(null),
@@ -1588,27 +1603,20 @@
1588
1603
  );
1589
1604
  }, resources)
1590
1605
  );
1591
- const run$ = rxjs.merge(markStale$, consolidate$).pipe(
1592
- rxjs.scan(
1593
- (acc, value) => {
1594
- if (value === StaleSymbol) {
1595
- return {
1596
- ...acc,
1597
- isStale: true
1598
- };
1599
- }
1600
- return {
1601
- isStale: false,
1602
- data: value
1603
- };
1604
- },
1605
- {
1606
- isStale: true,
1607
- data: resources
1608
- }
1609
- )
1606
+ const reflowableItemIndexes = resources.map((item) => reader.cfi.parseCfi(item.cfi).itemIndex).filter(isDefined).filter((index) => {
1607
+ var _a;
1608
+ return ((_a = reader.spineItemsManager.get(index)) == null ? void 0 : _a.renditionLayout) === `reflowable`;
1609
+ });
1610
+ const release = reader.spine.spineItemsLoader.forceOpen(
1611
+ reflowableItemIndexes
1612
+ );
1613
+ return consolidate$.pipe(
1614
+ rxjs.finalize(() => {
1615
+ setTimeout(() => {
1616
+ release();
1617
+ }, 1e3);
1618
+ })
1610
1619
  );
1611
- return run$;
1612
1620
  });
1613
1621
  };
1614
1622
  Report.namespace(NAMESPACE$6);
@@ -1685,22 +1693,20 @@
1685
1693
  };
1686
1694
  const applyChangeToSpineItem = () => {
1687
1695
  reader.spineItemsManager.items.forEach((item) => {
1688
- item.renderer.layers.forEach((layer) => {
1689
- if (layer.element instanceof HTMLIFrameElement) {
1690
- upsertCSS(layer.element, `prose-reader-theme`, getStyle());
1691
- }
1692
- });
1696
+ const frame = item.renderer.getDocumentFrame();
1697
+ if (frame) {
1698
+ upsertCSS(frame, `prose-reader-theme`, getStyle());
1699
+ }
1693
1700
  applyChangeToSpineItemElement({ container: item.element });
1694
1701
  });
1695
1702
  };
1696
1703
  reader.hookManager.register(`item.onDocumentLoad`, ({ itemId }) => {
1697
1704
  const item = reader.spineItemsManager.get(itemId);
1698
- if ((item == null ? void 0 : item.item.renditionLayout) !== "pre-paginated") {
1699
- item == null ? void 0 : item.renderer.layers.forEach((layer) => {
1700
- if (layer.element instanceof HTMLIFrameElement) {
1701
- upsertCSS(layer.element, `prose-reader-theme`, getStyle());
1702
- }
1703
- });
1705
+ if ((item == null ? void 0 : item.renditionLayout) !== "pre-paginated") {
1706
+ const frame = item == null ? void 0 : item.renderer.getDocumentFrame();
1707
+ if (frame) {
1708
+ upsertCSS(frame, `prose-reader-theme`, getStyle());
1709
+ }
1704
1710
  }
1705
1711
  });
1706
1712
  reader.spineItemsManager.items$.pipe(
@@ -2039,10 +2045,13 @@
2039
2045
  }
2040
2046
  class DestroyableClass {
2041
2047
  constructor() {
2048
+ this.isDestroyed = false;
2042
2049
  this.destroySubject = new rxjs.Subject();
2043
2050
  this.destroy$ = this.destroySubject.asObservable();
2044
2051
  }
2045
2052
  destroy() {
2053
+ if (this.isDestroyed) return;
2054
+ this.isDestroyed = true;
2046
2055
  this.destroySubject.next();
2047
2056
  this.destroySubject.complete();
2048
2057
  }
@@ -2408,10 +2417,10 @@
2408
2417
  return void 0;
2409
2418
  };
2410
2419
  const getFirstNodeOrRangeAtPage = (pageIndex, spineItem) => {
2411
- var _a, _b, _c;
2420
+ var _a, _b;
2412
2421
  const pageSize = context.getPageSize();
2413
- const frame = (_b = (_a = spineItem.renderer) == null ? void 0 : _a.layers[0]) == null ? void 0 : _b.element;
2414
- if (frame instanceof HTMLIFrameElement && ((_c = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _c.document) && // very important because it is being used by next functions
2422
+ const frame = (_a = spineItem.renderer) == null ? void 0 : _a.getDocumentFrame();
2423
+ if (frame && ((_b = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _b.document) && // very important because it is being used by next functions
2415
2424
  frame.contentWindow.document.body !== null) {
2416
2425
  const { x: left, y: top } = getSpineItemPositionFromPageIndex({
2417
2426
  pageIndex,
@@ -3621,15 +3630,15 @@
3621
3630
  cfi,
3622
3631
  spineItemsManager
3623
3632
  }) => {
3624
- var _a, _b;
3633
+ var _a;
3625
3634
  if (!cfi) return void 0;
3626
3635
  const spineItem = spineItemsManager.getSpineItemFromCfi(cfi);
3627
3636
  if (!spineItem) return void 0;
3628
3637
  const { cleanedCfi, offset } = parseCfi(cfi);
3629
3638
  const cfiHandler = new CfiHandler(cleanedCfi, {});
3630
- const rendererElement = (_a = spineItem.renderer.layers[0]) == null ? void 0 : _a.element;
3639
+ const rendererElement = spineItem.renderer.getDocumentFrame();
3631
3640
  if (rendererElement instanceof HTMLIFrameElement) {
3632
- const doc = (_b = rendererElement.contentWindow) == null ? void 0 : _b.document;
3641
+ const doc = (_a = rendererElement.contentWindow) == null ? void 0 : _a.document;
3633
3642
  if (doc) {
3634
3643
  try {
3635
3644
  const { node, offset: resolvedOffset } = cfiHandler.resolve(doc, {});
@@ -3826,14 +3835,11 @@
3826
3835
  this.navigateSubject = new rxjs.Subject();
3827
3836
  this.scrollingSubject = new rxjs.BehaviorSubject(false);
3828
3837
  this.isScrolling$ = this.scrollingSubject.asObservable();
3829
- const settingsThatRequireLayout$ = settings.values$.pipe(
3830
- mapKeysTo([
3831
- `computedPageTurnDirection`,
3832
- `computedPageTurnMode`,
3833
- `numberOfAdjacentSpineItemToPreLoad`
3834
- ]),
3835
- rxjs.distinctUntilChanged(shared.isShallowEqual)
3836
- );
3838
+ const settingsThatRequireLayout$ = settings.watch([
3839
+ `computedPageTurnDirection`,
3840
+ `computedPageTurnMode`,
3841
+ `numberOfAdjacentSpineItemToPreLoad`
3842
+ ]);
3837
3843
  const updateElementOnSettingsChange$ = rxjs.merge(
3838
3844
  settingsThatRequireLayout$,
3839
3845
  this.viewportElement$
@@ -5024,7 +5030,7 @@
5024
5030
  };
5025
5031
  this.inputSettings = settingsWithDefaults;
5026
5032
  this.outputSettingsUpdateSubject = new rxjs.Subject();
5027
- this._settings$ = this.outputSettingsUpdateSubject.asObservable().pipe(operators.shareReplay(1));
5033
+ this._settings$ = this.outputSettingsUpdateSubject.asObservable().pipe(rxjs.shareReplay(1));
5028
5034
  this._settings$.subscribe();
5029
5035
  }
5030
5036
  _prepareUpdate(settings) {
@@ -5062,6 +5068,12 @@
5062
5068
  }
5063
5069
  return this._settings$;
5064
5070
  }
5071
+ watch(keys) {
5072
+ return this.values$.pipe(
5073
+ mapKeysTo(keys),
5074
+ rxjs.distinctUntilChanged(shared.isShallowEqual)
5075
+ );
5076
+ }
5065
5077
  destroy() {
5066
5078
  super.destroy();
5067
5079
  this.outputSettingsUpdateSubject.complete();
@@ -5235,13 +5247,13 @@
5235
5247
  spineItem,
5236
5248
  spineItemLocator
5237
5249
  }) => {
5238
- var _a, _b;
5250
+ var _a;
5239
5251
  const nodeOrRange = spineItemLocator.getFirstNodeOrRangeAtPage(
5240
5252
  pageIndex,
5241
5253
  spineItem
5242
5254
  );
5243
- const rendererElement = (_a = spineItem.renderer.layers[0]) == null ? void 0 : _a.element;
5244
- if (nodeOrRange && rendererElement instanceof HTMLIFrameElement && ((_b = rendererElement.contentWindow) == null ? void 0 : _b.document)) {
5255
+ const rendererElement = spineItem.renderer.getDocumentFrame();
5256
+ if (nodeOrRange && rendererElement instanceof HTMLIFrameElement && ((_a = rendererElement.contentWindow) == null ? void 0 : _a.document)) {
5245
5257
  const cfiString = generateCfi(
5246
5258
  nodeOrRange.node,
5247
5259
  nodeOrRange.offset,
@@ -5390,6 +5402,7 @@
5390
5402
  constructor(params) {
5391
5403
  super();
5392
5404
  this.triggerSubject = new rxjs.Subject();
5405
+ this.lastLayoutDims = void 0;
5393
5406
  this.stateSubject = new rxjs.BehaviorSubject(`idle`);
5394
5407
  this.unload$ = this.triggerSubject.pipe(
5395
5408
  rxjs.withLatestFrom(this.stateSubject),
@@ -5516,6 +5529,24 @@
5516
5529
  })
5517
5530
  );
5518
5531
  }
5532
+ /**
5533
+ * @important
5534
+ *
5535
+ * If renderer returns undefined as dimensions we will use the previous
5536
+ * layout dimensions as fallback. This ensure minmum layout shift during
5537
+ * load / unload of items and improve stability..
5538
+ */
5539
+ layout(params) {
5540
+ return rxjs.defer(() => this.onLayout(params)).pipe(
5541
+ rxjs.map((dims) => {
5542
+ const { height, width } = dims ?? this.lastLayoutDims ?? { height: 0, width: 0 };
5543
+ const minHeight = Math.max(height, this.context.getPageSize().height);
5544
+ const minWidth = Math.max(width, params.minimumWidth);
5545
+ this.lastLayoutDims = { height: minHeight, width: minWidth };
5546
+ return this.lastLayoutDims;
5547
+ })
5548
+ );
5549
+ }
5519
5550
  destroy() {
5520
5551
  super.destroy();
5521
5552
  this.stateSubject.complete();
@@ -5543,6 +5574,9 @@
5543
5574
  onRenderHeadless() {
5544
5575
  return rxjs.EMPTY;
5545
5576
  }
5577
+ getDocumentFrame() {
5578
+ return void 0;
5579
+ }
5546
5580
  }
5547
5581
  class SpineItem extends DestroyableClass {
5548
5582
  constructor(item, parentElement, context, settings, hookManager, index) {
@@ -5577,13 +5611,13 @@
5577
5611
  }
5578
5612
  };
5579
5613
  this.getBoundingRectOfElementFromSelector = (selector) => {
5580
- var _a2, _b2, _c, _d, _e;
5581
- const frameElement = (_a2 = this.renderer.layers[0]) == null ? void 0 : _a2.element;
5614
+ var _a2, _b2, _c, _d;
5615
+ const frameElement = this.renderer.getDocumentFrame();
5582
5616
  if (frameElement && frameElement instanceof HTMLIFrameElement && selector) {
5583
5617
  if (selector.startsWith(`#`)) {
5584
- return (_c = (_b2 = frameElement.contentDocument) == null ? void 0 : _b2.getElementById(selector.replace(`#`, ``))) == null ? void 0 : _c.getBoundingClientRect();
5618
+ return (_b2 = (_a2 = frameElement.contentDocument) == null ? void 0 : _a2.getElementById(selector.replace(`#`, ``))) == null ? void 0 : _b2.getBoundingClientRect();
5585
5619
  }
5586
- return (_e = (_d = frameElement.contentDocument) == null ? void 0 : _d.querySelector(selector)) == null ? void 0 : _e.getBoundingClientRect();
5620
+ return (_d = (_c = frameElement.contentDocument) == null ? void 0 : _c.querySelector(selector)) == null ? void 0 : _d.getBoundingClientRect();
5587
5621
  }
5588
5622
  };
5589
5623
  this.layout = (params) => {
@@ -5591,7 +5625,9 @@
5591
5625
  this.layoutTriggerSubject.next(params);
5592
5626
  return nextResult();
5593
5627
  };
5594
- this.load = () => this.renderer.load();
5628
+ this.load = () => {
5629
+ this.renderer.load();
5630
+ };
5595
5631
  this.unload = () => {
5596
5632
  this.renderer.unload();
5597
5633
  };
@@ -5639,26 +5675,18 @@
5639
5675
  item: this.item,
5640
5676
  minimumWidth
5641
5677
  });
5642
- const layout$ = rxjs.defer(
5643
- () => this.renderer.onLayout({
5644
- blankPagePosition,
5645
- minPageSpread: minimumWidth / this.context.getPageSize().width,
5646
- minimumWidth,
5647
- spreadPosition
5648
- })
5649
- );
5678
+ const layout$ = this.renderer.layout({
5679
+ blankPagePosition,
5680
+ minPageSpread: minimumWidth / this.context.getPageSize().width,
5681
+ minimumWidth,
5682
+ spreadPosition
5683
+ });
5650
5684
  return rxjs.merge(
5651
5685
  rxjs.of({ type: "start" }),
5652
5686
  layout$.pipe(
5653
- operators.map((dims) => {
5654
- const { height, width } = dims ?? { height: 0, width: 0 };
5655
- const minHeight = Math.max(
5656
- height,
5657
- this.context.getPageSize().height
5658
- );
5659
- const minWidth = Math.max(width, minimumWidth);
5660
- this.containerElement.style.width = `${minWidth}px`;
5661
- this.containerElement.style.height = `${minHeight}px`;
5687
+ operators.map(({ height, width }) => {
5688
+ this.containerElement.style.width = `${width}px`;
5689
+ this.containerElement.style.height = `${height}px`;
5662
5690
  this.hookManager.execute(`item.onAfterLayout`, void 0, {
5663
5691
  blankPagePosition,
5664
5692
  item: this.item,
@@ -5666,7 +5694,7 @@
5666
5694
  });
5667
5695
  return {
5668
5696
  type: "end",
5669
- data: { width: minWidth, height: minHeight }
5697
+ data: { width, height }
5670
5698
  };
5671
5699
  })
5672
5700
  )
@@ -5730,6 +5758,12 @@
5730
5758
  )
5731
5759
  );
5732
5760
  }
5761
+ get renditionLayout() {
5762
+ var _a;
5763
+ const itemRenditionLayout = this.item.renditionLayout;
5764
+ if (itemRenditionLayout) return itemRenditionLayout;
5765
+ return ((_a = this.context.manifest) == null ? void 0 : _a.renditionLayout) ?? "reflowable";
5766
+ }
5733
5767
  }
5734
5768
  const createContainerElement = (containerElement, item, hookManager) => {
5735
5769
  const element = containerElement.ownerDocument.createElement(`div`);
@@ -6059,8 +6093,8 @@
6059
6093
  };
6060
6094
  const getSpineItemFromIframe = (iframe) => {
6061
6095
  return spineItemsManager.items.find((item) => {
6062
- var _a;
6063
- return ((_a = item.renderer.layers[0]) == null ? void 0 : _a.element) === iframe;
6096
+ const element = item.renderer.getDocumentFrame();
6097
+ return element === iframe;
6064
6098
  });
6065
6099
  };
6066
6100
  const getSpineItemPageIndexFromNode = (node, offset, spineItemOrIndex) => {
@@ -6196,33 +6230,6 @@
6196
6230
  getSafeSpineItemPositionFromUnsafeSpineItemPosition
6197
6231
  };
6198
6232
  };
6199
- const loadItems = ({
6200
- spineItemsManager,
6201
- settings
6202
- }) => (stream) => stream.pipe(
6203
- rxjs.tap(([beginIndex, endIndex]) => {
6204
- const { numberOfAdjacentSpineItemToPreLoad } = settings.values;
6205
- const leftMaximumIndex = beginIndex - numberOfAdjacentSpineItemToPreLoad;
6206
- const rightMaximumIndex = endIndex + numberOfAdjacentSpineItemToPreLoad;
6207
- spineItemsManager.items.forEach((orderedSpineItem, index) => {
6208
- const isWithinRange = index >= leftMaximumIndex && index <= rightMaximumIndex;
6209
- if (isWithinRange) {
6210
- orderedSpineItem.load();
6211
- } else {
6212
- orderedSpineItem.unload();
6213
- }
6214
- });
6215
- })
6216
- );
6217
- const mapToItemsToLoad = ({ spineLocator }) => (stream) => stream.pipe(
6218
- rxjs.map((position) => {
6219
- const { beginIndex = 0, endIndex = 0 } = spineLocator.getVisibleSpineItemsFromPosition({
6220
- position,
6221
- threshold: 0
6222
- }) || {};
6223
- return [beginIndex, endIndex];
6224
- })
6225
- );
6226
6233
  class SpineItemsLoader extends DestroyableClass {
6227
6234
  constructor(context, spineItemsManager, spineLocator, settings, spineLayout) {
6228
6235
  super();
@@ -6231,34 +6238,62 @@
6231
6238
  this.spineLocator = spineLocator;
6232
6239
  this.settings = settings;
6233
6240
  this.spineLayout = spineLayout;
6234
- const navigationUpdate$ = this.context.bridgeEvent.navigation$;
6235
- const layoutHasChanged$ = this.spineLayout.layout$.pipe(
6236
- rxjs.filter(({ hasChanged }) => hasChanged)
6241
+ this.forcedOpenSubject = new rxjs.BehaviorSubject([]);
6242
+ const forcedOpen$ = this.forcedOpenSubject.pipe(
6243
+ rxjs.map((v) => [...new Set(v.flat())].sort()),
6244
+ rxjs.distinctUntilChanged(shared.arrayEqual),
6245
+ rxjs.shareReplay({ bufferSize: 1, refCount: true })
6237
6246
  );
6238
- const numberOfAdjacentSpineItemToPreLoad$ = settings.values$.pipe(
6239
- rxjs.map(
6240
- ({ numberOfAdjacentSpineItemToPreLoad }) => numberOfAdjacentSpineItemToPreLoad
6241
- ),
6242
- rxjs.skip(1),
6243
- rxjs.distinctUntilChanged()
6247
+ const shouldReloadSpineItems$ = rxjs.merge(
6248
+ this.context.bridgeEvent.navigation$,
6249
+ this.spineLayout.layout$,
6250
+ forcedOpen$,
6251
+ settings.watch(["numberOfAdjacentSpineItemToPreLoad"])
6244
6252
  );
6245
- const loadSpineItems$ = rxjs.merge(
6246
- navigationUpdate$,
6247
- layoutHasChanged$,
6248
- numberOfAdjacentSpineItemToPreLoad$
6249
- ).pipe(
6253
+ const loadSpineItems$ = shouldReloadSpineItems$.pipe(
6250
6254
  // this can be changed by whatever we want and SHOULD not break navigation.
6251
6255
  // Ideally loading faster is better but loading too close to user navigating can
6252
6256
  // be dangerous.
6253
6257
  rxjs.debounceTime(100, rxjs.animationFrameScheduler),
6254
6258
  waitForSwitch(this.context.bridgeEvent.viewportFree$),
6255
- rxjs.withLatestFrom(this.context.bridgeEvent.navigation$),
6256
- rxjs.map(([, navigation]) => navigation.position),
6257
- mapToItemsToLoad({ spineLocator }),
6258
- loadItems({ spineItemsManager, settings })
6259
+ rxjs.withLatestFrom(this.context.bridgeEvent.navigation$, forcedOpen$),
6260
+ rxjs.map(([, navigation, forcedOpenIndexes]) => {
6261
+ const { numberOfAdjacentSpineItemToPreLoad } = settings.values;
6262
+ const { beginIndex = 0, endIndex = 0 } = spineLocator.getVisibleSpineItemsFromPosition({
6263
+ position: navigation.position,
6264
+ threshold: 0
6265
+ }) || {};
6266
+ const beginMaximumIndex = beginIndex - numberOfAdjacentSpineItemToPreLoad;
6267
+ const endMaximumIndex = endIndex + numberOfAdjacentSpineItemToPreLoad;
6268
+ const visibleIndexes = Array.from(
6269
+ { length: endMaximumIndex - beginMaximumIndex + 1 },
6270
+ (_, i) => beginMaximumIndex + i
6271
+ );
6272
+ const indexesToLoad = [...forcedOpenIndexes, ...visibleIndexes];
6273
+ spineItemsManager.items.forEach((orderedSpineItem, index) => {
6274
+ if (indexesToLoad.includes(index)) {
6275
+ orderedSpineItem.load();
6276
+ } else {
6277
+ orderedSpineItem.unload();
6278
+ }
6279
+ });
6280
+ })
6259
6281
  );
6260
6282
  loadSpineItems$.pipe(rxjs.takeUntil(this.destroy$)).subscribe();
6261
6283
  }
6284
+ forceOpen(spineItems) {
6285
+ this.forcedOpenSubject.next([...this.forcedOpenSubject.value, spineItems]);
6286
+ return () => {
6287
+ if (this.isDestroyed) return;
6288
+ this.forcedOpenSubject.next(
6289
+ this.forcedOpenSubject.value.filter((item) => item !== spineItems)
6290
+ );
6291
+ };
6292
+ }
6293
+ destroy() {
6294
+ super.destroy();
6295
+ this.forcedOpenSubject.complete();
6296
+ }
6262
6297
  }
6263
6298
  class SpineItemsObserver extends DestroyableClass {
6264
6299
  constructor(spineItemsManager, spineLocator) {
@@ -6326,10 +6361,10 @@
6326
6361
  const itemStartOnNewScreen = horizontalOffset % context.state.visibleAreaRect.width === 0;
6327
6362
  const isLastItem = index === spineItemsManager.items.length - 1;
6328
6363
  if (context.state.isUsingSpreadMode) {
6329
- if (!isGloballyPrePaginated && item.item.renditionLayout === `reflowable` && !isLastItem) {
6364
+ if (!isGloballyPrePaginated && item.renditionLayout === `reflowable` && !isLastItem) {
6330
6365
  minimumWidth = context.getPageSize().width * 2;
6331
6366
  }
6332
- if (!isGloballyPrePaginated && item.item.renditionLayout === `reflowable` && isLastItem && itemStartOnNewScreen) {
6367
+ if (!isGloballyPrePaginated && item.renditionLayout === `reflowable` && isLastItem && itemStartOnNewScreen) {
6333
6368
  minimumWidth = context.getPageSize().width * 2;
6334
6369
  }
6335
6370
  const lastItemStartOnNewScreenInAPrepaginatedBook = itemStartOnNewScreen && isLastItem && isGloballyPrePaginated;
@@ -7162,6 +7197,9 @@
7162
7197
  onRenderHeadless() {
7163
7198
  return rxjs.EMPTY;
7164
7199
  }
7200
+ getDocumentFrame() {
7201
+ return void 0;
7202
+ }
7165
7203
  }
7166
7204
  const mediaEnhancer = (next) => (options) => {
7167
7205
  const reader = next({
@@ -7227,10 +7265,10 @@
7227
7265
  );
7228
7266
  reader.hookManager.register(
7229
7267
  `item.onDocumentLoad`,
7230
- ({ layers, destroy: destroy2 }) => {
7268
+ ({ destroy: destroy2, itemId }) => {
7231
7269
  var _a, _b;
7232
- const frame = (_a = layers[0]) == null ? void 0 : _a.element;
7233
- if (!(frame instanceof HTMLIFrameElement)) return;
7270
+ const frame = (_a = reader.spineItemsManager.get(itemId)) == null ? void 0 : _a.renderer.getDocumentFrame();
7271
+ if (!frame) return;
7234
7272
  frameObserver.observe(frame);
7235
7273
  const videos = (_b = frame.contentDocument) == null ? void 0 : _b.body.getElementsByTagName(`video`);
7236
7274
  const unobserveElements = Array.from(videos || []).map((element) => {
@@ -7265,7 +7303,7 @@
7265
7303
  const estimateBeforeThisItem = ((_c = context.manifest) == null ? void 0 : _c.spineItems.slice(0, currentSpineIndex).reduce((acc, item) => acc + (item.progressionWeight ?? 0), 0)) || 0;
7266
7304
  const currentItemWeight = ((_e = (_d = context.manifest) == null ? void 0 : _d.spineItems[currentSpineIndex]) == null ? void 0 : _e.progressionWeight) || 0;
7267
7305
  let progressWithinThisItem = (pageIndex + 1) * (currentItemWeight / numberOfPages);
7268
- if (!isGloballyPrePaginated && currentItem.item.renditionLayout === `reflowable` && !itemIsReady) {
7306
+ if (!isGloballyPrePaginated && currentItem.renditionLayout === `reflowable` && !itemIsReady) {
7269
7307
  progressWithinThisItem = 0;
7270
7308
  }
7271
7309
  let totalProgress = estimateBeforeThisItem + progressWithinThisItem;
@@ -7337,31 +7375,27 @@
7337
7375
  }, {});
7338
7376
  reader.hookManager.register(
7339
7377
  `item.onDocumentLoad`,
7340
- ({ itemId, layers, destroy }) => {
7341
- var _a, _b;
7342
- const frame = (_a = layers[0]) == null ? void 0 : _a.element;
7343
- if (!(frame instanceof HTMLIFrameElement)) return;
7378
+ ({ itemId, destroy }) => {
7379
+ var _a;
7344
7380
  const item = reader.spineItemsManager.get(itemId);
7345
7381
  if (!item) return;
7346
- item.renderer.layers.forEach((layer) => {
7347
- if (layer.element instanceof HTMLIFrameElement) {
7348
- upsertCSS(
7349
- layer.element,
7350
- `prose-reader-accessibility`,
7351
- `
7382
+ const frame = item.renderer.getDocumentFrame();
7383
+ if (!frame) return;
7384
+ upsertCSS(
7385
+ frame,
7386
+ `prose-reader-accessibility`,
7387
+ `
7352
7388
  :focus-visible {
7353
7389
  ${/*
7354
- Some epubs remove the outline, this is not good practice since it reduce accessibility.
7355
- We will try to restore it by force.
7356
- */
7357
- ``}
7390
+ Some epubs remove the outline, this is not good practice since it reduce accessibility.
7391
+ We will try to restore it by force.
7392
+ */
7393
+ ``}
7358
7394
  outline: -webkit-focus-ring-color auto 1px;
7359
7395
  }
7360
7396
  `
7361
- );
7362
- }
7363
- });
7364
- const links = (_b = frame.contentDocument) == null ? void 0 : _b.body.querySelectorAll(`a`);
7397
+ );
7398
+ const links = (_a = frame.contentDocument) == null ? void 0 : _a.body.querySelectorAll(`a`);
7365
7399
  links == null ? void 0 : links.forEach((link) => {
7366
7400
  observer.observe(link);
7367
7401
  });
@@ -7527,11 +7561,11 @@
7527
7561
  };
7528
7562
  };
7529
7563
  const normalizeEventForViewport = (event, iframeOriginalEvent, locator, context) => {
7530
- var _a, _b;
7564
+ var _a;
7531
7565
  const originalFrame = (_a = iframeOriginalEvent == null ? void 0 : iframeOriginalEvent.view) == null ? void 0 : _a.frameElement;
7532
7566
  if (!iframeOriginalEvent || !originalFrame) return event;
7533
7567
  const spineItem = locator.getSpineItemFromIframe(originalFrame);
7534
- const frameElement = (_b = spineItem == null ? void 0 : spineItem.renderer.layers[0]) == null ? void 0 : _b.element;
7568
+ const frameElement = originalFrame;
7535
7569
  const { height: pageHeight, width: pageWidth } = context.getPageSize();
7536
7570
  if (!spineItem || !(frameElement instanceof HTMLIFrameElement)) return event;
7537
7571
  if (isPointerEvent(event)) {
@@ -7617,18 +7651,14 @@
7617
7651
  const reader = next(options);
7618
7652
  reader.hookManager.register(
7619
7653
  `item.onDocumentLoad`,
7620
- ({ destroy, layers, itemId }) => {
7621
- var _a;
7622
- const frame = (_a = layers.find(
7623
- (layer) => layer.element instanceof HTMLIFrameElement
7624
- )) == null ? void 0 : _a.element;
7625
- if (!(frame instanceof HTMLIFrameElement)) return;
7654
+ ({ destroy, itemId }) => {
7626
7655
  const item = reader.spineItemsManager.get(itemId);
7627
- if (!item) return;
7656
+ const frame = item == null ? void 0 : item.renderer.getDocumentFrame();
7657
+ if (!frame || !item) return;
7628
7658
  const unregister = passthroughEvents.map((event) => {
7629
- var _a2;
7659
+ var _a;
7630
7660
  const listener = (e) => {
7631
- var _a3;
7661
+ var _a2;
7632
7662
  let convertedEvent = e;
7633
7663
  if (isPointerEvent(e)) {
7634
7664
  convertedEvent = new PointerEvent(e.type, e);
@@ -7640,15 +7670,15 @@
7640
7670
  reader.spine.locator,
7641
7671
  reader.context
7642
7672
  );
7643
- (_a3 = reader.context.state.containerElement) == null ? void 0 : _a3.dispatchEvent(
7673
+ (_a2 = reader.context.state.containerElement) == null ? void 0 : _a2.dispatchEvent(
7644
7674
  normalizedEvent
7645
7675
  );
7646
7676
  }
7647
7677
  };
7648
- (_a2 = frame.contentDocument) == null ? void 0 : _a2.addEventListener(event, listener);
7678
+ (_a = frame.contentDocument) == null ? void 0 : _a.addEventListener(event, listener);
7649
7679
  return () => {
7650
- var _a3;
7651
- (_a3 = frame.contentDocument) == null ? void 0 : _a3.removeEventListener(event, listener);
7680
+ var _a2;
7681
+ (_a2 = frame.contentDocument) == null ? void 0 : _a2.removeEventListener(event, listener);
7652
7682
  };
7653
7683
  });
7654
7684
  destroy(() => {
@@ -7702,7 +7732,7 @@
7702
7732
  return `
7703
7733
  <html>
7704
7734
  <head>
7705
- ${item.renditionLayout !== `reflowable` ? `<meta name="viewport" content="width=${width}, height=${height}">` : ``}
7735
+ ${item.renditionLayout === `pre-paginated` ? `<meta name="viewport" content="width=${width}, height=${height}">` : ``}
7706
7736
  </head>
7707
7737
  <body style="margin: 0px;" tab-index="-1;">
7708
7738
  <img
@@ -8102,8 +8132,8 @@
8102
8132
  ``}
8103
8133
  img, video, audio, object, svg {
8104
8134
  max-width: 100%;
8105
- max-width: ${columnWidth}px !important;
8106
- max-height: ${columnHeight}px !important;
8135
+ -max-width: ${columnWidth}px !important;
8136
+ -max-height: ${columnHeight}px !important;
8107
8137
  -pointer-events: none;
8108
8138
  -webkit-column-break-inside: avoid;
8109
8139
  page-break-inside: avoid;
@@ -8383,12 +8413,12 @@
8383
8413
  blankPagePosition,
8384
8414
  spreadPosition
8385
8415
  }) {
8386
- var _a;
8416
+ var _a, _b;
8387
8417
  const { width: pageWidth, height: pageHeight } = this.context.getPageSize();
8388
8418
  const frameElement = this.getFrameElement();
8389
- if (!frameElement) return rxjs.of({ width: pageWidth, height: pageHeight });
8419
+ if (!frameElement) return rxjs.of(void 0);
8390
8420
  const isUsingVerticalWriting = !!((_a = this.writingMode) == null ? void 0 : _a.startsWith(`vertical`));
8391
- if (this.item.renditionLayout === `pre-paginated`) {
8421
+ if (this.item.renditionLayout === `pre-paginated` || !this.item.renditionLayout && ((_b = this.context.manifest) == null ? void 0 : _b.renditionLayout) === `pre-paginated`) {
8392
8422
  const dims = renderPrePaginated({
8393
8423
  blankPagePosition,
8394
8424
  enableTouch: this.settings.values.computedPageTurnMode !== `scrollable`,
@@ -8483,6 +8513,9 @@
8483
8513
  return void 0;
8484
8514
  }
8485
8515
  }
8516
+ getDocumentFrame() {
8517
+ return this.getFrameElement();
8518
+ }
8486
8519
  }
8487
8520
  const htmlEnhancer = (next) => (options) => {
8488
8521
  const reader = next({
@@ -8570,12 +8603,13 @@
8570
8603
  const selectionWithPointerUpSubject = new rxjs.Subject();
8571
8604
  reader.hookManager.register(
8572
8605
  `item.onDocumentLoad`,
8573
- ({ itemId, layers, destroy$, destroy }) => {
8574
- var _a, _b;
8575
- const frame = (_a = layers[0]) == null ? void 0 : _a.element;
8606
+ ({ itemId, destroy$, destroy }) => {
8607
+ var _a;
8608
+ const item = reader.spineItemsManager.get(itemId);
8609
+ const frame = item == null ? void 0 : item.renderer.getDocumentFrame();
8576
8610
  const itemIndex = reader.spineItemsManager.getSpineItemIndex(itemId) ?? 0;
8577
- if (frame instanceof HTMLIFrameElement) {
8578
- const frameDoc = frame.contentDocument || ((_b = frame.contentWindow) == null ? void 0 : _b.document);
8611
+ if (frame) {
8612
+ const frameDoc = frame.contentDocument || ((_a = frame.contentWindow) == null ? void 0 : _a.document);
8579
8613
  if (frameDoc) {
8580
8614
  const selectionTracker = new SelectionTracker(frameDoc);
8581
8615
  rxjs.merge(