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