@prose-reader/core 1.120.0 → 1.122.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.
@@ -35,7 +35,7 @@ export declare class CfiHandler {
35
35
  relativeToNode: string;
36
36
  offset: number;
37
37
  } | {
38
- node: ChildNode | undefined;
38
+ node: ChildNode;
39
39
  offset: number;
40
40
  relativeToNode?: undefined;
41
41
  } | undefined;
@@ -6,10 +6,10 @@ export declare const resolveCfi: ({ cfi, spineItemsManager, }: {
6
6
  node: Node | undefined;
7
7
  offset: number | undefined;
8
8
  spineItemIndex: number;
9
- spineItem: import('../../spineItem/SpineItem').SpineItem;
9
+ spineItem: import('../..').SpineItem;
10
10
  } | {
11
11
  spineItemIndex: number;
12
- spineItem: import('../../spineItem/SpineItem').SpineItem;
12
+ spineItem: import('../..').SpineItem;
13
13
  node?: undefined;
14
14
  offset?: undefined;
15
15
  } | undefined;
@@ -29,16 +29,16 @@ export declare const createReaderWithEnhancers: (options: Partial<import('./sett
29
29
  };
30
30
  generateCfiForSpineItemPage: (params: {
31
31
  pageIndex: number;
32
- spineItem: import('./spineItem/SpineItem').SpineItem;
32
+ spineItem: import('.').SpineItem;
33
33
  }) => string;
34
34
  resolveCfi: (params: Omit<Parameters<typeof import('./cfi/lookup/resolveCfi').resolveCfi>[0], "spineItemsManager">) => {
35
35
  node: Node | undefined;
36
36
  offset: number | undefined;
37
37
  spineItemIndex: number;
38
- spineItem: import('./spineItem/SpineItem').SpineItem;
38
+ spineItem: import('.').SpineItem;
39
39
  } | {
40
40
  spineItemIndex: number;
41
- spineItem: import('./spineItem/SpineItem').SpineItem;
41
+ spineItem: import('.').SpineItem;
42
42
  node?: undefined;
43
43
  offset?: undefined;
44
44
  } | undefined;
@@ -62,11 +62,11 @@ export declare const createReaderWithEnhancers: (options: Partial<import('./sett
62
62
  getNavigationForSpineItemPage: (params: Omit<Parameters<typeof import('./navigation/resolvers/getNavigationForSpineItemPage').getNavigationForSpineItemPage>[0], "context" | "spineItemsManager" | "spineItemNavigationResolver" | "spineLocator">) => import('./navigation/viewport/ViewportNavigator').ViewportPosition;
63
63
  getNavigationFromSpineItemPosition: (params: {
64
64
  spineItemPosition: import('./spineItem/types').UnsafeSpineItemPosition;
65
- spineItem: import('./spineItem/SpineItem').SpineItem;
65
+ spineItem: import('.').SpineItem;
66
66
  }) => import('./navigation/viewport/ViewportNavigator').ViewportPosition;
67
67
  getNavigationForCfi: (cfi: string) => import('./navigation/viewport/ViewportNavigator').ViewportPosition | undefined;
68
- getNavigationForLastPage: (spineItem: import('./spineItem/SpineItem').SpineItem) => import('./navigation/viewport/ViewportNavigator').ViewportPosition;
69
- getNavigationForSpineIndexOrId: (indexOrId: number | string | import('./spineItem/SpineItem').SpineItem) => import('./navigation/viewport/ViewportNavigator').ViewportPosition;
68
+ getNavigationForLastPage: (spineItem: import('.').SpineItem) => import('./navigation/viewport/ViewportNavigator').ViewportPosition;
69
+ getNavigationForSpineIndexOrId: (indexOrId: number | string | import('.').SpineItem) => import('./navigation/viewport/ViewportNavigator').ViewportPosition;
70
70
  getNavigationForPosition: (viewportPosition: import('./navigation/viewport/ViewportNavigator').ViewportPosition) => import('./navigation/viewport/ViewportNavigator').ViewportPosition;
71
71
  getMostPredominantNavigationForPosition: (viewportPosition: import('./navigation/viewport/ViewportNavigator').ViewportPosition) => import('./navigation/viewport/ViewportNavigator').ViewportPosition;
72
72
  getAdjustedPositionWithSafeEdge: (position: import('./navigation/viewport/ViewportNavigator').ViewportPosition) => {
@@ -84,9 +84,9 @@ export declare const createReaderWithEnhancers: (options: Partial<import('./sett
84
84
  }) => boolean;
85
85
  getAdjustedPositionForSpread: (position: import('./navigation/viewport/ViewportNavigator').ViewportPosition) => import('./navigation/viewport/ViewportNavigator').ViewportPosition;
86
86
  spineItemNavigator: {
87
- getNavigationForLastPage: (spineItem: import('./spineItem/SpineItem').SpineItem) => import('./spineItem/types').SafeSpineItemPosition;
88
- getNavigationForPosition: (spineItem: import('./spineItem/SpineItem').SpineItem, position: import('./spineItem/types').UnsafeSpineItemPosition) => import('./spineItem/types').SafeSpineItemPosition;
89
- getNavigationFromNode: (spineItem: import('./spineItem/SpineItem').SpineItem, node: Node, offset: number) => import('./spineItem/types').SafeSpineItemPosition;
87
+ getNavigationForLastPage: (spineItem: import('.').SpineItem) => import('./spineItem/types').SafeSpineItemPosition;
88
+ getNavigationForPosition: (spineItem: import('.').SpineItem, position: import('./spineItem/types').UnsafeSpineItemPosition) => import('./spineItem/types').SafeSpineItemPosition;
89
+ getNavigationFromNode: (spineItem: import('.').SpineItem, node: Node, offset: number) => import('./spineItem/types').SafeSpineItemPosition;
90
90
  };
91
91
  };
92
92
  };
@@ -123,11 +123,11 @@ export declare const createReaderWithEnhancers: (options: Partial<import('./sett
123
123
  getPercentageEstimate: (context: import('./context/Context').Context, currentSpineIndex: number, numberOfPages: number, pageIndex: number, currentPosition: {
124
124
  x: number;
125
125
  y: number;
126
- }, currentItem: import('./spineItem/SpineItem').SpineItem) => number;
126
+ }, currentItem: import('.').SpineItem) => number;
127
127
  getScrollPercentageWithinItem: (context: import('./context/Context').Context, currentPosition: {
128
128
  x: number;
129
129
  y: number;
130
- }, currentItem: import('./spineItem/SpineItem').SpineItem) => number;
130
+ }, currentItem: import('.').SpineItem) => number;
131
131
  };
132
132
  }, "pagination"> & {
133
133
  pagination: Omit<{
@@ -169,4 +169,31 @@ export declare const createReaderWithEnhancers: (options: Partial<import('./sett
169
169
  }>;
170
170
  };
171
171
  };
172
+ } & {
173
+ selection: {
174
+ selection$: import('rxjs').Observable<{
175
+ document: Document;
176
+ selection: Selection;
177
+ itemId: string;
178
+ } | undefined>;
179
+ selectionStart$: import('rxjs').Observable<boolean>;
180
+ selectionEnd$: import('rxjs').Observable<void>;
181
+ selectionAfterPointerUp$: import('rxjs').Observable<[Event, {
182
+ document: Document;
183
+ selection: Selection;
184
+ itemId: string;
185
+ } | undefined]>;
186
+ lastSelectionOnPointerdown$: import('rxjs').Observable<({
187
+ document: Document;
188
+ selection: Selection;
189
+ itemId: string;
190
+ } | undefined) | undefined>;
191
+ generateCfis: (params: {
192
+ itemId: string;
193
+ selection: Selection;
194
+ }) => {
195
+ anchorCfi: string | undefined;
196
+ focusCfi: string | undefined;
197
+ };
198
+ };
172
199
  };
@@ -0,0 +1,7 @@
1
+ import { Observable } from 'rxjs';
2
+ import { DestroyableClass } from '../../utils/DestroyableClass';
3
+ export declare class SelectionTracker extends DestroyableClass {
4
+ selectionChange$: Observable<Selection | null>;
5
+ selectionAfterPointerUp$: Observable<readonly [Event, Selection]>;
6
+ constructor(document: Document);
7
+ }
@@ -0,0 +1,7 @@
1
+ export declare const generateCfis: ({ itemId, selection, }: {
2
+ selection: Selection;
3
+ itemId: string;
4
+ }) => {
5
+ anchorCfi: string | undefined;
6
+ focusCfi: string | undefined;
7
+ };
@@ -0,0 +1,24 @@
1
+ import { Observable } from 'rxjs';
2
+ import { EnhancerOutput, RootEnhancer } from '../types/enhancer';
3
+ type SelectionValue = {
4
+ document: Document;
5
+ selection: Selection;
6
+ itemId: string;
7
+ } | undefined;
8
+ export declare const selectionEnhancer: <InheritOptions, InheritOutput extends EnhancerOutput<RootEnhancer>>(next: (options: InheritOptions) => InheritOutput) => (options: InheritOptions) => InheritOutput & {
9
+ selection: {
10
+ selection$: Observable<SelectionValue>;
11
+ selectionStart$: Observable<boolean>;
12
+ selectionEnd$: Observable<void>;
13
+ selectionAfterPointerUp$: Observable<[Event, SelectionValue]>;
14
+ lastSelectionOnPointerdown$: Observable<SelectionValue | undefined>;
15
+ generateCfis: (params: {
16
+ itemId: string;
17
+ selection: Selection;
18
+ }) => {
19
+ anchorCfi: string | undefined;
20
+ focusCfi: string | undefined;
21
+ };
22
+ };
23
+ };
24
+ export {};
@@ -12,7 +12,7 @@ export type CoreHook = {
12
12
  layers: {
13
13
  element: HTMLElement;
14
14
  }[];
15
- }) => void;
15
+ }) => Observable<void> | void;
16
16
  } | {
17
17
  name: `item.onDocumentLoad`;
18
18
  runFn: (params: {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { createSelection } from './selection';
2
1
  import { createReaderWithEnhancers as createReader } from './createReaderWithEnhancer';
3
2
  export type { Manifest } from '@prose-reader/shared';
4
3
  export { DocumentRenderer } from './spineItem/DocumentRenderer';
@@ -7,8 +6,9 @@ export { HookManager } from './hooks/HookManager';
7
6
  export { SettingsManager } from './settings/SettingsManager';
8
7
  export type Reader = ReturnType<typeof createReader>;
9
8
  export { createReader };
10
- export type ReaderSelection = ReturnType<typeof createSelection>;
11
9
  export { Report } from './report';
12
10
  export { isHtmlElement } from './utils/dom';
13
11
  export { isShallowEqual } from './utils/objects';
14
12
  export { waitForSwitch } from './utils/rxjs';
13
+ export { SpineItem } from './spineItem/SpineItem';
14
+ export * from './utils/DestroyableClass';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { takeUntil, Subject, combineLatest, map as map$1, switchMap, merge, EMPTY, fromEvent, withLatestFrom, NEVER, Observable, of, scheduled, animationFrameScheduler, take as take$1, from, distinctUntilChanged as distinctUntilChanged$1, tap as tap$1, throttleTime, finalize, startWith as startWith$1, debounceTime as debounceTime$1, BehaviorSubject, combineLatestWith, shareReplay as shareReplay$1, ReplaySubject, filter as filter$1, share, mergeMap, delay, identity, timer, skip as skip$1, exhaustMap, first as first$1, endWith, lastValueFrom, forkJoin, catchError as catchError$1 } from "rxjs";
2
- import { startWith, map, shareReplay, tap, pairwise, switchMap as switchMap$1, take, distinctUntilChanged, takeUntil as takeUntil$1, first, filter, debounceTime, skip, withLatestFrom as withLatestFrom$1, share as share$1, mergeMap as mergeMap$1, catchError } from "rxjs/operators";
1
+ import { takeUntil, Subject, combineLatest, map as map$1, switchMap, merge, EMPTY, fromEvent, withLatestFrom, NEVER, Observable, of, scheduled, animationFrameScheduler, take as take$1, from, distinctUntilChanged as distinctUntilChanged$1, tap as tap$1, throttleTime, finalize, startWith as startWith$1, debounceTime as debounceTime$1, BehaviorSubject, combineLatestWith, shareReplay as shareReplay$1, ReplaySubject, filter as filter$1, share, mergeMap, delay as delay$1, identity, timer, skip as skip$1, exhaustMap, first as first$1, endWith, lastValueFrom, forkJoin, catchError as catchError$1 } from "rxjs";
2
+ import { startWith, map, shareReplay, tap, pairwise, switchMap as switchMap$1, take, distinctUntilChanged, takeUntil as takeUntil$1, first, filter, delay, debounceTime, skip, withLatestFrom as withLatestFrom$1, share as share$1, mergeMap as mergeMap$1, catchError } from "rxjs/operators";
3
3
  import { shallowMergeIfDefined, isShallowEqual, detectMimeTypeFromName, parseContentType } from "@prose-reader/shared";
4
4
  import { isShallowEqual as isShallowEqual2 } from "@prose-reader/shared";
5
5
  const chromeEnhancer = (next) => (options) => {
@@ -518,14 +518,19 @@ const layoutEnhancer = (next) => (options) => {
518
518
  }
519
519
  });
520
520
  });
521
- reader.hookManager.register(`item.onAfterLayout`, ({ item }) => {
522
- const spineItem = reader.spineItemsManager.get(item.id);
523
- if (spineItem == null ? void 0 : spineItem.isReady) {
524
- spineItem == null ? void 0 : spineItem.renderer.layers.forEach(({ element }) => {
521
+ const revealItemOnReady$ = reader.spineItemsObserver.itemIsReady$.pipe(
522
+ filter(({ isReady }) => isReady),
523
+ /**
524
+ * Make sure that even if the document was loaded instantly, the layout is applied first
525
+ * and therefore the transition played. eg: pdf are loaded before attached to the dom.
526
+ */
527
+ delay(1, animationFrameScheduler),
528
+ tap(({ item }) => {
529
+ item.renderer.layers.forEach(({ element }) => {
525
530
  element.style.opacity = `1`;
526
531
  });
527
- }
528
- });
532
+ })
533
+ );
529
534
  const observeContainerResize = (container) => new Observable((observer) => {
530
535
  const resizeObserver = new ResizeObserver(() => {
531
536
  observer.next();
@@ -546,7 +551,6 @@ const layoutEnhancer = (next) => (options) => {
546
551
  })
547
552
  );
548
553
  const movingSafePan$ = createMovingSafePan$(reader);
549
- movingSafePan$.subscribe();
550
554
  settingsManager.values$.pipe(
551
555
  mapKeysTo([`pageHorizontalMargin`, `pageVerticalMargin`]),
552
556
  distinctUntilChanged(isShallowEqual),
@@ -556,7 +560,7 @@ const layoutEnhancer = (next) => (options) => {
556
560
  }),
557
561
  takeUntil$1(reader.$.destroy$)
558
562
  ).subscribe();
559
- merge(layoutOnContainerResize$).pipe(takeUntil$1(reader.$.destroy$)).subscribe();
563
+ merge(revealItemOnReady$, movingSafePan$, layoutOnContainerResize$).pipe(takeUntil$1(reader.$.destroy$)).subscribe();
560
564
  return {
561
565
  ...reader,
562
566
  destroy: () => {
@@ -3126,7 +3130,7 @@ class CfiHandler {
3126
3130
  let i, child;
3127
3131
  for (i = 0; i < children.length; i++) {
3128
3132
  child = children[i];
3129
- switch (child.nodeType) {
3133
+ switch (child == null ? void 0 : child.nodeType) {
3130
3134
  case ELEMENT_NODE:
3131
3135
  if (cfiCount % 2 === 0) {
3132
3136
  cfiCount += 2;
@@ -3162,12 +3166,11 @@ class CfiHandler {
3162
3166
  cfiCount += 1;
3163
3167
  }
3164
3168
  if (cfiCount === index) {
3165
- const trueLength = this.trueLength(dom, child.textContent);
3166
- if (offset >= trueLength) {
3167
- offset -= trueLength;
3168
- } else {
3169
+ const trueLength = this.trueLength(dom, child.textContent || "");
3170
+ if (offset <= trueLength) {
3169
3171
  return { node: child, offset };
3170
3172
  }
3173
+ offset -= trueLength;
3171
3174
  }
3172
3175
  lastChild = child;
3173
3176
  break;
@@ -3175,6 +3178,10 @@ class CfiHandler {
3175
3178
  continue;
3176
3179
  }
3177
3180
  }
3181
+ if (lastChild && (lastChild.nodeType === TEXT_NODE || lastChild.nodeType === CDATA_SECTION_NODE)) {
3182
+ const trueLength = this.trueLength(dom, lastChild.textContent || "");
3183
+ return { node: lastChild, offset: Math.min(offset, trueLength) };
3184
+ }
3178
3185
  if (index > cfiCount) {
3179
3186
  const o = { relativeToNode: `after`, offset: 0 };
3180
3187
  if (!lastChild) {
@@ -3701,7 +3708,7 @@ class ViewportNavigator extends DestroyableClass {
3701
3708
  * anything for x ms while we effectively adjust. We want it to be immediate.
3702
3709
  * However when user is repeatedly turning page, we can improve smoothness by delaying a bit the adjustment
3703
3710
  */
3704
- currentEvent.shouldAnimate ? delay(1, animationFrameScheduler) : identity,
3711
+ currentEvent.shouldAnimate ? delay$1(1, animationFrameScheduler) : identity,
3705
3712
  tap$1((data) => {
3706
3713
  const element2 = this.viewportElement$.getValue();
3707
3714
  const noAdjustmentNeeded = false;
@@ -3737,7 +3744,7 @@ class ViewportNavigator extends DestroyableClass {
3737
3744
  this.setViewportPosition(data.position);
3738
3745
  }
3739
3746
  }),
3740
- currentEvent.shouldAnimate ? delay(animationDuration / 2, animationFrameScheduler) : identity,
3747
+ currentEvent.shouldAnimate ? delay$1(animationDuration / 2, animationFrameScheduler) : identity,
3741
3748
  tap$1((data) => {
3742
3749
  const element2 = this.viewportElement$.getValue();
3743
3750
  if (pageTurnAnimation === `fade`) {
@@ -3745,7 +3752,7 @@ class ViewportNavigator extends DestroyableClass {
3745
3752
  element2.style.setProperty(`opacity`, `1`);
3746
3753
  }
3747
3754
  }),
3748
- currentEvent.shouldAnimate ? delay(animationDuration / 2, animationFrameScheduler) : identity,
3755
+ currentEvent.shouldAnimate ? delay$1(animationDuration / 2, animationFrameScheduler) : identity,
3749
3756
  tap$1((data) => {
3750
3757
  if (pageTurnAnimation === `fade`) {
3751
3758
  this.setViewportPosition(data.position);
@@ -5958,83 +5965,6 @@ class SpineLayout extends DestroyableClass {
5958
5965
  this.layoutSubject.complete();
5959
5966
  }
5960
5967
  }
5961
- const createFingerTracker = () => {
5962
- const fingerPositionInIframe = { x: void 0, y: void 0 };
5963
- const subject = new Subject();
5964
- let isMouseDown = false;
5965
- const track = (frame) => {
5966
- var _a, _b, _c;
5967
- fingerPositionInIframe.x = void 0;
5968
- fingerPositionInIframe.y = void 0;
5969
- (_a = frame.contentDocument) == null ? void 0 : _a.addEventListener(`mousedown`, (e) => {
5970
- isMouseDown = true;
5971
- fingerPositionInIframe.x = e.x;
5972
- fingerPositionInIframe.y = e.y;
5973
- subject.next({ event: `fingermove`, data: { x: e.x, y: e.y } });
5974
- });
5975
- (_b = frame.contentDocument) == null ? void 0 : _b.addEventListener(`mouseup`, () => {
5976
- isMouseDown = false;
5977
- fingerPositionInIframe.x = void 0;
5978
- fingerPositionInIframe.y = void 0;
5979
- subject.next({ event: `fingerout`, data: void 0 });
5980
- });
5981
- (_c = frame.contentDocument) == null ? void 0 : _c.addEventListener(`mousemove`, (e) => {
5982
- if (isMouseDown) {
5983
- subject.next({ event: `fingermove`, data: { x: e.x, y: e.y } });
5984
- }
5985
- });
5986
- };
5987
- return {
5988
- track,
5989
- getFingerPositionInIframe() {
5990
- return fingerPositionInIframe.x === void 0 || fingerPositionInIframe.y === void 0 ? void 0 : fingerPositionInIframe;
5991
- },
5992
- destroy: () => {
5993
- },
5994
- $: subject.asObservable()
5995
- };
5996
- };
5997
- const createSelectionTracker = () => {
5998
- let isSelecting = false;
5999
- let frame;
6000
- const subject = new Subject();
6001
- const mouseUpEvents = [`mouseup`, `pointerup`];
6002
- const track = (frameToTrack) => {
6003
- var _a, _b;
6004
- frame = frameToTrack;
6005
- mouseUpEvents.forEach((eventName) => {
6006
- var _a2;
6007
- (_a2 = frameToTrack.contentWindow) == null ? void 0 : _a2.addEventListener(eventName, () => {
6008
- isSelecting = false;
6009
- });
6010
- });
6011
- (_a = frameToTrack.contentDocument) == null ? void 0 : _a.addEventListener(`selectionchange`, () => {
6012
- var _a2;
6013
- subject.next({
6014
- event: `selectionchange`,
6015
- data: ((_a2 = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _a2.getSelection()) || null
6016
- });
6017
- });
6018
- (_b = frameToTrack.contentWindow) == null ? void 0 : _b.addEventListener(`selectstart`, () => {
6019
- isSelecting = true;
6020
- });
6021
- };
6022
- const destroy = () => {
6023
- };
6024
- return {
6025
- track,
6026
- destroy,
6027
- isSelecting: () => isSelecting,
6028
- getSelection: () => {
6029
- var _a;
6030
- const selection = (_a = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _a.getSelection();
6031
- if (!(selection == null ? void 0 : selection.anchorNode) || selection.type === `None` || selection.type === `Caret`)
6032
- return void 0;
6033
- return selection;
6034
- },
6035
- $: subject.asObservable()
6036
- };
6037
- };
6038
5968
  class DocumentRenderer {
6039
5969
  constructor(context, settings, hookManager, item, containerElement, resourcesHandler) {
6040
5970
  this.context = context;
@@ -6065,9 +5995,6 @@ class DocumentRenderer {
6065
5995
  this.destroy$ = this.triggerSubject.pipe(
6066
5996
  filter$1((trigger) => trigger === `destroy`)
6067
5997
  );
6068
- this.stateSubject.subscribe((state) => {
6069
- console.log(`FOOO`, item.id, `state`, state);
6070
- });
6071
5998
  this.load$.pipe(
6072
5999
  switchMap(() => {
6073
6000
  this.stateSubject.next(`loading`);
@@ -6266,8 +6193,6 @@ class SpineItem {
6266
6193
  this.destroy = () => {
6267
6194
  this.destroySubject$.next();
6268
6195
  this.containerElement.remove();
6269
- this.fingerTracker.destroy();
6270
- this.selectionTracker.destroy();
6271
6196
  this.destroySubject$.complete();
6272
6197
  this.renderer.destroy();
6273
6198
  };
@@ -6281,8 +6206,6 @@ class SpineItem {
6281
6206
  item,
6282
6207
  hookManager
6283
6208
  );
6284
- this.fingerTracker = createFingerTracker();
6285
- this.selectionTracker = createSelectionTracker();
6286
6209
  parentElement.appendChild(this.containerElement);
6287
6210
  const RendererClass = ((_b = (_a = this.settings.values).getRenderer) == null ? void 0 : _b.call(_a, item)) ?? DefaultRenderer;
6288
6211
  this.resourcesHandler = new ResourceHandler(item, this.settings);
@@ -6445,15 +6368,6 @@ class Spine extends DestroyableClass {
6445
6368
  layout() {
6446
6369
  this.spineLayout.layout();
6447
6370
  }
6448
- isSelecting() {
6449
- return this.spineItemsManager.items.some(
6450
- (item) => item.selectionTracker.isSelecting()
6451
- );
6452
- }
6453
- getSelection() {
6454
- var _a;
6455
- return (_a = this.spineItemsManager.items.find((item) => item.selectionTracker.getSelection())) == null ? void 0 : _a.selectionTracker.getSelection();
6456
- }
6457
6371
  destroy() {
6458
6372
  super.destroy();
6459
6373
  this.spineItemsLoader.destroy();
@@ -7424,8 +7338,6 @@ const eventsEnhancer = (next) => (options) => {
7424
7338
  (_a3 = frame.contentDocument) == null ? void 0 : _a3.removeEventListener(event, listener);
7425
7339
  };
7426
7340
  });
7427
- item.selectionTracker.track(frame);
7428
- item.fingerTracker.track(frame);
7429
7341
  destroy(() => {
7430
7342
  unregister.forEach((cb) => cb());
7431
7343
  });
@@ -8199,28 +8111,158 @@ const htmlEnhancer = (next) => (options) => {
8199
8111
  });
8200
8112
  return reader;
8201
8113
  };
8114
+ const generateCfis = ({
8115
+ itemId,
8116
+ selection
8117
+ }) => {
8118
+ const anchorCfi = selection.anchorNode ? CfiHandler.generate(
8119
+ selection.anchorNode,
8120
+ selection.anchorOffset,
8121
+ `|[prose~anchor~${encodeURIComponent(itemId)}]`
8122
+ ) : void 0;
8123
+ const focusCfi = selection.focusNode ? CfiHandler.generate(
8124
+ selection.focusNode,
8125
+ selection.focusOffset,
8126
+ `|[prose~anchor~${encodeURIComponent(itemId)}]`
8127
+ ) : void 0;
8128
+ return {
8129
+ anchorCfi,
8130
+ focusCfi
8131
+ };
8132
+ };
8133
+ class SelectionTracker extends DestroyableClass {
8134
+ constructor(document2) {
8135
+ super();
8136
+ this.selectionChange$ = fromEvent(document2, "selectionchange").pipe(
8137
+ map$1(() => document2.getSelection())
8138
+ );
8139
+ this.selectionAfterPointerUp$ = fromEvent(document2, "pointerup").pipe(
8140
+ /**
8141
+ * The selection is still valid during the event even if it will
8142
+ * be discarded. The timeout make sure to detect this edge case.
8143
+ */
8144
+ delay$1(0),
8145
+ map$1((event) => {
8146
+ const selection = document2.getSelection();
8147
+ return selection && !selection.isCollapsed ? [event, selection] : void 0;
8148
+ }),
8149
+ filter$1(isDefined)
8150
+ );
8151
+ }
8152
+ }
8153
+ const selectionEnhancer = (next) => (options) => {
8154
+ const reader = next(options);
8155
+ const selectionSubject = new BehaviorSubject(
8156
+ void 0
8157
+ );
8158
+ const selectionWithPointerUpSubject = new Subject();
8159
+ reader.hookManager.register(
8160
+ `item.onDocumentLoad`,
8161
+ ({ itemId, layers, destroy$, destroy }) => {
8162
+ var _a, _b;
8163
+ const frame = (_a = layers[0]) == null ? void 0 : _a.element;
8164
+ if (frame instanceof HTMLIFrameElement) {
8165
+ const frameDoc = frame.contentDocument || ((_b = frame.contentWindow) == null ? void 0 : _b.document);
8166
+ if (frameDoc) {
8167
+ const selectionTracker = new SelectionTracker(frameDoc);
8168
+ merge(
8169
+ selectionTracker.selectionChange$.pipe(
8170
+ tap$1((selection) => {
8171
+ if (selection == null ? void 0 : selection.toString()) {
8172
+ selectionSubject.next({
8173
+ document: frameDoc,
8174
+ selection,
8175
+ itemId
8176
+ });
8177
+ } else {
8178
+ selectionSubject.next(void 0);
8179
+ }
8180
+ })
8181
+ ),
8182
+ selectionTracker.selectionAfterPointerUp$.pipe(
8183
+ tap$1(([event, selection]) => {
8184
+ selectionWithPointerUpSubject.next([
8185
+ event,
8186
+ {
8187
+ document: frameDoc,
8188
+ selection,
8189
+ itemId
8190
+ }
8191
+ ]);
8192
+ })
8193
+ )
8194
+ ).pipe(takeUntil(destroy$)).subscribe();
8195
+ destroy(() => {
8196
+ selectionTracker.destroy();
8197
+ });
8198
+ }
8199
+ }
8200
+ }
8201
+ );
8202
+ const selection$ = selectionSubject.pipe(
8203
+ distinctUntilChanged$1(),
8204
+ shareReplay$1(1),
8205
+ takeUntil(reader.$.destroy$)
8206
+ );
8207
+ const selectionStart$ = selectionSubject.pipe(
8208
+ map$1((selection) => !!selection),
8209
+ distinctUntilChanged$1(),
8210
+ filter$1((isSelecting) => isSelecting),
8211
+ share()
8212
+ );
8213
+ const selectionEnd$ = selectionStart$.pipe(
8214
+ switchMap(() => selection$),
8215
+ distinctUntilChanged$1(),
8216
+ filter$1((selection) => !selection),
8217
+ share()
8218
+ );
8219
+ const selectionAfterPointerUp$ = selectionWithPointerUpSubject.asObservable();
8220
+ const lastSelectionOnPointerdown$ = reader.context.containerElement$.pipe(
8221
+ switchMap((container) => fromEvent(container, "pointerdown")),
8222
+ withLatestFrom(selection$),
8223
+ map$1(([, selection]) => selection),
8224
+ startWith$1(void 0)
8225
+ );
8226
+ return {
8227
+ ...reader,
8228
+ selection: {
8229
+ selection$,
8230
+ selectionStart$,
8231
+ selectionEnd$,
8232
+ selectionAfterPointerUp$,
8233
+ lastSelectionOnPointerdown$,
8234
+ generateCfis
8235
+ },
8236
+ destroy: () => {
8237
+ selectionSubject.complete();
8238
+ reader.destroy();
8239
+ }
8240
+ };
8241
+ };
8202
8242
  const createReaderWithEnhancers = (
8203
8243
  //__
8204
- hotkeysEnhancer(
8205
- loadingEnhancer(
8206
- webkitEnhancer(
8207
- fontsEnhancer(
8208
- linksEnhancer(
8209
- accessibilityEnhancer(
8210
- resourcesEnhancer(
8211
- utilsEnhancer(
8212
- layoutEnhancer(
8213
- zoomEnhancer(
8214
- mediaEnhancer(
8215
- chromeEnhancer(
8216
- navigationEnhancer(
8217
- themeEnhancer(
8218
- paginationEnhancer(
8219
- progressionEnhancer(
8220
- eventsEnhancer(
8221
- htmlEnhancer(
8222
- // __
8223
- createReader
8244
+ selectionEnhancer(
8245
+ hotkeysEnhancer(
8246
+ loadingEnhancer(
8247
+ webkitEnhancer(
8248
+ fontsEnhancer(
8249
+ linksEnhancer(
8250
+ accessibilityEnhancer(
8251
+ resourcesEnhancer(
8252
+ utilsEnhancer(
8253
+ layoutEnhancer(
8254
+ zoomEnhancer(
8255
+ mediaEnhancer(
8256
+ chromeEnhancer(
8257
+ navigationEnhancer(
8258
+ themeEnhancer(
8259
+ paginationEnhancer(
8260
+ progressionEnhancer(
8261
+ eventsEnhancer(
8262
+ htmlEnhancer(
8263
+ // __
8264
+ createReader
8265
+ )
8224
8266
  )
8225
8267
  )
8226
8268
  )
@@ -8241,11 +8283,13 @@ const createReaderWithEnhancers = (
8241
8283
  )
8242
8284
  );
8243
8285
  export {
8286
+ DestroyableClass,
8244
8287
  DocumentRenderer,
8245
8288
  HookManager,
8246
8289
  Report,
8247
8290
  ResourceHandler,
8248
8291
  SettingsManager3 as SettingsManager,
8292
+ SpineItem,
8249
8293
  createReaderWithEnhancers as createReader,
8250
8294
  isHtmlElement,
8251
8295
  isShallowEqual2 as isShallowEqual,