@prose-reader/core 1.55.0 → 1.57.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.
package/dist/index.js CHANGED
@@ -3,17 +3,17 @@ import { withLatestFrom, distinctUntilChanged, shareReplay, tap, pairwise, switc
3
3
  import { parseContentType, detectMimeTypeFromName } from "@prose-reader/shared";
4
4
  const chromeEnhancer = (next) => (options) => {
5
5
  const reader = next(options);
6
- reader.context$.pipe(takeUntil(reader.$.destroy$)).subscribe(({ containerElement }) => {
6
+ reader.context.state$.pipe(takeUntil(reader.$.destroy$)).subscribe(({ containerElement }) => {
7
7
  if (!containerElement)
8
8
  return;
9
9
  const onScroll = () => {
10
- if (reader.settings.getSettings().computedPageTurnMode === `controlled`) {
10
+ if (reader.settings.settings.computedPageTurnMode === `controlled`) {
11
11
  containerElement.scrollTo(0, 0);
12
12
  }
13
13
  };
14
14
  containerElement.addEventListener(`scroll`, onScroll);
15
15
  });
16
- reader.registerHook(`item.onLoad`, ({ frame }) => {
16
+ reader.hookManager.register(`item.onLoad`, ({ frame }) => {
17
17
  var _a;
18
18
  (_a = frame.contentDocument) == null ? void 0 : _a.body.setAttribute(`tabindex`, `-1`);
19
19
  });
@@ -102,7 +102,7 @@ const fontsEnhancer = (next) => (options) => {
102
102
  }
103
103
  `;
104
104
  const applyChangeToSpineItem = (requireLayout) => {
105
- reader.manipulateSpineItems(({ removeStyle, addStyle, item }) => {
105
+ reader.spine.manipulateSpineItems(({ removeStyle, addStyle, item }) => {
106
106
  if (item.renditionLayout !== `pre-paginated`) {
107
107
  removeStyle(`prose-reader-fonts`);
108
108
  addStyle(`prose-reader-fonts`, getStyle());
@@ -110,11 +110,15 @@ const fontsEnhancer = (next) => (options) => {
110
110
  return requireLayout;
111
111
  });
112
112
  };
113
- reader.registerHook(`item.onLoad`, ({ removeStyle, addStyle, item }) => {
114
- if (item.renditionLayout !== `pre-paginated`) {
115
- removeStyle(`prose-reader-fonts`);
116
- addStyle(`prose-reader-fonts`, getStyle());
117
- }
113
+ reader.hookManager.register(`item.onLoad`, ({ itemId }) => {
114
+ const item = reader.spineItemManager.get(itemId);
115
+ item == null ? void 0 : item.manipulateSpineItem(({ addStyle, removeStyle }) => {
116
+ if (item.item.renditionLayout !== `pre-paginated`) {
117
+ removeStyle(`prose-reader-fonts`);
118
+ addStyle(`prose-reader-fonts`, getStyle());
119
+ }
120
+ return false;
121
+ });
118
122
  });
119
123
  const shouldRequireLayout = (source) => source.pipe(
120
124
  pairwise(),
@@ -171,25 +175,25 @@ const hotkeysEnhancer = (next) => (options) => {
171
175
  map(([e, { pageTurnDirection }]) => {
172
176
  if (pageTurnDirection === "horizontal") {
173
177
  if (e.key === `ArrowRight`) {
174
- reader.turnRight();
178
+ reader.viewportNavigator.turnRight();
175
179
  }
176
180
  if (e.key === `ArrowLeft`) {
177
- reader.turnLeft();
181
+ reader.viewportNavigator.turnLeft();
178
182
  }
179
183
  }
180
184
  if (pageTurnDirection === "vertical") {
181
185
  if (e.key === `ArrowDown`) {
182
- reader.turnRight();
186
+ reader.viewportNavigator.turnRight();
183
187
  }
184
188
  if (e.key === `ArrowUp`) {
185
- reader.turnLeft();
189
+ reader.viewportNavigator.turnLeft();
186
190
  }
187
191
  }
188
192
  return e;
189
193
  })
190
194
  );
191
195
  navigateOnKey(document).pipe(takeUntil(reader.$.destroy$)).subscribe();
192
- reader.spineItems$.pipe(
196
+ reader.spine.$.spineItems$.pipe(
193
197
  switchMap(
194
198
  (spineItems) => merge(
195
199
  ...spineItems.map(
@@ -205,7 +209,7 @@ const hotkeysEnhancer = (next) => (options) => {
205
209
  };
206
210
  const createMovingSafePan$ = (reader) => {
207
211
  let iframeOverlayForAnimationsElement;
208
- const updateOverlayElement$ = reader.context$.pipe(
212
+ const updateOverlayElement$ = reader.context.state$.pipe(
209
213
  switchMap$1(({ containerElement }) => {
210
214
  if (!containerElement)
211
215
  return NEVER;
@@ -232,8 +236,8 @@ const createMovingSafePan$ = (reader) => {
232
236
  iframeOverlayForAnimationsElement == null ? void 0 : iframeOverlayForAnimationsElement.style.setProperty(`visibility`, `hidden`);
233
237
  })
234
238
  );
235
- const viewportFree$ = reader.$.viewportState$.pipe(filter((data) => data === `free`));
236
- const viewportBusy$ = reader.$.viewportState$.pipe(filter((data) => data === `busy`));
239
+ const viewportFree$ = reader.viewportNavigator.$.state$.pipe(filter((data) => data === `free`));
240
+ const viewportBusy$ = reader.viewportNavigator.$.state$.pipe(filter((data) => data === `busy`));
237
241
  const lockAfterViewportBusy$ = viewportBusy$.pipe(
238
242
  tap(() => {
239
243
  iframeOverlayForAnimationsElement == null ? void 0 : iframeOverlayForAnimationsElement.style.setProperty(`visibility`, `visible`);
@@ -241,7 +245,7 @@ const createMovingSafePan$ = (reader) => {
241
245
  );
242
246
  const resetLockViewportFree$ = createResetLock$(viewportFree$).pipe(take(1));
243
247
  const pageTurnMode$ = reader.settings.settings$.pipe(
244
- map$1(() => reader.settings.getSettings().computedPageTurnMode),
248
+ map$1(() => reader.settings.settings.computedPageTurnMode),
245
249
  distinctUntilChanged()
246
250
  );
247
251
  const handleViewportLock$ = pageTurnMode$.pipe(
@@ -269,9 +273,9 @@ const mapKeysTo = (keys) => {
269
273
  });
270
274
  };
271
275
  const fixReflowable = (reader) => {
272
- reader.registerHook(`item.onAfterLayout`, ({ item, blankPagePosition, minimumWidth }) => {
276
+ reader.hookManager.register(`item.onAfterLayout`, ({ item, blankPagePosition, minimumWidth }) => {
273
277
  var _a;
274
- const spineItem = reader.getSpineItem(item.id);
278
+ const spineItem = reader.spineItemManager.get(item.id);
275
279
  if (!((spineItem == null ? void 0 : spineItem.item.renditionLayout) === `reflowable`))
276
280
  return;
277
281
  const { viewportDimensions } = (spineItem == null ? void 0 : spineItem.getViewPortInformation()) ?? {};
@@ -297,9 +301,9 @@ const layoutEnhancer = (next) => (options) => {
297
301
  pageHorizontalMargin,
298
302
  pageVerticalMargin
299
303
  });
300
- reader.registerHook(`onViewportOffsetAdjust`, () => {
304
+ reader.hookManager.register(`onViewportOffsetAdjust`, () => {
301
305
  let hasRedrawn = false;
302
- reader.manipulateSpineItems(({ frame }) => {
306
+ reader.spine.manipulateSpineItems(({ frame }) => {
303
307
  if (!hasRedrawn && frame) {
304
308
  void frame.getBoundingClientRect().left;
305
309
  hasRedrawn = true;
@@ -307,7 +311,7 @@ const layoutEnhancer = (next) => (options) => {
307
311
  return SHOULD_NOT_LAYOUT;
308
312
  });
309
313
  });
310
- reader.registerHook(`item.onLayoutBeforeMeasurement`, ({ frame, minimumWidth, item, isImageType }) => {
314
+ reader.hookManager.register(`item.onLayoutBeforeMeasurement`, ({ frame, minimumWidth, item, isImageType }) => {
311
315
  var _a, _b;
312
316
  const { pageHorizontalMargin: pageHorizontalMargin2 = 0, pageVerticalMargin: pageVerticalMargin2 = 0 } = settingsSubject$.value;
313
317
  const pageSize = reader.context.getPageSize();
@@ -349,7 +353,7 @@ const layoutEnhancer = (next) => (options) => {
349
353
  fixReflowable(reader);
350
354
  let observer;
351
355
  if (options.layoutAutoResize === `container`) {
352
- reader.context$.pipe(
356
+ reader.context.state$.pipe(
353
357
  map$1((state) => state.containerElement),
354
358
  filter(isDefined),
355
359
  distinctUntilChanged(),
@@ -401,6 +405,12 @@ const layoutEnhancer = (next) => (options) => {
401
405
  };
402
406
  };
403
407
  const ROOT_NAMESPACE = `@prose-reader/core`;
408
+ const getWindow = () => {
409
+ if (typeof window === "undefined") {
410
+ return void 0;
411
+ }
412
+ return window;
413
+ };
404
414
  const wrap = (str) => `[${str}]`;
405
415
  const time = (name, targetDuration = 0) => {
406
416
  let tick = 0;
@@ -414,7 +424,8 @@ const time = (name, targetDuration = 0) => {
414
424
  const createReport = (namespace) => ({
415
425
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
416
426
  log: (...data) => {
417
- if (window.__PROSE_READER_DEBUG) {
427
+ var _a;
428
+ if ((_a = getWindow()) == null ? void 0 : _a.__PROSE_READER_DEBUG) {
418
429
  if (namespace)
419
430
  console.log(wrap(ROOT_NAMESPACE), wrap(namespace), ...data);
420
431
  else
@@ -423,7 +434,8 @@ const createReport = (namespace) => ({
423
434
  },
424
435
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
425
436
  warn: (...data) => {
426
- if (window.__PROSE_READER_DEBUG) {
437
+ var _a;
438
+ if ((_a = getWindow()) == null ? void 0 : _a.__PROSE_READER_DEBUG) {
427
439
  if (namespace)
428
440
  console.warn(wrap(ROOT_NAMESPACE), wrap(namespace), ...data);
429
441
  else
@@ -448,7 +460,8 @@ const createReport = (namespace) => ({
448
460
  // },
449
461
  time,
450
462
  logMetric: (performanceEntry, targetDuration = 0) => {
451
- if (window.__PROSE_READER_DEBUG) {
463
+ var _a;
464
+ if ((_a = getWindow()) == null ? void 0 : _a.__PROSE_READER_DEBUG) {
452
465
  if (performanceEntry.duration <= targetDuration)
453
466
  ;
454
467
  else {
@@ -461,7 +474,8 @@ const createReport = (namespace) => ({
461
474
  },
462
475
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
463
476
  measurePerformance: (name, targetDuration = 10, functionToMeasure, { disable } = {}) => {
464
- if (disable || !window.__PROSE_READER_DEBUG)
477
+ var _a;
478
+ if (disable || !((_a = getWindow()) == null ? void 0 : _a.__PROSE_READER_DEBUG))
465
479
  return functionToMeasure;
466
480
  return (...args) => {
467
481
  const t0 = performance.now();
@@ -492,15 +506,15 @@ const linksEnhancer = (next) => (options) => {
492
506
  return false;
493
507
  const hrefUrl = new URL(element.href);
494
508
  const hrefWithoutAnchor = `${hrefUrl.origin}${hrefUrl.pathname}`;
495
- const hasExistingSpineItem = (_a = reader.context.getManifest()) == null ? void 0 : _a.spineItems.some((item) => item.href === hrefWithoutAnchor);
509
+ const hasExistingSpineItem = (_a = reader.context.manifest) == null ? void 0 : _a.spineItems.some((item) => item.href === hrefWithoutAnchor);
496
510
  if (hasExistingSpineItem) {
497
- reader.goToUrl(hrefUrl);
511
+ reader.viewportNavigator.goToUrl(hrefUrl);
498
512
  return true;
499
513
  }
500
514
  return false;
501
515
  };
502
- reader.registerHook(`item.onLoad`, ({ frame }) => {
503
- if (frame.contentDocument) {
516
+ reader.hookManager.register(`item.onLoad`, ({ frame }) => {
517
+ if (frame == null ? void 0 : frame.contentDocument) {
504
518
  Array.from(frame.contentDocument.querySelectorAll(`a`)).forEach(
505
519
  (element) => element.addEventListener(`click`, (e) => {
506
520
  if (e.target && `style` in e.target && `ELEMENT_NODE` in e.target) {
@@ -524,27 +538,27 @@ const linksEnhancer = (next) => (options) => {
524
538
  const createNavigator = (reader) => {
525
539
  const goToNextSpineItem = () => {
526
540
  var _a;
527
- const focusedSpineItemIndex = reader.getFocusedSpineItemIndex() || 0;
528
- const { end = focusedSpineItemIndex } = reader.locator.getSpineItemsFromReadingOrderPosition(reader.getCurrentNavigationPosition()) || {};
529
- const numberOfSpineItems = ((_a = reader.context.getManifest()) == null ? void 0 : _a.spineItems.length) ?? 0;
541
+ const focusedSpineItemIndex = reader.spineItemManager.getFocusedSpineItemIndex() || 0;
542
+ const { end = focusedSpineItemIndex } = reader.spine.locator.getSpineItemsFromReadingOrderPosition(reader.viewportNavigator.getCurrentNavigationPosition()) || {};
543
+ const numberOfSpineItems = ((_a = reader.context.manifest) == null ? void 0 : _a.spineItems.length) ?? 0;
530
544
  const nextItem = end + 1;
531
545
  if (nextItem < numberOfSpineItems) {
532
- reader.goToSpineItem(nextItem);
546
+ reader.viewportNavigator.goToSpineItem(nextItem);
533
547
  }
534
548
  };
535
549
  const goToPreviousSpineItem = () => {
536
- const focusedSpineItemIndex = reader.getFocusedSpineItemIndex() || 0;
537
- const { begin = focusedSpineItemIndex } = reader.locator.getSpineItemsFromReadingOrderPosition(reader.getCurrentNavigationPosition()) || {};
550
+ const focusedSpineItemIndex = reader.spineItemManager.getFocusedSpineItemIndex() || 0;
551
+ const { begin = focusedSpineItemIndex } = reader.spine.locator.getSpineItemsFromReadingOrderPosition(reader.viewportNavigator.getCurrentNavigationPosition()) || {};
538
552
  const nextItem = begin - 1;
539
553
  if (nextItem >= 0) {
540
- reader.goToSpineItem(nextItem);
554
+ reader.viewportNavigator.goToSpineItem(nextItem);
541
555
  }
542
556
  };
543
557
  return {
544
558
  goToNextSpineItem,
545
559
  goToPreviousSpineItem,
546
560
  goToLeftSpineItem: () => {
547
- if (reader.settings.getSettings().computedPageTurnDirection === "vertical")
561
+ if (reader.settings.settings.computedPageTurnDirection === "vertical")
548
562
  return;
549
563
  if (reader.context.isRTL()) {
550
564
  return goToNextSpineItem();
@@ -552,7 +566,7 @@ const createNavigator = (reader) => {
552
566
  return goToPreviousSpineItem();
553
567
  },
554
568
  goToRightSpineItem: () => {
555
- if (reader.settings.getSettings().computedPageTurnDirection === "vertical")
569
+ if (reader.settings.settings.computedPageTurnDirection === "vertical")
556
570
  return;
557
571
  if (reader.context.isRTL()) {
558
572
  return goToPreviousSpineItem();
@@ -563,7 +577,7 @@ const createNavigator = (reader) => {
563
577
  };
564
578
  const createState = (reader) => {
565
579
  return reader.pagination.paginationInfo$.pipe(
566
- withLatestFrom$1(reader.context.$.manifest$, reader.settings.settings$),
580
+ withLatestFrom$1(reader.context.manifest$, reader.settings.settings$),
567
581
  map(([paginationInfo, manifest, { computedPageTurnDirection }]) => {
568
582
  const numberOfSpineItems = (manifest == null ? void 0 : manifest.spineItems.length) ?? 0;
569
583
  const isAtAbsoluteBeginning = paginationInfo.beginSpineItemIndex === 0 && paginationInfo.beginPageIndexInSpineItem === 0;
@@ -627,8 +641,8 @@ const buildChapterInfoFromSpineItem = (manifest, item) => {
627
641
  return buildChaptersInfo(href, ((_a = manifest.nav) == null ? void 0 : _a.toc) ?? [], manifest);
628
642
  };
629
643
  const getChaptersInfo = (reader) => {
630
- const manifest = reader.context.getManifest();
631
- const items = reader.getSpineItems();
644
+ const manifest = reader.context.manifest;
645
+ const items = reader.spineItemManager.getAll();
632
646
  if (!manifest)
633
647
  return {};
634
648
  return items.reduce(
@@ -642,7 +656,7 @@ const getChaptersInfo = (reader) => {
642
656
  );
643
657
  };
644
658
  const trackChapterInfo = (reader) => {
645
- return reader.spineItems$.pipe(
659
+ return reader.spine.$.spineItems$.pipe(
646
660
  startWith([]),
647
661
  map(() => getChaptersInfo(reader))
648
662
  );
@@ -733,7 +747,7 @@ const getClosestValidOffsetFromApproximateOffsetInPages = (offset, pageWidth, it
733
747
  const getSpineItemNumberOfPages = ({ spineItem, reader }) => {
734
748
  const writingMode = spineItem.spineItemFrame.getWritingMode();
735
749
  const { width, height } = spineItem.getElementDimensions();
736
- const settings = reader.settings.getSettings();
750
+ const settings = reader.settings.settings;
737
751
  if (settings.pageTurnDirection === `vertical` && settings.pageTurnMode === `scrollable`) {
738
752
  return 1;
739
753
  }
@@ -742,11 +756,11 @@ const getSpineItemNumberOfPages = ({ spineItem, reader }) => {
742
756
  }
743
757
  return calculateNumberOfPagesForItem(width, reader.context.getPageSize().width);
744
758
  };
745
- const getNumberOfPagesForAllSpineItems = (reader) => reader.getSpineItems().map((item) => {
759
+ const getNumberOfPagesForAllSpineItems = (reader) => reader.spineItemManager.getAll().map((item) => {
746
760
  return getSpineItemNumberOfPages({ spineItem: item, reader });
747
761
  }, 0);
748
762
  const trackTotalPages = (reader) => {
749
- const totalPages$ = reader.$.layout$.pipe(
763
+ const totalPages$ = reader.spine.$.layout$.pipe(
750
764
  debounceTime(10, animationFrameScheduler),
751
765
  withLatestFrom$1(reader.pagination.paginationInfo$),
752
766
  map(() => {
@@ -769,8 +783,8 @@ const trackTotalPages = (reader) => {
769
783
  };
770
784
  const mapPaginationInfoToExtendedInfo = (reader) => (paginationInfo, chaptersInfo) => {
771
785
  const context = reader.context;
772
- const beginItem = paginationInfo.beginSpineItemIndex !== void 0 ? reader.getSpineItem(paginationInfo.beginSpineItemIndex) : void 0;
773
- const endItem = paginationInfo.endSpineItemIndex !== void 0 ? reader.getSpineItem(paginationInfo.endSpineItemIndex) : void 0;
786
+ const beginItem = paginationInfo.beginSpineItemIndex !== void 0 ? reader.spineItemManager.get(paginationInfo.beginSpineItemIndex) : void 0;
787
+ const endItem = paginationInfo.endSpineItemIndex !== void 0 ? reader.spineItemManager.get(paginationInfo.endSpineItemIndex) : void 0;
774
788
  return {
775
789
  ...paginationInfo,
776
790
  beginChapterInfo: beginItem ? chaptersInfo[beginItem.item.id] : void 0,
@@ -799,13 +813,13 @@ const mapPaginationInfoToExtendedInfo = (reader) => (paginationInfo, chaptersInf
799
813
  paginationInfo.endSpineItemIndex ?? 0,
800
814
  paginationInfo.endNumberOfPagesInSpineItem,
801
815
  paginationInfo.endPageIndexInSpineItem || 0,
802
- reader.getCurrentViewportPosition(),
816
+ reader.viewportNavigator.getCurrentViewportPosition(),
803
817
  endItem
804
818
  ) : 0,
805
- isUsingSpread: context.isUsingSpreadMode() ?? false
819
+ isUsingSpread: context.state.isUsingSpreadMode ?? false
806
820
  // hasNextChapter: (reader.spine.spineItemIndex || 0) < (manifest.readingOrder.length - 1),
807
821
  // hasPreviousChapter: (reader.spine.spineItemIndex || 0) < (manifest.readingOrder.length - 1),
808
- // numberOfSpineItems: context.getManifest()?.readingOrder.length,
822
+ // numberOfSpineItems: context.manifest?.readingOrder.length,
809
823
  };
810
824
  };
811
825
  const trackPaginationInfo = (reader) => {
@@ -901,18 +915,22 @@ const themeEnhancer = (next) => (options) => {
901
915
  };
902
916
  };
903
917
  const applyChangeToSpineItem = () => {
904
- reader.manipulateSpineItems(({ removeStyle, addStyle, container }) => {
918
+ reader.spine.manipulateSpineItems(({ removeStyle, addStyle, container }) => {
905
919
  removeStyle(`prose-reader-theme`);
906
920
  addStyle(`prose-reader-theme`, getStyle());
907
921
  applyChangeToSpineItemElement({ container });
908
922
  return false;
909
923
  });
910
924
  };
911
- reader.registerHook(`item.onLoad`, ({ removeStyle, addStyle }) => {
912
- removeStyle(`prose-reader-theme`);
913
- addStyle(`prose-reader-theme`, getStyle());
925
+ reader.hookManager.register(`item.onLoad`, ({ itemId }) => {
926
+ const item = reader.spineItemManager.get(itemId);
927
+ item == null ? void 0 : item.manipulateSpineItem(({ removeStyle, addStyle }) => {
928
+ removeStyle(`prose-reader-theme`);
929
+ addStyle(`prose-reader-theme`, getStyle());
930
+ return false;
931
+ });
914
932
  });
915
- reader.spineItems$.pipe(
933
+ reader.spine.$.spineItems$.pipe(
916
934
  tap((items) => items.map(({ element }) => applyChangeToSpineItemElement({ container: element }))),
917
935
  takeUntil$1(reader.$.destroy$)
918
936
  ).subscribe();
@@ -949,7 +967,7 @@ const createElementZoomer = (reader) => {
949
967
  imgLastPosition = { x: 0, y: 0 };
950
968
  baseScale = 1;
951
969
  lastUserScale = 1;
952
- const container = reader.context.getState().containerElement;
970
+ const container = reader.context.state.containerElement;
953
971
  if (container) {
954
972
  imageMagnifierContainer = container.ownerDocument.createElement(`div`);
955
973
  imageMagnifierContainer.style.cssText = `
@@ -1007,6 +1025,7 @@ const createElementZoomer = (reader) => {
1007
1025
  `transform`,
1008
1026
  `translate3d(${imgLastPosition.x}px, ${imgLastPosition.y}px, 0px) scale3d(${baseScale}, ${baseScale}, 1)`
1009
1027
  );
1028
+ console.log({ delta, imgLastPosition });
1010
1029
  movingLastDelta = delta;
1011
1030
  }
1012
1031
  if (isLast) {
@@ -1124,7 +1143,7 @@ const zoomEnhancer = (next) => (options) => {
1124
1143
  const elementZoomer = createElementZoomer(reader);
1125
1144
  const viewportZoomer = createViewportZoomer(reader);
1126
1145
  const currentZoomerSubject$ = new BehaviorSubject(void 0);
1127
- const isUsingScrollableViewport = () => reader.settings.getSettings().computedPageTurnMode === `scrollable`;
1146
+ const isUsingScrollableViewport = () => reader.settings.settings.computedPageTurnMode === `scrollable`;
1128
1147
  const enter = (imgElement) => {
1129
1148
  var _a;
1130
1149
  (_a = currentZoomerSubject$ == null ? void 0 : currentZoomerSubject$.value) == null ? void 0 : _a.exit();
@@ -1207,143 +1226,100 @@ const isUsingSpreadMode = ({
1207
1226
  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`);
1208
1227
  };
1209
1228
  const isFullyPrePaginated = (manifest) => (manifest == null ? void 0 : manifest.renditionLayout) === "pre-paginated" || (manifest == null ? void 0 : manifest.spineItems.every((item) => item.renditionLayout === "pre-paginated"));
1210
- const createContext = (settings) => {
1211
- const stateSubject = new BehaviorSubject({});
1212
- const manifest$ = stateSubject.pipe(
1213
- map$1((state) => state.manifest),
1214
- filter(isDefined),
1215
- distinctUntilChanged()
1216
- );
1217
- const containerElement$ = stateSubject.pipe(
1218
- map$1((state) => state.containerElement),
1219
- filter(isDefined),
1220
- distinctUntilChanged()
1221
- );
1222
- const hasVerticalWriting$ = stateSubject.pipe(
1223
- map$1((state) => state.hasVerticalWriting),
1224
- filter(isDefined),
1225
- distinctUntilChanged()
1226
- );
1227
- const isUsingSpreadMode$ = stateSubject.pipe(
1228
- map$1((state) => state.isUsingSpreadMode),
1229
- distinctUntilChanged()
1230
- );
1231
- const visibleAreaRect = {
1232
- width: 0,
1233
- height: 0,
1234
- x: 0,
1235
- y: 0
1236
- };
1237
- const marginTop = 0;
1238
- const marginBottom = 0;
1239
- const destroy$ = new Subject();
1240
- const setState = (newState) => {
1241
- const newCompleteState = { ...stateSubject.getValue(), ...newState };
1242
- if (!isShallowEqual(newCompleteState, stateSubject.getValue())) {
1243
- stateSubject.next(newCompleteState);
1244
- }
1245
- };
1246
- const load = (newManifest, newLoadOptions) => {
1247
- setState({
1248
- manifest: newManifest,
1249
- ...newLoadOptions,
1250
- isFullyPrePaginated: isFullyPrePaginated(newManifest),
1229
+ const areAllItemsPrePaginated = (manifest) => !(manifest == null ? void 0 : manifest.spineItems.some((item) => item.renditionLayout === `reflowable`));
1230
+ class Context {
1231
+ constructor() {
1232
+ this._stateSubject = new BehaviorSubject({
1233
+ marginBottom: 0,
1234
+ marginTop: 0,
1235
+ calculatedInnerMargin: 0,
1236
+ visibleAreaRect: {
1237
+ width: 0,
1238
+ height: 0,
1239
+ x: 0,
1240
+ y: 0
1241
+ }
1242
+ });
1243
+ this.destroy$ = new Subject();
1244
+ this.state$ = this._stateSubject.pipe(distinctUntilChanged(isShallowEqual));
1245
+ this.manifest$ = this._stateSubject.pipe(
1246
+ map$1((state) => state.manifest),
1247
+ filter(isDefined),
1248
+ distinctUntilChanged()
1249
+ );
1250
+ this.containerElement$ = this._stateSubject.pipe(
1251
+ map$1((state) => state.containerElement),
1252
+ filter(isDefined),
1253
+ distinctUntilChanged()
1254
+ );
1255
+ this.hasVerticalWriting$ = this._stateSubject.pipe(
1256
+ map$1((state) => state.hasVerticalWriting),
1257
+ filter(isDefined),
1258
+ distinctUntilChanged()
1259
+ );
1260
+ this.isUsingSpreadMode$ = this._stateSubject.pipe(
1261
+ map$1((state) => state.isUsingSpreadMode),
1262
+ distinctUntilChanged()
1263
+ );
1264
+ this.isRTL = () => {
1265
+ var _a;
1266
+ return ((_a = this._stateSubject.getValue().manifest) == null ? void 0 : _a.readingDirection) === `rtl`;
1267
+ };
1268
+ this.destroy = () => {
1269
+ this._stateSubject.complete();
1270
+ this.destroy$.next();
1271
+ this.destroy$.complete();
1272
+ };
1273
+ }
1274
+ /**
1275
+ * @todo optimize to not run if not necessary
1276
+ */
1277
+ update(newState) {
1278
+ const previousState = this._stateSubject.getValue();
1279
+ const manifest = newState.manifest ?? previousState.manifest;
1280
+ const forceSinglePageMode = newState.forceSinglePageMode ?? previousState.forceSinglePageMode;
1281
+ const visibleAreaRect = newState.visibleAreaRect ?? previousState.visibleAreaRect;
1282
+ const marginTop = newState.marginTop ?? previousState.marginTop;
1283
+ const marginBottom = newState.marginBottom ?? previousState.marginBottom;
1284
+ const newCompleteState = {
1285
+ ...previousState,
1286
+ ...newState,
1287
+ ...newState.visibleAreaRect && {
1288
+ ...newState.visibleAreaRect,
1289
+ height: newState.visibleAreaRect.height - marginTop - marginBottom
1290
+ },
1291
+ ...newState.manifest && {
1292
+ areAllItemsPrePaginated: areAllItemsPrePaginated(manifest),
1293
+ isFullyPrePaginated: isFullyPrePaginated(manifest)
1294
+ },
1251
1295
  isUsingSpreadMode: isUsingSpreadMode({
1252
- manifest: newManifest,
1296
+ manifest,
1253
1297
  visibleAreaRect,
1254
- forceSinglePageMode: settings.getSettings().forceSinglePageMode
1298
+ forceSinglePageMode
1255
1299
  })
1256
- });
1257
- };
1258
- const isRTL = () => {
1259
- var _a;
1260
- return ((_a = stateSubject.getValue().manifest) == null ? void 0 : _a.readingDirection) === `rtl`;
1261
- };
1262
- const setHasVerticalWriting = (value) => setState({
1263
- hasVerticalWriting: value
1264
- });
1265
- const recomputeSettings$ = merge(hasVerticalWriting$, manifest$);
1266
- recomputeSettings$.pipe(
1267
- withLatestFrom(hasVerticalWriting$, manifest$),
1268
- tap(([, hasVerticalWriting, manifest]) => {
1269
- settings.recompute({ hasVerticalWriting, manifest });
1270
- }),
1271
- takeUntil$1(destroy$)
1272
- ).subscribe();
1273
- settings.$.settings$.pipe(
1274
- map$1(({ forceSinglePageMode }) => forceSinglePageMode),
1275
- distinctUntilChanged(),
1276
- withLatestFrom(manifest$),
1277
- tap(([forceSinglePageMode, manifest]) => {
1278
- setState({
1279
- isUsingSpreadMode: isUsingSpreadMode({
1280
- manifest,
1281
- visibleAreaRect,
1282
- forceSinglePageMode
1283
- })
1284
- });
1285
- }),
1286
- takeUntil$1(destroy$)
1287
- ).subscribe();
1288
- const destroy = () => {
1289
- stateSubject.complete();
1290
- destroy$.next();
1291
- destroy$.complete();
1292
- };
1293
- return {
1294
- load,
1295
- isRTL,
1296
- areAllItemsPrePaginated: () => {
1297
- var _a;
1298
- return areAllItemsPrePaginated$1((_a = stateSubject.getValue()) == null ? void 0 : _a.manifest);
1299
- },
1300
- destroy,
1301
- getCalculatedInnerMargin: () => 0,
1302
- getVisibleAreaRect: () => visibleAreaRect,
1303
- isUsingSpreadMode: () => stateSubject.getValue().isUsingSpreadMode,
1304
- setHasVerticalWriting,
1305
- setVisibleAreaRect: ({ height, width, x, y }) => {
1306
- visibleAreaRect.width = width;
1307
- visibleAreaRect.height = height - marginTop - marginBottom;
1308
- visibleAreaRect.x = x;
1309
- visibleAreaRect.y = y;
1310
- const manifest = stateSubject.getValue().manifest;
1311
- if (manifest) {
1312
- setState({
1313
- isUsingSpreadMode: isUsingSpreadMode({
1314
- manifest,
1315
- visibleAreaRect,
1316
- forceSinglePageMode: settings.getSettings().forceSinglePageMode
1317
- })
1318
- });
1319
- }
1320
- },
1321
- getState: () => stateSubject.getValue(),
1322
- getManifest: () => {
1323
- var _a;
1324
- return (_a = stateSubject.getValue()) == null ? void 0 : _a.manifest;
1325
- },
1326
- getReadingDirection: () => {
1327
- var _a, _b;
1328
- return (_b = (_a = stateSubject.getValue()) == null ? void 0 : _a.manifest) == null ? void 0 : _b.readingDirection;
1329
- },
1330
- getPageSize: () => {
1331
- return {
1332
- width: stateSubject.getValue().isUsingSpreadMode ? visibleAreaRect.width / 2 : visibleAreaRect.width,
1333
- height: visibleAreaRect.height
1334
- };
1335
- },
1336
- containerElement$,
1337
- isUsingSpreadMode$,
1338
- hasVerticalWriting$,
1339
- $: {
1340
- manifest$,
1341
- destroy$: destroy$.asObservable(),
1342
- state$: stateSubject.asObservable()
1300
+ };
1301
+ if (!isShallowEqual(newCompleteState, previousState)) {
1302
+ this._stateSubject.next(newCompleteState);
1343
1303
  }
1344
- };
1345
- };
1346
- const areAllItemsPrePaginated$1 = (manifest) => !(manifest == null ? void 0 : manifest.spineItems.some((item) => item.renditionLayout === `reflowable`));
1304
+ }
1305
+ get state() {
1306
+ return this._stateSubject.getValue();
1307
+ }
1308
+ get manifest() {
1309
+ return this.state.manifest;
1310
+ }
1311
+ get readingDirection() {
1312
+ var _a;
1313
+ return (_a = this.manifest) == null ? void 0 : _a.readingDirection;
1314
+ }
1315
+ getPageSize() {
1316
+ const { isUsingSpreadMode: isUsingSpreadMode2, visibleAreaRect } = this._stateSubject.getValue();
1317
+ return {
1318
+ width: isUsingSpreadMode2 ? visibleAreaRect.width / 2 : visibleAreaRect.width,
1319
+ height: visibleAreaRect.height
1320
+ };
1321
+ }
1322
+ }
1347
1323
  const __UNSAFE_REFERENCE_ORIGINAL_IFRAME_EVENT_KEY = `__UNSAFE_REFERENCE_ORIGINAL_IFRAME_EVENT`;
1348
1324
  const ITEM_EXTENSION_VALID_FOR_FRAME_SRC = [`.xhtml`, `.html`, `.htm`];
1349
1325
  const HTML_PREFIX$1 = `prose-reader`;
@@ -1396,11 +1372,6 @@ const createFrame$ = Report.measurePerformance(`SpineItemFrame createFrame`, Inf
1396
1372
  `;
1397
1373
  return of(frame);
1398
1374
  });
1399
- const createFrameManipulator = (frameElement) => ({
1400
- frame: frameElement,
1401
- removeStyle: createRemoveStyleHelper(frameElement),
1402
- addStyle: createAddStyleHelper(frameElement)
1403
- });
1404
1375
  const getIntrinsicDimensionsFromBase64Img = (data) => new Promise((resolve, reject) => {
1405
1376
  const image = new Image();
1406
1377
  image.src = data;
@@ -1453,15 +1424,14 @@ const createHtmlPageFromResource = async (resourceResponse, item) => {
1453
1424
  const content = await resourceResponse.text();
1454
1425
  return content;
1455
1426
  };
1456
- const isOnLoadHook = (hook) => hook.name === `item.onLoad`;
1457
1427
  const createLoader = ({
1458
1428
  item,
1459
1429
  parent,
1460
1430
  fetchResource,
1461
- hooks$,
1462
1431
  context,
1463
1432
  viewportState$,
1464
- settings
1433
+ settings,
1434
+ hookManager
1465
1435
  }) => {
1466
1436
  const destroySubject$ = new Subject();
1467
1437
  const loadSubject$ = new Subject();
@@ -1469,10 +1439,9 @@ const createLoader = ({
1469
1439
  const frameElementSubject$ = new BehaviorSubject(void 0);
1470
1440
  const isLoadedSubject$ = new BehaviorSubject(false);
1471
1441
  const isReadySubject$ = new BehaviorSubject(false);
1472
- let onLoadHookReturns = [];
1473
1442
  let computedStyleAfterLoad;
1474
1443
  const makeItHot = (source$) => {
1475
- source$.pipe(takeUntil$1(context.$.destroy$)).subscribe();
1444
+ source$.pipe(takeUntil$1(context.destroy$)).subscribe();
1476
1445
  return source$;
1477
1446
  };
1478
1447
  const getHtmlFromResource = (response) => createHtmlPageFromResource(response, item);
@@ -1486,14 +1455,7 @@ const createLoader = ({
1486
1455
  withLatestFrom(frameElementSubject$),
1487
1456
  filter(([_, frame]) => !!frame),
1488
1457
  map$1(([, frame]) => {
1489
- onLoadHookReturns.forEach((fn) => {
1490
- if (fn && `unsubscribe` in fn) {
1491
- fn.unsubscribe();
1492
- } else if (fn) {
1493
- fn();
1494
- }
1495
- });
1496
- onLoadHookReturns = [];
1458
+ hookManager.destroy(`item.onLoad`, item.id);
1497
1459
  frame == null ? void 0 : frame.remove();
1498
1460
  frameElementSubject$.next(void 0);
1499
1461
  }),
@@ -1538,8 +1500,7 @@ const createLoader = ({
1538
1500
  return EMPTY;
1539
1501
  return fromEvent(frame, `load`).pipe(
1540
1502
  take(1),
1541
- withLatestFrom(hooks$),
1542
- mergeMap(([_, hooks]) => {
1503
+ mergeMap(() => {
1543
1504
  var _a, _b;
1544
1505
  const body = (_a = frame.contentDocument) == null ? void 0 : _a.body;
1545
1506
  if (!body) {
@@ -1550,21 +1511,13 @@ const createLoader = ({
1550
1511
  if ((frame == null ? void 0 : frame.contentDocument) && body) {
1551
1512
  computedStyleAfterLoad = (_b = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _b.getComputedStyle(body);
1552
1513
  }
1553
- if (settings.getSettings().computedPageTurnMode !== `scrollable`) {
1514
+ if (settings.settings.computedPageTurnMode !== `scrollable`) {
1554
1515
  frame.setAttribute(`tab-index`, `0`);
1555
1516
  }
1556
- const manipulableFrame = createFrameManipulator(frame);
1557
- onLoadHookReturns = hooks.filter(isOnLoadHook).map((hook) => {
1558
- const hookReturn = hook.fn({
1559
- ...manipulableFrame,
1560
- item
1561
- });
1562
- if (hookReturn && `subscribe` in hookReturn) {
1563
- return hookReturn.subscribe();
1564
- }
1565
- return hookReturn;
1566
- });
1567
- return of(frame);
1517
+ return hookManager.execute(`item.onLoad`, item.id, {
1518
+ itemId: item.id,
1519
+ frame
1520
+ }).pipe(map$1(() => frame));
1568
1521
  })
1569
1522
  );
1570
1523
  }),
@@ -1613,14 +1566,19 @@ const createLoader = ({
1613
1566
  }
1614
1567
  };
1615
1568
  };
1569
+ const createFrameManipulator = (frameElement) => ({
1570
+ frame: frameElement,
1571
+ removeStyle: createRemoveStyleHelper(frameElement),
1572
+ addStyle: createAddStyleHelper(frameElement)
1573
+ });
1616
1574
  const createFrameItem = ({
1617
1575
  item,
1618
1576
  parent,
1619
1577
  fetchResource,
1620
1578
  context,
1621
- hooks$,
1622
1579
  viewportState$,
1623
- settings
1580
+ settings,
1581
+ hookManager
1624
1582
  }) => {
1625
1583
  const destroySubject$ = new Subject();
1626
1584
  const {
@@ -1629,7 +1587,7 @@ const createFrameItem = ({
1629
1587
  unload,
1630
1588
  destroy: loaderDestroy,
1631
1589
  getComputedStyleAfterLoad
1632
- } = createLoader({ context, hooks$, item, parent, fetchResource, viewportState$, settings });
1590
+ } = createLoader({ context, hookManager, item, parent, fetchResource, viewportState$, settings });
1633
1591
  let isLoadedSync = false;
1634
1592
  let isReadySync = false;
1635
1593
  isLoaded$.subscribe({
@@ -1717,7 +1675,7 @@ const createFrameItem = ({
1717
1675
  if (frame) {
1718
1676
  frame.style.width = `${size.width}px`;
1719
1677
  frame.style.height = `${size.height}px`;
1720
- if (settings.getSettings().computedPageTurnMode !== `scrollable`) {
1678
+ if (settings.settings.computedPageTurnMode !== `scrollable`) {
1721
1679
  frame.setAttribute(`tab-index`, `0`);
1722
1680
  }
1723
1681
  }
@@ -1824,201 +1782,27 @@ const createSelectionTracker = () => {
1824
1782
  return void 0;
1825
1783
  return selection;
1826
1784
  },
1827
- $: subject.asObservable()
1828
- };
1829
- };
1830
- const isHtmlElement = (element) => {
1831
- return typeof element === `object` && !!element && `nodeType` in element && (element == null ? void 0 : element.nodeType) === Node.ELEMENT_NODE && `innerText` in element;
1832
- };
1833
- function createRangeOrCaretFromPoint(doc, startX, startY) {
1834
- if (`caretPositionFromPoint` in doc) {
1835
- return doc.caretPositionFromPoint(startX, startY);
1836
- } else if (typeof doc.caretRangeFromPoint !== `undefined`) {
1837
- return doc.caretRangeFromPoint(startX, startY);
1838
- }
1839
- }
1840
- const getFirstVisibleNodeForViewport = Report.measurePerformance(
1841
- `getFirstVisibleNodeForViewport`,
1842
- 1,
1843
- (documentOrElement, viewport) => {
1844
- const element = `body` in documentOrElement ? getFirstVisibleElementForViewport(documentOrElement.body, viewport) : getFirstVisibleElementForViewport(documentOrElement, viewport);
1845
- const ownerDocument = `createRange` in documentOrElement ? documentOrElement : documentOrElement.ownerDocument;
1846
- if (element) {
1847
- let lastValidRange;
1848
- let lastValidOffset = 0;
1849
- const range = ownerDocument.createRange();
1850
- Array.from(element.childNodes).some((childNode) => {
1851
- range.selectNodeContents(childNode);
1852
- const rects = range.getClientRects();
1853
- const visibleRect = getFirstVisibleDOMRect(rects, viewport);
1854
- if (visibleRect) {
1855
- lastValidRange = range.cloneRange();
1856
- const rangeOrCaret = createRangeOrCaretFromPoint(ownerDocument, Math.ceil(visibleRect.left), Math.ceil(visibleRect.top));
1857
- if (rangeOrCaret && `startContainer` in rangeOrCaret && rangeOrCaret.startContainer === lastValidRange.startContainer) {
1858
- lastValidOffset = rangeOrCaret.startOffset;
1859
- }
1860
- if (rangeOrCaret && `offsetNode` in rangeOrCaret && rangeOrCaret.offsetNode === lastValidRange.startContainer) {
1861
- lastValidOffset = rangeOrCaret.offset;
1862
- }
1863
- return true;
1864
- }
1865
- return false;
1866
- });
1867
- if (lastValidRange) {
1868
- return { node: lastValidRange.startContainer, offset: lastValidOffset };
1869
- }
1870
- return { node: element, offset: 0 };
1871
- }
1872
- return void 0;
1873
- }
1874
- );
1875
- const getFirstVisibleElementForViewport = (element, viewport) => {
1876
- let lastValidElement;
1877
- const positionFromViewport = getElementOrNodePositionFromViewPort(element.getBoundingClientRect(), viewport);
1878
- if (positionFromViewport !== `before` && positionFromViewport !== `after`) {
1879
- lastValidElement = element;
1880
- }
1881
- Array.from(element.children).some((child) => {
1882
- const childInViewPort = getFirstVisibleElementForViewport(child, viewport);
1883
- if (childInViewPort) {
1884
- lastValidElement = childInViewPort;
1885
- return true;
1886
- }
1887
- return false;
1888
- });
1889
- return lastValidElement;
1890
- };
1891
- function getElementOrNodePositionFromViewPort(domRect, { left, right }) {
1892
- if (domRect.left <= left && domRect.right <= left)
1893
- return `before`;
1894
- if (domRect.left <= left && domRect.right > left && domRect.right <= right)
1895
- return `partially-before`;
1896
- if (domRect.left <= right && domRect.right > right)
1897
- return `partially-after`;
1898
- if (domRect.left > right)
1899
- return `after`;
1900
- return `within`;
1901
- }
1902
- function getFirstVisibleDOMRect(domRect, viewport) {
1903
- return Array.from(domRect).find((domRect2) => {
1904
- const position = getElementOrNodePositionFromViewPort(domRect2, viewport);
1905
- if (position !== `before` && position !== `after`) {
1906
- return true;
1907
- }
1908
- return false;
1909
- });
1910
- }
1911
- const getRangeFromNode = (node, offset) => {
1912
- var _a;
1913
- if (node.nodeType !== Node.CDATA_SECTION_NODE && node.nodeType !== Node.DOCUMENT_TYPE_NODE) {
1914
- const range = (_a = node.ownerDocument) == null ? void 0 : _a.createRange();
1915
- range == null ? void 0 : range.selectNodeContents(node);
1916
- try {
1917
- if (offset <= ((range == null ? void 0 : range.endOffset) || 0)) {
1918
- range == null ? void 0 : range.setStart(node, offset || 0);
1919
- }
1920
- } catch (e) {
1921
- Report.error(e);
1922
- }
1923
- return range;
1924
- }
1925
- return void 0;
1926
- };
1927
- const isPointerEvent = (event) => {
1928
- var _a, _b, _c, _d, _e;
1929
- 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)) {
1930
- const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
1931
- if (eventView.PointerEvent) {
1932
- return event instanceof eventView.PointerEvent;
1933
- }
1934
- }
1935
- if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
1936
- const eventView = event == null ? void 0 : event.view;
1937
- if (eventView.PointerEvent) {
1938
- return event instanceof eventView.PointerEvent;
1939
- }
1940
- }
1941
- return false;
1942
- };
1943
- const isMouseEvent = (event) => {
1944
- var _a, _b, _c, _d, _e;
1945
- if (isPointerEvent(event))
1946
- return false;
1947
- 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)) {
1948
- const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
1949
- if (eventView.MouseEvent) {
1950
- return event instanceof eventView.MouseEvent;
1951
- }
1952
- }
1953
- if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
1954
- const eventView = event == null ? void 0 : event.view;
1955
- if (eventView.MouseEvent) {
1956
- return event instanceof eventView.MouseEvent;
1957
- }
1958
- }
1959
- return false;
1960
- };
1961
- const isTouchEvent = (event) => {
1962
- var _a, _b, _c, _d, _e;
1963
- 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)) {
1964
- const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
1965
- if (eventView.TouchEvent) {
1966
- return event instanceof eventView.TouchEvent;
1967
- }
1968
- }
1969
- if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
1970
- const eventView = event == null ? void 0 : event.view;
1971
- if (eventView.TouchEvent) {
1972
- return event instanceof eventView.TouchEvent;
1973
- }
1974
- }
1975
- return false;
1785
+ $: subject.asObservable()
1786
+ };
1976
1787
  };
1977
- const pointerEvents = [
1978
- `pointercancel`,
1979
- `pointerdown`,
1980
- `pointerenter`,
1981
- `pointerleave`,
1982
- `pointermove`,
1983
- `pointerout`,
1984
- `pointerover`,
1985
- `pointerup`,
1986
- `touchstart`,
1987
- `touchend`
1988
- ];
1989
- const mouseEvents = [
1990
- `click`,
1991
- `mousedown`,
1992
- `mouseup`,
1993
- `mouseenter`,
1994
- `mouseleave`,
1995
- `mousemove`,
1996
- `mouseout`,
1997
- `mouseover`
1998
- ];
1999
- const passthroughEvents = [...pointerEvents, ...mouseEvents];
2000
1788
  const createCommonSpineItem = ({
2001
1789
  item,
2002
1790
  context,
2003
1791
  parentElement,
2004
- iframeEventBridgeElement$,
2005
- hooks$,
2006
1792
  viewportState$,
2007
- settings
1793
+ settings,
1794
+ hookManager
2008
1795
  }) => {
2009
- var _a;
2010
1796
  const destroySubject$ = new Subject();
2011
- const containerElement = createContainerElement$1(parentElement, item, hooks$);
1797
+ const containerElement = createContainerElement$1(parentElement, item, hookManager);
2012
1798
  const overlayElement = createOverlayElement(parentElement, item);
2013
1799
  const fingerTracker = createFingerTracker();
2014
1800
  const selectionTracker = createSelectionTracker();
2015
- const frameHooks = createFrameHooks(iframeEventBridgeElement$, fingerTracker, selectionTracker);
2016
1801
  const spineItemFrame = createFrameItem({
2017
1802
  parent: containerElement,
2018
1803
  item,
2019
1804
  context,
2020
- fetchResource: (_a = context.getState()) == null ? void 0 : _a.fetchResource,
2021
- hooks$: hooks$.asObservable().pipe(map$1((hooks) => [...hooks, ...frameHooks])),
1805
+ hookManager,
2022
1806
  viewportState$,
2023
1807
  settings
2024
1808
  });
@@ -2041,12 +1825,12 @@ const createCommonSpineItem = ({
2041
1825
  return memoizedElementDimensions;
2042
1826
  };
2043
1827
  const isImageType = () => {
2044
- var _a2;
2045
- return !!((_a2 = item.mediaType) == null ? void 0 : _a2.startsWith(`image/`));
1828
+ var _a;
1829
+ return !!((_a = item.mediaType) == null ? void 0 : _a.startsWith(`image/`));
2046
1830
  };
2047
1831
  const injectStyle = (cssText) => {
2048
- var _a2, _b;
2049
- (_a2 = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a2.removeStyle(`prose-reader-css`);
1832
+ var _a, _b;
1833
+ (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.removeStyle(`prose-reader-css`);
2050
1834
  (_b = spineItemFrame.getManipulableFrame()) == null ? void 0 : _b.addStyle(`prose-reader-css`, cssText);
2051
1835
  };
2052
1836
  const adjustPositionOfElement = ({ right, left, top }) => {
@@ -2067,10 +1851,10 @@ const createCommonSpineItem = ({
2067
1851
  }
2068
1852
  };
2069
1853
  const getViewPortInformation = () => {
2070
- var _a2;
1854
+ var _a;
2071
1855
  const { width: pageWidth, height: pageHeight } = context.getPageSize();
2072
1856
  const viewportDimensions = spineItemFrame.getViewportDimensions();
2073
- const frameElement = (_a2 = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a2.frame;
1857
+ const frameElement = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame;
2074
1858
  if (containerElement && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow) && viewportDimensions) {
2075
1859
  const computedWidthScale = pageWidth / viewportDimensions.width;
2076
1860
  const computedScale = Math.min(computedWidthScale, pageHeight / viewportDimensions.height);
@@ -2080,8 +1864,8 @@ const createCommonSpineItem = ({
2080
1864
  const loadContent = () => spineItemFrame.load();
2081
1865
  const unloadContent = () => spineItemFrame.unload();
2082
1866
  const getBoundingRectOfElementFromSelector = (selector) => {
2083
- var _a2, _b, _c, _d, _e;
2084
- const frame = (_a2 = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a2.frame;
1867
+ var _a, _b, _c, _d, _e;
1868
+ const frame = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame;
2085
1869
  if (frame && selector) {
2086
1870
  if (selector.startsWith(`#`)) {
2087
1871
  return (_c = (_b = frame.contentDocument) == null ? void 0 : _b.getElementById(selector.replace(`#`, ``))) == null ? void 0 : _c.getBoundingClientRect();
@@ -2126,16 +1910,12 @@ const createCommonSpineItem = ({
2126
1910
  }) => {
2127
1911
  containerElement.style.width = `${width}px`;
2128
1912
  containerElement.style.height = `${height}px`;
2129
- hooks$.getValue().forEach((hook) => {
2130
- if (hook.name === `item.onAfterLayout`) {
2131
- hook.fn({ blankPagePosition, item, minimumWidth });
2132
- }
2133
- });
1913
+ hookManager.execute(`item.onAfterLayout`, void 0, { blankPagePosition, item, minimumWidth });
2134
1914
  setLayoutDirty();
2135
1915
  };
2136
1916
  const translateFramePositionIntoPage = (position) => {
2137
- var _a2, _b;
2138
- const { left = 0, top = 0 } = ((_a2 = spineItemFrame.getFrameElement()) == null ? void 0 : _a2.getBoundingClientRect()) || {};
1917
+ var _a, _b;
1918
+ const { left = 0, top = 0 } = ((_a = spineItemFrame.getFrameElement()) == null ? void 0 : _a.getBoundingClientRect()) || {};
2139
1919
  const computedScale = ((_b = getViewPortInformation()) == null ? void 0 : _b.computedScale) ?? 1;
2140
1920
  const adjustedX = position.clientX * computedScale + left;
2141
1921
  const adjustedY = position.clientY * computedScale + top;
@@ -2145,20 +1925,14 @@ const createCommonSpineItem = ({
2145
1925
  };
2146
1926
  };
2147
1927
  const getResource = async () => {
2148
- const fetchResource = context.getState().fetchResource;
1928
+ const fetchResource = settings.settings.fetchResource;
2149
1929
  const lastFetch = (_) => {
2150
1930
  if (fetchResource) {
2151
1931
  return fetchResource(item);
2152
1932
  }
2153
1933
  return fetch(item.href);
2154
1934
  };
2155
- const finalFetch = hooks$.getValue().reduce((acc, hook) => {
2156
- if (hook.name === `item.onGetResource`) {
2157
- return hook.fn(acc);
2158
- }
2159
- return acc;
2160
- }, lastFetch);
2161
- return await finalFetch(item);
1935
+ return await lastFetch();
2162
1936
  };
2163
1937
  const manipulateSpineItem = (cb) => {
2164
1938
  const manipulableFrame = spineItemFrame.getManipulableFrame();
@@ -2181,16 +1955,12 @@ const createCommonSpineItem = ({
2181
1955
  overlayElement
2182
1956
  });
2183
1957
  };
2184
- const executeOnLayoutBeforeMeasurementHook = (options) => hooks$.getValue().forEach((hook) => {
2185
- if (hook.name === `item.onLayoutBeforeMeasurement`) {
2186
- hook.fn({
2187
- frame: spineItemFrame,
2188
- container: containerElement,
2189
- item,
2190
- isImageType,
2191
- ...options
2192
- });
2193
- }
1958
+ const executeOnLayoutBeforeMeasurementHook = (options) => hookManager.execute("item.onLayoutBeforeMeasurement", void 0, {
1959
+ frame: spineItemFrame,
1960
+ container: containerElement,
1961
+ item,
1962
+ isImageType,
1963
+ ...options
2194
1964
  });
2195
1965
  const contentLayout$ = spineItemFrame.$.contentLayoutChange$.pipe(
2196
1966
  withLatestFrom(spineItemFrame.$.isReady$),
@@ -2229,8 +1999,8 @@ const createCommonSpineItem = ({
2229
1999
  destroySubject$.complete();
2230
2000
  },
2231
2001
  isUsingVerticalWriting: () => {
2232
- var _a2;
2233
- return (_a2 = spineItemFrame.getWritingMode()) == null ? void 0 : _a2.startsWith(`vertical`);
2002
+ var _a;
2003
+ return (_a = spineItemFrame.getWritingMode()) == null ? void 0 : _a.startsWith(`vertical`);
2234
2004
  },
2235
2005
  /**
2236
2006
  * @important
@@ -2241,7 +2011,7 @@ const createCommonSpineItem = ({
2241
2011
  * be confined to a single page.
2242
2012
  */
2243
2013
  getReadingDirection: () => {
2244
- return spineItemFrame.getReadingDirection() || context.getReadingDirection();
2014
+ return spineItemFrame.getReadingDirection() || context.readingDirection;
2245
2015
  },
2246
2016
  manipulateSpineItem,
2247
2017
  executeOnLayoutBeforeMeasurementHook,
@@ -2256,7 +2026,7 @@ const createCommonSpineItem = ({
2256
2026
  }
2257
2027
  };
2258
2028
  };
2259
- const createContainerElement$1 = (containerElement, item, hooks$) => {
2029
+ const createContainerElement$1 = (containerElement, item, hookManager) => {
2260
2030
  const element = containerElement.ownerDocument.createElement(`div`);
2261
2031
  element.classList.add(`spineItem`);
2262
2032
  element.classList.add(`spineItem-${item.renditionLayout}`);
@@ -2264,12 +2034,8 @@ const createContainerElement$1 = (containerElement, item, hooks$) => {
2264
2034
  position: absolute;
2265
2035
  overflow: hidden;
2266
2036
  `;
2267
- return hooks$.getValue().reduce((element2, hook) => {
2268
- if (hook.name === `item.onBeforeContainerCreated`) {
2269
- return hook.fn(element2);
2270
- }
2271
- return element2;
2272
- }, element);
2037
+ hookManager.execute("item.onBeforeContainerCreated", void 0, { element });
2038
+ return element;
2273
2039
  };
2274
2040
  const createOverlayElement = (containerElement, item) => {
2275
2041
  const element = containerElement.ownerDocument.createElement(`div`);
@@ -2284,42 +2050,6 @@ const createOverlayElement = (containerElement, item) => {
2284
2050
  `;
2285
2051
  return element;
2286
2052
  };
2287
- const createFrameHooks = (iframeEventBridgeElement$, fingerTracker, selectionTracker) => {
2288
- return [
2289
- {
2290
- name: `item.onLoad`,
2291
- fn: ({ frame }) => {
2292
- const unregister = passthroughEvents.map((event) => {
2293
- var _a;
2294
- const listener = (e) => {
2295
- var _a2;
2296
- let convertedEvent = e;
2297
- if (isPointerEvent(e)) {
2298
- convertedEvent = new PointerEvent(e.type, e);
2299
- }
2300
- if (isMouseEvent(e)) {
2301
- convertedEvent = new MouseEvent(e.type, e);
2302
- }
2303
- if (convertedEvent !== e) {
2304
- attachOriginalFrameEventToDocumentEvent(convertedEvent, e);
2305
- (_a2 = iframeEventBridgeElement$.getValue()) == null ? void 0 : _a2.dispatchEvent(convertedEvent);
2306
- }
2307
- };
2308
- (_a = frame.contentDocument) == null ? void 0 : _a.addEventListener(event, listener);
2309
- return () => {
2310
- var _a2;
2311
- (_a2 = frame.contentDocument) == null ? void 0 : _a2.removeEventListener(event, listener);
2312
- };
2313
- });
2314
- selectionTracker.track(frame);
2315
- fingerTracker.track(frame);
2316
- return () => {
2317
- unregister.forEach((cb) => cb());
2318
- };
2319
- }
2320
- }
2321
- ];
2322
- };
2323
2053
  const getStyleForViewportDocument = () => {
2324
2054
  return `
2325
2055
  body {
@@ -2332,19 +2062,17 @@ const createPrePaginatedSpineItem = ({
2332
2062
  item,
2333
2063
  context,
2334
2064
  containerElement,
2335
- iframeEventBridgeElement$,
2336
- hooks$,
2337
2065
  viewportState$,
2338
- settings
2066
+ settings,
2067
+ hookManager
2339
2068
  }) => {
2340
2069
  const commonSpineItem = createCommonSpineItem({
2341
2070
  context,
2342
2071
  item,
2343
2072
  parentElement: containerElement,
2344
- iframeEventBridgeElement$,
2345
- hooks$,
2346
2073
  viewportState$,
2347
- settings
2074
+ settings,
2075
+ hookManager
2348
2076
  });
2349
2077
  const spineItemFrame = commonSpineItem.spineItemFrame;
2350
2078
  const layout = ({
@@ -2355,15 +2083,15 @@ const createPrePaginatedSpineItem = ({
2355
2083
  var _a;
2356
2084
  const { width: pageWidth, height: pageHeight } = context.getPageSize();
2357
2085
  const { viewportDimensions, computedScale = 1 } = commonSpineItem.getViewPortInformation() ?? {};
2358
- const visibleArea = context.getVisibleAreaRect();
2086
+ const visibleArea = context.state.visibleAreaRect;
2359
2087
  const frameElement = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame;
2360
2088
  if ((spineItemFrame == null ? void 0 : spineItemFrame.getIsLoaded()) && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
2361
2089
  const contentWidth = pageWidth;
2362
- const contentHeight = visibleArea.height + context.getCalculatedInnerMargin();
2090
+ const contentHeight = visibleArea.height + context.state.calculatedInnerMargin;
2363
2091
  const cssLink = buildDocumentStyle(
2364
2092
  {
2365
2093
  ...commonSpineItem.getDimensionsForPaginatedContent(),
2366
- enableTouch: settings.getSettings().computedPageTurnMode !== `scrollable`,
2094
+ enableTouch: settings.settings.computedPageTurnMode !== `scrollable`,
2367
2095
  spreadPosition
2368
2096
  },
2369
2097
  viewportDimensions
@@ -2506,19 +2234,17 @@ const createReflowableSpineItem = ({
2506
2234
  item,
2507
2235
  context,
2508
2236
  containerElement,
2509
- iframeEventBridgeElement$,
2510
- hooks$,
2511
2237
  viewportState$,
2512
- settings
2238
+ settings,
2239
+ hookManager
2513
2240
  }) => {
2514
2241
  const commonSpineItem = createCommonSpineItem({
2515
2242
  context,
2516
2243
  item,
2517
2244
  parentElement: containerElement,
2518
- iframeEventBridgeElement$,
2519
- hooks$,
2520
2245
  viewportState$,
2521
- settings
2246
+ settings,
2247
+ hookManager
2522
2248
  });
2523
2249
  const spineItemFrame = commonSpineItem.spineItemFrame;
2524
2250
  let latestContentHeightWhenLoaded;
@@ -2531,12 +2257,12 @@ const createReflowableSpineItem = ({
2531
2257
  (_b = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame) == null ? void 0 : _b.style.setProperty(`width`, `${pageWidth}px`);
2532
2258
  (_d = (_c = spineItemFrame.getManipulableFrame()) == null ? void 0 : _c.frame) == null ? void 0 : _d.style.setProperty(`height`, `${pageHeight}px`);
2533
2259
  const { viewportDimensions, computedScale = 1 } = commonSpineItem.getViewPortInformation() ?? {};
2534
- const visibleArea = context.getVisibleAreaRect();
2260
+ const visibleArea = context.state.visibleAreaRect;
2535
2261
  const frameElement = (_e = spineItemFrame.getManipulableFrame()) == null ? void 0 : _e.frame;
2536
- const isGloballyPrePaginated = ((_f = context.getManifest()) == null ? void 0 : _f.renditionLayout) === `pre-paginated`;
2262
+ const isGloballyPrePaginated = ((_f = context.manifest) == null ? void 0 : _f.renditionLayout) === `pre-paginated`;
2537
2263
  if ((spineItemFrame == null ? void 0 : spineItemFrame.getIsLoaded()) && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
2538
2264
  let contentWidth = pageWidth;
2539
- let contentHeight = visibleArea.height + context.getCalculatedInnerMargin();
2265
+ let contentHeight = visibleArea.height + context.state.calculatedInnerMargin;
2540
2266
  frameElement == null ? void 0 : frameElement.style.setProperty(`visibility`, `visible`);
2541
2267
  frameElement == null ? void 0 : frameElement.style.setProperty(`opacity`, `1`);
2542
2268
  if (viewportDimensions) {
@@ -2556,8 +2282,8 @@ const createReflowableSpineItem = ({
2556
2282
  frameElement == null ? void 0 : frameElement.style.setProperty(`transform-origin`, `center center`);
2557
2283
  } else {
2558
2284
  const frameStyle = commonSpineItem.isImageType() ? buildStyleForReflowableImageOnly({
2559
- isScrollable: ((_g = context.getManifest()) == null ? void 0 : _g.renditionFlow) === `scrolled-continuous`,
2560
- enableTouch: settings.getSettings().computedPageTurnMode !== `scrollable`
2285
+ isScrollable: ((_g = context.manifest) == null ? void 0 : _g.renditionFlow) === `scrolled-continuous`,
2286
+ enableTouch: settings.settings.computedPageTurnMode !== `scrollable`
2561
2287
  }) : buildStyleWithMultiColumn(
2562
2288
  commonSpineItem.getDimensionsForReflowableContent(spineItemFrame.isUsingVerticalWriting(), minimumWidth)
2563
2289
  );
@@ -2570,7 +2296,7 @@ const createReflowableSpineItem = ({
2570
2296
  width: minimumWidth,
2571
2297
  height: contentHeight
2572
2298
  });
2573
- } else if (((_h = context.getManifest()) == null ? void 0 : _h.renditionFlow) === `scrolled-continuous`) {
2299
+ } else if (((_h = context.manifest) == null ? void 0 : _h.renditionFlow) === `scrolled-continuous`) {
2574
2300
  contentHeight = frameElement.contentDocument.documentElement.scrollHeight;
2575
2301
  latestContentHeightWhenLoaded = contentHeight;
2576
2302
  spineItemFrame.staticLayout({
@@ -2782,90 +2508,29 @@ const createSpineItem = ({
2782
2508
  item,
2783
2509
  context,
2784
2510
  containerElement,
2785
- iframeEventBridgeElement$,
2786
- hooks$,
2787
2511
  viewportState$,
2788
- settings
2512
+ settings,
2513
+ hookManager
2789
2514
  }) => {
2790
2515
  if (item.renditionLayout === `pre-paginated`) {
2791
2516
  return createPrePaginatedSpineItem({
2792
2517
  item,
2793
2518
  context,
2794
2519
  containerElement,
2795
- iframeEventBridgeElement$,
2796
- hooks$,
2797
2520
  viewportState$,
2798
- settings
2521
+ settings,
2522
+ hookManager
2799
2523
  });
2800
2524
  }
2801
2525
  return createReflowableSpineItem({
2802
2526
  item,
2803
2527
  context,
2804
2528
  containerElement,
2805
- iframeEventBridgeElement$,
2806
- hooks$,
2807
2529
  viewportState$,
2808
- settings
2530
+ settings,
2531
+ hookManager
2809
2532
  });
2810
2533
  };
2811
- const createEventsHelper = ({
2812
- iframeEventBridgeElement$,
2813
- locator
2814
- }) => {
2815
- const normalizeEventForViewport = (event) => {
2816
- var _a;
2817
- const eventIsComingFromBridge = event.target === iframeEventBridgeElement$.getValue();
2818
- const iframeOriginalEvent = getOriginalFrameEventFromDocumentEvent(event);
2819
- const originalFrame = (_a = iframeOriginalEvent == null ? void 0 : iframeOriginalEvent.view) == null ? void 0 : _a.frameElement;
2820
- if (!eventIsComingFromBridge || !iframeOriginalEvent || !originalFrame)
2821
- return event;
2822
- const spineItem = locator.getSpineItemFromIframe(originalFrame);
2823
- if (!spineItem)
2824
- return event;
2825
- if (isPointerEvent(event)) {
2826
- const { clientX, clientY } = spineItem.translateFramePositionIntoPage(event);
2827
- const newEvent = new PointerEvent(event.type, {
2828
- ...event,
2829
- clientX,
2830
- clientY
2831
- });
2832
- Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
2833
- return newEvent;
2834
- }
2835
- if (isMouseEvent(event)) {
2836
- const { clientX, clientY } = spineItem.translateFramePositionIntoPage(event);
2837
- const newEvent = new MouseEvent(event.type, {
2838
- ...event,
2839
- clientX,
2840
- clientY
2841
- });
2842
- Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
2843
- return newEvent;
2844
- }
2845
- if (isTouchEvent(event)) {
2846
- const touches = Array.from(event.touches).map((touch) => {
2847
- const { clientX, clientY } = spineItem.translateFramePositionIntoPage(touch);
2848
- return new Touch({
2849
- identifier: touch.identifier,
2850
- target: touch.target,
2851
- clientX,
2852
- clientY
2853
- });
2854
- });
2855
- const newEvent = new TouchEvent(event.type, {
2856
- touches,
2857
- changedTouches: touches,
2858
- targetTouches: touches
2859
- });
2860
- Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
2861
- return newEvent;
2862
- }
2863
- return event;
2864
- };
2865
- return {
2866
- normalizeEventForViewport
2867
- };
2868
- };
2869
2534
  const ELEMENT_NODE = Node.ELEMENT_NODE;
2870
2535
  const TEXT_NODE = Node.TEXT_NODE;
2871
2536
  const CDATA_SECTION_NODE = Node.CDATA_SECTION_NODE;
@@ -3767,9 +3432,7 @@ const createSpine = ({
3767
3432
  element$,
3768
3433
  context,
3769
3434
  pagination,
3770
- iframeEventBridgeElement$,
3771
3435
  spineItemManager,
3772
- hooks$,
3773
3436
  spineItemLocator,
3774
3437
  spineLocator,
3775
3438
  cfiLocator,
@@ -3777,18 +3440,13 @@ const createSpine = ({
3777
3440
  navigationAdjusted$,
3778
3441
  currentNavigationPosition$,
3779
3442
  viewportState$,
3780
- settings
3443
+ settings,
3444
+ hookManager
3781
3445
  }) => {
3782
3446
  const spineItems$ = new Subject();
3783
3447
  const itemsBeforeDestroySubject$ = new Subject();
3784
3448
  const subject = new Subject();
3785
3449
  const containerElement$ = new BehaviorSubject(noopElement$1);
3786
- const eventsHelper = createEventsHelper({
3787
- context,
3788
- spineItemManager,
3789
- iframeEventBridgeElement$,
3790
- locator: spineLocator
3791
- });
3792
3450
  let selectionSubscription;
3793
3451
  const reload = (manifest) => {
3794
3452
  itemsBeforeDestroySubject$.next();
@@ -3797,11 +3455,10 @@ const createSpine = ({
3797
3455
  const spineItem = createSpineItem({
3798
3456
  item: resource,
3799
3457
  containerElement: containerElement$.getValue(),
3800
- iframeEventBridgeElement$,
3801
3458
  context,
3802
- hooks$,
3803
3459
  viewportState$,
3804
- settings
3460
+ settings,
3461
+ hookManager
3805
3462
  });
3806
3463
  spineItemManager.add(spineItem);
3807
3464
  });
@@ -3820,7 +3477,7 @@ const createSpine = ({
3820
3477
  var _a;
3821
3478
  (_a = spineItemManager.get(id)) == null ? void 0 : _a.manipulateSpineItem(cb);
3822
3479
  };
3823
- context.$.manifest$.pipe(tap(reload), takeUntil$1(context.$.destroy$)).subscribe();
3480
+ context.manifest$.pipe(tap(reload), takeUntil$1(context.destroy$)).subscribe();
3824
3481
  const waitForViewportFree$ = viewportState$.pipe(
3825
3482
  filter((v) => v === `free`),
3826
3483
  take(1)
@@ -3912,7 +3569,7 @@ const createSpine = ({
3912
3569
  Report.error(e);
3913
3570
  return EMPTY;
3914
3571
  }),
3915
- takeUntil$1(context.$.destroy$)
3572
+ takeUntil$1(context.destroy$)
3916
3573
  )
3917
3574
  ).subscribe();
3918
3575
  const itemUpdateOnNavigation$ = navigation$.pipe(
@@ -3958,7 +3615,7 @@ const createSpine = ({
3958
3615
  *
3959
3616
  * The cfi is later adjusted with heavy dom lookup once the viewport is free.
3960
3617
  */
3961
- 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) : (
3618
+ 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) : (
3962
3619
  /* @todo check ? */
3963
3620
  cfiLocator.getRootCfi(beginSpineItem)
3964
3621
  ),
@@ -3970,7 +3627,7 @@ const createSpine = ({
3970
3627
  spineItem: endSpineItem,
3971
3628
  spineItemIndex: endItemIndex,
3972
3629
  pageIndex: endPageIndex,
3973
- 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) : (
3630
+ 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) : (
3974
3631
  /* @todo check ? */
3975
3632
  cfiLocator.getRootCfi(endSpineItem)
3976
3633
  ),
@@ -3994,13 +3651,13 @@ const createSpine = ({
3994
3651
  time2();
3995
3652
  }),
3996
3653
  share(),
3997
- takeUntil$1(context.$.destroy$)
3654
+ takeUntil$1(context.destroy$)
3998
3655
  );
3999
3656
  itemUpdateOnNavigation$.pipe(
4000
3657
  switchMap$1((data) => {
4001
3658
  return adjustPagination(data.position).pipe(takeUntil$1(spineItemManager.$.layout$));
4002
3659
  }),
4003
- takeUntil$1(context.$.destroy$)
3660
+ takeUntil$1(context.destroy$)
4004
3661
  ).subscribe();
4005
3662
  merge(
4006
3663
  /**
@@ -4034,7 +3691,7 @@ const createSpine = ({
4034
3691
  take(1)
4035
3692
  );
4036
3693
  }),
4037
- takeUntil$1(context.$.destroy$)
3694
+ takeUntil$1(context.destroy$)
4038
3695
  ).subscribe();
4039
3696
  const elementSub = element$.pipe().subscribe((element) => {
4040
3697
  const containerElement = createContainerElement(element.ownerDocument);
@@ -4046,7 +3703,6 @@ const createSpine = ({
4046
3703
  locator: spineLocator,
4047
3704
  spineItemLocator,
4048
3705
  cfiLocator,
4049
- normalizeEventForViewport: eventsHelper.normalizeEventForViewport,
4050
3706
  manipulateSpineItems,
4051
3707
  manipulateSpineItem,
4052
3708
  destroy: () => {
@@ -4093,16 +3749,16 @@ const createSpineItemManager = ({ context, settings }) => {
4093
3749
  const orderedSpineItemsSubject$ = new BehaviorSubject([]);
4094
3750
  let focusedSpineItemIndex;
4095
3751
  const layout = () => {
4096
- const manifest = context.getManifest();
3752
+ const manifest = context.manifest;
4097
3753
  const newItemLayoutInformation = [];
4098
3754
  const isGloballyPrePaginated = (manifest == null ? void 0 : manifest.renditionLayout) === `pre-paginated`;
4099
3755
  orderedSpineItemsSubject$.value.reduce(
4100
3756
  ({ horizontalOffset, verticalOffset }, item, index) => {
4101
3757
  let minimumWidth = context.getPageSize().width;
4102
3758
  let blankPagePosition = `none`;
4103
- const itemStartOnNewScreen = horizontalOffset % context.getVisibleAreaRect().width === 0;
3759
+ const itemStartOnNewScreen = horizontalOffset % context.state.visibleAreaRect.width === 0;
4104
3760
  const isLastItem = index === orderedSpineItemsSubject$.value.length - 1;
4105
- if (context.isUsingSpreadMode()) {
3761
+ if (context.state.isUsingSpreadMode) {
4106
3762
  if (!isGloballyPrePaginated && item.item.renditionLayout === `reflowable` && !isLastItem) {
4107
3763
  minimumWidth = context.getPageSize().width * 2;
4108
3764
  }
@@ -4128,10 +3784,10 @@ const createSpineItemManager = ({ context, settings }) => {
4128
3784
  const { width, height } = item.layout({
4129
3785
  minimumWidth,
4130
3786
  blankPagePosition,
4131
- spreadPosition: context.isUsingSpreadMode() ? itemStartOnNewScreen ? context.isRTL() ? `right` : `left` : context.isRTL() ? `left` : `right` : `none`
3787
+ spreadPosition: context.state.isUsingSpreadMode ? itemStartOnNewScreen ? context.isRTL() ? `right` : `left` : context.isRTL() ? `left` : `right` : `none`
4132
3788
  });
4133
- if (settings.getSettings().computedPageTurnDirection === `vertical`) {
4134
- const currentValidEdgeYForVerticalPositioning = itemStartOnNewScreen ? verticalOffset : verticalOffset - context.getVisibleAreaRect().height;
3789
+ if (settings.settings.computedPageTurnDirection === `vertical`) {
3790
+ const currentValidEdgeYForVerticalPositioning = itemStartOnNewScreen ? verticalOffset : verticalOffset - context.state.visibleAreaRect.height;
4135
3791
  const currentValidEdgeXForVerticalPositioning = itemStartOnNewScreen ? 0 : horizontalOffset;
4136
3792
  if (context.isRTL()) {
4137
3793
  item.adjustPositionOfElement({
@@ -4162,8 +3818,8 @@ const createSpineItemManager = ({ context, settings }) => {
4162
3818
  item.adjustPositionOfElement(context.isRTL() ? { right: horizontalOffset, top: 0 } : { left: horizontalOffset, top: 0 });
4163
3819
  newItemLayoutInformation.push({
4164
3820
  ...context.isRTL() ? {
4165
- left: context.getVisibleAreaRect().width - horizontalOffset - width,
4166
- right: context.getVisibleAreaRect().width - horizontalOffset
3821
+ left: context.state.visibleAreaRect.width - horizontalOffset - width,
3822
+ right: context.state.visibleAreaRect.width - horizontalOffset
4167
3823
  } : {
4168
3824
  left: horizontalOffset,
4169
3825
  right: horizontalOffset + width
@@ -4198,9 +3854,9 @@ const createSpineItemManager = ({ context, settings }) => {
4198
3854
  const loadContents = Report.measurePerformance(`loadContents`, 10, (rangeOfIndex) => {
4199
3855
  var _a;
4200
3856
  const [leftIndex, rightIndex] = rangeOfIndex;
4201
- const numberOfAdjacentSpineItemToPreLoad = settings.getSettings().numberOfAdjacentSpineItemToPreLoad;
4202
- const isPrePaginated = ((_a = context.getManifest()) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
4203
- const isUsingFreeScroll = settings.getSettings().computedPageTurnMode === `scrollable`;
3857
+ const numberOfAdjacentSpineItemToPreLoad = settings.settings.numberOfAdjacentSpineItemToPreLoad;
3858
+ const isPrePaginated = ((_a = context.manifest) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
3859
+ const isUsingFreeScroll = settings.settings.computedPageTurnMode === `scrollable`;
4204
3860
  orderedSpineItemsSubject$.value.forEach((orderedSpineItem, index) => {
4205
3861
  const isBeforeFocusedWithPreload = (
4206
3862
  // we never want to preload anything before on free scroll on flow because it could offset the cursor
@@ -4248,18 +3904,22 @@ const createSpineItemManager = ({ context, settings }) => {
4248
3904
  };
4249
3905
  const add = (spineItem) => {
4250
3906
  orderedSpineItemsSubject$.value.push(spineItem);
4251
- spineItem.$.contentLayout$.pipe(takeUntil$1(context.$.destroy$)).subscribe(() => {
3907
+ spineItem.$.contentLayout$.pipe(takeUntil$1(context.destroy$)).subscribe(() => {
4252
3908
  layout();
4253
3909
  });
4254
3910
  spineItem.$.loaded$.pipe(
4255
3911
  tap(() => {
4256
3912
  if (spineItem.isUsingVerticalWriting()) {
4257
- context.setHasVerticalWriting(true);
3913
+ context.update({
3914
+ hasVerticalWriting: true
3915
+ });
4258
3916
  } else {
4259
- context.setHasVerticalWriting(false);
3917
+ context.update({
3918
+ hasVerticalWriting: false
3919
+ });
4260
3920
  }
4261
3921
  }),
4262
- takeUntil$1(context.$.destroy$)
3922
+ takeUntil$1(context.destroy$)
4263
3923
  ).subscribe();
4264
3924
  spineItem.load();
4265
3925
  };
@@ -4304,7 +3964,154 @@ const createSpineItemManager = ({ context, settings }) => {
4304
3964
  })
4305
3965
  )
4306
3966
  }
4307
- };
3967
+ };
3968
+ };
3969
+ const isHtmlElement = (element) => {
3970
+ return typeof element === `object` && !!element && `nodeType` in element && (element == null ? void 0 : element.nodeType) === Node.ELEMENT_NODE && `innerText` in element;
3971
+ };
3972
+ function createRangeOrCaretFromPoint(doc, startX, startY) {
3973
+ if (`caretPositionFromPoint` in doc) {
3974
+ return doc.caretPositionFromPoint(startX, startY);
3975
+ } else if (typeof doc.caretRangeFromPoint !== `undefined`) {
3976
+ return doc.caretRangeFromPoint(startX, startY);
3977
+ }
3978
+ }
3979
+ const getFirstVisibleNodeForViewport = Report.measurePerformance(
3980
+ `getFirstVisibleNodeForViewport`,
3981
+ 1,
3982
+ (documentOrElement, viewport) => {
3983
+ const element = `body` in documentOrElement ? getFirstVisibleElementForViewport(documentOrElement.body, viewport) : getFirstVisibleElementForViewport(documentOrElement, viewport);
3984
+ const ownerDocument = `createRange` in documentOrElement ? documentOrElement : documentOrElement.ownerDocument;
3985
+ if (element) {
3986
+ let lastValidRange;
3987
+ let lastValidOffset = 0;
3988
+ const range = ownerDocument.createRange();
3989
+ Array.from(element.childNodes).some((childNode) => {
3990
+ range.selectNodeContents(childNode);
3991
+ const rects = range.getClientRects();
3992
+ const visibleRect = getFirstVisibleDOMRect(rects, viewport);
3993
+ if (visibleRect) {
3994
+ lastValidRange = range.cloneRange();
3995
+ const rangeOrCaret = createRangeOrCaretFromPoint(ownerDocument, Math.ceil(visibleRect.left), Math.ceil(visibleRect.top));
3996
+ if (rangeOrCaret && `startContainer` in rangeOrCaret && rangeOrCaret.startContainer === lastValidRange.startContainer) {
3997
+ lastValidOffset = rangeOrCaret.startOffset;
3998
+ }
3999
+ if (rangeOrCaret && `offsetNode` in rangeOrCaret && rangeOrCaret.offsetNode === lastValidRange.startContainer) {
4000
+ lastValidOffset = rangeOrCaret.offset;
4001
+ }
4002
+ return true;
4003
+ }
4004
+ return false;
4005
+ });
4006
+ if (lastValidRange) {
4007
+ return { node: lastValidRange.startContainer, offset: lastValidOffset };
4008
+ }
4009
+ return { node: element, offset: 0 };
4010
+ }
4011
+ return void 0;
4012
+ }
4013
+ );
4014
+ const getFirstVisibleElementForViewport = (element, viewport) => {
4015
+ let lastValidElement;
4016
+ const positionFromViewport = getElementOrNodePositionFromViewPort(element.getBoundingClientRect(), viewport);
4017
+ if (positionFromViewport !== `before` && positionFromViewport !== `after`) {
4018
+ lastValidElement = element;
4019
+ }
4020
+ Array.from(element.children).some((child) => {
4021
+ const childInViewPort = getFirstVisibleElementForViewport(child, viewport);
4022
+ if (childInViewPort) {
4023
+ lastValidElement = childInViewPort;
4024
+ return true;
4025
+ }
4026
+ return false;
4027
+ });
4028
+ return lastValidElement;
4029
+ };
4030
+ function getElementOrNodePositionFromViewPort(domRect, { left, right }) {
4031
+ if (domRect.left <= left && domRect.right <= left)
4032
+ return `before`;
4033
+ if (domRect.left <= left && domRect.right > left && domRect.right <= right)
4034
+ return `partially-before`;
4035
+ if (domRect.left <= right && domRect.right > right)
4036
+ return `partially-after`;
4037
+ if (domRect.left > right)
4038
+ return `after`;
4039
+ return `within`;
4040
+ }
4041
+ function getFirstVisibleDOMRect(domRect, viewport) {
4042
+ return Array.from(domRect).find((domRect2) => {
4043
+ const position = getElementOrNodePositionFromViewPort(domRect2, viewport);
4044
+ if (position !== `before` && position !== `after`) {
4045
+ return true;
4046
+ }
4047
+ return false;
4048
+ });
4049
+ }
4050
+ const getRangeFromNode = (node, offset) => {
4051
+ var _a;
4052
+ if (node.nodeType !== Node.CDATA_SECTION_NODE && node.nodeType !== Node.DOCUMENT_TYPE_NODE) {
4053
+ const range = (_a = node.ownerDocument) == null ? void 0 : _a.createRange();
4054
+ range == null ? void 0 : range.selectNodeContents(node);
4055
+ try {
4056
+ if (offset <= ((range == null ? void 0 : range.endOffset) || 0)) {
4057
+ range == null ? void 0 : range.setStart(node, offset || 0);
4058
+ }
4059
+ } catch (e) {
4060
+ Report.error(e);
4061
+ }
4062
+ return range;
4063
+ }
4064
+ return void 0;
4065
+ };
4066
+ const isPointerEvent = (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.PointerEvent) {
4071
+ return event instanceof eventView.PointerEvent;
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.PointerEvent) {
4077
+ return event instanceof eventView.PointerEvent;
4078
+ }
4079
+ }
4080
+ return false;
4081
+ };
4082
+ const isMouseEvent = (event) => {
4083
+ var _a, _b, _c, _d, _e;
4084
+ if (isPointerEvent(event))
4085
+ return false;
4086
+ 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)) {
4087
+ const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
4088
+ if (eventView.MouseEvent) {
4089
+ return event instanceof eventView.MouseEvent;
4090
+ }
4091
+ }
4092
+ if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
4093
+ const eventView = event == null ? void 0 : event.view;
4094
+ if (eventView.MouseEvent) {
4095
+ return event instanceof eventView.MouseEvent;
4096
+ }
4097
+ }
4098
+ return false;
4099
+ };
4100
+ const isTouchEvent = (event) => {
4101
+ var _a, _b, _c, _d, _e;
4102
+ 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)) {
4103
+ const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
4104
+ if (eventView.TouchEvent) {
4105
+ return event instanceof eventView.TouchEvent;
4106
+ }
4107
+ }
4108
+ if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
4109
+ const eventView = event == null ? void 0 : event.view;
4110
+ if (eventView.TouchEvent) {
4111
+ return event instanceof eventView.TouchEvent;
4112
+ }
4113
+ }
4114
+ return false;
4308
4115
  };
4309
4116
  const createLocationResolver$1 = ({ context }) => {
4310
4117
  const getSafePosition = (unsafeSpineItemPosition, spineItem) => ({
@@ -4526,7 +4333,7 @@ const createNavigationResolver = ({
4526
4333
  { disable: true }
4527
4334
  );
4528
4335
  const getAdjustedPositionForSpread = ({ x, y }) => {
4529
- const isOffsetNotAtEdge = x % context.getVisibleAreaRect().width !== 0;
4336
+ const isOffsetNotAtEdge = x % context.state.visibleAreaRect.width !== 0;
4530
4337
  const correctedX = isOffsetNotAtEdge ? x - context.getPageSize().width : x;
4531
4338
  return { x: correctedX, y };
4532
4339
  };
@@ -4565,7 +4372,7 @@ const createNavigationResolver = ({
4565
4372
  return { x: 0, y: 0 };
4566
4373
  };
4567
4374
  const getNavigationForRightSinglePage = (position) => {
4568
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4375
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4569
4376
  const spineItem = locator.getSpineItemFromPosition(position) || spineItemManager.getFocusedSpineItem();
4570
4377
  const defaultNavigation = position;
4571
4378
  if (!spineItem) {
@@ -4584,7 +4391,7 @@ const createNavigationResolver = ({
4584
4391
  }
4585
4392
  };
4586
4393
  const getNavigationForLeftSinglePage = (position) => {
4587
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4394
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4588
4395
  const spineItem = locator.getSpineItemFromPosition(position) || spineItemManager.getFocusedSpineItem();
4589
4396
  const defaultNavigation = { ...position, spineItem };
4590
4397
  if (!spineItem) {
@@ -4608,7 +4415,7 @@ const createNavigationResolver = ({
4608
4415
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x === navigation.x) {
4609
4416
  return getAdjustedPositionForSpread(navigation);
4610
4417
  }
4611
- if (context.isUsingSpreadMode()) {
4418
+ if (context.state.isUsingSpreadMode) {
4612
4419
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x !== navigation.x) {
4613
4420
  return getAdjustedPositionForSpread(
4614
4421
  wrapPositionWithSafeEdge(
@@ -4622,7 +4429,7 @@ const createNavigationResolver = ({
4622
4429
  )
4623
4430
  );
4624
4431
  }
4625
- if (settings.getSettings().computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4432
+ if (settings.settings.computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4626
4433
  return getAdjustedPositionForSpread(navigation);
4627
4434
  }
4628
4435
  const doubleNavigation = getNavigationForRightSinglePage(navigation);
@@ -4636,7 +4443,7 @@ const createNavigationResolver = ({
4636
4443
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x === navigation.x) {
4637
4444
  return getAdjustedPositionForSpread(navigation);
4638
4445
  }
4639
- if (context.isUsingSpreadMode()) {
4446
+ if (context.state.isUsingSpreadMode) {
4640
4447
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x !== navigation.x) {
4641
4448
  return getAdjustedPositionForSpread(
4642
4449
  wrapPositionWithSafeEdge(
@@ -4644,7 +4451,7 @@ const createNavigationResolver = ({
4644
4451
  )
4645
4452
  );
4646
4453
  }
4647
- if (settings.getSettings().computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4454
+ if (settings.settings.computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4648
4455
  return getAdjustedPositionForSpread(navigation);
4649
4456
  }
4650
4457
  const doubleNavigation = getNavigationForLeftSinglePage(navigation);
@@ -4657,7 +4464,7 @@ const createNavigationResolver = ({
4657
4464
  try {
4658
4465
  const validUrl = url instanceof URL ? url : new URL(url);
4659
4466
  const urlWithoutAnchor = `${validUrl.origin}${validUrl.pathname}`;
4660
- const existingSpineItem = (_a = context.getManifest()) == null ? void 0 : _a.spineItems.find((item) => item.href === urlWithoutAnchor);
4467
+ const existingSpineItem = (_a = context.manifest) == null ? void 0 : _a.spineItems.find((item) => item.href === urlWithoutAnchor);
4661
4468
  if (existingSpineItem) {
4662
4469
  const spineItem = spineItemManager.get(existingSpineItem.id);
4663
4470
  if (spineItem) {
@@ -4686,15 +4493,15 @@ const createNavigationResolver = ({
4686
4493
  return { x: 0, y: 0 };
4687
4494
  };
4688
4495
  const getMostPredominantNavigationForPosition = (viewportPosition) => {
4689
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4496
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4690
4497
  const triggerPercentage = 0.5;
4691
- const triggerXPosition = pageTurnDirection === `horizontal` ? viewportPosition.x + context.getVisibleAreaRect().width * triggerPercentage : 0;
4692
- const triggerYPosition = pageTurnDirection === `horizontal` ? 0 : viewportPosition.y + context.getVisibleAreaRect().height * triggerPercentage;
4498
+ const triggerXPosition = pageTurnDirection === `horizontal` ? viewportPosition.x + context.state.visibleAreaRect.width * triggerPercentage : 0;
4499
+ const triggerYPosition = pageTurnDirection === `horizontal` ? 0 : viewportPosition.y + context.state.visibleAreaRect.height * triggerPercentage;
4693
4500
  const midScreenPositionSafePosition = wrapPositionWithSafeEdge({ x: triggerXPosition, y: triggerYPosition });
4694
4501
  return getNavigationForPosition(midScreenPositionSafePosition);
4695
4502
  };
4696
4503
  const isNavigationGoingForwardFrom = (to, from2) => {
4697
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4504
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4698
4505
  if (pageTurnDirection === `vertical`) {
4699
4506
  return to.y > from2.y;
4700
4507
  }
@@ -4738,14 +4545,14 @@ const createScrollViewportNavigator = ({
4738
4545
  );
4739
4546
  const adjustReadingOffset = ({ x, y }) => {
4740
4547
  var _a;
4741
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
4548
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
4742
4549
  lastScrollWasProgrammaticallyTriggered = true;
4743
4550
  (_a = element$.getValue()) == null ? void 0 : _a.scrollTo({ left: x, top: y });
4744
4551
  return true;
4745
4552
  }
4746
4553
  return false;
4747
4554
  };
4748
- const runOnFreePageTurnModeOnly$ = (source) => settings.$.settings$.pipe(
4555
+ const runOnFreePageTurnModeOnly$ = (source) => settings.settings$.pipe(
4749
4556
  map$1(({ computedPageTurnMode }) => computedPageTurnMode),
4750
4557
  distinctUntilChanged(),
4751
4558
  switchMap$1((mode) => iif(() => mode === `controlled`, EMPTY, source))
@@ -4755,7 +4562,7 @@ const createScrollViewportNavigator = ({
4755
4562
  filter(isDefined),
4756
4563
  switchMap$1((element) => fromEvent(element, `scroll`))
4757
4564
  )
4758
- ).pipe(onlyUserScrollFilter, share(), takeUntil$1(context.$.destroy$));
4565
+ ).pipe(onlyUserScrollFilter, share(), takeUntil$1(context.destroy$));
4759
4566
  const getScaledDownPosition = ({ x, y }) => {
4760
4567
  var _a, _b;
4761
4568
  const spineElement = spine.getElement();
@@ -4803,7 +4610,7 @@ const createScrollViewportNavigator = ({
4803
4610
  const userScrollEnd$ = userScroll$.pipe(
4804
4611
  debounceTime$1(SCROLL_FINISHED_DEBOUNCE_TIMEOUT, animationFrameScheduler),
4805
4612
  share(),
4806
- takeUntil$1(context.$.destroy$)
4613
+ takeUntil$1(context.destroy$)
4807
4614
  );
4808
4615
  const state$ = merge(
4809
4616
  userScroll$.pipe(
@@ -4896,7 +4703,7 @@ const createManualViewportNavigator = ({
4896
4703
  filter((e) => e.type === `pageIndex`),
4897
4704
  filter(() => {
4898
4705
  var _a;
4899
- if (((_a = context.getManifest()) == null ? void 0 : _a.renditionLayout) === `reflowable`) {
4706
+ if (((_a = context.manifest) == null ? void 0 : _a.renditionLayout) === `reflowable`) {
4900
4707
  Report.warn(`This method only works for pre-paginated content`);
4901
4708
  return false;
4902
4709
  }
@@ -5030,11 +4837,11 @@ const createPanViewportNavigator = ({
5030
4837
  `${NAMESPACE$1} moveTo`,
5031
4838
  5,
5032
4839
  (delta, { final, start } = {}) => {
5033
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
4840
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5034
4841
  Report.warn(`pan control is not available on free page turn mode`);
5035
4842
  return;
5036
4843
  }
5037
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4844
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
5038
4845
  if (start) {
5039
4846
  stateSubject$.next(`start`);
5040
4847
  movingLastDelta = { x: 0, y: 0 };
@@ -5094,7 +4901,7 @@ const createPanViewportNavigator = ({
5094
4901
  );
5095
4902
  const snapNavigation$ = navigationTriggerSubject$.pipe(
5096
4903
  filter((e) => e.type === `snap`),
5097
- withLatestFrom$1(settings.$.settings$),
4904
+ withLatestFrom$1(settings.settings$),
5098
4905
  switchMap$1(
5099
4906
  ([
5100
4907
  {
@@ -5102,11 +4909,11 @@ const createPanViewportNavigator = ({
5102
4909
  },
5103
4910
  { navigationSnapThreshold }
5104
4911
  ]) => {
5105
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4912
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
5106
4913
  const movingForward = navigator2.isNavigationGoingForwardFrom(to, from2);
5107
4914
  const triggerPercentage = movingForward ? 1 - navigationSnapThreshold : navigationSnapThreshold;
5108
- const triggerXPosition = pageTurnDirection === `horizontal` ? to.x + context.getVisibleAreaRect().width * triggerPercentage : 0;
5109
- const triggerYPosition = pageTurnDirection === `horizontal` ? 0 : to.y + context.getVisibleAreaRect().height * triggerPercentage;
4915
+ const triggerXPosition = pageTurnDirection === `horizontal` ? to.x + context.state.visibleAreaRect.width * triggerPercentage : 0;
4916
+ const triggerYPosition = pageTurnDirection === `horizontal` ? 0 : to.y + context.state.visibleAreaRect.height * triggerPercentage;
5110
4917
  const midScreenPositionSafePosition = navigator2.wrapPositionWithSafeEdge({
5111
4918
  x: triggerXPosition,
5112
4919
  y: triggerYPosition
@@ -5143,7 +4950,7 @@ const createViewportNavigator = ({
5143
4950
  parentElement$,
5144
4951
  cfiLocator,
5145
4952
  spineLocator,
5146
- hooks$,
4953
+ hookManager,
5147
4954
  spine,
5148
4955
  settings
5149
4956
  }) => {
@@ -5165,7 +4972,7 @@ const createViewportNavigator = ({
5165
4972
  const adjustNavigationSubject$ = new Subject();
5166
4973
  const getCurrentViewportPosition = Report.measurePerformance(`${NAMESPACE} getCurrentViewportPosition`, 1, () => {
5167
4974
  var _a;
5168
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
4975
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5169
4976
  return scrollViewportNavigator.getCurrentViewportPosition();
5170
4977
  }
5171
4978
  const { x, y } = ((_a = element$.getValue()) == null ? void 0 : _a.getBoundingClientRect()) ?? { x: 0, y: 0 };
@@ -5209,13 +5016,13 @@ const createViewportNavigator = ({
5209
5016
  const viewportNavigatorsSharedState$ = merge(...viewportNavigators.map(({ $: { state$: state$2 } }) => state$2));
5210
5017
  let lastUserExpectedNavigation;
5211
5018
  const makeItHot = (source$) => {
5212
- source$.pipe(takeUntil$1(context.$.destroy$)).subscribe();
5019
+ source$.pipe(takeUntil$1(context.destroy$)).subscribe();
5213
5020
  return source$;
5214
5021
  };
5215
5022
  const adjustReadingOffset = Report.measurePerformance(
5216
5023
  `adjustReadingOffset`,
5217
5024
  2,
5218
- ({ x, y }, hooks) => {
5025
+ ({ x, y }) => {
5219
5026
  const element = element$.getValue();
5220
5027
  if (!element)
5221
5028
  throw new Error("Invalid element");
@@ -5226,11 +5033,7 @@ const createViewportNavigator = ({
5226
5033
  if (!isAdjusted) {
5227
5034
  element.style.transform = `translate3d(${-x}px, -${y}px, 0)`;
5228
5035
  }
5229
- hooks.forEach((hook) => {
5230
- if (hook.name === `onViewportOffsetAdjust`) {
5231
- hook.fn();
5232
- }
5233
- });
5036
+ hookManager.execute("onViewportOffsetAdjust", void 0, {});
5234
5037
  },
5235
5038
  { disable: true }
5236
5039
  );
@@ -5238,7 +5041,7 @@ const createViewportNavigator = ({
5238
5041
  const lastCfi = pagination.getPaginationInfo().beginCfi;
5239
5042
  let adjustedSpinePosition = currentNavigationPositionSubject$.value;
5240
5043
  const offsetInSpineItem = 0;
5241
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
5044
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5242
5045
  adjustedSpinePosition = scrollViewportNavigator.getNavigationForPosition(getCurrentViewportPosition());
5243
5046
  } else if ((lastUserExpectedNavigation == null ? void 0 : lastUserExpectedNavigation.type) === `navigate-from-cfi`) {
5244
5047
  adjustedSpinePosition = navigator2.getNavigationForCfi(lastUserExpectedNavigation.data);
@@ -5283,7 +5086,7 @@ const createViewportNavigator = ({
5283
5086
  layoutSubject$.subscribe(() => {
5284
5087
  currentViewportPositionMemoUnused = void 0;
5285
5088
  });
5286
- const layoutChangeSettings$ = settings.$.settings$.pipe(
5089
+ const layoutChangeSettings$ = settings.settings$.pipe(
5287
5090
  mapKeysTo([`computedPageTurnDirection`, `computedPageTurnMode`, `numberOfAdjacentSpineItemToPreLoad`]),
5288
5091
  distinctUntilChanged(isShallowEqual),
5289
5092
  skip(1)
@@ -5291,7 +5094,7 @@ const createViewportNavigator = ({
5291
5094
  const layout$ = merge(layoutSubject$, layoutChangeSettings$).pipe(
5292
5095
  withLatestFrom(element$),
5293
5096
  tap(([, element]) => {
5294
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
5097
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5295
5098
  element.style.removeProperty(`transform`);
5296
5099
  element.style.removeProperty(`transition`);
5297
5100
  element.style.overflow = `scroll`;
@@ -5343,11 +5146,11 @@ const createViewportNavigator = ({
5343
5146
  return { ...event, lastUserExpectedNavigation };
5344
5147
  }),
5345
5148
  share(),
5346
- takeUntil$1(context.$.destroy$)
5149
+ takeUntil$1(context.destroy$)
5347
5150
  );
5348
5151
  const navigationWhichRequireManualAdjust$ = navigation$.pipe(
5349
5152
  filter(({ triggeredBy }) => {
5350
- if (triggeredBy === `scroll` || settings.getSettings().computedPageTurnMode === `scrollable` && triggeredBy === `adjust`) {
5153
+ if (triggeredBy === `scroll` || settings.settings.computedPageTurnMode === `scrollable` && triggeredBy === `adjust`) {
5351
5154
  return false;
5352
5155
  } else {
5353
5156
  return true;
@@ -5359,7 +5162,7 @@ const createViewportNavigator = ({
5359
5162
  navigationWhichRequireManualAdjust$
5360
5163
  ).pipe(
5361
5164
  map$1(({ animation, position }) => {
5362
- const shouldAnimate = !(!animation || animation === `turn` && settings.getSettings().computedPageTurnAnimation === `none`);
5165
+ const shouldAnimate = !(!animation || animation === `turn` && settings.settings.computedPageTurnAnimation === `none`);
5363
5166
  return {
5364
5167
  type: `manualAdjust`,
5365
5168
  shouldAnimate,
@@ -5381,8 +5184,8 @@ const createViewportNavigator = ({
5381
5184
  switchMap$1(([, currentEvent]) => {
5382
5185
  if ((currentEvent == null ? void 0 : currentEvent.type) !== `manualAdjust`)
5383
5186
  return EMPTY;
5384
- const animationDuration = currentEvent.animation === `snap` ? settings.getSettings().computedSnapAnimationDuration : settings.getSettings().computedPageTurnAnimationDuration;
5385
- const pageTurnAnimation = currentEvent.animation === `snap` ? `slide` : settings.getSettings().computedPageTurnAnimation;
5187
+ const animationDuration = currentEvent.animation === `snap` ? settings.settings.computedSnapAnimationDuration : settings.settings.computedPageTurnAnimationDuration;
5188
+ const pageTurnAnimation = currentEvent.animation === `snap` ? `slide` : settings.settings.computedPageTurnAnimation;
5386
5189
  return of(currentEvent).pipe(
5387
5190
  /**
5388
5191
  * @important
@@ -5416,23 +5219,22 @@ const createViewportNavigator = ({
5416
5219
  * need to adjust to anchor to the payload position. This is because we use viewport computed position,
5417
5220
  * not the value set by `setProperty`
5418
5221
  */
5419
- withLatestFrom(hooks$),
5420
- tap(([data, hooks]) => {
5222
+ tap((data) => {
5421
5223
  if (pageTurnAnimation !== `fade`) {
5422
- adjustReadingOffset(data.position, hooks);
5224
+ adjustReadingOffset(data.position);
5423
5225
  }
5424
5226
  }),
5425
5227
  currentEvent.shouldAnimate ? delay(animationDuration / 2, animationFrameScheduler) : identity,
5426
- tap(([data, hooks]) => {
5228
+ tap((data) => {
5427
5229
  if (pageTurnAnimation === `fade`) {
5428
- adjustReadingOffset(data.position, hooks);
5230
+ adjustReadingOffset(data.position);
5429
5231
  element$.getValue().style.setProperty(`opacity`, `1`);
5430
5232
  }
5431
5233
  }),
5432
5234
  currentEvent.shouldAnimate ? delay(animationDuration / 2, animationFrameScheduler) : identity,
5433
- tap(([data, hooks]) => {
5235
+ tap((data) => {
5434
5236
  if (pageTurnAnimation === `fade`) {
5435
- adjustReadingOffset(data.position, hooks);
5237
+ adjustReadingOffset(data.position);
5436
5238
  }
5437
5239
  }),
5438
5240
  takeUntil$1(
@@ -5444,7 +5246,7 @@ const createViewportNavigator = ({
5444
5246
  );
5445
5247
  }),
5446
5248
  share(),
5447
- takeUntil$1(context.$.destroy$)
5249
+ takeUntil$1(context.destroy$)
5448
5250
  );
5449
5251
  const adjustmentState$ = merge(
5450
5252
  merge(manualAdjust$).pipe(map$1(() => `start`)),
@@ -5499,7 +5301,7 @@ const createViewportNavigator = ({
5499
5301
  share()
5500
5302
  );
5501
5303
  const parentElementSub = parentElement$.pipe(filter(isDefined), withLatestFrom(spine.element$)).subscribe(([parentElement, spineElement]) => {
5502
- const element = createElement(parentElement.ownerDocument, hooks$);
5304
+ const element = createElement(parentElement.ownerDocument, hookManager);
5503
5305
  element.appendChild(spineElement);
5504
5306
  parentElement.appendChild(element);
5505
5307
  element$.next(element);
@@ -5535,19 +5337,15 @@ const createViewportNavigator = ({
5535
5337
  }
5536
5338
  };
5537
5339
  };
5538
- const createElement = (doc, hooks$) => {
5340
+ const createElement = (doc, hookManager) => {
5539
5341
  const element = doc.createElement(`div`);
5540
5342
  element.style.cssText = `
5541
5343
  height: 100%;
5542
5344
  position: relative;
5543
5345
  `;
5544
5346
  element.className = `${HTML_PREFIX$1}-viewport-navigator`;
5545
- return hooks$.getValue().reduce((element2, hook) => {
5546
- if (hook.name === `viewportNavigator.onBeforeContainerCreated`) {
5547
- return hook.fn(element2);
5548
- }
5549
- return element2;
5550
- }, element);
5347
+ hookManager.execute("viewportNavigator.onBeforeContainerCreated", void 0, { element });
5348
+ return element;
5551
5349
  };
5552
5350
  const createLocationResolver = ({
5553
5351
  spineItemManager,
@@ -5588,7 +5386,7 @@ const createLocationResolver = ({
5588
5386
  const spineItem = spineItemManager.getAll().find((item) => {
5589
5387
  const { left, right, bottom, top } = spineItemManager.getAbsolutePositionOf(item);
5590
5388
  const isWithinXAxis = position.x >= left && position.x < right;
5591
- if (settings.getSettings().computedPageTurnDirection === `horizontal`) {
5389
+ if (settings.settings.computedPageTurnDirection === `horizontal`) {
5592
5390
  return isWithinXAxis;
5593
5391
  } else {
5594
5392
  return isWithinXAxis && position.y >= top && position.y < bottom;
@@ -5615,7 +5413,7 @@ const createLocationResolver = ({
5615
5413
  if (itemAtPositionIndex === void 0)
5616
5414
  return void 0;
5617
5415
  let endPosition = position;
5618
- if (context.isUsingSpreadMode()) {
5416
+ if (context.state.isUsingSpreadMode) {
5619
5417
  endPosition = { x: position.x + context.getPageSize().width, y: position.y };
5620
5418
  }
5621
5419
  const endItemIndex = spineItemManager.getSpineItemIndex(getSpineItemFromPosition(endPosition) || spineItemManager.getFocusedSpineItem()) ?? itemAtPositionIndex;
@@ -5736,80 +5534,170 @@ const createCfiLocator = ({
5736
5534
  generateFromRange
5737
5535
  };
5738
5536
  };
5739
- const areAllItemsPrePaginated = (manifest) => !(manifest == null ? void 0 : manifest.spineItems.some((item) => item.renditionLayout === `reflowable`));
5740
- const createSettings = (initialSettings) => {
5741
- const mergedSettings = {
5742
- forceSinglePageMode: false,
5743
- pageTurnAnimation: `none`,
5744
- computedPageTurnAnimation: `none`,
5745
- pageTurnDirection: `horizontal`,
5746
- computedPageTurnDirection: `horizontal`,
5747
- pageTurnAnimationDuration: void 0,
5748
- computedPageTurnAnimationDuration: 0,
5749
- pageTurnMode: `controlled`,
5537
+ const getComputedSettings = (settings, context) => {
5538
+ const manifest = context.manifest;
5539
+ const hasVerticalWriting = context.state.hasVerticalWriting ?? false;
5540
+ const computedSettings = {
5541
+ computedPageTurnDirection: settings.pageTurnDirection,
5542
+ computedPageTurnAnimation: settings.pageTurnAnimation,
5750
5543
  computedPageTurnMode: `controlled`,
5751
- computedSnapAnimationDuration: 300,
5752
- navigationSnapThreshold: 0.3,
5753
- numberOfAdjacentSpineItemToPreLoad: 0,
5754
- ...initialSettings
5755
- };
5756
- updateComputedSettings(void 0, mergedSettings, false);
5757
- const settingsSubject$ = new BehaviorSubject(mergedSettings);
5758
- const setSettings = (newSettings, options) => {
5759
- if (Object.keys(newSettings).length === 0)
5760
- return;
5761
- const newMergedSettings = { ...settingsSubject$.value, ...newSettings };
5762
- updateComputedSettings(options.manifest, newMergedSettings, options.hasVerticalWriting ?? false);
5763
- settingsSubject$.next(newMergedSettings);
5764
- };
5765
- const recompute = (options) => {
5766
- const newMergedSettings = { ...settingsSubject$.value };
5767
- updateComputedSettings(options.manifest, newMergedSettings, options.hasVerticalWriting ?? false);
5768
- settingsSubject$.next(newMergedSettings);
5769
- };
5770
- const destroy = () => {
5771
- settingsSubject$.complete();
5772
- };
5773
- return {
5774
- getSettings: () => settingsSubject$.value,
5775
- setSettings,
5776
- recompute,
5777
- destroy,
5778
- $: {
5779
- settings$: settingsSubject$.asObservable().pipe(distinctUntilChanged(isShallowEqual))
5780
- }
5544
+ computedPageTurnAnimationDuration: 0,
5545
+ computedSnapAnimationDuration: 0
5781
5546
  };
5782
- };
5783
- const updateComputedSettings = (newManifest, settings, hasVerticalWriting) => {
5784
- settings.computedPageTurnDirection = settings.pageTurnDirection;
5785
- settings.computedPageTurnAnimation = settings.pageTurnAnimation;
5786
- settings.computedPageTurnMode = `controlled`;
5787
- if ((newManifest == null ? void 0 : newManifest.renditionFlow) === `scrolled-continuous`) {
5788
- settings.computedPageTurnMode = `scrollable`;
5789
- settings.computedPageTurnDirection = `vertical`;
5790
- } else if (newManifest && settings.pageTurnMode === `scrollable` && (newManifest.renditionLayout !== `pre-paginated` || !areAllItemsPrePaginated(newManifest))) {
5547
+ if ((manifest == null ? void 0 : manifest.renditionFlow) === `scrolled-continuous`) {
5548
+ computedSettings.computedPageTurnMode = `scrollable`;
5549
+ computedSettings.computedPageTurnDirection = `vertical`;
5550
+ } else if (manifest && settings.pageTurnMode === `scrollable` && (manifest.renditionLayout !== `pre-paginated` || !areAllItemsPrePaginated(manifest))) {
5791
5551
  Report.warn(`pageTurnMode ${settings.pageTurnMode} incompatible with current book, switching back to default`);
5792
- settings.computedPageTurnAnimation = `none`;
5793
- settings.computedPageTurnMode = `controlled`;
5552
+ computedSettings.computedPageTurnAnimation = `none`;
5553
+ computedSettings.computedPageTurnMode = `controlled`;
5794
5554
  } else if (settings.pageTurnMode === `scrollable`) {
5795
- settings.computedPageTurnMode = `scrollable`;
5796
- settings.computedPageTurnDirection = `vertical`;
5555
+ computedSettings.computedPageTurnMode = `scrollable`;
5556
+ computedSettings.computedPageTurnDirection = `vertical`;
5797
5557
  }
5798
- if (hasVerticalWriting && settings.computedPageTurnAnimation === `slide`) {
5558
+ if (hasVerticalWriting && computedSettings.computedPageTurnAnimation === `slide`) {
5799
5559
  Report.warn(
5800
- `pageTurnAnimation ${settings.computedPageTurnAnimation} incompatible with current book, switching back to default`
5560
+ `pageTurnAnimation ${computedSettings.computedPageTurnAnimation} incompatible with current book, switching back to default`
5801
5561
  );
5802
- settings.computedPageTurnAnimation = `none`;
5562
+ computedSettings.computedPageTurnAnimation = `none`;
5803
5563
  }
5804
- if (settings.computedPageTurnMode === `scrollable`) {
5805
- settings.computedPageTurnAnimationDuration = 0;
5806
- settings.computedPageTurnAnimation = `none`;
5564
+ if (computedSettings.computedPageTurnMode === `scrollable`) {
5565
+ computedSettings.computedPageTurnAnimationDuration = 0;
5566
+ computedSettings.computedPageTurnAnimation = `none`;
5807
5567
  } else {
5808
- settings.computedPageTurnAnimationDuration = settings.pageTurnAnimationDuration !== void 0 ? settings.pageTurnAnimationDuration : 300;
5568
+ computedSettings.computedPageTurnAnimationDuration = settings.pageTurnAnimationDuration !== void 0 ? settings.pageTurnAnimationDuration : 300;
5809
5569
  }
5570
+ return computedSettings;
5810
5571
  };
5811
- const IFRAME_EVENT_BRIDGE_ELEMENT_ID = `proseReaderIframeEventBridgeElement`;
5812
- const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5572
+ const defaultSettings = {
5573
+ forceSinglePageMode: false,
5574
+ pageTurnAnimation: `none`,
5575
+ // computedPageTurnAnimation: `none`,
5576
+ pageTurnDirection: `horizontal`,
5577
+ // computedPageTurnDirection: `horizontal`,
5578
+ pageTurnAnimationDuration: void 0,
5579
+ // computedPageTurnAnimationDuration: 0,
5580
+ pageTurnMode: `controlled`,
5581
+ // computedPageTurnMode: `controlled`,
5582
+ // computedSnapAnimationDuration: 300,
5583
+ navigationSnapThreshold: 0.3,
5584
+ numberOfAdjacentSpineItemToPreLoad: 0
5585
+ };
5586
+ class SettingsManager {
5587
+ constructor(initialSettings, context) {
5588
+ this._context = context;
5589
+ const settingsWithDefaults = {
5590
+ ...defaultSettings,
5591
+ ...initialSettings
5592
+ };
5593
+ const computedSettings = getComputedSettings(settingsWithDefaults, context);
5594
+ const settings = { ...settingsWithDefaults, ...computedSettings };
5595
+ this._settingsSubject$ = new BehaviorSubject(settings);
5596
+ this.settings$ = this._settingsSubject$.asObservable().pipe(distinctUntilChanged(isShallowEqual));
5597
+ const recomputeSettingsOnContextChange$ = combineLatest([context.hasVerticalWriting$, context.manifest$]).pipe(
5598
+ tap(() => {
5599
+ this._updateSettings(this.settings);
5600
+ })
5601
+ );
5602
+ const updateContextOnSettingsChanges$ = this._settingsSubject$.pipe(
5603
+ tap(({ forceSinglePageMode }) => {
5604
+ context.update({ forceSinglePageMode });
5605
+ })
5606
+ );
5607
+ merge(recomputeSettingsOnContextChange$, updateContextOnSettingsChanges$).pipe(takeUntil$1(context.destroy$)).subscribe();
5608
+ }
5609
+ // @see https://github.com/microsoft/TypeScript/issues/17293
5610
+ _updateSettings(settings) {
5611
+ const computed = getComputedSettings(settings, this._context);
5612
+ const newMergedSettings = { ...settings, ...computed };
5613
+ this._settingsSubject$.next(newMergedSettings);
5614
+ }
5615
+ setSettings(settings) {
5616
+ if (Object.keys(settings).length === 0)
5617
+ return;
5618
+ const newMergedSettings = { ...this._settingsSubject$.value, ...settings };
5619
+ this._updateSettings(newMergedSettings);
5620
+ }
5621
+ get settings() {
5622
+ return this._settingsSubject$.getValue();
5623
+ }
5624
+ destroy() {
5625
+ this._settingsSubject$.complete();
5626
+ }
5627
+ }
5628
+ class HookManager {
5629
+ constructor() {
5630
+ this._hooks = [];
5631
+ this._hookExecutions = [];
5632
+ }
5633
+ /**
5634
+ * Will:
5635
+ * - call destroy function for every execution of this specific hook
5636
+ * - remove the hook for further calls
5637
+ */
5638
+ _deregister(hookToDeregister) {
5639
+ this._hooks = this._hooks.filter((hook) => hook !== hookToDeregister);
5640
+ return this.destroy(hookToDeregister.name, void 0, hookToDeregister);
5641
+ }
5642
+ /**
5643
+ * Ideal when your logic only needs to apply something to the item when it's loaded.
5644
+ * You can manipulate your item later if you need to update it and trigger a layout.
5645
+ * This logic will not run every time there is a layout.
5646
+ */
5647
+ register(name, fn) {
5648
+ const hook = {
5649
+ name,
5650
+ runFn: (params) => {
5651
+ const returnValue = fn(params);
5652
+ if (!returnValue)
5653
+ return of(void 0);
5654
+ return returnValue;
5655
+ }
5656
+ };
5657
+ this._hooks.push(hook);
5658
+ return () => {
5659
+ this._deregister(hook);
5660
+ };
5661
+ }
5662
+ execute(name, id, params) {
5663
+ const hooks = this._hooks.filter((hook) => name === hook.name);
5664
+ const runFns = hooks.map((hook) => {
5665
+ let userDestroyFn = () => of(void 0);
5666
+ const destroySubject = new Subject();
5667
+ const destroy = (fn) => {
5668
+ userDestroyFn = fn;
5669
+ };
5670
+ const destroyFn = () => {
5671
+ destroySubject.next();
5672
+ destroySubject.complete();
5673
+ const result = userDestroyFn();
5674
+ return result ?? of(void 0);
5675
+ };
5676
+ const execution = hook.runFn({ ...params, destroy$: destroySubject.asObservable(), destroy });
5677
+ this._hookExecutions.push({
5678
+ name,
5679
+ id,
5680
+ destroyFn,
5681
+ ref: hook
5682
+ });
5683
+ return execution;
5684
+ });
5685
+ return combineLatest(runFns);
5686
+ }
5687
+ destroy(name, id, ref) {
5688
+ const instances = this._hookExecutions.filter(
5689
+ (hookInstance) => (
5690
+ // by ref is higher priority
5691
+ ref && hookInstance.ref === ref || // otherwise we refine by name and eventually by id
5692
+ name === hookInstance.name && (!id || id && id === hookInstance.id)
5693
+ )
5694
+ );
5695
+ this._hookExecutions = this._hookExecutions.filter((instance) => !instances.includes(instance));
5696
+ const destroyFns = instances.map(({ destroyFn }) => destroyFn());
5697
+ return combineLatest(destroyFns);
5698
+ }
5699
+ }
5700
+ const createReader = (inputSettings) => {
5813
5701
  const stateSubject$ = new BehaviorSubject({
5814
5702
  supportedPageTurnAnimation: [`fade`, `none`, `slide`],
5815
5703
  supportedPageTurnMode: [`controlled`, `scrollable`],
@@ -5818,24 +5706,23 @@ const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5818
5706
  });
5819
5707
  const destroy$ = new Subject();
5820
5708
  const selectionSubject$ = new Subject();
5821
- const hooksSubject$ = new BehaviorSubject(initialHooks || []);
5822
5709
  const navigationSubject = new Subject();
5823
5710
  const navigationAdjustedSubject = new Subject();
5824
5711
  const currentNavigationPositionSubject$ = new BehaviorSubject({ x: 0, y: 0 });
5825
5712
  const viewportStateSubject = new BehaviorSubject(`free`);
5826
- const settings = createSettings(inputSettings);
5827
- const context = createContext(settings);
5828
- const spineItemManager = createSpineItemManager({ context, settings });
5713
+ const hookManager = new HookManager();
5714
+ const context = new Context();
5715
+ const settingsManager = new SettingsManager(inputSettings, context);
5716
+ const spineItemManager = createSpineItemManager({ context, settings: settingsManager });
5829
5717
  const pagination = createPagination({ context, spineItemManager });
5830
5718
  const elementSubject$ = new BehaviorSubject(void 0);
5831
5719
  const element$ = elementSubject$.pipe(filter(isDefined));
5832
- const iframeEventBridgeElement$ = new BehaviorSubject(void 0);
5833
5720
  const spineItemLocator = createLocationResolver$1({ context });
5834
5721
  const spineLocator = createLocationResolver({
5835
5722
  context,
5836
5723
  spineItemManager,
5837
5724
  spineItemLocator,
5838
- settings
5725
+ settings: settingsManager
5839
5726
  });
5840
5727
  const cfiLocator = createCfiLocator({
5841
5728
  spineItemManager,
@@ -5845,19 +5732,18 @@ const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5845
5732
  const navigation$ = navigationSubject.asObservable();
5846
5733
  const spine = createSpine({
5847
5734
  element$,
5848
- iframeEventBridgeElement$,
5849
5735
  context,
5850
- settings,
5736
+ settings: settingsManager,
5851
5737
  pagination,
5852
5738
  spineItemManager,
5853
- hooks$: hooksSubject$,
5854
5739
  navigation$,
5855
5740
  spineLocator,
5856
5741
  spineItemLocator,
5857
5742
  cfiLocator,
5858
5743
  navigationAdjusted$: navigationAdjustedSubject.asObservable(),
5859
5744
  viewportState$: viewportStateSubject.asObservable(),
5860
- currentNavigationPosition$: currentNavigationPositionSubject$.asObservable()
5745
+ currentNavigationPosition$: currentNavigationPositionSubject$.asObservable(),
5746
+ hookManager
5861
5747
  });
5862
5748
  const viewportNavigator = createViewportNavigator({
5863
5749
  context,
@@ -5866,9 +5752,9 @@ const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5866
5752
  parentElement$: elementSubject$,
5867
5753
  cfiLocator,
5868
5754
  spineLocator,
5869
- hooks$: hooksSubject$,
5755
+ hookManager,
5870
5756
  spine,
5871
- settings
5757
+ settings: settingsManager
5872
5758
  });
5873
5759
  viewportNavigator.$.state$.subscribe(viewportStateSubject);
5874
5760
  viewportNavigator.$.navigation$.subscribe(navigationSubject);
@@ -5894,30 +5780,29 @@ const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5894
5780
  element.style.height = `${dimensions.height - marginTop - marginBottom}px`;
5895
5781
  element.style.width = `${containerElementEvenWidth - 2 * margin}px`;
5896
5782
  const elementRect = element.getBoundingClientRect();
5897
- context.setVisibleAreaRect({
5898
- x: elementRect.x,
5899
- y: elementRect.y,
5900
- width: containerElementEvenWidth,
5901
- height: dimensions.height
5783
+ context.update({
5784
+ visibleAreaRect: {
5785
+ x: elementRect.x,
5786
+ y: elementRect.y,
5787
+ width: containerElementEvenWidth,
5788
+ height: dimensions.height
5789
+ }
5902
5790
  });
5903
5791
  viewportNavigator.layout();
5904
5792
  };
5905
5793
  const load = (manifest, loadOptions) => {
5906
5794
  var _a;
5907
- if (context.getManifest()) {
5795
+ if (context.manifest) {
5908
5796
  Report.warn(`loading a new book is not supported yet`);
5909
5797
  return;
5910
5798
  }
5911
5799
  Report.log(`load`, { manifest, loadOptions });
5912
5800
  const element = createWrapperElement(loadOptions.containerElement);
5913
- const iframeEventBridgeElement = createIframeEventBridgeElement(loadOptions.containerElement);
5914
5801
  if (loadOptions.containerElement !== ((_a = elementSubject$.getValue()) == null ? void 0 : _a.parentElement)) {
5915
5802
  elementSubject$.next(element);
5916
- iframeEventBridgeElement$.next(iframeEventBridgeElement);
5917
5803
  loadOptions.containerElement.appendChild(element);
5918
- element.appendChild(iframeEventBridgeElement);
5919
5804
  }
5920
- context.load(manifest, loadOptions);
5805
+ context.update({ manifest, ...loadOptions, forceSinglePageMode: settingsManager.settings.forceSinglePageMode });
5921
5806
  layout();
5922
5807
  if (!loadOptions.cfi) {
5923
5808
  viewportNavigator.goToSpineItem(0, { animate: false });
@@ -5925,9 +5810,6 @@ const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5925
5810
  viewportNavigator.goToCfi(loadOptions.cfi, { animate: false });
5926
5811
  }
5927
5812
  };
5928
- const registerHook = (name, fn) => {
5929
- hooksSubject$.next([...hooksSubject$.getValue(), { name, fn }]);
5930
- };
5931
5813
  spine.$.$.pipe(
5932
5814
  tap((event) => {
5933
5815
  if (event.type === `onSelectionChange`) {
@@ -5940,18 +5822,18 @@ const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5940
5822
  switchMap(({ adjustedSpinePosition }) => {
5941
5823
  return spine.adjustPagination(adjustedSpinePosition).pipe(takeUntil$1(navigation$));
5942
5824
  }),
5943
- takeUntil$1(context.$.destroy$)
5825
+ takeUntil$1(context.destroy$)
5944
5826
  ).subscribe();
5945
- merge(context.$.state$, settings.$.settings$).pipe(
5827
+ merge(context.state$, settingsManager.settings$).pipe(
5946
5828
  map$1(() => void 0),
5947
- withLatestFrom(context.$.state$),
5829
+ withLatestFrom(context.state$),
5948
5830
  map$1(([, { hasVerticalWriting }]) => {
5949
- const manifest = context.getManifest();
5831
+ const manifest = context.manifest;
5950
5832
  return {
5951
5833
  hasVerticalWriting,
5952
5834
  renditionFlow: manifest == null ? void 0 : manifest.renditionFlow,
5953
5835
  renditionLayout: manifest == null ? void 0 : manifest.renditionLayout,
5954
- computedPageTurnMode: settings.getSettings().computedPageTurnMode
5836
+ computedPageTurnMode: settingsManager.settings.computedPageTurnMode
5955
5837
  };
5956
5838
  }),
5957
5839
  distinctUntilChanged(isShallowEqual),
@@ -5959,7 +5841,7 @@ const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5959
5841
  ({ hasVerticalWriting, renditionFlow, renditionLayout, computedPageTurnMode }) => {
5960
5842
  return {
5961
5843
  ...stateSubject$.value,
5962
- supportedPageTurnMode: renditionFlow === `scrolled-continuous` ? [`scrollable`] : !context.areAllItemsPrePaginated() ? [`controlled`] : [`controlled`, `scrollable`],
5844
+ supportedPageTurnMode: renditionFlow === `scrolled-continuous` ? [`scrollable`] : !context.state.areAllItemsPrePaginated ? [`controlled`] : [`controlled`, `scrollable`],
5963
5845
  supportedPageTurnAnimation: renditionFlow === `scrolled-continuous` || computedPageTurnMode === `scrollable` ? [`none`] : hasVerticalWriting ? [`fade`, `none`] : [`fade`, `none`, `slide`],
5964
5846
  supportedPageTurnDirection: computedPageTurnMode === `scrollable` ? [`vertical`] : renditionLayout === `reflowable` ? [`horizontal`] : [`horizontal`, `vertical`]
5965
5847
  };
@@ -5968,16 +5850,13 @@ const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5968
5850
  takeUntil$1(destroy$)
5969
5851
  ).subscribe(stateSubject$);
5970
5852
  const destroy = () => {
5971
- var _a, _b;
5972
- settings.destroy();
5973
- hooksSubject$.next([]);
5974
- hooksSubject$.complete();
5853
+ var _a;
5854
+ settingsManager.destroy();
5975
5855
  pagination.destroy();
5976
5856
  context.destroy();
5977
5857
  viewportNavigator.destroy();
5978
5858
  spine.destroy();
5979
5859
  (_a = elementSubject$.getValue()) == null ? void 0 : _a.remove();
5980
- (_b = iframeEventBridgeElement$.getValue()) == null ? void 0 : _b.remove();
5981
5860
  stateSubject$.complete();
5982
5861
  selectionSubject$.complete();
5983
5862
  destroy$.next();
@@ -5985,43 +5864,16 @@ const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
5985
5864
  };
5986
5865
  const reader = {
5987
5866
  context,
5988
- registerHook,
5989
5867
  spine,
5868
+ hookManager,
5990
5869
  viewportNavigator,
5991
- manipulateSpineItems: spine.manipulateSpineItems,
5992
- manipulateSpineItem: spine.manipulateSpineItem,
5993
- moveTo: viewportNavigator.moveTo,
5994
- turnLeft: viewportNavigator.turnLeft,
5995
- turnRight: viewportNavigator.turnRight,
5996
- goToPageOfCurrentChapter: viewportNavigator.goToPageOfCurrentChapter,
5997
- goToPage: viewportNavigator.goToPage,
5998
- goToUrl: viewportNavigator.goToUrl,
5999
- goToCfi: viewportNavigator.goToCfi,
6000
- goToSpineItem: viewportNavigator.goToSpineItem,
6001
- getFocusedSpineItemIndex: spineItemManager.getFocusedSpineItemIndex,
6002
- getSpineItem: spineItemManager.get,
6003
- getSpineItems: spineItemManager.getAll,
6004
- getAbsolutePositionOf: spineItemManager.getAbsolutePositionOf,
6005
- getSelection: spine.getSelection,
6006
- isSelecting: spine.isSelecting,
6007
- normalizeEventForViewport: spine.normalizeEventForViewport,
6008
- getCfiMetaInformation: spine.cfiLocator.getCfiMetaInformation,
6009
- resolveCfi: spine.cfiLocator.resolveCfi,
6010
- generateCfi: spine.cfiLocator.generateFromRange,
6011
- locator: spine.locator,
6012
- getCurrentNavigationPosition: viewportNavigator.getCurrentNavigationPosition,
6013
- getCurrentViewportPosition: viewportNavigator.getCurrentViewportPosition,
5870
+ spineItemManager,
6014
5871
  layout,
6015
5872
  load,
6016
5873
  destroy,
6017
- spineItems$: spine.$.spineItems$,
6018
- context$: context.$.state$,
6019
5874
  pagination,
6020
- settings: {
6021
- settings$: settings.$.settings$,
6022
- getSettings: settings.getSettings,
6023
- setSettings: (data) => settings.setSettings(data, context.getState())
6024
- },
5875
+ settings: settingsManager,
5876
+ element$,
6025
5877
  $: {
6026
5878
  state$: stateSubject$.asObservable(),
6027
5879
  /**
@@ -6030,21 +5882,12 @@ const createReader = ({ hooks: initialHooks, ...inputSettings }) => {
6030
5882
  * have an effect.
6031
5883
  * It can typically be used to hide a loading indicator.
6032
5884
  */
6033
- loadStatus$: context.$.manifest$.pipe(map$1((manifest) => manifest ? "ready" : "idle")),
5885
+ loadStatus$: context.manifest$.pipe(map$1((manifest) => manifest ? "ready" : "idle")),
6034
5886
  /**
6035
5887
  * Dispatched when a change in selection happens
6036
5888
  */
6037
5889
  selection$: selectionSubject$.asObservable(),
6038
- viewportState$: viewportNavigator.$.state$,
6039
- layout$: spine.$.layout$,
6040
- itemsBeforeDestroy$: spine.$.itemsBeforeDestroy$,
6041
- itemIsReady$: spineItemManager.$.itemIsReady$,
6042
5890
  destroy$
6043
- },
6044
- __debug: {
6045
- pagination,
6046
- context,
6047
- spineItemManager
6048
5891
  }
6049
5892
  };
6050
5893
  return reader;
@@ -6058,19 +5901,6 @@ const createWrapperElement = (containerElement) => {
6058
5901
  element.className = `${HTML_PREFIX$1}-reader`;
6059
5902
  return element;
6060
5903
  };
6061
- const createIframeEventBridgeElement = (containerElement) => {
6062
- const iframeEventBridgeElement = containerElement.ownerDocument.createElement(`div`);
6063
- iframeEventBridgeElement.id = IFRAME_EVENT_BRIDGE_ELEMENT_ID;
6064
- iframeEventBridgeElement.style.cssText = `
6065
- position: absolute;
6066
- height: 100%;
6067
- width: 100%;
6068
- top: 0;
6069
- left: 0;
6070
- z-index: -1;
6071
- `;
6072
- return iframeEventBridgeElement;
6073
- };
6074
5904
  const utilsEnhancer = (next) => (options) => {
6075
5905
  const reader = next(options);
6076
5906
  const isOrIsWithinValidLink = (target) => {
@@ -6195,9 +6025,9 @@ const createResourcesManager = (context) => {
6195
6025
  var _a, _b;
6196
6026
  if (typeof itemIndexOrId === `string` || typeof itemIndexOrId === `object`) {
6197
6027
  const id = typeof itemIndexOrId === `object` ? itemIndexOrId.id : void 0;
6198
- return (_a = context.getManifest()) == null ? void 0 : _a.spineItems.find((entry) => entry.id === id);
6028
+ return (_a = context.manifest) == null ? void 0 : _a.spineItems.find((entry) => entry.id === id);
6199
6029
  } else {
6200
- return (_b = context.getManifest()) == null ? void 0 : _b.spineItems[itemIndexOrId];
6030
+ return (_b = context.manifest) == null ? void 0 : _b.spineItems[itemIndexOrId];
6201
6031
  }
6202
6032
  };
6203
6033
  const get = async (itemIndexOrId, fetchResource) => {
@@ -6231,9 +6061,9 @@ const createResourcesManager = (context) => {
6231
6061
  })
6232
6062
  );
6233
6063
  }),
6234
- takeUntil$1(context.$.destroy$)
6064
+ takeUntil$1(context.destroy$)
6235
6065
  ).subscribe();
6236
- const onLoad$ = context.$.manifest$.pipe(
6066
+ const onLoad$ = context.manifest$.pipe(
6237
6067
  tap(() => {
6238
6068
  uniqueID = Date.now().toString();
6239
6069
  })
@@ -6257,7 +6087,7 @@ const createResourcesManager = (context) => {
6257
6087
  })
6258
6088
  );
6259
6089
  }),
6260
- takeUntil$1(context.$.destroy$)
6090
+ takeUntil$1(context.destroy$)
6261
6091
  ).subscribe();
6262
6092
  const destroy = () => {
6263
6093
  cache$.complete();
@@ -6270,14 +6100,6 @@ const createResourcesManager = (context) => {
6270
6100
  const resourcesEnhancer = (next) => (options) => {
6271
6101
  const reader = next(options);
6272
6102
  const resourceManager = createResourcesManager(reader.context);
6273
- const load = (manifest, loadOptions) => {
6274
- reader.load(manifest, {
6275
- ...loadOptions
6276
- });
6277
- };
6278
- reader.registerHook(`item.onGetResource`, (fetcher) => async (item) => {
6279
- return resourceManager.get(item, fetcher);
6280
- });
6281
6103
  const destroy = () => {
6282
6104
  resourceManager.destroy();
6283
6105
  reader.destroy();
@@ -6288,8 +6110,8 @@ const resourcesEnhancer = (next) => (options) => {
6288
6110
  // ...reader.$,
6289
6111
  // errors$: merge(reader.$.errors$, errorsSubject$.asObservable())
6290
6112
  // },
6291
- destroy,
6292
- load
6113
+ destroy
6114
+ // load,
6293
6115
  };
6294
6116
  };
6295
6117
  const mediaEnhancer = (next) => (options) => {
@@ -6340,7 +6162,7 @@ const mediaEnhancer = (next) => (options) => {
6340
6162
  threshold: 0.5
6341
6163
  }
6342
6164
  );
6343
- reader.registerHook(`item.onLoad`, ({ frame }) => {
6165
+ reader.hookManager.register(`item.onLoad`, ({ frame, destroy: destroy2 }) => {
6344
6166
  var _a;
6345
6167
  frameObserver.observe(frame);
6346
6168
  const videos = (_a = frame.contentDocument) == null ? void 0 : _a.body.getElementsByTagName(`video`);
@@ -6348,10 +6170,10 @@ const mediaEnhancer = (next) => (options) => {
6348
6170
  elementObserver.observe(element);
6349
6171
  return () => elementObserver.unobserve(element);
6350
6172
  });
6351
- return () => {
6173
+ destroy2(() => {
6352
6174
  frameObserver.unobserve(frame);
6353
6175
  unobserveElements.forEach((unobserve) => unobserve());
6354
- };
6176
+ });
6355
6177
  });
6356
6178
  const destroy = () => {
6357
6179
  frameObserver.disconnect();
@@ -6367,16 +6189,16 @@ const progressionEnhancer = (next) => (options) => {
6367
6189
  const reader = next(options);
6368
6190
  const getPercentageEstimate = (context, currentSpineIndex, numberOfPages, pageIndex, currentPosition, currentItem) => {
6369
6191
  var _a, _b, _c, _d, _e, _f;
6370
- const isGloballyPrePaginated = ((_a = context.getManifest()) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
6371
- const readingOrderLength = ((_b = context.getManifest()) == null ? void 0 : _b.spineItems.length) || 0;
6372
- const estimateBeforeThisItem = ((_c = context.getManifest()) == null ? void 0 : _c.spineItems.slice(0, currentSpineIndex).reduce((acc, item) => acc + item.progressionWeight, 0)) || 0;
6373
- const currentItemWeight = ((_e = (_d = context.getManifest()) == null ? void 0 : _d.spineItems[currentSpineIndex]) == null ? void 0 : _e.progressionWeight) || 0;
6192
+ const isGloballyPrePaginated = ((_a = context.manifest) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
6193
+ const readingOrderLength = ((_b = context.manifest) == null ? void 0 : _b.spineItems.length) || 0;
6194
+ const estimateBeforeThisItem = ((_c = context.manifest) == null ? void 0 : _c.spineItems.slice(0, currentSpineIndex).reduce((acc, item) => acc + item.progressionWeight, 0)) || 0;
6195
+ const currentItemWeight = ((_e = (_d = context.manifest) == null ? void 0 : _d.spineItems[currentSpineIndex]) == null ? void 0 : _e.progressionWeight) || 0;
6374
6196
  let progressWithinThisItem = (pageIndex + 1) * (currentItemWeight / numberOfPages);
6375
6197
  if (!isGloballyPrePaginated && currentItem.item.renditionLayout === `reflowable` && !currentItem.isReady()) {
6376
6198
  progressWithinThisItem = 0;
6377
6199
  }
6378
6200
  let totalProgress = estimateBeforeThisItem + progressWithinThisItem;
6379
- if (((_f = context.getManifest()) == null ? void 0 : _f.renditionFlow) === `scrolled-continuous`) {
6201
+ if (((_f = context.manifest) == null ? void 0 : _f.renditionFlow) === `scrolled-continuous`) {
6380
6202
  if (currentItem.isReady()) {
6381
6203
  progressWithinThisItem = getScrollPercentageWithinItem(context, currentPosition, currentItem);
6382
6204
  } else {
@@ -6394,11 +6216,11 @@ const progressionEnhancer = (next) => (options) => {
6394
6216
  };
6395
6217
  const getScrollPercentageWithinItem = (context, currentPosition, currentItem) => {
6396
6218
  const { height, width } = currentItem.getElementDimensions();
6397
- const { top, left } = reader.getAbsolutePositionOf(currentItem);
6398
- if (reader.settings.getSettings().computedPageTurnDirection === `vertical`) {
6399
- return Math.max(0, Math.min(1, (currentPosition.y - top + context.getVisibleAreaRect().height) / height));
6219
+ const { top, left } = reader.spineItemManager.getAbsolutePositionOf(currentItem);
6220
+ if (reader.settings.settings.computedPageTurnDirection === `vertical`) {
6221
+ return Math.max(0, Math.min(1, (currentPosition.y - top + context.state.visibleAreaRect.height) / height));
6400
6222
  } else {
6401
- return Math.max(0, Math.min(1, (currentPosition.x - left + context.getVisibleAreaRect().width) / width));
6223
+ return Math.max(0, Math.min(1, (currentPosition.x - left + context.state.visibleAreaRect.width) / width));
6402
6224
  }
6403
6225
  };
6404
6226
  return {
@@ -6420,67 +6242,59 @@ const accessibilityEnhancer = (next) => (options) => {
6420
6242
  }
6421
6243
  });
6422
6244
  }, {});
6423
- reader.registerHook(`item.onLoad`, ({ addStyle, frame }) => {
6245
+ reader.hookManager.register(`item.onLoad`, ({ itemId, frame, destroy }) => {
6424
6246
  var _a;
6425
- addStyle(
6426
- `prose-reader-accessibility`,
6247
+ const item = reader.spineItemManager.get(itemId);
6248
+ if (!item)
6249
+ return;
6250
+ item.manipulateSpineItem(({ addStyle }) => {
6251
+ addStyle(
6252
+ `prose-reader-accessibility`,
6253
+ `
6254
+ :focus-visible {
6255
+ ${/*
6256
+ Some epubs remove the outline, this is not good practice since it reduce accessibility.
6257
+ We will try to restore it by force.
6258
+ */
6259
+ ``}
6260
+ outline: -webkit-focus-ring-color auto 1px;
6261
+ }
6427
6262
  `
6428
- :focus-visible {
6429
- ${/*
6430
- Some epubs remove the outline, this is not good practice since it reduce accessibility.
6431
- We will try to restore it by force.
6432
- */
6433
- ``}
6434
- outline: -webkit-focus-ring-color auto 1px;
6435
- }
6436
- `
6437
- );
6263
+ );
6264
+ return false;
6265
+ });
6438
6266
  const links = (_a = frame.contentDocument) == null ? void 0 : _a.body.querySelectorAll(`a`);
6439
6267
  links == null ? void 0 : links.forEach((link) => {
6440
6268
  observer.observe(link);
6441
6269
  });
6442
- return () => {
6270
+ destroy(() => {
6443
6271
  links == null ? void 0 : links.forEach((link) => {
6444
6272
  observer.unobserve(link);
6445
6273
  });
6446
- };
6274
+ });
6447
6275
  });
6448
6276
  return {
6449
6277
  ...reader
6450
6278
  };
6451
6279
  };
6452
6280
  const IS_SAFARI = navigator.userAgent.indexOf(``) > -1 && navigator.userAgent.indexOf(`Chrome`) <= -1;
6453
- const webkitEnhancer = (next) => (options) => {
6454
- const transformFlickerFixHooks = [
6455
- {
6456
- name: `viewportNavigator.onBeforeContainerCreated`,
6457
- fn: (element) => {
6458
- element.style.cssText = `
6459
- ${element.style.cssText}
6460
- -webkit-transform-style: preserve-3d;
6461
- `;
6462
- return element;
6463
- }
6464
- },
6465
- {
6466
- name: `item.onBeforeContainerCreated`,
6467
- fn: (element) => {
6468
- element.style.cssText = `
6281
+ const webkitEnhancer = (createReader2) => (options) => {
6282
+ const reader = createReader2(options);
6283
+ if (IS_SAFARI) {
6284
+ reader.hookManager.register("viewportNavigator.onBeforeContainerCreated", ({ element }) => {
6285
+ element.style.cssText = `
6469
6286
  ${element.style.cssText}
6470
6287
  -webkit-transform-style: preserve-3d;
6471
- -webkit-backface-visibility: hidden;
6472
6288
  `;
6473
- return element;
6474
- }
6475
- }
6476
- ];
6477
- const existingHooks = options.hooks || [];
6478
- const reader = next({
6479
- ...options,
6480
- ...IS_SAFARI && {
6481
- hooks: [...existingHooks, ...transformFlickerFixHooks]
6482
- }
6483
- });
6289
+ });
6290
+ reader.hookManager.register("item.onBeforeContainerCreated", ({ element }) => {
6291
+ element.style.cssText = `
6292
+ ${element.style.cssText}
6293
+ -webkit-transform-style: preserve-3d;
6294
+ -webkit-backface-visibility: hidden;
6295
+ `;
6296
+ });
6297
+ }
6484
6298
  return reader;
6485
6299
  };
6486
6300
  const HTML_PREFIX = `${HTML_PREFIX$1}-enhancer-loading`;
@@ -6501,9 +6315,9 @@ const loadingEnhancer = (next) => (options) => {
6501
6315
  };
6502
6316
  }, {})
6503
6317
  );
6504
- const updateEntriesLayout$ = (entries) => combineLatest([reader.$.layout$, reader.theme.$.theme$]).pipe(
6318
+ const updateEntriesLayout$ = (entries) => combineLatest([reader.spine.$.layout$, reader.theme.$.theme$]).pipe(
6505
6319
  map$1(([, theme]) => ({
6506
- width: reader.context.getVisibleAreaRect().width,
6320
+ width: reader.context.state.visibleAreaRect.width,
6507
6321
  theme
6508
6322
  })),
6509
6323
  distinctUntilChanged(isShallowEqual),
@@ -6514,22 +6328,22 @@ const loadingEnhancer = (next) => (options) => {
6514
6328
  });
6515
6329
  })
6516
6330
  );
6517
- const updateEntriesVisibility$ = (entries) => reader.$.itemIsReady$.pipe(
6331
+ const updateEntriesVisibility$ = (entries) => reader.spineItemManager.$.itemIsReady$.pipe(
6518
6332
  tap(({ item, isReady }) => {
6519
6333
  var _a;
6520
6334
  (_a = entries[item.id]) == null ? void 0 : _a.style.setProperty(`visibility`, isReady ? `hidden` : `visible`);
6521
6335
  })
6522
6336
  );
6523
- const destroyEntries$ = (entries) => reader.$.itemsBeforeDestroy$.pipe(
6337
+ const destroyEntries$ = (entries) => reader.spine.$.itemsBeforeDestroy$.pipe(
6524
6338
  map$1(() => {
6525
6339
  Object.values(entries).forEach((element) => element.remove());
6526
6340
  return {};
6527
6341
  })
6528
6342
  );
6529
- const items$ = reader.spineItems$.pipe(
6343
+ const items$ = reader.spine.$.spineItems$.pipe(
6530
6344
  switchMap$1((items) => createEntries$(items)),
6531
6345
  shareReplay(1),
6532
- takeUntil$1(reader.context.$.destroy$)
6346
+ takeUntil$1(reader.context.destroy$)
6533
6347
  );
6534
6348
  items$.pipe(
6535
6349
  switchMap$1((entries) => merge(of(entries), destroyEntries$(entries))),
@@ -6551,7 +6365,7 @@ const createLoadingElementContainer = (containerElement, context) => {
6551
6365
  loadingElement.style.cssText = `
6552
6366
  height: 100%;
6553
6367
  width: 100%;
6554
- max-width: ${context.getVisibleAreaRect().width}px;
6368
+ max-width: ${context.state.visibleAreaRect.width}px;
6555
6369
  text-align: center;
6556
6370
  display: flex;
6557
6371
  justify-content: center;
@@ -6591,6 +6405,155 @@ const publicApiEnhancer = (next) => {
6591
6405
  return reader;
6592
6406
  };
6593
6407
  };
6408
+ const createNormalizeEventForViewport = ({
6409
+ iframeEventBridgeElement$,
6410
+ locator
6411
+ }) => {
6412
+ const normalizeEventForViewport = (event) => {
6413
+ var _a;
6414
+ const eventIsComingFromBridge = event.target === iframeEventBridgeElement$.getValue();
6415
+ const iframeOriginalEvent = getOriginalFrameEventFromDocumentEvent(event);
6416
+ const originalFrame = (_a = iframeOriginalEvent == null ? void 0 : iframeOriginalEvent.view) == null ? void 0 : _a.frameElement;
6417
+ if (!eventIsComingFromBridge || !iframeOriginalEvent || !originalFrame)
6418
+ return event;
6419
+ const spineItem = locator.getSpineItemFromIframe(originalFrame);
6420
+ if (!spineItem)
6421
+ return event;
6422
+ if (isPointerEvent(event)) {
6423
+ const { clientX, clientY } = spineItem.translateFramePositionIntoPage(event);
6424
+ const newEvent = new PointerEvent(event.type, {
6425
+ ...event,
6426
+ pointerId: event.pointerId,
6427
+ clientX,
6428
+ clientY
6429
+ });
6430
+ Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
6431
+ return newEvent;
6432
+ }
6433
+ if (isMouseEvent(event)) {
6434
+ const { clientX, clientY } = spineItem.translateFramePositionIntoPage(event);
6435
+ const newEvent = new MouseEvent(event.type, {
6436
+ ...event,
6437
+ clientX,
6438
+ clientY
6439
+ });
6440
+ Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
6441
+ return newEvent;
6442
+ }
6443
+ if (isTouchEvent(event)) {
6444
+ const touches = Array.from(event.touches).map((touch) => {
6445
+ const { clientX, clientY } = spineItem.translateFramePositionIntoPage(touch);
6446
+ return new Touch({
6447
+ identifier: touch.identifier,
6448
+ target: touch.target,
6449
+ clientX,
6450
+ clientY
6451
+ });
6452
+ });
6453
+ const newEvent = new TouchEvent(event.type, {
6454
+ touches,
6455
+ changedTouches: touches,
6456
+ targetTouches: touches
6457
+ });
6458
+ Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
6459
+ return newEvent;
6460
+ }
6461
+ return event;
6462
+ };
6463
+ return normalizeEventForViewport;
6464
+ };
6465
+ const IFRAME_EVENT_BRIDGE_ELEMENT_ID = `proseReaderIframeEventBridgeElement`;
6466
+ const createIframeEventBridgeElement = (container) => {
6467
+ const iframeEventBridgeElement = container.ownerDocument.createElement(`div`);
6468
+ iframeEventBridgeElement.id = IFRAME_EVENT_BRIDGE_ELEMENT_ID;
6469
+ iframeEventBridgeElement.style.cssText = `
6470
+ position: absolute;
6471
+ height: 100%;
6472
+ width: 100%;
6473
+ top: 0;
6474
+ left: 0;
6475
+ z-index: -1;
6476
+ `;
6477
+ return iframeEventBridgeElement;
6478
+ };
6479
+ const pointerEvents = [
6480
+ `pointercancel`,
6481
+ `pointerdown`,
6482
+ `pointerenter`,
6483
+ `pointerleave`,
6484
+ `pointermove`,
6485
+ `pointerout`,
6486
+ `pointerover`,
6487
+ `pointerup`,
6488
+ `touchstart`,
6489
+ `touchend`
6490
+ ];
6491
+ const mouseEvents = [
6492
+ `click`,
6493
+ `mousedown`,
6494
+ `mouseup`,
6495
+ `mouseenter`,
6496
+ `mouseleave`,
6497
+ `mousemove`,
6498
+ `mouseout`,
6499
+ `mouseover`
6500
+ ];
6501
+ const passthroughEvents = [...pointerEvents, ...mouseEvents];
6502
+ const eventsEnhancer = (next) => (options) => {
6503
+ const iframeEventBridgeElement$ = new BehaviorSubject(void 0);
6504
+ const reader = next(options);
6505
+ reader.hookManager.register(`item.onLoad`, ({ destroy, frame, itemId }) => {
6506
+ const item = reader.spineItemManager.get(itemId);
6507
+ if (!item)
6508
+ return;
6509
+ const unregister = passthroughEvents.map((event) => {
6510
+ var _a;
6511
+ const listener = (e) => {
6512
+ var _a2;
6513
+ let convertedEvent = e;
6514
+ if (isPointerEvent(e)) {
6515
+ convertedEvent = new PointerEvent(e.type, e);
6516
+ }
6517
+ if (isMouseEvent(e)) {
6518
+ convertedEvent = new MouseEvent(e.type, e);
6519
+ }
6520
+ if (convertedEvent !== e) {
6521
+ attachOriginalFrameEventToDocumentEvent(convertedEvent, e);
6522
+ (_a2 = iframeEventBridgeElement$.getValue()) == null ? void 0 : _a2.dispatchEvent(convertedEvent);
6523
+ }
6524
+ };
6525
+ (_a = frame.contentDocument) == null ? void 0 : _a.addEventListener(event, listener);
6526
+ return () => {
6527
+ var _a2;
6528
+ (_a2 = frame.contentDocument) == null ? void 0 : _a2.removeEventListener(event, listener);
6529
+ };
6530
+ });
6531
+ item.selectionTracker.track(frame);
6532
+ item.fingerTracker.track(frame);
6533
+ destroy(() => {
6534
+ unregister.forEach((cb) => cb());
6535
+ });
6536
+ });
6537
+ reader.element$.pipe(
6538
+ tap$1((wrapper) => {
6539
+ var _a;
6540
+ const iframeEventBridgeElement = createIframeEventBridgeElement(wrapper);
6541
+ wrapper.appendChild(iframeEventBridgeElement);
6542
+ (_a = iframeEventBridgeElement$.getValue()) == null ? void 0 : _a.remove();
6543
+ iframeEventBridgeElement$.next(iframeEventBridgeElement);
6544
+ }),
6545
+ takeUntil(reader.$.destroy$)
6546
+ ).subscribe();
6547
+ return {
6548
+ ...reader,
6549
+ events: {
6550
+ normalizeEventForViewport: createNormalizeEventForViewport({
6551
+ iframeEventBridgeElement$,
6552
+ locator: reader.spine.locator
6553
+ })
6554
+ }
6555
+ };
6556
+ };
6594
6557
  const createReaderWithEnhancers = (
6595
6558
  //__
6596
6559
  publicApiEnhancer(
@@ -6610,8 +6573,10 @@ const createReaderWithEnhancers = (
6610
6573
  hotkeysEnhancer(
6611
6574
  paginationEnhancer(
6612
6575
  progressionEnhancer(
6613
- // __
6614
- createReader
6576
+ eventsEnhancer(
6577
+ // __
6578
+ createReader
6579
+ )
6615
6580
  )
6616
6581
  )
6617
6582
  )