@prose-reader/core 1.14.0 → 1.16.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/context.d.ts +1 -1
- package/dist/createReaderWithEnhancer.d.ts +5467 -4
- package/dist/enhancers/accessibility.d.ts +5464 -1
- package/dist/enhancers/chrome.d.ts +5464 -1
- package/dist/enhancers/fonts.d.ts +5464 -1
- package/dist/enhancers/hotkeys.d.ts +5464 -1
- package/dist/enhancers/layoutEnhancer/layoutEnhancer.d.ts +5464 -1
- package/dist/enhancers/links.d.ts +5465 -2
- package/dist/enhancers/loadingEnhancer.d.ts +5465 -1
- package/dist/enhancers/media.d.ts +5464 -1
- package/dist/enhancers/navigation.d.ts +5464 -1
- package/dist/enhancers/pagination.d.ts +5464 -2
- package/dist/enhancers/progression.d.ts +5464 -2
- package/dist/enhancers/resources/index.d.ts +5464 -1
- package/dist/enhancers/theme.d.ts +5464 -1
- package/dist/enhancers/types/enhancer.d.ts +5464 -1
- package/dist/enhancers/utils.d.ts +5464 -1
- package/dist/enhancers/webkit.d.ts +5464 -1
- package/dist/enhancers/zoom/index.d.ts +5464 -2
- package/dist/prose.js +361 -54
- package/dist/prose.js.map +1 -1
- package/dist/prose.umd.cjs +361 -54
- package/dist/prose.umd.cjs.map +1 -1
- package/dist/reader.d.ts +5474 -4
- package/dist/types/index.d.ts +0 -1
- package/package.json +5 -10
- package/dist/types/Reader.d.ts +0 -68
package/dist/prose.umd.cjs
CHANGED
|
@@ -2127,7 +2127,15 @@
|
|
|
2127
2127
|
});
|
|
2128
2128
|
const reader = next(options);
|
|
2129
2129
|
const getStyle = () => `
|
|
2130
|
-
${
|
|
2130
|
+
${/*
|
|
2131
|
+
Ideally, we would like to use !important but it could break publisher specific
|
|
2132
|
+
cases.
|
|
2133
|
+
Also right now we do not apply it to * since it would also break publisher
|
|
2134
|
+
more specific scaling down the tree.
|
|
2135
|
+
|
|
2136
|
+
body *:not([class^="mjx-"]) {
|
|
2137
|
+
*/
|
|
2138
|
+
``}
|
|
2131
2139
|
body {
|
|
2132
2140
|
${settingsSubject$.value.fontScale !== 1 ? `font-size: ${settingsSubject$.value.fontScale}em !important;` : ``}
|
|
2133
2141
|
${settingsSubject$.value.lineHeight !== `publisher` ? `line-height: ${settingsSubject$.value.lineHeight} !important;` : ``}
|
|
@@ -2169,6 +2177,9 @@
|
|
|
2169
2177
|
);
|
|
2170
2178
|
return {
|
|
2171
2179
|
...reader,
|
|
2180
|
+
/**
|
|
2181
|
+
* Absorb current enhancer settings and passthrough the rest to reader
|
|
2182
|
+
*/
|
|
2172
2183
|
setSettings: (settings) => {
|
|
2173
2184
|
const {
|
|
2174
2185
|
fontJustification: fontJustification2 = settingsSubject$.value.fontJustification,
|
|
@@ -2182,6 +2193,9 @@
|
|
|
2182
2193
|
}
|
|
2183
2194
|
reader.setSettings(passthroughSettings);
|
|
2184
2195
|
},
|
|
2196
|
+
/**
|
|
2197
|
+
* Combine reader settings with enhancer settings
|
|
2198
|
+
*/
|
|
2185
2199
|
settings$
|
|
2186
2200
|
};
|
|
2187
2201
|
};
|
|
@@ -2449,6 +2463,7 @@
|
|
|
2449
2463
|
};
|
|
2450
2464
|
};
|
|
2451
2465
|
const createReport = (namespace) => ({
|
|
2466
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2452
2467
|
log: (...data) => {
|
|
2453
2468
|
if (window.__PROSE_READER_DEBUG) {
|
|
2454
2469
|
if (namespace)
|
|
@@ -2457,6 +2472,7 @@
|
|
|
2457
2472
|
console.log(wrap(ROOT_NAMESPACE), ...data);
|
|
2458
2473
|
}
|
|
2459
2474
|
},
|
|
2475
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2460
2476
|
warn: (...data) => {
|
|
2461
2477
|
if (window.__PROSE_READER_DEBUG) {
|
|
2462
2478
|
if (namespace)
|
|
@@ -2465,9 +2481,22 @@
|
|
|
2465
2481
|
console.warn(wrap(ROOT_NAMESPACE), ...data);
|
|
2466
2482
|
}
|
|
2467
2483
|
},
|
|
2484
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2468
2485
|
error: (...data) => {
|
|
2469
2486
|
console.error(...data);
|
|
2470
2487
|
},
|
|
2488
|
+
// time: (label?: string | undefined) => {
|
|
2489
|
+
// if (window.__PROSE_READER_DEBUG) {
|
|
2490
|
+
// // eslint-disable-next-line no-console
|
|
2491
|
+
// console.time(`[prose-reader] [metric] ${label}`);
|
|
2492
|
+
// }
|
|
2493
|
+
// },
|
|
2494
|
+
// timeEnd: (label?: string | undefined) => {
|
|
2495
|
+
// if (window.__PROSE_READER_DEBUG) {
|
|
2496
|
+
// // eslint-disable-next-line no-console
|
|
2497
|
+
// console.timeEnd(`[prose-reader] [metric] ${label}`);
|
|
2498
|
+
// }
|
|
2499
|
+
// },
|
|
2471
2500
|
time,
|
|
2472
2501
|
logMetric: (performanceEntry, targetDuration = 0) => {
|
|
2473
2502
|
if (window.__PROSE_READER_DEBUG) {
|
|
@@ -2481,6 +2510,7 @@
|
|
|
2481
2510
|
}
|
|
2482
2511
|
}
|
|
2483
2512
|
},
|
|
2513
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2484
2514
|
measurePerformance: (name, targetDuration = 10, functionToMeasure, { disable } = {}) => {
|
|
2485
2515
|
if (disable || !window.__PROSE_READER_DEBUG)
|
|
2486
2516
|
return functionToMeasure;
|
|
@@ -2675,15 +2705,37 @@
|
|
|
2675
2705
|
beginPageIndexInChapter: paginationInfo.beginPageIndex,
|
|
2676
2706
|
beginNumberOfPagesInChapter: paginationInfo.beginNumberOfPages,
|
|
2677
2707
|
beginChapterInfo: beginItem ? chaptersInfo[beginItem.item.id] : void 0,
|
|
2708
|
+
// chapterIndex: number;
|
|
2709
|
+
// pages: number;
|
|
2710
|
+
// pageIndexInBook: number;
|
|
2711
|
+
// pageIndexInChapter: number;
|
|
2712
|
+
// pagesOfChapter: number;
|
|
2713
|
+
// pagePercentageInChapter: number;
|
|
2714
|
+
// offsetPercentageInChapter: number;
|
|
2715
|
+
// domIndex: number;
|
|
2716
|
+
// charOffset: number;
|
|
2717
|
+
// serializeString?: string;
|
|
2678
2718
|
beginSpineItemIndex: paginationInfo.beginSpineItemIndex,
|
|
2719
|
+
// spineItemPath: beginItem?.item.path,
|
|
2720
|
+
// spineItemId: beginItem?.item.id,
|
|
2679
2721
|
beginCfi: paginationInfo.beginCfi,
|
|
2680
2722
|
beginSpineItemReadingDirection: beginItem == null ? void 0 : beginItem.getReadingDirection(),
|
|
2681
2723
|
endChapterInfo: endItem ? chaptersInfo[endItem.item.id] : void 0,
|
|
2682
2724
|
endPageIndexInChapter: paginationInfo.endPageIndex,
|
|
2683
2725
|
endNumberOfPagesInChapter: paginationInfo.endNumberOfPages,
|
|
2684
2726
|
endSpineItemIndex: paginationInfo.endSpineItemIndex,
|
|
2727
|
+
// spineItemPath: endItem?.item.path,
|
|
2728
|
+
// spineItemId: endItem?.item.id,
|
|
2685
2729
|
endSpineItemReadingDirection: endItem == null ? void 0 : endItem.getReadingDirection(),
|
|
2686
2730
|
endCfi: paginationInfo.endCfi,
|
|
2731
|
+
// end: ReadingLocation;
|
|
2732
|
+
// spineItemReadingDirection: focusedSpineItem?.getReadingDirection(),
|
|
2733
|
+
/**
|
|
2734
|
+
* This percentage is based of the weight (kb) of every items and the number of pages.
|
|
2735
|
+
* It is not accurate but gives a general good idea of the overall progress.
|
|
2736
|
+
* It is recommended to use this progress only for reflow books. For pre-paginated books
|
|
2737
|
+
* the number of pages and current index can be used instead since 1 page = 1 chapter.
|
|
2738
|
+
*/
|
|
2687
2739
|
percentageEstimateOfBook: endItem ? reader.progression.getPercentageEstimate(
|
|
2688
2740
|
context,
|
|
2689
2741
|
paginationInfo.endSpineItemIndex ?? 0,
|
|
@@ -2693,6 +2745,11 @@
|
|
|
2693
2745
|
endItem
|
|
2694
2746
|
) : 0,
|
|
2695
2747
|
isUsingSpread: context.shouldDisplaySpread()
|
|
2748
|
+
// chaptersOfBook: number;
|
|
2749
|
+
// chapter: string;
|
|
2750
|
+
// hasNextChapter: (reader.spine.spineItemIndex || 0) < (manifest.readingOrder.length - 1),
|
|
2751
|
+
// hasPreviousChapter: (reader.spine.spineItemIndex || 0) < (manifest.readingOrder.length - 1),
|
|
2752
|
+
// numberOfSpineItems: context.getManifest()?.readingOrder.length,
|
|
2696
2753
|
};
|
|
2697
2754
|
};
|
|
2698
2755
|
const getSpineItemNumberOfPages = (spineItem) => {
|
|
@@ -2732,6 +2789,9 @@
|
|
|
2732
2789
|
const numberOfPagesPerItems = getNumberOfPagesPerItems();
|
|
2733
2790
|
return {
|
|
2734
2791
|
numberOfPagesPerItems,
|
|
2792
|
+
/**
|
|
2793
|
+
* This may be not accurate for reflowable due to dynamic load / unload.
|
|
2794
|
+
*/
|
|
2735
2795
|
numberOfTotalPages: numberOfPagesPerItems.reduce((acc, numberOfPagesForItem) => acc + numberOfPagesForItem, 0)
|
|
2736
2796
|
};
|
|
2737
2797
|
}),
|
|
@@ -2762,28 +2822,34 @@
|
|
|
2762
2822
|
const buildChapterInfoFromSpineItem = (manifest, item) => {
|
|
2763
2823
|
var _a;
|
|
2764
2824
|
const { href } = item;
|
|
2765
|
-
return getChapterInfo(href, ((_a = manifest.nav) == null ? void 0 : _a.toc) ?? []);
|
|
2825
|
+
return getChapterInfo(href, ((_a = manifest.nav) == null ? void 0 : _a.toc) ?? [], manifest);
|
|
2766
2826
|
};
|
|
2767
|
-
const getChapterInfo = (href,
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
const
|
|
2827
|
+
const getChapterInfo = (href, tocItem, manifest) => {
|
|
2828
|
+
const spineItemIndex = manifest.spineItems.findIndex((item) => item.href === href);
|
|
2829
|
+
return tocItem.reduce((acc, tocItem2) => {
|
|
2830
|
+
const indexOfHash = tocItem2.href.indexOf(`#`);
|
|
2831
|
+
const tocItemPathWithoutAnchor = indexOfHash > 0 ? tocItem2.href.substr(0, indexOfHash) : tocItem2.href;
|
|
2771
2832
|
const tocItemHrefWithoutFilename = tocItemPathWithoutAnchor.substring(0, tocItemPathWithoutAnchor.lastIndexOf("/"));
|
|
2772
2833
|
const hrefWithoutFilename = href.substring(0, href.lastIndexOf("/"));
|
|
2773
2834
|
const hrefIsChapterHref = href.endsWith(tocItemPathWithoutAnchor);
|
|
2774
2835
|
const hrefIsWithinChapter = hrefWithoutFilename !== "" && hrefWithoutFilename.endsWith(tocItemHrefWithoutFilename);
|
|
2775
|
-
|
|
2836
|
+
const isPossibleTocItemCandidate = hrefIsChapterHref || hrefIsWithinChapter;
|
|
2837
|
+
if (isPossibleTocItemCandidate) {
|
|
2838
|
+
const spineItemIndexOfPossibleCandidate = manifest.spineItems.findIndex((item) => item.href === tocItem2.href);
|
|
2839
|
+
const spineItemIsBeforeThisTocItem = spineItemIndex < spineItemIndexOfPossibleCandidate;
|
|
2840
|
+
if (spineItemIsBeforeThisTocItem)
|
|
2841
|
+
return acc;
|
|
2776
2842
|
return {
|
|
2777
|
-
title:
|
|
2778
|
-
path:
|
|
2843
|
+
title: tocItem2.title,
|
|
2844
|
+
path: tocItem2.path
|
|
2779
2845
|
};
|
|
2780
2846
|
}
|
|
2781
|
-
const subInfo = getChapterInfo(href,
|
|
2847
|
+
const subInfo = getChapterInfo(href, tocItem2.contents, manifest);
|
|
2782
2848
|
if (subInfo) {
|
|
2783
2849
|
return {
|
|
2784
2850
|
subChapter: subInfo,
|
|
2785
|
-
title:
|
|
2786
|
-
path:
|
|
2851
|
+
title: tocItem2.title,
|
|
2852
|
+
path: tocItem2.path
|
|
2787
2853
|
};
|
|
2788
2854
|
}
|
|
2789
2855
|
return acc;
|
|
@@ -2816,7 +2882,11 @@
|
|
|
2816
2882
|
}
|
|
2817
2883
|
${(foundTheme == null ? void 0 : foundTheme.foregroundColor) ? `
|
|
2818
2884
|
body * {
|
|
2819
|
-
${
|
|
2885
|
+
${/*
|
|
2886
|
+
Ideally, we would like to use !important but it could break publisher specific
|
|
2887
|
+
cases
|
|
2888
|
+
*/
|
|
2889
|
+
``}
|
|
2820
2890
|
color: ${foundTheme.foregroundColor};
|
|
2821
2891
|
}
|
|
2822
2892
|
` : ``}
|
|
@@ -3414,6 +3484,8 @@
|
|
|
3414
3484
|
take(1)
|
|
3415
3485
|
);
|
|
3416
3486
|
const unload$ = unloadSubject$.asObservable().pipe(
|
|
3487
|
+
// @todo remove iframe when viewport is free
|
|
3488
|
+
// @todo use takeUntil(load$) when it's the case to cancel
|
|
3417
3489
|
withLatestFrom(frameElementSubject$),
|
|
3418
3490
|
filter(([_, frame]) => !!frame),
|
|
3419
3491
|
map(([, frame]) => {
|
|
@@ -3434,13 +3506,16 @@
|
|
|
3434
3506
|
const load$ = loadSubject$.asObservable().pipe(
|
|
3435
3507
|
withLatestFrom(isLoadedSubject$),
|
|
3436
3508
|
filter(([_, isLoaded]) => !isLoaded),
|
|
3509
|
+
// let's ignore later load as long as the first one still runs
|
|
3437
3510
|
exhaustMap(() => {
|
|
3438
3511
|
return createFrame$().pipe(
|
|
3439
3512
|
mergeMap((frame) => waitForViewportFree$.pipe(map(() => frame))),
|
|
3440
3513
|
mergeMap((frame) => {
|
|
3441
3514
|
parent.appendChild(frame);
|
|
3442
3515
|
frameElementSubject$.next(frame);
|
|
3443
|
-
if (!fetchResource && item.href.startsWith(window.location.origin) &&
|
|
3516
|
+
if (!fetchResource && item.href.startsWith(window.location.origin) && // we have an encoding and it's a valid html
|
|
3517
|
+
(item.mediaType && [`application/xhtml+xml`, `application/xml`, `text/html`, `text/xml`].includes(item.mediaType) || // no encoding ? then try to detect html
|
|
3518
|
+
!item.mediaType && ITEM_EXTENSION_VALID_FOR_FRAME_SRC.some((extension) => item.href.endsWith(extension)))) {
|
|
3444
3519
|
frame == null ? void 0 : frame.setAttribute(`src`, item.href);
|
|
3445
3520
|
return rxjs.of(frame);
|
|
3446
3521
|
} else {
|
|
@@ -3496,6 +3571,7 @@
|
|
|
3496
3571
|
})
|
|
3497
3572
|
);
|
|
3498
3573
|
}),
|
|
3574
|
+
// we stop loading as soon as unload is requested
|
|
3499
3575
|
takeUntil(unloadSubject$)
|
|
3500
3576
|
);
|
|
3501
3577
|
}),
|
|
@@ -3622,6 +3698,12 @@
|
|
|
3622
3698
|
getHtmlFromResource,
|
|
3623
3699
|
load,
|
|
3624
3700
|
unload,
|
|
3701
|
+
/**
|
|
3702
|
+
* Upward layout is used when the parent wants to manipulate the iframe without triggering
|
|
3703
|
+
* `layout` event. This is a particular case needed for iframe because the parent can layout following
|
|
3704
|
+
* an iframe `layout` event. Because the parent `layout` may change some of iframe properties we do not
|
|
3705
|
+
* want the iframe to trigger a new `layout` even and have infinite loop.
|
|
3706
|
+
*/
|
|
3625
3707
|
staticLayout: (size) => {
|
|
3626
3708
|
const frame = frameElement$.getValue();
|
|
3627
3709
|
if (frame) {
|
|
@@ -3632,6 +3714,8 @@
|
|
|
3632
3714
|
}
|
|
3633
3715
|
}
|
|
3634
3716
|
},
|
|
3717
|
+
// @todo block access, only public API to manipulate / get information (in order to memo / optimize)
|
|
3718
|
+
// manipulate() with cb and return boolean whether re-layout or not
|
|
3635
3719
|
getManipulableFrame,
|
|
3636
3720
|
getReadingDirection: () => {
|
|
3637
3721
|
var _a;
|
|
@@ -3653,6 +3737,10 @@
|
|
|
3653
3737
|
loaded$,
|
|
3654
3738
|
ready$,
|
|
3655
3739
|
isReady$: isReadySubject$.asObservable(),
|
|
3740
|
+
/**
|
|
3741
|
+
* This is used as upstream layout change. This event is being listened to by upper app
|
|
3742
|
+
* in order to layout again and adjust every element based on the new content.
|
|
3743
|
+
*/
|
|
3656
3744
|
contentLayoutChange$
|
|
3657
3745
|
}
|
|
3658
3746
|
};
|
|
@@ -3931,6 +4019,8 @@
|
|
|
3931
4019
|
const rect = containerElement.getBoundingClientRect();
|
|
3932
4020
|
const normalizedValues = {
|
|
3933
4021
|
...rect,
|
|
4022
|
+
// we want to round to first decimal because it's possible to have half pixel
|
|
4023
|
+
// however browser engine can also gives back x.yyyy based on their precision
|
|
3934
4024
|
width: Math.round(rect.width * 10) / 10,
|
|
3935
4025
|
height: Math.round(rect.height * 10) / 10
|
|
3936
4026
|
};
|
|
@@ -4010,6 +4100,8 @@
|
|
|
4010
4100
|
return {
|
|
4011
4101
|
columnHeight,
|
|
4012
4102
|
columnWidth,
|
|
4103
|
+
// horizontalMargin,
|
|
4104
|
+
// verticalMargin,
|
|
4013
4105
|
width
|
|
4014
4106
|
};
|
|
4015
4107
|
};
|
|
@@ -4327,22 +4419,37 @@
|
|
|
4327
4419
|
justify-content: ${spreadPosition === `left` ? `flex-end` : spreadPosition === `right` ? `flex-start` : `center`};
|
|
4328
4420
|
` : ``}
|
|
4329
4421
|
}
|
|
4330
|
-
${
|
|
4422
|
+
${/*
|
|
4423
|
+
might be html * but it does mess up things like figure if so.
|
|
4424
|
+
check accessible_epub_3
|
|
4425
|
+
*/
|
|
4426
|
+
``}
|
|
4331
4427
|
html, body {
|
|
4332
4428
|
height: 100%;
|
|
4333
4429
|
width: 100%;
|
|
4334
4430
|
}
|
|
4335
|
-
${
|
|
4431
|
+
${/*
|
|
4432
|
+
This one is important for preventing 100% img to resize above
|
|
4433
|
+
current width. Especially needed for cbz conversion
|
|
4434
|
+
*/
|
|
4435
|
+
``}
|
|
4336
4436
|
html, body {
|
|
4337
4437
|
-max-width: ${columnWidth}px !important;
|
|
4338
4438
|
}
|
|
4339
|
-
${
|
|
4439
|
+
${/*
|
|
4440
|
+
* @see https://hammerjs.github.io/touch-action/
|
|
4441
|
+
* It needs to be disabled when using free scroll
|
|
4442
|
+
*/
|
|
4443
|
+
``}
|
|
4340
4444
|
html, body {
|
|
4341
4445
|
${enableTouch ? `
|
|
4342
4446
|
touch-action: none
|
|
4343
4447
|
` : ``}
|
|
4344
4448
|
}
|
|
4345
|
-
${
|
|
4449
|
+
${/*
|
|
4450
|
+
prevent drag of image instead of touch on firefox
|
|
4451
|
+
*/
|
|
4452
|
+
``}
|
|
4346
4453
|
img {
|
|
4347
4454
|
user-select: none;
|
|
4348
4455
|
-webkit-user-drag: none;
|
|
@@ -4350,9 +4457,18 @@
|
|
|
4350
4457
|
-moz-user-drag: none;
|
|
4351
4458
|
-o-user-drag: none;
|
|
4352
4459
|
user-drag: none;
|
|
4353
|
-
${
|
|
4460
|
+
${/*
|
|
4461
|
+
prevent weird overflow or margin. Try `block` if `flex` has weird behavior
|
|
4462
|
+
*/
|
|
4463
|
+
``}
|
|
4354
4464
|
display: flex;
|
|
4355
|
-
${
|
|
4465
|
+
${/*
|
|
4466
|
+
If the document does not have viewport, we cannot scale anything inside.
|
|
4467
|
+
This should never happens with a valid epub document however it will happens if
|
|
4468
|
+
we load .jpg, .png, etc directly in the iframe. This is expected, in this case we force
|
|
4469
|
+
the inner content to display correctly.
|
|
4470
|
+
*/
|
|
4471
|
+
``}
|
|
4356
4472
|
${!viewportDimensions ? `
|
|
4357
4473
|
-width: 100%;
|
|
4358
4474
|
max-width: 100%;
|
|
@@ -4483,7 +4599,10 @@
|
|
|
4483
4599
|
height: 100%;
|
|
4484
4600
|
margin: 0;
|
|
4485
4601
|
}
|
|
4486
|
-
${
|
|
4602
|
+
${/*
|
|
4603
|
+
* @see https://hammerjs.github.io/touch-action/
|
|
4604
|
+
*/
|
|
4605
|
+
``}
|
|
4487
4606
|
html, body {
|
|
4488
4607
|
touch-action: none;
|
|
4489
4608
|
}
|
|
@@ -4491,7 +4610,10 @@
|
|
|
4491
4610
|
};
|
|
4492
4611
|
const buildStyleForReflowableImageOnly = ({ isScrollable, enableTouch }) => {
|
|
4493
4612
|
return `
|
|
4494
|
-
${
|
|
4613
|
+
${/*
|
|
4614
|
+
* @see https://hammerjs.github.io/touch-action/
|
|
4615
|
+
*/
|
|
4616
|
+
``}
|
|
4495
4617
|
html, body {
|
|
4496
4618
|
width: 100%;
|
|
4497
4619
|
margin: 0;
|
|
@@ -4506,9 +4628,14 @@
|
|
|
4506
4628
|
margin: 0;
|
|
4507
4629
|
padding: 0;
|
|
4508
4630
|
box-sizing: border-box;
|
|
4509
|
-
${
|
|
4631
|
+
${// we make sure img spread on entire screen
|
|
4632
|
+
``}
|
|
4510
4633
|
width: 100%;
|
|
4511
|
-
${
|
|
4634
|
+
${/**
|
|
4635
|
+
* line break issue
|
|
4636
|
+
* @see https://stackoverflow.com/questions/37869020/image-not-taking-up-the-full-height-of-container
|
|
4637
|
+
*/
|
|
4638
|
+
``}
|
|
4512
4639
|
display: block;
|
|
4513
4640
|
}
|
|
4514
4641
|
` : ``}
|
|
@@ -4523,13 +4650,28 @@
|
|
|
4523
4650
|
parsererror {
|
|
4524
4651
|
display: none !important;
|
|
4525
4652
|
}
|
|
4526
|
-
${
|
|
4653
|
+
${/*
|
|
4654
|
+
might be html * but it does mess up things like figure if so.
|
|
4655
|
+
check accessible_epub_3
|
|
4656
|
+
*/
|
|
4657
|
+
``}
|
|
4527
4658
|
html, body {
|
|
4528
4659
|
margin: 0;
|
|
4529
4660
|
padding: 0 !important;
|
|
4530
4661
|
-max-width: ${columnWidth}px !important;
|
|
4531
4662
|
}
|
|
4532
|
-
${
|
|
4663
|
+
${/*
|
|
4664
|
+
body {
|
|
4665
|
+
height: ${columnHeight}px !important;
|
|
4666
|
+
width: ${columnWidth}px !important;
|
|
4667
|
+
-margin-left: ${horizontalMargin}px !important;
|
|
4668
|
+
-margin-right: ${horizontalMargin}px !important;
|
|
4669
|
+
-margin: ${verticalMargin}px ${horizontalMargin}px !important;
|
|
4670
|
+
-padding-top: ${horizontalMargin}px !important;
|
|
4671
|
+
-padding-bottom: ${horizontalMargin}px !important;
|
|
4672
|
+
}
|
|
4673
|
+
*/
|
|
4674
|
+
``}
|
|
4533
4675
|
body {
|
|
4534
4676
|
padding: 0 !important;
|
|
4535
4677
|
width: ${width}px !important;
|
|
@@ -4545,18 +4687,33 @@
|
|
|
4545
4687
|
margin: 0;
|
|
4546
4688
|
}
|
|
4547
4689
|
body:focus-visible {
|
|
4548
|
-
${
|
|
4690
|
+
${/*
|
|
4691
|
+
we make sure that there are no outline when we focus something inside the iframe
|
|
4692
|
+
*/
|
|
4693
|
+
``}
|
|
4549
4694
|
outline: none;
|
|
4550
4695
|
}
|
|
4551
|
-
${
|
|
4696
|
+
${/*
|
|
4697
|
+
* @see https://hammerjs.github.io/touch-action/
|
|
4698
|
+
*/
|
|
4699
|
+
``}
|
|
4552
4700
|
html, body {
|
|
4553
4701
|
touch-action: none;
|
|
4554
4702
|
}
|
|
4555
|
-
${
|
|
4703
|
+
${/*
|
|
4704
|
+
this messes up hard, be careful with this
|
|
4705
|
+
*/
|
|
4706
|
+
``}
|
|
4556
4707
|
* {
|
|
4557
4708
|
-max-width: ${columnWidth}px !important;
|
|
4558
4709
|
}
|
|
4559
|
-
${
|
|
4710
|
+
${/*
|
|
4711
|
+
this is necessary to have a proper calculation when determining size
|
|
4712
|
+
of iframe content. If an img is using something like width:100% it would expand to
|
|
4713
|
+
the size of the original image and potentially gives back a wrong size (much larger)
|
|
4714
|
+
@see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Columns/Handling_Overflow_in_Multicol
|
|
4715
|
+
*/
|
|
4716
|
+
``}
|
|
4560
4717
|
img, video, audio, object, svg {
|
|
4561
4718
|
max-width: 100%;
|
|
4562
4719
|
max-width: ${columnWidth}px !important;
|
|
@@ -4575,7 +4732,17 @@
|
|
|
4575
4732
|
box-sizing: border-box;
|
|
4576
4733
|
d-max-width: ${columnWidth}px !important;
|
|
4577
4734
|
}
|
|
4578
|
-
${
|
|
4735
|
+
${/*
|
|
4736
|
+
img, video, audio, object, svg {
|
|
4737
|
+
max-height: ${columnHeight}px !important;
|
|
4738
|
+
box-sizing: border-box;
|
|
4739
|
+
object-fit: contain;
|
|
4740
|
+
-webkit-column-break-inside: avoid;
|
|
4741
|
+
page-break-inside: avoid;
|
|
4742
|
+
break-inside: avoid;
|
|
4743
|
+
}
|
|
4744
|
+
*/
|
|
4745
|
+
``}
|
|
4579
4746
|
table {
|
|
4580
4747
|
max-width: ${columnWidth}px !important;
|
|
4581
4748
|
table-layout: fixed;
|
|
@@ -4772,7 +4939,11 @@
|
|
|
4772
4939
|
this.isRange = false;
|
|
4773
4940
|
this.opts = Object.assign(
|
|
4774
4941
|
{
|
|
4942
|
+
// If CFI is a Simple Range, pretend it isn't
|
|
4943
|
+
// by parsing only the start of the range
|
|
4775
4944
|
flattenRange: false,
|
|
4945
|
+
// Strip temporal, spatial, offset and textLocationAssertion
|
|
4946
|
+
// from places where they don't make sense
|
|
4776
4947
|
stricter: true
|
|
4777
4948
|
},
|
|
4778
4949
|
opts || {}
|
|
@@ -4892,6 +5063,7 @@
|
|
|
4892
5063
|
return cfi.get();
|
|
4893
5064
|
}
|
|
4894
5065
|
}
|
|
5066
|
+
// Takes two CFI paths and compares them
|
|
4895
5067
|
static comparePath(a, b) {
|
|
4896
5068
|
const max = Math.max(a.length, b.length);
|
|
4897
5069
|
let i, cA, cB, diff;
|
|
@@ -4908,11 +5080,13 @@
|
|
|
4908
5080
|
}
|
|
4909
5081
|
return 0;
|
|
4910
5082
|
}
|
|
5083
|
+
// Sort an array of CFI objects
|
|
4911
5084
|
static sort(a) {
|
|
4912
5085
|
a.sort((a2, b) => {
|
|
4913
5086
|
return this.compare(a2, b);
|
|
4914
5087
|
});
|
|
4915
5088
|
}
|
|
5089
|
+
// Takes two CFI objects and compares them.
|
|
4916
5090
|
static compare(a, b) {
|
|
4917
5091
|
let oA = a.get();
|
|
4918
5092
|
let oB = b.get();
|
|
@@ -4932,6 +5106,7 @@
|
|
|
4932
5106
|
return this.comparePath(oA, oB);
|
|
4933
5107
|
}
|
|
4934
5108
|
}
|
|
5109
|
+
// Takes two parsed path parts (assuming path is split on '!') and compares them.
|
|
4935
5110
|
static compareParts(a, b) {
|
|
4936
5111
|
const max = Math.max(a.length, b.length);
|
|
4937
5112
|
let i, cA, cB, diff;
|
|
@@ -4973,6 +5148,7 @@
|
|
|
4973
5148
|
return str;
|
|
4974
5149
|
}
|
|
4975
5150
|
}
|
|
5151
|
+
// decode HTML/XML entities and compute length
|
|
4976
5152
|
trueLength(dom, str) {
|
|
4977
5153
|
return this.decodeEntities(dom, str).length;
|
|
4978
5154
|
}
|
|
@@ -5238,6 +5414,9 @@
|
|
|
5238
5414
|
throw new Error(`Missing child node index in CFI`);
|
|
5239
5415
|
return { parsed: o, offset: i, newDoc: state === `!` };
|
|
5240
5416
|
}
|
|
5417
|
+
// The CFI counts child nodes differently from the DOM
|
|
5418
|
+
// Retrieve the child of parentNode at the specified index
|
|
5419
|
+
// according to the CFI standard way of counting
|
|
5241
5420
|
getChildNodeByCFIIndex(dom, parentNode, index, offset) {
|
|
5242
5421
|
const children = parentNode.childNodes;
|
|
5243
5422
|
if (!children.length)
|
|
@@ -5316,6 +5495,7 @@
|
|
|
5316
5495
|
}
|
|
5317
5496
|
return false;
|
|
5318
5497
|
}
|
|
5498
|
+
// Use a Text Location Assertion to correct and offset
|
|
5319
5499
|
correctOffset(dom, node, offset, assertion) {
|
|
5320
5500
|
let curNode = node;
|
|
5321
5501
|
let matchStr;
|
|
@@ -5413,6 +5593,15 @@
|
|
|
5413
5593
|
}
|
|
5414
5594
|
return o;
|
|
5415
5595
|
}
|
|
5596
|
+
// Each part of a CFI (as separated by '!')
|
|
5597
|
+
// references a separate HTML/XHTML/XML document.
|
|
5598
|
+
// This function takes an index specifying the part
|
|
5599
|
+
// of the CFI and the appropriate Document or XMLDocument
|
|
5600
|
+
// that is referenced by the specified part of the CFI
|
|
5601
|
+
// and returns the URI for the document referenced by
|
|
5602
|
+
// the next part of the CFI
|
|
5603
|
+
// If the opt `ignoreIDs` is true then IDs
|
|
5604
|
+
// will not be used while resolving
|
|
5416
5605
|
resolveURI(index, dom, opts) {
|
|
5417
5606
|
opts = opts || {};
|
|
5418
5607
|
if (index < 0 || index > this.parts.length - 2) {
|
|
@@ -5424,7 +5613,8 @@
|
|
|
5424
5613
|
const o = this.resolveNode(index, subparts, dom, opts);
|
|
5425
5614
|
let node = o.node;
|
|
5426
5615
|
const tagName = node.tagName.toLowerCase();
|
|
5427
|
-
if (tagName === `itemref` &&
|
|
5616
|
+
if (tagName === `itemref` && // @ts-ignore
|
|
5617
|
+
node.parentNode.tagName.toLowerCase() === `spine`) {
|
|
5428
5618
|
const idref = node.getAttribute(`idref`);
|
|
5429
5619
|
if (!idref)
|
|
5430
5620
|
throw new Error(`Referenced node had not 'idref' attribute`);
|
|
@@ -5471,6 +5661,9 @@
|
|
|
5471
5661
|
delete o.offset;
|
|
5472
5662
|
return { ...lastPart, ...o };
|
|
5473
5663
|
}
|
|
5664
|
+
// Takes the Document or XMLDocument for the final
|
|
5665
|
+
// document referenced by the CFI
|
|
5666
|
+
// and returns the node and offset into that node
|
|
5474
5667
|
resolveLast(dom, opts) {
|
|
5475
5668
|
opts = Object.assign(
|
|
5476
5669
|
{
|
|
@@ -5728,7 +5921,22 @@
|
|
|
5728
5921
|
spineItem: beginSpineItem,
|
|
5729
5922
|
spineItemIndex: beginItemIndex,
|
|
5730
5923
|
pageIndex: beginPageIndex,
|
|
5731
|
-
|
|
5924
|
+
/**
|
|
5925
|
+
* Because the start of a navigation may involve animations and interactions we don't resolve heavy CFI here.
|
|
5926
|
+
* We do want to have certain information correct in the pagination right after a navigation (same tick) but we just
|
|
5927
|
+
* defer heavy non vital stuff for later.
|
|
5928
|
+
* There are only 4 different cfi update at this stage:
|
|
5929
|
+
* - navigation comes from cfi, we simply affect the cfi to the pagination
|
|
5930
|
+
* - navigation comes from adjustment with controlled mode, we don't update the cfi, just pass the previous one
|
|
5931
|
+
* - navigation comes from adjustment with free mode, we will update with root cfi if needed because we could be on new page
|
|
5932
|
+
* - navigation is not from adjustment, this means we are on either new page or new reading item, we use light cfi with root (no dom lookup)
|
|
5933
|
+
*
|
|
5934
|
+
* The cfi is later adjusted with heavy dom lookup once the viewport is free.
|
|
5935
|
+
*/
|
|
5936
|
+
cfi: (lastExpectedNavigation == null ? void 0 : lastExpectedNavigation.type) === `navigate-from-cfi` && spineItemToFocus === beginSpineItem ? lastExpectedNavigation.data : data.triggeredBy === `adjust` && context.getSettings().computedPageTurnMode === `controlled` ? pagination.getInfo().beginCfi : beginItemIndex !== pagination.getInfo().beginSpineItemIndex ? cfiLocator.getRootCfi(beginSpineItem) : (
|
|
5937
|
+
/* @todo check ? */
|
|
5938
|
+
cfiLocator.getRootCfi(beginSpineItem)
|
|
5939
|
+
),
|
|
5732
5940
|
options: {
|
|
5733
5941
|
isAtEndOfChapter: false
|
|
5734
5942
|
}
|
|
@@ -5737,7 +5945,10 @@
|
|
|
5737
5945
|
spineItem: endSpineItem,
|
|
5738
5946
|
spineItemIndex: endItemIndex,
|
|
5739
5947
|
pageIndex: endPageIndex,
|
|
5740
|
-
cfi: (lastExpectedNavigation == null ? void 0 : lastExpectedNavigation.type) === `navigate-from-cfi` && spineItemToFocus === endSpineItem ? lastExpectedNavigation.data : data.triggeredBy === `adjust` && context.getSettings().computedPageTurnMode === `controlled` ? pagination.getInfo().endCfi : endItemIndex !== pagination.getInfo().endSpineItemIndex ? cfiLocator.getRootCfi(endSpineItem) :
|
|
5948
|
+
cfi: (lastExpectedNavigation == null ? void 0 : lastExpectedNavigation.type) === `navigate-from-cfi` && spineItemToFocus === endSpineItem ? lastExpectedNavigation.data : data.triggeredBy === `adjust` && context.getSettings().computedPageTurnMode === `controlled` ? pagination.getInfo().endCfi : endItemIndex !== pagination.getInfo().endSpineItemIndex ? cfiLocator.getRootCfi(endSpineItem) : (
|
|
5949
|
+
/* @todo check ? */
|
|
5950
|
+
cfiLocator.getRootCfi(endSpineItem)
|
|
5951
|
+
),
|
|
5741
5952
|
options: {
|
|
5742
5953
|
isAtEndOfChapter: false
|
|
5743
5954
|
}
|
|
@@ -5767,7 +5978,16 @@
|
|
|
5767
5978
|
takeUntil(context.$.destroy$)
|
|
5768
5979
|
).subscribe();
|
|
5769
5980
|
rxjs.merge(
|
|
5981
|
+
/**
|
|
5982
|
+
* We want to update content after navigation since we are at a different place.
|
|
5983
|
+
* We also wait for navigated items to be updated so that we have access to correct focus.
|
|
5984
|
+
* which is why we use this observer rather than `navigation$`.
|
|
5985
|
+
*/
|
|
5770
5986
|
itemUpdateOnNavigation$,
|
|
5987
|
+
/**
|
|
5988
|
+
* This one make sure we also listen for layout change and that we execute the code once the navigation
|
|
5989
|
+
* has been adjusted (whether it's needed or not).
|
|
5990
|
+
*/
|
|
5771
5991
|
navigationAdjusted$
|
|
5772
5992
|
).pipe(
|
|
5773
5993
|
switchMap(() => {
|
|
@@ -5966,7 +6186,10 @@
|
|
|
5966
6186
|
const isPrePaginated = ((_a = context.getManifest()) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
|
|
5967
6187
|
const isUsingFreeScroll = context.getSettings().computedPageTurnMode === `scrollable`;
|
|
5968
6188
|
orderedSpineItemsSubject$.value.forEach((orderedSpineItem, index) => {
|
|
5969
|
-
const isBeforeFocusedWithPreload =
|
|
6189
|
+
const isBeforeFocusedWithPreload = (
|
|
6190
|
+
// we never want to preload anything before on free scroll on flow because it could offset the cursor
|
|
6191
|
+
index < leftIndex && !isPrePaginated && isUsingFreeScroll ? true : index < leftIndex - numberOfAdjacentSpineItemToPreLoad
|
|
6192
|
+
);
|
|
5970
6193
|
const isAfterTailWithPreload = index > rightIndex + numberOfAdjacentSpineItemToPreLoad;
|
|
5971
6194
|
if (!isBeforeFocusedWithPreload && !isAfterTailWithPreload) {
|
|
5972
6195
|
orderedSpineItem.loadContent();
|
|
@@ -6172,7 +6395,8 @@
|
|
|
6172
6395
|
var _a, _b, _c;
|
|
6173
6396
|
const pageSize = context.getPageSize();
|
|
6174
6397
|
const frame = (_b = (_a = spineItem.spineItemFrame) == null ? void 0 : _a.getManipulableFrame()) == null ? void 0 : _b.frame;
|
|
6175
|
-
if (((_c = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _c.document) &&
|
|
6398
|
+
if (((_c = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _c.document) && // very important because it is being used by next functions
|
|
6399
|
+
frame.contentWindow.document.body !== null) {
|
|
6176
6400
|
const { x: left, y: top } = getSpineItemPositionFromPageIndex(pageIndex, spineItem);
|
|
6177
6401
|
const viewport = {
|
|
6178
6402
|
left,
|
|
@@ -6742,8 +6966,14 @@
|
|
|
6742
6966
|
chapterPageNavigation$,
|
|
6743
6967
|
leftPageNavigation$,
|
|
6744
6968
|
rightPageNavigation$,
|
|
6969
|
+
// for some reason after too much item ts complains
|
|
6745
6970
|
rxjs.merge(cfiNavigation$, pageNavigation$)
|
|
6746
6971
|
).pipe(
|
|
6972
|
+
/**
|
|
6973
|
+
* Ideally when manually navigating we expect the navigation to be different from the previous one.
|
|
6974
|
+
* This is because manual navigation is not used with scroll where you can move within the same item. A manual
|
|
6975
|
+
* navigation would theoretically always move to different items.
|
|
6976
|
+
*/
|
|
6747
6977
|
withLatestFrom(currentNavigationSubject$),
|
|
6748
6978
|
filter(([navigation, currentNavigation]) => navigator2.areNavigationDifferent(navigation, currentNavigation)),
|
|
6749
6979
|
map(([navigation]) => navigation)
|
|
@@ -6918,6 +7148,9 @@
|
|
|
6918
7148
|
}
|
|
6919
7149
|
const { x, y } = element.getBoundingClientRect();
|
|
6920
7150
|
const newValue = {
|
|
7151
|
+
// we want to round to first decimal because it's possible to have half pixel
|
|
7152
|
+
// however browser engine can also gives back x.yyyy based on their precision
|
|
7153
|
+
// @see https://stackoverflow.com/questions/13847053/difference-between-and-math-floor for ~~
|
|
6921
7154
|
x: ~~(Math.abs(x) * 10) / 10,
|
|
6922
7155
|
y: ~~(Math.abs(y) * 10) / 10
|
|
6923
7156
|
};
|
|
@@ -7128,6 +7361,14 @@
|
|
|
7128
7361
|
const animationDuration = currentEvent.animation === `snap` ? context.getSettings().computedSnapAnimationDuration : context.getSettings().computedPageTurnAnimationDuration;
|
|
7129
7362
|
const pageTurnAnimation = currentEvent.animation === `snap` ? `slide` : context.getSettings().computedPageTurnAnimation;
|
|
7130
7363
|
return rxjs.of(currentEvent).pipe(
|
|
7364
|
+
/**
|
|
7365
|
+
* @important
|
|
7366
|
+
* Optimization:
|
|
7367
|
+
* When the adjustment does not need animation it means we want to be there as fast as possible
|
|
7368
|
+
* One example is when we adjust position after layout. In this case we don't want to have flicker or see
|
|
7369
|
+
* anything for x ms while we effectively adjust. We want it to be immediate.
|
|
7370
|
+
* However when user is repeatedly turning page, we can improve smoothness by delaying a bit the adjustment
|
|
7371
|
+
*/
|
|
7131
7372
|
currentEvent.shouldAnimate ? delay(1, rxjs.animationFrameScheduler) : rxjs.identity,
|
|
7132
7373
|
tap((data) => {
|
|
7133
7374
|
const noAdjustmentNeeded = false;
|
|
@@ -7144,6 +7385,14 @@
|
|
|
7144
7385
|
element.style.setProperty(`opacity`, `1`);
|
|
7145
7386
|
}
|
|
7146
7387
|
}),
|
|
7388
|
+
/**
|
|
7389
|
+
* @important
|
|
7390
|
+
* We always need to adjust the reading offset. Even if the current viewport value
|
|
7391
|
+
* is the same as the payload position. This is because an already running animation could
|
|
7392
|
+
* be active, meaning the viewport is still adjusting itself (after animation duration). So we
|
|
7393
|
+
* need to adjust to anchor to the payload position. This is because we use viewport computed position,
|
|
7394
|
+
* not the value set by `setProperty`
|
|
7395
|
+
*/
|
|
7147
7396
|
withLatestFrom(hooks$),
|
|
7148
7397
|
tap(([data, hooks]) => {
|
|
7149
7398
|
if (pageTurnAnimation !== `fade`) {
|
|
@@ -7182,6 +7431,12 @@
|
|
|
7182
7431
|
map((states) => states.every((state) => state === `end`) ? `free` : `busy`),
|
|
7183
7432
|
distinctUntilChanged(),
|
|
7184
7433
|
shareReplay(1),
|
|
7434
|
+
/**
|
|
7435
|
+
* @important
|
|
7436
|
+
* Since state$ is being updated from navigation$ and other exported streams we need it to be
|
|
7437
|
+
* hot so it always have the correct value no matter when someone subscribe later.
|
|
7438
|
+
* We cannot wait for the cold stream to start after a navigation already happened for example.
|
|
7439
|
+
*/
|
|
7185
7440
|
makeItHot
|
|
7186
7441
|
);
|
|
7187
7442
|
const waitForViewportFree$ = state$.pipe(
|
|
@@ -7189,6 +7444,24 @@
|
|
|
7189
7444
|
rxjs.take(1)
|
|
7190
7445
|
);
|
|
7191
7446
|
const navigationAdjustedAfterLayout$ = spine.$.layout$.pipe(
|
|
7447
|
+
/**
|
|
7448
|
+
* @important
|
|
7449
|
+
* Careful with using debounce / throttle here since it can decrease user experience
|
|
7450
|
+
* when layout happens it can means an item before the current one has been unloaded, at current code
|
|
7451
|
+
* we unload and size back each item to the screen so it will have the effect of flicker for user.
|
|
7452
|
+
* Consider this workflow:
|
|
7453
|
+
* - user navigate to page 2
|
|
7454
|
+
* - viewport move to item 2
|
|
7455
|
+
* - page 1 unload and goes back from 2000px to 500px
|
|
7456
|
+
* - layout triggered
|
|
7457
|
+
* - viewport is now on an item far after item 2 because item 1 shrink (PROBLEM)
|
|
7458
|
+
* - sometime after viewport is adjusted back to item 2.
|
|
7459
|
+
*
|
|
7460
|
+
* Two solution to fix this issue:
|
|
7461
|
+
* - maybe later try to implement a different strategy and never shrink back item unless they are loaded
|
|
7462
|
+
* - do not use debounce / throttle and navigate back to the item right on the same tick
|
|
7463
|
+
*/
|
|
7464
|
+
// debounceTime(10, animationFrameScheduler),
|
|
7192
7465
|
switchMap(
|
|
7193
7466
|
() => waitForViewportFree$.pipe(
|
|
7194
7467
|
switchMap(() => {
|
|
@@ -7258,10 +7531,18 @@
|
|
|
7258
7531
|
if (context.isRTL()) {
|
|
7259
7532
|
return {
|
|
7260
7533
|
x: leftEnd - position.x - context.getPageSize().width,
|
|
7534
|
+
// y: (topEnd - position.y) - context.getPageSize().height,
|
|
7261
7535
|
y: Math.max(0, position.y - topStart)
|
|
7262
7536
|
};
|
|
7263
7537
|
}
|
|
7264
7538
|
return {
|
|
7539
|
+
/**
|
|
7540
|
+
* when using spread the item could be on the right and therefore will be negative
|
|
7541
|
+
* @example
|
|
7542
|
+
* 400 (position = viewport), page of 200
|
|
7543
|
+
* 400 - 600 = -200.
|
|
7544
|
+
* However we can assume we are at 0, because we in fact can see the beginning of the item
|
|
7545
|
+
*/
|
|
7265
7546
|
x: Math.max(0, position.x - leftStart),
|
|
7266
7547
|
y: Math.max(0, position.y - topStart)
|
|
7267
7548
|
};
|
|
@@ -7273,6 +7554,7 @@
|
|
|
7273
7554
|
if (context.isRTL()) {
|
|
7274
7555
|
return {
|
|
7275
7556
|
x: leftEnd - spineItemPosition.x - context.getPageSize().width,
|
|
7557
|
+
// y: (topEnd - spineItemPosition.y) - context.getPageSize().height,
|
|
7276
7558
|
y: topStart + spineItemPosition.y
|
|
7277
7559
|
};
|
|
7278
7560
|
}
|
|
@@ -7613,10 +7895,23 @@
|
|
|
7613
7895
|
destroy,
|
|
7614
7896
|
setSettings: context.setSettings,
|
|
7615
7897
|
settings$: context.$.settings$,
|
|
7898
|
+
/**
|
|
7899
|
+
* @important
|
|
7900
|
+
* BehaviorSubject
|
|
7901
|
+
*/
|
|
7616
7902
|
pagination$: pagination.$.info$,
|
|
7617
7903
|
$: {
|
|
7618
7904
|
state$: stateSubject$.asObservable(),
|
|
7905
|
+
/**
|
|
7906
|
+
* Dispatched when the reader has loaded a book and is displayed a book.
|
|
7907
|
+
* Using navigation API and getting information about current content will
|
|
7908
|
+
* have an effect.
|
|
7909
|
+
* It can typically be used to hide a loading indicator.
|
|
7910
|
+
*/
|
|
7619
7911
|
ready$: readySubject$.asObservable(),
|
|
7912
|
+
/**
|
|
7913
|
+
* Dispatched when a change in selection happens
|
|
7914
|
+
*/
|
|
7620
7915
|
selection$: selectionSubject$.asObservable(),
|
|
7621
7916
|
viewportState$: viewportNavigator.$.state$,
|
|
7622
7917
|
layout$: spine.$.layout$,
|
|
@@ -7868,6 +8163,10 @@
|
|
|
7868
8163
|
};
|
|
7869
8164
|
return {
|
|
7870
8165
|
...reader,
|
|
8166
|
+
// $: {
|
|
8167
|
+
// ...reader.$,
|
|
8168
|
+
// errors$: merge(reader.$.errors$, errorsSubject$.asObservable())
|
|
8169
|
+
// },
|
|
7871
8170
|
destroy,
|
|
7872
8171
|
load
|
|
7873
8172
|
};
|
|
@@ -8006,7 +8305,11 @@
|
|
|
8006
8305
|
`prose-reader-accessibility`,
|
|
8007
8306
|
`
|
|
8008
8307
|
:focus-visible {
|
|
8009
|
-
${
|
|
8308
|
+
${/*
|
|
8309
|
+
Some epubs remove the outline, this is not good practice since it reduce accessibility.
|
|
8310
|
+
We will try to restore it by force.
|
|
8311
|
+
*/
|
|
8312
|
+
``}
|
|
8010
8313
|
outline: -webkit-focus-ring-color auto 1px;
|
|
8011
8314
|
}
|
|
8012
8315
|
`
|
|
@@ -8161,23 +8464,27 @@
|
|
|
8161
8464
|
container.appendChild(detailsElement);
|
|
8162
8465
|
return container;
|
|
8163
8466
|
};
|
|
8164
|
-
const createReaderWithEnhancers =
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
|
|
8168
|
-
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8467
|
+
const createReaderWithEnhancers = (
|
|
8468
|
+
//__
|
|
8469
|
+
loadingEnhancer(
|
|
8470
|
+
webkitEnhancer(
|
|
8471
|
+
fontsEnhancer(
|
|
8472
|
+
linksEnhancer(
|
|
8473
|
+
accessibilityEnhancer(
|
|
8474
|
+
resourcesEnhancer(
|
|
8475
|
+
utilsEnhancer(
|
|
8476
|
+
layoutEnhancer(
|
|
8477
|
+
zoomEnhancer(
|
|
8478
|
+
mediaEnhancer(
|
|
8479
|
+
chromeEnhancer(
|
|
8480
|
+
navigationEnhancer(
|
|
8481
|
+
themeEnhancer(
|
|
8482
|
+
hotkeysEnhancer(
|
|
8483
|
+
paginationEnhancer(
|
|
8484
|
+
progressionEnhancer(
|
|
8485
|
+
// __
|
|
8486
|
+
createReader
|
|
8487
|
+
)
|
|
8181
8488
|
)
|
|
8182
8489
|
)
|
|
8183
8490
|
)
|