@prose-reader/core 1.56.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(),
@@ -503,15 +507,15 @@
503
507
  return false;
504
508
  const hrefUrl = new URL(element.href);
505
509
  const hrefWithoutAnchor = `${hrefUrl.origin}${hrefUrl.pathname}`;
506
- 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);
507
511
  if (hasExistingSpineItem) {
508
- reader.goToUrl(hrefUrl);
512
+ reader.viewportNavigator.goToUrl(hrefUrl);
509
513
  return true;
510
514
  }
511
515
  return false;
512
516
  };
513
- reader.registerHook(`item.onLoad`, ({ frame }) => {
514
- if (frame.contentDocument) {
517
+ reader.hookManager.register(`item.onLoad`, ({ frame }) => {
518
+ if (frame == null ? void 0 : frame.contentDocument) {
515
519
  Array.from(frame.contentDocument.querySelectorAll(`a`)).forEach(
516
520
  (element) => element.addEventListener(`click`, (e) => {
517
521
  if (e.target && `style` in e.target && `ELEMENT_NODE` in e.target) {
@@ -535,27 +539,27 @@
535
539
  const createNavigator = (reader) => {
536
540
  const goToNextSpineItem = () => {
537
541
  var _a;
538
- const focusedSpineItemIndex = reader.getFocusedSpineItemIndex() || 0;
539
- const { end = focusedSpineItemIndex } = reader.locator.getSpineItemsFromReadingOrderPosition(reader.getCurrentNavigationPosition()) || {};
540
- const numberOfSpineItems = ((_a = reader.context.getManifest()) == null ? void 0 : _a.spineItems.length) ?? 0;
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;
541
545
  const nextItem = end + 1;
542
546
  if (nextItem < numberOfSpineItems) {
543
- reader.goToSpineItem(nextItem);
547
+ reader.viewportNavigator.goToSpineItem(nextItem);
544
548
  }
545
549
  };
546
550
  const goToPreviousSpineItem = () => {
547
- const focusedSpineItemIndex = reader.getFocusedSpineItemIndex() || 0;
548
- 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()) || {};
549
553
  const nextItem = begin - 1;
550
554
  if (nextItem >= 0) {
551
- reader.goToSpineItem(nextItem);
555
+ reader.viewportNavigator.goToSpineItem(nextItem);
552
556
  }
553
557
  };
554
558
  return {
555
559
  goToNextSpineItem,
556
560
  goToPreviousSpineItem,
557
561
  goToLeftSpineItem: () => {
558
- if (reader.settings.getSettings().computedPageTurnDirection === "vertical")
562
+ if (reader.settings.settings.computedPageTurnDirection === "vertical")
559
563
  return;
560
564
  if (reader.context.isRTL()) {
561
565
  return goToNextSpineItem();
@@ -563,7 +567,7 @@
563
567
  return goToPreviousSpineItem();
564
568
  },
565
569
  goToRightSpineItem: () => {
566
- if (reader.settings.getSettings().computedPageTurnDirection === "vertical")
570
+ if (reader.settings.settings.computedPageTurnDirection === "vertical")
567
571
  return;
568
572
  if (reader.context.isRTL()) {
569
573
  return goToPreviousSpineItem();
@@ -574,7 +578,7 @@
574
578
  };
575
579
  const createState = (reader) => {
576
580
  return reader.pagination.paginationInfo$.pipe(
577
- rxjs.withLatestFrom(reader.context.$.manifest$, reader.settings.settings$),
581
+ rxjs.withLatestFrom(reader.context.manifest$, reader.settings.settings$),
578
582
  rxjs.map(([paginationInfo, manifest, { computedPageTurnDirection }]) => {
579
583
  const numberOfSpineItems = (manifest == null ? void 0 : manifest.spineItems.length) ?? 0;
580
584
  const isAtAbsoluteBeginning = paginationInfo.beginSpineItemIndex === 0 && paginationInfo.beginPageIndexInSpineItem === 0;
@@ -638,8 +642,8 @@
638
642
  return buildChaptersInfo(href, ((_a = manifest.nav) == null ? void 0 : _a.toc) ?? [], manifest);
639
643
  };
640
644
  const getChaptersInfo = (reader) => {
641
- const manifest = reader.context.getManifest();
642
- const items = reader.getSpineItems();
645
+ const manifest = reader.context.manifest;
646
+ const items = reader.spineItemManager.getAll();
643
647
  if (!manifest)
644
648
  return {};
645
649
  return items.reduce(
@@ -653,7 +657,7 @@
653
657
  );
654
658
  };
655
659
  const trackChapterInfo = (reader) => {
656
- return reader.spineItems$.pipe(
660
+ return reader.spine.$.spineItems$.pipe(
657
661
  rxjs.startWith([]),
658
662
  rxjs.map(() => getChaptersInfo(reader))
659
663
  );
@@ -744,7 +748,7 @@
744
748
  const getSpineItemNumberOfPages = ({ spineItem, reader }) => {
745
749
  const writingMode = spineItem.spineItemFrame.getWritingMode();
746
750
  const { width, height } = spineItem.getElementDimensions();
747
- const settings = reader.settings.getSettings();
751
+ const settings = reader.settings.settings;
748
752
  if (settings.pageTurnDirection === `vertical` && settings.pageTurnMode === `scrollable`) {
749
753
  return 1;
750
754
  }
@@ -753,11 +757,11 @@
753
757
  }
754
758
  return calculateNumberOfPagesForItem(width, reader.context.getPageSize().width);
755
759
  };
756
- const getNumberOfPagesForAllSpineItems = (reader) => reader.getSpineItems().map((item) => {
760
+ const getNumberOfPagesForAllSpineItems = (reader) => reader.spineItemManager.getAll().map((item) => {
757
761
  return getSpineItemNumberOfPages({ spineItem: item, reader });
758
762
  }, 0);
759
763
  const trackTotalPages = (reader) => {
760
- const totalPages$ = reader.$.layout$.pipe(
764
+ const totalPages$ = reader.spine.$.layout$.pipe(
761
765
  rxjs.debounceTime(10, rxjs.animationFrameScheduler),
762
766
  rxjs.withLatestFrom(reader.pagination.paginationInfo$),
763
767
  rxjs.map(() => {
@@ -780,8 +784,8 @@
780
784
  };
781
785
  const mapPaginationInfoToExtendedInfo = (reader) => (paginationInfo, chaptersInfo) => {
782
786
  const context = reader.context;
783
- const beginItem = paginationInfo.beginSpineItemIndex !== void 0 ? reader.getSpineItem(paginationInfo.beginSpineItemIndex) : void 0;
784
- const endItem = paginationInfo.endSpineItemIndex !== void 0 ? reader.getSpineItem(paginationInfo.endSpineItemIndex) : void 0;
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;
785
789
  return {
786
790
  ...paginationInfo,
787
791
  beginChapterInfo: beginItem ? chaptersInfo[beginItem.item.id] : void 0,
@@ -810,13 +814,13 @@
810
814
  paginationInfo.endSpineItemIndex ?? 0,
811
815
  paginationInfo.endNumberOfPagesInSpineItem,
812
816
  paginationInfo.endPageIndexInSpineItem || 0,
813
- reader.getCurrentViewportPosition(),
817
+ reader.viewportNavigator.getCurrentViewportPosition(),
814
818
  endItem
815
819
  ) : 0,
816
- isUsingSpread: context.isUsingSpreadMode() ?? false
820
+ isUsingSpread: context.state.isUsingSpreadMode ?? false
817
821
  // hasNextChapter: (reader.spine.spineItemIndex || 0) < (manifest.readingOrder.length - 1),
818
822
  // hasPreviousChapter: (reader.spine.spineItemIndex || 0) < (manifest.readingOrder.length - 1),
819
- // numberOfSpineItems: context.getManifest()?.readingOrder.length,
823
+ // numberOfSpineItems: context.manifest?.readingOrder.length,
820
824
  };
821
825
  };
822
826
  const trackPaginationInfo = (reader) => {
@@ -912,18 +916,22 @@
912
916
  };
913
917
  };
914
918
  const applyChangeToSpineItem = () => {
915
- reader.manipulateSpineItems(({ removeStyle, addStyle, container }) => {
919
+ reader.spine.manipulateSpineItems(({ removeStyle, addStyle, container }) => {
916
920
  removeStyle(`prose-reader-theme`);
917
921
  addStyle(`prose-reader-theme`, getStyle());
918
922
  applyChangeToSpineItemElement({ container });
919
923
  return false;
920
924
  });
921
925
  };
922
- reader.registerHook(`item.onLoad`, ({ removeStyle, addStyle }) => {
923
- removeStyle(`prose-reader-theme`);
924
- 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
+ });
925
933
  });
926
- reader.spineItems$.pipe(
934
+ reader.spine.$.spineItems$.pipe(
927
935
  operators.tap((items) => items.map(({ element }) => applyChangeToSpineItemElement({ container: element }))),
928
936
  operators.takeUntil(reader.$.destroy$)
929
937
  ).subscribe();
@@ -960,7 +968,7 @@
960
968
  imgLastPosition = { x: 0, y: 0 };
961
969
  baseScale = 1;
962
970
  lastUserScale = 1;
963
- const container = reader.context.getState().containerElement;
971
+ const container = reader.context.state.containerElement;
964
972
  if (container) {
965
973
  imageMagnifierContainer = container.ownerDocument.createElement(`div`);
966
974
  imageMagnifierContainer.style.cssText = `
@@ -1018,6 +1026,7 @@
1018
1026
  `transform`,
1019
1027
  `translate3d(${imgLastPosition.x}px, ${imgLastPosition.y}px, 0px) scale3d(${baseScale}, ${baseScale}, 1)`
1020
1028
  );
1029
+ console.log({ delta, imgLastPosition });
1021
1030
  movingLastDelta = delta;
1022
1031
  }
1023
1032
  if (isLast) {
@@ -1135,7 +1144,7 @@
1135
1144
  const elementZoomer = createElementZoomer(reader);
1136
1145
  const viewportZoomer = createViewportZoomer(reader);
1137
1146
  const currentZoomerSubject$ = new rxjs.BehaviorSubject(void 0);
1138
- const isUsingScrollableViewport = () => reader.settings.getSettings().computedPageTurnMode === `scrollable`;
1147
+ const isUsingScrollableViewport = () => reader.settings.settings.computedPageTurnMode === `scrollable`;
1139
1148
  const enter = (imgElement) => {
1140
1149
  var _a;
1141
1150
  (_a = currentZoomerSubject$ == null ? void 0 : currentZoomerSubject$.value) == null ? void 0 : _a.exit();
@@ -1218,143 +1227,100 @@
1218
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`);
1219
1228
  };
1220
1229
  const isFullyPrePaginated = (manifest) => (manifest == null ? void 0 : manifest.renditionLayout) === "pre-paginated" || (manifest == null ? void 0 : manifest.spineItems.every((item) => item.renditionLayout === "pre-paginated"));
1221
- const createContext = (settings) => {
1222
- const stateSubject = new rxjs.BehaviorSubject({});
1223
- const manifest$ = stateSubject.pipe(
1224
- operators.map((state) => state.manifest),
1225
- operators.filter(isDefined),
1226
- operators.distinctUntilChanged()
1227
- );
1228
- const containerElement$ = stateSubject.pipe(
1229
- operators.map((state) => state.containerElement),
1230
- operators.filter(isDefined),
1231
- operators.distinctUntilChanged()
1232
- );
1233
- const hasVerticalWriting$ = stateSubject.pipe(
1234
- operators.map((state) => state.hasVerticalWriting),
1235
- operators.filter(isDefined),
1236
- operators.distinctUntilChanged()
1237
- );
1238
- const isUsingSpreadMode$ = stateSubject.pipe(
1239
- operators.map((state) => state.isUsingSpreadMode),
1240
- operators.distinctUntilChanged()
1241
- );
1242
- const visibleAreaRect = {
1243
- width: 0,
1244
- height: 0,
1245
- x: 0,
1246
- y: 0
1247
- };
1248
- const marginTop = 0;
1249
- const marginBottom = 0;
1250
- const destroy$ = new rxjs.Subject();
1251
- const setState = (newState) => {
1252
- const newCompleteState = { ...stateSubject.getValue(), ...newState };
1253
- if (!isShallowEqual(newCompleteState, stateSubject.getValue())) {
1254
- stateSubject.next(newCompleteState);
1255
- }
1256
- };
1257
- const load = (newManifest, newLoadOptions) => {
1258
- setState({
1259
- manifest: newManifest,
1260
- ...newLoadOptions,
1261
- isFullyPrePaginated: isFullyPrePaginated(newManifest),
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
+ },
1262
1296
  isUsingSpreadMode: isUsingSpreadMode({
1263
- manifest: newManifest,
1297
+ manifest,
1264
1298
  visibleAreaRect,
1265
- forceSinglePageMode: settings.getSettings().forceSinglePageMode
1299
+ forceSinglePageMode
1266
1300
  })
1267
- });
1268
- };
1269
- const isRTL = () => {
1270
- var _a;
1271
- return ((_a = stateSubject.getValue().manifest) == null ? void 0 : _a.readingDirection) === `rtl`;
1272
- };
1273
- const setHasVerticalWriting = (value) => setState({
1274
- hasVerticalWriting: value
1275
- });
1276
- const recomputeSettings$ = rxjs.merge(hasVerticalWriting$, manifest$);
1277
- recomputeSettings$.pipe(
1278
- operators.withLatestFrom(hasVerticalWriting$, manifest$),
1279
- operators.tap(([, hasVerticalWriting, manifest]) => {
1280
- settings.recompute({ hasVerticalWriting, manifest });
1281
- }),
1282
- operators.takeUntil(destroy$)
1283
- ).subscribe();
1284
- settings.$.settings$.pipe(
1285
- operators.map(({ forceSinglePageMode }) => forceSinglePageMode),
1286
- operators.distinctUntilChanged(),
1287
- operators.withLatestFrom(manifest$),
1288
- operators.tap(([forceSinglePageMode, manifest]) => {
1289
- setState({
1290
- isUsingSpreadMode: isUsingSpreadMode({
1291
- manifest,
1292
- visibleAreaRect,
1293
- forceSinglePageMode
1294
- })
1295
- });
1296
- }),
1297
- operators.takeUntil(destroy$)
1298
- ).subscribe();
1299
- const destroy = () => {
1300
- stateSubject.complete();
1301
- destroy$.next();
1302
- destroy$.complete();
1303
- };
1304
- return {
1305
- load,
1306
- isRTL,
1307
- areAllItemsPrePaginated: () => {
1308
- var _a;
1309
- return areAllItemsPrePaginated$1((_a = stateSubject.getValue()) == null ? void 0 : _a.manifest);
1310
- },
1311
- destroy,
1312
- getCalculatedInnerMargin: () => 0,
1313
- getVisibleAreaRect: () => visibleAreaRect,
1314
- isUsingSpreadMode: () => stateSubject.getValue().isUsingSpreadMode,
1315
- setHasVerticalWriting,
1316
- setVisibleAreaRect: ({ height, width, x, y }) => {
1317
- visibleAreaRect.width = width;
1318
- visibleAreaRect.height = height - marginTop - marginBottom;
1319
- visibleAreaRect.x = x;
1320
- visibleAreaRect.y = y;
1321
- const manifest = stateSubject.getValue().manifest;
1322
- if (manifest) {
1323
- setState({
1324
- isUsingSpreadMode: isUsingSpreadMode({
1325
- manifest,
1326
- visibleAreaRect,
1327
- forceSinglePageMode: settings.getSettings().forceSinglePageMode
1328
- })
1329
- });
1330
- }
1331
- },
1332
- getState: () => stateSubject.getValue(),
1333
- getManifest: () => {
1334
- var _a;
1335
- return (_a = stateSubject.getValue()) == null ? void 0 : _a.manifest;
1336
- },
1337
- getReadingDirection: () => {
1338
- var _a, _b;
1339
- return (_b = (_a = stateSubject.getValue()) == null ? void 0 : _a.manifest) == null ? void 0 : _b.readingDirection;
1340
- },
1341
- getPageSize: () => {
1342
- return {
1343
- width: stateSubject.getValue().isUsingSpreadMode ? visibleAreaRect.width / 2 : visibleAreaRect.width,
1344
- height: visibleAreaRect.height
1345
- };
1346
- },
1347
- containerElement$,
1348
- isUsingSpreadMode$,
1349
- hasVerticalWriting$,
1350
- $: {
1351
- manifest$,
1352
- destroy$: destroy$.asObservable(),
1353
- state$: stateSubject.asObservable()
1301
+ };
1302
+ if (!isShallowEqual(newCompleteState, previousState)) {
1303
+ this._stateSubject.next(newCompleteState);
1354
1304
  }
1355
- };
1356
- };
1357
- 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
+ }
1358
1324
  const __UNSAFE_REFERENCE_ORIGINAL_IFRAME_EVENT_KEY = `__UNSAFE_REFERENCE_ORIGINAL_IFRAME_EVENT`;
1359
1325
  const ITEM_EXTENSION_VALID_FOR_FRAME_SRC = [`.xhtml`, `.html`, `.htm`];
1360
1326
  const HTML_PREFIX$1 = `prose-reader`;
@@ -1407,11 +1373,6 @@
1407
1373
  `;
1408
1374
  return rxjs.of(frame);
1409
1375
  });
1410
- const createFrameManipulator = (frameElement) => ({
1411
- frame: frameElement,
1412
- removeStyle: createRemoveStyleHelper(frameElement),
1413
- addStyle: createAddStyleHelper(frameElement)
1414
- });
1415
1376
  const getIntrinsicDimensionsFromBase64Img = (data) => new Promise((resolve, reject) => {
1416
1377
  const image = new Image();
1417
1378
  image.src = data;
@@ -1464,15 +1425,14 @@
1464
1425
  const content = await resourceResponse.text();
1465
1426
  return content;
1466
1427
  };
1467
- const isOnLoadHook = (hook) => hook.name === `item.onLoad`;
1468
1428
  const createLoader = ({
1469
1429
  item,
1470
1430
  parent,
1471
1431
  fetchResource,
1472
- hooks$,
1473
1432
  context,
1474
1433
  viewportState$,
1475
- settings
1434
+ settings,
1435
+ hookManager
1476
1436
  }) => {
1477
1437
  const destroySubject$ = new rxjs.Subject();
1478
1438
  const loadSubject$ = new rxjs.Subject();
@@ -1480,10 +1440,9 @@
1480
1440
  const frameElementSubject$ = new rxjs.BehaviorSubject(void 0);
1481
1441
  const isLoadedSubject$ = new rxjs.BehaviorSubject(false);
1482
1442
  const isReadySubject$ = new rxjs.BehaviorSubject(false);
1483
- let onLoadHookReturns = [];
1484
1443
  let computedStyleAfterLoad;
1485
1444
  const makeItHot = (source$) => {
1486
- source$.pipe(operators.takeUntil(context.$.destroy$)).subscribe();
1445
+ source$.pipe(operators.takeUntil(context.destroy$)).subscribe();
1487
1446
  return source$;
1488
1447
  };
1489
1448
  const getHtmlFromResource = (response) => createHtmlPageFromResource(response, item);
@@ -1497,14 +1456,7 @@
1497
1456
  operators.withLatestFrom(frameElementSubject$),
1498
1457
  operators.filter(([_, frame]) => !!frame),
1499
1458
  operators.map(([, frame]) => {
1500
- onLoadHookReturns.forEach((fn) => {
1501
- if (fn && `unsubscribe` in fn) {
1502
- fn.unsubscribe();
1503
- } else if (fn) {
1504
- fn();
1505
- }
1506
- });
1507
- onLoadHookReturns = [];
1459
+ hookManager.destroy(`item.onLoad`, item.id);
1508
1460
  frame == null ? void 0 : frame.remove();
1509
1461
  frameElementSubject$.next(void 0);
1510
1462
  }),
@@ -1549,8 +1501,7 @@
1549
1501
  return rxjs.EMPTY;
1550
1502
  return rxjs.fromEvent(frame, `load`).pipe(
1551
1503
  operators.take(1),
1552
- operators.withLatestFrom(hooks$),
1553
- operators.mergeMap(([_, hooks]) => {
1504
+ operators.mergeMap(() => {
1554
1505
  var _a, _b;
1555
1506
  const body = (_a = frame.contentDocument) == null ? void 0 : _a.body;
1556
1507
  if (!body) {
@@ -1561,21 +1512,13 @@
1561
1512
  if ((frame == null ? void 0 : frame.contentDocument) && body) {
1562
1513
  computedStyleAfterLoad = (_b = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _b.getComputedStyle(body);
1563
1514
  }
1564
- if (settings.getSettings().computedPageTurnMode !== `scrollable`) {
1515
+ if (settings.settings.computedPageTurnMode !== `scrollable`) {
1565
1516
  frame.setAttribute(`tab-index`, `0`);
1566
1517
  }
1567
- const manipulableFrame = createFrameManipulator(frame);
1568
- onLoadHookReturns = hooks.filter(isOnLoadHook).map((hook) => {
1569
- const hookReturn = hook.fn({
1570
- ...manipulableFrame,
1571
- item
1572
- });
1573
- if (hookReturn && `subscribe` in hookReturn) {
1574
- return hookReturn.subscribe();
1575
- }
1576
- return hookReturn;
1577
- });
1578
- return rxjs.of(frame);
1518
+ return hookManager.execute(`item.onLoad`, item.id, {
1519
+ itemId: item.id,
1520
+ frame
1521
+ }).pipe(operators.map(() => frame));
1579
1522
  })
1580
1523
  );
1581
1524
  }),
@@ -1624,14 +1567,19 @@
1624
1567
  }
1625
1568
  };
1626
1569
  };
1570
+ const createFrameManipulator = (frameElement) => ({
1571
+ frame: frameElement,
1572
+ removeStyle: createRemoveStyleHelper(frameElement),
1573
+ addStyle: createAddStyleHelper(frameElement)
1574
+ });
1627
1575
  const createFrameItem = ({
1628
1576
  item,
1629
1577
  parent,
1630
1578
  fetchResource,
1631
1579
  context,
1632
- hooks$,
1633
1580
  viewportState$,
1634
- settings
1581
+ settings,
1582
+ hookManager
1635
1583
  }) => {
1636
1584
  const destroySubject$ = new rxjs.Subject();
1637
1585
  const {
@@ -1640,7 +1588,7 @@
1640
1588
  unload,
1641
1589
  destroy: loaderDestroy,
1642
1590
  getComputedStyleAfterLoad
1643
- } = createLoader({ context, hooks$, item, parent, fetchResource, viewportState$, settings });
1591
+ } = createLoader({ context, hookManager, item, parent, fetchResource, viewportState$, settings });
1644
1592
  let isLoadedSync = false;
1645
1593
  let isReadySync = false;
1646
1594
  isLoaded$.subscribe({
@@ -1728,7 +1676,7 @@
1728
1676
  if (frame) {
1729
1677
  frame.style.width = `${size.width}px`;
1730
1678
  frame.style.height = `${size.height}px`;
1731
- if (settings.getSettings().computedPageTurnMode !== `scrollable`) {
1679
+ if (settings.settings.computedPageTurnMode !== `scrollable`) {
1732
1680
  frame.setAttribute(`tab-index`, `0`);
1733
1681
  }
1734
1682
  }
@@ -1816,220 +1764,46 @@
1816
1764
  });
1817
1765
  (_a = frameToTrack.contentDocument) == null ? void 0 : _a.addEventListener(`selectionchange`, () => {
1818
1766
  var _a2;
1819
- subject.next({ event: `selectionchange`, data: ((_a2 = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _a2.getSelection()) || null });
1820
- });
1821
- (_b = frameToTrack.contentWindow) == null ? void 0 : _b.addEventListener(`selectstart`, () => {
1822
- isSelecting = true;
1823
- });
1824
- };
1825
- const destroy = () => {
1826
- };
1827
- return {
1828
- track,
1829
- destroy,
1830
- isSelecting: () => isSelecting,
1831
- getSelection: () => {
1832
- var _a;
1833
- const selection = (_a = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _a.getSelection();
1834
- if (!(selection == null ? void 0 : selection.anchorNode) || selection.type === `None` || selection.type === `Caret`)
1835
- return void 0;
1836
- return selection;
1837
- },
1838
- $: subject.asObservable()
1839
- };
1840
- };
1841
- const isHtmlElement = (element) => {
1842
- return typeof element === `object` && !!element && `nodeType` in element && (element == null ? void 0 : element.nodeType) === Node.ELEMENT_NODE && `innerText` in element;
1843
- };
1844
- function createRangeOrCaretFromPoint(doc, startX, startY) {
1845
- if (`caretPositionFromPoint` in doc) {
1846
- return doc.caretPositionFromPoint(startX, startY);
1847
- } else if (typeof doc.caretRangeFromPoint !== `undefined`) {
1848
- return doc.caretRangeFromPoint(startX, startY);
1849
- }
1850
- }
1851
- const getFirstVisibleNodeForViewport = Report.measurePerformance(
1852
- `getFirstVisibleNodeForViewport`,
1853
- 1,
1854
- (documentOrElement, viewport) => {
1855
- const element = `body` in documentOrElement ? getFirstVisibleElementForViewport(documentOrElement.body, viewport) : getFirstVisibleElementForViewport(documentOrElement, viewport);
1856
- const ownerDocument = `createRange` in documentOrElement ? documentOrElement : documentOrElement.ownerDocument;
1857
- if (element) {
1858
- let lastValidRange;
1859
- let lastValidOffset = 0;
1860
- const range = ownerDocument.createRange();
1861
- Array.from(element.childNodes).some((childNode) => {
1862
- range.selectNodeContents(childNode);
1863
- const rects = range.getClientRects();
1864
- const visibleRect = getFirstVisibleDOMRect(rects, viewport);
1865
- if (visibleRect) {
1866
- lastValidRange = range.cloneRange();
1867
- const rangeOrCaret = createRangeOrCaretFromPoint(ownerDocument, Math.ceil(visibleRect.left), Math.ceil(visibleRect.top));
1868
- if (rangeOrCaret && `startContainer` in rangeOrCaret && rangeOrCaret.startContainer === lastValidRange.startContainer) {
1869
- lastValidOffset = rangeOrCaret.startOffset;
1870
- }
1871
- if (rangeOrCaret && `offsetNode` in rangeOrCaret && rangeOrCaret.offsetNode === lastValidRange.startContainer) {
1872
- lastValidOffset = rangeOrCaret.offset;
1873
- }
1874
- return true;
1875
- }
1876
- return false;
1877
- });
1878
- if (lastValidRange) {
1879
- return { node: lastValidRange.startContainer, offset: lastValidOffset };
1880
- }
1881
- return { node: element, offset: 0 };
1882
- }
1883
- return void 0;
1884
- }
1885
- );
1886
- const getFirstVisibleElementForViewport = (element, viewport) => {
1887
- let lastValidElement;
1888
- const positionFromViewport = getElementOrNodePositionFromViewPort(element.getBoundingClientRect(), viewport);
1889
- if (positionFromViewport !== `before` && positionFromViewport !== `after`) {
1890
- lastValidElement = element;
1891
- }
1892
- Array.from(element.children).some((child) => {
1893
- const childInViewPort = getFirstVisibleElementForViewport(child, viewport);
1894
- if (childInViewPort) {
1895
- lastValidElement = childInViewPort;
1896
- return true;
1897
- }
1898
- return false;
1899
- });
1900
- return lastValidElement;
1901
- };
1902
- function getElementOrNodePositionFromViewPort(domRect, { left, right }) {
1903
- if (domRect.left <= left && domRect.right <= left)
1904
- return `before`;
1905
- if (domRect.left <= left && domRect.right > left && domRect.right <= right)
1906
- return `partially-before`;
1907
- if (domRect.left <= right && domRect.right > right)
1908
- return `partially-after`;
1909
- if (domRect.left > right)
1910
- return `after`;
1911
- return `within`;
1912
- }
1913
- function getFirstVisibleDOMRect(domRect, viewport) {
1914
- return Array.from(domRect).find((domRect2) => {
1915
- const position = getElementOrNodePositionFromViewPort(domRect2, viewport);
1916
- if (position !== `before` && position !== `after`) {
1917
- return true;
1918
- }
1919
- return false;
1920
- });
1921
- }
1922
- const getRangeFromNode = (node, offset) => {
1923
- var _a;
1924
- if (node.nodeType !== Node.CDATA_SECTION_NODE && node.nodeType !== Node.DOCUMENT_TYPE_NODE) {
1925
- const range = (_a = node.ownerDocument) == null ? void 0 : _a.createRange();
1926
- range == null ? void 0 : range.selectNodeContents(node);
1927
- try {
1928
- if (offset <= ((range == null ? void 0 : range.endOffset) || 0)) {
1929
- range == null ? void 0 : range.setStart(node, offset || 0);
1930
- }
1931
- } catch (e) {
1932
- Report.error(e);
1933
- }
1934
- return range;
1935
- }
1936
- return void 0;
1937
- };
1938
- const isPointerEvent = (event) => {
1939
- var _a, _b, _c, _d, _e;
1940
- if ((event == null ? void 0 : event.target) && ((_b = (_a = event == null ? void 0 : event.target) == null ? void 0 : _a.ownerDocument) == null ? void 0 : _b.defaultView)) {
1941
- const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
1942
- if (eventView.PointerEvent) {
1943
- return event instanceof eventView.PointerEvent;
1944
- }
1945
- }
1946
- if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
1947
- const eventView = event == null ? void 0 : event.view;
1948
- if (eventView.PointerEvent) {
1949
- return event instanceof eventView.PointerEvent;
1950
- }
1951
- }
1952
- return false;
1953
- };
1954
- const isMouseEvent = (event) => {
1955
- var _a, _b, _c, _d, _e;
1956
- if (isPointerEvent(event))
1957
- return false;
1958
- if ((event == null ? void 0 : event.target) && ((_b = (_a = event == null ? void 0 : event.target) == null ? void 0 : _a.ownerDocument) == null ? void 0 : _b.defaultView)) {
1959
- const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
1960
- if (eventView.MouseEvent) {
1961
- return event instanceof eventView.MouseEvent;
1962
- }
1963
- }
1964
- if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
1965
- const eventView = event == null ? void 0 : event.view;
1966
- if (eventView.MouseEvent) {
1967
- return event instanceof eventView.MouseEvent;
1968
- }
1969
- }
1970
- return false;
1971
- };
1972
- const isTouchEvent = (event) => {
1973
- var _a, _b, _c, _d, _e;
1974
- if ((event == null ? void 0 : event.target) && ((_b = (_a = event == null ? void 0 : event.target) == null ? void 0 : _a.ownerDocument) == null ? void 0 : _b.defaultView)) {
1975
- const eventView = (_d = (_c = event == null ? void 0 : event.target) == null ? void 0 : _c.ownerDocument) == null ? void 0 : _d.defaultView;
1976
- if (eventView.TouchEvent) {
1977
- return event instanceof eventView.TouchEvent;
1978
- }
1979
- }
1980
- if ((event == null ? void 0 : event.view) && ((_e = event == null ? void 0 : event.view) == null ? void 0 : _e.window)) {
1981
- const eventView = event == null ? void 0 : event.view;
1982
- if (eventView.TouchEvent) {
1983
- return event instanceof eventView.TouchEvent;
1984
- }
1985
- }
1986
- return false;
1987
- };
1988
- const pointerEvents = [
1989
- `pointercancel`,
1990
- `pointerdown`,
1991
- `pointerenter`,
1992
- `pointerleave`,
1993
- `pointermove`,
1994
- `pointerout`,
1995
- `pointerover`,
1996
- `pointerup`,
1997
- `touchstart`,
1998
- `touchend`
1999
- ];
2000
- const mouseEvents = [
2001
- `click`,
2002
- `mousedown`,
2003
- `mouseup`,
2004
- `mouseenter`,
2005
- `mouseleave`,
2006
- `mousemove`,
2007
- `mouseout`,
2008
- `mouseover`
2009
- ];
2010
- const passthroughEvents = [...pointerEvents, ...mouseEvents];
1767
+ subject.next({ event: `selectionchange`, data: ((_a2 = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _a2.getSelection()) || null });
1768
+ });
1769
+ (_b = frameToTrack.contentWindow) == null ? void 0 : _b.addEventListener(`selectstart`, () => {
1770
+ isSelecting = true;
1771
+ });
1772
+ };
1773
+ const destroy = () => {
1774
+ };
1775
+ return {
1776
+ track,
1777
+ destroy,
1778
+ isSelecting: () => isSelecting,
1779
+ getSelection: () => {
1780
+ var _a;
1781
+ const selection = (_a = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _a.getSelection();
1782
+ if (!(selection == null ? void 0 : selection.anchorNode) || selection.type === `None` || selection.type === `Caret`)
1783
+ return void 0;
1784
+ return selection;
1785
+ },
1786
+ $: subject.asObservable()
1787
+ };
1788
+ };
2011
1789
  const createCommonSpineItem = ({
2012
1790
  item,
2013
1791
  context,
2014
1792
  parentElement,
2015
- iframeEventBridgeElement$,
2016
- hooks$,
2017
1793
  viewportState$,
2018
- settings
1794
+ settings,
1795
+ hookManager
2019
1796
  }) => {
2020
- var _a;
2021
1797
  const destroySubject$ = new rxjs.Subject();
2022
- const containerElement = createContainerElement$1(parentElement, item, hooks$);
1798
+ const containerElement = createContainerElement$1(parentElement, item, hookManager);
2023
1799
  const overlayElement = createOverlayElement(parentElement, item);
2024
1800
  const fingerTracker = createFingerTracker();
2025
1801
  const selectionTracker = createSelectionTracker();
2026
- const frameHooks = createFrameHooks(iframeEventBridgeElement$, fingerTracker, selectionTracker);
2027
1802
  const spineItemFrame = createFrameItem({
2028
1803
  parent: containerElement,
2029
1804
  item,
2030
1805
  context,
2031
- fetchResource: (_a = context.getState()) == null ? void 0 : _a.fetchResource,
2032
- hooks$: hooks$.asObservable().pipe(operators.map((hooks) => [...hooks, ...frameHooks])),
1806
+ hookManager,
2033
1807
  viewportState$,
2034
1808
  settings
2035
1809
  });
@@ -2052,12 +1826,12 @@
2052
1826
  return memoizedElementDimensions;
2053
1827
  };
2054
1828
  const isImageType = () => {
2055
- var _a2;
2056
- return !!((_a2 = item.mediaType) == null ? void 0 : _a2.startsWith(`image/`));
1829
+ var _a;
1830
+ return !!((_a = item.mediaType) == null ? void 0 : _a.startsWith(`image/`));
2057
1831
  };
2058
1832
  const injectStyle = (cssText) => {
2059
- var _a2, _b;
2060
- (_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`);
2061
1835
  (_b = spineItemFrame.getManipulableFrame()) == null ? void 0 : _b.addStyle(`prose-reader-css`, cssText);
2062
1836
  };
2063
1837
  const adjustPositionOfElement = ({ right, left, top }) => {
@@ -2078,10 +1852,10 @@
2078
1852
  }
2079
1853
  };
2080
1854
  const getViewPortInformation = () => {
2081
- var _a2;
1855
+ var _a;
2082
1856
  const { width: pageWidth, height: pageHeight } = context.getPageSize();
2083
1857
  const viewportDimensions = spineItemFrame.getViewportDimensions();
2084
- const frameElement = (_a2 = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a2.frame;
1858
+ const frameElement = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame;
2085
1859
  if (containerElement && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow) && viewportDimensions) {
2086
1860
  const computedWidthScale = pageWidth / viewportDimensions.width;
2087
1861
  const computedScale = Math.min(computedWidthScale, pageHeight / viewportDimensions.height);
@@ -2091,8 +1865,8 @@
2091
1865
  const loadContent = () => spineItemFrame.load();
2092
1866
  const unloadContent = () => spineItemFrame.unload();
2093
1867
  const getBoundingRectOfElementFromSelector = (selector) => {
2094
- var _a2, _b, _c, _d, _e;
2095
- 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;
2096
1870
  if (frame && selector) {
2097
1871
  if (selector.startsWith(`#`)) {
2098
1872
  return (_c = (_b = frame.contentDocument) == null ? void 0 : _b.getElementById(selector.replace(`#`, ``))) == null ? void 0 : _c.getBoundingClientRect();
@@ -2137,16 +1911,12 @@
2137
1911
  }) => {
2138
1912
  containerElement.style.width = `${width}px`;
2139
1913
  containerElement.style.height = `${height}px`;
2140
- hooks$.getValue().forEach((hook) => {
2141
- if (hook.name === `item.onAfterLayout`) {
2142
- hook.fn({ blankPagePosition, item, minimumWidth });
2143
- }
2144
- });
1914
+ hookManager.execute(`item.onAfterLayout`, void 0, { blankPagePosition, item, minimumWidth });
2145
1915
  setLayoutDirty();
2146
1916
  };
2147
1917
  const translateFramePositionIntoPage = (position) => {
2148
- var _a2, _b;
2149
- 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()) || {};
2150
1920
  const computedScale = ((_b = getViewPortInformation()) == null ? void 0 : _b.computedScale) ?? 1;
2151
1921
  const adjustedX = position.clientX * computedScale + left;
2152
1922
  const adjustedY = position.clientY * computedScale + top;
@@ -2156,20 +1926,14 @@
2156
1926
  };
2157
1927
  };
2158
1928
  const getResource = async () => {
2159
- const fetchResource = context.getState().fetchResource;
1929
+ const fetchResource = settings.settings.fetchResource;
2160
1930
  const lastFetch = (_) => {
2161
1931
  if (fetchResource) {
2162
1932
  return fetchResource(item);
2163
1933
  }
2164
1934
  return fetch(item.href);
2165
1935
  };
2166
- const finalFetch = hooks$.getValue().reduce((acc, hook) => {
2167
- if (hook.name === `item.onGetResource`) {
2168
- return hook.fn(acc);
2169
- }
2170
- return acc;
2171
- }, lastFetch);
2172
- return await finalFetch(item);
1936
+ return await lastFetch();
2173
1937
  };
2174
1938
  const manipulateSpineItem = (cb) => {
2175
1939
  const manipulableFrame = spineItemFrame.getManipulableFrame();
@@ -2192,16 +1956,12 @@
2192
1956
  overlayElement
2193
1957
  });
2194
1958
  };
2195
- const executeOnLayoutBeforeMeasurementHook = (options) => hooks$.getValue().forEach((hook) => {
2196
- if (hook.name === `item.onLayoutBeforeMeasurement`) {
2197
- hook.fn({
2198
- frame: spineItemFrame,
2199
- container: containerElement,
2200
- item,
2201
- isImageType,
2202
- ...options
2203
- });
2204
- }
1959
+ const executeOnLayoutBeforeMeasurementHook = (options) => hookManager.execute("item.onLayoutBeforeMeasurement", void 0, {
1960
+ frame: spineItemFrame,
1961
+ container: containerElement,
1962
+ item,
1963
+ isImageType,
1964
+ ...options
2205
1965
  });
2206
1966
  const contentLayout$ = spineItemFrame.$.contentLayoutChange$.pipe(
2207
1967
  operators.withLatestFrom(spineItemFrame.$.isReady$),
@@ -2240,8 +2000,8 @@
2240
2000
  destroySubject$.complete();
2241
2001
  },
2242
2002
  isUsingVerticalWriting: () => {
2243
- var _a2;
2244
- return (_a2 = spineItemFrame.getWritingMode()) == null ? void 0 : _a2.startsWith(`vertical`);
2003
+ var _a;
2004
+ return (_a = spineItemFrame.getWritingMode()) == null ? void 0 : _a.startsWith(`vertical`);
2245
2005
  },
2246
2006
  /**
2247
2007
  * @important
@@ -2252,7 +2012,7 @@
2252
2012
  * be confined to a single page.
2253
2013
  */
2254
2014
  getReadingDirection: () => {
2255
- return spineItemFrame.getReadingDirection() || context.getReadingDirection();
2015
+ return spineItemFrame.getReadingDirection() || context.readingDirection;
2256
2016
  },
2257
2017
  manipulateSpineItem,
2258
2018
  executeOnLayoutBeforeMeasurementHook,
@@ -2267,7 +2027,7 @@
2267
2027
  }
2268
2028
  };
2269
2029
  };
2270
- const createContainerElement$1 = (containerElement, item, hooks$) => {
2030
+ const createContainerElement$1 = (containerElement, item, hookManager) => {
2271
2031
  const element = containerElement.ownerDocument.createElement(`div`);
2272
2032
  element.classList.add(`spineItem`);
2273
2033
  element.classList.add(`spineItem-${item.renditionLayout}`);
@@ -2275,12 +2035,8 @@
2275
2035
  position: absolute;
2276
2036
  overflow: hidden;
2277
2037
  `;
2278
- return hooks$.getValue().reduce((element2, hook) => {
2279
- if (hook.name === `item.onBeforeContainerCreated`) {
2280
- return hook.fn(element2);
2281
- }
2282
- return element2;
2283
- }, element);
2038
+ hookManager.execute("item.onBeforeContainerCreated", void 0, { element });
2039
+ return element;
2284
2040
  };
2285
2041
  const createOverlayElement = (containerElement, item) => {
2286
2042
  const element = containerElement.ownerDocument.createElement(`div`);
@@ -2295,42 +2051,6 @@
2295
2051
  `;
2296
2052
  return element;
2297
2053
  };
2298
- const createFrameHooks = (iframeEventBridgeElement$, fingerTracker, selectionTracker) => {
2299
- return [
2300
- {
2301
- name: `item.onLoad`,
2302
- fn: ({ frame }) => {
2303
- const unregister = passthroughEvents.map((event) => {
2304
- var _a;
2305
- const listener = (e) => {
2306
- var _a2;
2307
- let convertedEvent = e;
2308
- if (isPointerEvent(e)) {
2309
- convertedEvent = new PointerEvent(e.type, e);
2310
- }
2311
- if (isMouseEvent(e)) {
2312
- convertedEvent = new MouseEvent(e.type, e);
2313
- }
2314
- if (convertedEvent !== e) {
2315
- attachOriginalFrameEventToDocumentEvent(convertedEvent, e);
2316
- (_a2 = iframeEventBridgeElement$.getValue()) == null ? void 0 : _a2.dispatchEvent(convertedEvent);
2317
- }
2318
- };
2319
- (_a = frame.contentDocument) == null ? void 0 : _a.addEventListener(event, listener);
2320
- return () => {
2321
- var _a2;
2322
- (_a2 = frame.contentDocument) == null ? void 0 : _a2.removeEventListener(event, listener);
2323
- };
2324
- });
2325
- selectionTracker.track(frame);
2326
- fingerTracker.track(frame);
2327
- return () => {
2328
- unregister.forEach((cb) => cb());
2329
- };
2330
- }
2331
- }
2332
- ];
2333
- };
2334
2054
  const getStyleForViewportDocument = () => {
2335
2055
  return `
2336
2056
  body {
@@ -2343,19 +2063,17 @@
2343
2063
  item,
2344
2064
  context,
2345
2065
  containerElement,
2346
- iframeEventBridgeElement$,
2347
- hooks$,
2348
2066
  viewportState$,
2349
- settings
2067
+ settings,
2068
+ hookManager
2350
2069
  }) => {
2351
2070
  const commonSpineItem = createCommonSpineItem({
2352
2071
  context,
2353
2072
  item,
2354
2073
  parentElement: containerElement,
2355
- iframeEventBridgeElement$,
2356
- hooks$,
2357
2074
  viewportState$,
2358
- settings
2075
+ settings,
2076
+ hookManager
2359
2077
  });
2360
2078
  const spineItemFrame = commonSpineItem.spineItemFrame;
2361
2079
  const layout = ({
@@ -2366,15 +2084,15 @@
2366
2084
  var _a;
2367
2085
  const { width: pageWidth, height: pageHeight } = context.getPageSize();
2368
2086
  const { viewportDimensions, computedScale = 1 } = commonSpineItem.getViewPortInformation() ?? {};
2369
- const visibleArea = context.getVisibleAreaRect();
2087
+ const visibleArea = context.state.visibleAreaRect;
2370
2088
  const frameElement = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame;
2371
2089
  if ((spineItemFrame == null ? void 0 : spineItemFrame.getIsLoaded()) && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
2372
2090
  const contentWidth = pageWidth;
2373
- const contentHeight = visibleArea.height + context.getCalculatedInnerMargin();
2091
+ const contentHeight = visibleArea.height + context.state.calculatedInnerMargin;
2374
2092
  const cssLink = buildDocumentStyle(
2375
2093
  {
2376
2094
  ...commonSpineItem.getDimensionsForPaginatedContent(),
2377
- enableTouch: settings.getSettings().computedPageTurnMode !== `scrollable`,
2095
+ enableTouch: settings.settings.computedPageTurnMode !== `scrollable`,
2378
2096
  spreadPosition
2379
2097
  },
2380
2098
  viewportDimensions
@@ -2517,19 +2235,17 @@
2517
2235
  item,
2518
2236
  context,
2519
2237
  containerElement,
2520
- iframeEventBridgeElement$,
2521
- hooks$,
2522
2238
  viewportState$,
2523
- settings
2239
+ settings,
2240
+ hookManager
2524
2241
  }) => {
2525
2242
  const commonSpineItem = createCommonSpineItem({
2526
2243
  context,
2527
2244
  item,
2528
2245
  parentElement: containerElement,
2529
- iframeEventBridgeElement$,
2530
- hooks$,
2531
2246
  viewportState$,
2532
- settings
2247
+ settings,
2248
+ hookManager
2533
2249
  });
2534
2250
  const spineItemFrame = commonSpineItem.spineItemFrame;
2535
2251
  let latestContentHeightWhenLoaded;
@@ -2542,12 +2258,12 @@
2542
2258
  (_b = (_a = spineItemFrame.getManipulableFrame()) == null ? void 0 : _a.frame) == null ? void 0 : _b.style.setProperty(`width`, `${pageWidth}px`);
2543
2259
  (_d = (_c = spineItemFrame.getManipulableFrame()) == null ? void 0 : _c.frame) == null ? void 0 : _d.style.setProperty(`height`, `${pageHeight}px`);
2544
2260
  const { viewportDimensions, computedScale = 1 } = commonSpineItem.getViewPortInformation() ?? {};
2545
- const visibleArea = context.getVisibleAreaRect();
2261
+ const visibleArea = context.state.visibleAreaRect;
2546
2262
  const frameElement = (_e = spineItemFrame.getManipulableFrame()) == null ? void 0 : _e.frame;
2547
- 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`;
2548
2264
  if ((spineItemFrame == null ? void 0 : spineItemFrame.getIsLoaded()) && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
2549
2265
  let contentWidth = pageWidth;
2550
- let contentHeight = visibleArea.height + context.getCalculatedInnerMargin();
2266
+ let contentHeight = visibleArea.height + context.state.calculatedInnerMargin;
2551
2267
  frameElement == null ? void 0 : frameElement.style.setProperty(`visibility`, `visible`);
2552
2268
  frameElement == null ? void 0 : frameElement.style.setProperty(`opacity`, `1`);
2553
2269
  if (viewportDimensions) {
@@ -2567,8 +2283,8 @@
2567
2283
  frameElement == null ? void 0 : frameElement.style.setProperty(`transform-origin`, `center center`);
2568
2284
  } else {
2569
2285
  const frameStyle = commonSpineItem.isImageType() ? buildStyleForReflowableImageOnly({
2570
- isScrollable: ((_g = context.getManifest()) == null ? void 0 : _g.renditionFlow) === `scrolled-continuous`,
2571
- enableTouch: settings.getSettings().computedPageTurnMode !== `scrollable`
2286
+ isScrollable: ((_g = context.manifest) == null ? void 0 : _g.renditionFlow) === `scrolled-continuous`,
2287
+ enableTouch: settings.settings.computedPageTurnMode !== `scrollable`
2572
2288
  }) : buildStyleWithMultiColumn(
2573
2289
  commonSpineItem.getDimensionsForReflowableContent(spineItemFrame.isUsingVerticalWriting(), minimumWidth)
2574
2290
  );
@@ -2581,7 +2297,7 @@
2581
2297
  width: minimumWidth,
2582
2298
  height: contentHeight
2583
2299
  });
2584
- } 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`) {
2585
2301
  contentHeight = frameElement.contentDocument.documentElement.scrollHeight;
2586
2302
  latestContentHeightWhenLoaded = contentHeight;
2587
2303
  spineItemFrame.staticLayout({
@@ -2793,91 +2509,29 @@
2793
2509
  item,
2794
2510
  context,
2795
2511
  containerElement,
2796
- iframeEventBridgeElement$,
2797
- hooks$,
2798
2512
  viewportState$,
2799
- settings
2513
+ settings,
2514
+ hookManager
2800
2515
  }) => {
2801
2516
  if (item.renditionLayout === `pre-paginated`) {
2802
2517
  return createPrePaginatedSpineItem({
2803
2518
  item,
2804
2519
  context,
2805
2520
  containerElement,
2806
- iframeEventBridgeElement$,
2807
- hooks$,
2808
2521
  viewportState$,
2809
- settings
2522
+ settings,
2523
+ hookManager
2810
2524
  });
2811
2525
  }
2812
2526
  return createReflowableSpineItem({
2813
2527
  item,
2814
2528
  context,
2815
2529
  containerElement,
2816
- iframeEventBridgeElement$,
2817
- hooks$,
2818
2530
  viewportState$,
2819
- settings
2531
+ settings,
2532
+ hookManager
2820
2533
  });
2821
2534
  };
2822
- const createEventsHelper = ({
2823
- iframeEventBridgeElement$,
2824
- locator
2825
- }) => {
2826
- const normalizeEventForViewport = (event) => {
2827
- var _a;
2828
- const eventIsComingFromBridge = event.target === iframeEventBridgeElement$.getValue();
2829
- const iframeOriginalEvent = getOriginalFrameEventFromDocumentEvent(event);
2830
- const originalFrame = (_a = iframeOriginalEvent == null ? void 0 : iframeOriginalEvent.view) == null ? void 0 : _a.frameElement;
2831
- if (!eventIsComingFromBridge || !iframeOriginalEvent || !originalFrame)
2832
- return event;
2833
- const spineItem = locator.getSpineItemFromIframe(originalFrame);
2834
- if (!spineItem)
2835
- return event;
2836
- if (isPointerEvent(event)) {
2837
- const { clientX, clientY } = spineItem.translateFramePositionIntoPage(event);
2838
- const newEvent = new PointerEvent(event.type, {
2839
- ...event,
2840
- pointerId: event.pointerId,
2841
- clientX,
2842
- clientY
2843
- });
2844
- Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
2845
- return newEvent;
2846
- }
2847
- if (isMouseEvent(event)) {
2848
- const { clientX, clientY } = spineItem.translateFramePositionIntoPage(event);
2849
- const newEvent = new MouseEvent(event.type, {
2850
- ...event,
2851
- clientX,
2852
- clientY
2853
- });
2854
- Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
2855
- return newEvent;
2856
- }
2857
- if (isTouchEvent(event)) {
2858
- const touches = Array.from(event.touches).map((touch) => {
2859
- const { clientX, clientY } = spineItem.translateFramePositionIntoPage(touch);
2860
- return new Touch({
2861
- identifier: touch.identifier,
2862
- target: touch.target,
2863
- clientX,
2864
- clientY
2865
- });
2866
- });
2867
- const newEvent = new TouchEvent(event.type, {
2868
- touches,
2869
- changedTouches: touches,
2870
- targetTouches: touches
2871
- });
2872
- Object.defineProperty(newEvent, `target`, { value: iframeOriginalEvent.target, enumerable: true });
2873
- return newEvent;
2874
- }
2875
- return event;
2876
- };
2877
- return {
2878
- normalizeEventForViewport
2879
- };
2880
- };
2881
2535
  const ELEMENT_NODE = Node.ELEMENT_NODE;
2882
2536
  const TEXT_NODE = Node.TEXT_NODE;
2883
2537
  const CDATA_SECTION_NODE = Node.CDATA_SECTION_NODE;
@@ -3779,9 +3433,7 @@
3779
3433
  element$,
3780
3434
  context,
3781
3435
  pagination,
3782
- iframeEventBridgeElement$,
3783
3436
  spineItemManager,
3784
- hooks$,
3785
3437
  spineItemLocator,
3786
3438
  spineLocator,
3787
3439
  cfiLocator,
@@ -3789,18 +3441,13 @@
3789
3441
  navigationAdjusted$,
3790
3442
  currentNavigationPosition$,
3791
3443
  viewportState$,
3792
- settings
3444
+ settings,
3445
+ hookManager
3793
3446
  }) => {
3794
3447
  const spineItems$ = new rxjs.Subject();
3795
3448
  const itemsBeforeDestroySubject$ = new rxjs.Subject();
3796
3449
  const subject = new rxjs.Subject();
3797
3450
  const containerElement$ = new rxjs.BehaviorSubject(noopElement$1);
3798
- const eventsHelper = createEventsHelper({
3799
- context,
3800
- spineItemManager,
3801
- iframeEventBridgeElement$,
3802
- locator: spineLocator
3803
- });
3804
3451
  let selectionSubscription;
3805
3452
  const reload = (manifest) => {
3806
3453
  itemsBeforeDestroySubject$.next();
@@ -3809,11 +3456,10 @@
3809
3456
  const spineItem = createSpineItem({
3810
3457
  item: resource,
3811
3458
  containerElement: containerElement$.getValue(),
3812
- iframeEventBridgeElement$,
3813
3459
  context,
3814
- hooks$,
3815
3460
  viewportState$,
3816
- settings
3461
+ settings,
3462
+ hookManager
3817
3463
  });
3818
3464
  spineItemManager.add(spineItem);
3819
3465
  });
@@ -3832,7 +3478,7 @@
3832
3478
  var _a;
3833
3479
  (_a = spineItemManager.get(id)) == null ? void 0 : _a.manipulateSpineItem(cb);
3834
3480
  };
3835
- context.$.manifest$.pipe(operators.tap(reload), operators.takeUntil(context.$.destroy$)).subscribe();
3481
+ context.manifest$.pipe(operators.tap(reload), operators.takeUntil(context.destroy$)).subscribe();
3836
3482
  const waitForViewportFree$ = viewportState$.pipe(
3837
3483
  operators.filter((v) => v === `free`),
3838
3484
  operators.take(1)
@@ -3924,7 +3570,7 @@
3924
3570
  Report.error(e);
3925
3571
  return rxjs.EMPTY;
3926
3572
  }),
3927
- operators.takeUntil(context.$.destroy$)
3573
+ operators.takeUntil(context.destroy$)
3928
3574
  )
3929
3575
  ).subscribe();
3930
3576
  const itemUpdateOnNavigation$ = navigation$.pipe(
@@ -3970,7 +3616,7 @@
3970
3616
  *
3971
3617
  * The cfi is later adjusted with heavy dom lookup once the viewport is free.
3972
3618
  */
3973
- cfi: (lastExpectedNavigation == null ? void 0 : lastExpectedNavigation.type) === `navigate-from-cfi` && spineItemToFocus === beginSpineItem ? lastExpectedNavigation.data : data.triggeredBy === `adjust` && settings.getSettings().computedPageTurnMode === `controlled` ? pagination.getPaginationInfo().beginCfi : beginItemIndex !== pagination.getPaginationInfo().beginSpineItemIndex ? cfiLocator.getRootCfi(beginSpineItem) : (
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) : (
3974
3620
  /* @todo check ? */
3975
3621
  cfiLocator.getRootCfi(beginSpineItem)
3976
3622
  ),
@@ -3982,7 +3628,7 @@
3982
3628
  spineItem: endSpineItem,
3983
3629
  spineItemIndex: endItemIndex,
3984
3630
  pageIndex: endPageIndex,
3985
- cfi: (lastExpectedNavigation == null ? void 0 : lastExpectedNavigation.type) === `navigate-from-cfi` && spineItemToFocus === endSpineItem ? lastExpectedNavigation.data : data.triggeredBy === `adjust` && settings.getSettings().computedPageTurnMode === `controlled` ? pagination.getPaginationInfo().endCfi : endItemIndex !== pagination.getPaginationInfo().endSpineItemIndex ? cfiLocator.getRootCfi(endSpineItem) : (
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) : (
3986
3632
  /* @todo check ? */
3987
3633
  cfiLocator.getRootCfi(endSpineItem)
3988
3634
  ),
@@ -4006,13 +3652,13 @@
4006
3652
  time2();
4007
3653
  }),
4008
3654
  operators.share(),
4009
- operators.takeUntil(context.$.destroy$)
3655
+ operators.takeUntil(context.destroy$)
4010
3656
  );
4011
3657
  itemUpdateOnNavigation$.pipe(
4012
3658
  operators.switchMap((data) => {
4013
3659
  return adjustPagination(data.position).pipe(operators.takeUntil(spineItemManager.$.layout$));
4014
3660
  }),
4015
- operators.takeUntil(context.$.destroy$)
3661
+ operators.takeUntil(context.destroy$)
4016
3662
  ).subscribe();
4017
3663
  rxjs.merge(
4018
3664
  /**
@@ -4046,7 +3692,7 @@
4046
3692
  operators.take(1)
4047
3693
  );
4048
3694
  }),
4049
- operators.takeUntil(context.$.destroy$)
3695
+ operators.takeUntil(context.destroy$)
4050
3696
  ).subscribe();
4051
3697
  const elementSub = element$.pipe().subscribe((element) => {
4052
3698
  const containerElement = createContainerElement(element.ownerDocument);
@@ -4058,7 +3704,6 @@
4058
3704
  locator: spineLocator,
4059
3705
  spineItemLocator,
4060
3706
  cfiLocator,
4061
- normalizeEventForViewport: eventsHelper.normalizeEventForViewport,
4062
3707
  manipulateSpineItems,
4063
3708
  manipulateSpineItem,
4064
3709
  destroy: () => {
@@ -4105,16 +3750,16 @@
4105
3750
  const orderedSpineItemsSubject$ = new rxjs.BehaviorSubject([]);
4106
3751
  let focusedSpineItemIndex;
4107
3752
  const layout = () => {
4108
- const manifest = context.getManifest();
3753
+ const manifest = context.manifest;
4109
3754
  const newItemLayoutInformation = [];
4110
3755
  const isGloballyPrePaginated = (manifest == null ? void 0 : manifest.renditionLayout) === `pre-paginated`;
4111
3756
  orderedSpineItemsSubject$.value.reduce(
4112
3757
  ({ horizontalOffset, verticalOffset }, item, index) => {
4113
3758
  let minimumWidth = context.getPageSize().width;
4114
3759
  let blankPagePosition = `none`;
4115
- const itemStartOnNewScreen = horizontalOffset % context.getVisibleAreaRect().width === 0;
3760
+ const itemStartOnNewScreen = horizontalOffset % context.state.visibleAreaRect.width === 0;
4116
3761
  const isLastItem = index === orderedSpineItemsSubject$.value.length - 1;
4117
- if (context.isUsingSpreadMode()) {
3762
+ if (context.state.isUsingSpreadMode) {
4118
3763
  if (!isGloballyPrePaginated && item.item.renditionLayout === `reflowable` && !isLastItem) {
4119
3764
  minimumWidth = context.getPageSize().width * 2;
4120
3765
  }
@@ -4140,10 +3785,10 @@
4140
3785
  const { width, height } = item.layout({
4141
3786
  minimumWidth,
4142
3787
  blankPagePosition,
4143
- 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`
4144
3789
  });
4145
- if (settings.getSettings().computedPageTurnDirection === `vertical`) {
4146
- const currentValidEdgeYForVerticalPositioning = itemStartOnNewScreen ? verticalOffset : verticalOffset - context.getVisibleAreaRect().height;
3790
+ if (settings.settings.computedPageTurnDirection === `vertical`) {
3791
+ const currentValidEdgeYForVerticalPositioning = itemStartOnNewScreen ? verticalOffset : verticalOffset - context.state.visibleAreaRect.height;
4147
3792
  const currentValidEdgeXForVerticalPositioning = itemStartOnNewScreen ? 0 : horizontalOffset;
4148
3793
  if (context.isRTL()) {
4149
3794
  item.adjustPositionOfElement({
@@ -4174,8 +3819,8 @@
4174
3819
  item.adjustPositionOfElement(context.isRTL() ? { right: horizontalOffset, top: 0 } : { left: horizontalOffset, top: 0 });
4175
3820
  newItemLayoutInformation.push({
4176
3821
  ...context.isRTL() ? {
4177
- left: context.getVisibleAreaRect().width - horizontalOffset - width,
4178
- right: context.getVisibleAreaRect().width - horizontalOffset
3822
+ left: context.state.visibleAreaRect.width - horizontalOffset - width,
3823
+ right: context.state.visibleAreaRect.width - horizontalOffset
4179
3824
  } : {
4180
3825
  left: horizontalOffset,
4181
3826
  right: horizontalOffset + width
@@ -4210,9 +3855,9 @@
4210
3855
  const loadContents = Report.measurePerformance(`loadContents`, 10, (rangeOfIndex) => {
4211
3856
  var _a;
4212
3857
  const [leftIndex, rightIndex] = rangeOfIndex;
4213
- const numberOfAdjacentSpineItemToPreLoad = settings.getSettings().numberOfAdjacentSpineItemToPreLoad;
4214
- const isPrePaginated = ((_a = context.getManifest()) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
4215
- const isUsingFreeScroll = settings.getSettings().computedPageTurnMode === `scrollable`;
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`;
4216
3861
  orderedSpineItemsSubject$.value.forEach((orderedSpineItem, index) => {
4217
3862
  const isBeforeFocusedWithPreload = (
4218
3863
  // we never want to preload anything before on free scroll on flow because it could offset the cursor
@@ -4260,18 +3905,22 @@
4260
3905
  };
4261
3906
  const add = (spineItem) => {
4262
3907
  orderedSpineItemsSubject$.value.push(spineItem);
4263
- spineItem.$.contentLayout$.pipe(operators.takeUntil(context.$.destroy$)).subscribe(() => {
3908
+ spineItem.$.contentLayout$.pipe(operators.takeUntil(context.destroy$)).subscribe(() => {
4264
3909
  layout();
4265
3910
  });
4266
3911
  spineItem.$.loaded$.pipe(
4267
3912
  operators.tap(() => {
4268
3913
  if (spineItem.isUsingVerticalWriting()) {
4269
- context.setHasVerticalWriting(true);
3914
+ context.update({
3915
+ hasVerticalWriting: true
3916
+ });
4270
3917
  } else {
4271
- context.setHasVerticalWriting(false);
3918
+ context.update({
3919
+ hasVerticalWriting: false
3920
+ });
4272
3921
  }
4273
3922
  }),
4274
- operators.takeUntil(context.$.destroy$)
3923
+ operators.takeUntil(context.destroy$)
4275
3924
  ).subscribe();
4276
3925
  spineItem.load();
4277
3926
  };
@@ -4316,7 +3965,154 @@
4316
3965
  })
4317
3966
  )
4318
3967
  }
4319
- };
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;
4320
4116
  };
4321
4117
  const createLocationResolver$1 = ({ context }) => {
4322
4118
  const getSafePosition = (unsafeSpineItemPosition, spineItem) => ({
@@ -4538,7 +4334,7 @@
4538
4334
  { disable: true }
4539
4335
  );
4540
4336
  const getAdjustedPositionForSpread = ({ x, y }) => {
4541
- const isOffsetNotAtEdge = x % context.getVisibleAreaRect().width !== 0;
4337
+ const isOffsetNotAtEdge = x % context.state.visibleAreaRect.width !== 0;
4542
4338
  const correctedX = isOffsetNotAtEdge ? x - context.getPageSize().width : x;
4543
4339
  return { x: correctedX, y };
4544
4340
  };
@@ -4577,7 +4373,7 @@
4577
4373
  return { x: 0, y: 0 };
4578
4374
  };
4579
4375
  const getNavigationForRightSinglePage = (position) => {
4580
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4376
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4581
4377
  const spineItem = locator.getSpineItemFromPosition(position) || spineItemManager.getFocusedSpineItem();
4582
4378
  const defaultNavigation = position;
4583
4379
  if (!spineItem) {
@@ -4596,7 +4392,7 @@
4596
4392
  }
4597
4393
  };
4598
4394
  const getNavigationForLeftSinglePage = (position) => {
4599
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4395
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4600
4396
  const spineItem = locator.getSpineItemFromPosition(position) || spineItemManager.getFocusedSpineItem();
4601
4397
  const defaultNavigation = { ...position, spineItem };
4602
4398
  if (!spineItem) {
@@ -4620,7 +4416,7 @@
4620
4416
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x === navigation.x) {
4621
4417
  return getAdjustedPositionForSpread(navigation);
4622
4418
  }
4623
- if (context.isUsingSpreadMode()) {
4419
+ if (context.state.isUsingSpreadMode) {
4624
4420
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x !== navigation.x) {
4625
4421
  return getAdjustedPositionForSpread(
4626
4422
  wrapPositionWithSafeEdge(
@@ -4634,7 +4430,7 @@
4634
4430
  )
4635
4431
  );
4636
4432
  }
4637
- if (settings.getSettings().computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4433
+ if (settings.settings.computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4638
4434
  return getAdjustedPositionForSpread(navigation);
4639
4435
  }
4640
4436
  const doubleNavigation = getNavigationForRightSinglePage(navigation);
@@ -4648,7 +4444,7 @@
4648
4444
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x === navigation.x) {
4649
4445
  return getAdjustedPositionForSpread(navigation);
4650
4446
  }
4651
- if (context.isUsingSpreadMode()) {
4447
+ if (context.state.isUsingSpreadMode) {
4652
4448
  if ((spineItemOnPosition == null ? void 0 : spineItemOnPosition.isUsingVerticalWriting()) && position.x !== navigation.x) {
4653
4449
  return getAdjustedPositionForSpread(
4654
4450
  wrapPositionWithSafeEdge(
@@ -4656,7 +4452,7 @@
4656
4452
  )
4657
4453
  );
4658
4454
  }
4659
- if (settings.getSettings().computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4455
+ if (settings.settings.computedPageTurnDirection === `vertical` && position.y !== navigation.y) {
4660
4456
  return getAdjustedPositionForSpread(navigation);
4661
4457
  }
4662
4458
  const doubleNavigation = getNavigationForLeftSinglePage(navigation);
@@ -4669,7 +4465,7 @@
4669
4465
  try {
4670
4466
  const validUrl = url instanceof URL ? url : new URL(url);
4671
4467
  const urlWithoutAnchor = `${validUrl.origin}${validUrl.pathname}`;
4672
- 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);
4673
4469
  if (existingSpineItem) {
4674
4470
  const spineItem = spineItemManager.get(existingSpineItem.id);
4675
4471
  if (spineItem) {
@@ -4698,15 +4494,15 @@
4698
4494
  return { x: 0, y: 0 };
4699
4495
  };
4700
4496
  const getMostPredominantNavigationForPosition = (viewportPosition) => {
4701
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4497
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4702
4498
  const triggerPercentage = 0.5;
4703
- const triggerXPosition = pageTurnDirection === `horizontal` ? viewportPosition.x + context.getVisibleAreaRect().width * triggerPercentage : 0;
4704
- const triggerYPosition = pageTurnDirection === `horizontal` ? 0 : viewportPosition.y + context.getVisibleAreaRect().height * triggerPercentage;
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;
4705
4501
  const midScreenPositionSafePosition = wrapPositionWithSafeEdge({ x: triggerXPosition, y: triggerYPosition });
4706
4502
  return getNavigationForPosition(midScreenPositionSafePosition);
4707
4503
  };
4708
4504
  const isNavigationGoingForwardFrom = (to, from) => {
4709
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4505
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
4710
4506
  if (pageTurnDirection === `vertical`) {
4711
4507
  return to.y > from.y;
4712
4508
  }
@@ -4750,14 +4546,14 @@
4750
4546
  );
4751
4547
  const adjustReadingOffset = ({ x, y }) => {
4752
4548
  var _a;
4753
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
4549
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
4754
4550
  lastScrollWasProgrammaticallyTriggered = true;
4755
4551
  (_a = element$.getValue()) == null ? void 0 : _a.scrollTo({ left: x, top: y });
4756
4552
  return true;
4757
4553
  }
4758
4554
  return false;
4759
4555
  };
4760
- const runOnFreePageTurnModeOnly$ = (source) => settings.$.settings$.pipe(
4556
+ const runOnFreePageTurnModeOnly$ = (source) => settings.settings$.pipe(
4761
4557
  operators.map(({ computedPageTurnMode }) => computedPageTurnMode),
4762
4558
  operators.distinctUntilChanged(),
4763
4559
  operators.switchMap((mode) => rxjs.iif(() => mode === `controlled`, rxjs.EMPTY, source))
@@ -4767,7 +4563,7 @@
4767
4563
  operators.filter(isDefined),
4768
4564
  operators.switchMap((element) => rxjs.fromEvent(element, `scroll`))
4769
4565
  )
4770
- ).pipe(onlyUserScrollFilter, operators.share(), operators.takeUntil(context.$.destroy$));
4566
+ ).pipe(onlyUserScrollFilter, operators.share(), operators.takeUntil(context.destroy$));
4771
4567
  const getScaledDownPosition = ({ x, y }) => {
4772
4568
  var _a, _b;
4773
4569
  const spineElement = spine.getElement();
@@ -4815,7 +4611,7 @@
4815
4611
  const userScrollEnd$ = userScroll$.pipe(
4816
4612
  operators.debounceTime(SCROLL_FINISHED_DEBOUNCE_TIMEOUT, rxjs.animationFrameScheduler),
4817
4613
  operators.share(),
4818
- operators.takeUntil(context.$.destroy$)
4614
+ operators.takeUntil(context.destroy$)
4819
4615
  );
4820
4616
  const state$ = rxjs.merge(
4821
4617
  userScroll$.pipe(
@@ -4908,7 +4704,7 @@
4908
4704
  operators.filter((e) => e.type === `pageIndex`),
4909
4705
  operators.filter(() => {
4910
4706
  var _a;
4911
- if (((_a = context.getManifest()) == null ? void 0 : _a.renditionLayout) === `reflowable`) {
4707
+ if (((_a = context.manifest) == null ? void 0 : _a.renditionLayout) === `reflowable`) {
4912
4708
  Report.warn(`This method only works for pre-paginated content`);
4913
4709
  return false;
4914
4710
  }
@@ -5042,11 +4838,11 @@
5042
4838
  `${NAMESPACE$1} moveTo`,
5043
4839
  5,
5044
4840
  (delta, { final, start } = {}) => {
5045
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
4841
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5046
4842
  Report.warn(`pan control is not available on free page turn mode`);
5047
4843
  return;
5048
4844
  }
5049
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4845
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
5050
4846
  if (start) {
5051
4847
  stateSubject$.next(`start`);
5052
4848
  movingLastDelta = { x: 0, y: 0 };
@@ -5106,7 +4902,7 @@
5106
4902
  );
5107
4903
  const snapNavigation$ = navigationTriggerSubject$.pipe(
5108
4904
  operators.filter((e) => e.type === `snap`),
5109
- rxjs.withLatestFrom(settings.$.settings$),
4905
+ rxjs.withLatestFrom(settings.settings$),
5110
4906
  operators.switchMap(
5111
4907
  ([
5112
4908
  {
@@ -5114,11 +4910,11 @@
5114
4910
  },
5115
4911
  { navigationSnapThreshold }
5116
4912
  ]) => {
5117
- const pageTurnDirection = settings.getSettings().computedPageTurnDirection;
4913
+ const pageTurnDirection = settings.settings.computedPageTurnDirection;
5118
4914
  const movingForward = navigator2.isNavigationGoingForwardFrom(to, from);
5119
4915
  const triggerPercentage = movingForward ? 1 - navigationSnapThreshold : navigationSnapThreshold;
5120
- const triggerXPosition = pageTurnDirection === `horizontal` ? to.x + context.getVisibleAreaRect().width * triggerPercentage : 0;
5121
- const triggerYPosition = pageTurnDirection === `horizontal` ? 0 : to.y + context.getVisibleAreaRect().height * triggerPercentage;
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;
5122
4918
  const midScreenPositionSafePosition = navigator2.wrapPositionWithSafeEdge({
5123
4919
  x: triggerXPosition,
5124
4920
  y: triggerYPosition
@@ -5155,7 +4951,7 @@
5155
4951
  parentElement$,
5156
4952
  cfiLocator,
5157
4953
  spineLocator,
5158
- hooks$,
4954
+ hookManager,
5159
4955
  spine,
5160
4956
  settings
5161
4957
  }) => {
@@ -5177,7 +4973,7 @@
5177
4973
  const adjustNavigationSubject$ = new rxjs.Subject();
5178
4974
  const getCurrentViewportPosition = Report.measurePerformance(`${NAMESPACE} getCurrentViewportPosition`, 1, () => {
5179
4975
  var _a;
5180
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
4976
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5181
4977
  return scrollViewportNavigator.getCurrentViewportPosition();
5182
4978
  }
5183
4979
  const { x, y } = ((_a = element$.getValue()) == null ? void 0 : _a.getBoundingClientRect()) ?? { x: 0, y: 0 };
@@ -5221,13 +5017,13 @@
5221
5017
  const viewportNavigatorsSharedState$ = rxjs.merge(...viewportNavigators.map(({ $: { state$: state$2 } }) => state$2));
5222
5018
  let lastUserExpectedNavigation;
5223
5019
  const makeItHot = (source$) => {
5224
- source$.pipe(operators.takeUntil(context.$.destroy$)).subscribe();
5020
+ source$.pipe(operators.takeUntil(context.destroy$)).subscribe();
5225
5021
  return source$;
5226
5022
  };
5227
5023
  const adjustReadingOffset = Report.measurePerformance(
5228
5024
  `adjustReadingOffset`,
5229
5025
  2,
5230
- ({ x, y }, hooks) => {
5026
+ ({ x, y }) => {
5231
5027
  const element = element$.getValue();
5232
5028
  if (!element)
5233
5029
  throw new Error("Invalid element");
@@ -5238,11 +5034,7 @@
5238
5034
  if (!isAdjusted) {
5239
5035
  element.style.transform = `translate3d(${-x}px, -${y}px, 0)`;
5240
5036
  }
5241
- hooks.forEach((hook) => {
5242
- if (hook.name === `onViewportOffsetAdjust`) {
5243
- hook.fn();
5244
- }
5245
- });
5037
+ hookManager.execute("onViewportOffsetAdjust", void 0, {});
5246
5038
  },
5247
5039
  { disable: true }
5248
5040
  );
@@ -5250,7 +5042,7 @@
5250
5042
  const lastCfi = pagination.getPaginationInfo().beginCfi;
5251
5043
  let adjustedSpinePosition = currentNavigationPositionSubject$.value;
5252
5044
  const offsetInSpineItem = 0;
5253
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
5045
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5254
5046
  adjustedSpinePosition = scrollViewportNavigator.getNavigationForPosition(getCurrentViewportPosition());
5255
5047
  } else if ((lastUserExpectedNavigation == null ? void 0 : lastUserExpectedNavigation.type) === `navigate-from-cfi`) {
5256
5048
  adjustedSpinePosition = navigator2.getNavigationForCfi(lastUserExpectedNavigation.data);
@@ -5295,7 +5087,7 @@
5295
5087
  layoutSubject$.subscribe(() => {
5296
5088
  currentViewportPositionMemoUnused = void 0;
5297
5089
  });
5298
- const layoutChangeSettings$ = settings.$.settings$.pipe(
5090
+ const layoutChangeSettings$ = settings.settings$.pipe(
5299
5091
  mapKeysTo([`computedPageTurnDirection`, `computedPageTurnMode`, `numberOfAdjacentSpineItemToPreLoad`]),
5300
5092
  operators.distinctUntilChanged(isShallowEqual),
5301
5093
  operators.skip(1)
@@ -5303,7 +5095,7 @@
5303
5095
  const layout$ = rxjs.merge(layoutSubject$, layoutChangeSettings$).pipe(
5304
5096
  operators.withLatestFrom(element$),
5305
5097
  operators.tap(([, element]) => {
5306
- if (settings.getSettings().computedPageTurnMode === `scrollable`) {
5098
+ if (settings.settings.computedPageTurnMode === `scrollable`) {
5307
5099
  element.style.removeProperty(`transform`);
5308
5100
  element.style.removeProperty(`transition`);
5309
5101
  element.style.overflow = `scroll`;
@@ -5355,11 +5147,11 @@
5355
5147
  return { ...event, lastUserExpectedNavigation };
5356
5148
  }),
5357
5149
  operators.share(),
5358
- operators.takeUntil(context.$.destroy$)
5150
+ operators.takeUntil(context.destroy$)
5359
5151
  );
5360
5152
  const navigationWhichRequireManualAdjust$ = navigation$.pipe(
5361
5153
  operators.filter(({ triggeredBy }) => {
5362
- if (triggeredBy === `scroll` || settings.getSettings().computedPageTurnMode === `scrollable` && triggeredBy === `adjust`) {
5154
+ if (triggeredBy === `scroll` || settings.settings.computedPageTurnMode === `scrollable` && triggeredBy === `adjust`) {
5363
5155
  return false;
5364
5156
  } else {
5365
5157
  return true;
@@ -5371,7 +5163,7 @@
5371
5163
  navigationWhichRequireManualAdjust$
5372
5164
  ).pipe(
5373
5165
  operators.map(({ animation, position }) => {
5374
- const shouldAnimate = !(!animation || animation === `turn` && settings.getSettings().computedPageTurnAnimation === `none`);
5166
+ const shouldAnimate = !(!animation || animation === `turn` && settings.settings.computedPageTurnAnimation === `none`);
5375
5167
  return {
5376
5168
  type: `manualAdjust`,
5377
5169
  shouldAnimate,
@@ -5393,8 +5185,8 @@
5393
5185
  operators.switchMap(([, currentEvent]) => {
5394
5186
  if ((currentEvent == null ? void 0 : currentEvent.type) !== `manualAdjust`)
5395
5187
  return rxjs.EMPTY;
5396
- const animationDuration = currentEvent.animation === `snap` ? settings.getSettings().computedSnapAnimationDuration : settings.getSettings().computedPageTurnAnimationDuration;
5397
- const pageTurnAnimation = currentEvent.animation === `snap` ? `slide` : settings.getSettings().computedPageTurnAnimation;
5188
+ const animationDuration = currentEvent.animation === `snap` ? settings.settings.computedSnapAnimationDuration : settings.settings.computedPageTurnAnimationDuration;
5189
+ const pageTurnAnimation = currentEvent.animation === `snap` ? `slide` : settings.settings.computedPageTurnAnimation;
5398
5190
  return rxjs.of(currentEvent).pipe(
5399
5191
  /**
5400
5192
  * @important
@@ -5428,23 +5220,22 @@
5428
5220
  * need to adjust to anchor to the payload position. This is because we use viewport computed position,
5429
5221
  * not the value set by `setProperty`
5430
5222
  */
5431
- operators.withLatestFrom(hooks$),
5432
- operators.tap(([data, hooks]) => {
5223
+ operators.tap((data) => {
5433
5224
  if (pageTurnAnimation !== `fade`) {
5434
- adjustReadingOffset(data.position, hooks);
5225
+ adjustReadingOffset(data.position);
5435
5226
  }
5436
5227
  }),
5437
5228
  currentEvent.shouldAnimate ? operators.delay(animationDuration / 2, rxjs.animationFrameScheduler) : rxjs.identity,
5438
- operators.tap(([data, hooks]) => {
5229
+ operators.tap((data) => {
5439
5230
  if (pageTurnAnimation === `fade`) {
5440
- adjustReadingOffset(data.position, hooks);
5231
+ adjustReadingOffset(data.position);
5441
5232
  element$.getValue().style.setProperty(`opacity`, `1`);
5442
5233
  }
5443
5234
  }),
5444
5235
  currentEvent.shouldAnimate ? operators.delay(animationDuration / 2, rxjs.animationFrameScheduler) : rxjs.identity,
5445
- operators.tap(([data, hooks]) => {
5236
+ operators.tap((data) => {
5446
5237
  if (pageTurnAnimation === `fade`) {
5447
- adjustReadingOffset(data.position, hooks);
5238
+ adjustReadingOffset(data.position);
5448
5239
  }
5449
5240
  }),
5450
5241
  operators.takeUntil(
@@ -5456,7 +5247,7 @@
5456
5247
  );
5457
5248
  }),
5458
5249
  operators.share(),
5459
- operators.takeUntil(context.$.destroy$)
5250
+ operators.takeUntil(context.destroy$)
5460
5251
  );
5461
5252
  const adjustmentState$ = rxjs.merge(
5462
5253
  rxjs.merge(manualAdjust$).pipe(operators.map(() => `start`)),
@@ -5511,7 +5302,7 @@
5511
5302
  operators.share()
5512
5303
  );
5513
5304
  const parentElementSub = parentElement$.pipe(operators.filter(isDefined), operators.withLatestFrom(spine.element$)).subscribe(([parentElement, spineElement]) => {
5514
- const element = createElement(parentElement.ownerDocument, hooks$);
5305
+ const element = createElement(parentElement.ownerDocument, hookManager);
5515
5306
  element.appendChild(spineElement);
5516
5307
  parentElement.appendChild(element);
5517
5308
  element$.next(element);
@@ -5547,19 +5338,15 @@
5547
5338
  }
5548
5339
  };
5549
5340
  };
5550
- const createElement = (doc, hooks$) => {
5341
+ const createElement = (doc, hookManager) => {
5551
5342
  const element = doc.createElement(`div`);
5552
5343
  element.style.cssText = `
5553
5344
  height: 100%;
5554
5345
  position: relative;
5555
5346
  `;
5556
5347
  element.className = `${HTML_PREFIX$1}-viewport-navigator`;
5557
- return hooks$.getValue().reduce((element2, hook) => {
5558
- if (hook.name === `viewportNavigator.onBeforeContainerCreated`) {
5559
- return hook.fn(element2);
5560
- }
5561
- return element2;
5562
- }, element);
5348
+ hookManager.execute("viewportNavigator.onBeforeContainerCreated", void 0, { element });
5349
+ return element;
5563
5350
  };
5564
5351
  const createLocationResolver = ({
5565
5352
  spineItemManager,
@@ -5600,7 +5387,7 @@
5600
5387
  const spineItem = spineItemManager.getAll().find((item) => {
5601
5388
  const { left, right, bottom, top } = spineItemManager.getAbsolutePositionOf(item);
5602
5389
  const isWithinXAxis = position.x >= left && position.x < right;
5603
- if (settings.getSettings().computedPageTurnDirection === `horizontal`) {
5390
+ if (settings.settings.computedPageTurnDirection === `horizontal`) {
5604
5391
  return isWithinXAxis;
5605
5392
  } else {
5606
5393
  return isWithinXAxis && position.y >= top && position.y < bottom;
@@ -5627,7 +5414,7 @@
5627
5414
  if (itemAtPositionIndex === void 0)
5628
5415
  return void 0;
5629
5416
  let endPosition = position;
5630
- if (context.isUsingSpreadMode()) {
5417
+ if (context.state.isUsingSpreadMode) {
5631
5418
  endPosition = { x: position.x + context.getPageSize().width, y: position.y };
5632
5419
  }
5633
5420
  const endItemIndex = spineItemManager.getSpineItemIndex(getSpineItemFromPosition(endPosition) || spineItemManager.getFocusedSpineItem()) ?? itemAtPositionIndex;
@@ -5748,80 +5535,170 @@
5748
5535
  generateFromRange
5749
5536
  };
5750
5537
  };
5751
- const areAllItemsPrePaginated = (manifest) => !(manifest == null ? void 0 : manifest.spineItems.some((item) => item.renditionLayout === `reflowable`));
5752
- const createSettings = (initialSettings) => {
5753
- const mergedSettings = {
5754
- forceSinglePageMode: false,
5755
- pageTurnAnimation: `none`,
5756
- computedPageTurnAnimation: `none`,
5757
- pageTurnDirection: `horizontal`,
5758
- computedPageTurnDirection: `horizontal`,
5759
- pageTurnAnimationDuration: void 0,
5760
- computedPageTurnAnimationDuration: 0,
5761
- pageTurnMode: `controlled`,
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,
5762
5544
  computedPageTurnMode: `controlled`,
5763
- computedSnapAnimationDuration: 300,
5764
- navigationSnapThreshold: 0.3,
5765
- numberOfAdjacentSpineItemToPreLoad: 0,
5766
- ...initialSettings
5767
- };
5768
- updateComputedSettings(void 0, mergedSettings, false);
5769
- const settingsSubject$ = new rxjs.BehaviorSubject(mergedSettings);
5770
- const setSettings = (newSettings, options) => {
5771
- if (Object.keys(newSettings).length === 0)
5772
- return;
5773
- const newMergedSettings = { ...settingsSubject$.value, ...newSettings };
5774
- updateComputedSettings(options.manifest, newMergedSettings, options.hasVerticalWriting ?? false);
5775
- settingsSubject$.next(newMergedSettings);
5776
- };
5777
- const recompute = (options) => {
5778
- const newMergedSettings = { ...settingsSubject$.value };
5779
- updateComputedSettings(options.manifest, newMergedSettings, options.hasVerticalWriting ?? false);
5780
- settingsSubject$.next(newMergedSettings);
5781
- };
5782
- const destroy = () => {
5783
- settingsSubject$.complete();
5784
- };
5785
- return {
5786
- getSettings: () => settingsSubject$.value,
5787
- setSettings,
5788
- recompute,
5789
- destroy,
5790
- $: {
5791
- settings$: settingsSubject$.asObservable().pipe(operators.distinctUntilChanged(isShallowEqual))
5792
- }
5545
+ computedPageTurnAnimationDuration: 0,
5546
+ computedSnapAnimationDuration: 0
5793
5547
  };
5794
- };
5795
- const updateComputedSettings = (newManifest, settings, hasVerticalWriting) => {
5796
- settings.computedPageTurnDirection = settings.pageTurnDirection;
5797
- settings.computedPageTurnAnimation = settings.pageTurnAnimation;
5798
- settings.computedPageTurnMode = `controlled`;
5799
- if ((newManifest == null ? void 0 : newManifest.renditionFlow) === `scrolled-continuous`) {
5800
- settings.computedPageTurnMode = `scrollable`;
5801
- settings.computedPageTurnDirection = `vertical`;
5802
- } else if (newManifest && settings.pageTurnMode === `scrollable` && (newManifest.renditionLayout !== `pre-paginated` || !areAllItemsPrePaginated(newManifest))) {
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))) {
5803
5552
  Report.warn(`pageTurnMode ${settings.pageTurnMode} incompatible with current book, switching back to default`);
5804
- settings.computedPageTurnAnimation = `none`;
5805
- settings.computedPageTurnMode = `controlled`;
5553
+ computedSettings.computedPageTurnAnimation = `none`;
5554
+ computedSettings.computedPageTurnMode = `controlled`;
5806
5555
  } else if (settings.pageTurnMode === `scrollable`) {
5807
- settings.computedPageTurnMode = `scrollable`;
5808
- settings.computedPageTurnDirection = `vertical`;
5556
+ computedSettings.computedPageTurnMode = `scrollable`;
5557
+ computedSettings.computedPageTurnDirection = `vertical`;
5809
5558
  }
5810
- if (hasVerticalWriting && settings.computedPageTurnAnimation === `slide`) {
5559
+ if (hasVerticalWriting && computedSettings.computedPageTurnAnimation === `slide`) {
5811
5560
  Report.warn(
5812
- `pageTurnAnimation ${settings.computedPageTurnAnimation} incompatible with current book, switching back to default`
5561
+ `pageTurnAnimation ${computedSettings.computedPageTurnAnimation} incompatible with current book, switching back to default`
5813
5562
  );
5814
- settings.computedPageTurnAnimation = `none`;
5563
+ computedSettings.computedPageTurnAnimation = `none`;
5815
5564
  }
5816
- if (settings.computedPageTurnMode === `scrollable`) {
5817
- settings.computedPageTurnAnimationDuration = 0;
5818
- settings.computedPageTurnAnimation = `none`;
5565
+ if (computedSettings.computedPageTurnMode === `scrollable`) {
5566
+ computedSettings.computedPageTurnAnimationDuration = 0;
5567
+ computedSettings.computedPageTurnAnimation = `none`;
5819
5568
  } else {
5820
- settings.computedPageTurnAnimationDuration = settings.pageTurnAnimationDuration !== void 0 ? settings.pageTurnAnimationDuration : 300;
5569
+ computedSettings.computedPageTurnAnimationDuration = settings.pageTurnAnimationDuration !== void 0 ? settings.pageTurnAnimationDuration : 300;
5821
5570
  }
5571
+ return computedSettings;
5822
5572
  };
5823
- const IFRAME_EVENT_BRIDGE_ELEMENT_ID = `proseReaderIframeEventBridgeElement`;
5824
- 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) => {
5825
5702
  const stateSubject$ = new rxjs.BehaviorSubject({
5826
5703
  supportedPageTurnAnimation: [`fade`, `none`, `slide`],
5827
5704
  supportedPageTurnMode: [`controlled`, `scrollable`],
@@ -5830,24 +5707,23 @@
5830
5707
  });
5831
5708
  const destroy$ = new rxjs.Subject();
5832
5709
  const selectionSubject$ = new rxjs.Subject();
5833
- const hooksSubject$ = new rxjs.BehaviorSubject(initialHooks || []);
5834
5710
  const navigationSubject = new rxjs.Subject();
5835
5711
  const navigationAdjustedSubject = new rxjs.Subject();
5836
5712
  const currentNavigationPositionSubject$ = new rxjs.BehaviorSubject({ x: 0, y: 0 });
5837
5713
  const viewportStateSubject = new rxjs.BehaviorSubject(`free`);
5838
- const settings = createSettings(inputSettings);
5839
- const context = createContext(settings);
5840
- 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 });
5841
5718
  const pagination = createPagination({ context, spineItemManager });
5842
5719
  const elementSubject$ = new rxjs.BehaviorSubject(void 0);
5843
5720
  const element$ = elementSubject$.pipe(operators.filter(isDefined));
5844
- const iframeEventBridgeElement$ = new rxjs.BehaviorSubject(void 0);
5845
5721
  const spineItemLocator = createLocationResolver$1({ context });
5846
5722
  const spineLocator = createLocationResolver({
5847
5723
  context,
5848
5724
  spineItemManager,
5849
5725
  spineItemLocator,
5850
- settings
5726
+ settings: settingsManager
5851
5727
  });
5852
5728
  const cfiLocator = createCfiLocator({
5853
5729
  spineItemManager,
@@ -5857,19 +5733,18 @@
5857
5733
  const navigation$ = navigationSubject.asObservable();
5858
5734
  const spine = createSpine({
5859
5735
  element$,
5860
- iframeEventBridgeElement$,
5861
5736
  context,
5862
- settings,
5737
+ settings: settingsManager,
5863
5738
  pagination,
5864
5739
  spineItemManager,
5865
- hooks$: hooksSubject$,
5866
5740
  navigation$,
5867
5741
  spineLocator,
5868
5742
  spineItemLocator,
5869
5743
  cfiLocator,
5870
5744
  navigationAdjusted$: navigationAdjustedSubject.asObservable(),
5871
5745
  viewportState$: viewportStateSubject.asObservable(),
5872
- currentNavigationPosition$: currentNavigationPositionSubject$.asObservable()
5746
+ currentNavigationPosition$: currentNavigationPositionSubject$.asObservable(),
5747
+ hookManager
5873
5748
  });
5874
5749
  const viewportNavigator = createViewportNavigator({
5875
5750
  context,
@@ -5878,9 +5753,9 @@
5878
5753
  parentElement$: elementSubject$,
5879
5754
  cfiLocator,
5880
5755
  spineLocator,
5881
- hooks$: hooksSubject$,
5756
+ hookManager,
5882
5757
  spine,
5883
- settings
5758
+ settings: settingsManager
5884
5759
  });
5885
5760
  viewportNavigator.$.state$.subscribe(viewportStateSubject);
5886
5761
  viewportNavigator.$.navigation$.subscribe(navigationSubject);
@@ -5906,30 +5781,29 @@
5906
5781
  element.style.height = `${dimensions.height - marginTop - marginBottom}px`;
5907
5782
  element.style.width = `${containerElementEvenWidth - 2 * margin}px`;
5908
5783
  const elementRect = element.getBoundingClientRect();
5909
- context.setVisibleAreaRect({
5910
- x: elementRect.x,
5911
- y: elementRect.y,
5912
- width: containerElementEvenWidth,
5913
- height: dimensions.height
5784
+ context.update({
5785
+ visibleAreaRect: {
5786
+ x: elementRect.x,
5787
+ y: elementRect.y,
5788
+ width: containerElementEvenWidth,
5789
+ height: dimensions.height
5790
+ }
5914
5791
  });
5915
5792
  viewportNavigator.layout();
5916
5793
  };
5917
5794
  const load = (manifest, loadOptions) => {
5918
5795
  var _a;
5919
- if (context.getManifest()) {
5796
+ if (context.manifest) {
5920
5797
  Report.warn(`loading a new book is not supported yet`);
5921
5798
  return;
5922
5799
  }
5923
5800
  Report.log(`load`, { manifest, loadOptions });
5924
5801
  const element = createWrapperElement(loadOptions.containerElement);
5925
- const iframeEventBridgeElement = createIframeEventBridgeElement(loadOptions.containerElement);
5926
5802
  if (loadOptions.containerElement !== ((_a = elementSubject$.getValue()) == null ? void 0 : _a.parentElement)) {
5927
5803
  elementSubject$.next(element);
5928
- iframeEventBridgeElement$.next(iframeEventBridgeElement);
5929
5804
  loadOptions.containerElement.appendChild(element);
5930
- element.appendChild(iframeEventBridgeElement);
5931
5805
  }
5932
- context.load(manifest, loadOptions);
5806
+ context.update({ manifest, ...loadOptions, forceSinglePageMode: settingsManager.settings.forceSinglePageMode });
5933
5807
  layout();
5934
5808
  if (!loadOptions.cfi) {
5935
5809
  viewportNavigator.goToSpineItem(0, { animate: false });
@@ -5937,9 +5811,6 @@
5937
5811
  viewportNavigator.goToCfi(loadOptions.cfi, { animate: false });
5938
5812
  }
5939
5813
  };
5940
- const registerHook = (name, fn) => {
5941
- hooksSubject$.next([...hooksSubject$.getValue(), { name, fn }]);
5942
- };
5943
5814
  spine.$.$.pipe(
5944
5815
  operators.tap((event) => {
5945
5816
  if (event.type === `onSelectionChange`) {
@@ -5952,18 +5823,18 @@
5952
5823
  rxjs.switchMap(({ adjustedSpinePosition }) => {
5953
5824
  return spine.adjustPagination(adjustedSpinePosition).pipe(operators.takeUntil(navigation$));
5954
5825
  }),
5955
- operators.takeUntil(context.$.destroy$)
5826
+ operators.takeUntil(context.destroy$)
5956
5827
  ).subscribe();
5957
- rxjs.merge(context.$.state$, settings.$.settings$).pipe(
5828
+ rxjs.merge(context.state$, settingsManager.settings$).pipe(
5958
5829
  operators.map(() => void 0),
5959
- operators.withLatestFrom(context.$.state$),
5830
+ operators.withLatestFrom(context.state$),
5960
5831
  operators.map(([, { hasVerticalWriting }]) => {
5961
- const manifest = context.getManifest();
5832
+ const manifest = context.manifest;
5962
5833
  return {
5963
5834
  hasVerticalWriting,
5964
5835
  renditionFlow: manifest == null ? void 0 : manifest.renditionFlow,
5965
5836
  renditionLayout: manifest == null ? void 0 : manifest.renditionLayout,
5966
- computedPageTurnMode: settings.getSettings().computedPageTurnMode
5837
+ computedPageTurnMode: settingsManager.settings.computedPageTurnMode
5967
5838
  };
5968
5839
  }),
5969
5840
  operators.distinctUntilChanged(isShallowEqual),
@@ -5971,7 +5842,7 @@
5971
5842
  ({ hasVerticalWriting, renditionFlow, renditionLayout, computedPageTurnMode }) => {
5972
5843
  return {
5973
5844
  ...stateSubject$.value,
5974
- supportedPageTurnMode: renditionFlow === `scrolled-continuous` ? [`scrollable`] : !context.areAllItemsPrePaginated() ? [`controlled`] : [`controlled`, `scrollable`],
5845
+ supportedPageTurnMode: renditionFlow === `scrolled-continuous` ? [`scrollable`] : !context.state.areAllItemsPrePaginated ? [`controlled`] : [`controlled`, `scrollable`],
5975
5846
  supportedPageTurnAnimation: renditionFlow === `scrolled-continuous` || computedPageTurnMode === `scrollable` ? [`none`] : hasVerticalWriting ? [`fade`, `none`] : [`fade`, `none`, `slide`],
5976
5847
  supportedPageTurnDirection: computedPageTurnMode === `scrollable` ? [`vertical`] : renditionLayout === `reflowable` ? [`horizontal`] : [`horizontal`, `vertical`]
5977
5848
  };
@@ -5980,16 +5851,13 @@
5980
5851
  operators.takeUntil(destroy$)
5981
5852
  ).subscribe(stateSubject$);
5982
5853
  const destroy = () => {
5983
- var _a, _b;
5984
- settings.destroy();
5985
- hooksSubject$.next([]);
5986
- hooksSubject$.complete();
5854
+ var _a;
5855
+ settingsManager.destroy();
5987
5856
  pagination.destroy();
5988
5857
  context.destroy();
5989
5858
  viewportNavigator.destroy();
5990
5859
  spine.destroy();
5991
5860
  (_a = elementSubject$.getValue()) == null ? void 0 : _a.remove();
5992
- (_b = iframeEventBridgeElement$.getValue()) == null ? void 0 : _b.remove();
5993
5861
  stateSubject$.complete();
5994
5862
  selectionSubject$.complete();
5995
5863
  destroy$.next();
@@ -5997,43 +5865,16 @@
5997
5865
  };
5998
5866
  const reader = {
5999
5867
  context,
6000
- registerHook,
6001
5868
  spine,
5869
+ hookManager,
6002
5870
  viewportNavigator,
6003
- manipulateSpineItems: spine.manipulateSpineItems,
6004
- manipulateSpineItem: spine.manipulateSpineItem,
6005
- moveTo: viewportNavigator.moveTo,
6006
- turnLeft: viewportNavigator.turnLeft,
6007
- turnRight: viewportNavigator.turnRight,
6008
- goToPageOfCurrentChapter: viewportNavigator.goToPageOfCurrentChapter,
6009
- goToPage: viewportNavigator.goToPage,
6010
- goToUrl: viewportNavigator.goToUrl,
6011
- goToCfi: viewportNavigator.goToCfi,
6012
- goToSpineItem: viewportNavigator.goToSpineItem,
6013
- getFocusedSpineItemIndex: spineItemManager.getFocusedSpineItemIndex,
6014
- getSpineItem: spineItemManager.get,
6015
- getSpineItems: spineItemManager.getAll,
6016
- getAbsolutePositionOf: spineItemManager.getAbsolutePositionOf,
6017
- getSelection: spine.getSelection,
6018
- isSelecting: spine.isSelecting,
6019
- normalizeEventForViewport: spine.normalizeEventForViewport,
6020
- getCfiMetaInformation: spine.cfiLocator.getCfiMetaInformation,
6021
- resolveCfi: spine.cfiLocator.resolveCfi,
6022
- generateCfi: spine.cfiLocator.generateFromRange,
6023
- locator: spine.locator,
6024
- getCurrentNavigationPosition: viewportNavigator.getCurrentNavigationPosition,
6025
- getCurrentViewportPosition: viewportNavigator.getCurrentViewportPosition,
5871
+ spineItemManager,
6026
5872
  layout,
6027
5873
  load,
6028
5874
  destroy,
6029
- spineItems$: spine.$.spineItems$,
6030
- context$: context.$.state$,
6031
5875
  pagination,
6032
- settings: {
6033
- settings$: settings.$.settings$,
6034
- getSettings: settings.getSettings,
6035
- setSettings: (data) => settings.setSettings(data, context.getState())
6036
- },
5876
+ settings: settingsManager,
5877
+ element$,
6037
5878
  $: {
6038
5879
  state$: stateSubject$.asObservable(),
6039
5880
  /**
@@ -6042,21 +5883,12 @@
6042
5883
  * have an effect.
6043
5884
  * It can typically be used to hide a loading indicator.
6044
5885
  */
6045
- loadStatus$: context.$.manifest$.pipe(operators.map((manifest) => manifest ? "ready" : "idle")),
5886
+ loadStatus$: context.manifest$.pipe(operators.map((manifest) => manifest ? "ready" : "idle")),
6046
5887
  /**
6047
5888
  * Dispatched when a change in selection happens
6048
5889
  */
6049
5890
  selection$: selectionSubject$.asObservable(),
6050
- viewportState$: viewportNavigator.$.state$,
6051
- layout$: spine.$.layout$,
6052
- itemsBeforeDestroy$: spine.$.itemsBeforeDestroy$,
6053
- itemIsReady$: spineItemManager.$.itemIsReady$,
6054
5891
  destroy$
6055
- },
6056
- __debug: {
6057
- pagination,
6058
- context,
6059
- spineItemManager
6060
5892
  }
6061
5893
  };
6062
5894
  return reader;
@@ -6070,19 +5902,6 @@
6070
5902
  element.className = `${HTML_PREFIX$1}-reader`;
6071
5903
  return element;
6072
5904
  };
6073
- const createIframeEventBridgeElement = (containerElement) => {
6074
- const iframeEventBridgeElement = containerElement.ownerDocument.createElement(`div`);
6075
- iframeEventBridgeElement.id = IFRAME_EVENT_BRIDGE_ELEMENT_ID;
6076
- iframeEventBridgeElement.style.cssText = `
6077
- position: absolute;
6078
- height: 100%;
6079
- width: 100%;
6080
- top: 0;
6081
- left: 0;
6082
- z-index: -1;
6083
- `;
6084
- return iframeEventBridgeElement;
6085
- };
6086
5905
  const utilsEnhancer = (next) => (options) => {
6087
5906
  const reader = next(options);
6088
5907
  const isOrIsWithinValidLink = (target) => {
@@ -6207,9 +6026,9 @@
6207
6026
  var _a, _b;
6208
6027
  if (typeof itemIndexOrId === `string` || typeof itemIndexOrId === `object`) {
6209
6028
  const id = typeof itemIndexOrId === `object` ? itemIndexOrId.id : void 0;
6210
- 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);
6211
6030
  } else {
6212
- return (_b = context.getManifest()) == null ? void 0 : _b.spineItems[itemIndexOrId];
6031
+ return (_b = context.manifest) == null ? void 0 : _b.spineItems[itemIndexOrId];
6213
6032
  }
6214
6033
  };
6215
6034
  const get = async (itemIndexOrId, fetchResource) => {
@@ -6243,9 +6062,9 @@
6243
6062
  })
6244
6063
  );
6245
6064
  }),
6246
- operators.takeUntil(context.$.destroy$)
6065
+ operators.takeUntil(context.destroy$)
6247
6066
  ).subscribe();
6248
- const onLoad$ = context.$.manifest$.pipe(
6067
+ const onLoad$ = context.manifest$.pipe(
6249
6068
  operators.tap(() => {
6250
6069
  uniqueID = Date.now().toString();
6251
6070
  })
@@ -6269,7 +6088,7 @@
6269
6088
  })
6270
6089
  );
6271
6090
  }),
6272
- operators.takeUntil(context.$.destroy$)
6091
+ operators.takeUntil(context.destroy$)
6273
6092
  ).subscribe();
6274
6093
  const destroy = () => {
6275
6094
  cache$.complete();
@@ -6282,14 +6101,6 @@
6282
6101
  const resourcesEnhancer = (next) => (options) => {
6283
6102
  const reader = next(options);
6284
6103
  const resourceManager = createResourcesManager(reader.context);
6285
- const load = (manifest, loadOptions) => {
6286
- reader.load(manifest, {
6287
- ...loadOptions
6288
- });
6289
- };
6290
- reader.registerHook(`item.onGetResource`, (fetcher) => async (item) => {
6291
- return resourceManager.get(item, fetcher);
6292
- });
6293
6104
  const destroy = () => {
6294
6105
  resourceManager.destroy();
6295
6106
  reader.destroy();
@@ -6300,8 +6111,8 @@
6300
6111
  // ...reader.$,
6301
6112
  // errors$: merge(reader.$.errors$, errorsSubject$.asObservable())
6302
6113
  // },
6303
- destroy,
6304
- load
6114
+ destroy
6115
+ // load,
6305
6116
  };
6306
6117
  };
6307
6118
  const mediaEnhancer = (next) => (options) => {
@@ -6352,7 +6163,7 @@
6352
6163
  threshold: 0.5
6353
6164
  }
6354
6165
  );
6355
- reader.registerHook(`item.onLoad`, ({ frame }) => {
6166
+ reader.hookManager.register(`item.onLoad`, ({ frame, destroy: destroy2 }) => {
6356
6167
  var _a;
6357
6168
  frameObserver.observe(frame);
6358
6169
  const videos = (_a = frame.contentDocument) == null ? void 0 : _a.body.getElementsByTagName(`video`);
@@ -6360,10 +6171,10 @@
6360
6171
  elementObserver.observe(element);
6361
6172
  return () => elementObserver.unobserve(element);
6362
6173
  });
6363
- return () => {
6174
+ destroy2(() => {
6364
6175
  frameObserver.unobserve(frame);
6365
6176
  unobserveElements.forEach((unobserve) => unobserve());
6366
- };
6177
+ });
6367
6178
  });
6368
6179
  const destroy = () => {
6369
6180
  frameObserver.disconnect();
@@ -6379,16 +6190,16 @@
6379
6190
  const reader = next(options);
6380
6191
  const getPercentageEstimate = (context, currentSpineIndex, numberOfPages, pageIndex, currentPosition, currentItem) => {
6381
6192
  var _a, _b, _c, _d, _e, _f;
6382
- const isGloballyPrePaginated = ((_a = context.getManifest()) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
6383
- const readingOrderLength = ((_b = context.getManifest()) == null ? void 0 : _b.spineItems.length) || 0;
6384
- const estimateBeforeThisItem = ((_c = context.getManifest()) == null ? void 0 : _c.spineItems.slice(0, currentSpineIndex).reduce((acc, item) => acc + item.progressionWeight, 0)) || 0;
6385
- const currentItemWeight = ((_e = (_d = context.getManifest()) == null ? void 0 : _d.spineItems[currentSpineIndex]) == null ? void 0 : _e.progressionWeight) || 0;
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;
6386
6197
  let progressWithinThisItem = (pageIndex + 1) * (currentItemWeight / numberOfPages);
6387
6198
  if (!isGloballyPrePaginated && currentItem.item.renditionLayout === `reflowable` && !currentItem.isReady()) {
6388
6199
  progressWithinThisItem = 0;
6389
6200
  }
6390
6201
  let totalProgress = estimateBeforeThisItem + progressWithinThisItem;
6391
- if (((_f = context.getManifest()) == null ? void 0 : _f.renditionFlow) === `scrolled-continuous`) {
6202
+ if (((_f = context.manifest) == null ? void 0 : _f.renditionFlow) === `scrolled-continuous`) {
6392
6203
  if (currentItem.isReady()) {
6393
6204
  progressWithinThisItem = getScrollPercentageWithinItem(context, currentPosition, currentItem);
6394
6205
  } else {
@@ -6406,11 +6217,11 @@
6406
6217
  };
6407
6218
  const getScrollPercentageWithinItem = (context, currentPosition, currentItem) => {
6408
6219
  const { height, width } = currentItem.getElementDimensions();
6409
- const { top, left } = reader.getAbsolutePositionOf(currentItem);
6410
- if (reader.settings.getSettings().computedPageTurnDirection === `vertical`) {
6411
- return Math.max(0, Math.min(1, (currentPosition.y - top + context.getVisibleAreaRect().height) / height));
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));
6412
6223
  } else {
6413
- 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));
6414
6225
  }
6415
6226
  };
6416
6227
  return {
@@ -6432,67 +6243,59 @@
6432
6243
  }
6433
6244
  });
6434
6245
  }, {});
6435
- reader.registerHook(`item.onLoad`, ({ addStyle, frame }) => {
6246
+ reader.hookManager.register(`item.onLoad`, ({ itemId, frame, destroy }) => {
6436
6247
  var _a;
6437
- addStyle(
6438
- `prose-reader-accessibility`,
6439
- `
6440
- :focus-visible {
6441
- ${/*
6442
- Some epubs remove the outline, this is not good practice since it reduce accessibility.
6443
- We will try to restore it by force.
6444
- */
6445
- ``}
6446
- outline: -webkit-focus-ring-color auto 1px;
6447
- }
6448
- `
6449
- );
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
+ });
6450
6267
  const links = (_a = frame.contentDocument) == null ? void 0 : _a.body.querySelectorAll(`a`);
6451
6268
  links == null ? void 0 : links.forEach((link) => {
6452
6269
  observer.observe(link);
6453
6270
  });
6454
- return () => {
6271
+ destroy(() => {
6455
6272
  links == null ? void 0 : links.forEach((link) => {
6456
6273
  observer.unobserve(link);
6457
6274
  });
6458
- };
6275
+ });
6459
6276
  });
6460
6277
  return {
6461
6278
  ...reader
6462
6279
  };
6463
6280
  };
6464
6281
  const IS_SAFARI = navigator.userAgent.indexOf(``) > -1 && navigator.userAgent.indexOf(`Chrome`) <= -1;
6465
- const webkitEnhancer = (next) => (options) => {
6466
- const transformFlickerFixHooks = [
6467
- {
6468
- name: `viewportNavigator.onBeforeContainerCreated`,
6469
- fn: (element) => {
6470
- element.style.cssText = `
6471
- ${element.style.cssText}
6472
- -webkit-transform-style: preserve-3d;
6473
- `;
6474
- return element;
6475
- }
6476
- },
6477
- {
6478
- name: `item.onBeforeContainerCreated`,
6479
- fn: (element) => {
6480
- 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 = `
6481
6287
  ${element.style.cssText}
6482
6288
  -webkit-transform-style: preserve-3d;
6483
- -webkit-backface-visibility: hidden;
6484
6289
  `;
6485
- return element;
6486
- }
6487
- }
6488
- ];
6489
- const existingHooks = options.hooks || [];
6490
- const reader = next({
6491
- ...options,
6492
- ...IS_SAFARI && {
6493
- hooks: [...existingHooks, ...transformFlickerFixHooks]
6494
- }
6495
- });
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
+ }
6496
6299
  return reader;
6497
6300
  };
6498
6301
  const HTML_PREFIX = `${HTML_PREFIX$1}-enhancer-loading`;
@@ -6513,9 +6316,9 @@
6513
6316
  };
6514
6317
  }, {})
6515
6318
  );
6516
- const updateEntriesLayout$ = (entries) => rxjs.combineLatest([reader.$.layout$, reader.theme.$.theme$]).pipe(
6319
+ const updateEntriesLayout$ = (entries) => rxjs.combineLatest([reader.spine.$.layout$, reader.theme.$.theme$]).pipe(
6517
6320
  operators.map(([, theme]) => ({
6518
- width: reader.context.getVisibleAreaRect().width,
6321
+ width: reader.context.state.visibleAreaRect.width,
6519
6322
  theme
6520
6323
  })),
6521
6324
  operators.distinctUntilChanged(isShallowEqual),
@@ -6526,22 +6329,22 @@
6526
6329
  });
6527
6330
  })
6528
6331
  );
6529
- const updateEntriesVisibility$ = (entries) => reader.$.itemIsReady$.pipe(
6332
+ const updateEntriesVisibility$ = (entries) => reader.spineItemManager.$.itemIsReady$.pipe(
6530
6333
  operators.tap(({ item, isReady }) => {
6531
6334
  var _a;
6532
6335
  (_a = entries[item.id]) == null ? void 0 : _a.style.setProperty(`visibility`, isReady ? `hidden` : `visible`);
6533
6336
  })
6534
6337
  );
6535
- const destroyEntries$ = (entries) => reader.$.itemsBeforeDestroy$.pipe(
6338
+ const destroyEntries$ = (entries) => reader.spine.$.itemsBeforeDestroy$.pipe(
6536
6339
  operators.map(() => {
6537
6340
  Object.values(entries).forEach((element) => element.remove());
6538
6341
  return {};
6539
6342
  })
6540
6343
  );
6541
- const items$ = reader.spineItems$.pipe(
6344
+ const items$ = reader.spine.$.spineItems$.pipe(
6542
6345
  operators.switchMap((items) => createEntries$(items)),
6543
6346
  operators.shareReplay(1),
6544
- operators.takeUntil(reader.context.$.destroy$)
6347
+ operators.takeUntil(reader.context.destroy$)
6545
6348
  );
6546
6349
  items$.pipe(
6547
6350
  operators.switchMap((entries) => rxjs.merge(rxjs.of(entries), destroyEntries$(entries))),
@@ -6563,7 +6366,7 @@
6563
6366
  loadingElement.style.cssText = `
6564
6367
  height: 100%;
6565
6368
  width: 100%;
6566
- max-width: ${context.getVisibleAreaRect().width}px;
6369
+ max-width: ${context.state.visibleAreaRect.width}px;
6567
6370
  text-align: center;
6568
6371
  display: flex;
6569
6372
  justify-content: center;
@@ -6603,6 +6406,155 @@
6603
6406
  return reader;
6604
6407
  };
6605
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
+ };
6606
6558
  const createReaderWithEnhancers = (
6607
6559
  //__
6608
6560
  publicApiEnhancer(
@@ -6622,8 +6574,10 @@
6622
6574
  hotkeysEnhancer(
6623
6575
  paginationEnhancer(
6624
6576
  progressionEnhancer(
6625
- // __
6626
- createReader
6577
+ eventsEnhancer(
6578
+ // __
6579
+ createReader
6580
+ )
6627
6581
  )
6628
6582
  )
6629
6583
  )