@prose-reader/core 1.194.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.
@@ -138,20 +138,14 @@ export declare const createReaderWithEnhancers: (options: Partial<import('./sett
138
138
  theme$: import('rxjs').Observable<import('./enhancers/theme').Theme>;
139
139
  };
140
140
  };
141
+ } & {
142
+ links$: ReturnType<typeof import('./enhancers/html/links').handleLinks>;
141
143
  }, "load"> & import('./enhancers/navigation/types').NavigationEnhancerOutput & import('./enhancers/zoom/types').ZoomEnhancerOutput, "settings"> & {
142
144
  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>;
143
145
  } & {
144
146
  utils: {
145
147
  isOrIsWithinValidLink: (target: Event[`target`]) => boolean;
146
148
  };
147
- } & {
148
- $: {
149
- links$: import('rxjs').Observable<{
150
- event: `linkClicked`;
151
- data: HTMLAnchorElement;
152
- isNavigable: boolean;
153
- }>;
154
- };
155
149
  }, "settings"> & {
156
150
  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>;
157
151
  } & {
@@ -1,2 +1,8 @@
1
1
  import { EnhancerOptions, EnhancerOutput, RootEnhancer } from '../types/enhancer';
2
- export declare const htmlEnhancer: <InheritOptions extends EnhancerOptions<RootEnhancer>, InheritOutput extends EnhancerOutput<RootEnhancer>>(next: (options: InheritOptions) => InheritOutput) => (options: InheritOptions) => InheritOutput;
2
+ import { handleLinks } from './links';
3
+ export type HtmlEnhancerOutput = {
4
+ links$: ReturnType<typeof handleLinks>;
5
+ };
6
+ export declare const htmlEnhancer: <InheritOptions extends EnhancerOptions<RootEnhancer>, InheritOutput extends EnhancerOutput<RootEnhancer>>(next: (options: InheritOptions) => InheritOutput) => (options: InheritOptions) => InheritOutput & {
7
+ links$: ReturnType<typeof handleLinks>;
8
+ };
@@ -0,0 +1,2 @@
1
+ import { Reader } from '../../reader';
2
+ export declare const handleLinks: (reader: Reader) => import('rxjs').Observable<MouseEvent>;
@@ -1,3 +1,4 @@
1
+ import { HtmlEnhancerOutput } from '../html/enhancer';
1
2
  import { EnhancerOptions, EnhancerOutput, RootEnhancer } from '../types/enhancer';
2
3
  import { NavigationEnhancerOutput } from './types';
3
- export declare const navigationEnhancer: <InheritOptions extends EnhancerOptions<RootEnhancer>, InheritOutput extends EnhancerOutput<RootEnhancer>>(next: (options: InheritOptions) => InheritOutput) => (options: InheritOptions) => Omit<InheritOutput, "load"> & NavigationEnhancerOutput;
4
+ export declare const navigationEnhancer: <InheritOptions extends EnhancerOptions<RootEnhancer>, InheritOutput extends EnhancerOutput<RootEnhancer> & HtmlEnhancerOutput>(next: (options: InheritOptions) => InheritOutput) => (options: InheritOptions) => Omit<InheritOutput, "load"> & NavigationEnhancerOutput;
@@ -0,0 +1,4 @@
1
+ import { Reader } from '../../reader';
2
+ import { HtmlEnhancerOutput } from '../html/enhancer';
3
+ import { ManualNavigator } from './navigators/manualNavigator';
4
+ export declare const handleLinksNavigation: (reader: Reader & HtmlEnhancerOutput, manualNavigator: ManualNavigator) => import('rxjs').Observable<MouseEvent>;
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export { SettingsManager } from './settings/SettingsManager';
7
7
  export type Reader = ReturnType<typeof createReader>;
8
8
  export { createReader };
9
9
  export { Report } from './report';
10
- export { isHtmlElement } from './utils/dom';
10
+ export { isHtmlElement, isHtmlTagElement } from './utils/dom';
11
11
  export { isShallowEqual } from './utils/objects';
12
12
  export { waitForSwitch } from './utils/rxjs';
13
13
  export { SpineItem } from './spineItem/SpineItem';
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,
@@ -8934,22 +8941,20 @@ const createReaderWithEnhancers = (
8934
8941
  loadingEnhancer(
8935
8942
  webkitEnhancer(
8936
8943
  fontsEnhancer(
8937
- linksEnhancer(
8938
- accessibilityEnhancer(
8939
- resourcesEnhancer(
8940
- utilsEnhancer(
8941
- layoutEnhancer(
8942
- zoomEnhancer(
8943
- mediaEnhancer(
8944
- chromeEnhancer(
8945
- navigationEnhancer(
8944
+ accessibilityEnhancer(
8945
+ resourcesEnhancer(
8946
+ utilsEnhancer(
8947
+ layoutEnhancer(
8948
+ zoomEnhancer(
8949
+ navigationEnhancer(
8950
+ htmlEnhancer(
8951
+ mediaEnhancer(
8952
+ chromeEnhancer(
8946
8953
  themeEnhancer(
8947
8954
  paginationEnhancer(
8948
8955
  eventsEnhancer(
8949
- htmlEnhancer(
8950
- // __
8951
- createReader
8952
- )
8956
+ // __
8957
+ createReader
8953
8958
  )
8954
8959
  )
8955
8960
  )
@@ -8984,6 +8989,7 @@ export {
8984
8989
  idle,
8985
8990
  injectCSS,
8986
8991
  isHtmlElement,
8992
+ isHtmlTagElement,
8987
8993
  isShallowEqual2 as isShallowEqual,
8988
8994
  mapKeysTo,
8989
8995
  observeMutation,