@prose-reader/core 1.56.0 → 1.58.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.
Files changed (100) hide show
  1. package/dist/cfi.d.ts +74 -0
  2. package/dist/constants.d.ts +6 -0
  3. package/dist/context/Context.d.ts +63 -0
  4. package/dist/context/isUsingSpreadMode.d.ts +10 -0
  5. package/dist/createReaderWithEnhancer.d.ts +271 -0
  6. package/dist/enhancers/accessibility.d.ts +3 -0
  7. package/dist/enhancers/chrome.d.ts +3 -0
  8. package/dist/enhancers/events/createIframeEventBridgeElement.d.ts +1 -0
  9. package/dist/enhancers/events/events.d.ts +8 -0
  10. package/dist/enhancers/events/normalizeEventForViewport.d.ts +7 -0
  11. package/dist/enhancers/firefox.d.ts +3 -0
  12. package/dist/enhancers/fonts.d.ts +19 -0
  13. package/dist/enhancers/hotkeys.d.ts +3 -0
  14. package/dist/enhancers/layoutEnhancer/createMovingSafePan$.d.ts +4 -0
  15. package/dist/enhancers/layoutEnhancer/fixReflowable.d.ts +3 -0
  16. package/dist/enhancers/layoutEnhancer/layoutEnhancer.d.ts +10 -0
  17. package/dist/enhancers/layoutEnhancer/types.d.ts +8 -0
  18. package/dist/enhancers/links.d.ts +14 -0
  19. package/dist/enhancers/loadingEnhancer.d.ts +24 -0
  20. package/dist/enhancers/media.d.ts +3 -0
  21. package/dist/enhancers/navigation/navigation.d.ts +9 -0
  22. package/dist/enhancers/navigation/navigator.d.ts +8 -0
  23. package/dist/enhancers/navigation/state.d.ts +12 -0
  24. package/dist/enhancers/pagination/chapters.d.ts +24 -0
  25. package/dist/enhancers/pagination/constants.d.ts +1 -0
  26. package/dist/enhancers/pagination/enhancer.d.ts +14 -0
  27. package/dist/enhancers/pagination/pagination.d.ts +10 -0
  28. package/dist/enhancers/pagination/spine.d.ts +13 -0
  29. package/dist/enhancers/pagination/types.d.ts +19 -0
  30. package/dist/enhancers/pagination.test.d.ts +1 -0
  31. package/dist/enhancers/progression.d.ts +16 -0
  32. package/dist/enhancers/publicApi.d.ts +5 -0
  33. package/dist/enhancers/resources/index.d.ts +3 -0
  34. package/dist/enhancers/resources/indexedDB.d.ts +6 -0
  35. package/dist/enhancers/resources/resourcesManager.d.ts +7 -0
  36. package/dist/enhancers/theme.d.ts +32 -0
  37. package/dist/enhancers/types/enhancer.d.ts +9 -0
  38. package/dist/enhancers/utils.d.ts +7 -0
  39. package/dist/enhancers/webkit.d.ts +3 -0
  40. package/dist/enhancers/zoom/elementZoomer.d.ts +19 -0
  41. package/dist/enhancers/zoom/index.d.ts +4 -0
  42. package/dist/enhancers/zoom/types.d.ts +23 -0
  43. package/dist/enhancers/zoom/viewportZoomer.d.ts +19 -0
  44. package/dist/frames.d.ts +5 -0
  45. package/dist/hooks/HookManager.d.ts +10 -0
  46. package/dist/hooks/types.d.ts +64 -0
  47. package/dist/index.d.ts +9 -4324
  48. package/dist/index.js +1032 -1107
  49. package/dist/index.js.map +1 -1
  50. package/dist/index.umd.cjs +1032 -1107
  51. package/dist/index.umd.cjs.map +1 -1
  52. package/dist/manifest/areAllItemsPrePaginated.d.ts +3 -0
  53. package/dist/manifest/isFullyPrePaginated.d.ts +3 -0
  54. package/dist/pagination/pagination.d.ts +88 -0
  55. package/dist/pagination/types.d.ts +10 -0
  56. package/dist/reader.d.ts +8 -0
  57. package/dist/report.d.ts +26 -0
  58. package/dist/selection.d.ts +7 -0
  59. package/dist/settings/SettingsManager.d.ts +14 -0
  60. package/dist/settings/defaultSettings.d.ts +3 -0
  61. package/dist/settings/getComputedSettings.d.ts +4 -0
  62. package/dist/settings/types.d.ts +19 -0
  63. package/dist/spine/cfiLocator.d.ts +340 -0
  64. package/dist/spine/createSpine.d.ts +31 -0
  65. package/dist/spine/locationResolver.d.ts +636 -0
  66. package/dist/spine/navigationResolver.d.ts +48 -0
  67. package/dist/spine/types.d.ts +10 -0
  68. package/dist/spineItem/commonSpineItem.d.ts +165 -0
  69. package/dist/spineItem/createSpineItem.d.ts +167 -0
  70. package/dist/spineItem/frameItem/createFrame$.d.ts +1 -0
  71. package/dist/spineItem/frameItem/createFrameManipulator.d.ts +5 -0
  72. package/dist/spineItem/frameItem/createHtmlPageFromResource.d.ts +3 -0
  73. package/dist/spineItem/frameItem/frameItem.d.ts +49 -0
  74. package/dist/spineItem/frameItem/loader.d.ts +30 -0
  75. package/dist/spineItem/locationResolver.d.ts +24 -0
  76. package/dist/spineItem/navigationResolver.d.ts +16 -0
  77. package/dist/spineItem/prePaginatedSpineItem.d.ts +166 -0
  78. package/dist/spineItem/reflowableSpineItem.d.ts +165 -0
  79. package/dist/spineItem/styles/getStyleForViewportDocument.d.ts +1 -0
  80. package/dist/spineItem/trackers.d.ts +34 -0
  81. package/dist/spineItem/types.d.ts +19 -0
  82. package/dist/spineItemManager.d.ts +505 -0
  83. package/dist/types/Spine.d.ts +40 -0
  84. package/dist/types/index.d.ts +12 -0
  85. package/dist/types/reader.d.ts +44 -0
  86. package/dist/utils/compose.d.ts +8 -0
  87. package/dist/utils/dom.d.ts +19 -0
  88. package/dist/utils/isDefined.d.ts +1 -0
  89. package/dist/utils/layout.d.ts +7 -0
  90. package/dist/utils/layout.test.d.ts +1 -0
  91. package/dist/utils/manifest.d.ts +3 -0
  92. package/dist/utils/objects.d.ts +6 -0
  93. package/dist/utils/objects.test.d.ts +1 -0
  94. package/dist/utils/rxjs.d.ts +5 -0
  95. package/dist/viewportNavigator/manualViewportNavigator.d.ts +96 -0
  96. package/dist/viewportNavigator/panViewportNavigator.d.ts +55 -0
  97. package/dist/viewportNavigator/scrollViewportNavigator.d.ts +38 -0
  98. package/dist/viewportNavigator/types.d.ts +34 -0
  99. package/dist/viewportNavigator/viewportNavigator.d.ts +82 -0
  100. package/package.json +3 -3
@@ -4,17 +4,16 @@
4
4
  "use strict";
5
5
  const chromeEnhancer = (next) => (options) => {
6
6
  const reader = next(options);
7
- reader.context$.pipe(rxjs.takeUntil(reader.$.destroy$)).subscribe(({ containerElement }) => {
8
- if (!containerElement)
9
- return;
7
+ reader.context.state$.pipe(rxjs.takeUntil(reader.$.destroy$)).subscribe(({ containerElement }) => {
8
+ if (!containerElement) return;
10
9
  const onScroll = () => {
11
- if (reader.settings.getSettings().computedPageTurnMode === `controlled`) {
10
+ if (reader.settings.settings.computedPageTurnMode === `controlled`) {
12
11
  containerElement.scrollTo(0, 0);
13
12
  }
14
13
  };
15
14
  containerElement.addEventListener(`scroll`, onScroll);
16
15
  });
17
- reader.registerHook(`item.onLoad`, ({ frame }) => {
16
+ reader.hookManager.register(`item.onLoad`, ({ frame }) => {
18
17
  var _a;
19
18
  (_a = frame.contentDocument) == null ? void 0 : _a.body.setAttribute(`tabindex`, `-1`);
20
19
  });
@@ -55,8 +54,7 @@
55
54
  const groupBy = (list, getKey) => list.reduce(
56
55
  (previous, currentItem) => {
57
56
  const group = getKey(currentItem);
58
- if (!previous[group])
59
- previous[group] = [];
57
+ if (!previous[group]) previous[group] = [];
60
58
  previous[group].push(currentItem);
61
59
  return previous;
62
60
  },
@@ -76,7 +74,12 @@
76
74
  });
77
75
  };
78
76
  const fontsEnhancer = (next) => (options) => {
79
- const { fontScale = 1, lineHeight = `publisher`, fontWeight = `publisher`, fontJustification = `publisher` } = options;
77
+ const {
78
+ fontScale = 1,
79
+ lineHeight = `publisher`,
80
+ fontWeight = `publisher`,
81
+ fontJustification = `publisher`
82
+ } = options;
80
83
  const changes$ = new rxjs.Subject();
81
84
  const settings$ = new rxjs.BehaviorSubject({
82
85
  fontScale,
@@ -103,7 +106,7 @@
103
106
  }
104
107
  `;
105
108
  const applyChangeToSpineItem = (requireLayout) => {
106
- reader.manipulateSpineItems(({ removeStyle, addStyle, item }) => {
109
+ reader.spine.manipulateSpineItems(({ removeStyle, addStyle, item }) => {
107
110
  if (item.renditionLayout !== `pre-paginated`) {
108
111
  removeStyle(`prose-reader-fonts`);
109
112
  addStyle(`prose-reader-fonts`, getStyle());
@@ -111,19 +114,21 @@
111
114
  return requireLayout;
112
115
  });
113
116
  };
114
- reader.registerHook(`item.onLoad`, ({ removeStyle, addStyle, item }) => {
115
- if (item.renditionLayout !== `pre-paginated`) {
116
- removeStyle(`prose-reader-fonts`);
117
- addStyle(`prose-reader-fonts`, getStyle());
118
- }
117
+ reader.hookManager.register(`item.onLoad`, ({ itemId }) => {
118
+ const item = reader.spineItemManager.get(itemId);
119
+ item == null ? void 0 : item.manipulateSpineItem(({ addStyle, removeStyle }) => {
120
+ if (item.item.renditionLayout !== `pre-paginated`) {
121
+ removeStyle(`prose-reader-fonts`);
122
+ addStyle(`prose-reader-fonts`, getStyle());
123
+ }
124
+ return false;
125
+ });
119
126
  });
120
127
  const shouldRequireLayout = (source) => source.pipe(
121
128
  operators.pairwise(),
122
129
  rxjs.map(([old, latest]) => {
123
- if (latest.fontScale !== old.fontScale)
124
- return true;
125
- if (latest.lineHeight !== old.lineHeight)
126
- return true;
130
+ if (latest.fontScale !== old.fontScale) return true;
131
+ if (latest.lineHeight !== old.lineHeight) return true;
127
132
  return false;
128
133
  })
129
134
  );
@@ -172,25 +177,25 @@
172
177
  rxjs.map(([e, { pageTurnDirection }]) => {
173
178
  if (pageTurnDirection === "horizontal") {
174
179
  if (e.key === `ArrowRight`) {
175
- reader.turnRight();
180
+ reader.viewportNavigator.turnRight();
176
181
  }
177
182
  if (e.key === `ArrowLeft`) {
178
- reader.turnLeft();
183
+ reader.viewportNavigator.turnLeft();
179
184
  }
180
185
  }
181
186
  if (pageTurnDirection === "vertical") {
182
187
  if (e.key === `ArrowDown`) {
183
- reader.turnRight();
188
+ reader.viewportNavigator.turnRight();
184
189
  }
185
190
  if (e.key === `ArrowUp`) {
186
- reader.turnLeft();
191
+ reader.viewportNavigator.turnLeft();
187
192
  }
188
193
  }
189
194
  return e;
190
195
  })
191
196
  );
192
197
  navigateOnKey(document).pipe(rxjs.takeUntil(reader.$.destroy$)).subscribe();
193
- reader.spineItems$.pipe(
198
+ reader.spine.$.spineItems$.pipe(
194
199
  rxjs.switchMap(
195
200
  (spineItems) => rxjs.merge(
196
201
  ...spineItems.map(
@@ -206,10 +211,9 @@
206
211
  };
207
212
  const createMovingSafePan$ = (reader) => {
208
213
  let iframeOverlayForAnimationsElement;
209
- const updateOverlayElement$ = reader.context$.pipe(
214
+ const updateOverlayElement$ = reader.context.state$.pipe(
210
215
  operators.switchMap(({ containerElement }) => {
211
- if (!containerElement)
212
- return rxjs.NEVER;
216
+ if (!containerElement) return rxjs.NEVER;
213
217
  return new rxjs.Observable(() => {
214
218
  iframeOverlayForAnimationsElement = containerElement.ownerDocument.createElement(`div`);
215
219
  iframeOverlayForAnimationsElement.style.cssText = `
@@ -233,8 +237,8 @@
233
237
  iframeOverlayForAnimationsElement == null ? void 0 : iframeOverlayForAnimationsElement.style.setProperty(`visibility`, `hidden`);
234
238
  })
235
239
  );
236
- const viewportFree$ = reader.$.viewportState$.pipe(operators.filter((data) => data === `free`));
237
- const viewportBusy$ = reader.$.viewportState$.pipe(operators.filter((data) => data === `busy`));
240
+ const viewportFree$ = reader.viewportNavigator.$.state$.pipe(operators.filter((data) => data === `free`));
241
+ const viewportBusy$ = reader.viewportNavigator.$.state$.pipe(operators.filter((data) => data === `busy`));
238
242
  const lockAfterViewportBusy$ = viewportBusy$.pipe(
239
243
  operators.tap(() => {
240
244
  iframeOverlayForAnimationsElement == null ? void 0 : iframeOverlayForAnimationsElement.style.setProperty(`visibility`, `visible`);
@@ -242,7 +246,7 @@
242
246
  );
243
247
  const resetLockViewportFree$ = createResetLock$(viewportFree$).pipe(operators.take(1));
244
248
  const pageTurnMode$ = reader.settings.settings$.pipe(
245
- operators.map(() => reader.settings.getSettings().computedPageTurnMode),
249
+ operators.map(() => reader.settings.settings.computedPageTurnMode),
246
250
  operators.distinctUntilChanged()
247
251
  );
248
252
  const handleViewportLock$ = pageTurnMode$.pipe(
@@ -270,11 +274,10 @@
270
274
  });
271
275
  };
272
276
  const fixReflowable = (reader) => {
273
- reader.registerHook(`item.onAfterLayout`, ({ item, blankPagePosition, minimumWidth }) => {
277
+ reader.hookManager.register(`item.onAfterLayout`, ({ item, blankPagePosition, minimumWidth }) => {
274
278
  var _a;
275
- const spineItem = reader.getSpineItem(item.id);
276
- if (!((spineItem == null ? void 0 : spineItem.item.renditionLayout) === `reflowable`))
277
- return;
279
+ const spineItem = reader.spineItemManager.get(item.id);
280
+ if (!((spineItem == null ? void 0 : spineItem.item.renditionLayout) === `reflowable`)) return;
278
281
  const { viewportDimensions } = (spineItem == null ? void 0 : spineItem.getViewPortInformation()) ?? {};
279
282
  const { width: pageWidth } = reader.context.getPageSize();
280
283
  const frameElement = (_a = spineItem == null ? void 0 : spineItem.spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame;
@@ -298,9 +301,9 @@
298
301
  pageHorizontalMargin,
299
302
  pageVerticalMargin
300
303
  });
301
- reader.registerHook(`onViewportOffsetAdjust`, () => {
304
+ reader.hookManager.register(`onViewportOffsetAdjust`, () => {
302
305
  let hasRedrawn = false;
303
- reader.manipulateSpineItems(({ frame }) => {
306
+ reader.spine.manipulateSpineItems(({ frame }) => {
304
307
  if (!hasRedrawn && frame) {
305
308
  void frame.getBoundingClientRect().left;
306
309
  hasRedrawn = true;
@@ -308,7 +311,7 @@
308
311
  return SHOULD_NOT_LAYOUT;
309
312
  });
310
313
  });
311
- reader.registerHook(`item.onLayoutBeforeMeasurement`, ({ frame, minimumWidth, item, isImageType }) => {
314
+ reader.hookManager.register(`item.onLayoutBeforeMeasurement`, ({ frame, minimumWidth, item, isImageType }) => {
312
315
  var _a, _b;
313
316
  const { pageHorizontalMargin: pageHorizontalMargin2 = 0, pageVerticalMargin: pageVerticalMargin2 = 0 } = settingsSubject$.value;
314
317
  const pageSize = reader.context.getPageSize();
@@ -350,7 +353,7 @@
350
353
  fixReflowable(reader);
351
354
  let observer;
352
355
  if (options.layoutAutoResize === `container`) {
353
- reader.context$.pipe(
356
+ reader.context.state$.pipe(
354
357
  operators.map((state) => state.containerElement),
355
358
  operators.filter(isDefined),
356
359
  operators.distinctUntilChanged(),
@@ -423,20 +426,16 @@
423
426
  log: (...data) => {
424
427
  var _a;
425
428
  if ((_a = getWindow()) == null ? void 0 : _a.__PROSE_READER_DEBUG) {
426
- if (namespace)
427
- console.log(wrap(ROOT_NAMESPACE), wrap(namespace), ...data);
428
- else
429
- console.log(wrap(ROOT_NAMESPACE), ...data);
429
+ if (namespace) console.log(wrap(ROOT_NAMESPACE), wrap(namespace), ...data);
430
+ else console.log(wrap(ROOT_NAMESPACE), ...data);
430
431
  }
431
432
  },
432
433
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
433
434
  warn: (...data) => {
434
435
  var _a;
435
436
  if ((_a = getWindow()) == null ? void 0 : _a.__PROSE_READER_DEBUG) {
436
- if (namespace)
437
- console.warn(wrap(ROOT_NAMESPACE), wrap(namespace), ...data);
438
- else
439
- console.warn(wrap(ROOT_NAMESPACE), ...data);
437
+ if (namespace) console.warn(wrap(ROOT_NAMESPACE), wrap(namespace), ...data);
438
+ else console.warn(wrap(ROOT_NAMESPACE), ...data);
440
439
  }
441
440
  },
442
441
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -459,8 +458,7 @@
459
458
  logMetric: (performanceEntry, targetDuration = 0) => {
460
459
  var _a;
461
460
  if ((_a = getWindow()) == null ? void 0 : _a.__PROSE_READER_DEBUG) {
462
- if (performanceEntry.duration <= targetDuration)
463
- ;
461
+ if (performanceEntry.duration <= targetDuration) ;
464
462
  else {
465
463
  console.warn(
466
464
  `[prose-reader] [metric] `,
@@ -472,8 +470,7 @@
472
470
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
473
471
  measurePerformance: (name, targetDuration = 10, functionToMeasure, { disable } = {}) => {
474
472
  var _a;
475
- if (disable || !((_a = getWindow()) == null ? void 0 : _a.__PROSE_READER_DEBUG))
476
- return functionToMeasure;
473
+ if (disable || !((_a = getWindow()) == null ? void 0 : _a.__PROSE_READER_DEBUG)) return functionToMeasure;
477
474
  return (...args) => {
478
475
  const t0 = performance.now();
479
476
  const response = functionToMeasure(...args);
@@ -499,19 +496,18 @@
499
496
  const subject = new rxjs.Subject();
500
497
  const handleNavigationForClick = (element) => {
501
498
  var _a;
502
- if (!element.href)
503
- return false;
499
+ if (!element.href) return false;
504
500
  const hrefUrl = new URL(element.href);
505
501
  const hrefWithoutAnchor = `${hrefUrl.origin}${hrefUrl.pathname}`;
506
- const hasExistingSpineItem = (_a = reader.context.getManifest()) == null ? void 0 : _a.spineItems.some((item) => item.href === hrefWithoutAnchor);
502
+ const hasExistingSpineItem = (_a = reader.context.manifest) == null ? void 0 : _a.spineItems.some((item) => item.href === hrefWithoutAnchor);
507
503
  if (hasExistingSpineItem) {
508
- reader.goToUrl(hrefUrl);
504
+ reader.viewportNavigator.goToUrl(hrefUrl);
509
505
  return true;
510
506
  }
511
507
  return false;
512
508
  };
513
- reader.registerHook(`item.onLoad`, ({ frame }) => {
514
- if (frame.contentDocument) {
509
+ reader.hookManager.register(`item.onLoad`, ({ frame }) => {
510
+ if (frame == null ? void 0 : frame.contentDocument) {
515
511
  Array.from(frame.contentDocument.querySelectorAll(`a`)).forEach(
516
512
  (element) => element.addEventListener(`click`, (e) => {
517
513
  if (e.target && `style` in e.target && `ELEMENT_NODE` in e.target) {
@@ -535,36 +531,38 @@
535
531
  const createNavigator = (reader) => {
536
532
  const goToNextSpineItem = () => {
537
533
  var _a;
538
- const focusedSpineItemIndex = reader.getFocusedSpineItemIndex() || 0;
539
- const { end = focusedSpineItemIndex } = reader.locator.getSpineItemsFromReadingOrderPosition(reader.getCurrentNavigationPosition()) || {};
540
- const numberOfSpineItems = ((_a = reader.context.getManifest()) == null ? void 0 : _a.spineItems.length) ?? 0;
534
+ const focusedSpineItemIndex = reader.spineItemManager.getFocusedSpineItemIndex() || 0;
535
+ const { end = focusedSpineItemIndex } = reader.spine.locator.getSpineItemsFromReadingOrderPosition(
536
+ reader.viewportNavigator.getCurrentNavigationPosition()
537
+ ) || {};
538
+ const numberOfSpineItems = ((_a = reader.context.manifest) == null ? void 0 : _a.spineItems.length) ?? 0;
541
539
  const nextItem = end + 1;
542
540
  if (nextItem < numberOfSpineItems) {
543
- reader.goToSpineItem(nextItem);
541
+ reader.viewportNavigator.goToSpineItem(nextItem);
544
542
  }
545
543
  };
546
544
  const goToPreviousSpineItem = () => {
547
- const focusedSpineItemIndex = reader.getFocusedSpineItemIndex() || 0;
548
- const { begin = focusedSpineItemIndex } = reader.locator.getSpineItemsFromReadingOrderPosition(reader.getCurrentNavigationPosition()) || {};
545
+ const focusedSpineItemIndex = reader.spineItemManager.getFocusedSpineItemIndex() || 0;
546
+ const { begin = focusedSpineItemIndex } = reader.spine.locator.getSpineItemsFromReadingOrderPosition(
547
+ reader.viewportNavigator.getCurrentNavigationPosition()
548
+ ) || {};
549
549
  const nextItem = begin - 1;
550
550
  if (nextItem >= 0) {
551
- reader.goToSpineItem(nextItem);
551
+ reader.viewportNavigator.goToSpineItem(nextItem);
552
552
  }
553
553
  };
554
554
  return {
555
555
  goToNextSpineItem,
556
556
  goToPreviousSpineItem,
557
557
  goToLeftSpineItem: () => {
558
- if (reader.settings.getSettings().computedPageTurnDirection === "vertical")
559
- return;
558
+ if (reader.settings.settings.computedPageTurnDirection === "vertical") return;
560
559
  if (reader.context.isRTL()) {
561
560
  return goToNextSpineItem();
562
561
  }
563
562
  return goToPreviousSpineItem();
564
563
  },
565
564
  goToRightSpineItem: () => {
566
- if (reader.settings.getSettings().computedPageTurnDirection === "vertical")
567
- return;
565
+ if (reader.settings.settings.computedPageTurnDirection === "vertical") return;
568
566
  if (reader.context.isRTL()) {
569
567
  return goToPreviousSpineItem();
570
568
  }
@@ -574,7 +572,7 @@
574
572
  };
575
573
  const createState = (reader) => {
576
574
  return reader.pagination.paginationInfo$.pipe(
577
- rxjs.withLatestFrom(reader.context.$.manifest$, reader.settings.settings$),
575
+ rxjs.withLatestFrom(reader.context.manifest$, reader.settings.settings$),
578
576
  rxjs.map(([paginationInfo, manifest, { computedPageTurnDirection }]) => {
579
577
  const numberOfSpineItems = (manifest == null ? void 0 : manifest.spineItems.length) ?? 0;
580
578
  const isAtAbsoluteBeginning = paginationInfo.beginSpineItemIndex === 0 && paginationInfo.beginPageIndexInSpineItem === 0;
@@ -614,8 +612,7 @@
614
612
  if (isPossibleTocItemCandidate) {
615
613
  const spineItemIndexOfPossibleCandidate = manifest.spineItems.findIndex((item) => item.href === tocItem2.href);
616
614
  const spineItemIsBeforeThisTocItem = spineItemIndex < spineItemIndexOfPossibleCandidate;
617
- if (spineItemIsBeforeThisTocItem)
618
- return acc;
615
+ if (spineItemIsBeforeThisTocItem) return acc;
619
616
  const info = {
620
617
  title: tocItem2.title,
621
618
  path: tocItem2.path
@@ -638,10 +635,9 @@
638
635
  return buildChaptersInfo(href, ((_a = manifest.nav) == null ? void 0 : _a.toc) ?? [], manifest);
639
636
  };
640
637
  const getChaptersInfo = (reader) => {
641
- const manifest = reader.context.getManifest();
642
- const items = reader.getSpineItems();
643
- if (!manifest)
644
- return {};
638
+ const manifest = reader.context.manifest;
639
+ const items = reader.spineItemManager.getAll();
640
+ if (!manifest) return {};
645
641
  return items.reduce(
646
642
  (acc, { item }) => {
647
643
  return {
@@ -653,7 +649,7 @@
653
649
  );
654
650
  };
655
651
  const trackChapterInfo = (reader) => {
656
- return reader.spineItems$.pipe(
652
+ return reader.spine.$.spineItems$.pipe(
657
653
  rxjs.startWith([]),
658
654
  rxjs.map(() => getChaptersInfo(reader))
659
655
  );
@@ -730,21 +726,19 @@
730
726
  return Math.max(0, Math.min(lastPageOffset, logicalOffset));
731
727
  };
732
728
  const calculateNumberOfPagesForItem = (itemWidth, pageWidth) => {
733
- if ((pageWidth || 0) === 0 || (itemWidth || 0) === 0)
734
- return 1;
729
+ if ((pageWidth || 0) === 0 || (itemWidth || 0) === 0) return 1;
735
730
  return Math.floor(Math.max(1, itemWidth / pageWidth));
736
731
  };
737
732
  const getClosestValidOffsetFromApproximateOffsetInPages = (offset, pageWidth, itemWidth) => {
738
733
  const numberOfPages = calculateNumberOfPagesForItem(itemWidth, pageWidth);
739
734
  const offsetValues = [...Array(numberOfPages)].map((_, i) => i * pageWidth);
740
- if (offset >= numberOfPages * pageWidth)
741
- return offsetValues[offsetValues.length - 1] || 0;
735
+ if (offset >= numberOfPages * pageWidth) return offsetValues[offsetValues.length - 1] || 0;
742
736
  return offsetValues.find((offsetRange) => offset < offsetRange + pageWidth) || 0;
743
737
  };
744
738
  const getSpineItemNumberOfPages = ({ spineItem, reader }) => {
745
739
  const writingMode = spineItem.spineItemFrame.getWritingMode();
746
740
  const { width, height } = spineItem.getElementDimensions();
747
- const settings = reader.settings.getSettings();
741
+ const settings = reader.settings.settings;
748
742
  if (settings.pageTurnDirection === `vertical` && settings.pageTurnMode === `scrollable`) {
749
743
  return 1;
750
744
  }
@@ -753,11 +747,11 @@
753
747
  }
754
748
  return calculateNumberOfPagesForItem(width, reader.context.getPageSize().width);
755
749
  };
756
- const getNumberOfPagesForAllSpineItems = (reader) => reader.getSpineItems().map((item) => {
750
+ const getNumberOfPagesForAllSpineItems = (reader) => reader.spineItemManager.getAll().map((item) => {
757
751
  return getSpineItemNumberOfPages({ spineItem: item, reader });
758
752
  }, 0);
759
753
  const trackTotalPages = (reader) => {
760
- const totalPages$ = reader.$.layout$.pipe(
754
+ const totalPages$ = reader.spine.$.layout$.pipe(
761
755
  rxjs.debounceTime(10, rxjs.animationFrameScheduler),
762
756
  rxjs.withLatestFrom(reader.pagination.paginationInfo$),
763
757
  rxjs.map(() => {
@@ -780,8 +774,8 @@
780
774
  };
781
775
  const mapPaginationInfoToExtendedInfo = (reader) => (paginationInfo, chaptersInfo) => {
782
776
  const context = reader.context;
783
- const beginItem = paginationInfo.beginSpineItemIndex !== void 0 ? reader.getSpineItem(paginationInfo.beginSpineItemIndex) : void 0;
784
- const endItem = paginationInfo.endSpineItemIndex !== void 0 ? reader.getSpineItem(paginationInfo.endSpineItemIndex) : void 0;
777
+ const beginItem = paginationInfo.beginSpineItemIndex !== void 0 ? reader.spineItemManager.get(paginationInfo.beginSpineItemIndex) : void 0;
778
+ const endItem = paginationInfo.endSpineItemIndex !== void 0 ? reader.spineItemManager.get(paginationInfo.endSpineItemIndex) : void 0;
785
779
  return {
786
780
  ...paginationInfo,
787
781
  beginChapterInfo: beginItem ? chaptersInfo[beginItem.item.id] : void 0,
@@ -810,13 +804,13 @@
810
804
  paginationInfo.endSpineItemIndex ?? 0,
811
805
  paginationInfo.endNumberOfPagesInSpineItem,
812
806
  paginationInfo.endPageIndexInSpineItem || 0,
813
- reader.getCurrentViewportPosition(),
807
+ reader.viewportNavigator.getCurrentViewportPosition(),
814
808
  endItem
815
809
  ) : 0,
816
- isUsingSpread: context.isUsingSpreadMode() ?? false
810
+ isUsingSpread: context.state.isUsingSpreadMode ?? false
817
811
  // hasNextChapter: (reader.spine.spineItemIndex || 0) < (manifest.readingOrder.length - 1),
818
812
  // hasPreviousChapter: (reader.spine.spineItemIndex || 0) < (manifest.readingOrder.length - 1),
819
- // numberOfSpineItems: context.getManifest()?.readingOrder.length,
813
+ // numberOfSpineItems: context.manifest?.readingOrder.length,
820
814
  };
821
815
  };
822
816
  const trackPaginationInfo = (reader) => {
@@ -837,7 +831,10 @@
837
831
  })),
838
832
  rxjs.distinctUntilChanged(isShallowEqual)
839
833
  );
840
- const paginationInfo$ = rxjs.combineLatest([extandedBasePagination$, totalPages$]).pipe(
834
+ const paginationInfo$ = rxjs.combineLatest([
835
+ extandedBasePagination$,
836
+ totalPages$
837
+ ]).pipe(
841
838
  rxjs.map(([pageInfo, totalPageInfo]) => ({
842
839
  ...pageInfo,
843
840
  ...totalPageInfo,
@@ -912,18 +909,22 @@
912
909
  };
913
910
  };
914
911
  const applyChangeToSpineItem = () => {
915
- reader.manipulateSpineItems(({ removeStyle, addStyle, container }) => {
912
+ reader.spine.manipulateSpineItems(({ removeStyle, addStyle, container }) => {
916
913
  removeStyle(`prose-reader-theme`);
917
914
  addStyle(`prose-reader-theme`, getStyle());
918
915
  applyChangeToSpineItemElement({ container });
919
916
  return false;
920
917
  });
921
918
  };
922
- reader.registerHook(`item.onLoad`, ({ removeStyle, addStyle }) => {
923
- removeStyle(`prose-reader-theme`);
924
- addStyle(`prose-reader-theme`, getStyle());
919
+ reader.hookManager.register(`item.onLoad`, ({ itemId }) => {
920
+ const item = reader.spineItemManager.get(itemId);
921
+ item == null ? void 0 : item.manipulateSpineItem(({ removeStyle, addStyle }) => {
922
+ removeStyle(`prose-reader-theme`);
923
+ addStyle(`prose-reader-theme`, getStyle());
924
+ return false;
925
+ });
925
926
  });
926
- reader.spineItems$.pipe(
927
+ reader.spine.$.spineItems$.pipe(
927
928
  operators.tap((items) => items.map(({ element }) => applyChangeToSpineItemElement({ container: element }))),
928
929
  operators.takeUntil(reader.$.destroy$)
929
930
  ).subscribe();
@@ -960,7 +961,7 @@
960
961
  imgLastPosition = { x: 0, y: 0 };
961
962
  baseScale = 1;
962
963
  lastUserScale = 1;
963
- const container = reader.context.getState().containerElement;
964
+ const container = reader.context.state.containerElement;
964
965
  if (container) {
965
966
  imageMagnifierContainer = container.ownerDocument.createElement(`div`);
966
967
  imageMagnifierContainer.style.cssText = `
@@ -1018,6 +1019,7 @@
1018
1019
  `transform`,
1019
1020
  `translate3d(${imgLastPosition.x}px, ${imgLastPosition.y}px, 0px) scale3d(${baseScale}, ${baseScale}, 1)`
1020
1021
  );
1022
+ console.log({ delta, imgLastPosition });
1021
1023
  movingLastDelta = delta;
1022
1024
  }
1023
1025
  if (isLast) {
@@ -1085,8 +1087,7 @@
1085
1087
  const scale = (userScale) => {
1086
1088
  const spineElement = reader.spine.getElement();
1087
1089
  const viewportElement = reader.viewportNavigator.getElement();
1088
- if (!spineElement || !viewportElement)
1089
- return;
1090
+ if (!spineElement || !viewportElement) return;
1090
1091
  const roundedScale = Math.ceil((userScale < 1 ? baseScale - (1 - userScale) : baseScale + (userScale - 1)) * 100) / 100;
1091
1092
  const newScale = Math.max(roundedScale, 1);
1092
1093
  const currentScale = spineElement.getBoundingClientRect().width / spineElement.offsetWidth;
@@ -1135,7 +1136,7 @@
1135
1136
  const elementZoomer = createElementZoomer(reader);
1136
1137
  const viewportZoomer = createViewportZoomer(reader);
1137
1138
  const currentZoomerSubject$ = new rxjs.BehaviorSubject(void 0);
1138
- const isUsingScrollableViewport = () => reader.settings.getSettings().computedPageTurnMode === `scrollable`;
1139
+ const isUsingScrollableViewport = () => reader.settings.settings.computedPageTurnMode === `scrollable`;
1139
1140
  const enter = (imgElement) => {
1140
1141
  var _a;
1141
1142
  (_a = currentZoomerSubject$ == null ? void 0 : currentZoomerSubject$.value) == null ? void 0 : _a.exit();
@@ -1208,153 +1209,108 @@
1208
1209
  }) => {
1209
1210
  const { height, width } = visibleAreaRect;
1210
1211
  const isLandscape = width > height;
1211
- if (forceSinglePageMode)
1212
- return false;
1213
- if ((manifest == null ? void 0 : manifest.renditionFlow) === `scrolled-continuous`)
1214
- return false;
1212
+ if (forceSinglePageMode) return false;
1213
+ if ((manifest == null ? void 0 : manifest.renditionFlow) === `scrolled-continuous`) return false;
1215
1214
  if (!isLandscape && (manifest == null ? void 0 : manifest.renditionSpread) === `portrait`) {
1216
1215
  return true;
1217
1216
  }
1218
1217
  return isLandscape && ((manifest == null ? void 0 : manifest.renditionSpread) === void 0 || (manifest == null ? void 0 : manifest.renditionSpread) === `auto` || (manifest == null ? void 0 : manifest.renditionSpread) === `landscape` || (manifest == null ? void 0 : manifest.renditionSpread) === `both`);
1219
1218
  };
1220
1219
  const isFullyPrePaginated = (manifest) => (manifest == null ? void 0 : manifest.renditionLayout) === "pre-paginated" || (manifest == null ? void 0 : manifest.spineItems.every((item) => item.renditionLayout === "pre-paginated"));
1221
- const createContext = (settings) => {
1222
- const stateSubject = new rxjs.BehaviorSubject({});
1223
- const manifest$ = stateSubject.pipe(
1224
- operators.map((state) => state.manifest),
1225
- operators.filter(isDefined),
1226
- operators.distinctUntilChanged()
1227
- );
1228
- const containerElement$ = stateSubject.pipe(
1229
- operators.map((state) => state.containerElement),
1230
- operators.filter(isDefined),
1231
- operators.distinctUntilChanged()
1232
- );
1233
- const hasVerticalWriting$ = stateSubject.pipe(
1234
- operators.map((state) => state.hasVerticalWriting),
1235
- operators.filter(isDefined),
1236
- operators.distinctUntilChanged()
1237
- );
1238
- const isUsingSpreadMode$ = stateSubject.pipe(
1239
- operators.map((state) => state.isUsingSpreadMode),
1240
- operators.distinctUntilChanged()
1241
- );
1242
- const visibleAreaRect = {
1243
- width: 0,
1244
- height: 0,
1245
- x: 0,
1246
- y: 0
1247
- };
1248
- const marginTop = 0;
1249
- const marginBottom = 0;
1250
- const destroy$ = new rxjs.Subject();
1251
- const setState = (newState) => {
1252
- const newCompleteState = { ...stateSubject.getValue(), ...newState };
1253
- if (!isShallowEqual(newCompleteState, stateSubject.getValue())) {
1254
- stateSubject.next(newCompleteState);
1255
- }
1256
- };
1257
- const load = (newManifest, newLoadOptions) => {
1258
- setState({
1259
- manifest: newManifest,
1260
- ...newLoadOptions,
1261
- isFullyPrePaginated: isFullyPrePaginated(newManifest),
1220
+ const areAllItemsPrePaginated = (manifest) => !(manifest == null ? void 0 : manifest.spineItems.some((item) => item.renditionLayout === `reflowable`));
1221
+ class Context {
1222
+ constructor() {
1223
+ this._stateSubject = new rxjs.BehaviorSubject({
1224
+ marginBottom: 0,
1225
+ marginTop: 0,
1226
+ calculatedInnerMargin: 0,
1227
+ visibleAreaRect: {
1228
+ width: 0,
1229
+ height: 0,
1230
+ x: 0,
1231
+ y: 0
1232
+ }
1233
+ });
1234
+ this.destroy$ = new rxjs.Subject();
1235
+ this.state$ = this._stateSubject.pipe(operators.distinctUntilChanged(isShallowEqual));
1236
+ this.manifest$ = this._stateSubject.pipe(
1237
+ operators.map((state) => state.manifest),
1238
+ operators.filter(isDefined),
1239
+ operators.distinctUntilChanged()
1240
+ );
1241
+ this.containerElement$ = this._stateSubject.pipe(
1242
+ operators.map((state) => state.containerElement),
1243
+ operators.filter(isDefined),
1244
+ operators.distinctUntilChanged()
1245
+ );
1246
+ this.hasVerticalWriting$ = this._stateSubject.pipe(
1247
+ operators.map((state) => state.hasVerticalWriting),
1248
+ operators.filter(isDefined),
1249
+ operators.distinctUntilChanged()
1250
+ );
1251
+ this.isUsingSpreadMode$ = this._stateSubject.pipe(
1252
+ operators.map((state) => state.isUsingSpreadMode),
1253
+ operators.distinctUntilChanged()
1254
+ );
1255
+ this.isRTL = () => {
1256
+ var _a;
1257
+ return ((_a = this._stateSubject.getValue().manifest) == null ? void 0 : _a.readingDirection) === `rtl`;
1258
+ };
1259
+ this.destroy = () => {
1260
+ this._stateSubject.complete();
1261
+ this.destroy$.next();
1262
+ this.destroy$.complete();
1263
+ };
1264
+ }
1265
+ /**
1266
+ * @todo optimize to not run if not necessary
1267
+ */
1268
+ update(newState) {
1269
+ const previousState = this._stateSubject.getValue();
1270
+ const manifest = newState.manifest ?? previousState.manifest;
1271
+ const forceSinglePageMode = newState.forceSinglePageMode ?? previousState.forceSinglePageMode;
1272
+ const visibleAreaRect = newState.visibleAreaRect ?? previousState.visibleAreaRect;
1273
+ const marginTop = newState.marginTop ?? previousState.marginTop;
1274
+ const marginBottom = newState.marginBottom ?? previousState.marginBottom;
1275
+ const newCompleteState = {
1276
+ ...previousState,
1277
+ ...newState,
1278
+ ...newState.visibleAreaRect && {
1279
+ ...newState.visibleAreaRect,
1280
+ height: newState.visibleAreaRect.height - marginTop - marginBottom
1281
+ },
1282
+ ...newState.manifest && {
1283
+ areAllItemsPrePaginated: areAllItemsPrePaginated(manifest),
1284
+ isFullyPrePaginated: isFullyPrePaginated(manifest)
1285
+ },
1262
1286
  isUsingSpreadMode: isUsingSpreadMode({
1263
- manifest: newManifest,
1287
+ manifest,
1264
1288
  visibleAreaRect,
1265
- forceSinglePageMode: settings.getSettings().forceSinglePageMode
1289
+ forceSinglePageMode
1266
1290
  })
1267
- });
1268
- };
1269
- const isRTL = () => {
1270
- var _a;
1271
- return ((_a = stateSubject.getValue().manifest) == null ? void 0 : _a.readingDirection) === `rtl`;
1272
- };
1273
- const setHasVerticalWriting = (value) => setState({
1274
- hasVerticalWriting: value
1275
- });
1276
- const recomputeSettings$ = rxjs.merge(hasVerticalWriting$, manifest$);
1277
- recomputeSettings$.pipe(
1278
- operators.withLatestFrom(hasVerticalWriting$, manifest$),
1279
- operators.tap(([, hasVerticalWriting, manifest]) => {
1280
- settings.recompute({ hasVerticalWriting, manifest });
1281
- }),
1282
- operators.takeUntil(destroy$)
1283
- ).subscribe();
1284
- settings.$.settings$.pipe(
1285
- operators.map(({ forceSinglePageMode }) => forceSinglePageMode),
1286
- operators.distinctUntilChanged(),
1287
- operators.withLatestFrom(manifest$),
1288
- operators.tap(([forceSinglePageMode, manifest]) => {
1289
- setState({
1290
- isUsingSpreadMode: isUsingSpreadMode({
1291
- manifest,
1292
- visibleAreaRect,
1293
- forceSinglePageMode
1294
- })
1295
- });
1296
- }),
1297
- operators.takeUntil(destroy$)
1298
- ).subscribe();
1299
- const destroy = () => {
1300
- stateSubject.complete();
1301
- destroy$.next();
1302
- destroy$.complete();
1303
- };
1304
- return {
1305
- load,
1306
- isRTL,
1307
- areAllItemsPrePaginated: () => {
1308
- var _a;
1309
- return areAllItemsPrePaginated$1((_a = stateSubject.getValue()) == null ? void 0 : _a.manifest);
1310
- },
1311
- destroy,
1312
- getCalculatedInnerMargin: () => 0,
1313
- getVisibleAreaRect: () => visibleAreaRect,
1314
- isUsingSpreadMode: () => stateSubject.getValue().isUsingSpreadMode,
1315
- setHasVerticalWriting,
1316
- setVisibleAreaRect: ({ height, width, x, y }) => {
1317
- visibleAreaRect.width = width;
1318
- visibleAreaRect.height = height - marginTop - marginBottom;
1319
- visibleAreaRect.x = x;
1320
- visibleAreaRect.y = y;
1321
- const manifest = stateSubject.getValue().manifest;
1322
- if (manifest) {
1323
- setState({
1324
- isUsingSpreadMode: isUsingSpreadMode({
1325
- manifest,
1326
- visibleAreaRect,
1327
- forceSinglePageMode: settings.getSettings().forceSinglePageMode
1328
- })
1329
- });
1330
- }
1331
- },
1332
- getState: () => stateSubject.getValue(),
1333
- getManifest: () => {
1334
- var _a;
1335
- return (_a = stateSubject.getValue()) == null ? void 0 : _a.manifest;
1336
- },
1337
- getReadingDirection: () => {
1338
- var _a, _b;
1339
- return (_b = (_a = stateSubject.getValue()) == null ? void 0 : _a.manifest) == null ? void 0 : _b.readingDirection;
1340
- },
1341
- getPageSize: () => {
1342
- return {
1343
- width: stateSubject.getValue().isUsingSpreadMode ? visibleAreaRect.width / 2 : visibleAreaRect.width,
1344
- height: visibleAreaRect.height
1345
- };
1346
- },
1347
- containerElement$,
1348
- isUsingSpreadMode$,
1349
- hasVerticalWriting$,
1350
- $: {
1351
- manifest$,
1352
- destroy$: destroy$.asObservable(),
1353
- state$: stateSubject.asObservable()
1291
+ };
1292
+ if (!isShallowEqual(newCompleteState, previousState)) {
1293
+ this._stateSubject.next(newCompleteState);
1354
1294
  }
1355
- };
1356
- };
1357
- const areAllItemsPrePaginated$1 = (manifest) => !(manifest == null ? void 0 : manifest.spineItems.some((item) => item.renditionLayout === `reflowable`));
1295
+ }
1296
+ get state() {
1297
+ return this._stateSubject.getValue();
1298
+ }
1299
+ get manifest() {
1300
+ return this.state.manifest;
1301
+ }
1302
+ get readingDirection() {
1303
+ var _a;
1304
+ return (_a = this.manifest) == null ? void 0 : _a.readingDirection;
1305
+ }
1306
+ getPageSize() {
1307
+ const { isUsingSpreadMode: isUsingSpreadMode2, visibleAreaRect } = this._stateSubject.getValue();
1308
+ return {
1309
+ width: isUsingSpreadMode2 ? visibleAreaRect.width / 2 : visibleAreaRect.width,
1310
+ height: visibleAreaRect.height
1311
+ };
1312
+ }
1313
+ }
1358
1314
  const __UNSAFE_REFERENCE_ORIGINAL_IFRAME_EVENT_KEY = `__UNSAFE_REFERENCE_ORIGINAL_IFRAME_EVENT`;
1359
1315
  const ITEM_EXTENSION_VALID_FOR_FRAME_SRC = [`.xhtml`, `.html`, `.htm`];
1360
1316
  const HTML_PREFIX$1 = `prose-reader`;
@@ -1407,11 +1363,6 @@
1407
1363
  `;
1408
1364
  return rxjs.of(frame);
1409
1365
  });
1410
- const createFrameManipulator = (frameElement) => ({
1411
- frame: frameElement,
1412
- removeStyle: createRemoveStyleHelper(frameElement),
1413
- addStyle: createAddStyleHelper(frameElement)
1414
- });
1415
1366
  const getIntrinsicDimensionsFromBase64Img = (data) => new Promise((resolve, reject) => {
1416
1367
  const image = new Image();
1417
1368
  image.src = data;
@@ -1421,8 +1372,7 @@
1421
1372
  image.onerror = reject;
1422
1373
  });
1423
1374
  const createHtmlPageFromResource = async (resourceResponse, item) => {
1424
- if (typeof resourceResponse === `string`)
1425
- return resourceResponse;
1375
+ if (typeof resourceResponse === `string`) return resourceResponse;
1426
1376
  const contentType = shared.parseContentType(resourceResponse.headers.get(`Content-Type`) || ``) || shared.detectMimeTypeFromName(item.href);
1427
1377
  if ([`image/jpg`, `image/jpeg`, `image/png`, `image/webp`].some((mime) => mime === contentType)) {
1428
1378
  const data = await getBase64FromBlob(await resourceResponse.blob());
@@ -1464,15 +1414,14 @@
1464
1414
  const content = await resourceResponse.text();
1465
1415
  return content;
1466
1416
  };
1467
- const isOnLoadHook = (hook) => hook.name === `item.onLoad`;
1468
1417
  const createLoader = ({
1469
1418
  item,
1470
1419
  parent,
1471
1420
  fetchResource,
1472
- hooks$,
1473
1421
  context,
1474
1422
  viewportState$,
1475
- settings
1423
+ settings,
1424
+ hookManager
1476
1425
  }) => {
1477
1426
  const destroySubject$ = new rxjs.Subject();
1478
1427
  const loadSubject$ = new rxjs.Subject();
@@ -1480,10 +1429,9 @@
1480
1429
  const frameElementSubject$ = new rxjs.BehaviorSubject(void 0);
1481
1430
  const isLoadedSubject$ = new rxjs.BehaviorSubject(false);
1482
1431
  const isReadySubject$ = new rxjs.BehaviorSubject(false);
1483
- let onLoadHookReturns = [];
1484
1432
  let computedStyleAfterLoad;
1485
1433
  const makeItHot = (source$) => {
1486
- source$.pipe(operators.takeUntil(context.$.destroy$)).subscribe();
1434
+ source$.pipe(operators.takeUntil(context.destroy$)).subscribe();
1487
1435
  return source$;
1488
1436
  };
1489
1437
  const getHtmlFromResource = (response) => createHtmlPageFromResource(response, item);
@@ -1497,14 +1445,7 @@
1497
1445
  operators.withLatestFrom(frameElementSubject$),
1498
1446
  operators.filter(([_, frame]) => !!frame),
1499
1447
  operators.map(([, frame]) => {
1500
- onLoadHookReturns.forEach((fn) => {
1501
- if (fn && `unsubscribe` in fn) {
1502
- fn.unsubscribe();
1503
- } else if (fn) {
1504
- fn();
1505
- }
1506
- });
1507
- onLoadHookReturns = [];
1448
+ hookManager.destroy(`item.onLoad`, item.id);
1508
1449
  frame == null ? void 0 : frame.remove();
1509
1450
  frameElementSubject$.next(void 0);
1510
1451
  }),
@@ -1545,12 +1486,10 @@
1545
1486
  }
1546
1487
  }),
1547
1488
  operators.mergeMap((frame) => {
1548
- if (!frame)
1549
- return rxjs.EMPTY;
1489
+ if (!frame) return rxjs.EMPTY;
1550
1490
  return rxjs.fromEvent(frame, `load`).pipe(
1551
1491
  operators.take(1),
1552
- operators.withLatestFrom(hooks$),
1553
- operators.mergeMap(([_, hooks]) => {
1492
+ operators.mergeMap(() => {
1554
1493
  var _a, _b;
1555
1494
  const body = (_a = frame.contentDocument) == null ? void 0 : _a.body;
1556
1495
  if (!body) {
@@ -1561,21 +1500,14 @@
1561
1500
  if ((frame == null ? void 0 : frame.contentDocument) && body) {
1562
1501
  computedStyleAfterLoad = (_b = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _b.getComputedStyle(body);
1563
1502
  }
1564
- if (settings.getSettings().computedPageTurnMode !== `scrollable`) {
1503
+ if (settings.settings.computedPageTurnMode !== `scrollable`) {
1565
1504
  frame.setAttribute(`tab-index`, `0`);
1566
1505
  }
1567
- const manipulableFrame = createFrameManipulator(frame);
1568
- onLoadHookReturns = hooks.filter(isOnLoadHook).map((hook) => {
1569
- const hookReturn = hook.fn({
1570
- ...manipulableFrame,
1571
- item
1572
- });
1573
- if (hookReturn && `subscribe` in hookReturn) {
1574
- return hookReturn.subscribe();
1575
- }
1576
- return hookReturn;
1577
- });
1578
- return rxjs.of(frame);
1506
+ const hookResults = hookManager.execute(`item.onLoad`, item.id, {
1507
+ itemId: item.id,
1508
+ frame
1509
+ }).filter((result) => result instanceof rxjs.Observable);
1510
+ return rxjs.combineLatest([rxjs.of(null), ...hookResults]).pipe(operators.map(() => frame));
1579
1511
  })
1580
1512
  );
1581
1513
  }),
@@ -1624,14 +1556,19 @@
1624
1556
  }
1625
1557
  };
1626
1558
  };
1559
+ const createFrameManipulator = (frameElement) => ({
1560
+ frame: frameElement,
1561
+ removeStyle: createRemoveStyleHelper(frameElement),
1562
+ addStyle: createAddStyleHelper(frameElement)
1563
+ });
1627
1564
  const createFrameItem = ({
1628
1565
  item,
1629
1566
  parent,
1630
1567
  fetchResource,
1631
1568
  context,
1632
- hooks$,
1633
1569
  viewportState$,
1634
- settings
1570
+ settings,
1571
+ hookManager
1635
1572
  }) => {
1636
1573
  const destroySubject$ = new rxjs.Subject();
1637
1574
  const {
@@ -1640,7 +1577,7 @@
1640
1577
  unload,
1641
1578
  destroy: loaderDestroy,
1642
1579
  getComputedStyleAfterLoad
1643
- } = createLoader({ context, hooks$, item, parent, fetchResource, viewportState$, settings });
1580
+ } = createLoader({ context, hookManager, item, parent, fetchResource, viewportState$, settings });
1644
1581
  let isLoadedSync = false;
1645
1582
  let isReadySync = false;
1646
1583
  isLoaded$.subscribe({
@@ -1728,7 +1665,7 @@
1728
1665
  if (frame) {
1729
1666
  frame.style.width = `${size.width}px`;
1730
1667
  frame.style.height = `${size.height}px`;
1731
- if (settings.getSettings().computedPageTurnMode !== `scrollable`) {
1668
+ if (settings.settings.computedPageTurnMode !== `scrollable`) {
1732
1669
  frame.setAttribute(`tab-index`, `0`);
1733
1670
  }
1734
1671
  }
@@ -1743,8 +1680,7 @@
1743
1680
  return `rtl`;
1744
1681
  }
1745
1682
  const direction = (_a = getComputedStyleAfterLoad()) == null ? void 0 : _a.direction;
1746
- if ([`ltr`, `rtl`].includes(direction || ``))
1747
- return direction;
1683
+ if ([`ltr`, `rtl`].includes(direction || ``)) return direction;
1748
1684
  return void 0;
1749
1685
  },
1750
1686
  isUsingVerticalWriting,
@@ -1831,205 +1767,30 @@
1831
1767
  getSelection: () => {
1832
1768
  var _a;
1833
1769
  const selection = (_a = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _a.getSelection();
1834
- if (!(selection == null ? void 0 : selection.anchorNode) || selection.type === `None` || selection.type === `Caret`)
1835
- return void 0;
1770
+ if (!(selection == null ? void 0 : selection.anchorNode) || selection.type === `None` || selection.type === `Caret`) return void 0;
1836
1771
  return selection;
1837
1772
  },
1838
1773
  $: subject.asObservable()
1839
1774
  };
1840
1775
  };
1841
- const isHtmlElement = (element) => {
1842
- return typeof element === `object` && !!element && `nodeType` in element && (element == null ? void 0 : element.nodeType) === Node.ELEMENT_NODE && `innerText` in element;
1843
- };
1844
- function createRangeOrCaretFromPoint(doc, startX, startY) {
1845
- if (`caretPositionFromPoint` in doc) {
1846
- return doc.caretPositionFromPoint(startX, startY);
1847
- } else if (typeof doc.caretRangeFromPoint !== `undefined`) {
1848
- return doc.caretRangeFromPoint(startX, startY);
1849
- }
1850
- }
1851
- const getFirstVisibleNodeForViewport = Report.measurePerformance(
1852
- `getFirstVisibleNodeForViewport`,
1853
- 1,
1854
- (documentOrElement, viewport) => {
1855
- const element = `body` in documentOrElement ? getFirstVisibleElementForViewport(documentOrElement.body, viewport) : getFirstVisibleElementForViewport(documentOrElement, viewport);
1856
- const ownerDocument = `createRange` in documentOrElement ? documentOrElement : documentOrElement.ownerDocument;
1857
- if (element) {
1858
- let lastValidRange;
1859
- let lastValidOffset = 0;
1860
- const range = ownerDocument.createRange();
1861
- Array.from(element.childNodes).some((childNode) => {
1862
- range.selectNodeContents(childNode);
1863
- const rects = range.getClientRects();
1864
- const visibleRect = getFirstVisibleDOMRect(rects, viewport);
1865
- if (visibleRect) {
1866
- lastValidRange = range.cloneRange();
1867
- const rangeOrCaret = createRangeOrCaretFromPoint(ownerDocument, Math.ceil(visibleRect.left), Math.ceil(visibleRect.top));
1868
- if (rangeOrCaret && `startContainer` in rangeOrCaret && rangeOrCaret.startContainer === lastValidRange.startContainer) {
1869
- lastValidOffset = rangeOrCaret.startOffset;
1870
- }
1871
- if (rangeOrCaret && `offsetNode` in rangeOrCaret && rangeOrCaret.offsetNode === lastValidRange.startContainer) {
1872
- lastValidOffset = rangeOrCaret.offset;
1873
- }
1874
- return true;
1875
- }
1876
- return false;
1877
- });
1878
- if (lastValidRange) {
1879
- return { node: lastValidRange.startContainer, offset: lastValidOffset };
1880
- }
1881
- return { node: element, offset: 0 };
1882
- }
1883
- return void 0;
1884
- }
1885
- );
1886
- const getFirstVisibleElementForViewport = (element, viewport) => {
1887
- let lastValidElement;
1888
- const positionFromViewport = getElementOrNodePositionFromViewPort(element.getBoundingClientRect(), viewport);
1889
- if (positionFromViewport !== `before` && positionFromViewport !== `after`) {
1890
- lastValidElement = element;
1891
- }
1892
- Array.from(element.children).some((child) => {
1893
- const childInViewPort = getFirstVisibleElementForViewport(child, viewport);
1894
- if (childInViewPort) {
1895
- lastValidElement = childInViewPort;
1896
- return true;
1897
- }
1898
- return false;
1899
- });
1900
- return lastValidElement;
1901
- };
1902
- function getElementOrNodePositionFromViewPort(domRect, { left, right }) {
1903
- if (domRect.left <= left && domRect.right <= left)
1904
- return `before`;
1905
- if (domRect.left <= left && domRect.right > left && domRect.right <= right)
1906
- return `partially-before`;
1907
- if (domRect.left <= right && domRect.right > right)
1908
- return `partially-after`;
1909
- if (domRect.left > right)
1910
- return `after`;
1911
- return `within`;
1912
- }
1913
- function getFirstVisibleDOMRect(domRect, viewport) {
1914
- return Array.from(domRect).find((domRect2) => {
1915
- const position = getElementOrNodePositionFromViewPort(domRect2, viewport);
1916
- if (position !== `before` && position !== `after`) {
1917
- return true;
1918
- }
1919
- return false;
1920
- });
1921
- }
1922
- const getRangeFromNode = (node, offset) => {
1923
- var _a;
1924
- if (node.nodeType !== Node.CDATA_SECTION_NODE && node.nodeType !== Node.DOCUMENT_TYPE_NODE) {
1925
- const range = (_a = node.ownerDocument) == null ? void 0 : _a.createRange();
1926
- range == null ? void 0 : range.selectNodeContents(node);
1927
- try {
1928
- if (offset <= ((range == null ? void 0 : range.endOffset) || 0)) {
1929
- range == null ? void 0 : range.setStart(node, offset || 0);
1930
- }
1931
- } catch (e) {
1932
- Report.error(e);
1933
- }
1934
- return range;
1935
- }
1936
- return void 0;
1937
- };
1938
- const isPointerEvent = (event) => {
1939
- var _a, _b, _c, _d, _e;
1940
- if ((event == null ? void 0 : event.target) && ((_b = (_a = event == null ? void 0 : event.target) == null ? void 0 : _a.ownerDocument) == null ? void 0 : _b.defaultView)) {
1941
- const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
1942
- if (eventView.PointerEvent) {
1943
- return event instanceof eventView.PointerEvent;
1944
- }
1945
- }
1946
- if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
1947
- const eventView = event == null ? void 0 : event.view;
1948
- if (eventView.PointerEvent) {
1949
- return event instanceof eventView.PointerEvent;
1950
- }
1951
- }
1952
- return false;
1953
- };
1954
- const isMouseEvent = (event) => {
1955
- var _a, _b, _c, _d, _e;
1956
- if (isPointerEvent(event))
1957
- return false;
1958
- if ((event == null ? void 0 : event.target) && ((_b = (_a = event == null ? void 0 : event.target) == null ? void 0 : _a.ownerDocument) == null ? void 0 : _b.defaultView)) {
1959
- const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
1960
- if (eventView.MouseEvent) {
1961
- return event instanceof eventView.MouseEvent;
1962
- }
1963
- }
1964
- if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
1965
- const eventView = event == null ? void 0 : event.view;
1966
- if (eventView.MouseEvent) {
1967
- return event instanceof eventView.MouseEvent;
1968
- }
1969
- }
1970
- return false;
1971
- };
1972
- const isTouchEvent = (event) => {
1973
- var _a, _b, _c, _d, _e;
1974
- if ((event == null ? void 0 : event.target) && ((_b = (_a = event == null ? void 0 : event.target) == null ? void 0 : _a.ownerDocument) == null ? void 0 : _b.defaultView)) {
1975
- const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
1976
- if (eventView.TouchEvent) {
1977
- return event instanceof eventView.TouchEvent;
1978
- }
1979
- }
1980
- if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
1981
- const eventView = event == null ? void 0 : event.view;
1982
- if (eventView.TouchEvent) {
1983
- return event instanceof eventView.TouchEvent;
1984
- }
1985
- }
1986
- return false;
1987
- };
1988
- const pointerEvents = [
1989
- `pointercancel`,
1990
- `pointerdown`,
1991
- `pointerenter`,
1992
- `pointerleave`,
1993
- `pointermove`,
1994
- `pointerout`,
1995
- `pointerover`,
1996
- `pointerup`,
1997
- `touchstart`,
1998
- `touchend`
1999
- ];
2000
- const mouseEvents = [
2001
- `click`,
2002
- `mousedown`,
2003
- `mouseup`,
2004
- `mouseenter`,
2005
- `mouseleave`,
2006
- `mousemove`,
2007
- `mouseout`,
2008
- `mouseover`
2009
- ];
2010
- const passthroughEvents = [...pointerEvents, ...mouseEvents];
2011
1776
  const createCommonSpineItem = ({
2012
1777
  item,
2013
1778
  context,
2014
1779
  parentElement,
2015
- iframeEventBridgeElement$,
2016
- hooks$,
2017
1780
  viewportState$,
2018
- settings
1781
+ settings,
1782
+ hookManager
2019
1783
  }) => {
2020
- var _a;
2021
1784
  const destroySubject$ = new rxjs.Subject();
2022
- const containerElement = createContainerElement$1(parentElement, item, hooks$);
1785
+ const containerElement = createContainerElement$1(parentElement, item, hookManager);
2023
1786
  const overlayElement = createOverlayElement(parentElement, item);
2024
1787
  const fingerTracker = createFingerTracker();
2025
1788
  const selectionTracker = createSelectionTracker();
2026
- const frameHooks = createFrameHooks(iframeEventBridgeElement$, fingerTracker, selectionTracker);
2027
1789
  const spineItemFrame = createFrameItem({
2028
1790
  parent: containerElement,
2029
1791
  item,
2030
1792
  context,
2031
- fetchResource: (_a = context.getState()) == null ? void 0 : _a.fetchResource,
2032
- hooks$: hooks$.asObservable().pipe(operators.map((hooks) => [...hooks, ...frameHooks])),
1793
+ hookManager,
2033
1794
  viewportState$,
2034
1795
  settings
2035
1796
  });
@@ -2052,12 +1813,12 @@
2052
1813
  return memoizedElementDimensions;
2053
1814
  };
2054
1815
  const isImageType = () => {
2055
- var _a2;
2056
- return !!((_a2 = item.mediaType) == null ? void 0 : _a2.startsWith(`image/`));
1816
+ var _a;
1817
+ return !!((_a = item.mediaType) == null ? void 0 : _a.startsWith(`image/`));
2057
1818
  };
2058
1819
  const injectStyle = (cssText) => {
2059
- var _a2, _b;
2060
- (_a2 = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a2.removeStyle(`prose-reader-css`);
1820
+ var _a, _b;
1821
+ (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.removeStyle(`prose-reader-css`);
2061
1822
  (_b = spineItemFrame.getManipulableFrame()) == null ? void 0 : _b.addStyle(`prose-reader-css`, cssText);
2062
1823
  };
2063
1824
  const adjustPositionOfElement = ({ right, left, top }) => {
@@ -2078,10 +1839,10 @@
2078
1839
  }
2079
1840
  };
2080
1841
  const getViewPortInformation = () => {
2081
- var _a2;
1842
+ var _a;
2082
1843
  const { width: pageWidth, height: pageHeight } = context.getPageSize();
2083
1844
  const viewportDimensions = spineItemFrame.getViewportDimensions();
2084
- const frameElement = (_a2 = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a2.frame;
1845
+ const frameElement = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame;
2085
1846
  if (containerElement && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow) && viewportDimensions) {
2086
1847
  const computedWidthScale = pageWidth / viewportDimensions.width;
2087
1848
  const computedScale = Math.min(computedWidthScale, pageHeight / viewportDimensions.height);
@@ -2091,8 +1852,8 @@
2091
1852
  const loadContent = () => spineItemFrame.load();
2092
1853
  const unloadContent = () => spineItemFrame.unload();
2093
1854
  const getBoundingRectOfElementFromSelector = (selector) => {
2094
- var _a2, _b, _c, _d, _e;
2095
- const frame = (_a2 = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a2.frame;
1855
+ var _a, _b, _c, _d, _e;
1856
+ const frame = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame;
2096
1857
  if (frame && selector) {
2097
1858
  if (selector.startsWith(`#`)) {
2098
1859
  return (_c = (_b = frame.contentDocument) == null ? void 0 : _b.getElementById(selector.replace(`#`, ``))) == null ? void 0 : _c.getBoundingClientRect();
@@ -2137,16 +1898,12 @@
2137
1898
  }) => {
2138
1899
  containerElement.style.width = `${width}px`;
2139
1900
  containerElement.style.height = `${height}px`;
2140
- hooks$.getValue().forEach((hook) => {
2141
- if (hook.name === `item.onAfterLayout`) {
2142
- hook.fn({ blankPagePosition, item, minimumWidth });
2143
- }
2144
- });
1901
+ hookManager.execute(`item.onAfterLayout`, void 0, { blankPagePosition, item, minimumWidth });
2145
1902
  setLayoutDirty();
2146
1903
  };
2147
1904
  const translateFramePositionIntoPage = (position) => {
2148
- var _a2, _b;
2149
- const { left = 0, top = 0 } = ((_a2 = spineItemFrame.getFrameElement()) == null ? void 0 : _a2.getBoundingClientRect()) || {};
1905
+ var _a, _b;
1906
+ const { left = 0, top = 0 } = ((_a = spineItemFrame.getFrameElement()) == null ? void 0 : _a.getBoundingClientRect()) || {};
2150
1907
  const computedScale = ((_b = getViewPortInformation()) == null ? void 0 : _b.computedScale) ?? 1;
2151
1908
  const adjustedX = position.clientX * computedScale + left;
2152
1909
  const adjustedY = position.clientY * computedScale + top;
@@ -2156,20 +1913,14 @@
2156
1913
  };
2157
1914
  };
2158
1915
  const getResource = async () => {
2159
- const fetchResource = context.getState().fetchResource;
1916
+ const fetchResource = settings.settings.fetchResource;
2160
1917
  const lastFetch = (_) => {
2161
1918
  if (fetchResource) {
2162
1919
  return fetchResource(item);
2163
1920
  }
2164
1921
  return fetch(item.href);
2165
1922
  };
2166
- const finalFetch = hooks$.getValue().reduce((acc, hook) => {
2167
- if (hook.name === `item.onGetResource`) {
2168
- return hook.fn(acc);
2169
- }
2170
- return acc;
2171
- }, lastFetch);
2172
- return await finalFetch(item);
1923
+ return await lastFetch();
2173
1924
  };
2174
1925
  const manipulateSpineItem = (cb) => {
2175
1926
  const manipulableFrame = spineItemFrame.getManipulableFrame();
@@ -2192,16 +1943,12 @@
2192
1943
  overlayElement
2193
1944
  });
2194
1945
  };
2195
- const executeOnLayoutBeforeMeasurementHook = (options) => hooks$.getValue().forEach((hook) => {
2196
- if (hook.name === `item.onLayoutBeforeMeasurement`) {
2197
- hook.fn({
2198
- frame: spineItemFrame,
2199
- container: containerElement,
2200
- item,
2201
- isImageType,
2202
- ...options
2203
- });
2204
- }
1946
+ const executeOnLayoutBeforeMeasurementHook = (options) => hookManager.execute("item.onLayoutBeforeMeasurement", void 0, {
1947
+ frame: spineItemFrame,
1948
+ container: containerElement,
1949
+ item,
1950
+ isImageType,
1951
+ ...options
2205
1952
  });
2206
1953
  const contentLayout$ = spineItemFrame.$.contentLayoutChange$.pipe(
2207
1954
  operators.withLatestFrom(spineItemFrame.$.isReady$),
@@ -2240,8 +1987,8 @@
2240
1987
  destroySubject$.complete();
2241
1988
  },
2242
1989
  isUsingVerticalWriting: () => {
2243
- var _a2;
2244
- return (_a2 = spineItemFrame.getWritingMode()) == null ? void 0 : _a2.startsWith(`vertical`);
1990
+ var _a;
1991
+ return (_a = spineItemFrame.getWritingMode()) == null ? void 0 : _a.startsWith(`vertical`);
2245
1992
  },
2246
1993
  /**
2247
1994
  * @important
@@ -2252,7 +1999,7 @@
2252
1999
  * be confined to a single page.
2253
2000
  */
2254
2001
  getReadingDirection: () => {
2255
- return spineItemFrame.getReadingDirection() || context.getReadingDirection();
2002
+ return spineItemFrame.getReadingDirection() || context.readingDirection;
2256
2003
  },
2257
2004
  manipulateSpineItem,
2258
2005
  executeOnLayoutBeforeMeasurementHook,
@@ -2267,7 +2014,7 @@
2267
2014
  }
2268
2015
  };
2269
2016
  };
2270
- const createContainerElement$1 = (containerElement, item, hooks$) => {
2017
+ const createContainerElement$1 = (containerElement, item, hookManager) => {
2271
2018
  const element = containerElement.ownerDocument.createElement(`div`);
2272
2019
  element.classList.add(`spineItem`);
2273
2020
  element.classList.add(`spineItem-${item.renditionLayout}`);
@@ -2275,12 +2022,8 @@
2275
2022
  position: absolute;
2276
2023
  overflow: hidden;
2277
2024
  `;
2278
- return hooks$.getValue().reduce((element2, hook) => {
2279
- if (hook.name === `item.onBeforeContainerCreated`) {
2280
- return hook.fn(element2);
2281
- }
2282
- return element2;
2283
- }, element);
2025
+ hookManager.execute("item.onBeforeContainerCreated", void 0, { element });
2026
+ return element;
2284
2027
  };
2285
2028
  const createOverlayElement = (containerElement, item) => {
2286
2029
  const element = containerElement.ownerDocument.createElement(`div`);
@@ -2295,42 +2038,6 @@
2295
2038
  `;
2296
2039
  return element;
2297
2040
  };
2298
- const createFrameHooks = (iframeEventBridgeElement$, fingerTracker, selectionTracker) => {
2299
- return [
2300
- {
2301
- name: `item.onLoad`,
2302
- fn: ({ frame }) => {
2303
- const unregister = passthroughEvents.map((event) => {
2304
- var _a;
2305
- const listener = (e) => {
2306
- var _a2;
2307
- let convertedEvent = e;
2308
- if (isPointerEvent(e)) {
2309
- convertedEvent = new PointerEvent(e.type, e);
2310
- }
2311
- if (isMouseEvent(e)) {
2312
- convertedEvent = new MouseEvent(e.type, e);
2313
- }
2314
- if (convertedEvent !== e) {
2315
- attachOriginalFrameEventToDocumentEvent(convertedEvent, e);
2316
- (_a2 = iframeEventBridgeElement$.getValue()) == null ? void 0 : _a2.dispatchEvent(convertedEvent);
2317
- }
2318
- };
2319
- (_a = frame.contentDocument) == null ? void 0 : _a.addEventListener(event, listener);
2320
- return () => {
2321
- var _a2;
2322
- (_a2 = frame.contentDocument) == null ? void 0 : _a2.removeEventListener(event, listener);
2323
- };
2324
- });
2325
- selectionTracker.track(frame);
2326
- fingerTracker.track(frame);
2327
- return () => {
2328
- unregister.forEach((cb) => cb());
2329
- };
2330
- }
2331
- }
2332
- ];
2333
- };
2334
2041
  const getStyleForViewportDocument = () => {
2335
2042
  return `
2336
2043
  body {
@@ -2343,19 +2050,17 @@
2343
2050
  item,
2344
2051
  context,
2345
2052
  containerElement,
2346
- iframeEventBridgeElement$,
2347
- hooks$,
2348
2053
  viewportState$,
2349
- settings
2054
+ settings,
2055
+ hookManager
2350
2056
  }) => {
2351
2057
  const commonSpineItem = createCommonSpineItem({
2352
2058
  context,
2353
2059
  item,
2354
2060
  parentElement: containerElement,
2355
- iframeEventBridgeElement$,
2356
- hooks$,
2357
2061
  viewportState$,
2358
- settings
2062
+ settings,
2063
+ hookManager
2359
2064
  });
2360
2065
  const spineItemFrame = commonSpineItem.spineItemFrame;
2361
2066
  const layout = ({
@@ -2366,15 +2071,15 @@
2366
2071
  var _a;
2367
2072
  const { width: pageWidth, height: pageHeight } = context.getPageSize();
2368
2073
  const { viewportDimensions, computedScale = 1 } = commonSpineItem.getViewPortInformation() ?? {};
2369
- const visibleArea = context.getVisibleAreaRect();
2074
+ const visibleArea = context.state.visibleAreaRect;
2370
2075
  const frameElement = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame;
2371
2076
  if ((spineItemFrame == null ? void 0 : spineItemFrame.getIsLoaded()) && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
2372
2077
  const contentWidth = pageWidth;
2373
- const contentHeight = visibleArea.height + context.getCalculatedInnerMargin();
2078
+ const contentHeight = visibleArea.height + context.state.calculatedInnerMargin;
2374
2079
  const cssLink = buildDocumentStyle(
2375
2080
  {
2376
2081
  ...commonSpineItem.getDimensionsForPaginatedContent(),
2377
- enableTouch: settings.getSettings().computedPageTurnMode !== `scrollable`,
2082
+ enableTouch: settings.settings.computedPageTurnMode !== `scrollable`,
2378
2083
  spreadPosition
2379
2084
  },
2380
2085
  viewportDimensions
@@ -2517,19 +2222,17 @@
2517
2222
  item,
2518
2223
  context,
2519
2224
  containerElement,
2520
- iframeEventBridgeElement$,
2521
- hooks$,
2522
2225
  viewportState$,
2523
- settings
2226
+ settings,
2227
+ hookManager
2524
2228
  }) => {
2525
2229
  const commonSpineItem = createCommonSpineItem({
2526
2230
  context,
2527
2231
  item,
2528
2232
  parentElement: containerElement,
2529
- iframeEventBridgeElement$,
2530
- hooks$,
2531
2233
  viewportState$,
2532
- settings
2234
+ settings,
2235
+ hookManager
2533
2236
  });
2534
2237
  const spineItemFrame = commonSpineItem.spineItemFrame;
2535
2238
  let latestContentHeightWhenLoaded;
@@ -2542,12 +2245,12 @@
2542
2245
  (_b = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame) == null ? void 0 : _b.style.setProperty(`width`, `${pageWidth}px`);
2543
2246
  (_d = (_c = spineItemFrame.getManipulableFrame()) == null ? void 0 : _c.frame) == null ? void 0 : _d.style.setProperty(`height`, `${pageHeight}px`);
2544
2247
  const { viewportDimensions, computedScale = 1 } = commonSpineItem.getViewPortInformation() ?? {};
2545
- const visibleArea = context.getVisibleAreaRect();
2248
+ const visibleArea = context.state.visibleAreaRect;
2546
2249
  const frameElement = (_e = spineItemFrame.getManipulableFrame()) == null ? void 0 : _e.frame;
2547
- const isGloballyPrePaginated = ((_f = context.getManifest()) == null ? void 0 : _f.renditionLayout) === `pre-paginated`;
2250
+ const isGloballyPrePaginated = ((_f = context.manifest) == null ? void 0 : _f.renditionLayout) === `pre-paginated`;
2548
2251
  if ((spineItemFrame == null ? void 0 : spineItemFrame.getIsLoaded()) && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
2549
2252
  let contentWidth = pageWidth;
2550
- let contentHeight = visibleArea.height + context.getCalculatedInnerMargin();
2253
+ let contentHeight = visibleArea.height + context.state.calculatedInnerMargin;
2551
2254
  frameElement == null ? void 0 : frameElement.style.setProperty(`visibility`, `visible`);
2552
2255
  frameElement == null ? void 0 : frameElement.style.setProperty(`opacity`, `1`);
2553
2256
  if (viewportDimensions) {
@@ -2567,8 +2270,8 @@
2567
2270
  frameElement == null ? void 0 : frameElement.style.setProperty(`transform-origin`, `center center`);
2568
2271
  } else {
2569
2272
  const frameStyle = commonSpineItem.isImageType() ? buildStyleForReflowableImageOnly({
2570
- isScrollable: ((_g = context.getManifest()) == null ? void 0 : _g.renditionFlow) === `scrolled-continuous`,
2571
- enableTouch: settings.getSettings().computedPageTurnMode !== `scrollable`
2273
+ isScrollable: ((_g = context.manifest) == null ? void 0 : _g.renditionFlow) === `scrolled-continuous`,
2274
+ enableTouch: settings.settings.computedPageTurnMode !== `scrollable`
2572
2275
  }) : buildStyleWithMultiColumn(
2573
2276
  commonSpineItem.getDimensionsForReflowableContent(spineItemFrame.isUsingVerticalWriting(), minimumWidth)
2574
2277
  );
@@ -2581,7 +2284,7 @@
2581
2284
  width: minimumWidth,
2582
2285
  height: contentHeight
2583
2286
  });
2584
- } else if (((_h = context.getManifest()) == null ? void 0 : _h.renditionFlow) === `scrolled-continuous`) {
2287
+ } else if (((_h = context.manifest) == null ? void 0 : _h.renditionFlow) === `scrolled-continuous`) {
2585
2288
  contentHeight = frameElement.contentDocument.documentElement.scrollHeight;
2586
2289
  latestContentHeightWhenLoaded = contentHeight;
2587
2290
  spineItemFrame.staticLayout({
@@ -2645,7 +2348,10 @@
2645
2348
  }
2646
2349
  `;
2647
2350
  };
2648
- const buildStyleForReflowableImageOnly = ({ isScrollable, enableTouch }) => {
2351
+ const buildStyleForReflowableImageOnly = ({
2352
+ isScrollable,
2353
+ enableTouch
2354
+ }) => {
2649
2355
  return `
2650
2356
  ${/*
2651
2357
  * @see https://hammerjs.github.io/touch-action/
@@ -2793,91 +2499,29 @@
2793
2499
  item,
2794
2500
  context,
2795
2501
  containerElement,
2796
- iframeEventBridgeElement$,
2797
- hooks$,
2798
2502
  viewportState$,
2799
- settings
2503
+ settings,
2504
+ hookManager
2800
2505
  }) => {
2801
2506
  if (item.renditionLayout === `pre-paginated`) {
2802
2507
  return createPrePaginatedSpineItem({
2803
2508
  item,
2804
2509
  context,
2805
2510
  containerElement,
2806
- iframeEventBridgeElement$,
2807
- hooks$,
2808
2511
  viewportState$,
2809
- settings
2512
+ settings,
2513
+ hookManager
2810
2514
  });
2811
2515
  }
2812
2516
  return createReflowableSpineItem({
2813
2517
  item,
2814
2518
  context,
2815
2519
  containerElement,
2816
- iframeEventBridgeElement$,
2817
- hooks$,
2818
2520
  viewportState$,
2819
- settings
2521
+ settings,
2522
+ hookManager
2820
2523
  });
2821
2524
  };
2822
- const createEventsHelper = ({
2823
- iframeEventBridgeElement$,
2824
- locator
2825
- }) => {
2826
- const normalizeEventForViewport = (event) => {
2827
- var _a;
2828
- const eventIsComingFromBridge = event.target === iframeEventBridgeElement$.getValue();
2829
- const iframeOriginalEvent = getOriginalFrameEventFromDocumentEvent(event);
2830
- const originalFrame = (_a = iframeOriginalEvent == null ? void 0 : iframeOriginalEvent.view) == null ? void 0 : _a.frameElement;
2831
- if (!eventIsComingFromBridge || !iframeOriginalEvent || !originalFrame)
2832
- return event;
2833
- const spineItem = locator.getSpineItemFromIframe(originalFrame);
2834
- if (!spineItem)
2835
- return event;
2836
- if (isPointerEvent(event)) {
2837
- const { clientX, clientY } = spineItem.translateFramePositionIntoPage(event);
2838
- const newEvent = new PointerEvent(event.type, {
2839
- ...event,
2840
- pointerId: event.pointerId,
2841
- clientX,
2842
- clientY
2843
- });
2844
- Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
2845
- return newEvent;
2846
- }
2847
- if (isMouseEvent(event)) {
2848
- const { clientX, clientY } = spineItem.translateFramePositionIntoPage(event);
2849
- const newEvent = new MouseEvent(event.type, {
2850
- ...event,
2851
- clientX,
2852
- clientY
2853
- });
2854
- Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
2855
- return newEvent;
2856
- }
2857
- if (isTouchEvent(event)) {
2858
- const touches = Array.from(event.touches).map((touch) => {
2859
- const { clientX, clientY } = spineItem.translateFramePositionIntoPage(touch);
2860
- return new Touch({
2861
- identifier: touch.identifier,
2862
- target: touch.target,
2863
- clientX,
2864
- clientY
2865
- });
2866
- });
2867
- const newEvent = new TouchEvent(event.type, {
2868
- touches,
2869
- changedTouches: touches,
2870
- targetTouches: touches
2871
- });
2872
- Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
2873
- return newEvent;
2874
- }
2875
- return event;
2876
- };
2877
- return {
2878
- normalizeEventForViewport
2879
- };
2880
- };
2881
2525
  const ELEMENT_NODE = Node.ELEMENT_NODE;
2882
2526
  const TEXT_NODE = Node.TEXT_NODE;
2883
2527
  const CDATA_SECTION_NODE = Node.CDATA_SECTION_NODE;
@@ -2891,8 +2535,7 @@
2891
2535
  let m;
2892
2536
  do {
2893
2537
  m = str.match(regExp);
2894
- if (!m)
2895
- break;
2538
+ if (!m) break;
2896
2539
  matches.push(m.index + add);
2897
2540
  offset += m.index + m.length;
2898
2541
  str = str.slice(m.index + m.length);
@@ -2955,24 +2598,17 @@
2955
2598
  function compareTemporal(a, b) {
2956
2599
  const isA = typeof a === `number`;
2957
2600
  const isB = typeof b === `number`;
2958
- if (!isA && !isB)
2959
- return 0;
2960
- if (!isA && isB)
2961
- return -1;
2962
- if (isA && !isB)
2963
- return 1;
2601
+ if (!isA && !isB) return 0;
2602
+ if (!isA && isB) return -1;
2603
+ if (isA && !isB) return 1;
2964
2604
  return (a || 0) - (b || 0);
2965
2605
  }
2966
2606
  function compareSpatial(a, b) {
2967
- if (!a && !b)
2968
- return 0;
2969
- if (!a && b)
2970
- return -1;
2971
- if (a && !b)
2972
- return 1;
2607
+ if (!a && !b) return 0;
2608
+ if (!a && b) return -1;
2609
+ if (a && !b) return 1;
2973
2610
  const diff = (a.y || 0) - (b.y || 0);
2974
- if (diff)
2975
- return diff;
2611
+ if (diff) return diff;
2976
2612
  return (a.x || 0) - (b.x || 0);
2977
2613
  }
2978
2614
  class CFI {
@@ -2994,20 +2630,16 @@
2994
2630
  const isCFI = /^epubcfi\((.*)\)$/;
2995
2631
  str = str.trim();
2996
2632
  const m = str.match(isCFI);
2997
- if (!m)
2998
- throw new Error(`Not a valid CFI`);
2999
- if (m.length < 2)
3000
- return;
2633
+ if (!m) throw new Error(`Not a valid CFI`);
2634
+ if (m.length < 2) return;
3001
2635
  str = m[1] || ``;
3002
2636
  let parsed, offset, newDoc;
3003
2637
  let subParts = [];
3004
2638
  let sawComma = 0;
3005
2639
  while (str.length) {
3006
2640
  ({ parsed, offset, newDoc } = this.parse(str));
3007
- if (!parsed || offset === null)
3008
- throw new Error(`Parsing failed`);
3009
- if (sawComma && newDoc)
3010
- throw new Error(`CFI is a range that spans multiple documents. This is not allowed`);
2641
+ if (!parsed || offset === null) throw new Error(`Parsing failed`);
2642
+ if (sawComma && newDoc) throw new Error(`CFI is a range that spans multiple documents. This is not allowed`);
3011
2643
  subParts.push(parsed);
3012
2644
  if (newDoc || str.length - offset <= 0) {
3013
2645
  if (sawComma === 2) {
@@ -3051,8 +2683,7 @@
3051
2683
  if (!parts) {
3052
2684
  if (this.from) {
3053
2685
  this.removeIllegalOpts(this.from);
3054
- if (!this.to)
3055
- return;
2686
+ if (!this.to) return;
3056
2687
  parts = this.to;
3057
2688
  } else {
3058
2689
  parts = this.parts;
@@ -3075,8 +2706,7 @@
3075
2706
  let o;
3076
2707
  while (node.parentNode) {
3077
2708
  o = calcSiblingCount(node.parentNode.childNodes, node, offset);
3078
- if (!cfi && o.offset)
3079
- cfi = `:` + o.offset;
2709
+ if (!cfi && o.offset) cfi = `:` + o.offset;
3080
2710
  cfi = `/` + o.count + (node.id ? `[` + cfiEscape(node.id) + `]` : ``) + cfi;
3081
2711
  node = node.parentNode;
3082
2712
  }
@@ -3093,8 +2723,7 @@
3093
2723
  } else {
3094
2724
  cfi = this.generatePart(node, offset, extra);
3095
2725
  }
3096
- if (extra)
3097
- cfi += extra;
2726
+ if (extra) cfi += extra;
3098
2727
  return `epubcfi(` + cfi + `)`;
3099
2728
  }
3100
2729
  static toParsed(cfi) {
@@ -3111,13 +2740,10 @@
3111
2740
  for (i = 0; i < max; i++) {
3112
2741
  cA = a[i];
3113
2742
  cB = b[i];
3114
- if (!cA)
3115
- return -1;
3116
- if (!cB)
3117
- return 1;
2743
+ if (!cA) return -1;
2744
+ if (!cB) return 1;
3118
2745
  diff = this.compareParts(cA, cB);
3119
- if (diff)
3120
- return diff;
2746
+ if (diff) return diff;
3121
2747
  }
3122
2748
  return 0;
3123
2749
  }
@@ -3134,14 +2760,11 @@
3134
2760
  if (a.isRange || b.isRange) {
3135
2761
  if (a.isRange && b.isRange) {
3136
2762
  const diff = this.comparePath(oA.from, oB.from);
3137
- if (diff)
3138
- return diff;
2763
+ if (diff) return diff;
3139
2764
  return this.comparePath(oA.to, oB.to);
3140
2765
  }
3141
- if (a.isRange)
3142
- oA = oA.from;
3143
- if (b.isRange)
3144
- oB = oB.from;
2766
+ if (a.isRange) oA = oA.from;
2767
+ if (b.isRange) oB = oB.from;
3145
2768
  return this.comparePath(oA, oB);
3146
2769
  } else {
3147
2770
  return this.comparePath(oA, oB);
@@ -3154,29 +2777,22 @@
3154
2777
  for (i = 0; i < max; i++) {
3155
2778
  cA = a[i];
3156
2779
  cB = b[i];
3157
- if (!cA)
3158
- return -1;
3159
- if (!cB)
3160
- return 1;
2780
+ if (!cA) return -1;
2781
+ if (!cB) return 1;
3161
2782
  diff = cA.nodeIndex - cB.nodeIndex;
3162
- if (diff)
3163
- return diff;
2783
+ if (diff) return diff;
3164
2784
  if (cA.nodeIndex === 0) {
3165
2785
  return 0;
3166
2786
  }
3167
- if (i < max - 1)
3168
- continue;
2787
+ if (i < max - 1) continue;
3169
2788
  if (cA.nodeIndex % 2 === 0) {
3170
2789
  diff = compareTemporal(cA.temporal, cB.temporal);
3171
- if (diff)
3172
- return diff;
2790
+ if (diff) return diff;
3173
2791
  diff = compareSpatial(cA.spatial, cB.spatial);
3174
- if (diff)
3175
- return diff;
2792
+ if (diff) return diff;
3176
2793
  }
3177
2794
  diff = (cA.offset || 0) - (cB.offset || 0);
3178
- if (diff)
3179
- return diff;
2795
+ if (diff) return diff;
3180
2796
  }
3181
2797
  return 0;
3182
2798
  }
@@ -3194,8 +2810,7 @@
3194
2810
  return this.decodeEntities(dom, str).length;
3195
2811
  }
3196
2812
  getFrom() {
3197
- if (!this.isRange)
3198
- throw new Error(`Trying to get beginning of non-range CFI`);
2813
+ if (!this.isRange) throw new Error(`Trying to get beginning of non-range CFI`);
3199
2814
  if (!this.from) {
3200
2815
  return this.deepClone(this.parts);
3201
2816
  }
@@ -3204,8 +2819,7 @@
3204
2819
  return parts;
3205
2820
  }
3206
2821
  getTo() {
3207
- if (!this.isRange)
3208
- throw new Error(`Trying to get end of non-range CFI`);
2822
+ if (!this.isRange) throw new Error(`Trying to get end of non-range CFI`);
3209
2823
  const parts = this.deepClone(this.parts);
3210
2824
  parts[parts.length - 1] = parts[parts.length - 1].concat(this.to);
3211
2825
  return parts;
@@ -3221,8 +2835,7 @@
3221
2835
  return this.deepClone(this.parts);
3222
2836
  }
3223
2837
  parseSideBias(o, loc) {
3224
- if (!loc)
3225
- return;
2838
+ if (!loc) return;
3226
2839
  const m = loc.trim().match(/^(.*);s=([ba])$/);
3227
2840
  if (!m || m.length < 3) {
3228
2841
  if (typeof o.textLocationAssertion === `object`) {
@@ -3246,11 +2859,9 @@
3246
2859
  }
3247
2860
  }
3248
2861
  parseSpatialRange(range) {
3249
- if (!range)
3250
- return void 0;
2862
+ if (!range) return void 0;
3251
2863
  const m = range.trim().match(/^([\d\.]+):([\d\.]+)$/);
3252
- if (!m || m.length < 3)
3253
- return void 0;
2864
+ if (!m || m.length < 3) return void 0;
3254
2865
  const o = {
3255
2866
  x: parseInt(m[1]),
3256
2867
  y: parseInt(m[2])
@@ -3340,8 +2951,7 @@
3340
2951
  } else {
3341
2952
  prevState = state;
3342
2953
  state = null;
3343
- if (f && seenColon)
3344
- o.spatial = this.parseSpatialRange(f);
2954
+ if (f && seenColon) o.spatial = this.parseSpatialRange(f);
3345
2955
  f = null;
3346
2956
  }
3347
2957
  }
@@ -3451,8 +3061,7 @@
3451
3061
  }
3452
3062
  escape = false;
3453
3063
  }
3454
- if (!o.nodeIndex && o.nodeIndex !== 0)
3455
- throw new Error(`Missing child node index in CFI`);
3064
+ if (!o.nodeIndex && o.nodeIndex !== 0) throw new Error(`Missing child node index in CFI`);
3456
3065
  return { parsed: o, offset: i, newDoc: state === `!` };
3457
3066
  }
3458
3067
  // The CFI counts child nodes differently from the DOM
@@ -3460,8 +3069,7 @@
3460
3069
  // according to the CFI standard way of counting
3461
3070
  getChildNodeByCFIIndex(dom, parentNode, index, offset) {
3462
3071
  const children = parentNode.childNodes;
3463
- if (!children.length)
3464
- return { node: parentNode, offset: 0 };
3072
+ if (!children.length) return { node: parentNode, offset: 0 };
3465
3073
  if (index <= 0) {
3466
3074
  return { node: children[0], relativeToNode: `before`, offset: 0 };
3467
3075
  }
@@ -3529,8 +3137,7 @@
3529
3137
  }
3530
3138
  }
3531
3139
  isTextNode(node) {
3532
- if (!node)
3533
- return false;
3140
+ if (!node) return false;
3534
3141
  if (node.nodeType === TEXT_NODE || node.nodeType === CDATA_SECTION_NODE) {
3535
3142
  return true;
3536
3143
  }
@@ -3562,15 +3169,13 @@
3562
3169
  str = this.decodeEntities(dom, curNode.textContent);
3563
3170
  nodeLengths[i] = str.length;
3564
3171
  txt += str;
3565
- if (!curNode.nextSibling)
3566
- break;
3172
+ if (!curNode.nextSibling) break;
3567
3173
  curNode = curNode.nextSibling;
3568
3174
  i++;
3569
3175
  }
3570
3176
  const matchOffset = assertion.pre ? assertion.pre.length : 0;
3571
3177
  const m = matchAll(txt, new RegExp(matchStr), matchOffset);
3572
- if (!m.length)
3573
- return { node, offset };
3178
+ if (!m.length) return { node, offset };
3574
3179
  let newOffset = closest(m, offset);
3575
3180
  if (curNode === node && newOffset === offset) {
3576
3181
  return { node, offset };
@@ -3579,11 +3184,9 @@
3579
3184
  curNode = startNode;
3580
3185
  while (newOffset >= nodeLengths[i]) {
3581
3186
  newOffset -= nodeLengths[i];
3582
- if (newOffset < 0)
3583
- return { node, offset };
3187
+ if (newOffset < 0) return { node, offset };
3584
3188
  const nodeOffsets = [];
3585
- if (!curNode.nextSibling || i + 1 >= nodeOffsets.length)
3586
- return { node, offset };
3189
+ if (!curNode.nextSibling || i + 1 >= nodeOffsets.length) return { node, offset };
3587
3190
  i++;
3588
3191
  curNode = curNode.nextSibling;
3589
3192
  }
@@ -3591,8 +3194,7 @@
3591
3194
  }
3592
3195
  resolveNode(index, subparts, dom, opts) {
3593
3196
  opts = Object.assign({}, opts || {});
3594
- if (!dom)
3595
- throw new Error(`Missing DOM argument`);
3197
+ if (!dom) throw new Error(`Missing DOM argument`);
3596
3198
  let startNode;
3597
3199
  if (index === 0) {
3598
3200
  startNode = dom.querySelector(`package`);
@@ -3606,8 +3208,7 @@
3606
3208
  }
3607
3209
  }
3608
3210
  startNode = dom;
3609
- if (!startNode)
3610
- throw new Error(`Document incompatible with CFIs`);
3211
+ if (!startNode) throw new Error(`Document incompatible with CFIs`);
3611
3212
  let node = startNode;
3612
3213
  let startFrom = 0;
3613
3214
  let i;
@@ -3649,40 +3250,33 @@
3649
3250
  throw new Error(`index is out of bounds`);
3650
3251
  }
3651
3252
  const subparts = this.parts[index];
3652
- if (!subparts)
3653
- throw new Error(`Missing CFI part for index: ` + index);
3253
+ if (!subparts) throw new Error(`Missing CFI part for index: ` + index);
3654
3254
  const o = this.resolveNode(index, subparts, dom, opts);
3655
3255
  let node = o.node;
3656
3256
  const tagName = node.tagName.toLowerCase();
3657
3257
  if (tagName === `itemref` && // @ts-ignore
3658
3258
  node.parentNode.tagName.toLowerCase() === `spine`) {
3659
3259
  const idref = node.getAttribute(`idref`);
3660
- if (!idref)
3661
- throw new Error(`Referenced node had not 'idref' attribute`);
3260
+ if (!idref) throw new Error(`Referenced node had not 'idref' attribute`);
3662
3261
  node = dom.getElementById(idref);
3663
- if (!node)
3664
- throw new Error(`Specified node is missing from manifest`);
3262
+ if (!node) throw new Error(`Specified node is missing from manifest`);
3665
3263
  const href = node.getAttribute(`href`);
3666
- if (!href)
3667
- throw new Error(`Manifest item is missing href attribute`);
3264
+ if (!href) throw new Error(`Manifest item is missing href attribute`);
3668
3265
  return href;
3669
3266
  }
3670
3267
  if (tagName === `iframe` || tagName === `embed`) {
3671
3268
  const src = node.getAttribute(`src`);
3672
- if (!src)
3673
- throw new Error(tagName + ` element is missing 'src' attribute`);
3269
+ if (!src) throw new Error(tagName + ` element is missing 'src' attribute`);
3674
3270
  return src;
3675
3271
  }
3676
3272
  if (tagName === `object`) {
3677
3273
  const data = node.getAttribute(`data`);
3678
- if (!data)
3679
- throw new Error(tagName + ` element is missing 'data' attribute`);
3274
+ if (!data) throw new Error(tagName + ` element is missing 'data' attribute`);
3680
3275
  return data;
3681
3276
  }
3682
3277
  if (tagName === `image` || tagName === `use`) {
3683
3278
  const href = node.getAttribute(`xlink:href`);
3684
- if (!href)
3685
- throw new Error(tagName + ` element is missing 'xlink:href' attribute`);
3279
+ if (!href) throw new Error(tagName + ` element is missing 'xlink:href' attribute`);
3686
3280
  return href;
3687
3281
  }
3688
3282
  throw new Error(`No URI found`);
@@ -3693,13 +3287,11 @@
3693
3287
  resolveLocation(dom, parts) {
3694
3288
  const index = parts.length - 1;
3695
3289
  const subparts = parts[index];
3696
- if (!subparts)
3697
- throw new Error(`Missing CFI part for index: ` + index);
3290
+ if (!subparts) throw new Error(`Missing CFI part for index: ` + index);
3698
3291
  const o = this.resolveNode(index, subparts, dom);
3699
3292
  const lastPart = this.deepClone(subparts[subparts.length - 1]);
3700
3293
  delete lastPart.nodeIndex;
3701
- if (!lastPart.offset)
3702
- delete o.offset;
3294
+ if (!lastPart.offset) delete o.offset;
3703
3295
  return { ...lastPart, ...o };
3704
3296
  }
3705
3297
  // Takes the Document or XMLDocument for the final
@@ -3763,12 +3355,20 @@
3763
3355
  toString: () => text,
3764
3356
  getAnchorCfi: () => {
3765
3357
  if (selection.anchorNode) {
3766
- return CFI.generate(selection.anchorNode, selection.anchorOffset, `|[prose~anchor~${encodeURIComponent(item.id)}]`);
3358
+ return CFI.generate(
3359
+ selection.anchorNode,
3360
+ selection.anchorOffset,
3361
+ `|[prose~anchor~${encodeURIComponent(item.id)}]`
3362
+ );
3767
3363
  }
3768
3364
  },
3769
3365
  getFocusCfi: () => {
3770
3366
  if (selection.focusNode) {
3771
- return CFI.generate(selection.focusNode, selection.focusOffset, `|[prose~anchor~${encodeURIComponent(item.id)}]`);
3367
+ return CFI.generate(
3368
+ selection.focusNode,
3369
+ selection.focusOffset,
3370
+ `|[prose~anchor~${encodeURIComponent(item.id)}]`
3371
+ );
3772
3372
  }
3773
3373
  }
3774
3374
  };
@@ -3779,9 +3379,7 @@
3779
3379
  element$,
3780
3380
  context,
3781
3381
  pagination,
3782
- iframeEventBridgeElement$,
3783
3382
  spineItemManager,
3784
- hooks$,
3785
3383
  spineItemLocator,
3786
3384
  spineLocator,
3787
3385
  cfiLocator,
@@ -3789,18 +3387,13 @@
3789
3387
  navigationAdjusted$,
3790
3388
  currentNavigationPosition$,
3791
3389
  viewportState$,
3792
- settings
3390
+ settings,
3391
+ hookManager
3793
3392
  }) => {
3794
3393
  const spineItems$ = new rxjs.Subject();
3795
3394
  const itemsBeforeDestroySubject$ = new rxjs.Subject();
3796
3395
  const subject = new rxjs.Subject();
3797
3396
  const containerElement$ = new rxjs.BehaviorSubject(noopElement$1);
3798
- const eventsHelper = createEventsHelper({
3799
- context,
3800
- spineItemManager,
3801
- iframeEventBridgeElement$,
3802
- locator: spineLocator
3803
- });
3804
3397
  let selectionSubscription;
3805
3398
  const reload = (manifest) => {
3806
3399
  itemsBeforeDestroySubject$.next();
@@ -3809,11 +3402,10 @@
3809
3402
  const spineItem = createSpineItem({
3810
3403
  item: resource,
3811
3404
  containerElement: containerElement$.getValue(),
3812
- iframeEventBridgeElement$,
3813
3405
  context,
3814
- hooks$,
3815
3406
  viewportState$,
3816
- settings
3407
+ settings,
3408
+ hookManager
3817
3409
  });
3818
3410
  spineItemManager.add(spineItem);
3819
3411
  });
@@ -3832,7 +3424,7 @@
3832
3424
  var _a;
3833
3425
  (_a = spineItemManager.get(id)) == null ? void 0 : _a.manipulateSpineItem(cb);
3834
3426
  };
3835
- context.$.manifest$.pipe(operators.tap(reload), operators.takeUntil(context.$.destroy$)).subscribe();
3427
+ context.manifest$.pipe(operators.tap(reload), operators.takeUntil(context.destroy$)).subscribe();
3836
3428
  const waitForViewportFree$ = viewportState$.pipe(
3837
3429
  operators.filter((v) => v === `free`),
3838
3430
  operators.take(1)
@@ -3924,7 +3516,7 @@
3924
3516
  Report.error(e);
3925
3517
  return rxjs.EMPTY;
3926
3518
  }),
3927
- operators.takeUntil(context.$.destroy$)
3519
+ operators.takeUntil(context.destroy$)
3928
3520
  )
3929
3521
  ).subscribe();
3930
3522
  const itemUpdateOnNavigation$ = navigation$.pipe(
@@ -3950,7 +3542,10 @@
3950
3542
  beginSpineItem
3951
3543
  );
3952
3544
  const beginPageIndex = spineItemLocator.getSpineItemPageIndexFromPosition(beginPosition, beginSpineItem);
3953
- const endPosition = spineLocator.getSpineItemPositionFromSpinePosition(spineItemsFromPosition.endPosition, endSpineItem);
3545
+ const endPosition = spineLocator.getSpineItemPositionFromSpinePosition(
3546
+ spineItemsFromPosition.endPosition,
3547
+ endSpineItem
3548
+ );
3954
3549
  const endPageIndex = spineItemLocator.getSpineItemPageIndexFromPosition(endPosition, endSpineItem);
3955
3550
  const endItemIndex = spineItemManager.getSpineItemIndex(endSpineItem) ?? 0;
3956
3551
  pagination.updateBeginAndEnd(
@@ -3970,7 +3565,7 @@
3970
3565
  *
3971
3566
  * The cfi is later adjusted with heavy dom lookup once the viewport is free.
3972
3567
  */
3973
- cfi: (lastExpectedNavigation == null ? void 0 : lastExpectedNavigation.type) === `navigate-from-cfi` && spineItemToFocus === beginSpineItem ? lastExpectedNavigation.data : data.triggeredBy === `adjust` && settings.getSettings().computedPageTurnMode === `controlled` ? pagination.getPaginationInfo().beginCfi : beginItemIndex !== pagination.getPaginationInfo().beginSpineItemIndex ? cfiLocator.getRootCfi(beginSpineItem) : (
3568
+ cfi: (lastExpectedNavigation == null ? void 0 : lastExpectedNavigation.type) === `navigate-from-cfi` && spineItemToFocus === beginSpineItem ? lastExpectedNavigation.data : data.triggeredBy === `adjust` && settings.settings.computedPageTurnMode === `controlled` ? pagination.getPaginationInfo().beginCfi : beginItemIndex !== pagination.getPaginationInfo().beginSpineItemIndex ? cfiLocator.getRootCfi(beginSpineItem) : (
3974
3569
  /* @todo check ? */
3975
3570
  cfiLocator.getRootCfi(beginSpineItem)
3976
3571
  ),
@@ -3982,7 +3577,7 @@
3982
3577
  spineItem: endSpineItem,
3983
3578
  spineItemIndex: endItemIndex,
3984
3579
  pageIndex: endPageIndex,
3985
- cfi: (lastExpectedNavigation == null ? void 0 : lastExpectedNavigation.type) === `navigate-from-cfi` && spineItemToFocus === endSpineItem ? lastExpectedNavigation.data : data.triggeredBy === `adjust` && settings.getSettings().computedPageTurnMode === `controlled` ? pagination.getPaginationInfo().endCfi : endItemIndex !== pagination.getPaginationInfo().endSpineItemIndex ? cfiLocator.getRootCfi(endSpineItem) : (
3580
+ cfi: (lastExpectedNavigation == null ? void 0 : lastExpectedNavigation.type) === `navigate-from-cfi` && spineItemToFocus === endSpineItem ? lastExpectedNavigation.data : data.triggeredBy === `adjust` && settings.settings.computedPageTurnMode === `controlled` ? pagination.getPaginationInfo().endCfi : endItemIndex !== pagination.getPaginationInfo().endSpineItemIndex ? cfiLocator.getRootCfi(endSpineItem) : (
3986
3581
  /* @todo check ? */
3987
3582
  cfiLocator.getRootCfi(endSpineItem)
3988
3583
  ),
@@ -4006,13 +3601,13 @@
4006
3601
  time2();
4007
3602
  }),
4008
3603
  operators.share(),
4009
- operators.takeUntil(context.$.destroy$)
3604
+ operators.takeUntil(context.destroy$)
4010
3605
  );
4011
3606
  itemUpdateOnNavigation$.pipe(
4012
3607
  operators.switchMap((data) => {
4013
3608
  return adjustPagination(data.position).pipe(operators.takeUntil(spineItemManager.$.layout$));
4014
3609
  }),
4015
- operators.takeUntil(context.$.destroy$)
3610
+ operators.takeUntil(context.destroy$)
4016
3611
  ).subscribe();
4017
3612
  rxjs.merge(
4018
3613
  /**
@@ -4033,8 +3628,7 @@
4033
3628
  operators.map(([, currentNavigationPosition]) => {
4034
3629
  const focusedSpineItemIndex = spineItemManager.getFocusedSpineItemIndex();
4035
3630
  report.log(`update contents`, { focusedSpineItemIndex });
4036
- if (focusedSpineItemIndex === void 0)
4037
- return;
3631
+ if (focusedSpineItemIndex === void 0) return;
4038
3632
  const { begin = focusedSpineItemIndex, end = focusedSpineItemIndex } = spineLocator.getSpineItemsFromReadingOrderPosition(currentNavigationPosition) || {};
4039
3633
  if (begin !== focusedSpineItemIndex && end !== focusedSpineItemIndex) {
4040
3634
  Report.warn(`Current viewport is not in sync with focus item, load from focus item rather than viewport`);
@@ -4046,7 +3640,7 @@
4046
3640
  operators.take(1)
4047
3641
  );
4048
3642
  }),
4049
- operators.takeUntil(context.$.destroy$)
3643
+ operators.takeUntil(context.destroy$)
4050
3644
  ).subscribe();
4051
3645
  const elementSub = element$.pipe().subscribe((element) => {
4052
3646
  const containerElement = createContainerElement(element.ownerDocument);
@@ -4058,7 +3652,6 @@
4058
3652
  locator: spineLocator,
4059
3653
  spineItemLocator,
4060
3654
  cfiLocator,
4061
- normalizeEventForViewport: eventsHelper.normalizeEventForViewport,
4062
3655
  manipulateSpineItems,
4063
3656
  manipulateSpineItem,
4064
3657
  destroy: () => {
@@ -4105,16 +3698,16 @@
4105
3698
  const orderedSpineItemsSubject$ = new rxjs.BehaviorSubject([]);
4106
3699
  let focusedSpineItemIndex;
4107
3700
  const layout = () => {
4108
- const manifest = context.getManifest();
3701
+ const manifest = context.manifest;
4109
3702
  const newItemLayoutInformation = [];
4110
3703
  const isGloballyPrePaginated = (manifest == null ? void 0 : manifest.renditionLayout) === `pre-paginated`;
4111
3704
  orderedSpineItemsSubject$.value.reduce(
4112
3705
  ({ horizontalOffset, verticalOffset }, item, index) => {
4113
3706
  let minimumWidth = context.getPageSize().width;
4114
3707
  let blankPagePosition = `none`;
4115
- const itemStartOnNewScreen = horizontalOffset % context.getVisibleAreaRect().width === 0;
3708
+ const itemStartOnNewScreen = horizontalOffset % context.state.visibleAreaRect.width === 0;
4116
3709
  const isLastItem = index === orderedSpineItemsSubject$.value.length - 1;
4117
- if (context.isUsingSpreadMode()) {
3710
+ if (context.state.isUsingSpreadMode) {
4118
3711
  if (!isGloballyPrePaginated && item.item.renditionLayout === `reflowable` && !isLastItem) {
4119
3712
  minimumWidth = context.getPageSize().width * 2;
4120
3713
  }
@@ -4140,10 +3733,10 @@
4140
3733
  const { width, height } = item.layout({
4141
3734
  minimumWidth,
4142
3735
  blankPagePosition,
4143
- spreadPosition: context.isUsingSpreadMode() ? itemStartOnNewScreen ? context.isRTL() ? `right` : `left` : context.isRTL() ? `left` : `right` : `none`
3736
+ spreadPosition: context.state.isUsingSpreadMode ? itemStartOnNewScreen ? context.isRTL() ? `right` : `left` : context.isRTL() ? `left` : `right` : `none`
4144
3737
  });
4145
- if (settings.getSettings().computedPageTurnDirection === `vertical`) {
4146
- const currentValidEdgeYForVerticalPositioning = itemStartOnNewScreen ? verticalOffset : verticalOffset - context.getVisibleAreaRect().height;
3738
+ if (settings.settings.computedPageTurnDirection === `vertical`) {
3739
+ const currentValidEdgeYForVerticalPositioning = itemStartOnNewScreen ? verticalOffset : verticalOffset - context.state.visibleAreaRect.height;
4147
3740
  const currentValidEdgeXForVerticalPositioning = itemStartOnNewScreen ? 0 : horizontalOffset;
4148
3741
  if (context.isRTL()) {
4149
3742
  item.adjustPositionOfElement({
@@ -4171,11 +3764,13 @@
4171
3764
  verticalOffset: newEdgeY
4172
3765
  };
4173
3766
  }
4174
- item.adjustPositionOfElement(context.isRTL() ? { right: horizontalOffset, top: 0 } : { left: horizontalOffset, top: 0 });
3767
+ item.adjustPositionOfElement(
3768
+ context.isRTL() ? { right: horizontalOffset, top: 0 } : { left: horizontalOffset, top: 0 }
3769
+ );
4175
3770
  newItemLayoutInformation.push({
4176
3771
  ...context.isRTL() ? {
4177
- left: context.getVisibleAreaRect().width - horizontalOffset - width,
4178
- right: context.getVisibleAreaRect().width - horizontalOffset
3772
+ left: context.state.visibleAreaRect.width - horizontalOffset - width,
3773
+ right: context.state.visibleAreaRect.width - horizontalOffset
4179
3774
  } : {
4180
3775
  left: horizontalOffset,
4181
3776
  right: horizontalOffset + width
@@ -4192,27 +3787,27 @@
4192
3787
  },
4193
3788
  { horizontalOffset: 0, verticalOffset: 0 }
4194
3789
  );
4195
- const hasLayoutChanges = itemLayoutInformation.some((old, index) => !isShallowEqual(old, newItemLayoutInformation[index]));
3790
+ const hasLayoutChanges = itemLayoutInformation.some(
3791
+ (old, index) => !isShallowEqual(old, newItemLayoutInformation[index])
3792
+ );
4196
3793
  itemLayoutInformation = newItemLayoutInformation;
4197
3794
  Report.log(NAMESPACE$4, `layout`, { hasLayoutChanges, itemLayoutInformation });
4198
3795
  layout$.next(hasLayoutChanges);
4199
3796
  };
4200
3797
  const focus = (indexOrSpineItem) => {
4201
3798
  const spineItemToFocus = typeof indexOrSpineItem === `number` ? get(indexOrSpineItem) : indexOrSpineItem;
4202
- if (!spineItemToFocus)
4203
- return;
3799
+ if (!spineItemToFocus) return;
4204
3800
  const newActiveSpineItemIndex = orderedSpineItemsSubject$.value.indexOf(spineItemToFocus);
4205
- if (newActiveSpineItemIndex === focusedSpineItemIndex)
4206
- return;
3801
+ if (newActiveSpineItemIndex === focusedSpineItemIndex) return;
4207
3802
  focusedSpineItemIndex = newActiveSpineItemIndex;
4208
3803
  focus$.next({ data: spineItemToFocus });
4209
3804
  };
4210
3805
  const loadContents = Report.measurePerformance(`loadContents`, 10, (rangeOfIndex) => {
4211
3806
  var _a;
4212
3807
  const [leftIndex, rightIndex] = rangeOfIndex;
4213
- const numberOfAdjacentSpineItemToPreLoad = settings.getSettings().numberOfAdjacentSpineItemToPreLoad;
4214
- const isPrePaginated = ((_a = context.getManifest()) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
4215
- const isUsingFreeScroll = settings.getSettings().computedPageTurnMode === `scrollable`;
3808
+ const numberOfAdjacentSpineItemToPreLoad = settings.settings.numberOfAdjacentSpineItemToPreLoad;
3809
+ const isPrePaginated = ((_a = context.manifest) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
3810
+ const isUsingFreeScroll = settings.settings.computedPageTurnMode === `scrollable`;
4216
3811
  orderedSpineItemsSubject$.value.forEach((orderedSpineItem, index) => {
4217
3812
  const isBeforeFocusedWithPreload = (
4218
3813
  // we never want to preload anything before on free scroll on flow because it could offset the cursor
@@ -4253,25 +3848,28 @@
4253
3848
  return `before`;
4254
3849
  };
4255
3850
  const getSpineItemIndex = (spineItem) => {
4256
- if (!spineItem)
4257
- return void 0;
3851
+ if (!spineItem) return void 0;
4258
3852
  const index = orderedSpineItemsSubject$.value.indexOf(spineItem);
4259
3853
  return index < 0 ? void 0 : index;
4260
3854
  };
4261
3855
  const add = (spineItem) => {
4262
3856
  orderedSpineItemsSubject$.value.push(spineItem);
4263
- spineItem.$.contentLayout$.pipe(operators.takeUntil(context.$.destroy$)).subscribe(() => {
3857
+ spineItem.$.contentLayout$.pipe(operators.takeUntil(context.destroy$)).subscribe(() => {
4264
3858
  layout();
4265
3859
  });
4266
3860
  spineItem.$.loaded$.pipe(
4267
3861
  operators.tap(() => {
4268
3862
  if (spineItem.isUsingVerticalWriting()) {
4269
- context.setHasVerticalWriting(true);
3863
+ context.update({
3864
+ hasVerticalWriting: true
3865
+ });
4270
3866
  } else {
4271
- context.setHasVerticalWriting(false);
3867
+ context.update({
3868
+ hasVerticalWriting: false
3869
+ });
4272
3870
  }
4273
3871
  }),
4274
- operators.takeUntil(context.$.destroy$)
3872
+ operators.takeUntil(context.destroy$)
4275
3873
  ).subscribe();
4276
3874
  spineItem.load();
4277
3875
  };
@@ -4311,12 +3909,175 @@
4311
3909
  layout$: layout$.asObservable(),
4312
3910
  itemIsReady$: orderedSpineItemsSubject$.asObservable().pipe(
4313
3911
  operators.switchMap((items) => {
4314
- const itemsIsReady$ = items.map((item) => item.$.isReady$.pipe(operators.map((isReady) => ({ item: item.item, isReady }))));
3912
+ const itemsIsReady$ = items.map(
3913
+ (item) => item.$.isReady$.pipe(operators.map((isReady) => ({ item: item.item, isReady })))
3914
+ );
4315
3915
  return rxjs.merge(...itemsIsReady$);
4316
3916
  })
4317
3917
  )
4318
3918
  }
4319
- };
3919
+ };
3920
+ };
3921
+ const pointerEvents$1 = [
3922
+ `pointercancel`,
3923
+ `pointerdown`,
3924
+ `pointerenter`,
3925
+ `pointerleave`,
3926
+ `pointermove`,
3927
+ `pointerout`,
3928
+ `pointerover`,
3929
+ `pointerup`
3930
+ // `touchstart` as const,
3931
+ // `touchend` as const,
3932
+ ];
3933
+ const isHtmlElement = (element) => {
3934
+ return typeof element === `object` && !!element && `nodeType` in element && (element == null ? void 0 : element.nodeType) === Node.ELEMENT_NODE && `innerText` in element;
3935
+ };
3936
+ function createRangeOrCaretFromPoint(doc, startX, startY) {
3937
+ if (`caretPositionFromPoint` in doc) {
3938
+ return doc.caretPositionFromPoint(startX, startY);
3939
+ } else if (typeof doc.caretRangeFromPoint !== `undefined`) {
3940
+ return doc.caretRangeFromPoint(startX, startY);
3941
+ }
3942
+ }
3943
+ const getFirstVisibleNodeForViewport = Report.measurePerformance(
3944
+ `getFirstVisibleNodeForViewport`,
3945
+ 1,
3946
+ (documentOrElement, viewport) => {
3947
+ const element = `body` in documentOrElement ? getFirstVisibleElementForViewport(documentOrElement.body, viewport) : getFirstVisibleElementForViewport(documentOrElement, viewport);
3948
+ const ownerDocument = `createRange` in documentOrElement ? documentOrElement : documentOrElement.ownerDocument;
3949
+ if (element) {
3950
+ let lastValidRange;
3951
+ let lastValidOffset = 0;
3952
+ const range = ownerDocument.createRange();
3953
+ Array.from(element.childNodes).some((childNode) => {
3954
+ range.selectNodeContents(childNode);
3955
+ const rects = range.getClientRects();
3956
+ const visibleRect = getFirstVisibleDOMRect(rects, viewport);
3957
+ if (visibleRect) {
3958
+ lastValidRange = range.cloneRange();
3959
+ const rangeOrCaret = createRangeOrCaretFromPoint(
3960
+ ownerDocument,
3961
+ Math.ceil(visibleRect.left),
3962
+ Math.ceil(visibleRect.top)
3963
+ );
3964
+ if (rangeOrCaret && `startContainer` in rangeOrCaret && rangeOrCaret.startContainer === lastValidRange.startContainer) {
3965
+ lastValidOffset = rangeOrCaret.startOffset;
3966
+ }
3967
+ if (rangeOrCaret && `offsetNode` in rangeOrCaret && rangeOrCaret.offsetNode === lastValidRange.startContainer) {
3968
+ lastValidOffset = rangeOrCaret.offset;
3969
+ }
3970
+ return true;
3971
+ }
3972
+ return false;
3973
+ });
3974
+ if (lastValidRange) {
3975
+ return { node: lastValidRange.startContainer, offset: lastValidOffset };
3976
+ }
3977
+ return { node: element, offset: 0 };
3978
+ }
3979
+ return void 0;
3980
+ }
3981
+ );
3982
+ const getFirstVisibleElementForViewport = (element, viewport) => {
3983
+ let lastValidElement;
3984
+ const positionFromViewport = getElementOrNodePositionFromViewPort(element.getBoundingClientRect(), viewport);
3985
+ if (positionFromViewport !== `before` && positionFromViewport !== `after`) {
3986
+ lastValidElement = element;
3987
+ }
3988
+ Array.from(element.children).some((child) => {
3989
+ const childInViewPort = getFirstVisibleElementForViewport(child, viewport);
3990
+ if (childInViewPort) {
3991
+ lastValidElement = childInViewPort;
3992
+ return true;
3993
+ }
3994
+ return false;
3995
+ });
3996
+ return lastValidElement;
3997
+ };
3998
+ function getElementOrNodePositionFromViewPort(domRect, { left, right }) {
3999
+ if (domRect.left <= left && domRect.right <= left) return `before`;
4000
+ if (domRect.left <= left && domRect.right > left && domRect.right <= right) return `partially-before`;
4001
+ if (domRect.left <= right && domRect.right > right) return `partially-after`;
4002
+ if (domRect.left > right) return `after`;
4003
+ return `within`;
4004
+ }
4005
+ function getFirstVisibleDOMRect(domRect, viewport) {
4006
+ return Array.from(domRect).find((domRect2) => {
4007
+ const position = getElementOrNodePositionFromViewPort(domRect2, viewport);
4008
+ if (position !== `before` && position !== `after`) {
4009
+ return true;
4010
+ }
4011
+ return false;
4012
+ });
4013
+ }
4014
+ const getRangeFromNode = (node, offset) => {
4015
+ var _a;
4016
+ if (node.nodeType !== Node.CDATA_SECTION_NODE && node.nodeType !== Node.DOCUMENT_TYPE_NODE) {
4017
+ const range = (_a = node.ownerDocument) == null ? void 0 : _a.createRange();
4018
+ range == null ? void 0 : range.selectNodeContents(node);
4019
+ try {
4020
+ if (offset <= ((range == null ? void 0 : range.endOffset) || 0)) {
4021
+ range == null ? void 0 : range.setStart(node, offset || 0);
4022
+ }
4023
+ } catch (e) {
4024
+ Report.error(e);
4025
+ }
4026
+ return range;
4027
+ }
4028
+ return void 0;
4029
+ };
4030
+ const isPointerEvent = (event) => {
4031
+ var _a, _b, _c, _d, _e;
4032
+ if ((event == null ? void 0 : event.target) && ((_b = (_a = event == null ? void 0 : event.target) == null ? void 0 : _a.ownerDocument) == null ? void 0 : _b.defaultView)) {
4033
+ const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
4034
+ if (eventView.PointerEvent && event instanceof eventView.PointerEvent) {
4035
+ return true;
4036
+ }
4037
+ }
4038
+ if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
4039
+ const eventView = event == null ? void 0 : event.view;
4040
+ if (eventView.PointerEvent && event instanceof eventView.PointerEvent) {
4041
+ return true;
4042
+ }
4043
+ }
4044
+ if (pointerEvents$1.includes(event.type)) {
4045
+ return true;
4046
+ }
4047
+ return false;
4048
+ };
4049
+ const isMouseEvent = (event) => {
4050
+ var _a, _b, _c, _d, _e;
4051
+ if (isPointerEvent(event)) return false;
4052
+ if ((event == null ? void 0 : event.target) && ((_b = (_a = event == null ? void 0 : event.target) == null ? void 0 : _a.ownerDocument) == null ? void 0 : _b.defaultView)) {
4053
+ const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
4054
+ if (eventView.MouseEvent) {
4055
+ return event instanceof eventView.MouseEvent;
4056
+ }
4057
+ }
4058
+ if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
4059
+ const eventView = event == null ? void 0 : event.view;
4060
+ if (eventView.MouseEvent) {
4061
+ return event instanceof eventView.MouseEvent;
4062
+ }
4063
+ }
4064
+ return false;
4065
+ };
4066
+ const isTouchEvent = (event) => {
4067
+ var _a, _b, _c, _d, _e;
4068
+ if ((event == null ? void 0 : event.target) && ((_b = (_a = event == null ? void 0 : event.target) == null ? void 0 : _a.ownerDocument) == null ? void 0 : _b.defaultView)) {
4069
+ const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
4070
+ if (eventView.TouchEvent) {
4071
+ return event instanceof eventView.TouchEvent;
4072
+ }
4073
+ }
4074
+ if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
4075
+ const eventView = event == null ? void 0 : event.view;
4076
+ if (eventView.TouchEvent) {
4077
+ return event instanceof eventView.TouchEvent;
4078
+ }
4079
+ }
4080
+ return false;
4320
4081
  };
4321
4082
  const createLocationResolver$1 = ({ context }) => {
4322
4083
  const getSafePosition = (unsafeSpineItemPosition, spineItem) => ({
@@ -4416,10 +4177,8 @@
4416
4177
  };
4417
4178
  const getPageFromOffset = (offset, pageWidth, numberOfPages) => {
4418
4179
  const offsetValues = [...Array(numberOfPages)].map((_, i) => i * pageWidth);
4419
- if (offset <= 0)
4420
- return 0;
4421
- if (offset >= numberOfPages * pageWidth)
4422
- return numberOfPages - 1;
4180
+ if (offset <= 0) return 0;
4181
+ if (offset >= numberOfPages * pageWidth) return numberOfPages - 1;
4423
4182
  return Math.max(
4424
4183
  0,
4425
4184
  offsetValues.findIndex((offsetRange) => offset < offsetRange + pageWidth)
@@ -4455,7 +4214,10 @@
4455
4214
  y: position.y + context.getPageSize().height
4456
4215
  };
4457
4216
  }
4458
- const navigationPosition = spineItemLocator.getSpineItemClosestPositionFromUnsafePosition(nextPotentialPosition, spineItem);
4217
+ const navigationPosition = spineItemLocator.getSpineItemClosestPositionFromUnsafePosition(
4218
+ nextPotentialPosition,
4219
+ spineItem
4220
+ );
4459
4221
  return new SpineItemNavigationPosition(navigationPosition);
4460
4222
  };
4461
4223
  const getNavigationForRightPage = (position, spineItem) => {
@@ -4469,7 +4231,10 @@
4469
4231
  y: position.y - context.getPageSize().height
4470
4232
  };
4471
4233
  }
4472
- const navigationPosition = spineItemLocator.getSpineItemClosestPositionFromUnsafePosition(nextPotentialPosition, spineItem);
4234
+ const navigationPosition = spineItemLocator.getSpineItemClosestPositionFromUnsafePosition(
4235
+ nextPotentialPosition,
4236
+ spineItem
4237
+ );
4473
4238
  return new SpineItemNavigationPosition(navigationPosition);
4474
4239
  };
4475
4240
  const getNavigationForLastPage = (spineItem) => {
@@ -4492,7 +4257,10 @@
4492
4257
  return new SpineItemNavigationPosition(position || { x: 0, y: 0 });
4493
4258
  };
4494
4259
  const getNavigationForPosition = (spineItem, position) => {
4495
- const potentiallyCorrectedPosition = spineItemLocator.getSpineItemClosestPositionFromUnsafePosition(position, spineItem);
4260
+ const potentiallyCorrectedPosition = spineItemLocator.getSpineItemClosestPositionFromUnsafePosition(
4261
+ position,
4262
+ spineItem
4263
+ );
4496
4264
  return new SpineItemNavigationPosition(potentiallyCorrectedPosition);
4497
4265
  };
4498
4266
  return {
@@ -4538,7 +4306,7 @@
4538
4306
  { disable: true }
4539
4307
  );
4540
4308
  const getAdjustedPositionForSpread = ({ x, y }) => {
4541
- const isOffsetNotAtEdge = x % context.getVisibleAreaRect().width !== 0;
4309
+ const isOffsetNotAtEdge = x % context.state.visibleAreaRect.width !== 0;
4542
4310
  const correctedX = isOffsetNotAtEdge ? x - context.getPageSize().width : x;
4543
4311
  return { x: correctedX, y };
4544
4312
  };
@@ -4577,7 +4345,7 @@
4577
4345
  return { x: 0, y: 0 };
4578
4346
  };
4579
4347
  const getNavigationForRightSinglePage = (position) => {
4580
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4348
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4581
4349
  const spineItem = locator.getSpineItemFromPosition(position) || spineItemManager.getFocusedSpineItem();
4582
4350
  const defaultNavigation = position;
4583
4351
  if (!spineItem) {
@@ -4591,12 +4359,15 @@
4591
4359
  pageTurnDirection === `horizontal` ? { x: position.x + context.getPageSize().width, y: 0 } : { y: position.y + context.getPageSize().height, x: 0 }
4592
4360
  );
4593
4361
  } else {
4594
- const readingOrderPosition = locator.getSpinePositionFromSpineItemPosition(spineItemNavigationForRightPage, spineItem);
4362
+ const readingOrderPosition = locator.getSpinePositionFromSpineItemPosition(
4363
+ spineItemNavigationForRightPage,
4364
+ spineItem
4365
+ );
4595
4366
  return readingOrderPosition;
4596
4367
  }
4597
4368
  };
4598
4369
  const getNavigationForLeftSinglePage = (position) => {
4599
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4370
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4600
4371
  const spineItem = locator.getSpineItemFromPosition(position) || spineItemManager.getFocusedSpineItem();
4601
4372
  const defaultNavigation = { ...position, spineItem };
4602
4373
  if (!spineItem) {
@@ -4620,7 +4391,7 @@
4620
4391
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x === navigation.x) {
4621
4392
  return getAdjustedPositionForSpread(navigation);
4622
4393
  }
4623
- if (context.isUsingSpreadMode()) {
4394
+ if (context.state.isUsingSpreadMode) {
4624
4395
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x !== navigation.x) {
4625
4396
  return getAdjustedPositionForSpread(
4626
4397
  wrapPositionWithSafeEdge(
@@ -4634,7 +4405,7 @@
4634
4405
  )
4635
4406
  );
4636
4407
  }
4637
- if (settings.getSettings().computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4408
+ if (settings.settings.computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4638
4409
  return getAdjustedPositionForSpread(navigation);
4639
4410
  }
4640
4411
  const doubleNavigation = getNavigationForRightSinglePage(navigation);
@@ -4648,7 +4419,7 @@
4648
4419
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x === navigation.x) {
4649
4420
  return getAdjustedPositionForSpread(navigation);
4650
4421
  }
4651
- if (context.isUsingSpreadMode()) {
4422
+ if (context.state.isUsingSpreadMode) {
4652
4423
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x !== navigation.x) {
4653
4424
  return getAdjustedPositionForSpread(
4654
4425
  wrapPositionWithSafeEdge(
@@ -4656,7 +4427,7 @@
4656
4427
  )
4657
4428
  );
4658
4429
  }
4659
- if (settings.getSettings().computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4430
+ if (settings.settings.computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4660
4431
  return getAdjustedPositionForSpread(navigation);
4661
4432
  }
4662
4433
  const doubleNavigation = getNavigationForLeftSinglePage(navigation);
@@ -4669,7 +4440,7 @@
4669
4440
  try {
4670
4441
  const validUrl = url instanceof URL ? url : new URL(url);
4671
4442
  const urlWithoutAnchor = `${validUrl.origin}${validUrl.pathname}`;
4672
- const existingSpineItem = (_a = context.getManifest()) == null ? void 0 : _a.spineItems.find((item) => item.href === urlWithoutAnchor);
4443
+ const existingSpineItem = (_a = context.manifest) == null ? void 0 : _a.spineItems.find((item) => item.href === urlWithoutAnchor);
4673
4444
  if (existingSpineItem) {
4674
4445
  const spineItem = spineItemManager.get(existingSpineItem.id);
4675
4446
  if (spineItem) {
@@ -4698,15 +4469,15 @@
4698
4469
  return { x: 0, y: 0 };
4699
4470
  };
4700
4471
  const getMostPredominantNavigationForPosition = (viewportPosition) => {
4701
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4472
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4702
4473
  const triggerPercentage = 0.5;
4703
- const triggerXPosition = pageTurnDirection === `horizontal` ? viewportPosition.x + context.getVisibleAreaRect().width * triggerPercentage : 0;
4704
- const triggerYPosition = pageTurnDirection === `horizontal` ? 0 : viewportPosition.y + context.getVisibleAreaRect().height * triggerPercentage;
4474
+ const triggerXPosition = pageTurnDirection === `horizontal` ? viewportPosition.x + context.state.visibleAreaRect.width * triggerPercentage : 0;
4475
+ const triggerYPosition = pageTurnDirection === `horizontal` ? 0 : viewportPosition.y + context.state.visibleAreaRect.height * triggerPercentage;
4705
4476
  const midScreenPositionSafePosition = wrapPositionWithSafeEdge({ x: triggerXPosition, y: triggerYPosition });
4706
4477
  return getNavigationForPosition(midScreenPositionSafePosition);
4707
4478
  };
4708
4479
  const isNavigationGoingForwardFrom = (to, from) => {
4709
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4480
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4710
4481
  if (pageTurnDirection === `vertical`) {
4711
4482
  return to.y > from.y;
4712
4483
  }
@@ -4750,14 +4521,14 @@
4750
4521
  );
4751
4522
  const adjustReadingOffset = ({ x, y }) => {
4752
4523
  var _a;
4753
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
4524
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
4754
4525
  lastScrollWasProgrammaticallyTriggered = true;
4755
4526
  (_a = element$.getValue()) == null ? void 0 : _a.scrollTo({ left: x, top: y });
4756
4527
  return true;
4757
4528
  }
4758
4529
  return false;
4759
4530
  };
4760
- const runOnFreePageTurnModeOnly$ = (source) => settings.$.settings$.pipe(
4531
+ const runOnFreePageTurnModeOnly$ = (source) => settings.settings$.pipe(
4761
4532
  operators.map(({ computedPageTurnMode }) => computedPageTurnMode),
4762
4533
  operators.distinctUntilChanged(),
4763
4534
  operators.switchMap((mode) => rxjs.iif(() => mode === `controlled`, rxjs.EMPTY, source))
@@ -4767,12 +4538,11 @@
4767
4538
  operators.filter(isDefined),
4768
4539
  operators.switchMap((element) => rxjs.fromEvent(element, `scroll`))
4769
4540
  )
4770
- ).pipe(onlyUserScrollFilter, operators.share(), operators.takeUntil(context.$.destroy$));
4541
+ ).pipe(onlyUserScrollFilter, operators.share(), operators.takeUntil(context.destroy$));
4771
4542
  const getScaledDownPosition = ({ x, y }) => {
4772
4543
  var _a, _b;
4773
4544
  const spineElement = spine.getElement();
4774
- if (!spineElement)
4775
- throw new Error("Invalid spine element");
4545
+ if (!spineElement) throw new Error("Invalid spine element");
4776
4546
  const spineScaleX = spineElement.getBoundingClientRect().width / spineElement.offsetWidth;
4777
4547
  const scaledDownPosition = {
4778
4548
  x: getNewScaledOffset({
@@ -4815,7 +4585,7 @@
4815
4585
  const userScrollEnd$ = userScroll$.pipe(
4816
4586
  operators.debounceTime(SCROLL_FINISHED_DEBOUNCE_TIMEOUT, rxjs.animationFrameScheduler),
4817
4587
  operators.share(),
4818
- operators.takeUntil(context.$.destroy$)
4588
+ operators.takeUntil(context.destroy$)
4819
4589
  );
4820
4590
  const state$ = rxjs.merge(
4821
4591
  userScroll$.pipe(
@@ -4908,7 +4678,7 @@
4908
4678
  operators.filter((e) => e.type === `pageIndex`),
4909
4679
  operators.filter(() => {
4910
4680
  var _a;
4911
- if (((_a = context.getManifest()) == null ? void 0 : _a.renditionLayout) === `reflowable`) {
4681
+ if (((_a = context.manifest) == null ? void 0 : _a.renditionLayout) === `reflowable`) {
4912
4682
  Report.warn(`This method only works for pre-paginated content`);
4913
4683
  return false;
4914
4684
  }
@@ -4927,13 +4697,15 @@
4927
4697
  10,
4928
4698
  (navigation, { allowSpineItemChange = true } = {}) => {
4929
4699
  const currentSpineItem = spineItemManager.getFocusedSpineItem();
4930
- if (!currentSpineItem)
4931
- return rxjs.EMPTY;
4700
+ if (!currentSpineItem) return rxjs.EMPTY;
4932
4701
  const newSpineItem = locator.getSpineItemFromPosition(navigation) || currentSpineItem;
4933
4702
  const spineItemHasChanged = newSpineItem !== currentSpineItem;
4934
4703
  if (spineItemHasChanged) {
4935
4704
  if (allowSpineItemChange) {
4936
- const positionOfNewSpineItemComparedToCurrentOne = spineItemManager.comparePositionOf(newSpineItem, currentSpineItem);
4705
+ const positionOfNewSpineItemComparedToCurrentOne = spineItemManager.comparePositionOf(
4706
+ newSpineItem,
4707
+ currentSpineItem
4708
+ );
4937
4709
  if (positionOfNewSpineItemComparedToCurrentOne === `before`) {
4938
4710
  return rxjs.of({
4939
4711
  ...navigation,
@@ -5042,11 +4814,11 @@
5042
4814
  `${NAMESPACE$1} moveTo`,
5043
4815
  5,
5044
4816
  (delta, { final, start } = {}) => {
5045
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
4817
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5046
4818
  Report.warn(`pan control is not available on free page turn mode`);
5047
4819
  return;
5048
4820
  }
5049
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4821
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
5050
4822
  if (start) {
5051
4823
  stateSubject$.next(`start`);
5052
4824
  movingLastDelta = { x: 0, y: 0 };
@@ -5087,8 +4859,7 @@
5087
4859
  10,
5088
4860
  (navigation, { allowSpineItemChange = true } = {}) => {
5089
4861
  const currentSpineItem = spineItemManager.getFocusedSpineItem();
5090
- if (!currentSpineItem)
5091
- return void 0;
4862
+ if (!currentSpineItem) return void 0;
5092
4863
  const newSpineItem = locator.getSpineItemFromPosition(navigation) || currentSpineItem;
5093
4864
  const spineItemHasChanged = newSpineItem !== currentSpineItem;
5094
4865
  if (spineItemHasChanged) {
@@ -5106,7 +4877,7 @@
5106
4877
  );
5107
4878
  const snapNavigation$ = navigationTriggerSubject$.pipe(
5108
4879
  operators.filter((e) => e.type === `snap`),
5109
- rxjs.withLatestFrom(settings.$.settings$),
4880
+ rxjs.withLatestFrom(settings.settings$),
5110
4881
  operators.switchMap(
5111
4882
  ([
5112
4883
  {
@@ -5114,11 +4885,11 @@
5114
4885
  },
5115
4886
  { navigationSnapThreshold }
5116
4887
  ]) => {
5117
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4888
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
5118
4889
  const movingForward = navigator2.isNavigationGoingForwardFrom(to, from);
5119
4890
  const triggerPercentage = movingForward ? 1 - navigationSnapThreshold : navigationSnapThreshold;
5120
- const triggerXPosition = pageTurnDirection === `horizontal` ? to.x + context.getVisibleAreaRect().width * triggerPercentage : 0;
5121
- const triggerYPosition = pageTurnDirection === `horizontal` ? 0 : to.y + context.getVisibleAreaRect().height * triggerPercentage;
4891
+ const triggerXPosition = pageTurnDirection === `horizontal` ? to.x + context.state.visibleAreaRect.width * triggerPercentage : 0;
4892
+ const triggerYPosition = pageTurnDirection === `horizontal` ? 0 : to.y + context.state.visibleAreaRect.height * triggerPercentage;
5122
4893
  const midScreenPositionSafePosition = navigator2.wrapPositionWithSafeEdge({
5123
4894
  x: triggerXPosition,
5124
4895
  y: triggerYPosition
@@ -5155,7 +4926,7 @@
5155
4926
  parentElement$,
5156
4927
  cfiLocator,
5157
4928
  spineLocator,
5158
- hooks$,
4929
+ hookManager,
5159
4930
  spine,
5160
4931
  settings
5161
4932
  }) => {
@@ -5177,7 +4948,7 @@
5177
4948
  const adjustNavigationSubject$ = new rxjs.Subject();
5178
4949
  const getCurrentViewportPosition = Report.measurePerformance(`${NAMESPACE} getCurrentViewportPosition`, 1, () => {
5179
4950
  var _a;
5180
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
4951
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5181
4952
  return scrollViewportNavigator.getCurrentViewportPosition();
5182
4953
  }
5183
4954
  const { x, y } = ((_a = element$.getValue()) == null ? void 0 : _a.getBoundingClientRect()) ?? { x: 0, y: 0 };
@@ -5221,16 +4992,15 @@
5221
4992
  const viewportNavigatorsSharedState$ = rxjs.merge(...viewportNavigators.map(({ $: { state$: state$2 } }) => state$2));
5222
4993
  let lastUserExpectedNavigation;
5223
4994
  const makeItHot = (source$) => {
5224
- source$.pipe(operators.takeUntil(context.$.destroy$)).subscribe();
4995
+ source$.pipe(operators.takeUntil(context.destroy$)).subscribe();
5225
4996
  return source$;
5226
4997
  };
5227
4998
  const adjustReadingOffset = Report.measurePerformance(
5228
4999
  `adjustReadingOffset`,
5229
5000
  2,
5230
- ({ x, y }, hooks) => {
5001
+ ({ x, y }) => {
5231
5002
  const element = element$.getValue();
5232
- if (!element)
5233
- throw new Error("Invalid element");
5003
+ if (!element) throw new Error("Invalid element");
5234
5004
  currentViewportPositionMemoUnused = void 0;
5235
5005
  const isAdjusted = viewportNavigators.reduce((isAdjusted2, navigator22) => {
5236
5006
  return navigator22.adjustReadingOffset({ x, y }) || isAdjusted2;
@@ -5238,11 +5008,7 @@
5238
5008
  if (!isAdjusted) {
5239
5009
  element.style.transform = `translate3d(${-x}px, -${y}px, 0)`;
5240
5010
  }
5241
- hooks.forEach((hook) => {
5242
- if (hook.name === `onViewportOffsetAdjust`) {
5243
- hook.fn();
5244
- }
5245
- });
5011
+ hookManager.execute("onViewportOffsetAdjust", void 0, {});
5246
5012
  },
5247
5013
  { disable: true }
5248
5014
  );
@@ -5250,7 +5016,7 @@
5250
5016
  const lastCfi = pagination.getPaginationInfo().beginCfi;
5251
5017
  let adjustedSpinePosition = currentNavigationPositionSubject$.value;
5252
5018
  const offsetInSpineItem = 0;
5253
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
5019
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5254
5020
  adjustedSpinePosition = scrollViewportNavigator.getNavigationForPosition(getCurrentViewportPosition());
5255
5021
  } else if ((lastUserExpectedNavigation == null ? void 0 : lastUserExpectedNavigation.type) === `navigate-from-cfi`) {
5256
5022
  adjustedSpinePosition = navigator2.getNavigationForCfi(lastUserExpectedNavigation.data);
@@ -5295,7 +5061,7 @@
5295
5061
  layoutSubject$.subscribe(() => {
5296
5062
  currentViewportPositionMemoUnused = void 0;
5297
5063
  });
5298
- const layoutChangeSettings$ = settings.$.settings$.pipe(
5064
+ const layoutChangeSettings$ = settings.settings$.pipe(
5299
5065
  mapKeysTo([`computedPageTurnDirection`, `computedPageTurnMode`, `numberOfAdjacentSpineItemToPreLoad`]),
5300
5066
  operators.distinctUntilChanged(isShallowEqual),
5301
5067
  operators.skip(1)
@@ -5303,7 +5069,7 @@
5303
5069
  const layout$ = rxjs.merge(layoutSubject$, layoutChangeSettings$).pipe(
5304
5070
  operators.withLatestFrom(element$),
5305
5071
  operators.tap(([, element]) => {
5306
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
5072
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5307
5073
  element.style.removeProperty(`transform`);
5308
5074
  element.style.removeProperty(`transition`);
5309
5075
  element.style.overflow = `scroll`;
@@ -5355,11 +5121,11 @@
5355
5121
  return { ...event, lastUserExpectedNavigation };
5356
5122
  }),
5357
5123
  operators.share(),
5358
- operators.takeUntil(context.$.destroy$)
5124
+ operators.takeUntil(context.destroy$)
5359
5125
  );
5360
5126
  const navigationWhichRequireManualAdjust$ = navigation$.pipe(
5361
5127
  operators.filter(({ triggeredBy }) => {
5362
- if (triggeredBy === `scroll` || settings.getSettings().computedPageTurnMode === `scrollable` && triggeredBy === `adjust`) {
5128
+ if (triggeredBy === `scroll` || settings.settings.computedPageTurnMode === `scrollable` && triggeredBy === `adjust`) {
5363
5129
  return false;
5364
5130
  } else {
5365
5131
  return true;
@@ -5371,7 +5137,7 @@
5371
5137
  navigationWhichRequireManualAdjust$
5372
5138
  ).pipe(
5373
5139
  operators.map(({ animation, position }) => {
5374
- const shouldAnimate = !(!animation || animation === `turn` && settings.getSettings().computedPageTurnAnimation === `none`);
5140
+ const shouldAnimate = !(!animation || animation === `turn` && settings.settings.computedPageTurnAnimation === `none`);
5375
5141
  return {
5376
5142
  type: `manualAdjust`,
5377
5143
  shouldAnimate,
@@ -5391,10 +5157,9 @@
5391
5157
  }
5392
5158
  }),
5393
5159
  operators.switchMap(([, currentEvent]) => {
5394
- if ((currentEvent == null ? void 0 : currentEvent.type) !== `manualAdjust`)
5395
- return rxjs.EMPTY;
5396
- const animationDuration = currentEvent.animation === `snap` ? settings.getSettings().computedSnapAnimationDuration : settings.getSettings().computedPageTurnAnimationDuration;
5397
- const pageTurnAnimation = currentEvent.animation === `snap` ? `slide` : settings.getSettings().computedPageTurnAnimation;
5160
+ if ((currentEvent == null ? void 0 : currentEvent.type) !== `manualAdjust`) return rxjs.EMPTY;
5161
+ const animationDuration = currentEvent.animation === `snap` ? settings.settings.computedSnapAnimationDuration : settings.settings.computedPageTurnAnimationDuration;
5162
+ const pageTurnAnimation = currentEvent.animation === `snap` ? `slide` : settings.settings.computedPageTurnAnimation;
5398
5163
  return rxjs.of(currentEvent).pipe(
5399
5164
  /**
5400
5165
  * @important
@@ -5428,23 +5193,22 @@
5428
5193
  * need to adjust to anchor to the payload position. This is because we use viewport computed position,
5429
5194
  * not the value set by `setProperty`
5430
5195
  */
5431
- operators.withLatestFrom(hooks$),
5432
- operators.tap(([data, hooks]) => {
5196
+ operators.tap((data) => {
5433
5197
  if (pageTurnAnimation !== `fade`) {
5434
- adjustReadingOffset(data.position, hooks);
5198
+ adjustReadingOffset(data.position);
5435
5199
  }
5436
5200
  }),
5437
5201
  currentEvent.shouldAnimate ? operators.delay(animationDuration / 2, rxjs.animationFrameScheduler) : rxjs.identity,
5438
- operators.tap(([data, hooks]) => {
5202
+ operators.tap((data) => {
5439
5203
  if (pageTurnAnimation === `fade`) {
5440
- adjustReadingOffset(data.position, hooks);
5204
+ adjustReadingOffset(data.position);
5441
5205
  element$.getValue().style.setProperty(`opacity`, `1`);
5442
5206
  }
5443
5207
  }),
5444
5208
  currentEvent.shouldAnimate ? operators.delay(animationDuration / 2, rxjs.animationFrameScheduler) : rxjs.identity,
5445
- operators.tap(([data, hooks]) => {
5209
+ operators.tap((data) => {
5446
5210
  if (pageTurnAnimation === `fade`) {
5447
- adjustReadingOffset(data.position, hooks);
5211
+ adjustReadingOffset(data.position);
5448
5212
  }
5449
5213
  }),
5450
5214
  operators.takeUntil(
@@ -5456,7 +5220,7 @@
5456
5220
  );
5457
5221
  }),
5458
5222
  operators.share(),
5459
- operators.takeUntil(context.$.destroy$)
5223
+ operators.takeUntil(context.destroy$)
5460
5224
  );
5461
5225
  const adjustmentState$ = rxjs.merge(
5462
5226
  rxjs.merge(manualAdjust$).pipe(operators.map(() => `start`)),
@@ -5501,8 +5265,7 @@
5501
5265
  () => waitForViewportFree$.pipe(
5502
5266
  operators.switchMap(() => {
5503
5267
  const focusedSpineItem = spineItemManager.getFocusedSpineItem();
5504
- if (!focusedSpineItem)
5505
- return rxjs.EMPTY;
5268
+ if (!focusedSpineItem) return rxjs.EMPTY;
5506
5269
  return adjustNavigation(focusedSpineItem);
5507
5270
  }),
5508
5271
  operators.takeUntil(navigation$)
@@ -5511,7 +5274,7 @@
5511
5274
  operators.share()
5512
5275
  );
5513
5276
  const parentElementSub = parentElement$.pipe(operators.filter(isDefined), operators.withLatestFrom(spine.element$)).subscribe(([parentElement, spineElement]) => {
5514
- const element = createElement(parentElement.ownerDocument, hooks$);
5277
+ const element = createElement(parentElement.ownerDocument, hookManager);
5515
5278
  element.appendChild(spineElement);
5516
5279
  parentElement.appendChild(element);
5517
5280
  element$.next(element);
@@ -5547,19 +5310,15 @@
5547
5310
  }
5548
5311
  };
5549
5312
  };
5550
- const createElement = (doc, hooks$) => {
5313
+ const createElement = (doc, hookManager) => {
5551
5314
  const element = doc.createElement(`div`);
5552
5315
  element.style.cssText = `
5553
5316
  height: 100%;
5554
5317
  position: relative;
5555
5318
  `;
5556
5319
  element.className = `${HTML_PREFIX$1}-viewport-navigator`;
5557
- return hooks$.getValue().reduce((element2, hook) => {
5558
- if (hook.name === `viewportNavigator.onBeforeContainerCreated`) {
5559
- return hook.fn(element2);
5560
- }
5561
- return element2;
5562
- }, element);
5320
+ hookManager.execute("viewportNavigator.onBeforeContainerCreated", void 0, { element });
5321
+ return element;
5563
5322
  };
5564
5323
  const createLocationResolver = ({
5565
5324
  spineItemManager,
@@ -5600,7 +5359,7 @@
5600
5359
  const spineItem = spineItemManager.getAll().find((item) => {
5601
5360
  const { left, right, bottom, top } = spineItemManager.getAbsolutePositionOf(item);
5602
5361
  const isWithinXAxis = position.x >= left && position.x < right;
5603
- if (settings.getSettings().computedPageTurnDirection === `horizontal`) {
5362
+ if (settings.settings.computedPageTurnDirection === `horizontal`) {
5604
5363
  return isWithinXAxis;
5605
5364
  } else {
5606
5365
  return isWithinXAxis && position.y >= top && position.y < bottom;
@@ -5624,13 +5383,14 @@
5624
5383
  const getSpineItemsFromReadingOrderPosition = (position) => {
5625
5384
  const itemAtPosition = getSpineItemFromPosition(position) || spineItemManager.getFocusedSpineItem();
5626
5385
  const itemAtPositionIndex = spineItemManager.getSpineItemIndex(itemAtPosition);
5627
- if (itemAtPositionIndex === void 0)
5628
- return void 0;
5386
+ if (itemAtPositionIndex === void 0) return void 0;
5629
5387
  let endPosition = position;
5630
- if (context.isUsingSpreadMode()) {
5388
+ if (context.state.isUsingSpreadMode) {
5631
5389
  endPosition = { x: position.x + context.getPageSize().width, y: position.y };
5632
5390
  }
5633
- const endItemIndex = spineItemManager.getSpineItemIndex(getSpineItemFromPosition(endPosition) || spineItemManager.getFocusedSpineItem()) ?? itemAtPositionIndex;
5391
+ const endItemIndex = spineItemManager.getSpineItemIndex(
5392
+ getSpineItemFromPosition(endPosition) || spineItemManager.getFocusedSpineItem()
5393
+ ) ?? itemAtPositionIndex;
5634
5394
  const items = [
5635
5395
  { item: itemAtPositionIndex, position },
5636
5396
  { item: endItemIndex, position: endPosition }
@@ -5710,12 +5470,10 @@
5710
5470
  };
5711
5471
  const resolveCfi = (cfiString) => {
5712
5472
  var _a, _b, _c;
5713
- if (!cfiString)
5714
- return void 0;
5473
+ if (!cfiString) return void 0;
5715
5474
  const spineItem = getSpineItemFromCfi(cfiString);
5716
5475
  const spineItemIndex = spineItemManager.getSpineItemIndex(spineItem) || 0;
5717
- if (!spineItem)
5718
- return void 0;
5476
+ if (!spineItem) return void 0;
5719
5477
  const { cleanedCfi, offset } = extractProseMetadataFromCfi(cfiString);
5720
5478
  const cfi = new CFI(cleanedCfi, {});
5721
5479
  const doc = (_c = (_b = (_a = spineItem.spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame) == null ? void 0 : _b.contentWindow) == null ? void 0 : _c.document;
@@ -5748,80 +5506,164 @@
5748
5506
  generateFromRange
5749
5507
  };
5750
5508
  };
5751
- const areAllItemsPrePaginated = (manifest) => !(manifest == null ? void 0 : manifest.spineItems.some((item) => item.renditionLayout === `reflowable`));
5752
- const createSettings = (initialSettings) => {
5753
- const mergedSettings = {
5754
- forceSinglePageMode: false,
5755
- pageTurnAnimation: `none`,
5756
- computedPageTurnAnimation: `none`,
5757
- pageTurnDirection: `horizontal`,
5758
- computedPageTurnDirection: `horizontal`,
5759
- pageTurnAnimationDuration: void 0,
5760
- computedPageTurnAnimationDuration: 0,
5761
- pageTurnMode: `controlled`,
5509
+ const getComputedSettings = (settings, context) => {
5510
+ const manifest = context.manifest;
5511
+ const hasVerticalWriting = context.state.hasVerticalWriting ?? false;
5512
+ const computedSettings = {
5513
+ computedPageTurnDirection: settings.pageTurnDirection,
5514
+ computedPageTurnAnimation: settings.pageTurnAnimation,
5762
5515
  computedPageTurnMode: `controlled`,
5763
- computedSnapAnimationDuration: 300,
5764
- navigationSnapThreshold: 0.3,
5765
- numberOfAdjacentSpineItemToPreLoad: 0,
5766
- ...initialSettings
5767
- };
5768
- updateComputedSettings(void 0, mergedSettings, false);
5769
- const settingsSubject$ = new rxjs.BehaviorSubject(mergedSettings);
5770
- const setSettings = (newSettings, options) => {
5771
- if (Object.keys(newSettings).length === 0)
5772
- return;
5773
- const newMergedSettings = { ...settingsSubject$.value, ...newSettings };
5774
- updateComputedSettings(options.manifest, newMergedSettings, options.hasVerticalWriting ?? false);
5775
- settingsSubject$.next(newMergedSettings);
5776
- };
5777
- const recompute = (options) => {
5778
- const newMergedSettings = { ...settingsSubject$.value };
5779
- updateComputedSettings(options.manifest, newMergedSettings, options.hasVerticalWriting ?? false);
5780
- settingsSubject$.next(newMergedSettings);
5781
- };
5782
- const destroy = () => {
5783
- settingsSubject$.complete();
5784
- };
5785
- return {
5786
- getSettings: () => settingsSubject$.value,
5787
- setSettings,
5788
- recompute,
5789
- destroy,
5790
- $: {
5791
- settings$: settingsSubject$.asObservable().pipe(operators.distinctUntilChanged(isShallowEqual))
5792
- }
5516
+ computedPageTurnAnimationDuration: 0,
5517
+ computedSnapAnimationDuration: 0
5793
5518
  };
5794
- };
5795
- const updateComputedSettings = (newManifest, settings, hasVerticalWriting) => {
5796
- settings.computedPageTurnDirection = settings.pageTurnDirection;
5797
- settings.computedPageTurnAnimation = settings.pageTurnAnimation;
5798
- settings.computedPageTurnMode = `controlled`;
5799
- if ((newManifest == null ? void 0 : newManifest.renditionFlow) === `scrolled-continuous`) {
5800
- settings.computedPageTurnMode = `scrollable`;
5801
- settings.computedPageTurnDirection = `vertical`;
5802
- } else if (newManifest && settings.pageTurnMode === `scrollable` && (newManifest.renditionLayout !== `pre-paginated` || !areAllItemsPrePaginated(newManifest))) {
5519
+ if ((manifest == null ? void 0 : manifest.renditionFlow) === `scrolled-continuous`) {
5520
+ computedSettings.computedPageTurnMode = `scrollable`;
5521
+ computedSettings.computedPageTurnDirection = `vertical`;
5522
+ } else if (manifest && settings.pageTurnMode === `scrollable` && (manifest.renditionLayout !== `pre-paginated` || !areAllItemsPrePaginated(manifest))) {
5803
5523
  Report.warn(`pageTurnMode ${settings.pageTurnMode} incompatible with current book, switching back to default`);
5804
- settings.computedPageTurnAnimation = `none`;
5805
- settings.computedPageTurnMode = `controlled`;
5524
+ computedSettings.computedPageTurnAnimation = `none`;
5525
+ computedSettings.computedPageTurnMode = `controlled`;
5806
5526
  } else if (settings.pageTurnMode === `scrollable`) {
5807
- settings.computedPageTurnMode = `scrollable`;
5808
- settings.computedPageTurnDirection = `vertical`;
5527
+ computedSettings.computedPageTurnMode = `scrollable`;
5528
+ computedSettings.computedPageTurnDirection = `vertical`;
5809
5529
  }
5810
- if (hasVerticalWriting && settings.computedPageTurnAnimation === `slide`) {
5530
+ if (hasVerticalWriting && computedSettings.computedPageTurnAnimation === `slide`) {
5811
5531
  Report.warn(
5812
- `pageTurnAnimation ${settings.computedPageTurnAnimation} incompatible with current book, switching back to default`
5532
+ `pageTurnAnimation ${computedSettings.computedPageTurnAnimation} incompatible with current book, switching back to default`
5813
5533
  );
5814
- settings.computedPageTurnAnimation = `none`;
5534
+ computedSettings.computedPageTurnAnimation = `none`;
5815
5535
  }
5816
- if (settings.computedPageTurnMode === `scrollable`) {
5817
- settings.computedPageTurnAnimationDuration = 0;
5818
- settings.computedPageTurnAnimation = `none`;
5536
+ if (computedSettings.computedPageTurnMode === `scrollable`) {
5537
+ computedSettings.computedPageTurnAnimationDuration = 0;
5538
+ computedSettings.computedPageTurnAnimation = `none`;
5819
5539
  } else {
5820
- settings.computedPageTurnAnimationDuration = settings.pageTurnAnimationDuration !== void 0 ? settings.pageTurnAnimationDuration : 300;
5540
+ computedSettings.computedPageTurnAnimationDuration = settings.pageTurnAnimationDuration !== void 0 ? settings.pageTurnAnimationDuration : 300;
5821
5541
  }
5542
+ return computedSettings;
5822
5543
  };
5823
- const IFRAME_EVENT_BRIDGE_ELEMENT_ID = `proseReaderIframeEventBridgeElement`;
5824
- const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5544
+ const defaultSettings = {
5545
+ forceSinglePageMode: false,
5546
+ pageTurnAnimation: `none`,
5547
+ // computedPageTurnAnimation: `none`,
5548
+ pageTurnDirection: `horizontal`,
5549
+ // computedPageTurnDirection: `horizontal`,
5550
+ pageTurnAnimationDuration: void 0,
5551
+ // computedPageTurnAnimationDuration: 0,
5552
+ pageTurnMode: `controlled`,
5553
+ // computedPageTurnMode: `controlled`,
5554
+ // computedSnapAnimationDuration: 300,
5555
+ navigationSnapThreshold: 0.3,
5556
+ numberOfAdjacentSpineItemToPreLoad: 0
5557
+ };
5558
+ class SettingsManager {
5559
+ constructor(initialSettings, context) {
5560
+ this._context = context;
5561
+ const settingsWithDefaults = {
5562
+ ...defaultSettings,
5563
+ ...initialSettings
5564
+ };
5565
+ const computedSettings = getComputedSettings(settingsWithDefaults, context);
5566
+ const settings = { ...settingsWithDefaults, ...computedSettings };
5567
+ this._settingsSubject$ = new rxjs.BehaviorSubject(settings);
5568
+ this.settings$ = this._settingsSubject$.asObservable().pipe(operators.distinctUntilChanged(isShallowEqual));
5569
+ const recomputeSettingsOnContextChange$ = rxjs.combineLatest([context.hasVerticalWriting$, context.manifest$]).pipe(
5570
+ operators.tap(() => {
5571
+ this._updateSettings(this.settings);
5572
+ })
5573
+ );
5574
+ const updateContextOnSettingsChanges$ = this._settingsSubject$.pipe(
5575
+ operators.tap(({ forceSinglePageMode }) => {
5576
+ context.update({ forceSinglePageMode });
5577
+ })
5578
+ );
5579
+ rxjs.merge(recomputeSettingsOnContextChange$, updateContextOnSettingsChanges$).pipe(operators.takeUntil(context.destroy$)).subscribe();
5580
+ }
5581
+ // @see https://github.com/microsoft/TypeScript/issues/17293
5582
+ _updateSettings(settings) {
5583
+ const computed = getComputedSettings(settings, this._context);
5584
+ const newMergedSettings = { ...settings, ...computed };
5585
+ this._settingsSubject$.next(newMergedSettings);
5586
+ }
5587
+ setSettings(settings) {
5588
+ if (Object.keys(settings).length === 0) return;
5589
+ const newMergedSettings = { ...this._settingsSubject$.value, ...settings };
5590
+ this._updateSettings(newMergedSettings);
5591
+ }
5592
+ get settings() {
5593
+ return this._settingsSubject$.getValue();
5594
+ }
5595
+ destroy() {
5596
+ this._settingsSubject$.complete();
5597
+ }
5598
+ }
5599
+ class HookManager {
5600
+ constructor() {
5601
+ this._hooks = [];
5602
+ this._hookExecutions = [];
5603
+ }
5604
+ /**
5605
+ * Will:
5606
+ * - call destroy function for every execution of this specific hook
5607
+ * - remove the hook for further calls
5608
+ */
5609
+ deregister(hookToDeregister) {
5610
+ this._hooks = this._hooks.filter((hook) => hook !== hookToDeregister);
5611
+ return this.destroy(hookToDeregister.name, void 0, hookToDeregister);
5612
+ }
5613
+ /**
5614
+ * Ideal when your logic only needs to apply something to the item when it's loaded.
5615
+ * You can manipulate your item later if you need to update it and trigger a layout.
5616
+ * This logic will not run every time there is a layout.
5617
+ */
5618
+ register(name, fn) {
5619
+ const hook = {
5620
+ name,
5621
+ runFn: fn
5622
+ };
5623
+ this._hooks.push(hook);
5624
+ return () => {
5625
+ this.deregister(hook);
5626
+ };
5627
+ }
5628
+ execute(name, id, params) {
5629
+ const hooks = this._hooks.filter((hook) => name === hook.name);
5630
+ const fnResults = hooks.map((hook) => {
5631
+ let userDestroyFn = () => rxjs.of(void 0);
5632
+ const destroySubject = new rxjs.Subject();
5633
+ const destroy = (fn) => {
5634
+ userDestroyFn = fn;
5635
+ };
5636
+ const destroyFn = () => {
5637
+ destroySubject.next();
5638
+ destroySubject.complete();
5639
+ const result = userDestroyFn();
5640
+ return result ?? rxjs.of(void 0);
5641
+ };
5642
+ const fnResult = hook.runFn({ ...params, destroy$: destroySubject.asObservable(), destroy });
5643
+ this._hookExecutions.push({
5644
+ name,
5645
+ id,
5646
+ destroyFn,
5647
+ ref: hook
5648
+ });
5649
+ return fnResult;
5650
+ });
5651
+ return fnResults;
5652
+ }
5653
+ destroy(name, id, ref) {
5654
+ const instances = this._hookExecutions.filter(
5655
+ (hookInstance) => (
5656
+ // by ref is higher priority
5657
+ ref && hookInstance.ref === ref || // otherwise we refine by name and eventually by id
5658
+ name === hookInstance.name && (!id || id && id === hookInstance.id)
5659
+ )
5660
+ );
5661
+ this._hookExecutions = this._hookExecutions.filter((instance) => !instances.includes(instance));
5662
+ const destroyFns = instances.map(({ destroyFn }) => destroyFn());
5663
+ return rxjs.combineLatest(destroyFns);
5664
+ }
5665
+ }
5666
+ const createReader = (inputSettings) => {
5825
5667
  const stateSubject$ = new rxjs.BehaviorSubject({
5826
5668
  supportedPageTurnAnimation: [`fade`, `none`, `slide`],
5827
5669
  supportedPageTurnMode: [`controlled`, `scrollable`],
@@ -5830,24 +5672,23 @@
5830
5672
  });
5831
5673
  const destroy$ = new rxjs.Subject();
5832
5674
  const selectionSubject$ = new rxjs.Subject();
5833
- const hooksSubject$ = new rxjs.BehaviorSubject(initialHooks || []);
5834
5675
  const navigationSubject = new rxjs.Subject();
5835
5676
  const navigationAdjustedSubject = new rxjs.Subject();
5836
5677
  const currentNavigationPositionSubject$ = new rxjs.BehaviorSubject({ x: 0, y: 0 });
5837
5678
  const viewportStateSubject = new rxjs.BehaviorSubject(`free`);
5838
- const settings = createSettings(inputSettings);
5839
- const context = createContext(settings);
5840
- const spineItemManager = createSpineItemManager({ context, settings });
5679
+ const hookManager = new HookManager();
5680
+ const context = new Context();
5681
+ const settingsManager = new SettingsManager(inputSettings, context);
5682
+ const spineItemManager = createSpineItemManager({ context, settings: settingsManager });
5841
5683
  const pagination = createPagination({ context, spineItemManager });
5842
5684
  const elementSubject$ = new rxjs.BehaviorSubject(void 0);
5843
5685
  const element$ = elementSubject$.pipe(operators.filter(isDefined));
5844
- const iframeEventBridgeElement$ = new rxjs.BehaviorSubject(void 0);
5845
5686
  const spineItemLocator = createLocationResolver$1({ context });
5846
5687
  const spineLocator = createLocationResolver({
5847
5688
  context,
5848
5689
  spineItemManager,
5849
5690
  spineItemLocator,
5850
- settings
5691
+ settings: settingsManager
5851
5692
  });
5852
5693
  const cfiLocator = createCfiLocator({
5853
5694
  spineItemManager,
@@ -5857,19 +5698,18 @@
5857
5698
  const navigation$ = navigationSubject.asObservable();
5858
5699
  const spine = createSpine({
5859
5700
  element$,
5860
- iframeEventBridgeElement$,
5861
5701
  context,
5862
- settings,
5702
+ settings: settingsManager,
5863
5703
  pagination,
5864
5704
  spineItemManager,
5865
- hooks$: hooksSubject$,
5866
5705
  navigation$,
5867
5706
  spineLocator,
5868
5707
  spineItemLocator,
5869
5708
  cfiLocator,
5870
5709
  navigationAdjusted$: navigationAdjustedSubject.asObservable(),
5871
5710
  viewportState$: viewportStateSubject.asObservable(),
5872
- currentNavigationPosition$: currentNavigationPositionSubject$.asObservable()
5711
+ currentNavigationPosition$: currentNavigationPositionSubject$.asObservable(),
5712
+ hookManager
5873
5713
  });
5874
5714
  const viewportNavigator = createViewportNavigator({
5875
5715
  context,
@@ -5878,9 +5718,9 @@
5878
5718
  parentElement$: elementSubject$,
5879
5719
  cfiLocator,
5880
5720
  spineLocator,
5881
- hooks$: hooksSubject$,
5721
+ hookManager,
5882
5722
  spine,
5883
- settings
5723
+ settings: settingsManager
5884
5724
  });
5885
5725
  viewportNavigator.$.state$.subscribe(viewportStateSubject);
5886
5726
  viewportNavigator.$.navigation$.subscribe(navigationSubject);
@@ -5890,8 +5730,7 @@
5890
5730
  var _a;
5891
5731
  const containerElement = (_a = elementSubject$.getValue()) == null ? void 0 : _a.parentElement;
5892
5732
  const element = elementSubject$.getValue();
5893
- if (!element || !containerElement)
5894
- throw new Error("Invalid element");
5733
+ if (!element || !containerElement) throw new Error("Invalid element");
5895
5734
  const dimensions = {
5896
5735
  width: containerElement == null ? void 0 : containerElement.offsetWidth,
5897
5736
  height: containerElement == null ? void 0 : containerElement.offsetHeight
@@ -5906,30 +5745,29 @@
5906
5745
  element.style.height = `${dimensions.height - marginTop - marginBottom}px`;
5907
5746
  element.style.width = `${containerElementEvenWidth - 2 * margin}px`;
5908
5747
  const elementRect = element.getBoundingClientRect();
5909
- context.setVisibleAreaRect({
5910
- x: elementRect.x,
5911
- y: elementRect.y,
5912
- width: containerElementEvenWidth,
5913
- height: dimensions.height
5748
+ context.update({
5749
+ visibleAreaRect: {
5750
+ x: elementRect.x,
5751
+ y: elementRect.y,
5752
+ width: containerElementEvenWidth,
5753
+ height: dimensions.height
5754
+ }
5914
5755
  });
5915
5756
  viewportNavigator.layout();
5916
5757
  };
5917
5758
  const load = (manifest, loadOptions) => {
5918
5759
  var _a;
5919
- if (context.getManifest()) {
5760
+ if (context.manifest) {
5920
5761
  Report.warn(`loading a new book is not supported yet`);
5921
5762
  return;
5922
5763
  }
5923
5764
  Report.log(`load`, { manifest, loadOptions });
5924
5765
  const element = createWrapperElement(loadOptions.containerElement);
5925
- const iframeEventBridgeElement = createIframeEventBridgeElement(loadOptions.containerElement);
5926
5766
  if (loadOptions.containerElement !== ((_a = elementSubject$.getValue()) == null ? void 0 : _a.parentElement)) {
5927
5767
  elementSubject$.next(element);
5928
- iframeEventBridgeElement$.next(iframeEventBridgeElement);
5929
5768
  loadOptions.containerElement.appendChild(element);
5930
- element.appendChild(iframeEventBridgeElement);
5931
5769
  }
5932
- context.load(manifest, loadOptions);
5770
+ context.update({ manifest, ...loadOptions, forceSinglePageMode: settingsManager.settings.forceSinglePageMode });
5933
5771
  layout();
5934
5772
  if (!loadOptions.cfi) {
5935
5773
  viewportNavigator.goToSpineItem(0, { animate: false });
@@ -5937,9 +5775,6 @@
5937
5775
  viewportNavigator.goToCfi(loadOptions.cfi, { animate: false });
5938
5776
  }
5939
5777
  };
5940
- const registerHook = (name, fn) => {
5941
- hooksSubject$.next([...hooksSubject$.getValue(), { name, fn }]);
5942
- };
5943
5778
  spine.$.$.pipe(
5944
5779
  operators.tap((event) => {
5945
5780
  if (event.type === `onSelectionChange`) {
@@ -5952,26 +5787,31 @@
5952
5787
  rxjs.switchMap(({ adjustedSpinePosition }) => {
5953
5788
  return spine.adjustPagination(adjustedSpinePosition).pipe(operators.takeUntil(navigation$));
5954
5789
  }),
5955
- operators.takeUntil(context.$.destroy$)
5790
+ operators.takeUntil(context.destroy$)
5956
5791
  ).subscribe();
5957
- rxjs.merge(context.$.state$, settings.$.settings$).pipe(
5792
+ rxjs.merge(context.state$, settingsManager.settings$).pipe(
5958
5793
  operators.map(() => void 0),
5959
- operators.withLatestFrom(context.$.state$),
5794
+ operators.withLatestFrom(context.state$),
5960
5795
  operators.map(([, { hasVerticalWriting }]) => {
5961
- const manifest = context.getManifest();
5796
+ const manifest = context.manifest;
5962
5797
  return {
5963
5798
  hasVerticalWriting,
5964
5799
  renditionFlow: manifest == null ? void 0 : manifest.renditionFlow,
5965
5800
  renditionLayout: manifest == null ? void 0 : manifest.renditionLayout,
5966
- computedPageTurnMode: settings.getSettings().computedPageTurnMode
5801
+ computedPageTurnMode: settingsManager.settings.computedPageTurnMode
5967
5802
  };
5968
5803
  }),
5969
5804
  operators.distinctUntilChanged(isShallowEqual),
5970
5805
  operators.map(
5971
- ({ hasVerticalWriting, renditionFlow, renditionLayout, computedPageTurnMode }) => {
5806
+ ({
5807
+ hasVerticalWriting,
5808
+ renditionFlow,
5809
+ renditionLayout,
5810
+ computedPageTurnMode
5811
+ }) => {
5972
5812
  return {
5973
5813
  ...stateSubject$.value,
5974
- supportedPageTurnMode: renditionFlow === `scrolled-continuous` ? [`scrollable`] : !context.areAllItemsPrePaginated() ? [`controlled`] : [`controlled`, `scrollable`],
5814
+ supportedPageTurnMode: renditionFlow === `scrolled-continuous` ? [`scrollable`] : !context.state.areAllItemsPrePaginated ? [`controlled`] : [`controlled`, `scrollable`],
5975
5815
  supportedPageTurnAnimation: renditionFlow === `scrolled-continuous` || computedPageTurnMode === `scrollable` ? [`none`] : hasVerticalWriting ? [`fade`, `none`] : [`fade`, `none`, `slide`],
5976
5816
  supportedPageTurnDirection: computedPageTurnMode === `scrollable` ? [`vertical`] : renditionLayout === `reflowable` ? [`horizontal`] : [`horizontal`, `vertical`]
5977
5817
  };
@@ -5980,16 +5820,13 @@
5980
5820
  operators.takeUntil(destroy$)
5981
5821
  ).subscribe(stateSubject$);
5982
5822
  const destroy = () => {
5983
- var _a, _b;
5984
- settings.destroy();
5985
- hooksSubject$.next([]);
5986
- hooksSubject$.complete();
5823
+ var _a;
5824
+ settingsManager.destroy();
5987
5825
  pagination.destroy();
5988
5826
  context.destroy();
5989
5827
  viewportNavigator.destroy();
5990
5828
  spine.destroy();
5991
5829
  (_a = elementSubject$.getValue()) == null ? void 0 : _a.remove();
5992
- (_b = iframeEventBridgeElement$.getValue()) == null ? void 0 : _b.remove();
5993
5830
  stateSubject$.complete();
5994
5831
  selectionSubject$.complete();
5995
5832
  destroy$.next();
@@ -5997,43 +5834,16 @@
5997
5834
  };
5998
5835
  const reader = {
5999
5836
  context,
6000
- registerHook,
6001
5837
  spine,
5838
+ hookManager,
6002
5839
  viewportNavigator,
6003
- manipulateSpineItems: spine.manipulateSpineItems,
6004
- manipulateSpineItem: spine.manipulateSpineItem,
6005
- moveTo: viewportNavigator.moveTo,
6006
- turnLeft: viewportNavigator.turnLeft,
6007
- turnRight: viewportNavigator.turnRight,
6008
- goToPageOfCurrentChapter: viewportNavigator.goToPageOfCurrentChapter,
6009
- goToPage: viewportNavigator.goToPage,
6010
- goToUrl: viewportNavigator.goToUrl,
6011
- goToCfi: viewportNavigator.goToCfi,
6012
- goToSpineItem: viewportNavigator.goToSpineItem,
6013
- getFocusedSpineItemIndex: spineItemManager.getFocusedSpineItemIndex,
6014
- getSpineItem: spineItemManager.get,
6015
- getSpineItems: spineItemManager.getAll,
6016
- getAbsolutePositionOf: spineItemManager.getAbsolutePositionOf,
6017
- getSelection: spine.getSelection,
6018
- isSelecting: spine.isSelecting,
6019
- normalizeEventForViewport: spine.normalizeEventForViewport,
6020
- getCfiMetaInformation: spine.cfiLocator.getCfiMetaInformation,
6021
- resolveCfi: spine.cfiLocator.resolveCfi,
6022
- generateCfi: spine.cfiLocator.generateFromRange,
6023
- locator: spine.locator,
6024
- getCurrentNavigationPosition: viewportNavigator.getCurrentNavigationPosition,
6025
- getCurrentViewportPosition: viewportNavigator.getCurrentViewportPosition,
5840
+ spineItemManager,
6026
5841
  layout,
6027
5842
  load,
6028
5843
  destroy,
6029
- spineItems$: spine.$.spineItems$,
6030
- context$: context.$.state$,
6031
5844
  pagination,
6032
- settings: {
6033
- settings$: settings.$.settings$,
6034
- getSettings: settings.getSettings,
6035
- setSettings: (data) => settings.setSettings(data, context.getState())
6036
- },
5845
+ settings: settingsManager,
5846
+ element$,
6037
5847
  $: {
6038
5848
  state$: stateSubject$.asObservable(),
6039
5849
  /**
@@ -6042,21 +5852,12 @@
6042
5852
  * have an effect.
6043
5853
  * It can typically be used to hide a loading indicator.
6044
5854
  */
6045
- loadStatus$: context.$.manifest$.pipe(operators.map((manifest) => manifest ? "ready" : "idle")),
5855
+ loadStatus$: context.manifest$.pipe(operators.map((manifest) => manifest ? "ready" : "idle")),
6046
5856
  /**
6047
5857
  * Dispatched when a change in selection happens
6048
5858
  */
6049
5859
  selection$: selectionSubject$.asObservable(),
6050
- viewportState$: viewportNavigator.$.state$,
6051
- layout$: spine.$.layout$,
6052
- itemsBeforeDestroy$: spine.$.itemsBeforeDestroy$,
6053
- itemIsReady$: spineItemManager.$.itemIsReady$,
6054
5860
  destroy$
6055
- },
6056
- __debug: {
6057
- pagination,
6058
- context,
6059
- spineItemManager
6060
5861
  }
6061
5862
  };
6062
5863
  return reader;
@@ -6070,19 +5871,6 @@
6070
5871
  element.className = `${HTML_PREFIX$1}-reader`;
6071
5872
  return element;
6072
5873
  };
6073
- const createIframeEventBridgeElement = (containerElement) => {
6074
- const iframeEventBridgeElement = containerElement.ownerDocument.createElement(`div`);
6075
- iframeEventBridgeElement.id = IFRAME_EVENT_BRIDGE_ELEMENT_ID;
6076
- iframeEventBridgeElement.style.cssText = `
6077
- position: absolute;
6078
- height: 100%;
6079
- width: 100%;
6080
- top: 0;
6081
- left: 0;
6082
- z-index: -1;
6083
- `;
6084
- return iframeEventBridgeElement;
6085
- };
6086
5874
  const utilsEnhancer = (next) => (options) => {
6087
5875
  const reader = next(options);
6088
5876
  const isOrIsWithinValidLink = (target) => {
@@ -6207,15 +5995,14 @@
6207
5995
  var _a, _b;
6208
5996
  if (typeof itemIndexOrId === `string` || typeof itemIndexOrId === `object`) {
6209
5997
  const id = typeof itemIndexOrId === `object` ? itemIndexOrId.id : void 0;
6210
- return (_a = context.getManifest()) == null ? void 0 : _a.spineItems.find((entry) => entry.id === id);
5998
+ return (_a = context.manifest) == null ? void 0 : _a.spineItems.find((entry) => entry.id === id);
6211
5999
  } else {
6212
- return (_b = context.getManifest()) == null ? void 0 : _b.spineItems[itemIndexOrId];
6000
+ return (_b = context.manifest) == null ? void 0 : _b.spineItems[itemIndexOrId];
6213
6001
  }
6214
6002
  };
6215
6003
  const get = async (itemIndexOrId, fetchResource) => {
6216
6004
  const item = retrieveItem(itemIndexOrId);
6217
- if (!item)
6218
- return new Response(`Item not found`, { status: 404 });
6005
+ if (!item) return new Response(`Item not found`, { status: 404 });
6219
6006
  const db = await openDatabase(`prose-reader`);
6220
6007
  const cacheData = await db.get(`${uniqueID}_${item.id}`);
6221
6008
  if (cacheData) {
@@ -6231,8 +6018,7 @@
6231
6018
  cache$.asObservable().pipe(
6232
6019
  operators.mergeMap(({ id, data }) => {
6233
6020
  const item = retrieveItem(id);
6234
- if (!item)
6235
- return rxjs.EMPTY;
6021
+ if (!item) return rxjs.EMPTY;
6236
6022
  return rxjs.from(rxjs.forkJoin([openDatabase(`prose-reader`), rxjs.from(data.blob())])).pipe(
6237
6023
  operators.switchMap(([db, blob]) => {
6238
6024
  return rxjs.from(db.put(`${uniqueID}_${item.id}`, blob));
@@ -6243,9 +6029,9 @@
6243
6029
  })
6244
6030
  );
6245
6031
  }),
6246
- operators.takeUntil(context.$.destroy$)
6032
+ operators.takeUntil(context.destroy$)
6247
6033
  ).subscribe();
6248
- const onLoad$ = context.$.manifest$.pipe(
6034
+ const onLoad$ = context.manifest$.pipe(
6249
6035
  operators.tap(() => {
6250
6036
  uniqueID = Date.now().toString();
6251
6037
  })
@@ -6269,7 +6055,7 @@
6269
6055
  })
6270
6056
  );
6271
6057
  }),
6272
- operators.takeUntil(context.$.destroy$)
6058
+ operators.takeUntil(context.destroy$)
6273
6059
  ).subscribe();
6274
6060
  const destroy = () => {
6275
6061
  cache$.complete();
@@ -6282,14 +6068,6 @@
6282
6068
  const resourcesEnhancer = (next) => (options) => {
6283
6069
  const reader = next(options);
6284
6070
  const resourceManager = createResourcesManager(reader.context);
6285
- const load = (manifest, loadOptions) => {
6286
- reader.load(manifest, {
6287
- ...loadOptions
6288
- });
6289
- };
6290
- reader.registerHook(`item.onGetResource`, (fetcher) => async (item) => {
6291
- return resourceManager.get(item, fetcher);
6292
- });
6293
6071
  const destroy = () => {
6294
6072
  resourceManager.destroy();
6295
6073
  reader.destroy();
@@ -6300,8 +6078,8 @@
6300
6078
  // ...reader.$,
6301
6079
  // errors$: merge(reader.$.errors$, errorsSubject$.asObservable())
6302
6080
  // },
6303
- destroy,
6304
- load
6081
+ destroy
6082
+ // load,
6305
6083
  };
6306
6084
  };
6307
6085
  const mediaEnhancer = (next) => (options) => {
@@ -6352,7 +6130,7 @@
6352
6130
  threshold: 0.5
6353
6131
  }
6354
6132
  );
6355
- reader.registerHook(`item.onLoad`, ({ frame }) => {
6133
+ reader.hookManager.register(`item.onLoad`, ({ frame, destroy: destroy2 }) => {
6356
6134
  var _a;
6357
6135
  frameObserver.observe(frame);
6358
6136
  const videos = (_a = frame.contentDocument) == null ? void 0 : _a.body.getElementsByTagName(`video`);
@@ -6360,10 +6138,10 @@
6360
6138
  elementObserver.observe(element);
6361
6139
  return () => elementObserver.unobserve(element);
6362
6140
  });
6363
- return () => {
6141
+ destroy2(() => {
6364
6142
  frameObserver.unobserve(frame);
6365
6143
  unobserveElements.forEach((unobserve) => unobserve());
6366
- };
6144
+ });
6367
6145
  });
6368
6146
  const destroy = () => {
6369
6147
  frameObserver.disconnect();
@@ -6379,22 +6157,26 @@
6379
6157
  const reader = next(options);
6380
6158
  const getPercentageEstimate = (context, currentSpineIndex, numberOfPages, pageIndex, currentPosition, currentItem) => {
6381
6159
  var _a, _b, _c, _d, _e, _f;
6382
- const isGloballyPrePaginated = ((_a = context.getManifest()) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
6383
- const readingOrderLength = ((_b = context.getManifest()) == null ? void 0 : _b.spineItems.length) || 0;
6384
- const estimateBeforeThisItem = ((_c = context.getManifest()) == null ? void 0 : _c.spineItems.slice(0, currentSpineIndex).reduce((acc, item) => acc + item.progressionWeight, 0)) || 0;
6385
- const currentItemWeight = ((_e = (_d = context.getManifest()) == null ? void 0 : _d.spineItems[currentSpineIndex]) == null ? void 0 : _e.progressionWeight) || 0;
6160
+ const isGloballyPrePaginated = ((_a = context.manifest) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
6161
+ const readingOrderLength = ((_b = context.manifest) == null ? void 0 : _b.spineItems.length) || 0;
6162
+ const estimateBeforeThisItem = ((_c = context.manifest) == null ? void 0 : _c.spineItems.slice(0, currentSpineIndex).reduce((acc, item) => acc + item.progressionWeight, 0)) || 0;
6163
+ const currentItemWeight = ((_e = (_d = context.manifest) == null ? void 0 : _d.spineItems[currentSpineIndex]) == null ? void 0 : _e.progressionWeight) || 0;
6386
6164
  let progressWithinThisItem = (pageIndex + 1) * (currentItemWeight / numberOfPages);
6387
6165
  if (!isGloballyPrePaginated && currentItem.item.renditionLayout === `reflowable` && !currentItem.isReady()) {
6388
6166
  progressWithinThisItem = 0;
6389
6167
  }
6390
6168
  let totalProgress = estimateBeforeThisItem + progressWithinThisItem;
6391
- if (((_f = context.getManifest()) == null ? void 0 : _f.renditionFlow) === `scrolled-continuous`) {
6169
+ if (((_f = context.manifest) == null ? void 0 : _f.renditionFlow) === `scrolled-continuous`) {
6392
6170
  if (currentItem.isReady()) {
6393
6171
  progressWithinThisItem = getScrollPercentageWithinItem(context, currentPosition, currentItem);
6394
6172
  } else {
6395
6173
  progressWithinThisItem = 0;
6396
6174
  }
6397
- totalProgress = getTotalProgressFromPercentages(estimateBeforeThisItem, currentItemWeight, progressWithinThisItem);
6175
+ totalProgress = getTotalProgressFromPercentages(
6176
+ estimateBeforeThisItem,
6177
+ currentItemWeight,
6178
+ progressWithinThisItem
6179
+ );
6398
6180
  }
6399
6181
  if (currentSpineIndex === readingOrderLength - 1 && pageIndex === numberOfPages - 1 && totalProgress > 0.99) {
6400
6182
  return 1;
@@ -6406,11 +6188,11 @@
6406
6188
  };
6407
6189
  const getScrollPercentageWithinItem = (context, currentPosition, currentItem) => {
6408
6190
  const { height, width } = currentItem.getElementDimensions();
6409
- const { top, left } = reader.getAbsolutePositionOf(currentItem);
6410
- if (reader.settings.getSettings().computedPageTurnDirection === `vertical`) {
6411
- return Math.max(0, Math.min(1, (currentPosition.y - top + context.getVisibleAreaRect().height) / height));
6191
+ const { top, left } = reader.spineItemManager.getAbsolutePositionOf(currentItem);
6192
+ if (reader.settings.settings.computedPageTurnDirection === `vertical`) {
6193
+ return Math.max(0, Math.min(1, (currentPosition.y - top + context.state.visibleAreaRect.height) / height));
6412
6194
  } else {
6413
- return Math.max(0, Math.min(1, (currentPosition.x - left + context.getVisibleAreaRect().width) / width));
6195
+ return Math.max(0, Math.min(1, (currentPosition.x - left + context.state.visibleAreaRect.width) / width));
6414
6196
  }
6415
6197
  };
6416
6198
  return {
@@ -6432,67 +6214,58 @@
6432
6214
  }
6433
6215
  });
6434
6216
  }, {});
6435
- reader.registerHook(`item.onLoad`, ({ addStyle, frame }) => {
6217
+ reader.hookManager.register(`item.onLoad`, ({ itemId, frame, destroy }) => {
6436
6218
  var _a;
6437
- addStyle(
6438
- `prose-reader-accessibility`,
6439
- `
6440
- :focus-visible {
6441
- ${/*
6442
- Some epubs remove the outline, this is not good practice since it reduce accessibility.
6443
- We will try to restore it by force.
6444
- */
6445
- ``}
6446
- outline: -webkit-focus-ring-color auto 1px;
6447
- }
6448
- `
6449
- );
6219
+ const item = reader.spineItemManager.get(itemId);
6220
+ if (!item) return;
6221
+ item.manipulateSpineItem(({ addStyle }) => {
6222
+ addStyle(
6223
+ `prose-reader-accessibility`,
6224
+ `
6225
+ :focus-visible {
6226
+ ${/*
6227
+ Some epubs remove the outline, this is not good practice since it reduce accessibility.
6228
+ We will try to restore it by force.
6229
+ */
6230
+ ``}
6231
+ outline: -webkit-focus-ring-color auto 1px;
6232
+ }
6233
+ `
6234
+ );
6235
+ return false;
6236
+ });
6450
6237
  const links = (_a = frame.contentDocument) == null ? void 0 : _a.body.querySelectorAll(`a`);
6451
6238
  links == null ? void 0 : links.forEach((link) => {
6452
6239
  observer.observe(link);
6453
6240
  });
6454
- return () => {
6241
+ destroy(() => {
6455
6242
  links == null ? void 0 : links.forEach((link) => {
6456
6243
  observer.unobserve(link);
6457
6244
  });
6458
- };
6245
+ });
6459
6246
  });
6460
6247
  return {
6461
6248
  ...reader
6462
6249
  };
6463
6250
  };
6464
6251
  const IS_SAFARI = navigator.userAgent.indexOf(``) > -1 && navigator.userAgent.indexOf(`Chrome`) <= -1;
6465
- const webkitEnhancer = (next) => (options) => {
6466
- const transformFlickerFixHooks = [
6467
- {
6468
- name: `viewportNavigator.onBeforeContainerCreated`,
6469
- fn: (element) => {
6470
- element.style.cssText = `
6252
+ const webkitEnhancer = (createReader2) => (options) => {
6253
+ const reader = createReader2(options);
6254
+ if (IS_SAFARI) {
6255
+ reader.hookManager.register("viewportNavigator.onBeforeContainerCreated", ({ element }) => {
6256
+ element.style.cssText = `
6471
6257
  ${element.style.cssText}
6472
6258
  -webkit-transform-style: preserve-3d;
6473
6259
  `;
6474
- return element;
6475
- }
6476
- },
6477
- {
6478
- name: `item.onBeforeContainerCreated`,
6479
- fn: (element) => {
6480
- element.style.cssText = `
6481
- ${element.style.cssText}
6482
- -webkit-transform-style: preserve-3d;
6483
- -webkit-backface-visibility: hidden;
6484
- `;
6485
- return element;
6486
- }
6487
- }
6488
- ];
6489
- const existingHooks = options.hooks || [];
6490
- const reader = next({
6491
- ...options,
6492
- ...IS_SAFARI && {
6493
- hooks: [...existingHooks, ...transformFlickerFixHooks]
6494
- }
6495
- });
6260
+ });
6261
+ reader.hookManager.register("item.onBeforeContainerCreated", ({ element }) => {
6262
+ element.style.cssText = `
6263
+ ${element.style.cssText}
6264
+ -webkit-transform-style: preserve-3d;
6265
+ -webkit-backface-visibility: hidden;
6266
+ `;
6267
+ });
6268
+ }
6496
6269
  return reader;
6497
6270
  };
6498
6271
  const HTML_PREFIX = `${HTML_PREFIX$1}-enhancer-loading`;
@@ -6513,9 +6286,9 @@
6513
6286
  };
6514
6287
  }, {})
6515
6288
  );
6516
- const updateEntriesLayout$ = (entries) => rxjs.combineLatest([reader.$.layout$, reader.theme.$.theme$]).pipe(
6289
+ const updateEntriesLayout$ = (entries) => rxjs.combineLatest([reader.spine.$.layout$, reader.theme.$.theme$]).pipe(
6517
6290
  operators.map(([, theme]) => ({
6518
- width: reader.context.getVisibleAreaRect().width,
6291
+ width: reader.context.state.visibleAreaRect.width,
6519
6292
  theme
6520
6293
  })),
6521
6294
  operators.distinctUntilChanged(isShallowEqual),
@@ -6526,22 +6299,22 @@
6526
6299
  });
6527
6300
  })
6528
6301
  );
6529
- const updateEntriesVisibility$ = (entries) => reader.$.itemIsReady$.pipe(
6302
+ const updateEntriesVisibility$ = (entries) => reader.spineItemManager.$.itemIsReady$.pipe(
6530
6303
  operators.tap(({ item, isReady }) => {
6531
6304
  var _a;
6532
6305
  (_a = entries[item.id]) == null ? void 0 : _a.style.setProperty(`visibility`, isReady ? `hidden` : `visible`);
6533
6306
  })
6534
6307
  );
6535
- const destroyEntries$ = (entries) => reader.$.itemsBeforeDestroy$.pipe(
6308
+ const destroyEntries$ = (entries) => reader.spine.$.itemsBeforeDestroy$.pipe(
6536
6309
  operators.map(() => {
6537
6310
  Object.values(entries).forEach((element) => element.remove());
6538
6311
  return {};
6539
6312
  })
6540
6313
  );
6541
- const items$ = reader.spineItems$.pipe(
6314
+ const items$ = reader.spine.$.spineItems$.pipe(
6542
6315
  operators.switchMap((items) => createEntries$(items)),
6543
6316
  operators.shareReplay(1),
6544
- operators.takeUntil(reader.context.$.destroy$)
6317
+ operators.takeUntil(reader.context.destroy$)
6545
6318
  );
6546
6319
  items$.pipe(
6547
6320
  operators.switchMap((entries) => rxjs.merge(rxjs.of(entries), destroyEntries$(entries))),
@@ -6563,7 +6336,7 @@
6563
6336
  loadingElement.style.cssText = `
6564
6337
  height: 100%;
6565
6338
  width: 100%;
6566
- max-width: ${context.getVisibleAreaRect().width}px;
6339
+ max-width: ${context.state.visibleAreaRect.width}px;
6567
6340
  text-align: center;
6568
6341
  display: flex;
6569
6342
  justify-content: center;
@@ -6577,7 +6350,10 @@
6577
6350
  `;
6578
6351
  return loadingElement;
6579
6352
  };
6580
- const defaultLoadingElementCreate = ({ container, item }) => {
6353
+ const defaultLoadingElementCreate = ({
6354
+ container,
6355
+ item
6356
+ }) => {
6581
6357
  const logoElement = container.ownerDocument.createElement(`div`);
6582
6358
  logoElement.innerText = `prose`;
6583
6359
  logoElement.style.cssText = `
@@ -6603,6 +6379,152 @@
6603
6379
  return reader;
6604
6380
  };
6605
6381
  };
6382
+ const createNormalizeEventForViewport = ({
6383
+ iframeEventBridgeElement$,
6384
+ locator
6385
+ }) => {
6386
+ const normalizeEventForViewport = (event) => {
6387
+ var _a;
6388
+ const eventIsComingFromBridge = event.target === iframeEventBridgeElement$.getValue();
6389
+ const iframeOriginalEvent = getOriginalFrameEventFromDocumentEvent(event);
6390
+ const originalFrame = (_a = iframeOriginalEvent == null ? void 0 : iframeOriginalEvent.view) == null ? void 0 : _a.frameElement;
6391
+ if (!eventIsComingFromBridge || !iframeOriginalEvent || !originalFrame) return event;
6392
+ const spineItem = locator.getSpineItemFromIframe(originalFrame);
6393
+ if (!spineItem) return event;
6394
+ if (isPointerEvent(event)) {
6395
+ const { clientX, clientY } = spineItem.translateFramePositionIntoPage(event);
6396
+ const newEvent = new PointerEvent(event.type, {
6397
+ ...event,
6398
+ pointerId: event.pointerId,
6399
+ clientX,
6400
+ clientY
6401
+ });
6402
+ Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
6403
+ return newEvent;
6404
+ }
6405
+ if (isMouseEvent(event)) {
6406
+ const { clientX, clientY } = spineItem.translateFramePositionIntoPage(event);
6407
+ const newEvent = new MouseEvent(event.type, {
6408
+ ...event,
6409
+ clientX,
6410
+ clientY
6411
+ });
6412
+ Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
6413
+ return newEvent;
6414
+ }
6415
+ if (isTouchEvent(event)) {
6416
+ const touches = Array.from(event.touches).map((touch) => {
6417
+ const { clientX, clientY } = spineItem.translateFramePositionIntoPage(touch);
6418
+ return new Touch({
6419
+ identifier: touch.identifier,
6420
+ target: touch.target,
6421
+ clientX,
6422
+ clientY
6423
+ });
6424
+ });
6425
+ const newEvent = new TouchEvent(event.type, {
6426
+ touches,
6427
+ changedTouches: touches,
6428
+ targetTouches: touches
6429
+ });
6430
+ Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
6431
+ return newEvent;
6432
+ }
6433
+ return event;
6434
+ };
6435
+ return normalizeEventForViewport;
6436
+ };
6437
+ const IFRAME_EVENT_BRIDGE_ELEMENT_ID = `proseReaderIframeEventBridgeElement`;
6438
+ const createIframeEventBridgeElement = (container) => {
6439
+ const iframeEventBridgeElement = container.ownerDocument.createElement(`div`);
6440
+ iframeEventBridgeElement.id = IFRAME_EVENT_BRIDGE_ELEMENT_ID;
6441
+ iframeEventBridgeElement.style.cssText = `
6442
+ position: absolute;
6443
+ height: 100%;
6444
+ width: 100%;
6445
+ top: 0;
6446
+ left: 0;
6447
+ z-index: -1;
6448
+ `;
6449
+ return iframeEventBridgeElement;
6450
+ };
6451
+ const pointerEvents = [
6452
+ `pointercancel`,
6453
+ `pointerdown`,
6454
+ `pointerenter`,
6455
+ `pointerleave`,
6456
+ `pointermove`,
6457
+ `pointerout`,
6458
+ `pointerover`,
6459
+ `pointerup`,
6460
+ `touchstart`,
6461
+ `touchend`
6462
+ ];
6463
+ const mouseEvents = [
6464
+ `click`,
6465
+ `mousedown`,
6466
+ `mouseup`,
6467
+ `mouseenter`,
6468
+ `mouseleave`,
6469
+ `mousemove`,
6470
+ `mouseout`,
6471
+ `mouseover`
6472
+ ];
6473
+ const passthroughEvents = [...pointerEvents, ...mouseEvents];
6474
+ const eventsEnhancer = (next) => (options) => {
6475
+ const iframeEventBridgeElement$ = new rxjs.BehaviorSubject(void 0);
6476
+ const reader = next(options);
6477
+ reader.hookManager.register(`item.onLoad`, ({ destroy, frame, itemId }) => {
6478
+ const item = reader.spineItemManager.get(itemId);
6479
+ if (!item) return;
6480
+ const unregister = passthroughEvents.map((event) => {
6481
+ var _a;
6482
+ const listener = (e) => {
6483
+ var _a2;
6484
+ let convertedEvent = e;
6485
+ if (isPointerEvent(e)) {
6486
+ convertedEvent = new PointerEvent(e.type, e);
6487
+ }
6488
+ if (isMouseEvent(e)) {
6489
+ convertedEvent = new MouseEvent(e.type, e);
6490
+ }
6491
+ if (convertedEvent !== e) {
6492
+ attachOriginalFrameEventToDocumentEvent(convertedEvent, e);
6493
+ (_a2 = iframeEventBridgeElement$.getValue()) == null ? void 0 : _a2.dispatchEvent(convertedEvent);
6494
+ }
6495
+ };
6496
+ (_a = frame.contentDocument) == null ? void 0 : _a.addEventListener(event, listener);
6497
+ return () => {
6498
+ var _a2;
6499
+ (_a2 = frame.contentDocument) == null ? void 0 : _a2.removeEventListener(event, listener);
6500
+ };
6501
+ });
6502
+ item.selectionTracker.track(frame);
6503
+ item.fingerTracker.track(frame);
6504
+ destroy(() => {
6505
+ unregister.forEach((cb) => cb());
6506
+ });
6507
+ });
6508
+ reader.element$.pipe(
6509
+ rxjs.tap((wrapper) => {
6510
+ var _a;
6511
+ const iframeEventBridgeElement = createIframeEventBridgeElement(wrapper);
6512
+ wrapper.appendChild(iframeEventBridgeElement);
6513
+ (_a = iframeEventBridgeElement$.getValue()) == null ? void 0 : _a.remove();
6514
+ iframeEventBridgeElement$.next(iframeEventBridgeElement);
6515
+ }),
6516
+ rxjs.takeUntil(reader.$.destroy$)
6517
+ ).subscribe();
6518
+ return {
6519
+ ...reader,
6520
+ events: {
6521
+ normalizeEventForViewport: createNormalizeEventForViewport({
6522
+ iframeEventBridgeElement$,
6523
+ locator: reader.spine.locator
6524
+ })
6525
+ }
6526
+ };
6527
+ };
6606
6528
  const createReaderWithEnhancers = (
6607
6529
  //__
6608
6530
  publicApiEnhancer(
@@ -6622,8 +6544,10 @@
6622
6544
  hotkeysEnhancer(
6623
6545
  paginationEnhancer(
6624
6546
  progressionEnhancer(
6625
- // __
6626
- createReader
6547
+ eventsEnhancer(
6548
+ // __
6549
+ createReader
6550
+ )
6627
6551
  )
6628
6552
  )
6629
6553
  )
@@ -6642,6 +6566,7 @@
6642
6566
  )
6643
6567
  )
6644
6568
  );
6569
+ exports2.HookManager = HookManager;
6645
6570
  exports2.Report = Report;
6646
6571
  exports2.createReader = createReaderWithEnhancers;
6647
6572
  exports2.groupBy = groupBy;