@prose-reader/core 1.130.0 → 1.132.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/generateCfiFromRange.d.ts +1 -6
- package/dist/createReaderWithEnhancer.d.ts +9 -9
- package/dist/enhancers/html/renderer/HtmlRenderer.d.ts +1 -0
- package/dist/enhancers/html/renderer/attachFrameSrc.d.ts +1 -1
- package/dist/enhancers/html/renderer/medias.d.ts +10 -0
- package/dist/enhancers/layoutEnhancer/types.d.ts +1 -0
- package/dist/enhancers/media/ImageRenderer.d.ts +1 -0
- package/dist/enhancers/pagination/enhancer.d.ts +7 -1
- package/dist/enhancers/pagination/locate.d.ts +32 -0
- package/dist/enhancers/selection/selection.d.ts +3 -3
- package/dist/enhancers/selection/selectionEnhancer.d.ts +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +360 -82
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +350 -72
- package/dist/index.umd.cjs.map +1 -1
- package/dist/navigation/consolidation/consolidateWithPagination.d.ts +24 -0
- package/dist/reader.d.ts +1 -6
- package/dist/spineItem/SpineItem.d.ts +5 -5
- package/dist/spineItem/renderer/DefaultRenderer.d.ts +1 -0
- package/dist/spineItem/renderer/DocumentRenderer.d.ts +8 -1
- package/dist/spineItem/{ResourceHandler.d.ts → resources/ResourceHandler.d.ts} +1 -1
- package/dist/utils/rxjs.d.ts +2 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { takeUntil, Subject, combineLatest, switchMap, fromEvent, take, map as map$1, from, of, merge, EMPTY, withLatestFrom, NEVER, Observable, 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
|
|
2
|
-
import { startWith, map, shareReplay, tap, pairwise, switchMap as switchMap$1, take as take$1, distinctUntilChanged, takeUntil as takeUntil$1, first, filter,
|
|
3
|
-
import { shallowMergeIfDefined, isShallowEqual, detectMimeTypeFromName, parseContentType } from "@prose-reader/shared";
|
|
1
|
+
import { takeUntil, Subject, combineLatest, switchMap, fromEvent, take, map as map$1, from, of, merge, EMPTY, withLatestFrom, NEVER, Observable, scheduled, animationFrameScheduler, defer, distinctUntilChanged as distinctUntilChanged$1, tap as tap$1, throttleTime, finalize, startWith as startWith$1, debounceTime as debounceTime$1, BehaviorSubject, combineLatestWith, shareReplay as shareReplay$1, switchScan, forkJoin, scan, ReplaySubject, filter as filter$1, share, mergeMap, delay, identity, timer, skip as skip$1, exhaustMap, first as first$1, lastValueFrom, endWith, catchError, reduce, concatMap } from "rxjs";
|
|
2
|
+
import { startWith, map, shareReplay, tap, pairwise, switchMap as switchMap$1, take as take$1, distinctUntilChanged, takeUntil as takeUntil$1, first, filter, debounceTime, skip, withLatestFrom as withLatestFrom$1, share as share$1, mergeMap as mergeMap$1, catchError as catchError$1 } from "rxjs/operators";
|
|
3
|
+
import { shallowMergeIfDefined, isShallowEqual, detectMimeTypeFromName, parseContentType, getParentPath } 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);
|
|
@@ -406,6 +406,25 @@ const deferNextResult = (stream) => {
|
|
|
406
406
|
return stream;
|
|
407
407
|
};
|
|
408
408
|
};
|
|
409
|
+
function idle() {
|
|
410
|
+
return new Observable((observer) => {
|
|
411
|
+
if (window.requestIdleCallback) {
|
|
412
|
+
const handle = window.requestIdleCallback(() => {
|
|
413
|
+
observer.next();
|
|
414
|
+
observer.complete();
|
|
415
|
+
});
|
|
416
|
+
return () => cancelIdleCallback(handle);
|
|
417
|
+
}
|
|
418
|
+
const timeout = setTimeout(() => {
|
|
419
|
+
observer.next();
|
|
420
|
+
observer.complete();
|
|
421
|
+
}, 1);
|
|
422
|
+
return () => clearTimeout(timeout);
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
function deferIdle(callback) {
|
|
426
|
+
return defer(() => idle().pipe(switchMap$1(callback)));
|
|
427
|
+
}
|
|
409
428
|
const fixReflowable = (reader) => {
|
|
410
429
|
reader.hookManager.register(
|
|
411
430
|
`item.onAfterLayout`,
|
|
@@ -449,6 +468,8 @@ let SettingsManager$1 = class SettingsManager2 extends SettingsManagerOverload {
|
|
|
449
468
|
pageHorizontalMargin,
|
|
450
469
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
451
470
|
pageVerticalMargin,
|
|
471
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
472
|
+
layoutLayerTransition,
|
|
452
473
|
...rest
|
|
453
474
|
} = settings;
|
|
454
475
|
return rest;
|
|
@@ -457,18 +478,25 @@ let SettingsManager$1 = class SettingsManager2 extends SettingsManagerOverload {
|
|
|
457
478
|
return {
|
|
458
479
|
layoutAutoResize: "container",
|
|
459
480
|
pageHorizontalMargin: 24,
|
|
460
|
-
pageVerticalMargin: 24
|
|
481
|
+
pageVerticalMargin: 24,
|
|
482
|
+
layoutLayerTransition: true
|
|
461
483
|
};
|
|
462
484
|
}
|
|
463
485
|
};
|
|
464
486
|
const layoutEnhancer = (next) => (options) => {
|
|
465
|
-
const {
|
|
487
|
+
const {
|
|
488
|
+
pageHorizontalMargin,
|
|
489
|
+
pageVerticalMargin,
|
|
490
|
+
layoutAutoResize,
|
|
491
|
+
layoutLayerTransition
|
|
492
|
+
} = options;
|
|
466
493
|
const reader = next(options);
|
|
467
494
|
const settingsManager = new SettingsManager$1(
|
|
468
495
|
{
|
|
469
496
|
pageHorizontalMargin,
|
|
470
497
|
pageVerticalMargin,
|
|
471
|
-
layoutAutoResize
|
|
498
|
+
layoutAutoResize,
|
|
499
|
+
layoutLayerTransition
|
|
472
500
|
},
|
|
473
501
|
reader.settings
|
|
474
502
|
);
|
|
@@ -532,7 +560,9 @@ const layoutEnhancer = (next) => (options) => {
|
|
|
532
560
|
reader.hookManager.register(`item.onDocumentCreated`, ({ layers }) => {
|
|
533
561
|
layers.forEach(({ element }) => {
|
|
534
562
|
element.style.opacity = `0`;
|
|
535
|
-
|
|
563
|
+
if (settingsManager.values.layoutLayerTransition) {
|
|
564
|
+
element.style.transition = `opacity 300ms`;
|
|
565
|
+
}
|
|
536
566
|
});
|
|
537
567
|
});
|
|
538
568
|
reader.hookManager.register(`item.onBeforeLayout`, ({ item }) => {
|
|
@@ -545,11 +575,6 @@ const layoutEnhancer = (next) => (options) => {
|
|
|
545
575
|
});
|
|
546
576
|
const revealItemOnReady$ = reader.spineItemsObserver.itemIsReady$.pipe(
|
|
547
577
|
filter(({ isReady }) => isReady),
|
|
548
|
-
/**
|
|
549
|
-
* Make sure that even if the document was loaded instantly, the layout is applied first
|
|
550
|
-
* and therefore the transition played. eg: pdf are loaded before attached to the dom.
|
|
551
|
-
*/
|
|
552
|
-
delay(1, animationFrameScheduler),
|
|
553
578
|
tap(({ item }) => {
|
|
554
579
|
item.renderer.layers.forEach(({ element }) => {
|
|
555
580
|
element.style.opacity = `1`;
|
|
@@ -585,7 +610,22 @@ const layoutEnhancer = (next) => (options) => {
|
|
|
585
610
|
}),
|
|
586
611
|
takeUntil$1(reader.$.destroy$)
|
|
587
612
|
).subscribe();
|
|
588
|
-
|
|
613
|
+
const updateSpineItemClassName$ = reader.spineItemsObserver.itemIsReady$.pipe(
|
|
614
|
+
tap(({ item, isReady }) => {
|
|
615
|
+
const className = `prose-spineItem-ready`;
|
|
616
|
+
if (isReady) {
|
|
617
|
+
item.containerElement.classList.add(className);
|
|
618
|
+
} else {
|
|
619
|
+
item.containerElement.classList.remove(className);
|
|
620
|
+
}
|
|
621
|
+
})
|
|
622
|
+
);
|
|
623
|
+
merge(
|
|
624
|
+
updateSpineItemClassName$,
|
|
625
|
+
revealItemOnReady$,
|
|
626
|
+
movingSafePan$,
|
|
627
|
+
layoutOnContainerResize$
|
|
628
|
+
).pipe(takeUntil$1(reader.$.destroy$)).subscribe();
|
|
589
629
|
return {
|
|
590
630
|
...reader,
|
|
591
631
|
destroy: () => {
|
|
@@ -1474,17 +1514,116 @@ const trackPaginationInfo = (reader) => {
|
|
|
1474
1514
|
return { paginationInfo$, getPaginationInfo: () => currentValue.value };
|
|
1475
1515
|
};
|
|
1476
1516
|
const NAMESPACE$6 = `paginationEnhancer`;
|
|
1517
|
+
const consolidate = (item, reader) => {
|
|
1518
|
+
var _a;
|
|
1519
|
+
let itemPageIndex = (_a = item.meta) == null ? void 0 : _a.itemPageIndex;
|
|
1520
|
+
const { itemIndex } = reader.cfi.parseCfi(item.cfi);
|
|
1521
|
+
const spineItem = reader.spineItemsManager.get(itemIndex);
|
|
1522
|
+
if (!spineItem) return of({ ...item, meta: { ...item.meta, itemIndex } });
|
|
1523
|
+
if (spineItem.item.renditionLayout === `pre-paginated`) {
|
|
1524
|
+
itemPageIndex = 0;
|
|
1525
|
+
}
|
|
1526
|
+
return idle().pipe(
|
|
1527
|
+
withLatestFrom(spineItem.isReady$),
|
|
1528
|
+
map$1(([, isSpineItemReady]) => {
|
|
1529
|
+
var _a2, _b, _c;
|
|
1530
|
+
let range = void 0;
|
|
1531
|
+
const { node: startNode, offset: startOffset } = reader.cfi.resolveCfi({ cfi: item.cfi }) ?? {};
|
|
1532
|
+
if (spineItem.item.renditionLayout !== `pre-paginated` && startNode) {
|
|
1533
|
+
itemPageIndex = reader.spine.locator.spineItemLocator.getSpineItemPageIndexFromNode(
|
|
1534
|
+
startNode,
|
|
1535
|
+
startOffset ?? 0,
|
|
1536
|
+
spineItem
|
|
1537
|
+
) ?? itemPageIndex;
|
|
1538
|
+
}
|
|
1539
|
+
if (startNode && item.endCfi) {
|
|
1540
|
+
const { node: endNode, offset: endOffset } = reader.cfi.resolveCfi({ cfi: item.cfi }) ?? {};
|
|
1541
|
+
if (endNode && isSpineItemReady) {
|
|
1542
|
+
range = (_a2 = startNode == null ? void 0 : startNode.ownerDocument) == null ? void 0 : _a2.createRange();
|
|
1543
|
+
range == null ? void 0 : range.setStart(startNode, startOffset ?? 0);
|
|
1544
|
+
range == null ? void 0 : range.setEnd(endNode, endOffset ?? 0);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
let absolutePageIndex = (_b = item.meta) == null ? void 0 : _b.absolutePageIndex;
|
|
1548
|
+
if (itemPageIndex !== void 0) {
|
|
1549
|
+
absolutePageIndex = reader.spine.locator.getAbsolutePageIndexFromPageIndex({
|
|
1550
|
+
pageIndex: itemPageIndex,
|
|
1551
|
+
spineItemOrId: spineItem
|
|
1552
|
+
}) ?? ((_c = item.meta) == null ? void 0 : _c.absolutePageIndex);
|
|
1553
|
+
}
|
|
1554
|
+
return {
|
|
1555
|
+
...item,
|
|
1556
|
+
meta: {
|
|
1557
|
+
...item.meta,
|
|
1558
|
+
range,
|
|
1559
|
+
itemIndex,
|
|
1560
|
+
startNode,
|
|
1561
|
+
startOffset,
|
|
1562
|
+
absolutePageIndex,
|
|
1563
|
+
itemPageIndex
|
|
1564
|
+
}
|
|
1565
|
+
};
|
|
1566
|
+
})
|
|
1567
|
+
);
|
|
1568
|
+
};
|
|
1569
|
+
const createLocator = (reader) => (resources) => {
|
|
1570
|
+
return deferIdle(() => {
|
|
1571
|
+
if (!resources.length)
|
|
1572
|
+
return of({ isStale: false, data: resources });
|
|
1573
|
+
const StaleSymbol = Symbol("stale");
|
|
1574
|
+
const markStale$ = reader.layout$.pipe(
|
|
1575
|
+
startWith$1(null),
|
|
1576
|
+
map$1(() => StaleSymbol)
|
|
1577
|
+
);
|
|
1578
|
+
const consolidate$ = reader.layout$.pipe(
|
|
1579
|
+
debounceTime$1(10),
|
|
1580
|
+
startWith$1(null),
|
|
1581
|
+
switchScan((acc$) => {
|
|
1582
|
+
return forkJoin(
|
|
1583
|
+
acc$.map(
|
|
1584
|
+
(resource) => deferIdle(() => consolidate(resource, reader)).pipe(
|
|
1585
|
+
map$1((value) => value)
|
|
1586
|
+
)
|
|
1587
|
+
)
|
|
1588
|
+
);
|
|
1589
|
+
}, resources)
|
|
1590
|
+
);
|
|
1591
|
+
const run$ = merge(markStale$, consolidate$).pipe(
|
|
1592
|
+
scan(
|
|
1593
|
+
(acc, value) => {
|
|
1594
|
+
if (value === StaleSymbol) {
|
|
1595
|
+
return {
|
|
1596
|
+
...acc,
|
|
1597
|
+
isStale: true
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
1600
|
+
return {
|
|
1601
|
+
isStale: false,
|
|
1602
|
+
data: value
|
|
1603
|
+
};
|
|
1604
|
+
},
|
|
1605
|
+
{
|
|
1606
|
+
isStale: true,
|
|
1607
|
+
data: resources
|
|
1608
|
+
}
|
|
1609
|
+
)
|
|
1610
|
+
);
|
|
1611
|
+
return run$;
|
|
1612
|
+
});
|
|
1613
|
+
};
|
|
1477
1614
|
Report.namespace(NAMESPACE$6);
|
|
1478
1615
|
const paginationEnhancer = (next) => (options) => {
|
|
1479
1616
|
const reader = next(options);
|
|
1480
1617
|
const { paginationInfo$, getPaginationInfo } = trackPaginationInfo(reader);
|
|
1481
1618
|
paginationInfo$.pipe(takeUntil(reader.$.destroy$)).subscribe();
|
|
1619
|
+
const locate = createLocator(reader);
|
|
1482
1620
|
return {
|
|
1483
1621
|
...reader,
|
|
1484
1622
|
pagination: {
|
|
1485
1623
|
...reader.pagination,
|
|
1486
1624
|
getState: () => getPaginationInfo(),
|
|
1487
|
-
state$: paginationInfo
|
|
1625
|
+
state$: paginationInfo$,
|
|
1626
|
+
locate
|
|
1488
1627
|
}
|
|
1489
1628
|
};
|
|
1490
1629
|
};
|
|
@@ -3753,7 +3892,7 @@ class ViewportNavigator extends DestroyableClass {
|
|
|
3753
3892
|
* anything for x ms while we effectively adjust. We want it to be immediate.
|
|
3754
3893
|
* However when user is repeatedly turning page, we can improve smoothness by delaying a bit the adjustment
|
|
3755
3894
|
*/
|
|
3756
|
-
currentEvent.shouldAnimate ? delay
|
|
3895
|
+
currentEvent.shouldAnimate ? delay(1, animationFrameScheduler) : identity,
|
|
3757
3896
|
tap$1((data) => {
|
|
3758
3897
|
const element2 = this.viewportElement$.getValue();
|
|
3759
3898
|
const noAdjustmentNeeded = false;
|
|
@@ -3789,7 +3928,7 @@ class ViewportNavigator extends DestroyableClass {
|
|
|
3789
3928
|
this.setViewportPosition(data.position);
|
|
3790
3929
|
}
|
|
3791
3930
|
}),
|
|
3792
|
-
currentEvent.shouldAnimate ? delay
|
|
3931
|
+
currentEvent.shouldAnimate ? delay(animationDuration / 2, animationFrameScheduler) : identity,
|
|
3793
3932
|
tap$1((data) => {
|
|
3794
3933
|
const element2 = this.viewportElement$.getValue();
|
|
3795
3934
|
if (pageTurnAnimation === `fade`) {
|
|
@@ -3797,7 +3936,7 @@ class ViewportNavigator extends DestroyableClass {
|
|
|
3797
3936
|
element2.style.setProperty(`opacity`, `1`);
|
|
3798
3937
|
}
|
|
3799
3938
|
}),
|
|
3800
|
-
currentEvent.shouldAnimate ? delay
|
|
3939
|
+
currentEvent.shouldAnimate ? delay(animationDuration / 2, animationFrameScheduler) : identity,
|
|
3801
3940
|
tap$1((data) => {
|
|
3802
3941
|
if (pageTurnAnimation === `fade`) {
|
|
3803
3942
|
this.setViewportPosition(data.position);
|
|
@@ -4382,19 +4521,6 @@ const withUrlInfo = ({ navigationResolver }) => (stream) => {
|
|
|
4382
4521
|
})
|
|
4383
4522
|
);
|
|
4384
4523
|
};
|
|
4385
|
-
const withPaginationInfo = () => (stream) => {
|
|
4386
|
-
return stream.pipe(
|
|
4387
|
-
map$1(({ navigation, pagination, ...rest }) => {
|
|
4388
|
-
return {
|
|
4389
|
-
navigation: {
|
|
4390
|
-
...navigation,
|
|
4391
|
-
paginationBeginCfi: pagination.beginCfi
|
|
4392
|
-
},
|
|
4393
|
-
...rest
|
|
4394
|
-
};
|
|
4395
|
-
})
|
|
4396
|
-
);
|
|
4397
|
-
};
|
|
4398
4524
|
const withCfiPosition = ({ navigationResolver }) => (stream) => {
|
|
4399
4525
|
return stream.pipe(
|
|
4400
4526
|
map$1((params) => {
|
|
@@ -4490,6 +4616,52 @@ const withSpineItem = ({
|
|
|
4490
4616
|
})
|
|
4491
4617
|
);
|
|
4492
4618
|
};
|
|
4619
|
+
const withPaginationInfo = () => (stream) => {
|
|
4620
|
+
return stream.pipe(
|
|
4621
|
+
map$1(({ navigation, pagination, ...rest }) => {
|
|
4622
|
+
return {
|
|
4623
|
+
navigation: {
|
|
4624
|
+
...navigation,
|
|
4625
|
+
paginationBeginCfi: pagination.beginCfi
|
|
4626
|
+
},
|
|
4627
|
+
...rest
|
|
4628
|
+
};
|
|
4629
|
+
})
|
|
4630
|
+
);
|
|
4631
|
+
};
|
|
4632
|
+
const consolidateWithPagination = (context, navigation$, spine) => context.bridgeEvent.pagination$.pipe(
|
|
4633
|
+
withLatestFrom(navigation$),
|
|
4634
|
+
filter$1(
|
|
4635
|
+
([pagination, navigation]) => pagination.navigationId === navigation.id
|
|
4636
|
+
),
|
|
4637
|
+
/**
|
|
4638
|
+
* We only register the pagination cfi IF the spine item is ready.
|
|
4639
|
+
* Otherwise we might save something incomplete and thus restore
|
|
4640
|
+
* the user to an invalid location.
|
|
4641
|
+
*/
|
|
4642
|
+
switchMap(([pagination, navigation]) => {
|
|
4643
|
+
const spineItem = spine.spineItemsManager.get(navigation.spineItem);
|
|
4644
|
+
return ((spineItem == null ? void 0 : spineItem.isReady$.pipe(first$1())) ?? of(false)).pipe(
|
|
4645
|
+
filter$1((isReady) => isReady),
|
|
4646
|
+
map$1(() => ({
|
|
4647
|
+
pagination,
|
|
4648
|
+
navigation
|
|
4649
|
+
}))
|
|
4650
|
+
);
|
|
4651
|
+
}),
|
|
4652
|
+
withPaginationInfo(),
|
|
4653
|
+
distinctUntilChanged$1(
|
|
4654
|
+
(prev, curr) => prev.navigation.paginationBeginCfi === curr.navigation.paginationBeginCfi
|
|
4655
|
+
),
|
|
4656
|
+
map$1(
|
|
4657
|
+
({ navigation }) => ({
|
|
4658
|
+
...navigation,
|
|
4659
|
+
meta: {
|
|
4660
|
+
triggeredBy: "pagination"
|
|
4661
|
+
}
|
|
4662
|
+
})
|
|
4663
|
+
)
|
|
4664
|
+
);
|
|
4493
4665
|
const NAMESPACE$1 = `navigation/InternalNavigator`;
|
|
4494
4666
|
const report = Report.namespace(NAMESPACE$1);
|
|
4495
4667
|
class InternalNavigator extends DestroyableClass {
|
|
@@ -4613,7 +4785,12 @@ class InternalNavigator extends DestroyableClass {
|
|
|
4613
4785
|
const navigationUpateFromLayout$ = layoutHasChanged$.pipe(
|
|
4614
4786
|
switchMap(() => {
|
|
4615
4787
|
return of(null).pipe(
|
|
4616
|
-
switchMap(
|
|
4788
|
+
switchMap(
|
|
4789
|
+
() => isUserLocked$.pipe(
|
|
4790
|
+
filter$1((isLocked) => !isLocked),
|
|
4791
|
+
first$1()
|
|
4792
|
+
)
|
|
4793
|
+
),
|
|
4617
4794
|
map$1(
|
|
4618
4795
|
() => ({
|
|
4619
4796
|
...this.navigationSubject.getValue(),
|
|
@@ -4678,29 +4855,10 @@ class InternalNavigator extends DestroyableClass {
|
|
|
4678
4855
|
map$1(({ navigation }) => navigation),
|
|
4679
4856
|
share()
|
|
4680
4857
|
);
|
|
4681
|
-
const navigationUpdateOnPaginationUpdate$ =
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
),
|
|
4686
|
-
map$1(([pagination, navigation]) => ({
|
|
4687
|
-
pagination,
|
|
4688
|
-
navigation: {
|
|
4689
|
-
...navigation
|
|
4690
|
-
}
|
|
4691
|
-
})),
|
|
4692
|
-
withPaginationInfo(),
|
|
4693
|
-
distinctUntilChanged$1(
|
|
4694
|
-
(prev, curr) => prev.navigation.paginationBeginCfi === curr.navigation.paginationBeginCfi
|
|
4695
|
-
),
|
|
4696
|
-
map$1(
|
|
4697
|
-
({ navigation }) => ({
|
|
4698
|
-
...navigation,
|
|
4699
|
-
meta: {
|
|
4700
|
-
triggeredBy: "pagination"
|
|
4701
|
-
}
|
|
4702
|
-
})
|
|
4703
|
-
)
|
|
4858
|
+
const navigationUpdateOnPaginationUpdate$ = consolidateWithPagination(
|
|
4859
|
+
context,
|
|
4860
|
+
this.navigationSubject,
|
|
4861
|
+
spine
|
|
4704
4862
|
);
|
|
4705
4863
|
const navigationUpdate$ = merge(
|
|
4706
4864
|
navigationRestored$,
|
|
@@ -5173,9 +5331,7 @@ class PaginationController extends DestroyableClass {
|
|
|
5173
5331
|
})
|
|
5174
5332
|
);
|
|
5175
5333
|
const updateCfi$ = updatePagination$.pipe(
|
|
5176
|
-
|
|
5177
|
-
filter$1((state) => state === "free"),
|
|
5178
|
-
switchMap(() => timer(500, animationFrameScheduler)),
|
|
5334
|
+
waitForSwitch(this.context.bridgeEvent.viewportFree$),
|
|
5179
5335
|
tap$1(() => {
|
|
5180
5336
|
const {
|
|
5181
5337
|
beginSpineItemIndex,
|
|
@@ -5205,14 +5361,9 @@ class PaginationController extends DestroyableClass {
|
|
|
5205
5361
|
merge(updatePagination$, updateCfi$).pipe(takeUntil(this.destroy$)).subscribe();
|
|
5206
5362
|
}
|
|
5207
5363
|
}
|
|
5208
|
-
const generateCfiFromRange = ({
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
end,
|
|
5212
|
-
endNode
|
|
5213
|
-
}, item) => {
|
|
5214
|
-
const startCFI = generateCfi(startNode, start, item);
|
|
5215
|
-
const endCFI = generateCfi(endNode, end, item);
|
|
5364
|
+
const generateCfiFromRange = (range, item) => {
|
|
5365
|
+
const startCFI = generateCfi(range.startContainer, range.startOffset, item);
|
|
5366
|
+
const endCFI = generateCfi(range.endContainer, range.endOffset, item);
|
|
5216
5367
|
return { start: startCFI, end: endCFI };
|
|
5217
5368
|
};
|
|
5218
5369
|
const defaultGetResource = (item) => new URL(item.href);
|
|
@@ -5342,6 +5493,29 @@ class DocumentRenderer extends DestroyableClass {
|
|
|
5342
5493
|
unload() {
|
|
5343
5494
|
this.triggerSubject.next({ type: `unload` });
|
|
5344
5495
|
}
|
|
5496
|
+
renderHeadless() {
|
|
5497
|
+
const releaseSubject = new Subject();
|
|
5498
|
+
return defer(() => this.onRenderHeadless({ release: releaseSubject })).pipe(
|
|
5499
|
+
endWith(void 0),
|
|
5500
|
+
first$1(),
|
|
5501
|
+
map$1((doc) => {
|
|
5502
|
+
if (!doc) return void 0;
|
|
5503
|
+
return {
|
|
5504
|
+
doc,
|
|
5505
|
+
release: () => {
|
|
5506
|
+
releaseSubject.next(void 0);
|
|
5507
|
+
}
|
|
5508
|
+
};
|
|
5509
|
+
}),
|
|
5510
|
+
finalize(() => {
|
|
5511
|
+
releaseSubject.complete();
|
|
5512
|
+
}),
|
|
5513
|
+
catchError((e) => {
|
|
5514
|
+
Report.error(e);
|
|
5515
|
+
return of(void 0);
|
|
5516
|
+
})
|
|
5517
|
+
);
|
|
5518
|
+
}
|
|
5345
5519
|
destroy() {
|
|
5346
5520
|
super.destroy();
|
|
5347
5521
|
this.stateSubject.complete();
|
|
@@ -5366,6 +5540,9 @@ class DefaultRenderer extends DocumentRenderer {
|
|
|
5366
5540
|
onLayout() {
|
|
5367
5541
|
return of(void 0);
|
|
5368
5542
|
}
|
|
5543
|
+
onRenderHeadless() {
|
|
5544
|
+
return EMPTY;
|
|
5545
|
+
}
|
|
5369
5546
|
}
|
|
5370
5547
|
class SpineItem extends DestroyableClass {
|
|
5371
5548
|
constructor(item, parentElement, context, settings, hookManager, index) {
|
|
@@ -5497,20 +5674,29 @@ class SpineItem extends DestroyableClass {
|
|
|
5497
5674
|
}),
|
|
5498
5675
|
share$1()
|
|
5499
5676
|
);
|
|
5500
|
-
this.layout$ = layoutProcess$.pipe(
|
|
5501
|
-
filter((event) => event.type === `end`),
|
|
5502
|
-
map((event) => event.data),
|
|
5503
|
-
share$1()
|
|
5504
|
-
);
|
|
5505
5677
|
this.isReady$ = layoutProcess$.pipe(
|
|
5506
5678
|
withLatestFrom$1(this.renderer.isLoaded$),
|
|
5507
5679
|
map(([event, loaded]) => !!(event.type === `end` && loaded)),
|
|
5508
5680
|
startWith(false),
|
|
5509
5681
|
distinctUntilChanged(),
|
|
5510
|
-
shareReplay({ refCount: true })
|
|
5682
|
+
shareReplay({ refCount: true, bufferSize: 1 })
|
|
5683
|
+
);
|
|
5684
|
+
this.layout$ = layoutProcess$.pipe(
|
|
5685
|
+
filter((event) => event.type === `end`),
|
|
5686
|
+
map((event) => event.data),
|
|
5687
|
+
share$1()
|
|
5511
5688
|
);
|
|
5512
5689
|
this.needsLayout$ = merge(this.unloaded$, this.loaded$);
|
|
5513
|
-
merge(
|
|
5690
|
+
merge(
|
|
5691
|
+
/**
|
|
5692
|
+
* @important
|
|
5693
|
+
* The order is important here. We want to ensure the isReady value
|
|
5694
|
+
* is set before dispatching the layout event. Elements reacting
|
|
5695
|
+
* to layout changes may rely on the isReady value.
|
|
5696
|
+
*/
|
|
5697
|
+
this.isReady$,
|
|
5698
|
+
this.layout$
|
|
5699
|
+
).pipe(takeUntil$1(this.destroy$)).subscribe();
|
|
5514
5700
|
}
|
|
5515
5701
|
get element() {
|
|
5516
5702
|
return this.containerElement;
|
|
@@ -6359,7 +6545,9 @@ class SpineLayout extends DestroyableClass {
|
|
|
6359
6545
|
}),
|
|
6360
6546
|
share()
|
|
6361
6547
|
);
|
|
6362
|
-
this.info$ = this.layout$.pipe(
|
|
6548
|
+
this.info$ = this.layout$.pipe(
|
|
6549
|
+
shareReplay$1({ refCount: true, bufferSize: 1 })
|
|
6550
|
+
);
|
|
6363
6551
|
merge(this.layout$, this.info$).pipe(takeUntil(this.destroy$)).subscribe();
|
|
6364
6552
|
}
|
|
6365
6553
|
layout() {
|
|
@@ -6835,7 +7023,7 @@ const createResourcesManager = (context) => {
|
|
|
6835
7023
|
switchMap$1(([db, blob]) => {
|
|
6836
7024
|
return from(db.put(`${uniqueID}_${item.id}`, blob));
|
|
6837
7025
|
}),
|
|
6838
|
-
catchError((error) => {
|
|
7026
|
+
catchError$1((error) => {
|
|
6839
7027
|
Report.error(error);
|
|
6840
7028
|
return EMPTY;
|
|
6841
7029
|
})
|
|
@@ -6863,7 +7051,7 @@ const createResourcesManager = (context) => {
|
|
|
6863
7051
|
})
|
|
6864
7052
|
)
|
|
6865
7053
|
),
|
|
6866
|
-
catchError((error) => {
|
|
7054
|
+
catchError$1((error) => {
|
|
6867
7055
|
Report.error(error);
|
|
6868
7056
|
return EMPTY;
|
|
6869
7057
|
})
|
|
@@ -6971,6 +7159,9 @@ class ImageRenderer extends DocumentRenderer {
|
|
|
6971
7159
|
height
|
|
6972
7160
|
});
|
|
6973
7161
|
}
|
|
7162
|
+
onRenderHeadless() {
|
|
7163
|
+
return EMPTY;
|
|
7164
|
+
}
|
|
6974
7165
|
}
|
|
6975
7166
|
const mediaEnhancer = (next) => (options) => {
|
|
6976
7167
|
const reader = next({
|
|
@@ -7209,6 +7400,7 @@ const createLoadingElementContainer = (containerElement, context) => {
|
|
|
7209
7400
|
top: 0;
|
|
7210
7401
|
color: rgb(202, 202, 202);
|
|
7211
7402
|
background-color: white;
|
|
7403
|
+
z-index: 1;
|
|
7212
7404
|
`;
|
|
7213
7405
|
return loadingElement;
|
|
7214
7406
|
};
|
|
@@ -7277,11 +7469,15 @@ const loadingEnhancer = (next) => (options) => {
|
|
|
7277
7469
|
);
|
|
7278
7470
|
const updateEntriesVisibility$ = (entries) => reader.spineItemsObserver.itemIsReady$.pipe(
|
|
7279
7471
|
tap(({ item, isReady }) => {
|
|
7280
|
-
var _a;
|
|
7472
|
+
var _a, _b;
|
|
7281
7473
|
(_a = entries[item.item.id]) == null ? void 0 : _a.style.setProperty(
|
|
7282
7474
|
`visibility`,
|
|
7283
7475
|
isReady ? `hidden` : `visible`
|
|
7284
7476
|
);
|
|
7477
|
+
(_b = entries[item.item.id]) == null ? void 0 : _b.style.setProperty(
|
|
7478
|
+
`z-index`,
|
|
7479
|
+
isReady ? `0` : `1`
|
|
7480
|
+
);
|
|
7285
7481
|
})
|
|
7286
7482
|
);
|
|
7287
7483
|
const loadingItems$ = reader.spineItemsManager.items$.pipe(
|
|
@@ -7574,7 +7770,7 @@ const attachFrameSrc = ({
|
|
|
7574
7770
|
}
|
|
7575
7771
|
}),
|
|
7576
7772
|
map$1(() => frameElement),
|
|
7577
|
-
catchError
|
|
7773
|
+
catchError((e) => {
|
|
7578
7774
|
Report.error(
|
|
7579
7775
|
`Error while trying to fetch or load resource for item ${item.id}`
|
|
7580
7776
|
);
|
|
@@ -7997,8 +8193,6 @@ const renderReflowable = ({
|
|
|
7997
8193
|
if ((frameElement == null ? void 0 : frameElement.contentDocument) && (frameElement == null ? void 0 : frameElement.contentWindow)) {
|
|
7998
8194
|
let contentWidth = pageWidth;
|
|
7999
8195
|
let contentHeight = pageHeight;
|
|
8000
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`visibility`, `visible`);
|
|
8001
|
-
frameElement == null ? void 0 : frameElement.style.setProperty(`opacity`, `1`);
|
|
8002
8196
|
if (viewportDimensions == null ? void 0 : viewportDimensions.hasViewport) {
|
|
8003
8197
|
upsertCSS(
|
|
8004
8198
|
frameElement,
|
|
@@ -8094,6 +8288,51 @@ const renderReflowable = ({
|
|
|
8094
8288
|
latestContentHeightWhenLoaded: newLatestContentHeightWhenLoaded
|
|
8095
8289
|
};
|
|
8096
8290
|
};
|
|
8291
|
+
const loadMedias = ({
|
|
8292
|
+
settings,
|
|
8293
|
+
item,
|
|
8294
|
+
context
|
|
8295
|
+
}) => (stream) => stream.pipe(
|
|
8296
|
+
switchMap((frameElement) => {
|
|
8297
|
+
var _a;
|
|
8298
|
+
const images = ((_a = frameElement.contentDocument) == null ? void 0 : _a.getElementsByTagName("img")) || [];
|
|
8299
|
+
const imageObservables = Array.from(images).map((img) => {
|
|
8300
|
+
var _a2;
|
|
8301
|
+
const originalSrc = img.getAttribute("src");
|
|
8302
|
+
const spineItemUriParentPath = getParentPath(item.href);
|
|
8303
|
+
const foundItem = (_a2 = context.manifest) == null ? void 0 : _a2.items.find(({ href }) => {
|
|
8304
|
+
return `${spineItemUriParentPath}/${originalSrc}`.endsWith(
|
|
8305
|
+
`${href}`
|
|
8306
|
+
);
|
|
8307
|
+
});
|
|
8308
|
+
if (!foundItem) return of(null);
|
|
8309
|
+
const resourceHandler = new ResourceHandler(foundItem, settings);
|
|
8310
|
+
return from(resourceHandler.getResource()).pipe(
|
|
8311
|
+
mergeMap(
|
|
8312
|
+
(resource) => resource instanceof Response ? from(resource.blob()) : of(void 0)
|
|
8313
|
+
),
|
|
8314
|
+
tap$1((blob) => {
|
|
8315
|
+
if (blob) {
|
|
8316
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
8317
|
+
img.src = blobUrl;
|
|
8318
|
+
}
|
|
8319
|
+
})
|
|
8320
|
+
);
|
|
8321
|
+
});
|
|
8322
|
+
return combineLatest(imageObservables).pipe(map$1(() => frameElement));
|
|
8323
|
+
})
|
|
8324
|
+
);
|
|
8325
|
+
const unloadMedias = (frameElement) => {
|
|
8326
|
+
var _a;
|
|
8327
|
+
const images = Array.from(
|
|
8328
|
+
((_a = frameElement == null ? void 0 : frameElement.contentDocument) == null ? void 0 : _a.getElementsByTagName("img")) || []
|
|
8329
|
+
);
|
|
8330
|
+
images.forEach((img) => {
|
|
8331
|
+
if (img.src.startsWith("blob:")) {
|
|
8332
|
+
URL.revokeObjectURL(img.src);
|
|
8333
|
+
}
|
|
8334
|
+
});
|
|
8335
|
+
};
|
|
8097
8336
|
class HtmlRenderer extends DocumentRenderer {
|
|
8098
8337
|
constructor() {
|
|
8099
8338
|
super(...arguments);
|
|
@@ -8125,10 +8364,16 @@ class HtmlRenderer extends DocumentRenderer {
|
|
|
8125
8364
|
this.containerElement.appendChild(frameElement2);
|
|
8126
8365
|
}),
|
|
8127
8366
|
waitForFrameLoad,
|
|
8367
|
+
loadMedias({
|
|
8368
|
+
context: this.context,
|
|
8369
|
+
item: this.item,
|
|
8370
|
+
settings: this.settings
|
|
8371
|
+
}),
|
|
8128
8372
|
waitForFrameReady
|
|
8129
8373
|
);
|
|
8130
8374
|
}
|
|
8131
8375
|
onUnload() {
|
|
8376
|
+
unloadMedias(this.getFrameElement());
|
|
8132
8377
|
this.layers.forEach((layer) => layer.element.remove());
|
|
8133
8378
|
this.layers = [];
|
|
8134
8379
|
return EMPTY;
|
|
@@ -8172,6 +8417,34 @@ class HtmlRenderer extends DocumentRenderer {
|
|
|
8172
8417
|
this.latestContentHeightWhenLoaded = latestContentHeightWhenLoaded;
|
|
8173
8418
|
return of(rest);
|
|
8174
8419
|
}
|
|
8420
|
+
onRenderHeadless() {
|
|
8421
|
+
return from(this.resourcesHandler.fetchResource()).pipe(
|
|
8422
|
+
switchMap((resource) => {
|
|
8423
|
+
if (resource instanceof Response) {
|
|
8424
|
+
const contentType = resource.headers.get("content-type") ?? "";
|
|
8425
|
+
const parsableContentTypes = [
|
|
8426
|
+
`application/xhtml+xml`,
|
|
8427
|
+
`application/xml`,
|
|
8428
|
+
`text/html`,
|
|
8429
|
+
`text/xml`
|
|
8430
|
+
];
|
|
8431
|
+
if (parsableContentTypes.includes(contentType)) {
|
|
8432
|
+
return from(resource.text()).pipe(
|
|
8433
|
+
map$1((text) => {
|
|
8434
|
+
const domParser = new DOMParser();
|
|
8435
|
+
const doc = domParser.parseFromString(
|
|
8436
|
+
text,
|
|
8437
|
+
contentType
|
|
8438
|
+
);
|
|
8439
|
+
return doc;
|
|
8440
|
+
})
|
|
8441
|
+
);
|
|
8442
|
+
}
|
|
8443
|
+
}
|
|
8444
|
+
return of(void 0);
|
|
8445
|
+
})
|
|
8446
|
+
);
|
|
8447
|
+
}
|
|
8175
8448
|
getFrameElement() {
|
|
8176
8449
|
var _a;
|
|
8177
8450
|
const frame = (_a = this.layers[0]) == null ? void 0 : _a.element;
|
|
@@ -8248,7 +8521,7 @@ const getRangeFromSelection = (anchor, focus) => {
|
|
|
8248
8521
|
}
|
|
8249
8522
|
return range;
|
|
8250
8523
|
};
|
|
8251
|
-
const
|
|
8524
|
+
const createOrderedRangeFromSelection = ({
|
|
8252
8525
|
selection,
|
|
8253
8526
|
spineItem
|
|
8254
8527
|
}) => {
|
|
@@ -8280,7 +8553,7 @@ class SelectionTracker extends DestroyableClass {
|
|
|
8280
8553
|
* The selection is still valid during the event even if it will
|
|
8281
8554
|
* be discarded. The timeout make sure to detect this edge case.
|
|
8282
8555
|
*/
|
|
8283
|
-
delay
|
|
8556
|
+
delay(0),
|
|
8284
8557
|
map$1((event) => {
|
|
8285
8558
|
const selection = document2.getSelection();
|
|
8286
8559
|
return selection && !selection.isCollapsed ? [event, selection] : void 0;
|
|
@@ -8374,7 +8647,7 @@ const selectionEnhancer = (next) => (options) => {
|
|
|
8374
8647
|
selectionAfterPointerUp$,
|
|
8375
8648
|
lastSelectionOnPointerdown$,
|
|
8376
8649
|
getSelection: () => selectionSubject.getValue(),
|
|
8377
|
-
|
|
8650
|
+
createOrderedRangeFromSelection
|
|
8378
8651
|
},
|
|
8379
8652
|
destroy: () => {
|
|
8380
8653
|
selectionSubject.complete();
|
|
@@ -8434,11 +8707,16 @@ export {
|
|
|
8434
8707
|
SettingsManager3 as SettingsManager,
|
|
8435
8708
|
SpineItem,
|
|
8436
8709
|
createReaderWithEnhancers as createReader,
|
|
8710
|
+
deferIdle,
|
|
8711
|
+
deferNextResult,
|
|
8437
8712
|
getAttributeValueFromString,
|
|
8438
8713
|
getFrameViewportInfo,
|
|
8714
|
+
idle,
|
|
8439
8715
|
injectCSS,
|
|
8440
8716
|
isHtmlElement,
|
|
8441
8717
|
isShallowEqual2 as isShallowEqual,
|
|
8718
|
+
mapKeysTo,
|
|
8719
|
+
observeResize,
|
|
8442
8720
|
removeCSS,
|
|
8443
8721
|
upsertCSS,
|
|
8444
8722
|
waitForFrameLoad,
|