@prose-reader/core 1.117.0 → 1.118.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/cfi/generate/generateCfiForSpineItemPage.d.ts +1 -1
- package/dist/cfi/generate/getItemAnchor.d.ts +1 -1
- package/dist/cfi/generate/getRootCfi.d.ts +1 -1
- package/dist/cfi/lookup/resolveCfi.d.ts +2 -236
- package/dist/context/Context.d.ts +1 -1
- package/dist/createReaderWithEnhancer.d.ts +11 -245
- package/dist/enhancers/events/normalizeEventForViewport.d.ts +2 -1
- package/dist/enhancers/events/translateFramePositionIntoPage.d.ts +12 -0
- package/dist/enhancers/html/enhancer.d.ts +2 -0
- package/dist/enhancers/html/renderer/HtmlRenderer.d.ts +26 -0
- package/dist/{spineItem/frame/loader → enhancers/html/renderer}/attachFrameSrc.d.ts +4 -2
- package/dist/{spineItem/frame → enhancers/html/renderer}/createHtmlPageFromResource.d.ts +1 -1
- package/dist/enhancers/html/renderer/prePaginated/renderPrePaginated.d.ts +31 -0
- package/dist/enhancers/html/renderer/reflowable/renderReflowable.d.ts +22 -0
- package/dist/enhancers/loading/constants.d.ts +2 -0
- package/dist/enhancers/loading/createLoadingElement.d.ts +7 -0
- package/dist/enhancers/{loadingEnhancer.d.ts → loading/loadingEnhancer.d.ts} +3 -3
- package/dist/enhancers/media/ImageRenderer.d.ts +15 -0
- package/dist/enhancers/media/media.d.ts +2 -0
- package/dist/enhancers/navigation/resolvers/getNavigationForLeftOrTopPage.d.ts +1 -1
- package/dist/enhancers/navigation/resolvers/getNavigationForRightOrBottomPage.d.ts +1 -1
- package/dist/enhancers/navigation/resolvers/getSpineItemPositionForLeftPage.d.ts +1 -1
- package/dist/enhancers/navigation/resolvers/getSpineItemPositionForRightPage.d.ts +1 -1
- package/dist/enhancers/progression.d.ts +1 -1
- package/dist/hooks/types.d.ts +19 -9
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2314 -2181
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +3010 -2877
- package/dist/index.umd.cjs.map +1 -1
- package/dist/navigation/Navigator.d.ts +6 -6
- package/dist/navigation/resolvers/NavigationResolver.d.ts +1 -1
- package/dist/navigation/resolvers/getNavigationForSpineItemPage.d.ts +1 -1
- package/dist/navigation/resolvers/getNavigationFromSpineItemPosition.d.ts +1 -1
- package/dist/reader.d.ts +3 -237
- package/dist/settings/SettingsManager.d.ts +2 -1
- package/dist/settings/types.d.ts +9 -1
- package/dist/spine/SpineItemsManager.d.ts +6 -591
- package/dist/spine/SpineItemsObserver.d.ts +2 -1
- package/dist/spine/SpineLayout.d.ts +1 -1
- package/dist/spine/locator/SpineLocator.d.ts +5 -473
- package/dist/spine/locator/getAbsolutePageIndexFromPageIndex.d.ts +1 -1
- package/dist/spine/locator/getSpineInfoFromAbsolutePageIndex.d.ts +2 -118
- package/dist/spine/locator/getSpineItemFromPosition.d.ts +1 -118
- package/dist/spineItem/DocumentRenderer.d.ts +48 -0
- package/dist/spineItem/ResourceHandler.d.ts +15 -0
- package/dist/spineItem/SpineItem.d.ts +64 -0
- package/dist/spineItem/locationResolver.d.ts +1 -1
- package/dist/spineItem/navigationResolver.d.ts +1 -1
- package/dist/utils/frames.d.ts +15 -0
- package/package.json +3 -3
- package/dist/enhancers/media.d.ts +0 -2
- package/dist/spineItem/commonSpineItem.d.ts +0 -128
- package/dist/spineItem/createSpineItem.d.ts +0 -130
- package/dist/spineItem/frame/FrameItem.d.ts +0 -43
- package/dist/spineItem/frame/loader/configureFrame.d.ts +0 -9
- package/dist/spineItem/frame/loader/loadFrame.d.ts +0 -11
- package/dist/spineItem/frame/loader/loader.d.ts +0 -22
- package/dist/spineItem/frame/loader/unloadFrame.d.ts +0 -8
- package/dist/spineItem/frame/loader/waitForFrameLoad.d.ts +0 -2
- package/dist/spineItem/frame/loader/waitForFrameReady.d.ts +0 -2
- package/dist/spineItem/prePaginatedSpineItem.d.ts +0 -129
- package/dist/spineItem/reflowable/ReflowableSpineItems.d.ts +0 -128
- package/dist/spineItem/styles/getStyleForViewportDocument.d.ts +0 -1
- /package/dist/{spineItem/frame/loader → enhancers/html/renderer}/createFrameElement.d.ts +0 -0
- /package/dist/{spineItem → enhancers/html/renderer}/reflowable/styles.d.ts +0 -0
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { takeUntil, Subject, combineLatest, map as map$1, switchMap, merge, EMPTY, fromEvent, withLatestFrom, NEVER, Observable, of, scheduled, animationFrameScheduler, 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,
|
|
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,
|
|
3
|
-
import { shallowMergeIfDefined, isShallowEqual,
|
|
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";
|
|
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) => {
|
|
6
6
|
const reader = next(options);
|
|
@@ -13,9 +13,11 @@ const chromeEnhancer = (next) => (options) => {
|
|
|
13
13
|
};
|
|
14
14
|
containerElement.addEventListener(`scroll`, onScroll);
|
|
15
15
|
});
|
|
16
|
-
reader.hookManager.register(`item.
|
|
17
|
-
var _a;
|
|
18
|
-
(_a =
|
|
16
|
+
reader.hookManager.register(`item.onDocumentLoad`, ({ layers }) => {
|
|
17
|
+
var _a, _b;
|
|
18
|
+
const frame = (_a = layers[0]) == null ? void 0 : _a.element;
|
|
19
|
+
if (!(frame instanceof HTMLIFrameElement)) return;
|
|
20
|
+
(_b = frame.contentDocument) == null ? void 0 : _b.body.setAttribute(`tabindex`, `-1`);
|
|
19
21
|
});
|
|
20
22
|
return reader;
|
|
21
23
|
};
|
|
@@ -142,21 +144,19 @@ const fontsEnhancer = (next) => (options) => {
|
|
|
142
144
|
`;
|
|
143
145
|
const applyChangeToSpineItems = (requireLayout) => {
|
|
144
146
|
reader.spineItemsManager.items.forEach((item) => {
|
|
145
|
-
var _a
|
|
147
|
+
var _a;
|
|
146
148
|
if (item.item.renditionLayout !== `pre-paginated`) {
|
|
147
|
-
(
|
|
148
|
-
(_d = (_c = item.frame).addStyle) == null ? void 0 : _d.call(_c, `prose-reader-fonts`, getStyle());
|
|
149
|
+
(_a = item.upsertCSS) == null ? void 0 : _a.call(item, `prose-reader-fonts`, getStyle());
|
|
149
150
|
}
|
|
150
151
|
});
|
|
151
152
|
if (requireLayout) {
|
|
152
153
|
reader.layout();
|
|
153
154
|
}
|
|
154
155
|
};
|
|
155
|
-
reader.hookManager.register(`item.
|
|
156
|
+
reader.hookManager.register(`item.onDocumentLoad`, ({ itemId }) => {
|
|
156
157
|
const item = reader.spineItemsManager.get(itemId);
|
|
157
158
|
if ((item == null ? void 0 : item.item.renditionLayout) !== `pre-paginated`) {
|
|
158
|
-
item == null ? void 0 : item.
|
|
159
|
-
item == null ? void 0 : item.frame.addStyle(`prose-reader-fonts`, getStyle());
|
|
159
|
+
item == null ? void 0 : item.upsertCSS(`prose-reader-fonts`, getStyle());
|
|
160
160
|
}
|
|
161
161
|
});
|
|
162
162
|
const shouldRequireLayout = (source) => source.pipe(
|
|
@@ -211,10 +211,12 @@ const hotkeysEnhancer = (next) => (options) => {
|
|
|
211
211
|
switchMap(
|
|
212
212
|
(spineItems) => merge(
|
|
213
213
|
...spineItems.map(
|
|
214
|
-
(item) => item
|
|
215
|
-
switchMap(
|
|
216
|
-
|
|
217
|
-
|
|
214
|
+
(item) => item.loaded$.pipe(
|
|
215
|
+
switchMap(() => {
|
|
216
|
+
var _a;
|
|
217
|
+
const element = (_a = item.renderer.layers[0]) == null ? void 0 : _a.element;
|
|
218
|
+
return element instanceof HTMLIFrameElement && (element == null ? void 0 : element.contentDocument) ? navigateOnKey(element.contentDocument) : EMPTY;
|
|
219
|
+
})
|
|
218
220
|
)
|
|
219
221
|
)
|
|
220
222
|
)
|
|
@@ -312,19 +314,94 @@ const waitForSwitch = (waitForStream) => (stream) => stream.pipe(
|
|
|
312
314
|
)
|
|
313
315
|
)
|
|
314
316
|
);
|
|
317
|
+
const getAttributeValueFromString = (string, key) => {
|
|
318
|
+
const regExp = new RegExp(key + `\\s*=\\s*([0-9.]+)`, `i`);
|
|
319
|
+
const match = string.match(regExp) || [];
|
|
320
|
+
const firstMatch = match[1] || `0`;
|
|
321
|
+
return match && parseFloat(firstMatch) || 0;
|
|
322
|
+
};
|
|
323
|
+
const injectCSS = (frameElement, id, style, prepend) => {
|
|
324
|
+
if (frameElement && frameElement.contentDocument && frameElement.contentDocument.head) {
|
|
325
|
+
const userStyle = document.createElement(`style`);
|
|
326
|
+
userStyle.id = id;
|
|
327
|
+
userStyle.innerHTML = style;
|
|
328
|
+
if (prepend) {
|
|
329
|
+
frameElement.contentDocument.head.prepend(userStyle);
|
|
330
|
+
} else {
|
|
331
|
+
frameElement.contentDocument.head.appendChild(userStyle);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
const removeCSS = (frameElement, id) => {
|
|
336
|
+
if (frameElement && frameElement.contentDocument && frameElement.contentDocument.head) {
|
|
337
|
+
const styleElement = frameElement.contentDocument.getElementById(id);
|
|
338
|
+
if (styleElement) {
|
|
339
|
+
styleElement.remove();
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
const upsertCSS = (frameElement, id, style, prepend) => {
|
|
344
|
+
if (!frameElement) return;
|
|
345
|
+
removeCSS(frameElement, id);
|
|
346
|
+
injectCSS(frameElement, id, style, prepend);
|
|
347
|
+
};
|
|
348
|
+
const getFrameViewportInfo = (frame) => {
|
|
349
|
+
if (frame && (frame == null ? void 0 : frame.contentDocument)) {
|
|
350
|
+
const doc = frame.contentDocument;
|
|
351
|
+
const viewportMetaElement = doc.querySelector(`meta[name='viewport']`);
|
|
352
|
+
if (viewportMetaElement) {
|
|
353
|
+
const viewportContent = viewportMetaElement.getAttribute(`content`);
|
|
354
|
+
if (viewportContent) {
|
|
355
|
+
const width = getAttributeValueFromString(viewportContent, `width`);
|
|
356
|
+
const height = getAttributeValueFromString(viewportContent, `height`);
|
|
357
|
+
if (width > 0 && height > 0) {
|
|
358
|
+
return {
|
|
359
|
+
hasViewport: true,
|
|
360
|
+
width,
|
|
361
|
+
height
|
|
362
|
+
};
|
|
363
|
+
} else {
|
|
364
|
+
return { hasViewport: true };
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return { hasViewport: false };
|
|
370
|
+
};
|
|
371
|
+
const waitForFrameLoad = (stream) => stream.pipe(
|
|
372
|
+
switchMap(
|
|
373
|
+
(frame) => fromEvent(frame, `load`).pipe(
|
|
374
|
+
take$1(1),
|
|
375
|
+
map$1(() => frame)
|
|
376
|
+
)
|
|
377
|
+
)
|
|
378
|
+
);
|
|
379
|
+
const waitForFrameReady = (stream) => stream.pipe(
|
|
380
|
+
switchMap(
|
|
381
|
+
(frame) => {
|
|
382
|
+
var _a;
|
|
383
|
+
return from(((_a = frame == null ? void 0 : frame.contentDocument) == null ? void 0 : _a.fonts.ready) || of(void 0)).pipe(
|
|
384
|
+
map$1(() => frame)
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
)
|
|
388
|
+
);
|
|
315
389
|
const fixReflowable = (reader) => {
|
|
316
390
|
reader.hookManager.register(
|
|
317
391
|
`item.onAfterLayout`,
|
|
318
392
|
({ item, blankPagePosition, minimumWidth }) => {
|
|
393
|
+
var _a, _b;
|
|
319
394
|
const spineItem = reader.spineItemsManager.get(item.id);
|
|
320
|
-
|
|
321
|
-
|
|
395
|
+
const element = (_a = spineItem == null ? void 0 : spineItem.renderer.layers[0]) == null ? void 0 : _a.element;
|
|
396
|
+
if (!((spineItem == null ? void 0 : spineItem.item.renditionLayout) === `reflowable`) || !(element instanceof HTMLIFrameElement))
|
|
397
|
+
return;
|
|
398
|
+
const { hasViewport } = getFrameViewportInfo(element);
|
|
322
399
|
const { width: pageWidth } = reader.context.getPageSize();
|
|
323
|
-
const frameElement = spineItem == null ? void 0 : spineItem.
|
|
324
|
-
if (
|
|
400
|
+
const frameElement = (_b = spineItem == null ? void 0 : spineItem.renderer.layers[0]) == null ? void 0 : _b.element;
|
|
401
|
+
if (hasViewport) {
|
|
325
402
|
const spineManagerWantAFullWidthItem = pageWidth < minimumWidth;
|
|
326
403
|
const noBlankPageAsked = blankPagePosition === `none`;
|
|
327
|
-
if (noBlankPageAsked && spineManagerWantAFullWidthItem) {
|
|
404
|
+
if (noBlankPageAsked && spineManagerWantAFullWidthItem && frameElement instanceof HTMLIFrameElement) {
|
|
328
405
|
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
329
406
|
`left`,
|
|
330
407
|
reader.context.isRTL() ? `75%` : `25%`
|
|
@@ -378,57 +455,77 @@ const layoutEnhancer = (next) => (options) => {
|
|
|
378
455
|
reader.hookManager.register(`onViewportOffsetAdjust`, () => {
|
|
379
456
|
let hasRedrawn = false;
|
|
380
457
|
reader.spineItemsManager.items.forEach((item) => {
|
|
381
|
-
|
|
458
|
+
var _a;
|
|
459
|
+
const frame = (_a = item.renderer.layers[0]) == null ? void 0 : _a.element;
|
|
382
460
|
if (!hasRedrawn && frame) {
|
|
383
461
|
void frame.getBoundingClientRect().left;
|
|
384
462
|
hasRedrawn = true;
|
|
385
463
|
}
|
|
386
464
|
});
|
|
387
465
|
});
|
|
388
|
-
reader.hookManager.register(
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
columnGap = pageVerticalMargin2 * 2;
|
|
404
|
-
}
|
|
405
|
-
frame == null ? void 0 : frame.removeStyle(`prose-layout-enhancer-css`);
|
|
406
|
-
frame == null ? void 0 : frame.addStyle(
|
|
407
|
-
`prose-layout-enhancer-css`,
|
|
408
|
-
`
|
|
409
|
-
body {
|
|
410
|
-
width: ${width}px !important;
|
|
411
|
-
margin: ${pageVerticalMargin2}px ${pageHorizontalMargin2}px !important;
|
|
412
|
-
column-gap: ${columnGap}px !important;
|
|
413
|
-
column-width: ${columnWidth}px !important;
|
|
414
|
-
height: ${columnHeight}px !important;
|
|
415
|
-
}
|
|
416
|
-
img, video, audio, object, svg {
|
|
417
|
-
max-width: ${columnWidth}px !important;
|
|
418
|
-
max-height: ${columnHeight}px !important;
|
|
419
|
-
}
|
|
420
|
-
table {
|
|
421
|
-
max-width: ${columnWidth}px !important;
|
|
422
|
-
}
|
|
423
|
-
td {
|
|
424
|
-
max-width: ${columnWidth}px;
|
|
425
|
-
}
|
|
426
|
-
`
|
|
427
|
-
);
|
|
466
|
+
reader.hookManager.register(`item.onBeforeLayout`, ({ item }) => {
|
|
467
|
+
const spineItem = reader.spineItemsManager.get(item.id);
|
|
468
|
+
const mimeType = item.mediaType ?? detectMimeTypeFromName(item.href);
|
|
469
|
+
const isImageType = !!(mimeType == null ? void 0 : mimeType.startsWith(`image/`));
|
|
470
|
+
const { pageHorizontalMargin: pageHorizontalMargin2 = 0, pageVerticalMargin: pageVerticalMargin2 = 0 } = settingsManager.values;
|
|
471
|
+
const pageSize = reader.context.getPageSize();
|
|
472
|
+
if ((spineItem == null ? void 0 : spineItem.item.renditionLayout) === `reflowable` && !isImageType) {
|
|
473
|
+
let columnWidth = pageSize.width - pageHorizontalMargin2 * 2;
|
|
474
|
+
const columnHeight = pageSize.height - pageVerticalMargin2 * 2;
|
|
475
|
+
let width = pageSize.width - pageHorizontalMargin2 * 2;
|
|
476
|
+
let columnGap = pageHorizontalMargin2 * 2;
|
|
477
|
+
if (spineItem.isUsingVerticalWriting()) {
|
|
478
|
+
width = pageSize.width - pageHorizontalMargin2 * 2;
|
|
479
|
+
columnWidth = columnHeight;
|
|
480
|
+
columnGap = pageVerticalMargin2 * 2;
|
|
428
481
|
}
|
|
482
|
+
spineItem == null ? void 0 : spineItem.upsertCSS(
|
|
483
|
+
`prose-layout-enhancer-css`,
|
|
484
|
+
`
|
|
485
|
+
body {
|
|
486
|
+
width: ${width}px !important;
|
|
487
|
+
margin: ${pageVerticalMargin2}px ${pageHorizontalMargin2}px !important;
|
|
488
|
+
column-gap: ${columnGap}px !important;
|
|
489
|
+
column-width: ${columnWidth}px !important;
|
|
490
|
+
height: ${columnHeight}px !important;
|
|
491
|
+
}
|
|
492
|
+
img, video, audio, object, svg {
|
|
493
|
+
max-width: ${columnWidth}px !important;
|
|
494
|
+
max-height: ${columnHeight}px !important;
|
|
495
|
+
}
|
|
496
|
+
table {
|
|
497
|
+
max-width: ${columnWidth}px !important;
|
|
498
|
+
}
|
|
499
|
+
td {
|
|
500
|
+
max-width: ${columnWidth}px;
|
|
501
|
+
}
|
|
502
|
+
`
|
|
503
|
+
);
|
|
429
504
|
}
|
|
430
|
-
);
|
|
505
|
+
});
|
|
431
506
|
fixReflowable(reader);
|
|
507
|
+
reader.hookManager.register(`item.onDocumentCreated`, ({ layers }) => {
|
|
508
|
+
layers.forEach(({ element }) => {
|
|
509
|
+
element.style.opacity = `0`;
|
|
510
|
+
element.style.transition = `opacity 300ms`;
|
|
511
|
+
});
|
|
512
|
+
});
|
|
513
|
+
reader.hookManager.register(`item.onBeforeLayout`, ({ item }) => {
|
|
514
|
+
const spineItem = reader.spineItemsManager.get(item.id);
|
|
515
|
+
spineItem == null ? void 0 : spineItem.renderer.layers.forEach(({ element }) => {
|
|
516
|
+
if (reader.settings.values.computedPageTurnMode !== `scrollable`) {
|
|
517
|
+
element.setAttribute(`tab-index`, `0`);
|
|
518
|
+
}
|
|
519
|
+
});
|
|
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 }) => {
|
|
525
|
+
element.style.opacity = `1`;
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
});
|
|
432
529
|
const observeContainerResize = (container) => new Observable((observer) => {
|
|
433
530
|
const resizeObserver = new ResizeObserver(() => {
|
|
434
531
|
observer.next();
|
|
@@ -573,7 +670,10 @@ const linksEnhancer = (next) => (options) => {
|
|
|
573
670
|
}
|
|
574
671
|
return false;
|
|
575
672
|
};
|
|
576
|
-
reader.hookManager.register(`item.
|
|
673
|
+
reader.hookManager.register(`item.onDocumentLoad`, ({ layers }) => {
|
|
674
|
+
var _a;
|
|
675
|
+
const frame = (_a = layers[0]) == null ? void 0 : _a.element;
|
|
676
|
+
if (!(frame instanceof HTMLIFrameElement)) return;
|
|
577
677
|
if (frame == null ? void 0 : frame.contentDocument) {
|
|
578
678
|
Array.from(frame.contentDocument.querySelectorAll(`a`)).forEach(
|
|
579
679
|
(element) => element.addEventListener(`click`, (e) => {
|
|
@@ -1404,16 +1504,14 @@ const themeEnhancer = (next) => (options) => {
|
|
|
1404
1504
|
};
|
|
1405
1505
|
const applyChangeToSpineItem = () => {
|
|
1406
1506
|
reader.spineItemsManager.items.forEach((item) => {
|
|
1407
|
-
var _a
|
|
1408
|
-
(
|
|
1409
|
-
(_d = (_c = item.frame).addStyle) == null ? void 0 : _d.call(_c, `prose-reader-theme`, getStyle());
|
|
1507
|
+
var _a;
|
|
1508
|
+
(_a = item.upsertCSS) == null ? void 0 : _a.call(item, `prose-reader-theme`, getStyle());
|
|
1410
1509
|
applyChangeToSpineItemElement({ container: item.element });
|
|
1411
1510
|
});
|
|
1412
1511
|
};
|
|
1413
|
-
reader.hookManager.register(`item.
|
|
1512
|
+
reader.hookManager.register(`item.onDocumentLoad`, ({ itemId }) => {
|
|
1414
1513
|
const item = reader.spineItemsManager.get(itemId);
|
|
1415
|
-
item == null ? void 0 : item.
|
|
1416
|
-
item == null ? void 0 : item.frame.addStyle(`prose-reader-theme`, getStyle());
|
|
1514
|
+
item == null ? void 0 : item.upsertCSS(`prose-reader-theme`, getStyle());
|
|
1417
1515
|
});
|
|
1418
1516
|
reader.spineItemsManager.items$.pipe(
|
|
1419
1517
|
tap(
|
|
@@ -2119,10 +2217,10 @@ const createSpineItemLocator = ({
|
|
|
2119
2217
|
return void 0;
|
|
2120
2218
|
};
|
|
2121
2219
|
const getFirstNodeOrRangeAtPage = (pageIndex, spineItem) => {
|
|
2122
|
-
var _a, _b;
|
|
2220
|
+
var _a, _b, _c;
|
|
2123
2221
|
const pageSize = context.getPageSize();
|
|
2124
|
-
const frame = (_a = spineItem.
|
|
2125
|
-
if (((
|
|
2222
|
+
const frame = (_b = (_a = spineItem.renderer) == null ? void 0 : _a.layers[0]) == null ? void 0 : _b.element;
|
|
2223
|
+
if (frame instanceof HTMLIFrameElement && ((_c = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _c.document) && // very important because it is being used by next functions
|
|
2126
2224
|
frame.contentWindow.document.body !== null) {
|
|
2127
2225
|
const { x: left, y: top } = getSpineItemPositionFromPageIndex({
|
|
2128
2226
|
pageIndex,
|
|
@@ -3335,22 +3433,25 @@ const resolveCfi = ({
|
|
|
3335
3433
|
if (!spineItem) return void 0;
|
|
3336
3434
|
const { cleanedCfi, offset } = extractProseMetadataFromCfi(cfi);
|
|
3337
3435
|
const cfiHandler = new CfiHandler(cleanedCfi, {});
|
|
3338
|
-
const
|
|
3339
|
-
if (
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
node,
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3436
|
+
const rendererElement = (_a = spineItem.renderer.layers[0]) == null ? void 0 : _a.element;
|
|
3437
|
+
if (rendererElement instanceof HTMLIFrameElement) {
|
|
3438
|
+
const doc = (_b = rendererElement.contentWindow) == null ? void 0 : _b.document;
|
|
3439
|
+
if (doc) {
|
|
3440
|
+
try {
|
|
3441
|
+
const { node, offset: resolvedOffset } = cfiHandler.resolve(doc, {});
|
|
3442
|
+
return {
|
|
3443
|
+
node,
|
|
3444
|
+
offset: offset ?? resolvedOffset,
|
|
3445
|
+
spineItemIndex,
|
|
3446
|
+
spineItem
|
|
3447
|
+
};
|
|
3448
|
+
} catch (e) {
|
|
3449
|
+
Report.error(e);
|
|
3450
|
+
return {
|
|
3451
|
+
spineItemIndex,
|
|
3452
|
+
spineItem
|
|
3453
|
+
};
|
|
3454
|
+
}
|
|
3354
3455
|
}
|
|
3355
3456
|
}
|
|
3356
3457
|
return {
|
|
@@ -3551,7 +3652,8 @@ class ViewportNavigator extends DestroyableClass {
|
|
|
3551
3652
|
if (settings.values.computedPageTurnMode === `scrollable`) {
|
|
3552
3653
|
element.style.removeProperty(`transform`);
|
|
3553
3654
|
element.style.removeProperty(`transition`);
|
|
3554
|
-
element.style.
|
|
3655
|
+
element.style.overflowY = `scroll`;
|
|
3656
|
+
element.style.overflowX = `hidden`;
|
|
3555
3657
|
} else {
|
|
3556
3658
|
element.style.removeProperty(`overflow`);
|
|
3557
3659
|
element.style.removeProperty(`overflowY`);
|
|
@@ -4703,8 +4805,9 @@ const createNavigator = ({
|
|
|
4703
4805
|
getElement: () => element$.getValue()
|
|
4704
4806
|
};
|
|
4705
4807
|
};
|
|
4706
|
-
class SettingsManager3 {
|
|
4808
|
+
class SettingsManager3 extends DestroyableClass {
|
|
4707
4809
|
constructor(initialSettings) {
|
|
4810
|
+
super();
|
|
4708
4811
|
const settingsWithDefaults = {
|
|
4709
4812
|
...this.getDefaultSettings(),
|
|
4710
4813
|
...initialSettings
|
|
@@ -4750,6 +4853,7 @@ class SettingsManager3 {
|
|
|
4750
4853
|
return this._settings$;
|
|
4751
4854
|
}
|
|
4752
4855
|
destroy() {
|
|
4856
|
+
super.destroy();
|
|
4753
4857
|
this.outputSettingsUpdateSubject.complete();
|
|
4754
4858
|
}
|
|
4755
4859
|
}
|
|
@@ -4903,7 +5007,7 @@ class HookManager {
|
|
|
4903
5007
|
const getItemAnchor = (spineItem) => `|[prose~anchor~${encodeURIComponent(spineItem.item.id)}]`;
|
|
4904
5008
|
const getRootCfi = (spineItem) => {
|
|
4905
5009
|
const itemAnchor = getItemAnchor(spineItem);
|
|
4906
|
-
return `epubcfi(/0${itemAnchor})
|
|
5010
|
+
return `epubcfi(/0${itemAnchor})`;
|
|
4907
5011
|
};
|
|
4908
5012
|
const generateCfiForSpineItemPage = Report.measurePerformance(
|
|
4909
5013
|
`getCfi`,
|
|
@@ -4918,16 +5022,16 @@ const generateCfiForSpineItemPage = Report.measurePerformance(
|
|
|
4918
5022
|
pageIndex,
|
|
4919
5023
|
spineItem
|
|
4920
5024
|
);
|
|
4921
|
-
const
|
|
5025
|
+
const rendererElement = (_a = spineItem.renderer.layers[0]) == null ? void 0 : _a.element;
|
|
4922
5026
|
const itemAnchor = getItemAnchor(spineItem);
|
|
4923
5027
|
const offset = `|[prose~offset~${(nodeOrRange == null ? void 0 : nodeOrRange.offset) || 0}]`;
|
|
4924
|
-
if (nodeOrRange &&
|
|
5028
|
+
if (nodeOrRange && rendererElement instanceof HTMLIFrameElement && ((_b = rendererElement.contentWindow) == null ? void 0 : _b.document)) {
|
|
4925
5029
|
const cfiString = CfiHandler.generate(
|
|
4926
5030
|
nodeOrRange.node,
|
|
4927
5031
|
0,
|
|
4928
5032
|
`${itemAnchor}${offset}`
|
|
4929
5033
|
);
|
|
4930
|
-
return cfiString;
|
|
5034
|
+
return cfiString.trim();
|
|
4931
5035
|
}
|
|
4932
5036
|
return getRootCfi(spineItem);
|
|
4933
5037
|
}
|
|
@@ -5116,1679 +5220,368 @@ class SpineItemsManager extends DestroyableClass {
|
|
|
5116
5220
|
this.orderedSpineItemsSubject.value.forEach((item) => item.destroy());
|
|
5117
5221
|
}
|
|
5118
5222
|
}
|
|
5119
|
-
const
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
};
|
|
5125
|
-
const getIntrinsicDimensionsFromBase64Img = (data) => new Promise((resolve, reject) => {
|
|
5126
|
-
const image = new Image();
|
|
5127
|
-
image.src = data;
|
|
5128
|
-
image.onload = () => {
|
|
5129
|
-
resolve({ height: image.naturalHeight, width: image.naturalWidth });
|
|
5130
|
-
};
|
|
5131
|
-
image.onerror = reject;
|
|
5132
|
-
});
|
|
5133
|
-
const createHtmlPageFromResource = async (resourceResponse, item) => {
|
|
5134
|
-
if (typeof resourceResponse === `string`) return resourceResponse;
|
|
5135
|
-
const contentType = parseContentType(resourceResponse.headers.get(`Content-Type`) || ``) || detectMimeTypeFromName(item.href);
|
|
5136
|
-
if ([`image/jpg`, `image/jpeg`, `image/png`, `image/webp`].some(
|
|
5137
|
-
(mime) => mime === contentType
|
|
5138
|
-
)) {
|
|
5139
|
-
const data = await getBase64FromBlob(await resourceResponse.blob());
|
|
5140
|
-
const { height, width } = await getIntrinsicDimensionsFromBase64Img(data);
|
|
5141
|
-
return `
|
|
5142
|
-
<html>
|
|
5143
|
-
<head>
|
|
5144
|
-
${item.renditionLayout !== `reflowable` ? `<meta name="viewport" content="width=${width}, height=${height}">` : ``}
|
|
5145
|
-
</head>
|
|
5146
|
-
<body style="margin: 0px;" tab-index="-1;">
|
|
5147
|
-
<img
|
|
5148
|
-
src="${data}"
|
|
5149
|
-
style="max-width: 100%;height:100%;object-fit:contain;"
|
|
5150
|
-
>
|
|
5151
|
-
</body>
|
|
5152
|
-
</html>
|
|
5153
|
-
`;
|
|
5154
|
-
}
|
|
5155
|
-
if ([`text/plain`].some((mime) => mime === contentType)) {
|
|
5156
|
-
const data = await resourceResponse.text();
|
|
5157
|
-
return `
|
|
5158
|
-
<!DOCTYPE html>
|
|
5159
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
|
|
5160
|
-
<head>
|
|
5161
|
-
<style>
|
|
5162
|
-
pre {
|
|
5163
|
-
white-space: pre;
|
|
5164
|
-
white-space: pre-wrap;
|
|
5165
|
-
word-wrap: break-word;
|
|
5166
|
-
}
|
|
5167
|
-
</style>
|
|
5168
|
-
</head>
|
|
5169
|
-
<body>
|
|
5170
|
-
<pre>${data}</pre>
|
|
5171
|
-
</body>
|
|
5172
|
-
</html>
|
|
5173
|
-
`;
|
|
5174
|
-
}
|
|
5175
|
-
const content = await resourceResponse.text();
|
|
5176
|
-
return content;
|
|
5177
|
-
};
|
|
5178
|
-
const attachFrameSrc = ({
|
|
5179
|
-
settings,
|
|
5180
|
-
item
|
|
5223
|
+
const getSpineItemFromPosition = ({
|
|
5224
|
+
position,
|
|
5225
|
+
spineItemsManager,
|
|
5226
|
+
spineLayout,
|
|
5227
|
+
settings
|
|
5181
5228
|
}) => {
|
|
5182
|
-
const
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
))) {
|
|
5196
|
-
frameElement == null ? void 0 : frameElement.setAttribute(`src`, item.href);
|
|
5197
|
-
return of(frameElement);
|
|
5198
|
-
} else {
|
|
5199
|
-
const fetchFn = fetchResource || (() => fetch(item.href));
|
|
5200
|
-
return from(fetchFn(item)).pipe(
|
|
5201
|
-
mergeMap((response) => getHtmlFromResource(response)),
|
|
5202
|
-
tap$1((htmlDoc) => {
|
|
5203
|
-
if (htmlDoc) {
|
|
5204
|
-
const blob = new Blob([htmlDoc], { type: "text/html" });
|
|
5205
|
-
const blobURL = URL.createObjectURL(blob);
|
|
5206
|
-
frameElement == null ? void 0 : frameElement.setAttribute(`src`, blobURL);
|
|
5207
|
-
}
|
|
5208
|
-
}),
|
|
5209
|
-
map$1(() => frameElement),
|
|
5210
|
-
catchError((e) => {
|
|
5211
|
-
Report.error(
|
|
5212
|
-
`Error while trying to fetch or load resource for item ${item.id}`
|
|
5213
|
-
);
|
|
5214
|
-
console.error(e);
|
|
5215
|
-
return of(frameElement);
|
|
5216
|
-
})
|
|
5217
|
-
);
|
|
5218
|
-
}
|
|
5219
|
-
})
|
|
5220
|
-
);
|
|
5229
|
+
const spineItem = spineItemsManager.items.find((item) => {
|
|
5230
|
+
const { left, right, bottom, top } = spineLayout.getAbsolutePositionOf(item);
|
|
5231
|
+
const isWithinXAxis = position.x >= left && position.x < right;
|
|
5232
|
+
if (settings.values.computedPageTurnDirection === `horizontal`) {
|
|
5233
|
+
return isWithinXAxis;
|
|
5234
|
+
} else {
|
|
5235
|
+
return isWithinXAxis && position.y >= top && position.y < bottom;
|
|
5236
|
+
}
|
|
5237
|
+
});
|
|
5238
|
+
if (position.x === 0 && !spineItem) {
|
|
5239
|
+
return spineItemsManager.items[0];
|
|
5240
|
+
}
|
|
5241
|
+
return spineItem;
|
|
5221
5242
|
};
|
|
5222
|
-
const
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5243
|
+
const isItemVisibleByThresholdForPosition = ({
|
|
5244
|
+
itemHeight,
|
|
5245
|
+
itemWidth,
|
|
5246
|
+
visibleWidthOfItem,
|
|
5247
|
+
visibleHeightOfItem,
|
|
5248
|
+
threshold
|
|
5226
5249
|
}) => {
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
var _a;
|
|
5232
|
-
const body = (_a = frame.contentDocument) == null ? void 0 : _a.body;
|
|
5233
|
-
if (!body) {
|
|
5234
|
-
Report.error(`Something went wrong on iframe load ${item.id}`);
|
|
5235
|
-
return EMPTY;
|
|
5236
|
-
}
|
|
5237
|
-
frame.setAttribute(`role`, `main`);
|
|
5238
|
-
if ((frame == null ? void 0 : frame.contentDocument) && body) ;
|
|
5239
|
-
if (settings.values.computedPageTurnMode !== `scrollable`) {
|
|
5240
|
-
frame.setAttribute(`tab-index`, `0`);
|
|
5241
|
-
}
|
|
5242
|
-
const hookResults = hookManager.execute(`item.onLoad`, item.id, {
|
|
5243
|
-
itemId: item.id,
|
|
5244
|
-
frame
|
|
5245
|
-
}).filter(
|
|
5246
|
-
(result) => result instanceof Observable
|
|
5247
|
-
);
|
|
5248
|
-
return combineLatest([of(null), ...hookResults]).pipe(map$1(() => frame));
|
|
5249
|
-
})
|
|
5250
|
-
);
|
|
5250
|
+
const visibleWidthRatioOfSpineItem = visibleWidthOfItem / itemWidth;
|
|
5251
|
+
const visibleHeightRatioOfSpineItem = visibleHeightOfItem / itemHeight;
|
|
5252
|
+
const isItemVisibleEnough = visibleWidthRatioOfSpineItem >= threshold && visibleHeightRatioOfSpineItem >= threshold;
|
|
5253
|
+
return isItemVisibleEnough;
|
|
5251
5254
|
};
|
|
5252
|
-
const
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
const frame = document.createElement(`iframe`);
|
|
5257
|
-
frame.frameBorder = `no`;
|
|
5258
|
-
frame.tabIndex = 0;
|
|
5259
|
-
frame.setAttribute(
|
|
5260
|
-
`sandbox`,
|
|
5261
|
-
`
|
|
5262
|
-
allow-same-origin
|
|
5263
|
-
allow-scripts
|
|
5264
|
-
allow-top-navigation-to-custom-protocols
|
|
5265
|
-
`
|
|
5266
|
-
);
|
|
5267
|
-
frame.scrolling = `no`;
|
|
5268
|
-
frame.style.cssText = `
|
|
5269
|
-
visibility: hidden;
|
|
5270
|
-
overflow: hidden;
|
|
5271
|
-
background-color: transparent;
|
|
5272
|
-
border: 0px none transparent;
|
|
5273
|
-
padding: 0px;
|
|
5274
|
-
transition: opacity 300ms;
|
|
5275
|
-
opacity: 0;
|
|
5276
|
-
`;
|
|
5277
|
-
return frame;
|
|
5278
|
-
}
|
|
5279
|
-
);
|
|
5280
|
-
const waitForFrameLoad = (stream) => stream.pipe(
|
|
5281
|
-
switchMap(
|
|
5282
|
-
(frame) => fromEvent(frame, `load`).pipe(
|
|
5283
|
-
take$1(1),
|
|
5284
|
-
map$1(() => frame)
|
|
5285
|
-
)
|
|
5286
|
-
)
|
|
5287
|
-
);
|
|
5288
|
-
const loadFrame = ({
|
|
5289
|
-
settings,
|
|
5290
|
-
item,
|
|
5291
|
-
hookManager,
|
|
5292
|
-
element,
|
|
5293
|
-
onFrameElement,
|
|
5255
|
+
const isItemVisibleOnScreenByThresholdForPosition = ({
|
|
5256
|
+
visibleWidthOfItem,
|
|
5257
|
+
visibleHeightOfItem,
|
|
5258
|
+
threshold,
|
|
5294
5259
|
context
|
|
5295
5260
|
}) => {
|
|
5296
|
-
const
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
onFrameElement(frame);
|
|
5301
|
-
}),
|
|
5302
|
-
attachFrameSrc({ settings, item }),
|
|
5303
|
-
waitForSwitch(context.bridgeEvent.viewportFree$),
|
|
5304
|
-
waitForFrameLoad,
|
|
5305
|
-
waitForSwitch(context.bridgeEvent.viewportFree$),
|
|
5306
|
-
configureFrame({
|
|
5307
|
-
item,
|
|
5308
|
-
settings,
|
|
5309
|
-
hookManager
|
|
5310
|
-
})
|
|
5311
|
-
);
|
|
5261
|
+
const widthRatioOfSpaceTakenInScreen = visibleWidthOfItem / context.state.visibleAreaRect.width;
|
|
5262
|
+
const heightRatioOfSpaceTakenInScreen = visibleHeightOfItem / context.state.visibleAreaRect.height;
|
|
5263
|
+
const isItemVisibleEnoughOnScreen = heightRatioOfSpaceTakenInScreen >= threshold && widthRatioOfSpaceTakenInScreen >= threshold;
|
|
5264
|
+
return isItemVisibleEnoughOnScreen;
|
|
5312
5265
|
};
|
|
5313
|
-
const
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5266
|
+
const getItemVisibilityForPosition = ({
|
|
5267
|
+
itemPosition: {
|
|
5268
|
+
bottom,
|
|
5269
|
+
left,
|
|
5270
|
+
right,
|
|
5271
|
+
top,
|
|
5272
|
+
width: itemWidth,
|
|
5273
|
+
height: itemHeight
|
|
5274
|
+
},
|
|
5275
|
+
threshold,
|
|
5276
|
+
viewportPosition,
|
|
5277
|
+
restrictToScreen,
|
|
5317
5278
|
context
|
|
5318
5279
|
}) => {
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5280
|
+
const viewportLeft = viewportPosition.x;
|
|
5281
|
+
const viewportRight = viewportPosition.x + (context.state.visibleAreaRect.width - 1);
|
|
5282
|
+
const viewportTop = viewportPosition.y;
|
|
5283
|
+
const viewportBottom = Math.max(
|
|
5284
|
+
viewportPosition.y + (context.state.visibleAreaRect.height - 1),
|
|
5285
|
+
0
|
|
5286
|
+
);
|
|
5287
|
+
const visibleWidthOfItem = Math.max(
|
|
5288
|
+
0,
|
|
5289
|
+
Math.min(right, viewportRight) - Math.max(left, viewportLeft)
|
|
5325
5290
|
);
|
|
5291
|
+
const visibleHeightOfItem = Math.max(
|
|
5292
|
+
0,
|
|
5293
|
+
Math.min(bottom, viewportBottom) - Math.max(top, viewportTop)
|
|
5294
|
+
);
|
|
5295
|
+
const itemIsOnTheOuterEdge = visibleWidthOfItem <= 0 || visibleHeightOfItem <= 0;
|
|
5296
|
+
if (itemIsOnTheOuterEdge) return { visible: false };
|
|
5297
|
+
const isItemVisibleEnoughOnScreen = isItemVisibleOnScreenByThresholdForPosition({
|
|
5298
|
+
threshold,
|
|
5299
|
+
visibleHeightOfItem,
|
|
5300
|
+
visibleWidthOfItem,
|
|
5301
|
+
context
|
|
5302
|
+
});
|
|
5303
|
+
if (restrictToScreen) {
|
|
5304
|
+
return { visible: isItemVisibleEnoughOnScreen };
|
|
5305
|
+
}
|
|
5306
|
+
const isItemVisibleEnough = isItemVisibleByThresholdForPosition({
|
|
5307
|
+
itemHeight,
|
|
5308
|
+
itemWidth,
|
|
5309
|
+
threshold,
|
|
5310
|
+
visibleHeightOfItem,
|
|
5311
|
+
visibleWidthOfItem
|
|
5312
|
+
});
|
|
5313
|
+
return {
|
|
5314
|
+
visible: isItemVisibleEnough || isItemVisibleEnoughOnScreen
|
|
5315
|
+
};
|
|
5326
5316
|
};
|
|
5327
|
-
const
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
}
|
|
5333
|
-
)
|
|
5334
|
-
);
|
|
5335
|
-
const createLoader = ({
|
|
5336
|
-
item,
|
|
5337
|
-
parent,
|
|
5317
|
+
const getVisibleSpineItemsFromPosition = ({
|
|
5318
|
+
position,
|
|
5319
|
+
threshold,
|
|
5320
|
+
restrictToScreen,
|
|
5321
|
+
spineItemsManager,
|
|
5338
5322
|
context,
|
|
5339
5323
|
settings,
|
|
5340
|
-
|
|
5324
|
+
spineLayout
|
|
5341
5325
|
}) => {
|
|
5342
|
-
const
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
ignoreElements(),
|
|
5365
|
-
startWith("loading"),
|
|
5366
|
-
endWith("success"),
|
|
5367
|
-
defaultIfEmpty("idle")
|
|
5368
|
-
)
|
|
5369
|
-
),
|
|
5370
|
-
startWith("idle"),
|
|
5371
|
-
distinctUntilChanged(),
|
|
5372
|
-
share$1()
|
|
5373
|
-
);
|
|
5374
|
-
const unloaded$ = unloadFrame$.pipe(filter((state) => state === "success"));
|
|
5375
|
-
const unloading$ = unloadFrame$.pipe(filter((state) => state === "loading"));
|
|
5376
|
-
const loadFrame$ = loadSubject.pipe(
|
|
5377
|
-
exhaustMap$1(() => {
|
|
5378
|
-
const preventFurtherLoad$ = NEVER;
|
|
5379
|
-
return merge(
|
|
5380
|
-
preventFurtherLoad$,
|
|
5381
|
-
context.bridgeEvent.viewportFree$.pipe(
|
|
5382
|
-
first(),
|
|
5383
|
-
switchMap$1(
|
|
5384
|
-
() => loadFrame({
|
|
5385
|
-
element: parent,
|
|
5386
|
-
hookManager,
|
|
5387
|
-
item,
|
|
5388
|
-
onFrameElement: (element) => {
|
|
5389
|
-
frameElementSubject.next(element);
|
|
5390
|
-
},
|
|
5391
|
-
settings,
|
|
5392
|
-
context
|
|
5393
|
-
})
|
|
5394
|
-
),
|
|
5395
|
-
map((frame) => ({ state: "success", frame })),
|
|
5396
|
-
startWith({ state: "loading" }),
|
|
5397
|
-
defaultIfEmpty({ state: "idle" })
|
|
5398
|
-
)
|
|
5399
|
-
).pipe(takeUntil$1(unloaded$));
|
|
5400
|
-
}),
|
|
5401
|
-
startWith({ state: "idle" }),
|
|
5402
|
-
share$1()
|
|
5403
|
-
);
|
|
5404
|
-
const loading$ = loadFrame$.pipe(filter(({ state }) => state === "loading"));
|
|
5405
|
-
const loaded$ = loadFrame$.pipe(
|
|
5406
|
-
filter((state) => state.state === "success"),
|
|
5407
|
-
map(({ frame }) => frame)
|
|
5408
|
-
);
|
|
5409
|
-
const frameIsReady$ = loaded$.pipe(
|
|
5410
|
-
switchMap$1(
|
|
5411
|
-
(frame) => of(frame).pipe(waitForFrameReady, takeUntil$1(unloadSubject))
|
|
5412
|
-
),
|
|
5413
|
-
share$1()
|
|
5414
|
-
);
|
|
5415
|
-
const ready$ = frameIsReady$;
|
|
5416
|
-
const state$ = merge(
|
|
5417
|
-
unloaded$.pipe(map(() => "idle")),
|
|
5418
|
-
unloading$.pipe(map(() => "unloading")),
|
|
5419
|
-
loaded$.pipe(map(() => "loaded")),
|
|
5420
|
-
loading$.pipe(map(() => "loading")),
|
|
5421
|
-
ready$.pipe(map(() => "ready"))
|
|
5422
|
-
).pipe(
|
|
5423
|
-
startWith("idle"),
|
|
5424
|
-
tap((state) => stateSubject.next(state)),
|
|
5425
|
-
shareReplay(1)
|
|
5326
|
+
const fallbackSpineItem = getSpineItemFromPosition({
|
|
5327
|
+
position,
|
|
5328
|
+
settings,
|
|
5329
|
+
spineItemsManager,
|
|
5330
|
+
spineLayout
|
|
5331
|
+
}) || spineItemsManager.get(0);
|
|
5332
|
+
const spineItemsVisible = spineItemsManager.items.reduce(
|
|
5333
|
+
(acc, spineItem) => {
|
|
5334
|
+
const itemPosition = spineLayout.getAbsolutePositionOf(spineItem);
|
|
5335
|
+
const { visible } = getItemVisibilityForPosition({
|
|
5336
|
+
itemPosition,
|
|
5337
|
+
threshold,
|
|
5338
|
+
viewportPosition: position,
|
|
5339
|
+
restrictToScreen,
|
|
5340
|
+
context
|
|
5341
|
+
});
|
|
5342
|
+
if (visible) {
|
|
5343
|
+
return [...acc, spineItem];
|
|
5344
|
+
}
|
|
5345
|
+
return acc;
|
|
5346
|
+
},
|
|
5347
|
+
[]
|
|
5426
5348
|
);
|
|
5427
|
-
const
|
|
5428
|
-
|
|
5349
|
+
const beginItem = spineItemsVisible[0] ?? fallbackSpineItem;
|
|
5350
|
+
const endItem = spineItemsVisible[spineItemsVisible.length - 1] ?? beginItem;
|
|
5351
|
+
if (!beginItem || !endItem) return void 0;
|
|
5352
|
+
const beginItemIndex = spineItemsManager.getSpineItemIndex(beginItem);
|
|
5353
|
+
const endItemIndex = spineItemsManager.getSpineItemIndex(endItem);
|
|
5429
5354
|
return {
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
destroy: () => {
|
|
5433
|
-
unloadSubject.next();
|
|
5434
|
-
unloadSubject.complete();
|
|
5435
|
-
loadSubject.complete();
|
|
5436
|
-
frameElementSubject.complete();
|
|
5437
|
-
destroySubject$.next();
|
|
5438
|
-
destroySubject$.complete();
|
|
5439
|
-
stateSubject.complete();
|
|
5440
|
-
},
|
|
5441
|
-
get state() {
|
|
5442
|
-
return stateSubject.getValue();
|
|
5443
|
-
},
|
|
5444
|
-
get element() {
|
|
5445
|
-
return frameElementSubject.getValue();
|
|
5446
|
-
},
|
|
5447
|
-
isReady$,
|
|
5448
|
-
ready$,
|
|
5449
|
-
loaded$,
|
|
5450
|
-
unloaded$,
|
|
5451
|
-
element$: frameElementSubject.asObservable()
|
|
5355
|
+
beginIndex: beginItemIndex ?? 0,
|
|
5356
|
+
endIndex: endItemIndex ?? 0
|
|
5452
5357
|
};
|
|
5453
5358
|
};
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
this.item = item;
|
|
5459
|
-
this.context = context;
|
|
5460
|
-
this.settings = settings;
|
|
5461
|
-
this.hookManager = hookManager;
|
|
5462
|
-
this.getViewportDimensions = () => {
|
|
5463
|
-
const frame = this.loader.element;
|
|
5464
|
-
if (frame && (frame == null ? void 0 : frame.contentDocument)) {
|
|
5465
|
-
const doc = frame.contentDocument;
|
|
5466
|
-
const viewPortMeta = doc.querySelector(`meta[name='viewport']`);
|
|
5467
|
-
if (viewPortMeta) {
|
|
5468
|
-
const viewPortMetaInfos = viewPortMeta.getAttribute(`content`);
|
|
5469
|
-
if (viewPortMetaInfos) {
|
|
5470
|
-
const width = getAttributeValueFromString(viewPortMetaInfos, `width`);
|
|
5471
|
-
const height = getAttributeValueFromString(
|
|
5472
|
-
viewPortMetaInfos,
|
|
5473
|
-
`height`
|
|
5474
|
-
);
|
|
5475
|
-
if (width > 0 && height > 0) {
|
|
5476
|
-
return {
|
|
5477
|
-
width,
|
|
5478
|
-
height
|
|
5479
|
-
};
|
|
5480
|
-
} else {
|
|
5481
|
-
return void 0;
|
|
5482
|
-
}
|
|
5483
|
-
}
|
|
5484
|
-
}
|
|
5485
|
-
}
|
|
5486
|
-
return void 0;
|
|
5487
|
-
};
|
|
5488
|
-
this.getWritingMode = () => {
|
|
5489
|
-
var _a;
|
|
5490
|
-
return (_a = this.getComputedStyleAfterLoad()) == null ? void 0 : _a.writingMode;
|
|
5491
|
-
};
|
|
5492
|
-
this.isUsingVerticalWriting = () => {
|
|
5493
|
-
var _a;
|
|
5494
|
-
return !!((_a = this.getWritingMode()) == null ? void 0 : _a.startsWith(`vertical`));
|
|
5495
|
-
};
|
|
5496
|
-
this.getHtmlFromResource = (response) => {
|
|
5497
|
-
return createHtmlPageFromResource(response, this.item);
|
|
5498
|
-
};
|
|
5499
|
-
this.staticLayout = (size) => {
|
|
5500
|
-
const frame = this.loader.element;
|
|
5501
|
-
if (frame) {
|
|
5502
|
-
frame.style.width = `${size.width}px`;
|
|
5503
|
-
frame.style.height = `${size.height}px`;
|
|
5504
|
-
if (this.settings.values.computedPageTurnMode !== `scrollable`) {
|
|
5505
|
-
frame.setAttribute(`tab-index`, `0`);
|
|
5506
|
-
}
|
|
5507
|
-
}
|
|
5508
|
-
};
|
|
5509
|
-
this.destroy = () => {
|
|
5510
|
-
super.destroy();
|
|
5511
|
-
this.loader.destroy();
|
|
5512
|
-
};
|
|
5513
|
-
this.loader = createLoader({
|
|
5514
|
-
context,
|
|
5515
|
-
hookManager,
|
|
5516
|
-
item,
|
|
5517
|
-
parent,
|
|
5518
|
-
settings
|
|
5519
|
-
});
|
|
5520
|
-
this.contentLayoutChange$ = merge(
|
|
5521
|
-
this.loader.unloaded$.pipe(map(() => ({ isFirstLayout: false }))),
|
|
5522
|
-
this.ready$.pipe(map(() => ({ isFirstLayout: true })))
|
|
5523
|
-
);
|
|
5524
|
-
}
|
|
5525
|
-
// @todo optimize
|
|
5526
|
-
getComputedStyleAfterLoad() {
|
|
5527
|
-
var _a, _b;
|
|
5528
|
-
const frame = this.loader.element;
|
|
5529
|
-
const body = (_a = frame == null ? void 0 : frame.contentDocument) == null ? void 0 : _a.body;
|
|
5530
|
-
if (body) {
|
|
5531
|
-
return (_b = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _b.getComputedStyle(body);
|
|
5532
|
-
}
|
|
5533
|
-
}
|
|
5534
|
-
get element() {
|
|
5535
|
-
return this.loader.element;
|
|
5536
|
-
}
|
|
5537
|
-
get unloaded$() {
|
|
5538
|
-
return this.loader.unloaded$;
|
|
5539
|
-
}
|
|
5540
|
-
get loaded$() {
|
|
5541
|
-
return this.loader.loaded$;
|
|
5542
|
-
}
|
|
5543
|
-
get ready$() {
|
|
5544
|
-
return this.loader.ready$;
|
|
5545
|
-
}
|
|
5546
|
-
get isReady$() {
|
|
5547
|
-
return this.loader.isReady$;
|
|
5548
|
-
}
|
|
5549
|
-
get isLoaded() {
|
|
5550
|
-
return this.loader.state === "loaded" || this.loader.state === "ready";
|
|
5551
|
-
}
|
|
5552
|
-
get isReady() {
|
|
5553
|
-
return this.loader.state === "ready";
|
|
5554
|
-
}
|
|
5555
|
-
load() {
|
|
5556
|
-
this.loader.load();
|
|
5557
|
-
}
|
|
5558
|
-
unload() {
|
|
5559
|
-
this.loader.unload();
|
|
5560
|
-
}
|
|
5561
|
-
addStyle(id, style, prepend) {
|
|
5562
|
-
const frameElement = this.loader.element;
|
|
5563
|
-
if (frameElement && frameElement.contentDocument && frameElement.contentDocument.head) {
|
|
5564
|
-
const userStyle = document.createElement(`style`);
|
|
5565
|
-
userStyle.id = id;
|
|
5566
|
-
userStyle.innerHTML = style;
|
|
5567
|
-
if (prepend) {
|
|
5568
|
-
frameElement.contentDocument.head.prepend(userStyle);
|
|
5569
|
-
} else {
|
|
5570
|
-
frameElement.contentDocument.head.appendChild(userStyle);
|
|
5571
|
-
}
|
|
5572
|
-
}
|
|
5573
|
-
}
|
|
5574
|
-
removeStyle(id) {
|
|
5575
|
-
const frameElement = this.loader.element;
|
|
5576
|
-
if (frameElement && frameElement.contentDocument && frameElement.contentDocument.head) {
|
|
5577
|
-
const styleElement = frameElement.contentDocument.getElementById(id);
|
|
5578
|
-
if (styleElement) {
|
|
5579
|
-
styleElement.remove();
|
|
5580
|
-
}
|
|
5581
|
-
}
|
|
5582
|
-
}
|
|
5583
|
-
}
|
|
5584
|
-
const createFingerTracker = () => {
|
|
5585
|
-
const fingerPositionInIframe = { x: void 0, y: void 0 };
|
|
5586
|
-
const subject = new Subject();
|
|
5587
|
-
let isMouseDown = false;
|
|
5588
|
-
const track = (frame) => {
|
|
5589
|
-
var _a, _b, _c;
|
|
5590
|
-
fingerPositionInIframe.x = void 0;
|
|
5591
|
-
fingerPositionInIframe.y = void 0;
|
|
5592
|
-
(_a = frame.contentDocument) == null ? void 0 : _a.addEventListener(`mousedown`, (e) => {
|
|
5593
|
-
isMouseDown = true;
|
|
5594
|
-
fingerPositionInIframe.x = e.x;
|
|
5595
|
-
fingerPositionInIframe.y = e.y;
|
|
5596
|
-
subject.next({ event: `fingermove`, data: { x: e.x, y: e.y } });
|
|
5597
|
-
});
|
|
5598
|
-
(_b = frame.contentDocument) == null ? void 0 : _b.addEventListener(`mouseup`, () => {
|
|
5599
|
-
isMouseDown = false;
|
|
5600
|
-
fingerPositionInIframe.x = void 0;
|
|
5601
|
-
fingerPositionInIframe.y = void 0;
|
|
5602
|
-
subject.next({ event: `fingerout`, data: void 0 });
|
|
5603
|
-
});
|
|
5604
|
-
(_c = frame.contentDocument) == null ? void 0 : _c.addEventListener(`mousemove`, (e) => {
|
|
5605
|
-
if (isMouseDown) {
|
|
5606
|
-
subject.next({ event: `fingermove`, data: { x: e.x, y: e.y } });
|
|
5607
|
-
}
|
|
5608
|
-
});
|
|
5609
|
-
};
|
|
5359
|
+
const getSpinePositionFromSpineItemPosition = ({
|
|
5360
|
+
spineItemPosition,
|
|
5361
|
+
itemLayout: { left, top }
|
|
5362
|
+
}) => {
|
|
5610
5363
|
return {
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
return fingerPositionInIframe.x === void 0 || fingerPositionInIframe.y === void 0 ? void 0 : fingerPositionInIframe;
|
|
5614
|
-
},
|
|
5615
|
-
destroy: () => {
|
|
5616
|
-
},
|
|
5617
|
-
$: subject.asObservable()
|
|
5364
|
+
x: left + spineItemPosition.x,
|
|
5365
|
+
y: top + spineItemPosition.y
|
|
5618
5366
|
};
|
|
5619
5367
|
};
|
|
5620
|
-
const
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
(
|
|
5631
|
-
|
|
5368
|
+
const getSpineInfoFromAbsolutePageIndex = ({
|
|
5369
|
+
absolutePageIndex,
|
|
5370
|
+
spineLayout,
|
|
5371
|
+
spineItemsManager,
|
|
5372
|
+
context,
|
|
5373
|
+
settings
|
|
5374
|
+
}) => {
|
|
5375
|
+
const items = spineItemsManager.items;
|
|
5376
|
+
const { found, currentAbsolutePage } = items.reduce(
|
|
5377
|
+
(acc, item) => {
|
|
5378
|
+
if (acc.found) return acc;
|
|
5379
|
+
const itemLayout = spineLayout.getAbsolutePositionOf(item);
|
|
5380
|
+
const numberOfPages = getSpineItemNumberOfPages({
|
|
5381
|
+
isUsingVerticalWriting: !!item.isUsingVerticalWriting(),
|
|
5382
|
+
itemHeight: itemLayout.height,
|
|
5383
|
+
itemWidth: itemLayout.width,
|
|
5384
|
+
context,
|
|
5385
|
+
settings
|
|
5632
5386
|
});
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5387
|
+
const possiblePageIndex = absolutePageIndex - acc.currentAbsolutePage;
|
|
5388
|
+
const currentAbsolutePage2 = acc.currentAbsolutePage + numberOfPages;
|
|
5389
|
+
if (possiblePageIndex <= numberOfPages - 1) {
|
|
5390
|
+
return {
|
|
5391
|
+
...acc,
|
|
5392
|
+
currentAbsolutePage: currentAbsolutePage2,
|
|
5393
|
+
found: { item, pageIndex: possiblePageIndex }
|
|
5394
|
+
};
|
|
5395
|
+
}
|
|
5396
|
+
return {
|
|
5397
|
+
...acc,
|
|
5398
|
+
currentAbsolutePage: currentAbsolutePage2
|
|
5399
|
+
};
|
|
5400
|
+
},
|
|
5401
|
+
{ currentAbsolutePage: 0 }
|
|
5402
|
+
);
|
|
5403
|
+
if (found) {
|
|
5404
|
+
return {
|
|
5405
|
+
spineItem: found.item,
|
|
5406
|
+
pageIndex: found.pageIndex,
|
|
5407
|
+
itemIndex: spineItemsManager.getSpineItemIndex(found.item) ?? 0,
|
|
5408
|
+
currentAbsolutePage
|
|
5409
|
+
};
|
|
5410
|
+
}
|
|
5411
|
+
return void 0;
|
|
5412
|
+
};
|
|
5413
|
+
const getAbsolutePageIndexFromPageIndex = ({
|
|
5414
|
+
pageIndex,
|
|
5415
|
+
spineItemOrId,
|
|
5416
|
+
spineLayout,
|
|
5417
|
+
spineItemsManager,
|
|
5418
|
+
context,
|
|
5419
|
+
settings
|
|
5420
|
+
}) => {
|
|
5421
|
+
const items = spineItemsManager.items;
|
|
5422
|
+
const spineItem = spineItemsManager.get(spineItemOrId);
|
|
5423
|
+
if (!spineItem) return void 0;
|
|
5424
|
+
const { currentAbsolutePage } = items.reduce(
|
|
5425
|
+
(acc, item) => {
|
|
5426
|
+
if (acc.found) return acc;
|
|
5427
|
+
const itemLayout = spineLayout.getAbsolutePositionOf(item);
|
|
5428
|
+
const numberOfPages = getSpineItemNumberOfPages({
|
|
5429
|
+
isUsingVerticalWriting: !!item.isUsingVerticalWriting(),
|
|
5430
|
+
itemHeight: itemLayout.height,
|
|
5431
|
+
itemWidth: itemLayout.width,
|
|
5432
|
+
context,
|
|
5433
|
+
settings
|
|
5639
5434
|
});
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
var _a;
|
|
5653
|
-
const selection = (_a = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _a.getSelection();
|
|
5654
|
-
if (!(selection == null ? void 0 : selection.anchorNode) || selection.type === `None` || selection.type === `Caret`)
|
|
5655
|
-
return void 0;
|
|
5656
|
-
return selection;
|
|
5435
|
+
if (spineItem === item) {
|
|
5436
|
+
if (pageIndex <= numberOfPages - 1) {
|
|
5437
|
+
return {
|
|
5438
|
+
currentAbsolutePage: acc.currentAbsolutePage + pageIndex,
|
|
5439
|
+
found: true
|
|
5440
|
+
};
|
|
5441
|
+
}
|
|
5442
|
+
}
|
|
5443
|
+
return {
|
|
5444
|
+
...acc,
|
|
5445
|
+
currentAbsolutePage: acc.currentAbsolutePage + numberOfPages
|
|
5446
|
+
};
|
|
5657
5447
|
},
|
|
5658
|
-
|
|
5659
|
-
|
|
5448
|
+
{ currentAbsolutePage: 0, found: false }
|
|
5449
|
+
);
|
|
5450
|
+
return currentAbsolutePage;
|
|
5660
5451
|
};
|
|
5661
|
-
const
|
|
5662
|
-
|
|
5452
|
+
const createSpineLocator = ({
|
|
5453
|
+
spineItemsManager,
|
|
5663
5454
|
context,
|
|
5664
|
-
|
|
5455
|
+
spineItemLocator,
|
|
5665
5456
|
settings,
|
|
5666
|
-
|
|
5667
|
-
index
|
|
5457
|
+
spineLayout
|
|
5668
5458
|
}) => {
|
|
5669
|
-
const
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5459
|
+
const getSpineItemPositionFromSpinePosition = Report.measurePerformance(
|
|
5460
|
+
`getSpineItemPositionFromSpinePosition`,
|
|
5461
|
+
10,
|
|
5462
|
+
(position, spineItem) => {
|
|
5463
|
+
const { left, top } = spineLayout.getAbsolutePositionOf(spineItem);
|
|
5464
|
+
return {
|
|
5465
|
+
/**
|
|
5466
|
+
* when using spread the item could be on the right and therefore will be negative
|
|
5467
|
+
* @example
|
|
5468
|
+
* 400 (position = viewport), page of 200
|
|
5469
|
+
* 400 - 600 = -200.
|
|
5470
|
+
* However we can assume we are at 0, because we in fact can see the beginning of the item
|
|
5471
|
+
*/
|
|
5472
|
+
x: Math.max(position.x - left, 0),
|
|
5473
|
+
y: Math.max(position.y - top, 0)
|
|
5474
|
+
};
|
|
5475
|
+
},
|
|
5476
|
+
{ disable: true }
|
|
5684
5477
|
);
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
...rect,
|
|
5691
|
-
// we want to round to first decimal because it's possible to have half pixel
|
|
5692
|
-
// however browser engine can also gives back x.yyyy based on their precision
|
|
5693
|
-
width: Math.round(rect.width * 10) / 10,
|
|
5694
|
-
height: Math.round(rect.height * 10) / 10
|
|
5695
|
-
};
|
|
5696
|
-
return normalizedValues;
|
|
5697
|
-
};
|
|
5698
|
-
const isImageType = () => {
|
|
5699
|
-
const mimeType = item.mediaType ?? detectMimeTypeFromName(item.href);
|
|
5700
|
-
return !!(mimeType == null ? void 0 : mimeType.startsWith(`image/`));
|
|
5701
|
-
};
|
|
5702
|
-
const injectStyle = (cssText) => {
|
|
5703
|
-
frameItem.removeStyle(`prose-reader-css`);
|
|
5704
|
-
frameItem.addStyle(`prose-reader-css`, cssText);
|
|
5705
|
-
};
|
|
5706
|
-
const adjustPositionOfElement = ({
|
|
5707
|
-
right,
|
|
5708
|
-
left,
|
|
5709
|
-
top
|
|
5710
|
-
}) => {
|
|
5711
|
-
if (right !== void 0) {
|
|
5712
|
-
containerElement.style.right = `${right}px`;
|
|
5713
|
-
} else {
|
|
5714
|
-
containerElement.style.removeProperty(`right`);
|
|
5715
|
-
}
|
|
5716
|
-
if (left !== void 0) {
|
|
5717
|
-
containerElement.style.left = `${left}px`;
|
|
5718
|
-
} else {
|
|
5719
|
-
containerElement.style.removeProperty(`left`);
|
|
5720
|
-
}
|
|
5721
|
-
if (top !== void 0) {
|
|
5722
|
-
containerElement.style.top = `${top}px`;
|
|
5723
|
-
} else {
|
|
5724
|
-
containerElement.style.removeProperty(`top`);
|
|
5725
|
-
}
|
|
5726
|
-
};
|
|
5727
|
-
const getViewPortInformation = () => {
|
|
5728
|
-
const { width: pageWidth, height: pageHeight } = context.getPageSize();
|
|
5729
|
-
const viewportDimensions = frameItem.getViewportDimensions();
|
|
5730
|
-
const frameElement = frameItem.element;
|
|
5731
|
-
if (containerElement && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow) && viewportDimensions) {
|
|
5732
|
-
const computedWidthScale = pageWidth / viewportDimensions.width;
|
|
5733
|
-
const computedScale = Math.min(
|
|
5734
|
-
computedWidthScale,
|
|
5735
|
-
pageHeight / viewportDimensions.height
|
|
5736
|
-
);
|
|
5737
|
-
return { computedScale, computedWidthScale, viewportDimensions };
|
|
5738
|
-
}
|
|
5739
|
-
};
|
|
5740
|
-
const load = () => frameItem.load();
|
|
5741
|
-
const unload = () => frameItem.unload();
|
|
5742
|
-
const getBoundingRectOfElementFromSelector = (selector) => {
|
|
5743
|
-
var _a, _b, _c, _d;
|
|
5744
|
-
const frameElement = frameItem.element;
|
|
5745
|
-
if (frameElement && selector) {
|
|
5746
|
-
if (selector.startsWith(`#`)) {
|
|
5747
|
-
return (_b = (_a = frameElement.contentDocument) == null ? void 0 : _a.getElementById(selector.replace(`#`, ``))) == null ? void 0 : _b.getBoundingClientRect();
|
|
5748
|
-
}
|
|
5749
|
-
return (_d = (_c = frameElement.contentDocument) == null ? void 0 : _c.querySelector(selector)) == null ? void 0 : _d.getBoundingClientRect();
|
|
5750
|
-
}
|
|
5478
|
+
const getSpinePositionFromSpineItem = (spineItem) => {
|
|
5479
|
+
return getSpinePositionFromSpineItemPosition({
|
|
5480
|
+
spineItemPosition: { x: 0, y: 0 },
|
|
5481
|
+
itemLayout: spineLayout.getAbsolutePositionOf(spineItem)
|
|
5482
|
+
});
|
|
5751
5483
|
};
|
|
5752
|
-
const
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
return { columnHeight, columnWidth };
|
|
5484
|
+
const getSpineItemFromIframe = (iframe) => {
|
|
5485
|
+
return spineItemsManager.items.find((item) => {
|
|
5486
|
+
var _a;
|
|
5487
|
+
return ((_a = item.renderer.layers[0]) == null ? void 0 : _a.element) === iframe;
|
|
5488
|
+
});
|
|
5758
5489
|
};
|
|
5759
|
-
const
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
width = minimumWidth - horizontalMargin * 2;
|
|
5768
|
-
columnWidth = columnHeight;
|
|
5490
|
+
const getSpineItemPageIndexFromNode = (node, offset, spineItemOrIndex) => {
|
|
5491
|
+
if (typeof spineItemOrIndex === `number`) {
|
|
5492
|
+
const spineItem = spineItemsManager.get(spineItemOrIndex);
|
|
5493
|
+
return spineItem ? spineItemLocator.getSpineItemPageIndexFromNode(
|
|
5494
|
+
node,
|
|
5495
|
+
offset || 0,
|
|
5496
|
+
spineItem
|
|
5497
|
+
) : void 0;
|
|
5769
5498
|
}
|
|
5770
|
-
return
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
width
|
|
5776
|
-
};
|
|
5499
|
+
return spineItemLocator.getSpineItemPageIndexFromNode(
|
|
5500
|
+
node,
|
|
5501
|
+
offset || 0,
|
|
5502
|
+
spineItemOrIndex
|
|
5503
|
+
);
|
|
5777
5504
|
};
|
|
5778
|
-
const
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5505
|
+
const getVisiblePagesFromViewportPosition = ({
|
|
5506
|
+
position,
|
|
5507
|
+
threshold,
|
|
5508
|
+
spineItem,
|
|
5509
|
+
restrictToScreen
|
|
5783
5510
|
}) => {
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
minimumWidth
|
|
5511
|
+
const { height, width } = spineItem.getElementDimensions();
|
|
5512
|
+
const numberOfPages = spineItemLocator.getSpineItemNumberOfPages({
|
|
5513
|
+
isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
|
|
5514
|
+
itemHeight: height,
|
|
5515
|
+
itemWidth: width
|
|
5790
5516
|
});
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5517
|
+
const pages = Array.from(Array(numberOfPages)).map((_, index) => {
|
|
5518
|
+
const spineItemPosition = spineItemLocator.getSpineItemPositionFromPageIndex({
|
|
5519
|
+
pageIndex: index,
|
|
5520
|
+
isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
|
|
5521
|
+
itemLayout: spineItem.getElementDimensions()
|
|
5522
|
+
});
|
|
5523
|
+
const spinePosition = getSpinePositionFromSpineItemPosition({
|
|
5524
|
+
spineItemPosition,
|
|
5525
|
+
itemLayout: spineLayout.getAbsolutePositionOf(spineItem)
|
|
5526
|
+
});
|
|
5527
|
+
return {
|
|
5528
|
+
index,
|
|
5529
|
+
absolutePosition: {
|
|
5530
|
+
width: context.getPageSize().width,
|
|
5531
|
+
height: context.getPageSize().height,
|
|
5532
|
+
left: spinePosition.x,
|
|
5533
|
+
top: spinePosition.y,
|
|
5534
|
+
bottom: spinePosition.y + context.getPageSize().height,
|
|
5535
|
+
right: spinePosition.x + context.getPageSize().width
|
|
5536
|
+
}
|
|
5537
|
+
};
|
|
5538
|
+
});
|
|
5539
|
+
const pagesVisible = pages.reduce(
|
|
5540
|
+
(acc, { absolutePosition, index }) => {
|
|
5541
|
+
const { visible } = getItemVisibilityForPosition({
|
|
5542
|
+
context,
|
|
5543
|
+
viewportPosition: position,
|
|
5544
|
+
restrictToScreen,
|
|
5545
|
+
threshold,
|
|
5546
|
+
itemPosition: absolutePosition
|
|
5547
|
+
});
|
|
5548
|
+
if (visible) {
|
|
5549
|
+
return [...acc, index];
|
|
5550
|
+
}
|
|
5551
|
+
return acc;
|
|
5552
|
+
},
|
|
5553
|
+
[]
|
|
5554
|
+
);
|
|
5555
|
+
const beginPageIndex = pagesVisible[0];
|
|
5556
|
+
const endPageIndex = pagesVisible[pagesVisible.length - 1] ?? beginPageIndex;
|
|
5557
|
+
if (beginPageIndex === void 0 || endPageIndex === void 0)
|
|
5558
|
+
return void 0;
|
|
5798
5559
|
return {
|
|
5799
|
-
|
|
5800
|
-
|
|
5560
|
+
beginPageIndex,
|
|
5561
|
+
endPageIndex
|
|
5801
5562
|
};
|
|
5802
5563
|
};
|
|
5803
|
-
const
|
|
5804
|
-
const
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5564
|
+
const isPositionWithinSpineItem = (position, spineItem) => {
|
|
5565
|
+
const { bottom, left, right, top } = spineLayout.getAbsolutePositionOf(spineItem);
|
|
5566
|
+
return position.x >= left && position.x <= right && position.y <= bottom && position.y >= top;
|
|
5567
|
+
};
|
|
5568
|
+
const getSafeSpineItemPositionFromUnsafeSpineItemPosition = (unsafePosition, spineItem) => {
|
|
5569
|
+
const { height, width } = spineLayout.getAbsolutePositionOf(spineItem);
|
|
5570
|
+
return {
|
|
5571
|
+
x: Math.min(Math.max(0, unsafePosition.x), width),
|
|
5572
|
+
y: Math.min(Math.max(0, unsafePosition.y), height)
|
|
5810
5573
|
};
|
|
5811
|
-
return await lastFetch();
|
|
5812
5574
|
};
|
|
5813
|
-
const executeOnLayoutBeforeMeasurementHook = (options) => hookManager.execute("item.onLayoutBeforeMeasurement", void 0, {
|
|
5814
|
-
itemIndex: index,
|
|
5815
|
-
isImageType,
|
|
5816
|
-
...options
|
|
5817
|
-
});
|
|
5818
|
-
const contentLayout$ = frameItem.contentLayoutChange$.pipe(
|
|
5819
|
-
withLatestFrom$1(frameItem.isReady$),
|
|
5820
|
-
map(([data, isReady]) => ({
|
|
5821
|
-
isFirstLayout: data.isFirstLayout,
|
|
5822
|
-
isReady
|
|
5823
|
-
}))
|
|
5824
|
-
);
|
|
5825
5575
|
return {
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
load,
|
|
5836
|
-
unload,
|
|
5837
|
-
frame: frameItem,
|
|
5838
|
-
element: containerElement,
|
|
5839
|
-
getBoundingRectOfElementFromSelector,
|
|
5840
|
-
getViewPortInformation,
|
|
5841
|
-
isImageType,
|
|
5842
|
-
isReady: () => frameItem.isReady,
|
|
5843
|
-
destroy: () => {
|
|
5844
|
-
destroySubject$.next();
|
|
5845
|
-
containerElement.remove();
|
|
5846
|
-
frameItem == null ? void 0 : frameItem.destroy();
|
|
5847
|
-
fingerTracker.destroy();
|
|
5848
|
-
selectionTracker.destroy();
|
|
5849
|
-
destroySubject$.complete();
|
|
5850
|
-
},
|
|
5851
|
-
/**
|
|
5852
|
-
* @important
|
|
5853
|
-
* Do not use this value for layout and navigation. It will be in possible conflict
|
|
5854
|
-
* with the global reading direction. A book should not mix them anyway. A page can have
|
|
5855
|
-
* a different reading direction for style reason but it should be in theory pre-paginated.
|
|
5856
|
-
* For example an english page in a japanese manga. That's expected and will
|
|
5857
|
-
* be confined to a single page.
|
|
5858
|
-
*/
|
|
5859
|
-
get readingDirection() {
|
|
5860
|
-
var _a;
|
|
5861
|
-
const writingMode = this.frame.getWritingMode();
|
|
5862
|
-
if (writingMode === `vertical-rl`) {
|
|
5863
|
-
return `rtl`;
|
|
5864
|
-
}
|
|
5865
|
-
const direction = (_a = this.frame.getComputedStyleAfterLoad()) == null ? void 0 : _a.direction;
|
|
5866
|
-
if ([`ltr`, `rtl`].includes(direction || ``))
|
|
5867
|
-
return direction;
|
|
5868
|
-
return void 0;
|
|
5869
|
-
},
|
|
5870
|
-
isUsingVerticalWriting: () => {
|
|
5871
|
-
var _a;
|
|
5872
|
-
return (_a = frameItem.getWritingMode()) == null ? void 0 : _a.startsWith(`vertical`);
|
|
5873
|
-
},
|
|
5874
|
-
executeOnLayoutBeforeMeasurementHook,
|
|
5875
|
-
selectionTracker,
|
|
5876
|
-
fingerTracker,
|
|
5877
|
-
getDimensionsForReflowableContent,
|
|
5878
|
-
getDimensionsForPaginatedContent,
|
|
5879
|
-
$: {
|
|
5880
|
-
contentLayout$,
|
|
5881
|
-
loaded$: frameItem.loaded$,
|
|
5882
|
-
isReady$: frameItem.isReady$
|
|
5883
|
-
}
|
|
5884
|
-
};
|
|
5885
|
-
};
|
|
5886
|
-
const createContainerElement = (containerElement, item, hookManager) => {
|
|
5887
|
-
const element = containerElement.ownerDocument.createElement(`div`);
|
|
5888
|
-
element.classList.add(`spineItem`);
|
|
5889
|
-
element.classList.add(`spineItem-${item.renditionLayout}`);
|
|
5890
|
-
element.style.cssText = `
|
|
5891
|
-
position: absolute;
|
|
5892
|
-
overflow: hidden;
|
|
5893
|
-
`;
|
|
5894
|
-
hookManager.execute("item.onBeforeContainerCreated", void 0, { element });
|
|
5895
|
-
return element;
|
|
5896
|
-
};
|
|
5897
|
-
const createOverlayElement = (containerElement, item) => {
|
|
5898
|
-
const element = containerElement.ownerDocument.createElement(`div`);
|
|
5899
|
-
element.classList.add(`spineItemOverlay`);
|
|
5900
|
-
element.classList.add(`spineItemOverlay-${item.renditionLayout}`);
|
|
5901
|
-
element.style.cssText = `
|
|
5902
|
-
position: absolute;
|
|
5903
|
-
width: 100%;
|
|
5904
|
-
height: 100%;
|
|
5905
|
-
pointer-events: none;
|
|
5906
|
-
background-color: transparent;
|
|
5907
|
-
`;
|
|
5908
|
-
return element;
|
|
5909
|
-
};
|
|
5910
|
-
const getStyleForViewportDocument = () => {
|
|
5911
|
-
return `
|
|
5912
|
-
body {
|
|
5913
|
-
margin: 0;
|
|
5914
|
-
}
|
|
5915
|
-
}
|
|
5916
|
-
`;
|
|
5917
|
-
};
|
|
5918
|
-
const createPrePaginatedSpineItem = ({
|
|
5919
|
-
item,
|
|
5920
|
-
context,
|
|
5921
|
-
containerElement,
|
|
5922
|
-
settings,
|
|
5923
|
-
hookManager,
|
|
5924
|
-
index
|
|
5925
|
-
}) => {
|
|
5926
|
-
const commonSpineItem = createCommonSpineItem({
|
|
5927
|
-
context,
|
|
5928
|
-
item,
|
|
5929
|
-
parentElement: containerElement,
|
|
5930
|
-
settings,
|
|
5931
|
-
hookManager,
|
|
5932
|
-
index
|
|
5933
|
-
});
|
|
5934
|
-
const spineItemFrame = commonSpineItem.frame;
|
|
5935
|
-
const layout = ({
|
|
5936
|
-
blankPagePosition,
|
|
5937
|
-
minimumWidth,
|
|
5938
|
-
spreadPosition
|
|
5939
|
-
}) => {
|
|
5940
|
-
const { width: pageWidth, height: pageHeight } = context.getPageSize();
|
|
5941
|
-
const { viewportDimensions, computedScale = 1 } = commonSpineItem.getViewPortInformation() ?? {};
|
|
5942
|
-
const visibleArea = context.state.visibleAreaRect;
|
|
5943
|
-
const frameElement = spineItemFrame.element;
|
|
5944
|
-
if ((spineItemFrame == null ? void 0 : spineItemFrame.isLoaded) && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
|
|
5945
|
-
const contentWidth = pageWidth;
|
|
5946
|
-
const contentHeight = visibleArea.height + context.state.calculatedInnerMargin;
|
|
5947
|
-
const cssLink = buildDocumentStyle(
|
|
5948
|
-
{
|
|
5949
|
-
...commonSpineItem.getDimensionsForPaginatedContent(),
|
|
5950
|
-
enableTouch: settings.values.computedPageTurnMode !== `scrollable`,
|
|
5951
|
-
spreadPosition
|
|
5952
|
-
},
|
|
5953
|
-
viewportDimensions
|
|
5954
|
-
);
|
|
5955
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`visibility`, `visible`);
|
|
5956
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`opacity`, `1`);
|
|
5957
|
-
if (viewportDimensions) {
|
|
5958
|
-
commonSpineItem.injectStyle(cssLink);
|
|
5959
|
-
spineItemFrame.staticLayout({
|
|
5960
|
-
width: viewportDimensions.width,
|
|
5961
|
-
height: viewportDimensions.height
|
|
5962
|
-
});
|
|
5963
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`position`, `absolute`);
|
|
5964
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`top`, `50%`);
|
|
5965
|
-
if (spreadPosition === `left`) {
|
|
5966
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`right`, `0`);
|
|
5967
|
-
frameElement == null ? void 0 : frameElement.style.removeProperty(`left`);
|
|
5968
|
-
} else if (blankPagePosition === `before` && context.isRTL()) {
|
|
5969
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`right`, `50%`);
|
|
5970
|
-
frameElement == null ? void 0 : frameElement.style.removeProperty(`left`);
|
|
5971
|
-
} else if (spreadPosition === `right`) {
|
|
5972
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`left`, `0`);
|
|
5973
|
-
frameElement == null ? void 0 : frameElement.style.removeProperty(`right`);
|
|
5974
|
-
} else {
|
|
5975
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
5976
|
-
`left`,
|
|
5977
|
-
blankPagePosition === `before` ? context.isRTL() ? `25%` : `75%` : blankPagePosition === `after` ? context.isRTL() ? `75%` : `25%` : `50%`
|
|
5978
|
-
);
|
|
5979
|
-
frameElement == null ? void 0 : frameElement.style.removeProperty(`right`);
|
|
5980
|
-
}
|
|
5981
|
-
const transformTranslateX = spreadPosition !== `none` ? `0` : `-50%`;
|
|
5982
|
-
const transformOriginX = spreadPosition === `right` && blankPagePosition !== `before` ? `left` : spreadPosition === `left` || blankPagePosition === `before` && context.isRTL() ? `right` : `center`;
|
|
5983
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
5984
|
-
`transform`,
|
|
5985
|
-
`translate(${transformTranslateX}, -50%) scale(${computedScale})`
|
|
5986
|
-
);
|
|
5987
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
5988
|
-
`transform-origin`,
|
|
5989
|
-
`${transformOriginX} center`
|
|
5990
|
-
);
|
|
5991
|
-
commonSpineItem.executeOnLayoutBeforeMeasurementHook({ minimumWidth });
|
|
5992
|
-
} else {
|
|
5993
|
-
commonSpineItem.injectStyle(cssLink);
|
|
5994
|
-
spineItemFrame.staticLayout({
|
|
5995
|
-
width: contentWidth,
|
|
5996
|
-
height: contentHeight
|
|
5997
|
-
});
|
|
5998
|
-
if (blankPagePosition === `before`) {
|
|
5999
|
-
if (context.isRTL()) {
|
|
6000
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`margin-right`, `${pageWidth}px`);
|
|
6001
|
-
} else {
|
|
6002
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`margin-left`, `${pageWidth}px`);
|
|
6003
|
-
}
|
|
6004
|
-
} else {
|
|
6005
|
-
frameElement == null ? void 0 : frameElement.style.removeProperty(`margin-left`);
|
|
6006
|
-
frameElement == null ? void 0 : frameElement.style.removeProperty(`margin-right`);
|
|
6007
|
-
}
|
|
6008
|
-
}
|
|
6009
|
-
commonSpineItem.executeOnLayoutBeforeMeasurementHook({ minimumWidth });
|
|
6010
|
-
commonSpineItem.layout({
|
|
6011
|
-
width: minimumWidth,
|
|
6012
|
-
height: contentHeight,
|
|
6013
|
-
blankPagePosition,
|
|
6014
|
-
minimumWidth
|
|
6015
|
-
});
|
|
6016
|
-
return { width: minimumWidth, height: contentHeight };
|
|
6017
|
-
} else {
|
|
6018
|
-
commonSpineItem.executeOnLayoutBeforeMeasurementHook({ minimumWidth });
|
|
6019
|
-
commonSpineItem.layout({
|
|
6020
|
-
width: minimumWidth,
|
|
6021
|
-
height: pageHeight,
|
|
6022
|
-
blankPagePosition,
|
|
6023
|
-
minimumWidth
|
|
6024
|
-
});
|
|
6025
|
-
}
|
|
6026
|
-
return { width: minimumWidth, height: pageHeight };
|
|
6027
|
-
};
|
|
6028
|
-
return {
|
|
6029
|
-
...commonSpineItem,
|
|
6030
|
-
layout
|
|
6031
|
-
};
|
|
6032
|
-
};
|
|
6033
|
-
const buildDocumentStyle = ({
|
|
6034
|
-
columnWidth,
|
|
6035
|
-
enableTouch,
|
|
6036
|
-
spreadPosition
|
|
6037
|
-
}, viewportDimensions) => {
|
|
6038
|
-
return `
|
|
6039
|
-
${getStyleForViewportDocument()}
|
|
6040
|
-
body {
|
|
6041
|
-
${!viewportDimensions ? `
|
|
6042
|
-
display: flex;
|
|
6043
|
-
justify-content: ${spreadPosition === `left` ? `flex-end` : spreadPosition === `right` ? `flex-start` : `center`};
|
|
6044
|
-
` : ``}
|
|
6045
|
-
}
|
|
6046
|
-
${/*
|
|
6047
|
-
might be html * but it does mess up things like figure if so.
|
|
6048
|
-
check accessible_epub_3
|
|
6049
|
-
*/
|
|
6050
|
-
``}
|
|
6051
|
-
html, body {
|
|
6052
|
-
height: 100%;
|
|
6053
|
-
width: 100%;
|
|
6054
|
-
}
|
|
6055
|
-
${/*
|
|
6056
|
-
This one is important for preventing 100% img to resize above
|
|
6057
|
-
current width. Especially needed for cbz conversion
|
|
6058
|
-
*/
|
|
6059
|
-
``}
|
|
6060
|
-
html, body {
|
|
6061
|
-
-max-width: ${columnWidth}px !important;
|
|
6062
|
-
}
|
|
6063
|
-
${/*
|
|
6064
|
-
* @see https://hammerjs.github.io/touch-action/
|
|
6065
|
-
* It needs to be disabled when using free scroll
|
|
6066
|
-
*/
|
|
6067
|
-
``}
|
|
6068
|
-
html, body {
|
|
6069
|
-
${enableTouch ? `
|
|
6070
|
-
touch-action: none
|
|
6071
|
-
` : ``}
|
|
6072
|
-
}
|
|
6073
|
-
${/*
|
|
6074
|
-
prevent drag of image instead of touch on firefox
|
|
6075
|
-
*/
|
|
6076
|
-
``}
|
|
6077
|
-
img {
|
|
6078
|
-
user-select: none;
|
|
6079
|
-
-webkit-user-drag: none;
|
|
6080
|
-
-khtml-user-drag: none;
|
|
6081
|
-
-moz-user-drag: none;
|
|
6082
|
-
-o-user-drag: none;
|
|
6083
|
-
user-drag: none;
|
|
6084
|
-
${/*
|
|
6085
|
-
prevent weird overflow or margin. Try `block` if `flex` has weird behavior
|
|
6086
|
-
*/
|
|
6087
|
-
``}
|
|
6088
|
-
display: flex;
|
|
6089
|
-
${/*
|
|
6090
|
-
If the document does not have viewport, we cannot scale anything inside.
|
|
6091
|
-
This should never happens with a valid epub document however it will happens if
|
|
6092
|
-
we load .jpg, .png, etc directly in the iframe. This is expected, in this case we force
|
|
6093
|
-
the inner content to display correctly.
|
|
6094
|
-
*/
|
|
6095
|
-
``}
|
|
6096
|
-
${!viewportDimensions ? `
|
|
6097
|
-
-width: 100%;
|
|
6098
|
-
max-width: 100%;
|
|
6099
|
-
height:100%;
|
|
6100
|
-
object-fit:contain;
|
|
6101
|
-
` : ``}
|
|
6102
|
-
}
|
|
6103
|
-
`;
|
|
6104
|
-
};
|
|
6105
|
-
const buildStyleForViewportFrame = () => {
|
|
6106
|
-
return `
|
|
6107
|
-
${getStyleForViewportDocument()}
|
|
6108
|
-
html {
|
|
6109
|
-
width: 100%;
|
|
6110
|
-
height: 100%;
|
|
6111
|
-
}
|
|
6112
|
-
body {
|
|
6113
|
-
width: 100%;
|
|
6114
|
-
height: 100%;
|
|
6115
|
-
margin: 0;
|
|
6116
|
-
}
|
|
6117
|
-
${/*
|
|
6118
|
-
* @see https://hammerjs.github.io/touch-action/
|
|
6119
|
-
*/
|
|
6120
|
-
``}
|
|
6121
|
-
html, body {
|
|
6122
|
-
touch-action: none;
|
|
6123
|
-
}
|
|
6124
|
-
`;
|
|
6125
|
-
};
|
|
6126
|
-
const buildStyleForReflowableImageOnly = ({
|
|
6127
|
-
isScrollable,
|
|
6128
|
-
enableTouch
|
|
6129
|
-
}) => {
|
|
6130
|
-
return `
|
|
6131
|
-
${/*
|
|
6132
|
-
* @see https://hammerjs.github.io/touch-action/
|
|
6133
|
-
*/
|
|
6134
|
-
``}
|
|
6135
|
-
html, body {
|
|
6136
|
-
width: 100%;
|
|
6137
|
-
margin: 0;
|
|
6138
|
-
padding: 0;
|
|
6139
|
-
${enableTouch ? `
|
|
6140
|
-
touch-action: none
|
|
6141
|
-
` : ``}
|
|
6142
|
-
}
|
|
6143
|
-
${isScrollable ? `
|
|
6144
|
-
img {
|
|
6145
|
-
height: auto !important;
|
|
6146
|
-
margin: 0;
|
|
6147
|
-
padding: 0;
|
|
6148
|
-
box-sizing: border-box;
|
|
6149
|
-
${// we make sure img spread on entire screen
|
|
6150
|
-
``}
|
|
6151
|
-
width: 100%;
|
|
6152
|
-
${/**
|
|
6153
|
-
* line break issue
|
|
6154
|
-
* @see https://stackoverflow.com/questions/37869020/image-not-taking-up-the-full-height-of-container
|
|
6155
|
-
*/
|
|
6156
|
-
``}
|
|
6157
|
-
display: block;
|
|
6158
|
-
}
|
|
6159
|
-
` : ``}
|
|
6160
|
-
`;
|
|
6161
|
-
};
|
|
6162
|
-
const buildStyleWithMultiColumn = ({
|
|
6163
|
-
width,
|
|
6164
|
-
columnHeight,
|
|
6165
|
-
columnWidth
|
|
6166
|
-
}) => {
|
|
6167
|
-
return `
|
|
6168
|
-
parsererror {
|
|
6169
|
-
display: none !important;
|
|
6170
|
-
}
|
|
6171
|
-
${/*
|
|
6172
|
-
might be html * but it does mess up things like figure if so.
|
|
6173
|
-
check accessible_epub_3
|
|
6174
|
-
*/
|
|
6175
|
-
``}
|
|
6176
|
-
html, body {
|
|
6177
|
-
margin: 0;
|
|
6178
|
-
padding: 0 !important;
|
|
6179
|
-
-max-width: ${columnWidth}px !important;
|
|
6180
|
-
}
|
|
6181
|
-
${/*
|
|
6182
|
-
body {
|
|
6183
|
-
height: ${columnHeight}px !important;
|
|
6184
|
-
width: ${columnWidth}px !important;
|
|
6185
|
-
-margin-left: ${horizontalMargin}px !important;
|
|
6186
|
-
-margin-right: ${horizontalMargin}px !important;
|
|
6187
|
-
-margin: ${verticalMargin}px ${horizontalMargin}px !important;
|
|
6188
|
-
-padding-top: ${horizontalMargin}px !important;
|
|
6189
|
-
-padding-bottom: ${horizontalMargin}px !important;
|
|
6190
|
-
}
|
|
6191
|
-
*/
|
|
6192
|
-
``}
|
|
6193
|
-
body {
|
|
6194
|
-
padding: 0 !important;
|
|
6195
|
-
width: ${width}px !important;
|
|
6196
|
-
height: ${columnHeight}px !important;
|
|
6197
|
-
overflow-y: hidden;
|
|
6198
|
-
column-gap: 0px !important;
|
|
6199
|
-
column-width: ${columnWidth}px !important;
|
|
6200
|
-
column-fill: auto !important;
|
|
6201
|
-
word-wrap: break-word;
|
|
6202
|
-
box-sizing: border-box;
|
|
6203
|
-
}
|
|
6204
|
-
body {
|
|
6205
|
-
margin: 0;
|
|
6206
|
-
}
|
|
6207
|
-
body:focus-visible {
|
|
6208
|
-
${/*
|
|
6209
|
-
we make sure that there are no outline when we focus something inside the iframe
|
|
6210
|
-
*/
|
|
6211
|
-
``}
|
|
6212
|
-
outline: none;
|
|
6213
|
-
}
|
|
6214
|
-
${/*
|
|
6215
|
-
* @see https://hammerjs.github.io/touch-action/
|
|
6216
|
-
*/
|
|
6217
|
-
``}
|
|
6218
|
-
html, body {
|
|
6219
|
-
touch-action: none;
|
|
6220
|
-
}
|
|
6221
|
-
${/*
|
|
6222
|
-
this messes up hard, be careful with this
|
|
6223
|
-
*/
|
|
6224
|
-
``}
|
|
6225
|
-
* {
|
|
6226
|
-
-max-width: ${columnWidth}px !important;
|
|
6227
|
-
}
|
|
6228
|
-
${/*
|
|
6229
|
-
this is necessary to have a proper calculation when determining size
|
|
6230
|
-
of iframe content. If an img is using something like width:100% it would expand to
|
|
6231
|
-
the size of the original image and potentially gives back a wrong size (much larger)
|
|
6232
|
-
@see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Columns/Handling_Overflow_in_Multicol
|
|
6233
|
-
*/
|
|
6234
|
-
``}
|
|
6235
|
-
img, video, audio, object, svg {
|
|
6236
|
-
max-width: 100%;
|
|
6237
|
-
max-width: ${columnWidth}px !important;
|
|
6238
|
-
max-height: ${columnHeight}px !important;
|
|
6239
|
-
-pointer-events: none;
|
|
6240
|
-
-webkit-column-break-inside: avoid;
|
|
6241
|
-
page-break-inside: avoid;
|
|
6242
|
-
break-inside: avoid;
|
|
6243
|
-
}
|
|
6244
|
-
figure {
|
|
6245
|
-
d-max-width: ${columnWidth}px !important;
|
|
6246
|
-
}
|
|
6247
|
-
img {
|
|
6248
|
-
object-fit: contain;
|
|
6249
|
-
break-inside: avoid;
|
|
6250
|
-
box-sizing: border-box;
|
|
6251
|
-
d-max-width: ${columnWidth}px !important;
|
|
6252
|
-
}
|
|
6253
|
-
${/*
|
|
6254
|
-
img, video, audio, object, svg {
|
|
6255
|
-
max-height: ${columnHeight}px !important;
|
|
6256
|
-
box-sizing: border-box;
|
|
6257
|
-
object-fit: contain;
|
|
6258
|
-
-webkit-column-break-inside: avoid;
|
|
6259
|
-
page-break-inside: avoid;
|
|
6260
|
-
break-inside: avoid;
|
|
6261
|
-
}
|
|
6262
|
-
*/
|
|
6263
|
-
``}
|
|
6264
|
-
table {
|
|
6265
|
-
max-width: ${columnWidth}px !important;
|
|
6266
|
-
table-layout: fixed;
|
|
6267
|
-
}
|
|
6268
|
-
td {
|
|
6269
|
-
max-width: ${columnWidth}px;
|
|
6270
|
-
}
|
|
6271
|
-
`;
|
|
6272
|
-
};
|
|
6273
|
-
const createReflowableSpineItem = ({
|
|
6274
|
-
item,
|
|
6275
|
-
context,
|
|
6276
|
-
containerElement,
|
|
6277
|
-
settings,
|
|
6278
|
-
hookManager,
|
|
6279
|
-
index
|
|
6280
|
-
}) => {
|
|
6281
|
-
const commonSpineItem = createCommonSpineItem({
|
|
6282
|
-
context,
|
|
6283
|
-
item,
|
|
6284
|
-
parentElement: containerElement,
|
|
6285
|
-
settings,
|
|
6286
|
-
hookManager,
|
|
6287
|
-
index
|
|
6288
|
-
});
|
|
6289
|
-
const spineItemFrame = commonSpineItem.frame;
|
|
6290
|
-
let latestContentHeightWhenLoaded;
|
|
6291
|
-
const layout = ({
|
|
6292
|
-
blankPagePosition,
|
|
6293
|
-
minimumWidth
|
|
6294
|
-
}) => {
|
|
6295
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
6296
|
-
const { width: pageWidth, height: pageSizeHeight } = context.getPageSize();
|
|
6297
|
-
const continuousScrollableReflowableItem = ((_a = context.manifest) == null ? void 0 : _a.renditionLayout) === "reflowable" && ((_b = context.manifest) == null ? void 0 : _b.renditionFlow) === "scrolled-continuous" && commonSpineItem.item.renditionLayout === "reflowable";
|
|
6298
|
-
const pageHeight = continuousScrollableReflowableItem ? Math.min(400, pageSizeHeight) : pageSizeHeight;
|
|
6299
|
-
(_c = spineItemFrame.element) == null ? void 0 : _c.style.setProperty(`width`, `${pageWidth}px`);
|
|
6300
|
-
if (!continuousScrollableReflowableItem) {
|
|
6301
|
-
(_d = spineItemFrame.element) == null ? void 0 : _d.style.setProperty(`height`, `${pageHeight}px`);
|
|
6302
|
-
}
|
|
6303
|
-
const { viewportDimensions, computedScale = 1 } = commonSpineItem.getViewPortInformation() ?? {};
|
|
6304
|
-
const visibleArea = context.state.visibleAreaRect;
|
|
6305
|
-
const frameElement = spineItemFrame.element;
|
|
6306
|
-
const isGloballyPrePaginated = ((_e = context.manifest) == null ? void 0 : _e.renditionLayout) === `pre-paginated`;
|
|
6307
|
-
if ((spineItemFrame == null ? void 0 : spineItemFrame.isLoaded) && (frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
|
|
6308
|
-
let contentWidth = pageWidth;
|
|
6309
|
-
let contentHeight = visibleArea.height + context.state.calculatedInnerMargin;
|
|
6310
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`visibility`, `visible`);
|
|
6311
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`opacity`, `1`);
|
|
6312
|
-
if (viewportDimensions) {
|
|
6313
|
-
commonSpineItem.injectStyle(buildStyleForViewportFrame());
|
|
6314
|
-
commonSpineItem.executeOnLayoutBeforeMeasurementHook({ minimumWidth });
|
|
6315
|
-
spineItemFrame.staticLayout({
|
|
6316
|
-
width: viewportDimensions.width,
|
|
6317
|
-
height: viewportDimensions.height
|
|
6318
|
-
});
|
|
6319
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`position`, `absolute`);
|
|
6320
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`top`, `50%`);
|
|
6321
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
6322
|
-
`left`,
|
|
6323
|
-
blankPagePosition === `before` ? context.isRTL() ? `25%` : `75%` : blankPagePosition === `after` ? context.isRTL() ? `75%` : `25%` : `50%`
|
|
6324
|
-
);
|
|
6325
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
6326
|
-
`transform`,
|
|
6327
|
-
`translate(-50%, -50%) scale(${computedScale})`
|
|
6328
|
-
);
|
|
6329
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`transform-origin`, `center center`);
|
|
6330
|
-
} else {
|
|
6331
|
-
const frameStyle = commonSpineItem.isImageType() ? buildStyleForReflowableImageOnly({
|
|
6332
|
-
isScrollable: ((_f = context.manifest) == null ? void 0 : _f.renditionFlow) === `scrolled-continuous`,
|
|
6333
|
-
enableTouch: settings.values.computedPageTurnMode !== `scrollable`
|
|
6334
|
-
}) : buildStyleWithMultiColumn(
|
|
6335
|
-
commonSpineItem.getDimensionsForReflowableContent(
|
|
6336
|
-
spineItemFrame.isUsingVerticalWriting(),
|
|
6337
|
-
minimumWidth
|
|
6338
|
-
)
|
|
6339
|
-
);
|
|
6340
|
-
commonSpineItem.injectStyle(frameStyle);
|
|
6341
|
-
commonSpineItem.executeOnLayoutBeforeMeasurementHook({ minimumWidth });
|
|
6342
|
-
if (spineItemFrame.isUsingVerticalWriting()) {
|
|
6343
|
-
const pages = Math.ceil(
|
|
6344
|
-
frameElement.contentDocument.documentElement.scrollHeight / pageHeight
|
|
6345
|
-
);
|
|
6346
|
-
contentHeight = pages * pageHeight;
|
|
6347
|
-
spineItemFrame.staticLayout({
|
|
6348
|
-
width: minimumWidth,
|
|
6349
|
-
height: contentHeight
|
|
6350
|
-
});
|
|
6351
|
-
} else if (((_g = context.manifest) == null ? void 0 : _g.renditionFlow) === `scrolled-continuous`) {
|
|
6352
|
-
contentHeight = frameElement.contentDocument.body.scrollHeight;
|
|
6353
|
-
latestContentHeightWhenLoaded = contentHeight;
|
|
6354
|
-
spineItemFrame.staticLayout({
|
|
6355
|
-
width: minimumWidth,
|
|
6356
|
-
height: contentHeight
|
|
6357
|
-
});
|
|
6358
|
-
} else {
|
|
6359
|
-
const pages = Math.ceil(
|
|
6360
|
-
frameElement.contentDocument.documentElement.scrollWidth / pageWidth
|
|
6361
|
-
);
|
|
6362
|
-
if (isGloballyPrePaginated) {
|
|
6363
|
-
contentWidth = pageWidth;
|
|
6364
|
-
} else {
|
|
6365
|
-
contentWidth = pages * pageWidth;
|
|
6366
|
-
}
|
|
6367
|
-
spineItemFrame.staticLayout({
|
|
6368
|
-
width: contentWidth,
|
|
6369
|
-
height: contentHeight
|
|
6370
|
-
});
|
|
6371
|
-
}
|
|
6372
|
-
}
|
|
6373
|
-
const isFillingAllScreen = contentWidth % minimumWidth === 0;
|
|
6374
|
-
if (!isFillingAllScreen) {
|
|
6375
|
-
contentWidth = contentWidth + pageWidth;
|
|
6376
|
-
if (context.isRTL() && !commonSpineItem.isUsingVerticalWriting()) {
|
|
6377
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`margin-left`, `${pageWidth}px`);
|
|
6378
|
-
}
|
|
6379
|
-
} else {
|
|
6380
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`margin-left`, `0px`);
|
|
6381
|
-
}
|
|
6382
|
-
commonSpineItem.layout({
|
|
6383
|
-
width: contentWidth,
|
|
6384
|
-
height: contentHeight,
|
|
6385
|
-
blankPagePosition,
|
|
6386
|
-
minimumWidth
|
|
6387
|
-
});
|
|
6388
|
-
return { width: contentWidth, height: contentHeight };
|
|
6389
|
-
} else {
|
|
6390
|
-
commonSpineItem.executeOnLayoutBeforeMeasurementHook({ minimumWidth });
|
|
6391
|
-
}
|
|
6392
|
-
const height = latestContentHeightWhenLoaded || pageHeight;
|
|
6393
|
-
commonSpineItem.layout({
|
|
6394
|
-
width: minimumWidth,
|
|
6395
|
-
height,
|
|
6396
|
-
blankPagePosition,
|
|
6397
|
-
minimumWidth
|
|
6398
|
-
});
|
|
6399
|
-
return { width: minimumWidth, height };
|
|
6400
|
-
};
|
|
6401
|
-
return {
|
|
6402
|
-
...commonSpineItem,
|
|
6403
|
-
layout
|
|
6404
|
-
};
|
|
6405
|
-
};
|
|
6406
|
-
const createSpineItem = ({
|
|
6407
|
-
item,
|
|
6408
|
-
context,
|
|
6409
|
-
containerElement,
|
|
6410
|
-
settings,
|
|
6411
|
-
hookManager,
|
|
6412
|
-
index
|
|
6413
|
-
}) => {
|
|
6414
|
-
if (item.renditionLayout === `pre-paginated`) {
|
|
6415
|
-
return createPrePaginatedSpineItem({
|
|
6416
|
-
item,
|
|
6417
|
-
context,
|
|
6418
|
-
containerElement,
|
|
6419
|
-
settings,
|
|
6420
|
-
hookManager,
|
|
6421
|
-
index
|
|
6422
|
-
});
|
|
6423
|
-
}
|
|
6424
|
-
return createReflowableSpineItem({
|
|
6425
|
-
item,
|
|
6426
|
-
context,
|
|
6427
|
-
containerElement,
|
|
6428
|
-
settings,
|
|
6429
|
-
hookManager,
|
|
6430
|
-
index
|
|
6431
|
-
});
|
|
6432
|
-
};
|
|
6433
|
-
const getSpineItemFromPosition = ({
|
|
6434
|
-
position,
|
|
6435
|
-
spineItemsManager,
|
|
6436
|
-
spineLayout,
|
|
6437
|
-
settings
|
|
6438
|
-
}) => {
|
|
6439
|
-
const spineItem = spineItemsManager.items.find((item) => {
|
|
6440
|
-
const { left, right, bottom, top } = spineLayout.getAbsolutePositionOf(item);
|
|
6441
|
-
const isWithinXAxis = position.x >= left && position.x < right;
|
|
6442
|
-
if (settings.values.computedPageTurnDirection === `horizontal`) {
|
|
6443
|
-
return isWithinXAxis;
|
|
6444
|
-
} else {
|
|
6445
|
-
return isWithinXAxis && position.y >= top && position.y < bottom;
|
|
6446
|
-
}
|
|
6447
|
-
});
|
|
6448
|
-
if (position.x === 0 && !spineItem) {
|
|
6449
|
-
return spineItemsManager.items[0];
|
|
6450
|
-
}
|
|
6451
|
-
return spineItem;
|
|
6452
|
-
};
|
|
6453
|
-
const isItemVisibleByThresholdForPosition = ({
|
|
6454
|
-
itemHeight,
|
|
6455
|
-
itemWidth,
|
|
6456
|
-
visibleWidthOfItem,
|
|
6457
|
-
visibleHeightOfItem,
|
|
6458
|
-
threshold
|
|
6459
|
-
}) => {
|
|
6460
|
-
const visibleWidthRatioOfSpineItem = visibleWidthOfItem / itemWidth;
|
|
6461
|
-
const visibleHeightRatioOfSpineItem = visibleHeightOfItem / itemHeight;
|
|
6462
|
-
const isItemVisibleEnough = visibleWidthRatioOfSpineItem >= threshold && visibleHeightRatioOfSpineItem >= threshold;
|
|
6463
|
-
return isItemVisibleEnough;
|
|
6464
|
-
};
|
|
6465
|
-
const isItemVisibleOnScreenByThresholdForPosition = ({
|
|
6466
|
-
visibleWidthOfItem,
|
|
6467
|
-
visibleHeightOfItem,
|
|
6468
|
-
threshold,
|
|
6469
|
-
context
|
|
6470
|
-
}) => {
|
|
6471
|
-
const widthRatioOfSpaceTakenInScreen = visibleWidthOfItem / context.state.visibleAreaRect.width;
|
|
6472
|
-
const heightRatioOfSpaceTakenInScreen = visibleHeightOfItem / context.state.visibleAreaRect.height;
|
|
6473
|
-
const isItemVisibleEnoughOnScreen = heightRatioOfSpaceTakenInScreen >= threshold && widthRatioOfSpaceTakenInScreen >= threshold;
|
|
6474
|
-
return isItemVisibleEnoughOnScreen;
|
|
6475
|
-
};
|
|
6476
|
-
const getItemVisibilityForPosition = ({
|
|
6477
|
-
itemPosition: {
|
|
6478
|
-
bottom,
|
|
6479
|
-
left,
|
|
6480
|
-
right,
|
|
6481
|
-
top,
|
|
6482
|
-
width: itemWidth,
|
|
6483
|
-
height: itemHeight
|
|
6484
|
-
},
|
|
6485
|
-
threshold,
|
|
6486
|
-
viewportPosition,
|
|
6487
|
-
restrictToScreen,
|
|
6488
|
-
context
|
|
6489
|
-
}) => {
|
|
6490
|
-
const viewportLeft = viewportPosition.x;
|
|
6491
|
-
const viewportRight = viewportPosition.x + (context.state.visibleAreaRect.width - 1);
|
|
6492
|
-
const viewportTop = viewportPosition.y;
|
|
6493
|
-
const viewportBottom = Math.max(
|
|
6494
|
-
viewportPosition.y + (context.state.visibleAreaRect.height - 1),
|
|
6495
|
-
0
|
|
6496
|
-
);
|
|
6497
|
-
const visibleWidthOfItem = Math.max(
|
|
6498
|
-
0,
|
|
6499
|
-
Math.min(right, viewportRight) - Math.max(left, viewportLeft)
|
|
6500
|
-
);
|
|
6501
|
-
const visibleHeightOfItem = Math.max(
|
|
6502
|
-
0,
|
|
6503
|
-
Math.min(bottom, viewportBottom) - Math.max(top, viewportTop)
|
|
6504
|
-
);
|
|
6505
|
-
const itemIsOnTheOuterEdge = visibleWidthOfItem <= 0 || visibleHeightOfItem <= 0;
|
|
6506
|
-
if (itemIsOnTheOuterEdge) return { visible: false };
|
|
6507
|
-
const isItemVisibleEnoughOnScreen = isItemVisibleOnScreenByThresholdForPosition({
|
|
6508
|
-
threshold,
|
|
6509
|
-
visibleHeightOfItem,
|
|
6510
|
-
visibleWidthOfItem,
|
|
6511
|
-
context
|
|
6512
|
-
});
|
|
6513
|
-
if (restrictToScreen) {
|
|
6514
|
-
return { visible: isItemVisibleEnoughOnScreen };
|
|
6515
|
-
}
|
|
6516
|
-
const isItemVisibleEnough = isItemVisibleByThresholdForPosition({
|
|
6517
|
-
itemHeight,
|
|
6518
|
-
itemWidth,
|
|
6519
|
-
threshold,
|
|
6520
|
-
visibleHeightOfItem,
|
|
6521
|
-
visibleWidthOfItem
|
|
6522
|
-
});
|
|
6523
|
-
return {
|
|
6524
|
-
visible: isItemVisibleEnough || isItemVisibleEnoughOnScreen
|
|
6525
|
-
};
|
|
6526
|
-
};
|
|
6527
|
-
const getVisibleSpineItemsFromPosition = ({
|
|
6528
|
-
position,
|
|
6529
|
-
threshold,
|
|
6530
|
-
restrictToScreen,
|
|
6531
|
-
spineItemsManager,
|
|
6532
|
-
context,
|
|
6533
|
-
settings,
|
|
6534
|
-
spineLayout
|
|
6535
|
-
}) => {
|
|
6536
|
-
const fallbackSpineItem = getSpineItemFromPosition({
|
|
6537
|
-
position,
|
|
6538
|
-
settings,
|
|
6539
|
-
spineItemsManager,
|
|
6540
|
-
spineLayout
|
|
6541
|
-
}) || spineItemsManager.get(0);
|
|
6542
|
-
const spineItemsVisible = spineItemsManager.items.reduce(
|
|
6543
|
-
(acc, spineItem) => {
|
|
6544
|
-
const itemPosition = spineLayout.getAbsolutePositionOf(spineItem);
|
|
6545
|
-
const { visible } = getItemVisibilityForPosition({
|
|
6546
|
-
itemPosition,
|
|
6547
|
-
threshold,
|
|
6548
|
-
viewportPosition: position,
|
|
6549
|
-
restrictToScreen,
|
|
6550
|
-
context
|
|
6551
|
-
});
|
|
6552
|
-
if (visible) {
|
|
6553
|
-
return [...acc, spineItem];
|
|
6554
|
-
}
|
|
6555
|
-
return acc;
|
|
6556
|
-
},
|
|
6557
|
-
[]
|
|
6558
|
-
);
|
|
6559
|
-
const beginItem = spineItemsVisible[0] ?? fallbackSpineItem;
|
|
6560
|
-
const endItem = spineItemsVisible[spineItemsVisible.length - 1] ?? beginItem;
|
|
6561
|
-
if (!beginItem || !endItem) return void 0;
|
|
6562
|
-
const beginItemIndex = spineItemsManager.getSpineItemIndex(beginItem);
|
|
6563
|
-
const endItemIndex = spineItemsManager.getSpineItemIndex(endItem);
|
|
6564
|
-
return {
|
|
6565
|
-
beginIndex: beginItemIndex ?? 0,
|
|
6566
|
-
endIndex: endItemIndex ?? 0
|
|
6567
|
-
};
|
|
6568
|
-
};
|
|
6569
|
-
const getSpinePositionFromSpineItemPosition = ({
|
|
6570
|
-
spineItemPosition,
|
|
6571
|
-
itemLayout: { left, top }
|
|
6572
|
-
}) => {
|
|
6573
|
-
return {
|
|
6574
|
-
x: left + spineItemPosition.x,
|
|
6575
|
-
y: top + spineItemPosition.y
|
|
6576
|
-
};
|
|
6577
|
-
};
|
|
6578
|
-
const getSpineInfoFromAbsolutePageIndex = ({
|
|
6579
|
-
absolutePageIndex,
|
|
6580
|
-
spineLayout,
|
|
6581
|
-
spineItemsManager,
|
|
6582
|
-
context,
|
|
6583
|
-
settings
|
|
6584
|
-
}) => {
|
|
6585
|
-
const items = spineItemsManager.items;
|
|
6586
|
-
const { found, currentAbsolutePage } = items.reduce(
|
|
6587
|
-
(acc, item) => {
|
|
6588
|
-
if (acc.found) return acc;
|
|
6589
|
-
const itemLayout = spineLayout.getAbsolutePositionOf(item);
|
|
6590
|
-
const numberOfPages = getSpineItemNumberOfPages({
|
|
6591
|
-
isUsingVerticalWriting: !!item.isUsingVerticalWriting(),
|
|
6592
|
-
itemHeight: itemLayout.height,
|
|
6593
|
-
itemWidth: itemLayout.width,
|
|
6594
|
-
context,
|
|
6595
|
-
settings
|
|
6596
|
-
});
|
|
6597
|
-
const possiblePageIndex = absolutePageIndex - acc.currentAbsolutePage;
|
|
6598
|
-
const currentAbsolutePage2 = acc.currentAbsolutePage + numberOfPages;
|
|
6599
|
-
if (possiblePageIndex <= numberOfPages - 1) {
|
|
6600
|
-
return {
|
|
6601
|
-
...acc,
|
|
6602
|
-
currentAbsolutePage: currentAbsolutePage2,
|
|
6603
|
-
found: { item, pageIndex: possiblePageIndex }
|
|
6604
|
-
};
|
|
6605
|
-
}
|
|
6606
|
-
return {
|
|
6607
|
-
...acc,
|
|
6608
|
-
currentAbsolutePage: currentAbsolutePage2
|
|
6609
|
-
};
|
|
6610
|
-
},
|
|
6611
|
-
{ currentAbsolutePage: 0 }
|
|
6612
|
-
);
|
|
6613
|
-
if (found) {
|
|
6614
|
-
return {
|
|
6615
|
-
spineItem: found.item,
|
|
6616
|
-
pageIndex: found.pageIndex,
|
|
6617
|
-
itemIndex: spineItemsManager.getSpineItemIndex(found.item) ?? 0,
|
|
6618
|
-
currentAbsolutePage
|
|
6619
|
-
};
|
|
6620
|
-
}
|
|
6621
|
-
return void 0;
|
|
6622
|
-
};
|
|
6623
|
-
const getAbsolutePageIndexFromPageIndex = ({
|
|
6624
|
-
pageIndex,
|
|
6625
|
-
spineItemOrId,
|
|
6626
|
-
spineLayout,
|
|
6627
|
-
spineItemsManager,
|
|
6628
|
-
context,
|
|
6629
|
-
settings
|
|
6630
|
-
}) => {
|
|
6631
|
-
const items = spineItemsManager.items;
|
|
6632
|
-
const spineItem = spineItemsManager.get(spineItemOrId);
|
|
6633
|
-
if (!spineItem) return void 0;
|
|
6634
|
-
const { currentAbsolutePage } = items.reduce(
|
|
6635
|
-
(acc, item) => {
|
|
6636
|
-
if (acc.found) return acc;
|
|
6637
|
-
const itemLayout = spineLayout.getAbsolutePositionOf(item);
|
|
6638
|
-
const numberOfPages = getSpineItemNumberOfPages({
|
|
6639
|
-
isUsingVerticalWriting: !!item.isUsingVerticalWriting(),
|
|
6640
|
-
itemHeight: itemLayout.height,
|
|
6641
|
-
itemWidth: itemLayout.width,
|
|
6642
|
-
context,
|
|
6643
|
-
settings
|
|
6644
|
-
});
|
|
6645
|
-
if (spineItem === item) {
|
|
6646
|
-
if (pageIndex <= numberOfPages - 1) {
|
|
6647
|
-
return {
|
|
6648
|
-
currentAbsolutePage: acc.currentAbsolutePage + pageIndex,
|
|
6649
|
-
found: true
|
|
6650
|
-
};
|
|
6651
|
-
}
|
|
6652
|
-
}
|
|
6653
|
-
return {
|
|
6654
|
-
...acc,
|
|
6655
|
-
currentAbsolutePage: acc.currentAbsolutePage + numberOfPages
|
|
6656
|
-
};
|
|
6657
|
-
},
|
|
6658
|
-
{ currentAbsolutePage: 0, found: false }
|
|
6659
|
-
);
|
|
6660
|
-
return currentAbsolutePage;
|
|
6661
|
-
};
|
|
6662
|
-
const createSpineLocator = ({
|
|
6663
|
-
spineItemsManager,
|
|
6664
|
-
context,
|
|
6665
|
-
spineItemLocator,
|
|
6666
|
-
settings,
|
|
6667
|
-
spineLayout
|
|
6668
|
-
}) => {
|
|
6669
|
-
const getSpineItemPositionFromSpinePosition = Report.measurePerformance(
|
|
6670
|
-
`getSpineItemPositionFromSpinePosition`,
|
|
6671
|
-
10,
|
|
6672
|
-
(position, spineItem) => {
|
|
6673
|
-
const { left, top } = spineLayout.getAbsolutePositionOf(spineItem);
|
|
6674
|
-
return {
|
|
6675
|
-
/**
|
|
6676
|
-
* when using spread the item could be on the right and therefore will be negative
|
|
6677
|
-
* @example
|
|
6678
|
-
* 400 (position = viewport), page of 200
|
|
6679
|
-
* 400 - 600 = -200.
|
|
6680
|
-
* However we can assume we are at 0, because we in fact can see the beginning of the item
|
|
6681
|
-
*/
|
|
6682
|
-
x: Math.max(position.x - left, 0),
|
|
6683
|
-
y: Math.max(position.y - top, 0)
|
|
6684
|
-
};
|
|
6685
|
-
},
|
|
6686
|
-
{ disable: true }
|
|
6687
|
-
);
|
|
6688
|
-
const getSpinePositionFromSpineItem = (spineItem) => {
|
|
6689
|
-
return getSpinePositionFromSpineItemPosition({
|
|
6690
|
-
spineItemPosition: { x: 0, y: 0 },
|
|
6691
|
-
itemLayout: spineLayout.getAbsolutePositionOf(spineItem)
|
|
6692
|
-
});
|
|
6693
|
-
};
|
|
6694
|
-
const getSpineItemFromIframe = (iframe) => {
|
|
6695
|
-
return spineItemsManager.items.find((item) => item.frame.element === iframe);
|
|
6696
|
-
};
|
|
6697
|
-
const getSpineItemPageIndexFromNode = (node, offset, spineItemOrIndex) => {
|
|
6698
|
-
if (typeof spineItemOrIndex === `number`) {
|
|
6699
|
-
const spineItem = spineItemsManager.get(spineItemOrIndex);
|
|
6700
|
-
return spineItem ? spineItemLocator.getSpineItemPageIndexFromNode(
|
|
6701
|
-
node,
|
|
6702
|
-
offset || 0,
|
|
6703
|
-
spineItem
|
|
6704
|
-
) : void 0;
|
|
6705
|
-
}
|
|
6706
|
-
return spineItemLocator.getSpineItemPageIndexFromNode(
|
|
6707
|
-
node,
|
|
6708
|
-
offset || 0,
|
|
6709
|
-
spineItemOrIndex
|
|
6710
|
-
);
|
|
6711
|
-
};
|
|
6712
|
-
const getVisiblePagesFromViewportPosition = ({
|
|
6713
|
-
position,
|
|
6714
|
-
threshold,
|
|
6715
|
-
spineItem,
|
|
6716
|
-
restrictToScreen
|
|
6717
|
-
}) => {
|
|
6718
|
-
const { height, width } = spineItem.getElementDimensions();
|
|
6719
|
-
const numberOfPages = spineItemLocator.getSpineItemNumberOfPages({
|
|
6720
|
-
isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
|
|
6721
|
-
itemHeight: height,
|
|
6722
|
-
itemWidth: width
|
|
6723
|
-
});
|
|
6724
|
-
const pages = Array.from(Array(numberOfPages)).map((_, index) => {
|
|
6725
|
-
const spineItemPosition = spineItemLocator.getSpineItemPositionFromPageIndex({
|
|
6726
|
-
pageIndex: index,
|
|
6727
|
-
isUsingVerticalWriting: !!spineItem.isUsingVerticalWriting(),
|
|
6728
|
-
itemLayout: spineItem.getElementDimensions()
|
|
6729
|
-
});
|
|
6730
|
-
const spinePosition = getSpinePositionFromSpineItemPosition({
|
|
6731
|
-
spineItemPosition,
|
|
6732
|
-
itemLayout: spineLayout.getAbsolutePositionOf(spineItem)
|
|
6733
|
-
});
|
|
6734
|
-
return {
|
|
6735
|
-
index,
|
|
6736
|
-
absolutePosition: {
|
|
6737
|
-
width: context.getPageSize().width,
|
|
6738
|
-
height: context.getPageSize().height,
|
|
6739
|
-
left: spinePosition.x,
|
|
6740
|
-
top: spinePosition.y,
|
|
6741
|
-
bottom: spinePosition.y + context.getPageSize().height,
|
|
6742
|
-
right: spinePosition.x + context.getPageSize().width
|
|
6743
|
-
}
|
|
6744
|
-
};
|
|
6745
|
-
});
|
|
6746
|
-
const pagesVisible = pages.reduce(
|
|
6747
|
-
(acc, { absolutePosition, index }) => {
|
|
6748
|
-
const { visible } = getItemVisibilityForPosition({
|
|
6749
|
-
context,
|
|
6750
|
-
viewportPosition: position,
|
|
6751
|
-
restrictToScreen,
|
|
6752
|
-
threshold,
|
|
6753
|
-
itemPosition: absolutePosition
|
|
6754
|
-
});
|
|
6755
|
-
if (visible) {
|
|
6756
|
-
return [...acc, index];
|
|
6757
|
-
}
|
|
6758
|
-
return acc;
|
|
6759
|
-
},
|
|
6760
|
-
[]
|
|
6761
|
-
);
|
|
6762
|
-
const beginPageIndex = pagesVisible[0];
|
|
6763
|
-
const endPageIndex = pagesVisible[pagesVisible.length - 1] ?? beginPageIndex;
|
|
6764
|
-
if (beginPageIndex === void 0 || endPageIndex === void 0)
|
|
6765
|
-
return void 0;
|
|
6766
|
-
return {
|
|
6767
|
-
beginPageIndex,
|
|
6768
|
-
endPageIndex
|
|
6769
|
-
};
|
|
6770
|
-
};
|
|
6771
|
-
const isPositionWithinSpineItem = (position, spineItem) => {
|
|
6772
|
-
const { bottom, left, right, top } = spineLayout.getAbsolutePositionOf(spineItem);
|
|
6773
|
-
return position.x >= left && position.x <= right && position.y <= bottom && position.y >= top;
|
|
6774
|
-
};
|
|
6775
|
-
const getSafeSpineItemPositionFromUnsafeSpineItemPosition = (unsafePosition, spineItem) => {
|
|
6776
|
-
const { height, width } = spineLayout.getAbsolutePositionOf(spineItem);
|
|
6777
|
-
return {
|
|
6778
|
-
x: Math.min(Math.max(0, unsafePosition.x), width),
|
|
6779
|
-
y: Math.min(Math.max(0, unsafePosition.y), height)
|
|
6780
|
-
};
|
|
6781
|
-
};
|
|
6782
|
-
return {
|
|
6783
|
-
getSpinePositionFromSpineItemPosition: ({
|
|
6784
|
-
spineItem,
|
|
6785
|
-
spineItemPosition
|
|
6786
|
-
}) => {
|
|
6787
|
-
const itemLayout = spineLayout.getAbsolutePositionOf(spineItem);
|
|
6788
|
-
return getSpinePositionFromSpineItemPosition({
|
|
6789
|
-
itemLayout,
|
|
6790
|
-
spineItemPosition
|
|
6791
|
-
});
|
|
5576
|
+
getSpinePositionFromSpineItemPosition: ({
|
|
5577
|
+
spineItem,
|
|
5578
|
+
spineItemPosition
|
|
5579
|
+
}) => {
|
|
5580
|
+
const itemLayout = spineLayout.getAbsolutePositionOf(spineItem);
|
|
5581
|
+
return getSpinePositionFromSpineItemPosition({
|
|
5582
|
+
itemLayout,
|
|
5583
|
+
spineItemPosition
|
|
5584
|
+
});
|
|
6792
5585
|
},
|
|
6793
5586
|
getAbsolutePageIndexFromPageIndex: (params) => getAbsolutePageIndexFromPageIndex({
|
|
6794
5587
|
...params,
|
|
@@ -6899,7 +5692,7 @@ class SpineItemsObserver extends DestroyableClass {
|
|
|
6899
5692
|
this.itemIsReady$ = this.spineItemsManager.items$.pipe(
|
|
6900
5693
|
switchMap((items) => {
|
|
6901
5694
|
const itemsIsReady$ = items.map(
|
|
6902
|
-
(item) => item
|
|
5695
|
+
(item) => item.isReady$.pipe(map$1((isReady) => ({ item, isReady })))
|
|
6903
5696
|
);
|
|
6904
5697
|
return merge(...itemsIsReady$);
|
|
6905
5698
|
}),
|
|
@@ -6916,6 +5709,14 @@ class SpineItemsObserver extends DestroyableClass {
|
|
|
6916
5709
|
}),
|
|
6917
5710
|
share()
|
|
6918
5711
|
);
|
|
5712
|
+
this.itemLoaded$ = this.spineItemsManager.items$.pipe(
|
|
5713
|
+
switchMap((items) => {
|
|
5714
|
+
const itemsIsReady$ = items.map(
|
|
5715
|
+
(item) => item.loaded$.pipe(map$1(() => item))
|
|
5716
|
+
);
|
|
5717
|
+
return merge(...itemsIsReady$);
|
|
5718
|
+
})
|
|
5719
|
+
);
|
|
6919
5720
|
}
|
|
6920
5721
|
}
|
|
6921
5722
|
const convertSpinePositionToLayoutPosition = ({
|
|
@@ -6945,14 +5746,14 @@ class SpineLayout extends DestroyableClass {
|
|
|
6945
5746
|
spineItemsManager.items$.pipe(
|
|
6946
5747
|
switchMap((items) => {
|
|
6947
5748
|
const itemsLayout$ = items.map(
|
|
6948
|
-
(spineItem) => spineItem
|
|
5749
|
+
(spineItem) => spineItem.contentLayout$.pipe(
|
|
6949
5750
|
tap$1(() => {
|
|
6950
5751
|
this.layout();
|
|
6951
5752
|
})
|
|
6952
5753
|
)
|
|
6953
5754
|
);
|
|
6954
5755
|
const writingModeUpdate$ = items.map(
|
|
6955
|
-
(spineItem) => spineItem
|
|
5756
|
+
(spineItem) => spineItem.loaded$.pipe(
|
|
6956
5757
|
tap$1(() => {
|
|
6957
5758
|
if (spineItem.isUsingVerticalWriting()) {
|
|
6958
5759
|
this.context.update({
|
|
@@ -7157,6 +5958,423 @@ class SpineLayout extends DestroyableClass {
|
|
|
7157
5958
|
this.layoutSubject.complete();
|
|
7158
5959
|
}
|
|
7159
5960
|
}
|
|
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
|
+
class DocumentRenderer {
|
|
6039
|
+
constructor(context, settings, hookManager, item, containerElement, resourcesHandler) {
|
|
6040
|
+
this.context = context;
|
|
6041
|
+
this.settings = settings;
|
|
6042
|
+
this.hookManager = hookManager;
|
|
6043
|
+
this.item = item;
|
|
6044
|
+
this.containerElement = containerElement;
|
|
6045
|
+
this.resourcesHandler = resourcesHandler;
|
|
6046
|
+
this.stateSubject = new BehaviorSubject(`idle`);
|
|
6047
|
+
this.triggerSubject = new Subject();
|
|
6048
|
+
this.layers = [];
|
|
6049
|
+
this.unload$ = this.triggerSubject.pipe(
|
|
6050
|
+
withLatestFrom(this.stateSubject),
|
|
6051
|
+
filter$1(
|
|
6052
|
+
([trigger, state]) => trigger === `unload` && state !== "idle" && state !== "unloading"
|
|
6053
|
+
),
|
|
6054
|
+
map$1(() => void 0),
|
|
6055
|
+
share()
|
|
6056
|
+
);
|
|
6057
|
+
this.load$ = this.triggerSubject.pipe(
|
|
6058
|
+
withLatestFrom(this.stateSubject),
|
|
6059
|
+
filter$1(
|
|
6060
|
+
([trigger, state]) => trigger === `load` && state !== "ready" && state !== "loaded" && state !== "loading"
|
|
6061
|
+
),
|
|
6062
|
+
map$1(() => void 0),
|
|
6063
|
+
share()
|
|
6064
|
+
);
|
|
6065
|
+
this.destroy$ = this.triggerSubject.pipe(
|
|
6066
|
+
filter$1((trigger) => trigger === `destroy`)
|
|
6067
|
+
);
|
|
6068
|
+
this.stateSubject.subscribe((state) => {
|
|
6069
|
+
console.log(`FOOO`, item.id, `state`, state);
|
|
6070
|
+
});
|
|
6071
|
+
this.load$.pipe(
|
|
6072
|
+
switchMap(() => {
|
|
6073
|
+
this.stateSubject.next(`loading`);
|
|
6074
|
+
const createDocument$ = this.onCreateDocument().pipe(
|
|
6075
|
+
endWith(null),
|
|
6076
|
+
first$1()
|
|
6077
|
+
);
|
|
6078
|
+
return createDocument$.pipe(
|
|
6079
|
+
tap$1(() => {
|
|
6080
|
+
this.hookManager.execute(`item.onDocumentCreated`, this.item.id, {
|
|
6081
|
+
itemId: this.item.id,
|
|
6082
|
+
layers: this.layers
|
|
6083
|
+
});
|
|
6084
|
+
}),
|
|
6085
|
+
switchMap(() => {
|
|
6086
|
+
const loadDocument$ = this.onLoadDocument().pipe(
|
|
6087
|
+
endWith(null),
|
|
6088
|
+
first$1()
|
|
6089
|
+
);
|
|
6090
|
+
return loadDocument$;
|
|
6091
|
+
}),
|
|
6092
|
+
waitForSwitch(this.context.bridgeEvent.viewportFree$),
|
|
6093
|
+
switchMap(() => {
|
|
6094
|
+
const hookResults = this.hookManager.execute(`item.onDocumentLoad`, this.item.id, {
|
|
6095
|
+
itemId: this.item.id,
|
|
6096
|
+
layers: this.layers
|
|
6097
|
+
}).filter(
|
|
6098
|
+
(result) => result instanceof Observable
|
|
6099
|
+
);
|
|
6100
|
+
return combineLatest([of(null), ...hookResults]).pipe(first$1());
|
|
6101
|
+
}),
|
|
6102
|
+
tap$1(() => {
|
|
6103
|
+
this.stateSubject.next(`loaded`);
|
|
6104
|
+
this.stateSubject.next(`ready`);
|
|
6105
|
+
}),
|
|
6106
|
+
takeUntil(merge(this.destroy$, this.unload$))
|
|
6107
|
+
);
|
|
6108
|
+
})
|
|
6109
|
+
).subscribe();
|
|
6110
|
+
this.unload$.pipe(
|
|
6111
|
+
switchMap(() => {
|
|
6112
|
+
this.stateSubject.next(`unloading`);
|
|
6113
|
+
return this.context.bridgeEvent.viewportFree$.pipe(
|
|
6114
|
+
first$1(),
|
|
6115
|
+
tap$1(() => {
|
|
6116
|
+
this.hookManager.destroy(`item.onDocumentLoad`, this.item.id);
|
|
6117
|
+
}),
|
|
6118
|
+
switchMap(() => {
|
|
6119
|
+
const unload$ = this.onUnload().pipe(endWith(null), first$1());
|
|
6120
|
+
return unload$;
|
|
6121
|
+
}),
|
|
6122
|
+
tap$1(() => {
|
|
6123
|
+
this.stateSubject.next(`idle`);
|
|
6124
|
+
}),
|
|
6125
|
+
takeUntil(merge(this.destroy$, this.load$))
|
|
6126
|
+
);
|
|
6127
|
+
})
|
|
6128
|
+
).subscribe();
|
|
6129
|
+
}
|
|
6130
|
+
get state$() {
|
|
6131
|
+
return this.stateSubject;
|
|
6132
|
+
}
|
|
6133
|
+
load() {
|
|
6134
|
+
this.triggerSubject.next(`load`);
|
|
6135
|
+
}
|
|
6136
|
+
unload() {
|
|
6137
|
+
this.triggerSubject.next(`unload`);
|
|
6138
|
+
}
|
|
6139
|
+
destroy() {
|
|
6140
|
+
this.triggerSubject.next(`destroy`);
|
|
6141
|
+
this.triggerSubject.complete();
|
|
6142
|
+
this.stateSubject.complete();
|
|
6143
|
+
}
|
|
6144
|
+
get writingMode() {
|
|
6145
|
+
return void 0;
|
|
6146
|
+
}
|
|
6147
|
+
get readingDirection() {
|
|
6148
|
+
return void 0;
|
|
6149
|
+
}
|
|
6150
|
+
}
|
|
6151
|
+
class DefaultRenderer extends DocumentRenderer {
|
|
6152
|
+
onUnload() {
|
|
6153
|
+
return EMPTY;
|
|
6154
|
+
}
|
|
6155
|
+
onCreateDocument() {
|
|
6156
|
+
return EMPTY;
|
|
6157
|
+
}
|
|
6158
|
+
onLoadDocument() {
|
|
6159
|
+
return EMPTY;
|
|
6160
|
+
}
|
|
6161
|
+
layout() {
|
|
6162
|
+
return void 0;
|
|
6163
|
+
}
|
|
6164
|
+
}
|
|
6165
|
+
const defaultGetResource = (item) => new URL(item.href);
|
|
6166
|
+
class ResourceHandler {
|
|
6167
|
+
constructor(item, settings) {
|
|
6168
|
+
this.item = item;
|
|
6169
|
+
this.settings = settings;
|
|
6170
|
+
}
|
|
6171
|
+
async getResource() {
|
|
6172
|
+
var _a, _b;
|
|
6173
|
+
const resource = await lastValueFrom(
|
|
6174
|
+
((_b = (_a = this.settings.values).getResource) == null ? void 0 : _b.call(_a, this.item)) ?? of(void 0)
|
|
6175
|
+
);
|
|
6176
|
+
return resource ?? defaultGetResource(this.item);
|
|
6177
|
+
}
|
|
6178
|
+
async fetchResource() {
|
|
6179
|
+
const resource = await this.getResource();
|
|
6180
|
+
if (resource instanceof Response) return resource;
|
|
6181
|
+
if (resource instanceof URL) return fetch(resource);
|
|
6182
|
+
return resource;
|
|
6183
|
+
}
|
|
6184
|
+
}
|
|
6185
|
+
class SpineItem {
|
|
6186
|
+
constructor(item, parentElement, context, settings, hookManager, index) {
|
|
6187
|
+
var _a, _b;
|
|
6188
|
+
this.item = item;
|
|
6189
|
+
this.parentElement = parentElement;
|
|
6190
|
+
this.context = context;
|
|
6191
|
+
this.settings = settings;
|
|
6192
|
+
this.hookManager = hookManager;
|
|
6193
|
+
this.index = index;
|
|
6194
|
+
this.adjustPositionOfElement = ({
|
|
6195
|
+
right,
|
|
6196
|
+
left,
|
|
6197
|
+
top
|
|
6198
|
+
}) => {
|
|
6199
|
+
if (right !== void 0) {
|
|
6200
|
+
this.containerElement.style.right = `${right}px`;
|
|
6201
|
+
} else {
|
|
6202
|
+
this.containerElement.style.removeProperty(`right`);
|
|
6203
|
+
}
|
|
6204
|
+
if (left !== void 0) {
|
|
6205
|
+
this.containerElement.style.left = `${left}px`;
|
|
6206
|
+
} else {
|
|
6207
|
+
this.containerElement.style.removeProperty(`left`);
|
|
6208
|
+
}
|
|
6209
|
+
if (top !== void 0) {
|
|
6210
|
+
this.containerElement.style.top = `${top}px`;
|
|
6211
|
+
} else {
|
|
6212
|
+
this.containerElement.style.removeProperty(`top`);
|
|
6213
|
+
}
|
|
6214
|
+
};
|
|
6215
|
+
this.getBoundingRectOfElementFromSelector = (selector) => {
|
|
6216
|
+
var _a2, _b2, _c, _d, _e;
|
|
6217
|
+
const frameElement = (_a2 = this.renderer.layers[0]) == null ? void 0 : _a2.element;
|
|
6218
|
+
if (frameElement && frameElement instanceof HTMLIFrameElement && selector) {
|
|
6219
|
+
if (selector.startsWith(`#`)) {
|
|
6220
|
+
return (_c = (_b2 = frameElement.contentDocument) == null ? void 0 : _b2.getElementById(selector.replace(`#`, ``))) == null ? void 0 : _c.getBoundingClientRect();
|
|
6221
|
+
}
|
|
6222
|
+
return (_e = (_d = frameElement.contentDocument) == null ? void 0 : _d.querySelector(selector)) == null ? void 0 : _e.getBoundingClientRect();
|
|
6223
|
+
}
|
|
6224
|
+
};
|
|
6225
|
+
this.layout = ({
|
|
6226
|
+
blankPagePosition,
|
|
6227
|
+
minimumWidth,
|
|
6228
|
+
spreadPosition
|
|
6229
|
+
}) => {
|
|
6230
|
+
this.hookManager.execute(`item.onBeforeLayout`, void 0, {
|
|
6231
|
+
blankPagePosition,
|
|
6232
|
+
item: this.item,
|
|
6233
|
+
minimumWidth
|
|
6234
|
+
});
|
|
6235
|
+
const { height, width } = this.renderer.layout({
|
|
6236
|
+
blankPagePosition,
|
|
6237
|
+
minPageSpread: minimumWidth / this.context.getPageSize().width,
|
|
6238
|
+
spreadPosition
|
|
6239
|
+
}) ?? { width: 0, height: 0 };
|
|
6240
|
+
const minHeight = Math.max(height, this.context.getPageSize().height);
|
|
6241
|
+
const minWidth = Math.max(width, minimumWidth);
|
|
6242
|
+
this.containerElement.style.width = `${minWidth}px`;
|
|
6243
|
+
this.containerElement.style.height = `${minHeight}px`;
|
|
6244
|
+
this.hookManager.execute(`item.onAfterLayout`, void 0, {
|
|
6245
|
+
blankPagePosition,
|
|
6246
|
+
item: this.item,
|
|
6247
|
+
minimumWidth
|
|
6248
|
+
});
|
|
6249
|
+
return { width: minWidth, height: minHeight };
|
|
6250
|
+
};
|
|
6251
|
+
this.load = () => this.renderer.load();
|
|
6252
|
+
this.unload = () => {
|
|
6253
|
+
this.renderer.unload();
|
|
6254
|
+
};
|
|
6255
|
+
this.getElementDimensions = () => {
|
|
6256
|
+
const rect = this.containerElement.getBoundingClientRect();
|
|
6257
|
+
const normalizedValues = {
|
|
6258
|
+
...rect,
|
|
6259
|
+
// we want to round to first decimal because it's possible to have half pixel
|
|
6260
|
+
// however browser engine can also gives back x.yyyy based on their precision
|
|
6261
|
+
width: Math.round(rect.width * 10) / 10,
|
|
6262
|
+
height: Math.round(rect.height * 10) / 10
|
|
6263
|
+
};
|
|
6264
|
+
return normalizedValues;
|
|
6265
|
+
};
|
|
6266
|
+
this.destroy = () => {
|
|
6267
|
+
this.destroySubject$.next();
|
|
6268
|
+
this.containerElement.remove();
|
|
6269
|
+
this.fingerTracker.destroy();
|
|
6270
|
+
this.selectionTracker.destroy();
|
|
6271
|
+
this.destroySubject$.complete();
|
|
6272
|
+
this.renderer.destroy();
|
|
6273
|
+
};
|
|
6274
|
+
this.isUsingVerticalWriting = () => {
|
|
6275
|
+
var _a2;
|
|
6276
|
+
return !!((_a2 = this.renderer.writingMode) == null ? void 0 : _a2.startsWith(`vertical`));
|
|
6277
|
+
};
|
|
6278
|
+
this.destroySubject$ = new Subject();
|
|
6279
|
+
this.containerElement = createContainerElement(
|
|
6280
|
+
parentElement,
|
|
6281
|
+
item,
|
|
6282
|
+
hookManager
|
|
6283
|
+
);
|
|
6284
|
+
this.fingerTracker = createFingerTracker();
|
|
6285
|
+
this.selectionTracker = createSelectionTracker();
|
|
6286
|
+
parentElement.appendChild(this.containerElement);
|
|
6287
|
+
const RendererClass = ((_b = (_a = this.settings.values).getRenderer) == null ? void 0 : _b.call(_a, item)) ?? DefaultRenderer;
|
|
6288
|
+
this.resourcesHandler = new ResourceHandler(item, this.settings);
|
|
6289
|
+
this.renderer = new RendererClass(
|
|
6290
|
+
context,
|
|
6291
|
+
settings,
|
|
6292
|
+
hookManager,
|
|
6293
|
+
item,
|
|
6294
|
+
this.containerElement,
|
|
6295
|
+
this.resourcesHandler
|
|
6296
|
+
);
|
|
6297
|
+
const contentLayoutChange$ = merge(
|
|
6298
|
+
this.unloaded$.pipe(map(() => ({ isFirstLayout: false }))),
|
|
6299
|
+
this.ready$.pipe(map(() => ({ isFirstLayout: true })))
|
|
6300
|
+
);
|
|
6301
|
+
this.contentLayout$ = contentLayoutChange$.pipe(
|
|
6302
|
+
withLatestFrom$1(this.isReady$),
|
|
6303
|
+
map(([data, isReady]) => ({
|
|
6304
|
+
isFirstLayout: data.isFirstLayout,
|
|
6305
|
+
isReady
|
|
6306
|
+
}))
|
|
6307
|
+
);
|
|
6308
|
+
}
|
|
6309
|
+
get element() {
|
|
6310
|
+
return this.containerElement;
|
|
6311
|
+
}
|
|
6312
|
+
/**
|
|
6313
|
+
* @important
|
|
6314
|
+
* Do not use this value for layout and navigation. It will be in possible conflict
|
|
6315
|
+
* with the global reading direction. A book should not mix them anyway. A page can have
|
|
6316
|
+
* a different reading direction for style reason but it should be in theory pre-paginated.
|
|
6317
|
+
* For example an english page in a japanese manga. That's expected and will
|
|
6318
|
+
* be confined to a single page.
|
|
6319
|
+
*/
|
|
6320
|
+
get readingDirection() {
|
|
6321
|
+
return this.renderer.readingDirection;
|
|
6322
|
+
}
|
|
6323
|
+
get isReady() {
|
|
6324
|
+
return this.renderer.state$.getValue() === "ready";
|
|
6325
|
+
}
|
|
6326
|
+
get ready$() {
|
|
6327
|
+
return this.renderer.state$.pipe(
|
|
6328
|
+
distinctUntilChanged(),
|
|
6329
|
+
filter((state) => state === "ready")
|
|
6330
|
+
);
|
|
6331
|
+
}
|
|
6332
|
+
get loaded$() {
|
|
6333
|
+
return this.renderer.state$.pipe(
|
|
6334
|
+
distinctUntilChanged(),
|
|
6335
|
+
filter((state) => state === "loaded")
|
|
6336
|
+
);
|
|
6337
|
+
}
|
|
6338
|
+
get unloaded$() {
|
|
6339
|
+
return this.renderer.state$.pipe(
|
|
6340
|
+
distinctUntilChanged(),
|
|
6341
|
+
filter((state) => state !== "idle"),
|
|
6342
|
+
switchMap$1(
|
|
6343
|
+
() => this.renderer.state$.pipe(
|
|
6344
|
+
filter((state) => state === `idle`),
|
|
6345
|
+
first()
|
|
6346
|
+
)
|
|
6347
|
+
)
|
|
6348
|
+
);
|
|
6349
|
+
}
|
|
6350
|
+
get isReady$() {
|
|
6351
|
+
return this.renderer.state$.pipe(map((state) => state === "ready"));
|
|
6352
|
+
}
|
|
6353
|
+
/**
|
|
6354
|
+
* Helper that will inject CSS into the document frame.
|
|
6355
|
+
*
|
|
6356
|
+
* @important
|
|
6357
|
+
* The document needs to be detected as a frame.
|
|
6358
|
+
*/
|
|
6359
|
+
upsertCSS(id, style, prepend) {
|
|
6360
|
+
this.renderer.layers.forEach((layer) => {
|
|
6361
|
+
if (layer.element instanceof HTMLIFrameElement) {
|
|
6362
|
+
upsertCSS(layer.element, id, style, prepend);
|
|
6363
|
+
}
|
|
6364
|
+
});
|
|
6365
|
+
}
|
|
6366
|
+
}
|
|
6367
|
+
const createContainerElement = (containerElement, item, hookManager) => {
|
|
6368
|
+
const element = containerElement.ownerDocument.createElement(`div`);
|
|
6369
|
+
element.classList.add(`spineItem`);
|
|
6370
|
+
element.classList.add(`spineItem-${item.renditionLayout}`);
|
|
6371
|
+
element.style.cssText = `
|
|
6372
|
+
position: absolute;
|
|
6373
|
+
overflow: hidden;
|
|
6374
|
+
`;
|
|
6375
|
+
hookManager.execute("item.onBeforeContainerCreated", void 0, { element });
|
|
6376
|
+
return element;
|
|
6377
|
+
};
|
|
7160
6378
|
class Spine extends DestroyableClass {
|
|
7161
6379
|
constructor(parentElement$, context, pagination, spineItemsManager, spineItemLocator, settings, hookManager) {
|
|
7162
6380
|
super();
|
|
@@ -7196,14 +6414,14 @@ class Spine extends DestroyableClass {
|
|
|
7196
6414
|
tap((manifest) => {
|
|
7197
6415
|
this.spineItemsManager.destroyItems();
|
|
7198
6416
|
const spineItems = manifest.spineItems.map(
|
|
7199
|
-
(resource, index) =>
|
|
7200
|
-
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
6417
|
+
(resource, index) => new SpineItem(
|
|
6418
|
+
resource,
|
|
6419
|
+
this.elementSubject.getValue(),
|
|
6420
|
+
this.context,
|
|
6421
|
+
this.settings,
|
|
6422
|
+
this.hookManager,
|
|
7205
6423
|
index
|
|
7206
|
-
|
|
6424
|
+
)
|
|
7207
6425
|
);
|
|
7208
6426
|
this.spineItemsManager.addMany(spineItems);
|
|
7209
6427
|
})
|
|
@@ -7581,492 +6799,1403 @@ const createResourcesManager = (context) => {
|
|
|
7581
6799
|
if (cacheData) {
|
|
7582
6800
|
return new Response(cacheData, { status: 200 });
|
|
7583
6801
|
}
|
|
7584
|
-
const data = fetchResource && await fetchResource(item) || await fetch(item.href);
|
|
7585
|
-
cache(item, data.clone());
|
|
7586
|
-
return data;
|
|
7587
|
-
};
|
|
7588
|
-
const cache = (itemIndexOrId, data) => {
|
|
7589
|
-
cache$.next({ id: itemIndexOrId, data });
|
|
6802
|
+
const data = fetchResource && await fetchResource(item) || await fetch(item.href);
|
|
6803
|
+
cache(item, data.clone());
|
|
6804
|
+
return data;
|
|
6805
|
+
};
|
|
6806
|
+
const cache = (itemIndexOrId, data) => {
|
|
6807
|
+
cache$.next({ id: itemIndexOrId, data });
|
|
6808
|
+
};
|
|
6809
|
+
cache$.asObservable().pipe(
|
|
6810
|
+
mergeMap$1(({ id, data }) => {
|
|
6811
|
+
const item = retrieveItem(id);
|
|
6812
|
+
if (!item) return EMPTY;
|
|
6813
|
+
return from(
|
|
6814
|
+
forkJoin([openDatabase(`prose-reader`), from(data.blob())])
|
|
6815
|
+
).pipe(
|
|
6816
|
+
switchMap$1(([db, blob]) => {
|
|
6817
|
+
return from(db.put(`${uniqueID}_${item.id}`, blob));
|
|
6818
|
+
}),
|
|
6819
|
+
catchError((error) => {
|
|
6820
|
+
Report.error(error);
|
|
6821
|
+
return EMPTY;
|
|
6822
|
+
})
|
|
6823
|
+
);
|
|
6824
|
+
}),
|
|
6825
|
+
takeUntil$1(context.destroy$)
|
|
6826
|
+
).subscribe();
|
|
6827
|
+
const onLoad$ = context.manifest$.pipe(
|
|
6828
|
+
tap(() => {
|
|
6829
|
+
uniqueID = Date.now().toString();
|
|
6830
|
+
})
|
|
6831
|
+
);
|
|
6832
|
+
merge(onLoad$).pipe(
|
|
6833
|
+
switchMap$1(() => {
|
|
6834
|
+
Report.log(`Cleanup up old cache...`);
|
|
6835
|
+
return from(openDatabase(`prose-reader`)).pipe(
|
|
6836
|
+
switchMap$1(
|
|
6837
|
+
(db) => from(db.keys()).pipe(
|
|
6838
|
+
map(
|
|
6839
|
+
(keys) => keys.filter((key) => !key.toString().startsWith(uniqueID))
|
|
6840
|
+
),
|
|
6841
|
+
switchMap$1((keysToRemove) => {
|
|
6842
|
+
const promises = keysToRemove.map((key) => db.remove(key));
|
|
6843
|
+
return from(Promise.all(promises));
|
|
6844
|
+
})
|
|
6845
|
+
)
|
|
6846
|
+
),
|
|
6847
|
+
catchError((error) => {
|
|
6848
|
+
Report.error(error);
|
|
6849
|
+
return EMPTY;
|
|
6850
|
+
})
|
|
6851
|
+
);
|
|
6852
|
+
}),
|
|
6853
|
+
takeUntil$1(context.destroy$)
|
|
6854
|
+
).subscribe();
|
|
6855
|
+
const destroy = () => {
|
|
6856
|
+
cache$.complete();
|
|
6857
|
+
};
|
|
6858
|
+
return {
|
|
6859
|
+
get,
|
|
6860
|
+
destroy
|
|
6861
|
+
};
|
|
6862
|
+
};
|
|
6863
|
+
const resourcesEnhancer = (next) => (options) => {
|
|
6864
|
+
const reader = next(options);
|
|
6865
|
+
const resourceManager = createResourcesManager(reader.context);
|
|
6866
|
+
const destroy = () => {
|
|
6867
|
+
resourceManager.destroy();
|
|
6868
|
+
reader.destroy();
|
|
6869
|
+
};
|
|
6870
|
+
return {
|
|
6871
|
+
...reader,
|
|
6872
|
+
// $: {
|
|
6873
|
+
// ...reader.$,
|
|
6874
|
+
// errors$: merge(reader.$.errors$, errorsSubject$.asObservable())
|
|
6875
|
+
// },
|
|
6876
|
+
destroy
|
|
6877
|
+
// load,
|
|
6878
|
+
};
|
|
6879
|
+
};
|
|
6880
|
+
class ImageRenderer extends DocumentRenderer {
|
|
6881
|
+
getImageElement() {
|
|
6882
|
+
var _a;
|
|
6883
|
+
const element = (_a = this.layers[0]) == null ? void 0 : _a.element;
|
|
6884
|
+
if (!(element instanceof HTMLImageElement)) return void 0;
|
|
6885
|
+
return element;
|
|
6886
|
+
}
|
|
6887
|
+
onCreateDocument() {
|
|
6888
|
+
return from(this.resourcesHandler.getResource()).pipe(
|
|
6889
|
+
switchMap((responseOrUrl) => {
|
|
6890
|
+
const imgElement = this.containerElement.ownerDocument.createElement(`img`);
|
|
6891
|
+
this.layers = [{ element: imgElement }];
|
|
6892
|
+
imgElement.style.objectFit = `contain`;
|
|
6893
|
+
imgElement.style.userSelect = `none`;
|
|
6894
|
+
if (responseOrUrl instanceof URL) {
|
|
6895
|
+
return of(responseOrUrl.href);
|
|
6896
|
+
} else if (responseOrUrl instanceof Response) {
|
|
6897
|
+
return from(responseOrUrl.blob()).pipe(
|
|
6898
|
+
map$1((blob) => {
|
|
6899
|
+
return URL.createObjectURL(blob);
|
|
6900
|
+
})
|
|
6901
|
+
);
|
|
6902
|
+
}
|
|
6903
|
+
throw new Error(`Invalid resource`);
|
|
6904
|
+
}),
|
|
6905
|
+
tap$1((src) => {
|
|
6906
|
+
const element = this.getImageElement();
|
|
6907
|
+
if (element) {
|
|
6908
|
+
element.src = src;
|
|
6909
|
+
}
|
|
6910
|
+
})
|
|
6911
|
+
);
|
|
6912
|
+
}
|
|
6913
|
+
onLoadDocument() {
|
|
6914
|
+
const imageElement = this.getImageElement();
|
|
6915
|
+
if (!imageElement) throw new Error(`invalid element`);
|
|
6916
|
+
this.containerElement.appendChild(imageElement);
|
|
6917
|
+
return fromEvent(imageElement, `load`);
|
|
6918
|
+
}
|
|
6919
|
+
onUnload() {
|
|
6920
|
+
const imageElement = this.getImageElement();
|
|
6921
|
+
if (imageElement) {
|
|
6922
|
+
URL.revokeObjectURL(imageElement.src);
|
|
6923
|
+
}
|
|
6924
|
+
this.layers.forEach(({ element }) => {
|
|
6925
|
+
element.remove();
|
|
6926
|
+
});
|
|
6927
|
+
this.layers = [];
|
|
6928
|
+
return EMPTY;
|
|
6929
|
+
}
|
|
6930
|
+
layout({
|
|
6931
|
+
spreadPosition
|
|
6932
|
+
}) {
|
|
6933
|
+
var _a, _b;
|
|
6934
|
+
const element = this.getImageElement();
|
|
6935
|
+
const continuousScrollableReflowableItem = ((_a = this.context.manifest) == null ? void 0 : _a.renditionLayout) === "reflowable" && ((_b = this.context.manifest) == null ? void 0 : _b.renditionFlow) === "scrolled-continuous";
|
|
6936
|
+
const { height: pageHeight, width: pageWidth } = this.context.getPageSize();
|
|
6937
|
+
let height = pageHeight;
|
|
6938
|
+
const width = pageWidth;
|
|
6939
|
+
if (element) {
|
|
6940
|
+
const naturalWidth = element.naturalWidth;
|
|
6941
|
+
const naturalHeight = element.naturalHeight;
|
|
6942
|
+
const ratio = naturalWidth / naturalHeight;
|
|
6943
|
+
if (continuousScrollableReflowableItem) {
|
|
6944
|
+
height = pageWidth / ratio;
|
|
6945
|
+
}
|
|
6946
|
+
element.style.height = `${height}px`;
|
|
6947
|
+
element.style.width = `${width}px`;
|
|
6948
|
+
element.style.objectPosition = spreadPosition === "left" ? `right` : spreadPosition === `right` ? `left` : `center`;
|
|
6949
|
+
}
|
|
6950
|
+
return {
|
|
6951
|
+
width,
|
|
6952
|
+
height
|
|
6953
|
+
};
|
|
6954
|
+
}
|
|
6955
|
+
}
|
|
6956
|
+
const mediaEnhancer = (next) => (options) => {
|
|
6957
|
+
const reader = next({
|
|
6958
|
+
...options,
|
|
6959
|
+
getRenderer(item) {
|
|
6960
|
+
var _a;
|
|
6961
|
+
const MaybeRenderer = (_a = options.getRenderer) == null ? void 0 : _a.call(options, item);
|
|
6962
|
+
const mimeType = item.mediaType ?? detectMimeTypeFromName(item.href);
|
|
6963
|
+
const isImageType = !!(mimeType == null ? void 0 : mimeType.startsWith(`image/`));
|
|
6964
|
+
if (!MaybeRenderer && isImageType) {
|
|
6965
|
+
return ImageRenderer;
|
|
6966
|
+
}
|
|
6967
|
+
return MaybeRenderer;
|
|
6968
|
+
}
|
|
6969
|
+
});
|
|
6970
|
+
const frameObserver = new IntersectionObserver(
|
|
6971
|
+
(entries) => {
|
|
6972
|
+
entries.forEach((entry) => {
|
|
6973
|
+
var _a;
|
|
6974
|
+
const frame = entry.target;
|
|
6975
|
+
const audios = Array.from(
|
|
6976
|
+
((_a = frame.contentDocument) == null ? void 0 : _a.body.getElementsByTagName(`audio`)) || []
|
|
6977
|
+
);
|
|
6978
|
+
if (!entry.isIntersecting) {
|
|
6979
|
+
audios.forEach((audioElement) => {
|
|
6980
|
+
audioElement.pause();
|
|
6981
|
+
audioElement.currentTime = 0;
|
|
6982
|
+
});
|
|
6983
|
+
} else {
|
|
6984
|
+
audios.forEach((audioElement) => {
|
|
6985
|
+
if (audioElement.hasAttribute(`autoplay`) && audioElement.paused && audioElement.readyState >= 2) {
|
|
6986
|
+
audioElement.play().catch(console.error);
|
|
6987
|
+
}
|
|
6988
|
+
});
|
|
6989
|
+
}
|
|
6990
|
+
});
|
|
6991
|
+
},
|
|
6992
|
+
{
|
|
6993
|
+
threshold: 0.01
|
|
6994
|
+
}
|
|
6995
|
+
);
|
|
6996
|
+
const elementObserver = new IntersectionObserver(
|
|
6997
|
+
(entries) => {
|
|
6998
|
+
entries.forEach((entry) => {
|
|
6999
|
+
if (entry.target.tagName === `video`) {
|
|
7000
|
+
const video = entry.target;
|
|
7001
|
+
if (!entry.isIntersecting) {
|
|
7002
|
+
video.pause();
|
|
7003
|
+
video.currentTime = 0;
|
|
7004
|
+
} else {
|
|
7005
|
+
if (video.hasAttribute(`autoplay`)) {
|
|
7006
|
+
if (video.paused && video.readyState >= 2) {
|
|
7007
|
+
video.play().catch(console.error);
|
|
7008
|
+
}
|
|
7009
|
+
}
|
|
7010
|
+
}
|
|
7011
|
+
}
|
|
7012
|
+
});
|
|
7013
|
+
},
|
|
7014
|
+
{
|
|
7015
|
+
threshold: 0.5
|
|
7016
|
+
}
|
|
7017
|
+
);
|
|
7018
|
+
reader.hookManager.register(
|
|
7019
|
+
`item.onDocumentLoad`,
|
|
7020
|
+
({ layers, destroy: destroy2 }) => {
|
|
7021
|
+
var _a, _b;
|
|
7022
|
+
const frame = (_a = layers[0]) == null ? void 0 : _a.element;
|
|
7023
|
+
if (!(frame instanceof HTMLIFrameElement)) return;
|
|
7024
|
+
frameObserver.observe(frame);
|
|
7025
|
+
const videos = (_b = frame.contentDocument) == null ? void 0 : _b.body.getElementsByTagName(`video`);
|
|
7026
|
+
const unobserveElements = Array.from(videos || []).map((element) => {
|
|
7027
|
+
elementObserver.observe(element);
|
|
7028
|
+
return () => elementObserver.unobserve(element);
|
|
7029
|
+
});
|
|
7030
|
+
destroy2(() => {
|
|
7031
|
+
frameObserver.unobserve(frame);
|
|
7032
|
+
unobserveElements.forEach((unobserve) => unobserve());
|
|
7033
|
+
});
|
|
7034
|
+
}
|
|
7035
|
+
);
|
|
7036
|
+
const destroy = () => {
|
|
7037
|
+
frameObserver.disconnect();
|
|
7038
|
+
elementObserver.disconnect();
|
|
7039
|
+
reader.destroy();
|
|
7040
|
+
};
|
|
7041
|
+
return {
|
|
7042
|
+
...reader,
|
|
7043
|
+
destroy
|
|
7044
|
+
};
|
|
7045
|
+
};
|
|
7046
|
+
const progressionEnhancer = (next) => (options) => {
|
|
7047
|
+
const reader = next(options);
|
|
7048
|
+
const getPercentageEstimate = (context, currentSpineIndex, numberOfPages, pageIndex, currentPosition, currentItem) => {
|
|
7049
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7050
|
+
const isGloballyPrePaginated = ((_a = context.manifest) == null ? void 0 : _a.renditionLayout) === `pre-paginated`;
|
|
7051
|
+
const readingOrderLength = ((_b = context.manifest) == null ? void 0 : _b.spineItems.length) || 0;
|
|
7052
|
+
const estimateBeforeThisItem = ((_c = context.manifest) == null ? void 0 : _c.spineItems.slice(0, currentSpineIndex).reduce((acc, item) => acc + (item.progressionWeight ?? 0), 0)) || 0;
|
|
7053
|
+
const currentItemWeight = ((_e = (_d = context.manifest) == null ? void 0 : _d.spineItems[currentSpineIndex]) == null ? void 0 : _e.progressionWeight) || 0;
|
|
7054
|
+
let progressWithinThisItem = (pageIndex + 1) * (currentItemWeight / numberOfPages);
|
|
7055
|
+
if (!isGloballyPrePaginated && currentItem.item.renditionLayout === `reflowable` && !currentItem.isReady) {
|
|
7056
|
+
progressWithinThisItem = 0;
|
|
7057
|
+
}
|
|
7058
|
+
let totalProgress = estimateBeforeThisItem + progressWithinThisItem;
|
|
7059
|
+
if (((_f = context.manifest) == null ? void 0 : _f.renditionFlow) === `scrolled-continuous`) {
|
|
7060
|
+
if (currentItem.isReady) {
|
|
7061
|
+
progressWithinThisItem = getScrollPercentageWithinItem(
|
|
7062
|
+
context,
|
|
7063
|
+
currentPosition,
|
|
7064
|
+
currentItem
|
|
7065
|
+
);
|
|
7066
|
+
} else {
|
|
7067
|
+
progressWithinThisItem = 0;
|
|
7068
|
+
}
|
|
7069
|
+
totalProgress = getTotalProgressFromPercentages(
|
|
7070
|
+
estimateBeforeThisItem,
|
|
7071
|
+
currentItemWeight,
|
|
7072
|
+
progressWithinThisItem
|
|
7073
|
+
);
|
|
7074
|
+
}
|
|
7075
|
+
if (currentSpineIndex === readingOrderLength - 1 && pageIndex === numberOfPages - 1 && totalProgress > 0.99) {
|
|
7076
|
+
return 1;
|
|
7077
|
+
}
|
|
7078
|
+
return totalProgress;
|
|
7079
|
+
};
|
|
7080
|
+
const getTotalProgressFromPercentages = (estimateBeforeThisItem, currentItemWeight, progressWithinThisItem) => {
|
|
7081
|
+
return estimateBeforeThisItem + currentItemWeight * progressWithinThisItem;
|
|
7082
|
+
};
|
|
7083
|
+
const getScrollPercentageWithinItem = (context, currentPosition, currentItem) => {
|
|
7084
|
+
const { height, width } = currentItem.getElementDimensions();
|
|
7085
|
+
const { top, left } = reader.spine.spineLayout.getAbsolutePositionOf(currentItem);
|
|
7086
|
+
if (reader.settings.values.computedPageTurnDirection === `vertical`) {
|
|
7087
|
+
return Math.max(
|
|
7088
|
+
0,
|
|
7089
|
+
Math.min(
|
|
7090
|
+
1,
|
|
7091
|
+
(currentPosition.y - top + context.state.visibleAreaRect.height) / height
|
|
7092
|
+
)
|
|
7093
|
+
);
|
|
7094
|
+
} else {
|
|
7095
|
+
return Math.max(
|
|
7096
|
+
0,
|
|
7097
|
+
Math.min(
|
|
7098
|
+
1,
|
|
7099
|
+
(currentPosition.x - left + context.state.visibleAreaRect.width) / width
|
|
7100
|
+
)
|
|
7101
|
+
);
|
|
7102
|
+
}
|
|
7103
|
+
};
|
|
7104
|
+
return {
|
|
7105
|
+
...reader,
|
|
7106
|
+
progression: {
|
|
7107
|
+
getPercentageEstimate,
|
|
7108
|
+
getScrollPercentageWithinItem
|
|
7109
|
+
}
|
|
7110
|
+
};
|
|
7111
|
+
};
|
|
7112
|
+
const accessibilityEnhancer = (next) => (options) => {
|
|
7113
|
+
const reader = next(options);
|
|
7114
|
+
const observer = new IntersectionObserver((entries) => {
|
|
7115
|
+
entries.forEach((entry) => {
|
|
7116
|
+
if (entry.isIntersecting) {
|
|
7117
|
+
entry.target.removeAttribute(`tab-index`);
|
|
7118
|
+
} else {
|
|
7119
|
+
entry.target.setAttribute(`tab-index`, `-1`);
|
|
7120
|
+
}
|
|
7121
|
+
});
|
|
7122
|
+
}, {});
|
|
7123
|
+
reader.hookManager.register(
|
|
7124
|
+
`item.onDocumentLoad`,
|
|
7125
|
+
({ itemId, layers, destroy }) => {
|
|
7126
|
+
var _a, _b;
|
|
7127
|
+
const frame = (_a = layers[0]) == null ? void 0 : _a.element;
|
|
7128
|
+
if (!(frame instanceof HTMLIFrameElement)) return;
|
|
7129
|
+
const item = reader.spineItemsManager.get(itemId);
|
|
7130
|
+
if (!item) return;
|
|
7131
|
+
item.upsertCSS(
|
|
7132
|
+
`prose-reader-accessibility`,
|
|
7133
|
+
`
|
|
7134
|
+
:focus-visible {
|
|
7135
|
+
${/*
|
|
7136
|
+
Some epubs remove the outline, this is not good practice since it reduce accessibility.
|
|
7137
|
+
We will try to restore it by force.
|
|
7138
|
+
*/
|
|
7139
|
+
``}
|
|
7140
|
+
outline: -webkit-focus-ring-color auto 1px;
|
|
7141
|
+
}
|
|
7142
|
+
`
|
|
7143
|
+
);
|
|
7144
|
+
const links = (_b = frame.contentDocument) == null ? void 0 : _b.body.querySelectorAll(`a`);
|
|
7145
|
+
links == null ? void 0 : links.forEach((link) => {
|
|
7146
|
+
observer.observe(link);
|
|
7147
|
+
});
|
|
7148
|
+
destroy(() => {
|
|
7149
|
+
links == null ? void 0 : links.forEach((link) => {
|
|
7150
|
+
observer.unobserve(link);
|
|
7151
|
+
});
|
|
7152
|
+
});
|
|
7153
|
+
}
|
|
7154
|
+
);
|
|
7155
|
+
return {
|
|
7156
|
+
...reader
|
|
7590
7157
|
};
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7158
|
+
};
|
|
7159
|
+
navigator.userAgent.indexOf(``) > -1 && navigator.userAgent.indexOf(`Chrome`) <= -1;
|
|
7160
|
+
const webkitEnhancer = (createReader2) => (options) => {
|
|
7161
|
+
const reader = createReader2(options);
|
|
7162
|
+
return reader;
|
|
7163
|
+
};
|
|
7164
|
+
const HTML_PREFIX = `${HTML_PREFIX$1}-enhancer-loading`;
|
|
7165
|
+
const CONTAINER_HTML_PREFIX = `${HTML_PREFIX}-container`;
|
|
7166
|
+
const createLoadingElementContainer = (containerElement, context) => {
|
|
7167
|
+
const loadingElement = containerElement.ownerDocument.createElement(`div`);
|
|
7168
|
+
loadingElement.classList.add(CONTAINER_HTML_PREFIX);
|
|
7169
|
+
loadingElement.style.cssText = `
|
|
7170
|
+
height: 100%;
|
|
7171
|
+
width: 100%;
|
|
7172
|
+
max-width: ${context.state.visibleAreaRect.width}px;
|
|
7173
|
+
text-align: center;
|
|
7174
|
+
display: flex;
|
|
7175
|
+
justify-content: center;
|
|
7176
|
+
align-items: center;
|
|
7177
|
+
flex-direction: column;
|
|
7178
|
+
position: absolute;
|
|
7179
|
+
left: 0;
|
|
7180
|
+
top: 0;
|
|
7181
|
+
color: rgb(202, 202, 202);
|
|
7182
|
+
background-color: white;
|
|
7183
|
+
`;
|
|
7184
|
+
return loadingElement;
|
|
7185
|
+
};
|
|
7186
|
+
const defaultLoadingElementCreate = ({
|
|
7187
|
+
container,
|
|
7188
|
+
item
|
|
7189
|
+
}) => {
|
|
7190
|
+
const logoElement = container.ownerDocument.createElement(`div`);
|
|
7191
|
+
logoElement.innerText = `prose`;
|
|
7192
|
+
logoElement.style.cssText = `
|
|
7193
|
+
font-size: 4em;
|
|
7194
|
+
`;
|
|
7195
|
+
const detailsElement = container.ownerDocument.createElement(`div`);
|
|
7196
|
+
detailsElement.innerText = `loading ${item.id}`;
|
|
7197
|
+
detailsElement.style.cssText = `
|
|
7198
|
+
font-size: 1.2em;
|
|
7199
|
+
text-overflow: ellipsis;
|
|
7200
|
+
white-space: nowrap;
|
|
7201
|
+
overflow: hidden;
|
|
7202
|
+
max-width: 300px;
|
|
7203
|
+
width: 80%;
|
|
7204
|
+
`;
|
|
7205
|
+
container.appendChild(logoElement);
|
|
7206
|
+
container.appendChild(detailsElement);
|
|
7207
|
+
return container;
|
|
7208
|
+
};
|
|
7209
|
+
const loadingEnhancer = (next) => (options) => {
|
|
7210
|
+
const { loadingElementCreate = defaultLoadingElementCreate } = options;
|
|
7211
|
+
const reader = next(options);
|
|
7212
|
+
const createEntries$ = (items) => of(
|
|
7213
|
+
items.reduce((acc, { item, element }) => {
|
|
7214
|
+
const alreadyExistingElement = element.querySelector(
|
|
7215
|
+
`.${CONTAINER_HTML_PREFIX}`
|
|
7605
7216
|
);
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7217
|
+
if (alreadyExistingElement instanceof HTMLElement)
|
|
7218
|
+
return {
|
|
7219
|
+
...acc,
|
|
7220
|
+
[item.id]: alreadyExistingElement
|
|
7221
|
+
};
|
|
7222
|
+
const loadingElementContainer = loadingElementCreate({
|
|
7223
|
+
container: createLoadingElementContainer(element, reader.context),
|
|
7224
|
+
item
|
|
7225
|
+
});
|
|
7226
|
+
element.appendChild(loadingElementContainer);
|
|
7227
|
+
return {
|
|
7228
|
+
...acc,
|
|
7229
|
+
[item.id]: loadingElementContainer
|
|
7230
|
+
};
|
|
7231
|
+
}, {})
|
|
7232
|
+
);
|
|
7233
|
+
const updateEntriesLayout$ = (entries) => combineLatest([reader.layout$, reader.theme.$.theme$]).pipe(
|
|
7234
|
+
map(([, theme]) => ({
|
|
7235
|
+
width: reader.context.state.visibleAreaRect.width,
|
|
7236
|
+
theme
|
|
7237
|
+
})),
|
|
7238
|
+
distinctUntilChanged(isShallowEqual),
|
|
7239
|
+
tap(({ width, theme }) => {
|
|
7240
|
+
Object.values(entries).forEach((element) => {
|
|
7241
|
+
element.style.setProperty(`max-width`, `${width}px`);
|
|
7242
|
+
element.style.setProperty(
|
|
7243
|
+
`color`,
|
|
7244
|
+
theme === `sepia` ? `#939393` : `rgb(202, 202, 202)`
|
|
7245
|
+
);
|
|
7246
|
+
});
|
|
7612
7247
|
})
|
|
7613
7248
|
);
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
map(
|
|
7621
|
-
(keys) => keys.filter((key) => !key.toString().startsWith(uniqueID))
|
|
7622
|
-
),
|
|
7623
|
-
switchMap$1((keysToRemove) => {
|
|
7624
|
-
const promises = keysToRemove.map((key) => db.remove(key));
|
|
7625
|
-
return from(Promise.all(promises));
|
|
7626
|
-
})
|
|
7627
|
-
)
|
|
7628
|
-
),
|
|
7629
|
-
catchError$1((error) => {
|
|
7630
|
-
Report.error(error);
|
|
7631
|
-
return EMPTY;
|
|
7632
|
-
})
|
|
7249
|
+
const updateEntriesVisibility$ = (entries) => reader.spineItemsObserver.itemIsReady$.pipe(
|
|
7250
|
+
tap(({ item, isReady }) => {
|
|
7251
|
+
var _a;
|
|
7252
|
+
(_a = entries[item.item.id]) == null ? void 0 : _a.style.setProperty(
|
|
7253
|
+
`visibility`,
|
|
7254
|
+
isReady ? `hidden` : `visible`
|
|
7633
7255
|
);
|
|
7634
|
-
})
|
|
7635
|
-
|
|
7256
|
+
})
|
|
7257
|
+
);
|
|
7258
|
+
const loadingItems$ = reader.spineItemsManager.items$.pipe(
|
|
7259
|
+
switchMap$1((items) => createEntries$(items)),
|
|
7260
|
+
shareReplay(1),
|
|
7261
|
+
takeUntil$1(reader.context.destroy$)
|
|
7262
|
+
);
|
|
7263
|
+
loadingItems$.pipe(
|
|
7264
|
+
switchMap$1(
|
|
7265
|
+
(entries) => merge(
|
|
7266
|
+
updateEntriesLayout$(entries),
|
|
7267
|
+
updateEntriesVisibility$(entries)
|
|
7268
|
+
)
|
|
7269
|
+
),
|
|
7270
|
+
takeUntil$1(reader.$.destroy$)
|
|
7636
7271
|
).subscribe();
|
|
7637
|
-
const destroy = () => {
|
|
7638
|
-
cache$.complete();
|
|
7639
|
-
};
|
|
7640
7272
|
return {
|
|
7641
|
-
|
|
7642
|
-
|
|
7273
|
+
...reader,
|
|
7274
|
+
loading: {
|
|
7275
|
+
$: {
|
|
7276
|
+
items$: loadingItems$
|
|
7277
|
+
}
|
|
7278
|
+
}
|
|
7643
7279
|
};
|
|
7644
7280
|
};
|
|
7645
|
-
const
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7281
|
+
const translateFramePositionIntoPage = ({
|
|
7282
|
+
position,
|
|
7283
|
+
frameElement,
|
|
7284
|
+
pageWidth,
|
|
7285
|
+
pageHeight
|
|
7286
|
+
}) => {
|
|
7287
|
+
const {
|
|
7288
|
+
height: viewportHeight = pageHeight,
|
|
7289
|
+
width: viewportWidth = pageWidth
|
|
7290
|
+
} = getFrameViewportInfo(frameElement);
|
|
7291
|
+
const computedWidthScale = pageWidth / viewportWidth;
|
|
7292
|
+
const computedScale = Math.min(
|
|
7293
|
+
computedWidthScale,
|
|
7294
|
+
pageHeight / viewportHeight
|
|
7295
|
+
);
|
|
7296
|
+
const { left = 0, top = 0 } = (frameElement == null ? void 0 : frameElement.getBoundingClientRect()) || {};
|
|
7297
|
+
const adjustedX = position.clientX * computedScale + left;
|
|
7298
|
+
const adjustedY = position.clientY * computedScale + top;
|
|
7652
7299
|
return {
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
// ...reader.$,
|
|
7656
|
-
// errors$: merge(reader.$.errors$, errorsSubject$.asObservable())
|
|
7657
|
-
// },
|
|
7658
|
-
destroy
|
|
7659
|
-
// load,
|
|
7300
|
+
clientX: adjustedX,
|
|
7301
|
+
clientY: adjustedY
|
|
7660
7302
|
};
|
|
7661
7303
|
};
|
|
7662
|
-
const
|
|
7304
|
+
const normalizeEventForViewport = (event, iframeOriginalEvent, locator, context) => {
|
|
7305
|
+
var _a, _b;
|
|
7306
|
+
const originalFrame = (_a = iframeOriginalEvent == null ? void 0 : iframeOriginalEvent.view) == null ? void 0 : _a.frameElement;
|
|
7307
|
+
if (!iframeOriginalEvent || !originalFrame) return event;
|
|
7308
|
+
const spineItem = locator.getSpineItemFromIframe(originalFrame);
|
|
7309
|
+
const frameElement = (_b = spineItem == null ? void 0 : spineItem.renderer.layers[0]) == null ? void 0 : _b.element;
|
|
7310
|
+
const { height: pageHeight, width: pageWidth } = context.getPageSize();
|
|
7311
|
+
if (!spineItem || !(frameElement instanceof HTMLIFrameElement)) return event;
|
|
7312
|
+
if (isPointerEvent(event)) {
|
|
7313
|
+
const { clientX, clientY } = translateFramePositionIntoPage({
|
|
7314
|
+
position: event,
|
|
7315
|
+
frameElement,
|
|
7316
|
+
pageHeight,
|
|
7317
|
+
pageWidth
|
|
7318
|
+
});
|
|
7319
|
+
const newEvent = new PointerEvent(event.type, {
|
|
7320
|
+
...event,
|
|
7321
|
+
pointerId: event.pointerId,
|
|
7322
|
+
clientX,
|
|
7323
|
+
clientY
|
|
7324
|
+
});
|
|
7325
|
+
Object.defineProperty(newEvent, `target`, {
|
|
7326
|
+
value: iframeOriginalEvent.target,
|
|
7327
|
+
enumerable: true
|
|
7328
|
+
});
|
|
7329
|
+
return newEvent;
|
|
7330
|
+
}
|
|
7331
|
+
if (isMouseEvent(event)) {
|
|
7332
|
+
const { clientX, clientY } = translateFramePositionIntoPage({
|
|
7333
|
+
position: event,
|
|
7334
|
+
frameElement,
|
|
7335
|
+
pageHeight,
|
|
7336
|
+
pageWidth
|
|
7337
|
+
});
|
|
7338
|
+
const newEvent = new MouseEvent(event.type, {
|
|
7339
|
+
...event,
|
|
7340
|
+
clientX,
|
|
7341
|
+
clientY
|
|
7342
|
+
});
|
|
7343
|
+
Object.defineProperty(newEvent, `target`, {
|
|
7344
|
+
value: iframeOriginalEvent.target,
|
|
7345
|
+
enumerable: true
|
|
7346
|
+
});
|
|
7347
|
+
return newEvent;
|
|
7348
|
+
}
|
|
7349
|
+
if (isTouchEvent(event)) {
|
|
7350
|
+
const touches = Array.from(event.touches).map((touch) => {
|
|
7351
|
+
const { clientX, clientY } = translateFramePositionIntoPage({
|
|
7352
|
+
position: touch,
|
|
7353
|
+
frameElement,
|
|
7354
|
+
pageHeight,
|
|
7355
|
+
pageWidth
|
|
7356
|
+
});
|
|
7357
|
+
return new Touch({
|
|
7358
|
+
identifier: touch.identifier,
|
|
7359
|
+
target: touch.target,
|
|
7360
|
+
clientX,
|
|
7361
|
+
clientY
|
|
7362
|
+
});
|
|
7363
|
+
});
|
|
7364
|
+
const newEvent = new TouchEvent(event.type, {
|
|
7365
|
+
touches,
|
|
7366
|
+
changedTouches: touches,
|
|
7367
|
+
targetTouches: touches
|
|
7368
|
+
});
|
|
7369
|
+
Object.defineProperty(newEvent, `target`, {
|
|
7370
|
+
value: iframeOriginalEvent.target,
|
|
7371
|
+
enumerable: true
|
|
7372
|
+
});
|
|
7373
|
+
return newEvent;
|
|
7374
|
+
}
|
|
7375
|
+
return event;
|
|
7376
|
+
};
|
|
7377
|
+
const pointerEvents = [
|
|
7378
|
+
`pointercancel`,
|
|
7379
|
+
`pointerdown`,
|
|
7380
|
+
`pointerenter`,
|
|
7381
|
+
`pointerleave`,
|
|
7382
|
+
`pointermove`,
|
|
7383
|
+
`pointerout`,
|
|
7384
|
+
`pointerover`,
|
|
7385
|
+
`pointerup`
|
|
7386
|
+
];
|
|
7387
|
+
const passthroughEvents = [
|
|
7388
|
+
...pointerEvents
|
|
7389
|
+
/*, ...mouseEvents*/
|
|
7390
|
+
];
|
|
7391
|
+
const eventsEnhancer = (next) => (options) => {
|
|
7663
7392
|
const reader = next(options);
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
7667
|
-
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7393
|
+
reader.hookManager.register(
|
|
7394
|
+
`item.onDocumentLoad`,
|
|
7395
|
+
({ destroy, layers, itemId }) => {
|
|
7396
|
+
var _a;
|
|
7397
|
+
const frame = (_a = layers[0]) == null ? void 0 : _a.element;
|
|
7398
|
+
if (!(frame instanceof HTMLIFrameElement)) return;
|
|
7399
|
+
const item = reader.spineItemsManager.get(itemId);
|
|
7400
|
+
if (!item) return;
|
|
7401
|
+
const unregister = passthroughEvents.map((event) => {
|
|
7402
|
+
var _a2;
|
|
7403
|
+
const listener = (e) => {
|
|
7404
|
+
var _a3;
|
|
7405
|
+
let convertedEvent = e;
|
|
7406
|
+
if (isPointerEvent(e)) {
|
|
7407
|
+
convertedEvent = new PointerEvent(e.type, e);
|
|
7408
|
+
}
|
|
7409
|
+
if (convertedEvent !== e) {
|
|
7410
|
+
const normalizedEvent = normalizeEventForViewport(
|
|
7411
|
+
convertedEvent,
|
|
7412
|
+
e,
|
|
7413
|
+
reader.spine.locator,
|
|
7414
|
+
reader.context
|
|
7415
|
+
);
|
|
7416
|
+
(_a3 = reader.context.state.containerElement) == null ? void 0 : _a3.dispatchEvent(
|
|
7417
|
+
normalizedEvent
|
|
7418
|
+
);
|
|
7419
|
+
}
|
|
7420
|
+
};
|
|
7421
|
+
(_a2 = frame.contentDocument) == null ? void 0 : _a2.addEventListener(event, listener);
|
|
7422
|
+
return () => {
|
|
7423
|
+
var _a3;
|
|
7424
|
+
(_a3 = frame.contentDocument) == null ? void 0 : _a3.removeEventListener(event, listener);
|
|
7425
|
+
};
|
|
7426
|
+
});
|
|
7427
|
+
item.selectionTracker.track(frame);
|
|
7428
|
+
item.fingerTracker.track(frame);
|
|
7429
|
+
destroy(() => {
|
|
7430
|
+
unregister.forEach((cb) => cb());
|
|
7684
7431
|
});
|
|
7685
|
-
},
|
|
7686
|
-
{
|
|
7687
|
-
threshold: 0.01
|
|
7688
7432
|
}
|
|
7689
7433
|
);
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7434
|
+
return reader;
|
|
7435
|
+
};
|
|
7436
|
+
const createFrameElement = Report.measurePerformance(
|
|
7437
|
+
`SpineItemFrame createFrame`,
|
|
7438
|
+
Infinity,
|
|
7439
|
+
() => {
|
|
7440
|
+
const frame = document.createElement(`iframe`);
|
|
7441
|
+
frame.frameBorder = `no`;
|
|
7442
|
+
frame.tabIndex = 0;
|
|
7443
|
+
frame.setAttribute(
|
|
7444
|
+
`sandbox`,
|
|
7445
|
+
`
|
|
7446
|
+
allow-same-origin
|
|
7447
|
+
allow-scripts
|
|
7448
|
+
allow-top-navigation-to-custom-protocols
|
|
7449
|
+
`
|
|
7450
|
+
);
|
|
7451
|
+
frame.style.cssText = `
|
|
7452
|
+
overflow: hidden;
|
|
7453
|
+
background-color: transparent;
|
|
7454
|
+
border: 0px none transparent;
|
|
7455
|
+
padding: 0px;
|
|
7456
|
+
`;
|
|
7457
|
+
frame.setAttribute(`role`, `main`);
|
|
7458
|
+
return frame;
|
|
7459
|
+
}
|
|
7460
|
+
);
|
|
7461
|
+
const getIntrinsicDimensionsFromBase64Img = (data) => new Promise((resolve, reject) => {
|
|
7462
|
+
const image = new Image();
|
|
7463
|
+
image.src = data;
|
|
7464
|
+
image.onload = () => {
|
|
7465
|
+
resolve({ height: image.naturalHeight, width: image.naturalWidth });
|
|
7466
|
+
};
|
|
7467
|
+
image.onerror = reject;
|
|
7468
|
+
});
|
|
7469
|
+
const createHtmlPageFromResource = async (resourceResponse, item) => {
|
|
7470
|
+
if (typeof resourceResponse === `string`) return resourceResponse;
|
|
7471
|
+
const contentType = parseContentType(resourceResponse.headers.get(`Content-Type`) || ``) || detectMimeTypeFromName(item.href);
|
|
7472
|
+
if ([`image/jpg`, `image/jpeg`, `image/png`, `image/webp`].some(
|
|
7473
|
+
(mime) => mime === contentType
|
|
7474
|
+
)) {
|
|
7475
|
+
const data = await getBase64FromBlob(await resourceResponse.blob());
|
|
7476
|
+
const { height, width } = await getIntrinsicDimensionsFromBase64Img(data);
|
|
7477
|
+
return `
|
|
7478
|
+
<html>
|
|
7479
|
+
<head>
|
|
7480
|
+
${item.renditionLayout !== `reflowable` ? `<meta name="viewport" content="width=${width}, height=${height}">` : ``}
|
|
7481
|
+
</head>
|
|
7482
|
+
<body style="margin: 0px;" tab-index="-1;">
|
|
7483
|
+
<img
|
|
7484
|
+
src="${data}"
|
|
7485
|
+
style="max-width: 100%;height:100%;object-fit:contain;"
|
|
7486
|
+
>
|
|
7487
|
+
</body>
|
|
7488
|
+
</html>
|
|
7489
|
+
`;
|
|
7490
|
+
}
|
|
7491
|
+
if ([`text/plain`].some((mime) => mime === contentType)) {
|
|
7492
|
+
const data = await resourceResponse.text();
|
|
7493
|
+
return `
|
|
7494
|
+
<!DOCTYPE html>
|
|
7495
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
|
|
7496
|
+
<head>
|
|
7497
|
+
<style>
|
|
7498
|
+
pre {
|
|
7499
|
+
white-space: pre;
|
|
7500
|
+
white-space: pre-wrap;
|
|
7501
|
+
word-wrap: break-word;
|
|
7703
7502
|
}
|
|
7503
|
+
</style>
|
|
7504
|
+
</head>
|
|
7505
|
+
<body>
|
|
7506
|
+
<pre>${data}</pre>
|
|
7507
|
+
</body>
|
|
7508
|
+
</html>
|
|
7509
|
+
`;
|
|
7510
|
+
}
|
|
7511
|
+
const content = await resourceResponse.text();
|
|
7512
|
+
return content;
|
|
7513
|
+
};
|
|
7514
|
+
const attachFrameSrc = ({
|
|
7515
|
+
item,
|
|
7516
|
+
resourcesHandler
|
|
7517
|
+
}) => {
|
|
7518
|
+
const getHtmlFromResource = (response) => createHtmlPageFromResource(response, item);
|
|
7519
|
+
return (stream) => stream.pipe(
|
|
7520
|
+
switchMap((frameElement) => {
|
|
7521
|
+
return from(resourcesHandler.getResource()).pipe(
|
|
7522
|
+
switchMap((resource) => {
|
|
7523
|
+
if (resource instanceof URL && item.href.startsWith(window.location.origin) && // we have an encoding and it's a valid html
|
|
7524
|
+
(item.mediaType && [
|
|
7525
|
+
`application/xhtml+xml`,
|
|
7526
|
+
`application/xml`,
|
|
7527
|
+
`text/html`,
|
|
7528
|
+
`text/xml`
|
|
7529
|
+
].includes(item.mediaType) || // no encoding ? then try to detect html
|
|
7530
|
+
!item.mediaType && ITEM_EXTENSION_VALID_FOR_FRAME_SRC.some(
|
|
7531
|
+
(extension) => item.href.endsWith(extension)
|
|
7532
|
+
))) {
|
|
7533
|
+
frameElement == null ? void 0 : frameElement.setAttribute(`src`, item.href);
|
|
7534
|
+
return of(frameElement);
|
|
7535
|
+
} else {
|
|
7536
|
+
const resourceResponse$ = resource instanceof URL ? from(resourcesHandler.fetchResource()) : resource instanceof Response ? of(resource) : EMPTY;
|
|
7537
|
+
return resourceResponse$.pipe(
|
|
7538
|
+
filter$1((response) => response instanceof Response),
|
|
7539
|
+
switchMap((response) => from(getHtmlFromResource(response))),
|
|
7540
|
+
tap$1((htmlDoc) => {
|
|
7541
|
+
if (htmlDoc) {
|
|
7542
|
+
const blob = new Blob([htmlDoc], { type: "text/html" });
|
|
7543
|
+
const blobURL = URL.createObjectURL(blob);
|
|
7544
|
+
frameElement == null ? void 0 : frameElement.setAttribute(`src`, blobURL);
|
|
7545
|
+
}
|
|
7546
|
+
}),
|
|
7547
|
+
map$1(() => frameElement),
|
|
7548
|
+
catchError$1((e) => {
|
|
7549
|
+
Report.error(
|
|
7550
|
+
`Error while trying to fetch or load resource for item ${item.id}`
|
|
7551
|
+
);
|
|
7552
|
+
console.error(e);
|
|
7553
|
+
return of(frameElement);
|
|
7554
|
+
})
|
|
7555
|
+
);
|
|
7704
7556
|
}
|
|
7705
|
-
}
|
|
7706
|
-
|
|
7707
|
-
}
|
|
7708
|
-
{
|
|
7709
|
-
threshold: 0.5
|
|
7710
|
-
}
|
|
7557
|
+
})
|
|
7558
|
+
);
|
|
7559
|
+
})
|
|
7711
7560
|
);
|
|
7712
|
-
reader.hookManager.register(`item.onLoad`, ({ frame, destroy: destroy2 }) => {
|
|
7713
|
-
var _a;
|
|
7714
|
-
frameObserver.observe(frame);
|
|
7715
|
-
const videos = (_a = frame.contentDocument) == null ? void 0 : _a.body.getElementsByTagName(`video`);
|
|
7716
|
-
const unobserveElements = Array.from(videos || []).map((element) => {
|
|
7717
|
-
elementObserver.observe(element);
|
|
7718
|
-
return () => elementObserver.unobserve(element);
|
|
7719
|
-
});
|
|
7720
|
-
destroy2(() => {
|
|
7721
|
-
frameObserver.unobserve(frame);
|
|
7722
|
-
unobserveElements.forEach((unobserve) => unobserve());
|
|
7723
|
-
});
|
|
7724
|
-
});
|
|
7725
|
-
const destroy = () => {
|
|
7726
|
-
frameObserver.disconnect();
|
|
7727
|
-
elementObserver.disconnect();
|
|
7728
|
-
reader.destroy();
|
|
7729
|
-
};
|
|
7730
|
-
return {
|
|
7731
|
-
...reader,
|
|
7732
|
-
destroy
|
|
7733
|
-
};
|
|
7734
7561
|
};
|
|
7735
|
-
const
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7562
|
+
const getStyleForViewportDocument = () => {
|
|
7563
|
+
return `
|
|
7564
|
+
body {
|
|
7565
|
+
margin: 0;
|
|
7566
|
+
}
|
|
7567
|
+
}
|
|
7568
|
+
`;
|
|
7569
|
+
};
|
|
7570
|
+
const getViewPortInformation = ({
|
|
7571
|
+
pageHeight,
|
|
7572
|
+
pageWidth,
|
|
7573
|
+
frameElement
|
|
7574
|
+
}) => {
|
|
7575
|
+
const viewportDimensions = getFrameViewportInfo(frameElement);
|
|
7576
|
+
if ((frameElement == null ? void 0 : frameElement.contentDocument) && frameElement.contentWindow && viewportDimensions) {
|
|
7577
|
+
const computedWidthScale = pageWidth / (viewportDimensions.width ?? 1);
|
|
7578
|
+
const computedScale = Math.min(
|
|
7579
|
+
computedWidthScale,
|
|
7580
|
+
pageHeight / (viewportDimensions.height ?? 1)
|
|
7581
|
+
);
|
|
7582
|
+
return { computedScale, computedWidthScale, viewportDimensions };
|
|
7583
|
+
}
|
|
7584
|
+
};
|
|
7585
|
+
const buildDocumentStyle = ({
|
|
7586
|
+
columnWidth,
|
|
7587
|
+
enableTouch,
|
|
7588
|
+
spreadPosition
|
|
7589
|
+
}, viewportDimensions) => {
|
|
7590
|
+
return `
|
|
7591
|
+
${getStyleForViewportDocument()}
|
|
7592
|
+
body {
|
|
7593
|
+
${!viewportDimensions ? `
|
|
7594
|
+
display: flex;
|
|
7595
|
+
justify-content: ${spreadPosition === `left` ? `flex-end` : spreadPosition === `right` ? `flex-start` : `center`};
|
|
7596
|
+
` : ``}
|
|
7597
|
+
}
|
|
7598
|
+
${/*
|
|
7599
|
+
might be html * but it does mess up things like figure if so.
|
|
7600
|
+
check accessible_epub_3
|
|
7601
|
+
*/
|
|
7602
|
+
``}
|
|
7603
|
+
html, body {
|
|
7604
|
+
height: 100%;
|
|
7605
|
+
width: 100%;
|
|
7606
|
+
}
|
|
7607
|
+
${/*
|
|
7608
|
+
This one is important for preventing 100% img to resize above
|
|
7609
|
+
current width. Especially needed for cbz conversion
|
|
7610
|
+
*/
|
|
7611
|
+
``}
|
|
7612
|
+
html, body {
|
|
7613
|
+
-max-width: ${columnWidth}px !important;
|
|
7614
|
+
}
|
|
7615
|
+
${/*
|
|
7616
|
+
* @see https://hammerjs.github.io/touch-action/
|
|
7617
|
+
* It needs to be disabled when using free scroll
|
|
7618
|
+
*/
|
|
7619
|
+
``}
|
|
7620
|
+
html, body {
|
|
7621
|
+
${enableTouch ? `
|
|
7622
|
+
touch-action: none
|
|
7623
|
+
` : ``}
|
|
7624
|
+
}
|
|
7625
|
+
${/*
|
|
7626
|
+
prevent drag of image instead of touch on firefox
|
|
7627
|
+
*/
|
|
7628
|
+
``}
|
|
7629
|
+
img {
|
|
7630
|
+
user-select: none;
|
|
7631
|
+
-webkit-user-drag: none;
|
|
7632
|
+
-khtml-user-drag: none;
|
|
7633
|
+
-moz-user-drag: none;
|
|
7634
|
+
-o-user-drag: none;
|
|
7635
|
+
user-drag: none;
|
|
7636
|
+
${/*
|
|
7637
|
+
prevent weird overflow or margin. Try `block` if `flex` has weird behavior
|
|
7638
|
+
*/
|
|
7639
|
+
``}
|
|
7640
|
+
display: flex;
|
|
7641
|
+
${/*
|
|
7642
|
+
If the document does not have viewport, we cannot scale anything inside.
|
|
7643
|
+
This should never happens with a valid epub document however it will happens if
|
|
7644
|
+
we load .jpg, .png, etc directly in the iframe. This is expected, in this case we force
|
|
7645
|
+
the inner content to display correctly.
|
|
7646
|
+
*/
|
|
7647
|
+
``}
|
|
7648
|
+
${!viewportDimensions ? `
|
|
7649
|
+
-width: 100%;
|
|
7650
|
+
max-width: 100%;
|
|
7651
|
+
height:100%;
|
|
7652
|
+
object-fit:contain;
|
|
7653
|
+
` : ``}
|
|
7654
|
+
}
|
|
7655
|
+
`;
|
|
7656
|
+
};
|
|
7657
|
+
const getDimensionsForPaginatedContent = ({
|
|
7658
|
+
pageHeight: columnHeight,
|
|
7659
|
+
pageWidth
|
|
7660
|
+
}) => {
|
|
7661
|
+
const columnWidth = pageWidth;
|
|
7662
|
+
return { columnHeight, columnWidth };
|
|
7663
|
+
};
|
|
7664
|
+
const staticLayout$1 = (frameElement, size) => {
|
|
7665
|
+
frameElement.style.width = `${size.width}px`;
|
|
7666
|
+
frameElement.style.height = `${size.height}px`;
|
|
7667
|
+
};
|
|
7668
|
+
const renderPrePaginated = ({
|
|
7669
|
+
minPageSpread,
|
|
7670
|
+
blankPagePosition,
|
|
7671
|
+
spreadPosition,
|
|
7672
|
+
pageHeight,
|
|
7673
|
+
pageWidth,
|
|
7674
|
+
frameElement,
|
|
7675
|
+
isRTL,
|
|
7676
|
+
enableTouch
|
|
7677
|
+
}) => {
|
|
7678
|
+
const minimumWidth = minPageSpread * pageWidth;
|
|
7679
|
+
if ((frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
|
|
7680
|
+
const { viewportDimensions, computedScale = 1 } = getViewPortInformation({ frameElement, pageHeight, pageWidth }) ?? {};
|
|
7681
|
+
const contentWidth = pageWidth;
|
|
7682
|
+
const contentHeight = pageHeight;
|
|
7683
|
+
const cssLink = buildDocumentStyle(
|
|
7684
|
+
{
|
|
7685
|
+
...getDimensionsForPaginatedContent({ pageHeight, pageWidth }),
|
|
7686
|
+
enableTouch,
|
|
7687
|
+
spreadPosition
|
|
7688
|
+
},
|
|
7689
|
+
viewportDimensions
|
|
7690
|
+
);
|
|
7691
|
+
upsertCSS(frameElement, `prose-reader-css`, cssLink);
|
|
7692
|
+
if (viewportDimensions) {
|
|
7693
|
+
staticLayout$1(frameElement, {
|
|
7694
|
+
width: viewportDimensions.width ?? 1,
|
|
7695
|
+
height: viewportDimensions.height ?? 1
|
|
7696
|
+
});
|
|
7697
|
+
} else {
|
|
7698
|
+
staticLayout$1(frameElement, {
|
|
7699
|
+
width: contentWidth,
|
|
7700
|
+
height: contentHeight
|
|
7701
|
+
});
|
|
7746
7702
|
}
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
);
|
|
7703
|
+
if (viewportDimensions) {
|
|
7704
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`position`, `absolute`);
|
|
7705
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`top`, `50%`);
|
|
7706
|
+
if (spreadPosition === `left`) {
|
|
7707
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`right`, `0`);
|
|
7708
|
+
frameElement == null ? void 0 : frameElement.style.removeProperty(`left`);
|
|
7709
|
+
} else if (blankPagePosition === `before` && isRTL) {
|
|
7710
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`right`, `50%`);
|
|
7711
|
+
frameElement == null ? void 0 : frameElement.style.removeProperty(`left`);
|
|
7712
|
+
} else if (spreadPosition === `right`) {
|
|
7713
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`left`, `0`);
|
|
7714
|
+
frameElement == null ? void 0 : frameElement.style.removeProperty(`right`);
|
|
7755
7715
|
} else {
|
|
7756
|
-
|
|
7716
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
7717
|
+
`left`,
|
|
7718
|
+
blankPagePosition === `before` ? isRTL ? `25%` : `75%` : blankPagePosition === `after` ? isRTL ? `75%` : `25%` : `50%`
|
|
7719
|
+
);
|
|
7720
|
+
frameElement == null ? void 0 : frameElement.style.removeProperty(`right`);
|
|
7757
7721
|
}
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
|
|
7722
|
+
const transformTranslateX = spreadPosition !== `none` ? `0` : `-50%`;
|
|
7723
|
+
const transformOriginX = spreadPosition === `right` && blankPagePosition !== `before` ? `left` : spreadPosition === `left` || blankPagePosition === `before` && isRTL ? `right` : `center`;
|
|
7724
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
7725
|
+
`transform`,
|
|
7726
|
+
`translate(${transformTranslateX}, -50%) scale(${computedScale})`
|
|
7762
7727
|
);
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
}
|
|
7767
|
-
return totalProgress;
|
|
7768
|
-
};
|
|
7769
|
-
const getTotalProgressFromPercentages = (estimateBeforeThisItem, currentItemWeight, progressWithinThisItem) => {
|
|
7770
|
-
return estimateBeforeThisItem + currentItemWeight * progressWithinThisItem;
|
|
7771
|
-
};
|
|
7772
|
-
const getScrollPercentageWithinItem = (context, currentPosition, currentItem) => {
|
|
7773
|
-
const { height, width } = currentItem.getElementDimensions();
|
|
7774
|
-
const { top, left } = reader.spine.spineLayout.getAbsolutePositionOf(currentItem);
|
|
7775
|
-
if (reader.settings.values.computedPageTurnDirection === `vertical`) {
|
|
7776
|
-
return Math.max(
|
|
7777
|
-
0,
|
|
7778
|
-
Math.min(
|
|
7779
|
-
1,
|
|
7780
|
-
(currentPosition.y - top + context.state.visibleAreaRect.height) / height
|
|
7781
|
-
)
|
|
7728
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
7729
|
+
`transform-origin`,
|
|
7730
|
+
`${transformOriginX} center`
|
|
7782
7731
|
);
|
|
7783
7732
|
} else {
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
...reader,
|
|
7795
|
-
progression: {
|
|
7796
|
-
getPercentageEstimate,
|
|
7797
|
-
getScrollPercentageWithinItem
|
|
7733
|
+
if (blankPagePosition === `before`) {
|
|
7734
|
+
if (isRTL) {
|
|
7735
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`margin-right`, `${pageWidth}px`);
|
|
7736
|
+
} else {
|
|
7737
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`margin-left`, `${pageWidth}px`);
|
|
7738
|
+
}
|
|
7739
|
+
} else {
|
|
7740
|
+
frameElement == null ? void 0 : frameElement.style.removeProperty(`margin-left`);
|
|
7741
|
+
frameElement == null ? void 0 : frameElement.style.removeProperty(`margin-right`);
|
|
7742
|
+
}
|
|
7798
7743
|
}
|
|
7799
|
-
|
|
7744
|
+
return { width: minimumWidth, height: contentHeight };
|
|
7745
|
+
}
|
|
7746
|
+
return { width: minimumWidth, height: pageHeight };
|
|
7800
7747
|
};
|
|
7801
|
-
const
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
} else {
|
|
7808
|
-
entry.target.setAttribute(`tab-index`, `-1`);
|
|
7748
|
+
const buildStyleForViewportFrame = () => {
|
|
7749
|
+
return `
|
|
7750
|
+
${getStyleForViewportDocument()}
|
|
7751
|
+
html {
|
|
7752
|
+
width: 100%;
|
|
7753
|
+
height: 100%;
|
|
7809
7754
|
}
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
*/
|
|
7824
|
-
``}
|
|
7825
|
-
outline: -webkit-focus-ring-color auto 1px;
|
|
7826
|
-
}
|
|
7827
|
-
`
|
|
7828
|
-
);
|
|
7829
|
-
const links = (_a = frame.contentDocument) == null ? void 0 : _a.body.querySelectorAll(`a`);
|
|
7830
|
-
links == null ? void 0 : links.forEach((link) => {
|
|
7831
|
-
observer.observe(link);
|
|
7832
|
-
});
|
|
7833
|
-
destroy(() => {
|
|
7834
|
-
links == null ? void 0 : links.forEach((link) => {
|
|
7835
|
-
observer.unobserve(link);
|
|
7836
|
-
});
|
|
7837
|
-
});
|
|
7838
|
-
});
|
|
7839
|
-
return {
|
|
7840
|
-
...reader
|
|
7841
|
-
};
|
|
7755
|
+
body {
|
|
7756
|
+
width: 100%;
|
|
7757
|
+
height: 100%;
|
|
7758
|
+
margin: 0;
|
|
7759
|
+
}
|
|
7760
|
+
${/*
|
|
7761
|
+
* @see https://hammerjs.github.io/touch-action/
|
|
7762
|
+
*/
|
|
7763
|
+
``}
|
|
7764
|
+
html, body {
|
|
7765
|
+
touch-action: none;
|
|
7766
|
+
}
|
|
7767
|
+
`;
|
|
7842
7768
|
};
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7769
|
+
const buildStyleForReflowableImageOnly = ({
|
|
7770
|
+
isScrollable,
|
|
7771
|
+
enableTouch
|
|
7772
|
+
}) => {
|
|
7773
|
+
return `
|
|
7774
|
+
${/*
|
|
7775
|
+
* @see https://hammerjs.github.io/touch-action/
|
|
7776
|
+
*/
|
|
7777
|
+
``}
|
|
7778
|
+
html, body {
|
|
7779
|
+
width: 100%;
|
|
7780
|
+
margin: 0;
|
|
7781
|
+
padding: 0;
|
|
7782
|
+
${enableTouch ? `
|
|
7783
|
+
touch-action: none
|
|
7784
|
+
` : ``}
|
|
7785
|
+
}
|
|
7786
|
+
${isScrollable ? `
|
|
7787
|
+
img {
|
|
7788
|
+
height: auto !important;
|
|
7789
|
+
margin: 0;
|
|
7790
|
+
padding: 0;
|
|
7791
|
+
box-sizing: border-box;
|
|
7792
|
+
${// we make sure img spread on entire screen
|
|
7793
|
+
``}
|
|
7794
|
+
width: 100%;
|
|
7795
|
+
${/**
|
|
7796
|
+
* line break issue
|
|
7797
|
+
* @see https://stackoverflow.com/questions/37869020/image-not-taking-up-the-full-height-of-container
|
|
7798
|
+
*/
|
|
7799
|
+
``}
|
|
7800
|
+
display: block;
|
|
7801
|
+
}
|
|
7802
|
+
` : ``}
|
|
7803
|
+
`;
|
|
7847
7804
|
};
|
|
7848
|
-
const
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
}
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
};
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7805
|
+
const buildStyleWithMultiColumn = ({
|
|
7806
|
+
width,
|
|
7807
|
+
columnHeight,
|
|
7808
|
+
columnWidth
|
|
7809
|
+
}) => {
|
|
7810
|
+
return `
|
|
7811
|
+
parsererror {
|
|
7812
|
+
display: none !important;
|
|
7813
|
+
}
|
|
7814
|
+
${/*
|
|
7815
|
+
might be html * but it does mess up things like figure if so.
|
|
7816
|
+
check accessible_epub_3
|
|
7817
|
+
*/
|
|
7818
|
+
``}
|
|
7819
|
+
html, body {
|
|
7820
|
+
margin: 0;
|
|
7821
|
+
padding: 0 !important;
|
|
7822
|
+
-max-width: ${columnWidth}px !important;
|
|
7823
|
+
}
|
|
7824
|
+
${/*
|
|
7825
|
+
body {
|
|
7826
|
+
height: ${columnHeight}px !important;
|
|
7827
|
+
width: ${columnWidth}px !important;
|
|
7828
|
+
-margin-left: ${horizontalMargin}px !important;
|
|
7829
|
+
-margin-right: ${horizontalMargin}px !important;
|
|
7830
|
+
-margin: ${verticalMargin}px ${horizontalMargin}px !important;
|
|
7831
|
+
-padding-top: ${horizontalMargin}px !important;
|
|
7832
|
+
-padding-bottom: ${horizontalMargin}px !important;
|
|
7833
|
+
}
|
|
7834
|
+
*/
|
|
7835
|
+
``}
|
|
7836
|
+
body {
|
|
7837
|
+
padding: 0 !important;
|
|
7838
|
+
width: ${width}px !important;
|
|
7839
|
+
height: ${columnHeight}px !important;
|
|
7840
|
+
overflow-y: hidden;
|
|
7841
|
+
column-gap: 0px !important;
|
|
7842
|
+
column-width: ${columnWidth}px !important;
|
|
7843
|
+
column-fill: auto !important;
|
|
7844
|
+
word-wrap: break-word;
|
|
7845
|
+
box-sizing: border-box;
|
|
7846
|
+
}
|
|
7847
|
+
body {
|
|
7848
|
+
margin: 0;
|
|
7849
|
+
}
|
|
7850
|
+
body:focus-visible {
|
|
7851
|
+
${/*
|
|
7852
|
+
we make sure that there are no outline when we focus something inside the iframe
|
|
7853
|
+
*/
|
|
7854
|
+
``}
|
|
7855
|
+
outline: none;
|
|
7856
|
+
}
|
|
7857
|
+
${/*
|
|
7858
|
+
* @see https://hammerjs.github.io/touch-action/
|
|
7859
|
+
*/
|
|
7860
|
+
``}
|
|
7861
|
+
html, body {
|
|
7862
|
+
touch-action: none;
|
|
7863
|
+
}
|
|
7864
|
+
${/*
|
|
7865
|
+
this messes up hard, be careful with this
|
|
7866
|
+
*/
|
|
7867
|
+
``}
|
|
7868
|
+
* {
|
|
7869
|
+
-max-width: ${columnWidth}px !important;
|
|
7870
|
+
}
|
|
7871
|
+
${/*
|
|
7872
|
+
this is necessary to have a proper calculation when determining size
|
|
7873
|
+
of iframe content. If an img is using something like width:100% it would expand to
|
|
7874
|
+
the size of the original image and potentially gives back a wrong size (much larger)
|
|
7875
|
+
@see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Columns/Handling_Overflow_in_Multicol
|
|
7876
|
+
*/
|
|
7877
|
+
``}
|
|
7878
|
+
img, video, audio, object, svg {
|
|
7879
|
+
max-width: 100%;
|
|
7880
|
+
max-width: ${columnWidth}px !important;
|
|
7881
|
+
max-height: ${columnHeight}px !important;
|
|
7882
|
+
-pointer-events: none;
|
|
7883
|
+
-webkit-column-break-inside: avoid;
|
|
7884
|
+
page-break-inside: avoid;
|
|
7885
|
+
break-inside: avoid;
|
|
7886
|
+
}
|
|
7887
|
+
figure {
|
|
7888
|
+
d-max-width: ${columnWidth}px !important;
|
|
7889
|
+
}
|
|
7890
|
+
img {
|
|
7891
|
+
object-fit: contain;
|
|
7892
|
+
break-inside: avoid;
|
|
7893
|
+
box-sizing: border-box;
|
|
7894
|
+
d-max-width: ${columnWidth}px !important;
|
|
7918
7895
|
}
|
|
7896
|
+
${/*
|
|
7897
|
+
img, video, audio, object, svg {
|
|
7898
|
+
max-height: ${columnHeight}px !important;
|
|
7899
|
+
box-sizing: border-box;
|
|
7900
|
+
object-fit: contain;
|
|
7901
|
+
-webkit-column-break-inside: avoid;
|
|
7902
|
+
page-break-inside: avoid;
|
|
7903
|
+
break-inside: avoid;
|
|
7919
7904
|
}
|
|
7905
|
+
*/
|
|
7906
|
+
``}
|
|
7907
|
+
table {
|
|
7908
|
+
max-width: ${columnWidth}px !important;
|
|
7909
|
+
table-layout: fixed;
|
|
7910
|
+
}
|
|
7911
|
+
td {
|
|
7912
|
+
max-width: ${columnWidth}px;
|
|
7913
|
+
}
|
|
7914
|
+
`;
|
|
7915
|
+
};
|
|
7916
|
+
const getDimensionsForReflowableContent = ({
|
|
7917
|
+
isUsingVerticalWriting,
|
|
7918
|
+
minimumWidth,
|
|
7919
|
+
pageHeight,
|
|
7920
|
+
pageWidth
|
|
7921
|
+
}) => {
|
|
7922
|
+
const horizontalMargin = 0;
|
|
7923
|
+
const verticalMargin = 0;
|
|
7924
|
+
let columnWidth = pageWidth - horizontalMargin * 2;
|
|
7925
|
+
const columnHeight = pageHeight - verticalMargin * 2;
|
|
7926
|
+
let width = pageWidth - horizontalMargin * 2;
|
|
7927
|
+
if (isUsingVerticalWriting) {
|
|
7928
|
+
width = minimumWidth - horizontalMargin * 2;
|
|
7929
|
+
columnWidth = columnHeight;
|
|
7930
|
+
}
|
|
7931
|
+
return {
|
|
7932
|
+
columnHeight,
|
|
7933
|
+
columnWidth,
|
|
7934
|
+
width
|
|
7920
7935
|
};
|
|
7921
7936
|
};
|
|
7922
|
-
const
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
loadingElement.style.cssText = `
|
|
7926
|
-
height: 100%;
|
|
7927
|
-
width: 100%;
|
|
7928
|
-
max-width: ${context.state.visibleAreaRect.width}px;
|
|
7929
|
-
text-align: center;
|
|
7930
|
-
display: flex;
|
|
7931
|
-
justify-content: center;
|
|
7932
|
-
align-items: center;
|
|
7933
|
-
flex-direction: column;
|
|
7934
|
-
position: absolute;
|
|
7935
|
-
left: 0;
|
|
7936
|
-
top: 0;
|
|
7937
|
-
color: rgb(202, 202, 202);
|
|
7938
|
-
-background-color: white;
|
|
7939
|
-
`;
|
|
7940
|
-
return loadingElement;
|
|
7937
|
+
const staticLayout = (frameElement, size) => {
|
|
7938
|
+
frameElement.style.width = `${size.width}px`;
|
|
7939
|
+
frameElement.style.height = `${size.height}px`;
|
|
7941
7940
|
};
|
|
7942
|
-
const
|
|
7943
|
-
|
|
7944
|
-
|
|
7941
|
+
const renderReflowable = ({
|
|
7942
|
+
pageHeight: pageSizeHeight,
|
|
7943
|
+
pageWidth,
|
|
7944
|
+
frameElement,
|
|
7945
|
+
manifest,
|
|
7946
|
+
latestContentHeightWhenLoaded,
|
|
7947
|
+
minPageSpread,
|
|
7948
|
+
isRTL,
|
|
7949
|
+
blankPagePosition,
|
|
7950
|
+
isImageType,
|
|
7951
|
+
enableTouch,
|
|
7952
|
+
isUsingVerticalWriting
|
|
7945
7953
|
}) => {
|
|
7946
|
-
const
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7954
|
+
const minimumWidth = minPageSpread * pageWidth;
|
|
7955
|
+
let newLatestContentHeightWhenLoaded = latestContentHeightWhenLoaded;
|
|
7956
|
+
const continuousScrollableReflowableItem = (manifest == null ? void 0 : manifest.renditionLayout) === "reflowable" && (manifest == null ? void 0 : manifest.renditionFlow) === "scrolled-continuous";
|
|
7957
|
+
const pageHeight = continuousScrollableReflowableItem ? Math.min(400, pageSizeHeight) : pageSizeHeight;
|
|
7958
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`width`, `${pageWidth}px`);
|
|
7959
|
+
if (!continuousScrollableReflowableItem) {
|
|
7960
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`height`, `${pageHeight}px`);
|
|
7961
|
+
}
|
|
7962
|
+
const { viewportDimensions, computedScale = 1 } = getViewPortInformation({
|
|
7963
|
+
frameElement,
|
|
7964
|
+
pageHeight,
|
|
7965
|
+
pageWidth
|
|
7966
|
+
}) ?? {};
|
|
7967
|
+
const isGloballyPrePaginated = (manifest == null ? void 0 : manifest.renditionLayout) === `pre-paginated`;
|
|
7968
|
+
if ((frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
|
|
7969
|
+
let contentWidth = pageWidth;
|
|
7970
|
+
let contentHeight = pageHeight;
|
|
7971
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`visibility`, `visible`);
|
|
7972
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`opacity`, `1`);
|
|
7973
|
+
if (viewportDimensions == null ? void 0 : viewportDimensions.hasViewport) {
|
|
7974
|
+
upsertCSS(
|
|
7975
|
+
frameElement,
|
|
7976
|
+
`prose-reader-html-renderer-framce-css`,
|
|
7977
|
+
buildStyleForViewportFrame()
|
|
7978
|
+
);
|
|
7979
|
+
staticLayout(
|
|
7980
|
+
frameElement,
|
|
7981
|
+
{
|
|
7982
|
+
width: viewportDimensions.width ?? 1,
|
|
7983
|
+
height: viewportDimensions.height ?? 1
|
|
7984
|
+
}
|
|
7985
|
+
);
|
|
7986
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`position`, `absolute`);
|
|
7987
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`top`, `50%`);
|
|
7988
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
7989
|
+
`left`,
|
|
7990
|
+
blankPagePosition === `before` ? isRTL ? `25%` : `75%` : blankPagePosition === `after` ? isRTL ? `75%` : `25%` : `50%`
|
|
7991
|
+
);
|
|
7992
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(
|
|
7993
|
+
`transform`,
|
|
7994
|
+
`translate(-50%, -50%) scale(${computedScale})`
|
|
7995
|
+
);
|
|
7996
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`transform-origin`, `center center`);
|
|
7997
|
+
} else {
|
|
7998
|
+
const frameStyle = isImageType ? buildStyleForReflowableImageOnly({
|
|
7999
|
+
isScrollable: (manifest == null ? void 0 : manifest.renditionFlow) === `scrolled-continuous`,
|
|
8000
|
+
enableTouch
|
|
8001
|
+
}) : buildStyleWithMultiColumn(
|
|
8002
|
+
getDimensionsForReflowableContent({
|
|
8003
|
+
isUsingVerticalWriting,
|
|
8004
|
+
minimumWidth,
|
|
8005
|
+
pageHeight,
|
|
8006
|
+
pageWidth
|
|
8007
|
+
})
|
|
8008
|
+
);
|
|
8009
|
+
upsertCSS(frameElement, `prose-reader-css`, frameStyle, true);
|
|
8010
|
+
if (isUsingVerticalWriting) {
|
|
8011
|
+
const pages = Math.ceil(
|
|
8012
|
+
frameElement.contentDocument.documentElement.scrollHeight / pageHeight
|
|
8013
|
+
);
|
|
8014
|
+
contentHeight = pages * pageHeight;
|
|
8015
|
+
staticLayout(
|
|
8016
|
+
frameElement,
|
|
8017
|
+
{
|
|
8018
|
+
width: minimumWidth,
|
|
8019
|
+
height: contentHeight
|
|
8020
|
+
}
|
|
8021
|
+
);
|
|
8022
|
+
} else if ((manifest == null ? void 0 : manifest.renditionFlow) === `scrolled-continuous`) {
|
|
8023
|
+
contentHeight = frameElement.contentDocument.body.scrollHeight;
|
|
8024
|
+
newLatestContentHeightWhenLoaded = contentHeight;
|
|
8025
|
+
staticLayout(
|
|
8026
|
+
frameElement,
|
|
8027
|
+
{
|
|
8028
|
+
width: minimumWidth,
|
|
8029
|
+
height: contentHeight
|
|
8030
|
+
}
|
|
8031
|
+
);
|
|
8032
|
+
} else {
|
|
8033
|
+
const pages = Math.ceil(
|
|
8034
|
+
frameElement.contentDocument.documentElement.scrollWidth / pageWidth
|
|
8035
|
+
);
|
|
8036
|
+
if (isGloballyPrePaginated) {
|
|
8037
|
+
contentWidth = pageWidth;
|
|
8038
|
+
} else {
|
|
8039
|
+
contentWidth = pages * pageWidth;
|
|
8040
|
+
}
|
|
8041
|
+
staticLayout(
|
|
8042
|
+
frameElement,
|
|
8043
|
+
{
|
|
8044
|
+
width: contentWidth,
|
|
8045
|
+
height: contentHeight
|
|
8046
|
+
}
|
|
8047
|
+
);
|
|
8048
|
+
}
|
|
8049
|
+
}
|
|
8050
|
+
const isFillingAllScreen = contentWidth % minimumWidth === 0;
|
|
8051
|
+
if (!isFillingAllScreen) {
|
|
8052
|
+
contentWidth = contentWidth + pageWidth;
|
|
8053
|
+
if (isRTL && !isUsingVerticalWriting) {
|
|
8054
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`margin-left`, `${pageWidth}px`);
|
|
8055
|
+
}
|
|
8056
|
+
} else {
|
|
8057
|
+
frameElement == null ? void 0 : frameElement.style.setProperty(`margin-left`, `0px`);
|
|
8058
|
+
}
|
|
8059
|
+
return { width: contentWidth, height: contentHeight };
|
|
8060
|
+
}
|
|
8061
|
+
const height = newLatestContentHeightWhenLoaded || pageHeight;
|
|
8062
|
+
return {
|
|
8063
|
+
width: minimumWidth,
|
|
8064
|
+
height,
|
|
8065
|
+
latestContentHeightWhenLoaded: newLatestContentHeightWhenLoaded
|
|
8066
|
+
};
|
|
7964
8067
|
};
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
}
|
|
7979
|
-
Object.defineProperty(newEvent, `target`, {
|
|
7980
|
-
value: iframeOriginalEvent.target,
|
|
7981
|
-
enumerable: true
|
|
7982
|
-
});
|
|
7983
|
-
return newEvent;
|
|
8068
|
+
class HtmlRenderer extends DocumentRenderer {
|
|
8069
|
+
constructor(context, settings, hookManager, item, containerElement, resourcesHandler) {
|
|
8070
|
+
super(
|
|
8071
|
+
context,
|
|
8072
|
+
settings,
|
|
8073
|
+
hookManager,
|
|
8074
|
+
item,
|
|
8075
|
+
containerElement,
|
|
8076
|
+
resourcesHandler
|
|
8077
|
+
);
|
|
8078
|
+
this.isImageType = () => {
|
|
8079
|
+
const mimeType = this.item.mediaType ?? detectMimeTypeFromName(this.item.href);
|
|
8080
|
+
return !!(mimeType == null ? void 0 : mimeType.startsWith(`image/`));
|
|
8081
|
+
};
|
|
7984
8082
|
}
|
|
7985
|
-
|
|
7986
|
-
const
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
8083
|
+
onCreateDocument() {
|
|
8084
|
+
const frameElement = createFrameElement();
|
|
8085
|
+
this.layers = [
|
|
8086
|
+
{
|
|
8087
|
+
element: frameElement
|
|
8088
|
+
}
|
|
8089
|
+
];
|
|
8090
|
+
return EMPTY;
|
|
8091
|
+
}
|
|
8092
|
+
onLoadDocument() {
|
|
8093
|
+
const frameElement = this.getFrameElement();
|
|
8094
|
+
if (!frameElement) throw new Error(`invalid frame`);
|
|
8095
|
+
return of(frameElement).pipe(
|
|
8096
|
+
attachFrameSrc({
|
|
8097
|
+
item: this.item,
|
|
8098
|
+
resourcesHandler: this.resourcesHandler,
|
|
8099
|
+
settings: this.settings
|
|
8100
|
+
}),
|
|
8101
|
+
waitForSwitch(this.context.bridgeEvent.viewportFree$),
|
|
8102
|
+
tap$1((frameElement2) => {
|
|
8103
|
+
this.containerElement.appendChild(frameElement2);
|
|
8104
|
+
}),
|
|
8105
|
+
waitForFrameLoad,
|
|
8106
|
+
waitForFrameReady
|
|
8107
|
+
);
|
|
7997
8108
|
}
|
|
7998
|
-
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
|
|
8002
|
-
|
|
8003
|
-
|
|
8004
|
-
|
|
8005
|
-
|
|
8109
|
+
onUnload() {
|
|
8110
|
+
this.layers.forEach((layer) => layer.element.remove());
|
|
8111
|
+
this.layers = [];
|
|
8112
|
+
return EMPTY;
|
|
8113
|
+
}
|
|
8114
|
+
layout({
|
|
8115
|
+
minPageSpread,
|
|
8116
|
+
blankPagePosition,
|
|
8117
|
+
spreadPosition
|
|
8118
|
+
}) {
|
|
8119
|
+
var _a;
|
|
8120
|
+
const { width: pageWidth, height: pageHeight } = this.context.getPageSize();
|
|
8121
|
+
const frameElement = this.getFrameElement();
|
|
8122
|
+
if (!frameElement) return { width: pageWidth, height: pageHeight };
|
|
8123
|
+
const isUsingVerticalWriting = !!((_a = this.writingMode) == null ? void 0 : _a.startsWith(`vertical`));
|
|
8124
|
+
if (this.item.renditionLayout === `pre-paginated`) {
|
|
8125
|
+
return renderPrePaginated({
|
|
8126
|
+
blankPagePosition,
|
|
8127
|
+
enableTouch: this.settings.values.computedPageTurnMode !== `scrollable`,
|
|
8128
|
+
frameElement,
|
|
8129
|
+
isRTL: this.context.isRTL(),
|
|
8130
|
+
minPageSpread,
|
|
8131
|
+
pageHeight,
|
|
8132
|
+
pageWidth,
|
|
8133
|
+
spreadPosition
|
|
8006
8134
|
});
|
|
8135
|
+
}
|
|
8136
|
+
const { latestContentHeightWhenLoaded, ...rest } = renderReflowable({
|
|
8137
|
+
pageHeight,
|
|
8138
|
+
pageWidth,
|
|
8139
|
+
frameElement,
|
|
8140
|
+
manifest: this.context.manifest,
|
|
8141
|
+
blankPagePosition,
|
|
8142
|
+
isUsingVerticalWriting,
|
|
8143
|
+
isRTL: this.context.isRTL(),
|
|
8144
|
+
latestContentHeightWhenLoaded: this.latestContentHeightWhenLoaded,
|
|
8145
|
+
minPageSpread,
|
|
8146
|
+
isImageType: this.isImageType(),
|
|
8147
|
+
enableTouch: this.settings.values.computedPageTurnMode !== `scrollable`
|
|
8007
8148
|
});
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
changedTouches: touches,
|
|
8011
|
-
targetTouches: touches
|
|
8012
|
-
});
|
|
8013
|
-
Object.defineProperty(newEvent, `target`, {
|
|
8014
|
-
value: iframeOriginalEvent.target,
|
|
8015
|
-
enumerable: true
|
|
8016
|
-
});
|
|
8017
|
-
return newEvent;
|
|
8149
|
+
this.latestContentHeightWhenLoaded = latestContentHeightWhenLoaded;
|
|
8150
|
+
return rest;
|
|
8018
8151
|
}
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
const
|
|
8022
|
-
|
|
8023
|
-
|
|
8024
|
-
|
|
8025
|
-
|
|
8026
|
-
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
|
|
8031
|
-
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
const
|
|
8152
|
+
getFrameElement() {
|
|
8153
|
+
var _a;
|
|
8154
|
+
const frame = (_a = this.layers[0]) == null ? void 0 : _a.element;
|
|
8155
|
+
if (!(frame instanceof HTMLIFrameElement)) return;
|
|
8156
|
+
return frame;
|
|
8157
|
+
}
|
|
8158
|
+
// @todo optimize
|
|
8159
|
+
getComputedStyleAfterLoad() {
|
|
8160
|
+
var _a, _b;
|
|
8161
|
+
const frame = this.getFrameElement();
|
|
8162
|
+
const body = (_a = frame == null ? void 0 : frame.contentDocument) == null ? void 0 : _a.body;
|
|
8163
|
+
if (body) {
|
|
8164
|
+
return (_b = frame == null ? void 0 : frame.contentWindow) == null ? void 0 : _b.getComputedStyle(body);
|
|
8165
|
+
}
|
|
8166
|
+
}
|
|
8167
|
+
get writingMode() {
|
|
8168
|
+
var _a;
|
|
8169
|
+
return (_a = this.getComputedStyleAfterLoad()) == null ? void 0 : _a.writingMode;
|
|
8170
|
+
}
|
|
8171
|
+
get readingDirection() {
|
|
8172
|
+
var _a;
|
|
8173
|
+
const writingMode = this.writingMode;
|
|
8174
|
+
if (writingMode === `vertical-rl`) {
|
|
8175
|
+
return `rtl`;
|
|
8176
|
+
}
|
|
8177
|
+
const direction = (_a = this.getComputedStyleAfterLoad()) == null ? void 0 : _a.direction;
|
|
8178
|
+
switch (direction) {
|
|
8179
|
+
case `ltr`:
|
|
8180
|
+
case `inherit`:
|
|
8181
|
+
case `initial`: {
|
|
8182
|
+
return `ltr`;
|
|
8183
|
+
}
|
|
8184
|
+
case `rtl`:
|
|
8185
|
+
return `rtl`;
|
|
8186
|
+
default:
|
|
8187
|
+
return void 0;
|
|
8188
|
+
}
|
|
8189
|
+
}
|
|
8190
|
+
}
|
|
8191
|
+
const htmlEnhancer = (next) => (options) => {
|
|
8192
|
+
const reader = next({
|
|
8193
|
+
...options,
|
|
8194
|
+
getRenderer(item) {
|
|
8041
8195
|
var _a;
|
|
8042
|
-
const
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
if (isPointerEvent(e)) {
|
|
8046
|
-
convertedEvent = new PointerEvent(e.type, e);
|
|
8047
|
-
}
|
|
8048
|
-
if (convertedEvent !== e) {
|
|
8049
|
-
const normalizedEvent = normalizeEventForViewport(
|
|
8050
|
-
convertedEvent,
|
|
8051
|
-
e,
|
|
8052
|
-
reader.spine.locator
|
|
8053
|
-
);
|
|
8054
|
-
(_a2 = reader.context.state.containerElement) == null ? void 0 : _a2.dispatchEvent(
|
|
8055
|
-
normalizedEvent
|
|
8056
|
-
);
|
|
8057
|
-
}
|
|
8058
|
-
};
|
|
8059
|
-
(_a = frame.contentDocument) == null ? void 0 : _a.addEventListener(event, listener);
|
|
8060
|
-
return () => {
|
|
8061
|
-
var _a2;
|
|
8062
|
-
(_a2 = frame.contentDocument) == null ? void 0 : _a2.removeEventListener(event, listener);
|
|
8063
|
-
};
|
|
8064
|
-
});
|
|
8065
|
-
item.selectionTracker.track(frame);
|
|
8066
|
-
item.fingerTracker.track(frame);
|
|
8067
|
-
destroy(() => {
|
|
8068
|
-
unregister.forEach((cb) => cb());
|
|
8069
|
-
});
|
|
8196
|
+
const MaybeRenderer = (_a = options.getRenderer) == null ? void 0 : _a.call(options, item);
|
|
8197
|
+
return MaybeRenderer ?? HtmlRenderer;
|
|
8198
|
+
}
|
|
8070
8199
|
});
|
|
8071
8200
|
return reader;
|
|
8072
8201
|
};
|
|
@@ -8089,8 +8218,10 @@ const createReaderWithEnhancers = (
|
|
|
8089
8218
|
paginationEnhancer(
|
|
8090
8219
|
progressionEnhancer(
|
|
8091
8220
|
eventsEnhancer(
|
|
8092
|
-
|
|
8093
|
-
|
|
8221
|
+
htmlEnhancer(
|
|
8222
|
+
// __
|
|
8223
|
+
createReader
|
|
8224
|
+
)
|
|
8094
8225
|
)
|
|
8095
8226
|
)
|
|
8096
8227
|
)
|
|
@@ -8110,8 +8241,10 @@ const createReaderWithEnhancers = (
|
|
|
8110
8241
|
)
|
|
8111
8242
|
);
|
|
8112
8243
|
export {
|
|
8244
|
+
DocumentRenderer,
|
|
8113
8245
|
HookManager,
|
|
8114
8246
|
Report,
|
|
8247
|
+
ResourceHandler,
|
|
8115
8248
|
SettingsManager3 as SettingsManager,
|
|
8116
8249
|
createReaderWithEnhancers as createReader,
|
|
8117
8250
|
isHtmlElement,
|