@prose-reader/core 1.201.0 → 1.202.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/createReaderWithEnhancer.d.ts +10 -10
  2. package/dist/enhancers/{layoutEnhancer → layout}/types.d.ts +1 -0
  3. package/dist/enhancers/layout/viewportMode.d.ts +3 -0
  4. package/dist/enhancers/navigation/navigators/manualNavigator.d.ts +1 -1
  5. package/dist/enhancers/pagination/enhancer.d.ts +1 -1
  6. package/dist/enhancers/pagination/pagination.d.ts +1 -1
  7. package/dist/enhancers/pagination/progression.d.ts +1 -1
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +140 -90
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.umd.cjs +142 -91
  12. package/dist/index.umd.cjs.map +1 -1
  13. package/dist/navigation/InternalNavigator.d.ts +1 -1
  14. package/dist/navigation/Navigator.d.ts +4 -2
  15. package/dist/navigation/UserScrollNavigation.d.ts +18 -0
  16. package/dist/navigation/consolidation/mapUserNavigationToInternal.d.ts +1 -1
  17. package/dist/navigation/controllers/ScrollNavigationController.d.ts +1 -0
  18. package/dist/navigation/tests/utils.d.ts +0 -11
  19. package/dist/navigation/types.d.ts +11 -0
  20. package/dist/reader.d.ts +2 -2
  21. package/dist/settings/SettingsManagerOverload.d.ts +1 -0
  22. package/dist/spine/loader/SpineItemsLoader.d.ts +2 -1
  23. package/dist/viewport/Viewport.d.ts +5 -1
  24. package/package.json +3 -3
  25. package/dist/navigation/UserNavigator.d.ts +0 -29
  26. package/dist/enhancers/{layoutEnhancer → layout}/SettingsManager.d.ts +1 -1
  27. /package/dist/enhancers/{layoutEnhancer → layout}/createMovingSafePan$.d.ts +0 -0
  28. /package/dist/enhancers/{layoutEnhancer → layout}/fixReflowable.d.ts +0 -0
  29. /package/dist/enhancers/{layoutEnhancer → layout}/layoutEnhancer.d.ts +0 -0
  30. /package/dist/enhancers/{layoutEnhancer → layout}/layoutInfo.d.ts +0 -0
@@ -1,5 +1,5 @@
1
- export declare const createReaderWithEnhancers: (options: Partial<import('./settings/types').CoreInputSettings> & Partial<import('./enhancers/layoutEnhancer/types').InputSettings> & {
2
- theme?: import('./enhancers/theme').Theme;
1
+ export declare const createReaderWithEnhancers: (options: Partial<import('./settings/types').CoreInputSettings> & Partial<import('./enhancers/layout/types').InputSettings> & {
2
+ theme?: import('.').Theme;
3
3
  } & Partial<import('./enhancers/fonts/types').InputSettings> & {
4
4
  loadingElementCreate?: (options: {
5
5
  container: HTMLElement;
@@ -55,9 +55,9 @@ export declare const createReaderWithEnhancers: (options: Partial<import('./sett
55
55
  internalNavigator: import('./navigation/InternalNavigator').InternalNavigator;
56
56
  scrollNavigationController: import('./navigation/controllers/ScrollNavigationController').ScrollNavigationController;
57
57
  controlledNavigationController: import('./navigation/controllers/ControlledNavigationController').ControlledNavigationController;
58
- isLocked$: import('rxjs').Observable<boolean>;
58
+ locker: import('./navigation/Locker').Locker;
59
59
  viewportState$: import('rxjs').Observable<"free" | "busy">;
60
- navigate: (to: import('./navigation/UserNavigator').UserNavigationEntry) => void;
60
+ navigate: (to: import('./navigation/types').UserNavigationEntry) => void;
61
61
  lock(): () => void;
62
62
  navigationResolver: {
63
63
  getNavigationForUrl: (url: string | URL) => {
@@ -119,8 +119,8 @@ export declare const createReaderWithEnhancers: (options: Partial<import('./sett
119
119
  }>;
120
120
  destroy$: import('rxjs').Subject<void>;
121
121
  };
122
- }, "settings"> & import('./enhancers/layoutEnhancer/layoutEnhancer').LayoutEnhancerOutput & {
123
- settings: import('./settings/SettingsInterface').SettingsInterface<import('./settings/types').CoreInputSettings & import('./enhancers/layoutEnhancer/types').InputSettings, import('./enhancers/layoutEnhancer/types').InputSettings & import('./settings/types').CoreInputSettings & import('./settings/types').ComputedCoreSettings>;
122
+ }, "settings"> & import('./enhancers/layout/layoutEnhancer').LayoutEnhancerOutput & {
123
+ settings: import('./settings/SettingsInterface').SettingsInterface<import('./settings/types').CoreInputSettings & import('./enhancers/layout/types').InputSettings, import('./enhancers/layout/types').InputSettings & import('./settings/types').CoreInputSettings & import('./settings/types').ComputedCoreSettings>;
124
124
  }, "pagination"> & {
125
125
  pagination: Omit<{
126
126
  getState: () => import('./pagination/Pagination').PaginationInfo;
@@ -133,10 +133,10 @@ export declare const createReaderWithEnhancers: (options: Partial<import('./sett
133
133
  };
134
134
  } & {
135
135
  theme: {
136
- set: (theme: import('./enhancers/theme').Theme) => void;
137
- get: () => import('./enhancers/theme').Theme;
136
+ set: (theme: import('.').Theme) => void;
137
+ get: () => import('.').Theme;
138
138
  $: {
139
- theme$: import('rxjs').Observable<import('./enhancers/theme').Theme>;
139
+ theme$: import('rxjs').Observable<import('.').Theme>;
140
140
  };
141
141
  };
142
142
  } & {
@@ -146,7 +146,7 @@ export declare const createReaderWithEnhancers: (options: Partial<import('./sett
146
146
  isOrIsWithinValidLink: (target: Event[`target`]) => boolean;
147
147
  };
148
148
  }, "settings"> & {
149
- settings: import('./settings/SettingsInterface').SettingsInterface<import('./settings/types').CoreInputSettings & import('./enhancers/layoutEnhancer/types').InputSettings & import('./enhancers/fonts/types').InputSettings, import('./enhancers/fonts/types').InputSettings & import('./enhancers/layoutEnhancer/types').InputSettings & import('./settings/types').CoreInputSettings & import('./settings/types').ComputedCoreSettings>;
149
+ settings: import('./settings/SettingsInterface').SettingsInterface<import('./settings/types').CoreInputSettings & import('./enhancers/layout/types').InputSettings & import('./enhancers/fonts/types').InputSettings, import('./enhancers/fonts/types').InputSettings & import('./enhancers/layout/types').InputSettings & import('./settings/types').CoreInputSettings & import('./settings/types').ComputedCoreSettings>;
150
150
  } & {
151
151
  loading: {
152
152
  $: {
@@ -3,5 +3,6 @@ export type InputSettings = {
3
3
  pageVerticalMargin: number;
4
4
  layoutAutoResize: `container` | false;
5
5
  layoutLayerTransition: boolean;
6
+ viewportMode: `normal` | `thumbnails`;
6
7
  };
7
8
  export type OutputSettings = InputSettings;
@@ -0,0 +1,3 @@
1
+ import { Observable } from 'rxjs';
2
+ import { Reader } from '../../reader';
3
+ export declare const createViewportModeHandler: (reader: Reader, viewportMode$: Observable<`normal` | `thumbnails`>) => Observable<"normal" | "thumbnails">;
@@ -1,4 +1,4 @@
1
- import { UserNavigationEntry } from '../../../navigation/UserNavigator';
1
+ import { UserNavigationEntry } from '../../../navigation/types';
2
2
  import { Reader } from '../../../reader';
3
3
  import { SpinePosition } from '../../../spine/types';
4
4
  export declare class ManualNavigator {
@@ -1,6 +1,6 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { PaginationInfo } from '../../pagination/Pagination';
3
- import { LayoutEnhancerOutput } from '../layoutEnhancer/layoutEnhancer';
3
+ import { LayoutEnhancerOutput } from '../layout/layoutEnhancer';
4
4
  import { EnhancerOutput, RootEnhancer } from '../types/enhancer';
5
5
  import { ConsolidatedResource, LocatableResource } from './locate';
6
6
  import { ExtraPaginationInfo } from './types';
@@ -1,7 +1,7 @@
1
1
  import { Observable, ObservedValueOf } from 'rxjs';
2
2
  import { PaginationInfo } from '../../pagination/Pagination';
3
3
  import { Reader } from '../../reader';
4
- import { LayoutEnhancerOutput } from '../layoutEnhancer/layoutEnhancer';
4
+ import { LayoutEnhancerOutput } from '../layout/layoutEnhancer';
5
5
  import { trackChapterInfo } from './chapters';
6
6
  import { EnhancerPaginationInto, ExtraPaginationInfo } from './types';
7
7
  export declare const mapPaginationInfoToExtendedInfo: (reader: Reader, paginationInfo: PaginationInfo, chaptersInfo: ObservedValueOf<ReturnType<typeof trackChapterInfo>>, percentageEstimateOfBook: number) => Observable<Omit<ExtraPaginationInfo, "beginAbsolutePageIndex" | "endAbsolutePageIndex" | "beginAbsolutePageIndex" | "numberOfTotalPages">>;
@@ -1,6 +1,6 @@
1
1
  import { Reader } from '../../reader';
2
2
  import { SpineItem } from '../../spineItem/SpineItem';
3
- import { LayoutEnhancerOutput } from '../layoutEnhancer/layoutEnhancer';
3
+ import { LayoutEnhancerOutput } from '../layout/layoutEnhancer';
4
4
  export declare const getPercentageEstimate: (reader: Reader & LayoutEnhancerOutput, currentSpineIndex: number, pageIndex: number, currentPosition: {
5
5
  x: number;
6
6
  y: number;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { createReaderWithEnhancers as createReader } from './createReaderWithEnh
2
2
  export type { Manifest } from '@prose-reader/shared';
3
3
  export { DocumentRenderer } from './spineItem/renderer/DocumentRenderer';
4
4
  export { ResourceHandler } from './spineItem/resources/ResourceHandler';
5
+ export type { Theme } from './enhancers/theme';
5
6
  export { HookManager } from './hooks/HookManager';
6
7
  export { SettingsManager } from './settings/SettingsManager';
7
8
  export type Reader = ReturnType<typeof createReader>;
package/dist/index.js CHANGED
@@ -2,7 +2,6 @@ import { switchMap, of, fromEvent, take, map, from, takeUntil, Observable, defer
2
2
  import { switchMap as switchMap$1, first, map as map$1, distinctUntilChanged, startWith, shareReplay, 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 { isShallowEqual, shallowMergeIfDefined, getParentPath, parseContentType, detectMimeTypeFromName, arrayEqual } from "@prose-reader/shared";
4
4
  import { isShallowEqual as isShallowEqual2 } from "@prose-reader/shared";
5
- import { isDefined as isDefined$1 } from "reactjrx";
6
5
  const getAttributeValueFromString = (string, key) => {
7
6
  const regExp = new RegExp(`${key}\\s*=\\s*([0-9.]+)`, `i`);
8
7
  const match = string.match(regExp) || [];
@@ -732,9 +731,12 @@ class SettingsManagerOverload {
732
731
  ...this.outputSettings
733
732
  };
734
733
  }
735
- watch(keys) {
734
+ watch(keyOrKeys) {
735
+ if (Array.isArray(keyOrKeys)) {
736
+ return this.values$.pipe(watchKeys(keyOrKeys));
737
+ }
736
738
  return this.values$.pipe(
737
- mapKeysTo(keys),
739
+ map$1((result) => result[keyOrKeys]),
738
740
  distinctUntilChanged(isShallowEqual)
739
741
  );
740
742
  }
@@ -1071,8 +1073,9 @@ class DocumentRenderer extends DestroyableClass {
1071
1073
  return defer(() => this.onLayout(params)).pipe();
1072
1074
  }
1073
1075
  destroy() {
1074
- super.destroy();
1076
+ this.unload();
1075
1077
  this.stateSubject.complete();
1078
+ super.destroy();
1076
1079
  }
1077
1080
  get writingMode() {
1078
1081
  return void 0;
@@ -2054,6 +2057,7 @@ let SettingsManager$1 = class SettingsManager2 extends SettingsManagerOverload {
2054
2057
  pageHorizontalMargin,
2055
2058
  pageVerticalMargin,
2056
2059
  layoutLayerTransition,
2060
+ viewportMode,
2057
2061
  ...rest
2058
2062
  } = settings;
2059
2063
  return rest;
@@ -2063,7 +2067,8 @@ let SettingsManager$1 = class SettingsManager2 extends SettingsManagerOverload {
2063
2067
  layoutAutoResize: "container",
2064
2068
  pageHorizontalMargin: 24,
2065
2069
  pageVerticalMargin: 24,
2066
- layoutLayerTransition: true
2070
+ layoutLayerTransition: true,
2071
+ viewportMode: "normal"
2067
2072
  };
2068
2073
  }
2069
2074
  };
@@ -2241,6 +2246,24 @@ const createLayoutInfo = (reader) => {
2241
2246
  info$.pipe(takeUntil(reader.$.destroy$)).subscribe();
2242
2247
  return { layout$, info$ };
2243
2248
  };
2249
+ const createViewportModeHandler = (reader, viewportMode$) => {
2250
+ return viewportMode$.pipe(
2251
+ tap$1((viewportMode) => {
2252
+ reader.viewport.value.element.style.transition = `transform 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275)`;
2253
+ if (reader.settings.values.computedPageTurnMode === "scrollable") {
2254
+ reader.viewport.value.element.style.transformOrigin = `top`;
2255
+ } else {
2256
+ reader.viewport.value.element.style.transformOrigin = `center`;
2257
+ }
2258
+ if (viewportMode === `thumbnails`) {
2259
+ reader.viewport.value.element.style.transform = `scale(0.5)`;
2260
+ } else {
2261
+ reader.viewport.value.element.style.transform = `scale(1)`;
2262
+ }
2263
+ reader.layout();
2264
+ })
2265
+ );
2266
+ };
2244
2267
  const layoutEnhancer = (next) => (options) => {
2245
2268
  const {
2246
2269
  pageHorizontalMargin,
@@ -2376,11 +2399,16 @@ const layoutEnhancer = (next) => (options) => {
2376
2399
  })
2377
2400
  );
2378
2401
  const { layout$, info$ } = createLayoutInfo(reader);
2402
+ const viewportModeHandler$ = createViewportModeHandler(
2403
+ reader,
2404
+ settingsManager.watch(`viewportMode`)
2405
+ );
2379
2406
  merge(
2380
2407
  updateSpineItemClassName$,
2381
2408
  revealItemOnReady$,
2382
2409
  movingSafePan$,
2383
- layoutOnContainerResize$
2410
+ layoutOnContainerResize$,
2411
+ viewportModeHandler$
2384
2412
  ).pipe(takeUntil$1(reader.$.destroy$)).subscribe();
2385
2413
  return {
2386
2414
  ...reader,
@@ -2699,7 +2727,7 @@ const handleLinksNavigation = (reader, manualNavigator) => {
2699
2727
  })
2700
2728
  );
2701
2729
  };
2702
- const report$4 = Report.namespace(`navigation`);
2730
+ const report$3 = Report.namespace(`navigation`);
2703
2731
  class SpineItemPosition {
2704
2732
  constructor(position) {
2705
2733
  this.__symbol = Symbol(`SpineItemPosition`);
@@ -3099,7 +3127,7 @@ class ManualNavigator {
3099
3127
  pageIndex,
3100
3128
  spineItemId
3101
3129
  });
3102
- report$4.debug(`.goToPageOfSpineItem()`, {
3130
+ report$3.debug(`.goToPageOfSpineItem()`, {
3103
3131
  pageIndex,
3104
3132
  spineItemId,
3105
3133
  ...rest,
@@ -3117,7 +3145,7 @@ class ManualNavigator {
3117
3145
  const foundInfo = this.reader.spine.locator.getSpineInfoFromAbsolutePageIndex({
3118
3146
  absolutePageIndex
3119
3147
  });
3120
- report$4.debug(`.goToAbsolutePageIndex()`, {
3148
+ report$3.debug(`.goToAbsolutePageIndex()`, {
3121
3149
  absolutePageIndex,
3122
3150
  ...rest,
3123
3151
  foundInfo
@@ -3160,7 +3188,7 @@ class PanNavigator {
3160
3188
  }
3161
3189
  let navigation = this.reader.navigation.getNavigation().position;
3162
3190
  if (delta) {
3163
- const viewportScale = this.reader.viewport.absoluteViewport.width / this.reader.viewport.absoluteViewport.width;
3191
+ const viewportScale = this.reader.viewport.absoluteViewport.width / this.reader.viewport.relativeViewport.width;
3164
3192
  const correctedX = Math.floor(delta.x) - (((_b = this.lastDelta) == null ? void 0 : _b.x) || 0);
3165
3193
  const correctedY = Math.floor(delta.y) - (((_c = this.lastDelta) == null ? void 0 : _c.y) || 0);
3166
3194
  const x = Math.floor(
@@ -3286,7 +3314,7 @@ const navigationEnhancer = (next) => (options) => {
3286
3314
  }
3287
3315
  };
3288
3316
  };
3289
- const NAMESPACE$5 = `paginationEnhancer`;
3317
+ const NAMESPACE$4 = `paginationEnhancer`;
3290
3318
  const consolidate = (item, reader) => {
3291
3319
  var _a;
3292
3320
  let itemPageIndex = (_a = item.meta) == null ? void 0 : _a.itemPageIndex;
@@ -3641,7 +3669,7 @@ const trackPaginationInfo = (reader) => {
3641
3669
  );
3642
3670
  return { paginationInfo$, getPaginationInfo: () => currentValue.value };
3643
3671
  };
3644
- Report.namespace(NAMESPACE$5);
3672
+ Report.namespace(NAMESPACE$4);
3645
3673
  const paginationEnhancer = (next) => (options) => {
3646
3674
  const reader = next(options);
3647
3675
  const { paginationInfo$, getPaginationInfo } = trackPaginationInfo(reader);
@@ -6158,8 +6186,8 @@ const withRestoredPosition = ({
6158
6186
  );
6159
6187
  })
6160
6188
  );
6161
- const NAMESPACE$4 = `navigation/InternalNavigator`;
6162
- const report$3 = Report.namespace(NAMESPACE$4);
6189
+ const NAMESPACE$3 = `navigation/InternalNavigator`;
6190
+ const report$2 = Report.namespace(NAMESPACE$3);
6163
6191
  class InternalNavigator extends DestroyableClass {
6164
6192
  constructor(settings, context, userNavigation$, viewportController, scrollNavigationController, navigationResolver, spine, isUserLocked$) {
6165
6193
  super();
@@ -6361,7 +6389,7 @@ class InternalNavigator extends DestroyableClass {
6361
6389
  );
6362
6390
  const notifyNavigationUpdate = (stream) => stream.pipe(
6363
6391
  tap$1(([currentNavigation, previousNavigation]) => {
6364
- report$3.info(
6392
+ report$2.info(
6365
6393
  `navigation updated from ${currentNavigation.meta.triggeredBy} of type ${currentNavigation.type}`,
6366
6394
  {
6367
6395
  previousNavigation,
@@ -6437,40 +6465,23 @@ const getScaledDownPosition = ({
6437
6465
  return scaledDownPosition;
6438
6466
  };
6439
6467
  const SCROLL_FINISHED_DEBOUNCE_TIMEOUT = 500;
6440
- const NAMESPACE$3 = `navigation/UserNavigator`;
6441
- const report$2 = Report.namespace(NAMESPACE$3);
6442
- class UserNavigator extends DestroyableClass {
6443
- constructor(settings, scrollNavigatorElement$, context, scrollHappeningFromBrowser$, spine) {
6468
+ class UserScrollNavigation extends DestroyableClass {
6469
+ constructor(settings, context, spine, scrollNavigationController, locker) {
6444
6470
  super();
6445
6471
  this.settings = settings;
6446
- this.scrollNavigatorElement$ = scrollNavigatorElement$;
6447
6472
  this.context = context;
6448
- this.scrollHappeningFromBrowser$ = scrollHappeningFromBrowser$;
6449
6473
  this.spine = spine;
6474
+ this.scrollNavigationController = scrollNavigationController;
6475
+ this.locker = locker;
6450
6476
  this.navigationSubject = new Subject();
6451
- this.locker = new Locker();
6452
6477
  this.navigation$ = this.navigationSubject.asObservable();
6453
- const userScroll$ = scrollNavigatorElement$.pipe(
6454
- filter(isDefined$1),
6455
- switchMap(
6456
- (element) => settings.watch(["computedPageTurnMode"]).pipe(
6457
- switchMap(
6458
- ({ computedPageTurnMode }) => computedPageTurnMode === "controlled" ? NEVER : fromEvent(element, `scroll`).pipe(
6459
- withLatestFrom(scrollHappeningFromBrowser$),
6460
- filter(
6461
- ([, shouldAvoidScrollEvent]) => !shouldAvoidScrollEvent
6462
- ),
6463
- map(([event]) => event)
6464
- )
6465
- )
6466
- )
6467
- ),
6468
- share()
6469
- );
6470
- const navigateOnScroll$ = userScroll$.pipe(
6478
+ const navigateOnScroll$ = this.scrollNavigationController.userScroll$.pipe(
6471
6479
  exhaustMap((event) => {
6472
6480
  const unlock = this.locker.lock();
6473
- return merge(userScroll$, of(event)).pipe(
6481
+ return merge(
6482
+ this.scrollNavigationController.userScroll$,
6483
+ of(event)
6484
+ ).pipe(
6474
6485
  debounceTime$1(
6475
6486
  SCROLL_FINISHED_DEBOUNCE_TIMEOUT,
6476
6487
  animationFrameScheduler
@@ -6486,7 +6497,7 @@ class UserNavigator extends DestroyableClass {
6486
6497
  }),
6487
6498
  spineElement: this.spine.element
6488
6499
  });
6489
- this.navigate({
6500
+ this.navigationSubject.next({
6490
6501
  animation: false,
6491
6502
  type: "scroll",
6492
6503
  position: scaledDownPosition
@@ -6500,15 +6511,6 @@ class UserNavigator extends DestroyableClass {
6500
6511
  );
6501
6512
  merge(navigateOnScroll$).pipe(takeUntil(this.destroy$)).subscribe();
6502
6513
  }
6503
- /**
6504
- * Remember that this navigation is not trustable.
6505
- *
6506
- * It needs to be verified and adjusted if necessary before becoming internal.
6507
- */
6508
- navigate(to) {
6509
- report$2.info(`.navigate`, to);
6510
- this.navigationSubject.next(to);
6511
- }
6512
6514
  }
6513
6515
  const spinePositionToTranslation = (position) => {
6514
6516
  return {
@@ -6773,6 +6775,46 @@ class ScrollNavigationController extends ReactiveEntity {
6773
6775
  switchMap(() => merge(of(true), of(false))),
6774
6776
  shareReplay$1(1)
6775
6777
  );
6778
+ const isSpineScrolling$ = merge(
6779
+ spine.element$.pipe(switchMap((element) => observeResize(element))),
6780
+ spine.element$.pipe(switchMap((element) => fromEvent(element, "scroll"))),
6781
+ spine.spineItemsObserver.itemResize$
6782
+ ).pipe(
6783
+ switchMap(
6784
+ () => timer(10).pipe(
6785
+ map(() => false),
6786
+ startWith$1(true)
6787
+ )
6788
+ ),
6789
+ distinctUntilChanged$1(),
6790
+ startWith$1(false)
6791
+ );
6792
+ const scrollHappeningFromBrowser$ = combineLatest([
6793
+ isSpineScrolling$,
6794
+ this.isScrolling$
6795
+ ]).pipe(
6796
+ map(
6797
+ ([spineScrolling, viewportScrolling]) => spineScrolling || viewportScrolling
6798
+ ),
6799
+ shareReplay$1(1)
6800
+ );
6801
+ this.userScroll$ = this.watch("element").pipe(
6802
+ filter(isDefined),
6803
+ switchMap(
6804
+ (element) => settings.watch(["computedPageTurnMode"]).pipe(
6805
+ switchMap(
6806
+ ({ computedPageTurnMode }) => computedPageTurnMode === "controlled" ? NEVER : fromEvent(element, `scroll`).pipe(
6807
+ withLatestFrom(scrollHappeningFromBrowser$),
6808
+ filter(
6809
+ ([, shouldAvoidScrollEvent]) => !shouldAvoidScrollEvent
6810
+ ),
6811
+ map(([event]) => event)
6812
+ )
6813
+ )
6814
+ )
6815
+ ),
6816
+ share()
6817
+ );
6776
6818
  merge(elementCreation$, toggleElementDisplay$, navigate$).pipe(takeUntil(this.destroy$)).subscribe();
6777
6819
  }
6778
6820
  navigate(navigation) {
@@ -7416,6 +7458,8 @@ const createNavigator = ({
7416
7458
  settings,
7417
7459
  viewport
7418
7460
  }) => {
7461
+ const userExplicitNavigationSubject = new Subject();
7462
+ const locker = new Locker();
7419
7463
  const navigationResolver = createNavigationResolver({
7420
7464
  context,
7421
7465
  settings,
@@ -7437,58 +7481,42 @@ const createNavigator = ({
7437
7481
  spine,
7438
7482
  context
7439
7483
  );
7440
- const isSpineScrolling$ = merge(
7441
- spine.element$.pipe(switchMap$1((element) => observeResize(element))),
7442
- spine.element$.pipe(switchMap$1((element) => fromEvent(element, "scroll"))),
7443
- spine.spineItemsObserver.itemResize$
7444
- ).pipe(
7445
- switchMap$1(
7446
- () => timer(10).pipe(
7447
- map$1(() => false),
7448
- startWith(true)
7449
- )
7450
- ),
7451
- distinctUntilChanged(),
7452
- startWith(false)
7453
- );
7454
- const scrollHappeningFromBrowser$ = combineLatest([
7455
- isSpineScrolling$,
7456
- scrollNavigationController.isScrolling$
7457
- ]).pipe(
7458
- map$1(
7459
- ([spineScrolling, viewportScrolling]) => spineScrolling || viewportScrolling
7460
- ),
7461
- shareReplay(1)
7462
- );
7463
- const userNavigator = new UserNavigator(
7484
+ const userScrollNavigation = new UserScrollNavigation(
7464
7485
  settings,
7465
- scrollNavigationController.watch("element"),
7466
7486
  context,
7467
- scrollHappeningFromBrowser$,
7468
- spine
7487
+ spine,
7488
+ scrollNavigationController,
7489
+ locker
7490
+ );
7491
+ const userNavigation$ = merge(
7492
+ userExplicitNavigationSubject,
7493
+ userScrollNavigation.navigation$
7469
7494
  );
7470
7495
  const internalNavigator = new InternalNavigator(
7471
7496
  settings,
7472
7497
  context,
7473
- userNavigator.navigation$,
7498
+ userNavigation$,
7474
7499
  controlledNavigationController,
7475
7500
  scrollNavigationController,
7476
7501
  navigationResolver,
7477
7502
  spine,
7478
- userNavigator.locker.isLocked$
7503
+ locker.isLocked$
7479
7504
  );
7480
7505
  const viewportState$ = combineLatest([
7481
7506
  controlledNavigationController.isNavigating$,
7482
7507
  scrollNavigationController.isNavigating$,
7483
- userNavigator.locker.isLocked$,
7508
+ locker.isLocked$,
7484
7509
  internalNavigator.locker.isLocked$
7485
7510
  ]).pipe(
7486
7511
  map$1((states) => states.some((isLocked) => isLocked) ? `busy` : `free`),
7487
7512
  distinctUntilChanged(),
7488
7513
  shareReplay(1)
7489
7514
  );
7515
+ const navigate = (to) => {
7516
+ userExplicitNavigationSubject.next(to);
7517
+ };
7490
7518
  const destroy = () => {
7491
- userNavigator.destroy();
7519
+ userScrollNavigation.destroy();
7492
7520
  controlledNavigationController.destroy();
7493
7521
  internalNavigator.destroy();
7494
7522
  };
@@ -7498,11 +7526,11 @@ const createNavigator = ({
7498
7526
  internalNavigator,
7499
7527
  scrollNavigationController,
7500
7528
  controlledNavigationController,
7501
- isLocked$: userNavigator.locker.isLocked$,
7529
+ locker,
7502
7530
  viewportState$,
7503
- navigate: userNavigator.navigate.bind(userNavigator),
7531
+ navigate,
7504
7532
  lock() {
7505
- return userNavigator.locker.lock();
7533
+ return locker.lock();
7506
7534
  },
7507
7535
  navigationResolver,
7508
7536
  navigation$: internalNavigator.navigation$
@@ -8369,11 +8397,16 @@ class SpineItemsLoader extends DestroyableClass {
8369
8397
  loadSpineItems$.pipe(takeUntil(this.destroy$)).subscribe();
8370
8398
  }
8371
8399
  forceOpen(spineItems) {
8372
- this.forcedOpenSubject.next([...this.forcedOpenSubject.value, spineItems]);
8400
+ const indexes = spineItems.map(
8401
+ (item) => typeof item === "number" ? item : item.index
8402
+ );
8403
+ this.forcedOpenSubject.next([...this.forcedOpenSubject.value, indexes]);
8373
8404
  return () => {
8374
8405
  if (this.isDestroyed) return;
8375
8406
  this.forcedOpenSubject.next(
8376
- this.forcedOpenSubject.value.filter((item) => item !== spineItems)
8407
+ this.forcedOpenSubject.value.filter(
8408
+ (arrayOfIndexes) => arrayOfIndexes !== indexes
8409
+ )
8377
8410
  );
8378
8411
  };
8379
8412
  }
@@ -8955,11 +8988,23 @@ class Viewport extends ReactiveEntity {
8955
8988
  `;
8956
8989
  element.className = `${HTML_PREFIX$1}-viewport`;
8957
8990
  super({
8958
- element
8991
+ element,
8992
+ pageSize: {
8993
+ width: 1,
8994
+ height: 1
8995
+ }
8959
8996
  });
8960
8997
  this.context = context;
8998
+ const updatePageSize$ = this.context.watch("visibleAreaRect").pipe(
8999
+ tap$1(() => {
9000
+ this.update({
9001
+ pageSize: this.calculatePageSize()
9002
+ });
9003
+ })
9004
+ );
9005
+ merge(updatePageSize$).pipe(takeUntil(this.destroy$)).subscribe();
8961
9006
  }
8962
- getPageSize() {
9007
+ calculatePageSize() {
8963
9008
  const absoluteViewport = this.absoluteViewport;
8964
9009
  const { isUsingSpreadMode: isUsingSpreadMode2 } = this.context.state;
8965
9010
  return {
@@ -8978,6 +9023,9 @@ class Viewport extends ReactiveEntity {
8978
9023
  * @important
8979
9024
  *
8980
9025
  * Contains long floating values.
9026
+ *
9027
+ * @todo take position of translate into consideration in something
9028
+ * like relativeViewportPosition or even better a ViewportSlicePosition
8981
9029
  */
8982
9030
  get relativeViewport() {
8983
9031
  const absoluteViewport = this.absoluteViewport;
@@ -9038,7 +9086,9 @@ const createReader = (inputSettings) => {
9038
9086
  );
9039
9087
  navigator2.viewportState$.subscribe(context.bridgeEvent.viewportStateSubject);
9040
9088
  navigator2.navigation$.subscribe(context.bridgeEvent.navigationSubject);
9041
- navigator2.isLocked$.subscribe(context.bridgeEvent.navigationIsLockedSubject);
9089
+ navigator2.locker.isLocked$.subscribe(
9090
+ context.bridgeEvent.navigationIsLockedSubject
9091
+ );
9042
9092
  pagination.state$.subscribe(context.bridgeEvent.paginationSubject);
9043
9093
  const layout = () => {
9044
9094
  var _a;