@prose-reader/core 1.193.0 → 1.195.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { switchMap, of, fromEvent, take, map, from, takeUntil, Observable, defer, Subject, combineLatest, merge, EMPTY, withLatestFrom, BehaviorSubject, filter, share, first as first$1, mergeMap, endWith, tap as tap$1, finalize, catchError, lastValueFrom, NEVER, scheduled, animationFrameScheduler, distinctUntilChanged as distinctUntilChanged$1, throttleTime, debounceTime as debounceTime$1, startWith as startWith$1, switchScan, forkJoin, shareReplay as shareReplay$1, delay, ReplaySubject, identity, timer, skip as skip$1, exhaustMap, reduce, concatMap } from "rxjs";
1
+ import { switchMap, of, fromEvent, take, map, from, takeUntil, Observable, defer, Subject, combineLatest, merge, EMPTY, withLatestFrom, NEVER, tap as tap$1, share, BehaviorSubject, filter, first as first$1, mergeMap, endWith, finalize, catchError, lastValueFrom, scheduled, animationFrameScheduler, distinctUntilChanged as distinctUntilChanged$1, throttleTime, debounceTime as debounceTime$1, startWith as startWith$1, switchScan, forkJoin, shareReplay as shareReplay$1, delay, ReplaySubject, identity, timer, skip as skip$1, exhaustMap, reduce, concatMap } from "rxjs";
2
2
  import { switchMap as switchMap$1, first, map as map$1, startWith, shareReplay, distinctUntilChanged, tap, pairwise, take as take$1, takeUntil as takeUntil$1, filter as filter$1, debounceTime, skip, mergeMap as mergeMap$1, catchError as catchError$1, withLatestFrom as withLatestFrom$1 } from "rxjs/operators";
3
3
  import { shallowMergeIfDefined, isShallowEqual, getParentPath, parseContentType, detectMimeTypeFromName, arrayEqual } from "@prose-reader/shared";
4
4
  import { isShallowEqual as isShallowEqual2 } from "@prose-reader/shared";
@@ -458,6 +458,9 @@ const revokeDocumentBlobs = (_document) => {
458
458
  }
459
459
  }
460
460
  };
461
+ function isHtmlTagElement(element, tagName) {
462
+ return isHtmlElement(element) && element.tagName.toLowerCase() === tagName.toLowerCase();
463
+ }
461
464
  const translateFramePositionIntoPage = ({
462
465
  position,
463
466
  frameElement
@@ -885,6 +888,33 @@ const hotkeysEnhancer = (next) => (options) => {
885
888
  ).subscribe();
886
889
  return reader;
887
890
  };
891
+ const handleLinks = (reader) => {
892
+ return reader.spine.spineItemsManager.items$.pipe(
893
+ switchMap(
894
+ (items) => merge(
895
+ ...items.map((item) => {
896
+ return item.loaded$.pipe(
897
+ switchMap(() => {
898
+ const frame = item.renderer.getDocumentFrame();
899
+ if (!frame || !(frame == null ? void 0 : frame.contentDocument)) return NEVER;
900
+ const anchorElements = Array.from(
901
+ frame.contentDocument.querySelectorAll(`a`)
902
+ );
903
+ const events$ = anchorElements.map(
904
+ (element) => fromEvent(element, `click`)
905
+ );
906
+ return merge(...events$);
907
+ })
908
+ );
909
+ })
910
+ )
911
+ ),
912
+ tap$1((event) => {
913
+ event.preventDefault();
914
+ }),
915
+ share()
916
+ );
917
+ };
888
918
  class DestroyableClass {
889
919
  constructor() {
890
920
  this.isDestroyed = false;
@@ -1997,7 +2027,12 @@ const htmlEnhancer = (next) => (options) => {
1997
2027
  return maybeFactory ?? ((props) => new HtmlRenderer(props));
1998
2028
  }
1999
2029
  });
2000
- return reader;
2030
+ const links$ = handleLinks(reader);
2031
+ links$.pipe(takeUntil(reader.$.destroy$)).subscribe();
2032
+ return {
2033
+ ...reader,
2034
+ links$
2035
+ };
2001
2036
  };
2002
2037
  function isDefined(arg) {
2003
2038
  return arg !== null && arg !== void 0;
@@ -2255,52 +2290,6 @@ const layoutEnhancer = (next) => (options) => {
2255
2290
  settings: settingsManager
2256
2291
  };
2257
2292
  };
2258
- const linksEnhancer = (next) => (options) => {
2259
- const reader = next(options);
2260
- const subject = new Subject();
2261
- const handleNavigationForClick = (element) => {
2262
- var _a;
2263
- if (!element.href) return false;
2264
- const hrefUrl = new URL(element.href);
2265
- const hrefWithoutAnchor = `${hrefUrl.origin}${hrefUrl.pathname}`;
2266
- const hasExistingSpineItem = (_a = reader.context.manifest) == null ? void 0 : _a.spineItems.some(
2267
- (item) => item.href === hrefWithoutAnchor
2268
- );
2269
- if (hasExistingSpineItem) {
2270
- reader.navigation.goToUrl(hrefUrl);
2271
- return true;
2272
- }
2273
- return false;
2274
- };
2275
- reader.hookManager.register(`item.onDocumentLoad`, ({ itemId }) => {
2276
- const item = reader.spineItemsManager.get(itemId);
2277
- const frame = item == null ? void 0 : item.renderer.getDocumentFrame();
2278
- if (!frame) return;
2279
- if (frame == null ? void 0 : frame.contentDocument) {
2280
- Array.from(frame.contentDocument.querySelectorAll(`a`)).forEach(
2281
- (element) => element.addEventListener(`click`, (e) => {
2282
- if (e.target && `style` in e.target && `ELEMENT_NODE` in e.target) {
2283
- Report.warn(`prevented click on`, element, e);
2284
- e.preventDefault();
2285
- const isNavigable = handleNavigationForClick(element);
2286
- subject.next({
2287
- event: `linkClicked`,
2288
- data: element,
2289
- isNavigable
2290
- });
2291
- }
2292
- })
2293
- );
2294
- }
2295
- });
2296
- return {
2297
- ...reader,
2298
- $: {
2299
- ...reader.$,
2300
- links$: subject.asObservable()
2301
- }
2302
- };
2303
- };
2304
2293
  const HTML_PREFIX = `${HTML_PREFIX$1}-enhancer-loading`;
2305
2294
  const CONTAINER_HTML_PREFIX = `${HTML_PREFIX}-container`;
2306
2295
  const createLoadingElementContainer = (containerElement, context) => {
@@ -2588,6 +2577,22 @@ const mediaEnhancer = (next) => (options) => {
2588
2577
  destroy
2589
2578
  };
2590
2579
  };
2580
+ const handleLinksNavigation = (reader, manualNavigator) => {
2581
+ return reader.links$.pipe(
2582
+ tap$1((event) => {
2583
+ var _a;
2584
+ if (!isHtmlTagElement(event.target, "a") || event.type !== "click") return;
2585
+ const hrefUrl = new URL(event.target.href);
2586
+ const hrefWithoutAnchor = `${hrefUrl.origin}${hrefUrl.pathname}`;
2587
+ const hasExistingSpineItem = (_a = reader.context.manifest) == null ? void 0 : _a.spineItems.some(
2588
+ (item) => item.href === hrefWithoutAnchor
2589
+ );
2590
+ if (hasExistingSpineItem) {
2591
+ manualNavigator.goToUrl(hrefUrl);
2592
+ }
2593
+ })
2594
+ );
2595
+ };
2591
2596
  const report$4 = Report.namespace(`navigation`);
2592
2597
  const getSpineItemPositionForLeftPage = ({
2593
2598
  position,
@@ -3121,6 +3126,8 @@ const navigationEnhancer = (next) => (options) => {
3121
3126
  manualNavigator.goToCfi(cfi, { animate: false });
3122
3127
  }
3123
3128
  };
3129
+ const linksNavigation$ = handleLinksNavigation(reader, manualNavigator);
3130
+ linksNavigation$.pipe(takeUntil(reader.$.destroy$)).subscribe();
3124
3131
  return {
3125
3132
  ...reader,
3126
3133
  load,
@@ -3301,7 +3308,7 @@ const getTotalProgressFromPercentages = (estimateBeforeThisItem, currentItemWeig
3301
3308
  };
3302
3309
  const getScrollPercentageWithinItem = (reader, currentPosition, currentItem) => {
3303
3310
  const context = reader.context;
3304
- const { height, width } = currentItem.getElementDimensions();
3311
+ const { height, width } = currentItem.layoutPosition;
3305
3312
  const { top, left } = reader.spine.spineLayout.getAbsolutePositionOf(currentItem);
3306
3313
  if (reader.settings.values.computedPageTurnDirection === `vertical`) {
3307
3314
  return Math.max(
@@ -3365,7 +3372,7 @@ const getPercentageEstimate = (reader, currentSpineIndex, pageIndex, currentPosi
3365
3372
  );
3366
3373
  };
3367
3374
  const getNumberOfPagesForAllSpineItems = (reader) => reader.spineItemsManager.items.map((item) => {
3368
- const { height, width } = item.getElementDimensions();
3375
+ const { height, width } = item.layoutPosition;
3369
3376
  return reader.spine.spineItemLocator.getSpineItemNumberOfPages({
3370
3377
  isUsingVerticalWriting: !!item.isUsingVerticalWriting(),
3371
3378
  itemHeight: height,
@@ -5565,7 +5572,7 @@ const createSpineItemLocator = ({
5565
5572
  const range = node ? getRangeFromNode(node, offset) : void 0;
5566
5573
  offsetOfNodeInSpineItem = (range == null ? void 0 : range.getBoundingClientRect().x) || offsetOfNodeInSpineItem;
5567
5574
  }
5568
- const spineItemWidth = ((_a = spineItem.getElementDimensions()) == null ? void 0 : _a.width) || 0;
5575
+ const spineItemWidth = ((_a = spineItem.layoutPosition) == null ? void 0 : _a.width) || 0;
5569
5576
  const pageWidth = context.getPageSize().width;
5570
5577
  if (offsetOfNodeInSpineItem !== void 0) {
5571
5578
  const val = getClosestValidOffsetFromApproximateOffsetInPages(
@@ -5585,7 +5592,7 @@ const createSpineItemLocator = ({
5585
5592
  frame.contentWindow.document.body !== null) {
5586
5593
  const { x: left, y: top } = getSpineItemPositionFromPageIndex({
5587
5594
  pageIndex,
5588
- itemLayout: spineItem.getElementDimensions(),
5595
+ itemLayout: spineItem.layoutPosition,
5589
5596
  context,
5590
5597
  isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting()
5591
5598
  });
@@ -5604,7 +5611,7 @@ const createSpineItemLocator = ({
5604
5611
  return void 0;
5605
5612
  };
5606
5613
  const getSpineItemClosestPositionFromUnsafePosition = (unsafePosition, spineItem) => {
5607
- const { width, height } = spineItem.getElementDimensions();
5614
+ const { width, height } = spineItem.layoutPosition;
5608
5615
  const adjustedPosition = {
5609
5616
  x: getClosestValidOffsetFromApproximateOffsetInPages(
5610
5617
  unsafePosition.x,
@@ -5621,7 +5628,7 @@ const createSpineItemLocator = ({
5621
5628
  };
5622
5629
  const getSpineItemPageIndexFromNode = (node, offset, spineItem) => {
5623
5630
  const position = getSpineItemPositionFromNode(node, offset, spineItem);
5624
- const { height, width } = spineItem.getElementDimensions();
5631
+ const { height, width } = spineItem.layoutPosition;
5625
5632
  return position ? getSpineItemPageIndexFromPosition({
5626
5633
  isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
5627
5634
  position,
@@ -5659,7 +5666,7 @@ const createSpineItemLocator = ({
5659
5666
  context,
5660
5667
  isUsingVerticalWriting: !!item.isUsingVerticalWriting(),
5661
5668
  settings,
5662
- itemLayout: item.getElementDimensions()
5669
+ itemLayout: item.layoutPosition
5663
5670
  });
5664
5671
  },
5665
5672
  getSpineItemNumberOfPages: (params) => getSpineItemNumberOfPages({
@@ -5675,7 +5682,7 @@ const createNavigationResolver$1 = ({
5675
5682
  }) => {
5676
5683
  const spineItemLocator = createSpineItemLocator({ context, settings });
5677
5684
  const getNavigationForLastPage = (spineItem) => {
5678
- const { height, width } = spineItem.getElementDimensions();
5685
+ const { height, width } = spineItem.layoutPosition;
5679
5686
  const numberOfPages = spineItemLocator.getSpineItemNumberOfPages({
5680
5687
  isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
5681
5688
  itemHeight: height,
@@ -5684,7 +5691,7 @@ const createNavigationResolver$1 = ({
5684
5691
  return spineItemLocator.getSpineItemPositionFromPageIndex({
5685
5692
  pageIndex: numberOfPages - 1,
5686
5693
  isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
5687
- itemLayout: spineItem.getElementDimensions()
5694
+ itemLayout: spineItem.layoutPosition
5688
5695
  });
5689
5696
  };
5690
5697
  const getNavigationFromNode = (spineItem, node, offset) => {
@@ -5751,7 +5758,7 @@ const getSpineItemOffsetFromAnchor = ({
5751
5758
  context
5752
5759
  }) => {
5753
5760
  var _a;
5754
- const itemWidth = ((_a = spineItem.getElementDimensions()) == null ? void 0 : _a.width) || 0;
5761
+ const itemWidth = ((_a = spineItem.layoutPosition) == null ? void 0 : _a.width) || 0;
5755
5762
  const pageWidth = context.getPageSize().width;
5756
5763
  const anchorElementBoundingRect = spineItem.getBoundingRectOfElementFromSelector(anchor);
5757
5764
  const offsetOfAnchor = (anchorElementBoundingRect == null ? void 0 : anchorElementBoundingRect.x) || 0;
@@ -5910,7 +5917,7 @@ const getNavigationForSpineItemPage = ({
5910
5917
  const spineItemNavigation = spineLocator.spineItemLocator.getSpineItemPositionFromPageIndex({
5911
5918
  pageIndex,
5912
5919
  isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
5913
- itemLayout: spineItem.getElementDimensions()
5920
+ itemLayout: spineItem.layoutPosition
5914
5921
  });
5915
5922
  const readingOffset = spineLocator.getSpinePositionFromSpineItemPosition({
5916
5923
  spineItemPosition: spineItemNavigation,
@@ -6677,7 +6684,7 @@ const withSpineItemPosition = ({
6677
6684
  const positionInSpineItem = spineLocator.spineItemLocator.getSpineItemPositionFromPageIndex({
6678
6685
  pageIndex: beginPageIndexForDirection,
6679
6686
  isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
6680
- itemLayout: spineItem.getElementDimensions()
6687
+ itemLayout: spineItem.layoutPosition
6681
6688
  });
6682
6689
  return positionInSpineItem;
6683
6690
  }
@@ -7376,13 +7383,13 @@ class PaginationController extends DestroyableClass {
7376
7383
  const shouldUpdateEndCfi = previousPagination.endSpineItemIndex !== endSpineItemIndex || endLastCfi === void 0 || isRootCfi(endLastCfi);
7377
7384
  const beginCfi = shouldUpdateBeginCfi ? getRootCfi(beginSpineItem) : beginLastCfi;
7378
7385
  const endCfi = shouldUpdateEndCfi ? getRootCfi(endSpineItem) : endLastCfi;
7379
- const beginSpineItemDimensions = beginSpineItem.getElementDimensions();
7386
+ const beginSpineItemDimensions = beginSpineItem.layoutPosition;
7380
7387
  const beginNumberOfPagesInSpineItem = this.spineItemLocator.getSpineItemNumberOfPages({
7381
7388
  itemHeight: beginSpineItemDimensions.height,
7382
7389
  itemWidth: beginSpineItemDimensions.width,
7383
7390
  isUsingVerticalWriting: !!beginSpineItem.isUsingVerticalWriting()
7384
7391
  });
7385
- const endSpineItemDimensions = endSpineItem.getElementDimensions();
7392
+ const endSpineItemDimensions = endSpineItem.layoutPosition;
7386
7393
  const endNumberOfPagesInSpineItem = this.spineItemLocator.getSpineItemNumberOfPages({
7387
7394
  itemHeight: endSpineItemDimensions.height,
7388
7395
  itemWidth: endSpineItemDimensions.width,
@@ -7557,24 +7564,44 @@ class ReaderSettingsManager extends SettingsManager3 {
7557
7564
  };
7558
7565
  }
7559
7566
  }
7560
- const getSpineItemFromPosition = ({
7561
- position,
7562
- spineItemsManager,
7567
+ const getAbsolutePageIndexFromPageIndex = ({
7568
+ pageIndex,
7569
+ spineItemOrId,
7563
7570
  spineLayout,
7571
+ spineItemsManager,
7572
+ context,
7564
7573
  settings
7565
7574
  }) => {
7566
- const spineItem = spineItemsManager.items.find((item) => {
7567
- const { left, right, bottom, top } = spineLayout.getAbsolutePositionOf(item);
7568
- const isWithinXAxis = position.x >= left && position.x < right;
7569
- if (settings.values.computedPageTurnDirection === `horizontal`) {
7570
- return isWithinXAxis;
7571
- }
7572
- return isWithinXAxis && position.y >= top && position.y < bottom;
7573
- });
7574
- if (position.x === 0 && !spineItem) {
7575
- return spineItemsManager.items[0];
7576
- }
7577
- return spineItem;
7575
+ const items = spineItemsManager.items;
7576
+ const spineItem = spineItemsManager.get(spineItemOrId);
7577
+ if (!spineItem) return void 0;
7578
+ const { currentAbsolutePage } = items.reduce(
7579
+ (acc, item) => {
7580
+ if (acc.found) return acc;
7581
+ const itemLayout = spineLayout.getAbsolutePositionOf(item);
7582
+ const numberOfPages = getSpineItemNumberOfPages({
7583
+ isUsingVerticalWriting: !!item.isUsingVerticalWriting(),
7584
+ itemHeight: itemLayout.height,
7585
+ itemWidth: itemLayout.width,
7586
+ context,
7587
+ settings
7588
+ });
7589
+ if (spineItem === item) {
7590
+ if (pageIndex <= numberOfPages - 1) {
7591
+ return {
7592
+ currentAbsolutePage: acc.currentAbsolutePage + pageIndex,
7593
+ found: true
7594
+ };
7595
+ }
7596
+ }
7597
+ return {
7598
+ ...acc,
7599
+ currentAbsolutePage: acc.currentAbsolutePage + numberOfPages
7600
+ };
7601
+ },
7602
+ { currentAbsolutePage: 0, found: false }
7603
+ );
7604
+ return currentAbsolutePage;
7578
7605
  };
7579
7606
  const isItemVisibleByThresholdForPosition = ({
7580
7607
  itemHeight,
@@ -7650,57 +7677,6 @@ const getItemVisibilityForPosition = ({
7650
7677
  visible: isItemVisibleEnough || isItemVisibleEnoughOnScreen
7651
7678
  };
7652
7679
  };
7653
- const getVisibleSpineItemsFromPosition = ({
7654
- position,
7655
- threshold,
7656
- restrictToScreen,
7657
- spineItemsManager,
7658
- context,
7659
- settings,
7660
- spineLayout
7661
- }) => {
7662
- const fallbackSpineItem = getSpineItemFromPosition({
7663
- position,
7664
- settings,
7665
- spineItemsManager,
7666
- spineLayout
7667
- }) || spineItemsManager.get(0);
7668
- const spineItemsVisible = spineItemsManager.items.reduce(
7669
- (acc, spineItem) => {
7670
- const itemPosition = spineLayout.getAbsolutePositionOf(spineItem);
7671
- const { visible } = getItemVisibilityForPosition({
7672
- itemPosition,
7673
- threshold,
7674
- viewportPosition: position,
7675
- restrictToScreen,
7676
- context
7677
- });
7678
- if (visible) {
7679
- return [...acc, spineItem];
7680
- }
7681
- return acc;
7682
- },
7683
- []
7684
- );
7685
- const beginItem = spineItemsVisible[0] ?? fallbackSpineItem;
7686
- const endItem = spineItemsVisible[spineItemsVisible.length - 1] ?? beginItem;
7687
- if (!beginItem || !endItem) return void 0;
7688
- const beginItemIndex = spineItemsManager.getSpineItemIndex(beginItem);
7689
- const endItemIndex = spineItemsManager.getSpineItemIndex(endItem);
7690
- return {
7691
- beginIndex: beginItemIndex ?? 0,
7692
- endIndex: endItemIndex ?? 0
7693
- };
7694
- };
7695
- const getSpinePositionFromSpineItemPosition = ({
7696
- spineItemPosition,
7697
- itemLayout: { left, top }
7698
- }) => {
7699
- return {
7700
- x: left + spineItemPosition.x,
7701
- y: top + spineItemPosition.y
7702
- };
7703
- };
7704
7680
  const getSpineInfoFromAbsolutePageIndex = ({
7705
7681
  absolutePageIndex,
7706
7682
  spineLayout,
@@ -7746,44 +7722,75 @@ const getSpineInfoFromAbsolutePageIndex = ({
7746
7722
  }
7747
7723
  return void 0;
7748
7724
  };
7749
- const getAbsolutePageIndexFromPageIndex = ({
7750
- pageIndex,
7751
- spineItemOrId,
7725
+ const getSpineItemFromPosition = ({
7726
+ position,
7727
+ spineItemsManager,
7752
7728
  spineLayout,
7729
+ settings
7730
+ }) => {
7731
+ const spineItem = spineItemsManager.items.find((item) => {
7732
+ const { left, right, bottom, top } = spineLayout.getAbsolutePositionOf(item);
7733
+ const isWithinXAxis = position.x >= left && position.x < right;
7734
+ if (settings.values.computedPageTurnDirection === `horizontal`) {
7735
+ return isWithinXAxis;
7736
+ }
7737
+ return isWithinXAxis && position.y >= top && position.y < bottom;
7738
+ });
7739
+ if (position.x === 0 && !spineItem) {
7740
+ return spineItemsManager.items[0];
7741
+ }
7742
+ return spineItem;
7743
+ };
7744
+ const getSpinePositionFromSpineItemPosition = ({
7745
+ spineItemPosition,
7746
+ itemLayout: { left, top }
7747
+ }) => {
7748
+ return {
7749
+ x: left + spineItemPosition.x,
7750
+ y: top + spineItemPosition.y
7751
+ };
7752
+ };
7753
+ const getVisibleSpineItemsFromPosition = ({
7754
+ position,
7755
+ threshold,
7756
+ restrictToScreen,
7753
7757
  spineItemsManager,
7754
7758
  context,
7755
- settings
7759
+ settings,
7760
+ spineLayout
7756
7761
  }) => {
7757
- const items = spineItemsManager.items;
7758
- const spineItem = spineItemsManager.get(spineItemOrId);
7759
- if (!spineItem) return void 0;
7760
- const { currentAbsolutePage } = items.reduce(
7761
- (acc, item) => {
7762
- if (acc.found) return acc;
7763
- const itemLayout = spineLayout.getAbsolutePositionOf(item);
7764
- const numberOfPages = getSpineItemNumberOfPages({
7765
- isUsingVerticalWriting: !!item.isUsingVerticalWriting(),
7766
- itemHeight: itemLayout.height,
7767
- itemWidth: itemLayout.width,
7768
- context,
7769
- settings
7762
+ const fallbackSpineItem = getSpineItemFromPosition({
7763
+ position,
7764
+ settings,
7765
+ spineItemsManager,
7766
+ spineLayout
7767
+ }) || spineItemsManager.get(0);
7768
+ const spineItemsVisible = spineItemsManager.items.reduce(
7769
+ (acc, spineItem) => {
7770
+ const itemPosition = spineLayout.getAbsolutePositionOf(spineItem);
7771
+ const { visible } = getItemVisibilityForPosition({
7772
+ itemPosition,
7773
+ threshold,
7774
+ viewportPosition: position,
7775
+ restrictToScreen,
7776
+ context
7770
7777
  });
7771
- if (spineItem === item) {
7772
- if (pageIndex <= numberOfPages - 1) {
7773
- return {
7774
- currentAbsolutePage: acc.currentAbsolutePage + pageIndex,
7775
- found: true
7776
- };
7777
- }
7778
+ if (visible) {
7779
+ return [...acc, spineItem];
7778
7780
  }
7779
- return {
7780
- ...acc,
7781
- currentAbsolutePage: acc.currentAbsolutePage + numberOfPages
7782
- };
7781
+ return acc;
7783
7782
  },
7784
- { currentAbsolutePage: 0, found: false }
7783
+ []
7785
7784
  );
7786
- return currentAbsolutePage;
7785
+ const beginItem = spineItemsVisible[0] ?? fallbackSpineItem;
7786
+ const endItem = spineItemsVisible[spineItemsVisible.length - 1] ?? beginItem;
7787
+ if (!beginItem || !endItem) return void 0;
7788
+ const beginItemIndex = spineItemsManager.getSpineItemIndex(beginItem);
7789
+ const endItemIndex = spineItemsManager.getSpineItemIndex(endItem);
7790
+ return {
7791
+ beginIndex: beginItemIndex ?? 0,
7792
+ endIndex: endItemIndex ?? 0
7793
+ };
7787
7794
  };
7788
7795
  const createSpineLocator = ({
7789
7796
  spineItemsManager,
@@ -7844,7 +7851,7 @@ const createSpineLocator = ({
7844
7851
  spineItem,
7845
7852
  restrictToScreen
7846
7853
  }) => {
7847
- const { height, width } = spineItem.getElementDimensions();
7854
+ const { height, width } = spineItem.layoutPosition;
7848
7855
  const numberOfPages = spineItemLocator.getSpineItemNumberOfPages({
7849
7856
  isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
7850
7857
  itemHeight: height,
@@ -7854,7 +7861,7 @@ const createSpineLocator = ({
7854
7861
  const spineItemPosition = spineItemLocator.getSpineItemPositionFromPageIndex({
7855
7862
  pageIndex: index,
7856
7863
  isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
7857
- itemLayout: spineItem.getElementDimensions()
7864
+ itemLayout: spineItem.layoutPosition
7858
7865
  });
7859
7866
  const spinePosition = getSpinePositionFromSpineItemPosition({
7860
7867
  spineItemPosition,
@@ -8079,8 +8086,7 @@ const layoutItem = ({
8079
8086
  isGloballyPrePaginated,
8080
8087
  settings,
8081
8088
  index,
8082
- item,
8083
- newItemLayoutInformation
8089
+ item
8084
8090
  }) => {
8085
8091
  let minimumWidth = context.getPageSize().width;
8086
8092
  let blankPagePosition = `none`;
@@ -8132,16 +8138,6 @@ const layoutItem = ({
8132
8138
  }
8133
8139
  const newEdgeX = width + currentValidEdgeXForVerticalPositioning;
8134
8140
  const newEdgeY = height + currentValidEdgeYForVerticalPositioning;
8135
- newItemLayoutInformation.push({
8136
- left: currentValidEdgeXForVerticalPositioning,
8137
- right: newEdgeX,
8138
- top: currentValidEdgeYForVerticalPositioning,
8139
- bottom: newEdgeY,
8140
- height,
8141
- width,
8142
- x: currentValidEdgeXForVerticalPositioning,
8143
- y: currentValidEdgeYForVerticalPositioning
8144
- });
8145
8141
  return {
8146
8142
  horizontalOffset: newEdgeX,
8147
8143
  verticalOffset: newEdgeY
@@ -8150,17 +8146,6 @@ const layoutItem = ({
8150
8146
  item.adjustPositionOfElement(
8151
8147
  context.isRTL() ? { right: horizontalOffset, top: 0 } : { left: horizontalOffset, top: 0 }
8152
8148
  );
8153
- const left = context.isRTL() ? context.state.visibleAreaRect.width - horizontalOffset - width : horizontalOffset;
8154
- newItemLayoutInformation.push({
8155
- right: context.isRTL() ? context.state.visibleAreaRect.width - horizontalOffset : horizontalOffset + width,
8156
- left,
8157
- x: left,
8158
- top: verticalOffset,
8159
- bottom: height,
8160
- height,
8161
- width,
8162
- y: verticalOffset
8163
- });
8164
8149
  return {
8165
8150
  horizontalOffset: horizontalOffset + width,
8166
8151
  verticalOffset: 0
@@ -8175,7 +8160,6 @@ class SpineLayout extends DestroyableClass {
8175
8160
  this.spineItemsManager = spineItemsManager;
8176
8161
  this.context = context;
8177
8162
  this.settings = settings;
8178
- this.itemLayoutInformation = [];
8179
8163
  this.layoutSubject = new Subject();
8180
8164
  spineItemsManager.items$.pipe(
8181
8165
  switchMap((items) => {
@@ -8217,7 +8201,6 @@ class SpineLayout extends DestroyableClass {
8217
8201
  exhaustMap(() => {
8218
8202
  layoutInProgress.next(true);
8219
8203
  const manifest = this.context.manifest;
8220
- const newItemLayoutInformation = [];
8221
8204
  const isGloballyPrePaginated = isFullyPrePaginated(manifest) ?? false;
8222
8205
  return from(this.spineItemsManager.items).pipe(
8223
8206
  reduce(
@@ -8231,31 +8214,22 @@ class SpineLayout extends DestroyableClass {
8231
8214
  item,
8232
8215
  settings: this.settings,
8233
8216
  spineItemsManager: this.spineItemsManager,
8234
- verticalOffset,
8235
- newItemLayoutInformation
8217
+ verticalOffset
8236
8218
  })
8237
8219
  )
8238
8220
  ),
8239
8221
  of({ horizontalOffset: 0, verticalOffset: 0 })
8240
8222
  ),
8241
8223
  concatMap((layout$) => layout$),
8242
- map(() => {
8243
- const hasChanged = this.itemLayoutInformation.length !== newItemLayoutInformation.length || this.itemLayoutInformation.some(
8244
- (old, index) => !isShallowEqual(old, newItemLayoutInformation[index])
8245
- );
8246
- this.itemLayoutInformation = newItemLayoutInformation;
8247
- Report.log(NAMESPACE, `layout`, {
8248
- hasChanged,
8249
- itemLayoutInformation: this.itemLayoutInformation
8250
- });
8251
- return { hasChanged };
8224
+ tap$1(() => {
8225
+ Report.log(NAMESPACE, `layout`);
8252
8226
  }),
8253
8227
  finalize(() => {
8254
8228
  layoutInProgress.next(false);
8255
8229
  })
8256
8230
  );
8257
8231
  }),
8258
- map(({ hasChanged }) => {
8232
+ map(() => {
8259
8233
  const items = spineItemsManager.items;
8260
8234
  const spineItemsPagesAbsolutePositions = items.map((item) => {
8261
8235
  const itemLayout = this.getAbsolutePositionOf(item);
@@ -8296,7 +8270,6 @@ class SpineLayout extends DestroyableClass {
8296
8270
  []
8297
8271
  );
8298
8272
  return {
8299
- hasChanged,
8300
8273
  spineItemsAbsolutePositions: items.map(
8301
8274
  (item) => this.getAbsolutePositionOf(item)
8302
8275
  ),
@@ -8314,12 +8287,9 @@ class SpineLayout extends DestroyableClass {
8314
8287
  layout() {
8315
8288
  this.layoutSubject.next(void 0);
8316
8289
  }
8317
- /**
8318
- * It's important to not use x,y since we need the absolute position of each element. Otherwise x,y would be relative to
8319
- * current window (viewport).
8320
- */
8321
8290
  getAbsolutePositionOf(spineItemOrIndex) {
8322
- const fallback = {
8291
+ var _a;
8292
+ return ((_a = this.spineItemsManager.get(spineItemOrIndex)) == null ? void 0 : _a.layoutPosition) || {
8323
8293
  left: 0,
8324
8294
  right: 0,
8325
8295
  top: 0,
@@ -8329,10 +8299,6 @@ class SpineLayout extends DestroyableClass {
8329
8299
  x: 0,
8330
8300
  y: 0
8331
8301
  };
8332
- const spineItem = this.spineItemsManager.get(spineItemOrIndex);
8333
- const indexOfItem = spineItem ? this.spineItemsManager.items.indexOf(spineItem) : -1;
8334
- const layoutInformation = this.itemLayoutInformation[indexOfItem];
8335
- return layoutInformation || fallback;
8336
8302
  }
8337
8303
  destroy() {
8338
8304
  super.destroy();
@@ -8457,6 +8423,35 @@ class SpineItemLayout extends DestroyableClass {
8457
8423
  const adjustedValue = multiplier * pageSize;
8458
8424
  return Math.max(adjustedValue, pageSize);
8459
8425
  }
8426
+ /**
8427
+ * Returns the absolute layout position relative to the parent element which
8428
+ * is supposedly and expectedly the spine element.
8429
+ *
8430
+ * @important
8431
+ *
8432
+ * This method is stable and does not consider scalings or transforms on the parents.
8433
+ *
8434
+ * It does assume and requires that:
8435
+ * - the navigator element and the spine element are direct parents.
8436
+ * - the spine items are correctly positioned in the DOM and with correct styles values.
8437
+ */
8438
+ get layoutPosition() {
8439
+ const left = Math.round(this.containerElement.offsetLeft * 10) / 10;
8440
+ const top = Math.round(this.containerElement.offsetTop * 10) / 10;
8441
+ const width = Math.round(this.containerElement.offsetWidth * 10) / 10;
8442
+ const height = Math.round(this.containerElement.offsetHeight * 10) / 10;
8443
+ const normalizedValues = {
8444
+ left,
8445
+ top,
8446
+ right: left + width,
8447
+ bottom: top + height,
8448
+ x: left,
8449
+ y: top,
8450
+ width,
8451
+ height
8452
+ };
8453
+ return normalizedValues;
8454
+ }
8460
8455
  }
8461
8456
  class DefaultRenderer extends DocumentRenderer {
8462
8457
  onUnload() {
@@ -8504,17 +8499,6 @@ class SpineItem extends DestroyableClass {
8504
8499
  this.unload = () => {
8505
8500
  this.renderer.unload();
8506
8501
  };
8507
- this.getElementDimensions = () => {
8508
- const rect = this.containerElement.getBoundingClientRect();
8509
- const normalizedValues = {
8510
- ...rect,
8511
- // we want to round to first decimal because it's possible to have half pixel
8512
- // however browser engine can also gives back x.yyyy based on their precision
8513
- width: Math.round(rect.width * 10) / 10,
8514
- height: Math.round(rect.height * 10) / 10
8515
- };
8516
- return normalizedValues;
8517
- };
8518
8502
  this.destroy = () => {
8519
8503
  super.destroy();
8520
8504
  this.containerElement.remove();
@@ -8584,6 +8568,9 @@ class SpineItem extends DestroyableClass {
8584
8568
  get readingDirection() {
8585
8569
  return this.renderer.readingDirection;
8586
8570
  }
8571
+ get layoutPosition() {
8572
+ return this.spineItemLayout.layoutPosition;
8573
+ }
8587
8574
  get loaded$() {
8588
8575
  return this.renderer.state$.pipe(
8589
8576
  distinctUntilChanged(),
@@ -8954,22 +8941,20 @@ const createReaderWithEnhancers = (
8954
8941
  loadingEnhancer(
8955
8942
  webkitEnhancer(
8956
8943
  fontsEnhancer(
8957
- linksEnhancer(
8958
- accessibilityEnhancer(
8959
- resourcesEnhancer(
8960
- utilsEnhancer(
8961
- layoutEnhancer(
8962
- zoomEnhancer(
8963
- mediaEnhancer(
8964
- chromeEnhancer(
8965
- navigationEnhancer(
8944
+ accessibilityEnhancer(
8945
+ resourcesEnhancer(
8946
+ utilsEnhancer(
8947
+ layoutEnhancer(
8948
+ zoomEnhancer(
8949
+ navigationEnhancer(
8950
+ htmlEnhancer(
8951
+ mediaEnhancer(
8952
+ chromeEnhancer(
8966
8953
  themeEnhancer(
8967
8954
  paginationEnhancer(
8968
8955
  eventsEnhancer(
8969
- htmlEnhancer(
8970
- // __
8971
- createReader
8972
- )
8956
+ // __
8957
+ createReader
8973
8958
  )
8974
8959
  )
8975
8960
  )
@@ -9004,6 +8989,7 @@ export {
9004
8989
  idle,
9005
8990
  injectCSS,
9006
8991
  isHtmlElement,
8992
+ isHtmlTagElement,
9007
8993
  isShallowEqual2 as isShallowEqual,
9008
8994
  mapKeysTo,
9009
8995
  observeMutation,