@prose-reader/core 1.191.0 → 1.193.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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { switchMap, of, fromEvent, take, map, from, takeUntil, Observable, defer, Subject, combineLatest, merge, EMPTY, withLatestFrom, BehaviorSubject, filter, share, first as first$1, mergeMap, endWith, tap as tap$1, finalize, catchError, lastValueFrom, NEVER, scheduled, animationFrameScheduler, distinctUntilChanged as distinctUntilChanged$1, throttleTime, debounceTime as debounceTime$1, startWith as startWith$1, switchScan, forkJoin, shareReplay as shareReplay$1, delay, ReplaySubject, identity, timer, skip as skip$1, exhaustMap, reduce, concatMap } from "rxjs";
2
- import { switchMap as switchMap$1, first, map as map$1, startWith, shareReplay, distinctUntilChanged, tap, pairwise, take as take$1, takeUntil as takeUntil$1, filter as filter$1, debounceTime, skip, mergeMap as mergeMap$1, catchError as catchError$1, withLatestFrom as withLatestFrom$1, share as share$1 } from "rxjs/operators";
2
+ import { switchMap as switchMap$1, first, map as map$1, startWith, shareReplay, distinctUntilChanged, tap, pairwise, take as take$1, takeUntil as takeUntil$1, filter as filter$1, debounceTime, skip, mergeMap as mergeMap$1, catchError as catchError$1, withLatestFrom as withLatestFrom$1 } from "rxjs/operators";
3
3
  import { shallowMergeIfDefined, isShallowEqual, getParentPath, parseContentType, detectMimeTypeFromName, arrayEqual } from "@prose-reader/shared";
4
4
  import { isShallowEqual as isShallowEqual2 } from "@prose-reader/shared";
5
5
  const getAttributeValueFromString = (string, key) => {
@@ -902,7 +902,6 @@ class DocumentRenderer extends DestroyableClass {
902
902
  constructor(params) {
903
903
  super();
904
904
  this.triggerSubject = new Subject();
905
- this.lastLayoutDims = void 0;
906
905
  this.stateSubject = new BehaviorSubject(`idle`);
907
906
  this.unload$ = this.triggerSubject.pipe(
908
907
  withLatestFrom(this.stateSubject),
@@ -1034,48 +1033,8 @@ class DocumentRenderer extends DestroyableClass {
1034
1033
  })
1035
1034
  );
1036
1035
  }
1037
- /**
1038
- * @important
1039
- *
1040
- * If renderer returns undefined as dimensions we will use the previous
1041
- * layout dimensions as fallback. This ensure minmum layout shift during
1042
- * load / unload of items and improve stability..
1043
- */
1044
1036
  layout(params) {
1045
- return defer(() => this.onLayout(params)).pipe(
1046
- map((dims) => {
1047
- var _a, _b;
1048
- const { height: defaultHeight, width: defaultWidth } = this.context.getPageSize();
1049
- if (dims) {
1050
- const { height, width } = dims;
1051
- if (height < defaultHeight || width < defaultWidth) {
1052
- Report.warn(
1053
- `Your height or width is smaller than the page size. Please check your rendering.`
1054
- );
1055
- }
1056
- this.lastLayoutDims = { height, width };
1057
- return this.lastLayoutDims;
1058
- }
1059
- if (this.renditionLayout === `pre-paginated`) {
1060
- this.lastLayoutDims = {
1061
- height: this.context.getPageSize().height,
1062
- width: params.minimumWidth
1063
- };
1064
- } else {
1065
- this.lastLayoutDims = {
1066
- height: Math.max(
1067
- defaultHeight,
1068
- ((_a = this.lastLayoutDims) == null ? void 0 : _a.height) ?? defaultHeight
1069
- ),
1070
- width: Math.max(
1071
- defaultWidth,
1072
- ((_b = this.lastLayoutDims) == null ? void 0 : _b.width) ?? defaultWidth
1073
- )
1074
- };
1075
- }
1076
- return this.lastLayoutDims;
1077
- })
1078
- );
1037
+ return defer(() => this.onLayout(params)).pipe();
1079
1038
  }
1080
1039
  destroy() {
1081
1040
  super.destroy();
@@ -8380,6 +8339,125 @@ class SpineLayout extends DestroyableClass {
8380
8339
  this.layoutSubject.complete();
8381
8340
  }
8382
8341
  }
8342
+ class SpineItemLayout extends DestroyableClass {
8343
+ constructor(item, containerElement, context, hookManager, renderer) {
8344
+ super();
8345
+ this.item = item;
8346
+ this.containerElement = containerElement;
8347
+ this.context = context;
8348
+ this.hookManager = hookManager;
8349
+ this.renderer = renderer;
8350
+ this.layoutTriggerSubject = new Subject();
8351
+ this.lastLayout = null;
8352
+ this.applyDimsAfterLayout = ({
8353
+ blankPagePosition,
8354
+ minimumWidth
8355
+ }) => (stream) => {
8356
+ return stream.pipe(
8357
+ map((dims) => {
8358
+ var _a;
8359
+ const trustableLastLayout = isShallowEqual(
8360
+ (_a = this.lastLayout) == null ? void 0 : _a.pageSize,
8361
+ this.context.getPageSize()
8362
+ ) ? this.lastLayout : void 0;
8363
+ const { width: previousWidth, height: previousHeight } = trustableLastLayout ?? {};
8364
+ const { width = previousWidth, height = previousHeight } = dims ?? {};
8365
+ const { width: pageSizeWidth, height: pageSizeHeight } = this.context.getPageSize();
8366
+ const safeWidth = this.validateDimension(
8367
+ width ?? pageSizeWidth,
8368
+ pageSizeWidth,
8369
+ minimumWidth
8370
+ );
8371
+ const safeHeight = this.validateDimension(
8372
+ height ?? pageSizeHeight,
8373
+ pageSizeHeight,
8374
+ pageSizeHeight
8375
+ );
8376
+ this.lastLayout = {
8377
+ width: safeWidth,
8378
+ height: safeHeight,
8379
+ pageSize: this.context.getPageSize()
8380
+ };
8381
+ this.containerElement.style.width = `${safeWidth}px`;
8382
+ this.containerElement.style.height = `${safeHeight}px`;
8383
+ this.hookManager.execute(`item.onAfterLayout`, void 0, {
8384
+ blankPagePosition,
8385
+ item: this.item,
8386
+ minimumWidth
8387
+ });
8388
+ return { width: safeWidth, height: safeHeight };
8389
+ })
8390
+ );
8391
+ };
8392
+ this.layout = (params) => {
8393
+ const nextResult = deferNextResult(this.layout$.pipe(first$1()));
8394
+ this.layoutTriggerSubject.next(params);
8395
+ return nextResult();
8396
+ };
8397
+ this.adjustPositionOfElement = ({
8398
+ right,
8399
+ left,
8400
+ top
8401
+ }) => {
8402
+ if (right !== void 0) {
8403
+ this.containerElement.style.right = `${right}px`;
8404
+ } else {
8405
+ this.containerElement.style.removeProperty(`right`);
8406
+ }
8407
+ if (left !== void 0) {
8408
+ this.containerElement.style.left = `${left}px`;
8409
+ } else {
8410
+ this.containerElement.style.removeProperty(`left`);
8411
+ }
8412
+ if (top !== void 0) {
8413
+ this.containerElement.style.top = `${top}px`;
8414
+ } else {
8415
+ this.containerElement.style.removeProperty(`top`);
8416
+ }
8417
+ };
8418
+ this.layoutProcess$ = this.layoutTriggerSubject.pipe(
8419
+ switchMap((params) => {
8420
+ const { blankPagePosition, minimumWidth, spreadPosition } = params;
8421
+ this.hookManager.execute(`item.onBeforeLayout`, void 0, {
8422
+ blankPagePosition,
8423
+ item: this.item,
8424
+ minimumWidth
8425
+ });
8426
+ const rendererLayout$ = this.renderer.layout({
8427
+ blankPagePosition,
8428
+ minPageSpread: minimumWidth / this.context.getPageSize().width,
8429
+ minimumWidth,
8430
+ spreadPosition
8431
+ });
8432
+ return merge(
8433
+ of({ type: "start" }),
8434
+ rendererLayout$.pipe(
8435
+ this.applyDimsAfterLayout(params),
8436
+ map(
8437
+ (data) => ({
8438
+ type: "end",
8439
+ data
8440
+ })
8441
+ )
8442
+ )
8443
+ );
8444
+ }),
8445
+ share()
8446
+ );
8447
+ this.layout$ = this.layoutProcess$.pipe(
8448
+ filter((event) => event.type === `end`),
8449
+ map((event) => event.data),
8450
+ share()
8451
+ );
8452
+ }
8453
+ validateDimension(value, pageSize, minimum) {
8454
+ if (value <= 0) return minimum;
8455
+ const maxValue = Math.max(value, minimum);
8456
+ const multiplier = Math.ceil(maxValue / pageSize);
8457
+ const adjustedValue = multiplier * pageSize;
8458
+ return Math.max(adjustedValue, pageSize);
8459
+ }
8460
+ }
8383
8461
  class DefaultRenderer extends DocumentRenderer {
8384
8462
  onUnload() {
8385
8463
  return EMPTY;
@@ -8410,28 +8488,6 @@ class SpineItem extends DestroyableClass {
8410
8488
  this.settings = settings;
8411
8489
  this.hookManager = hookManager;
8412
8490
  this.index = index;
8413
- this.layoutTriggerSubject = new Subject();
8414
- this.adjustPositionOfElement = ({
8415
- right,
8416
- left,
8417
- top
8418
- }) => {
8419
- if (right !== void 0) {
8420
- this.containerElement.style.right = `${right}px`;
8421
- } else {
8422
- this.containerElement.style.removeProperty(`right`);
8423
- }
8424
- if (left !== void 0) {
8425
- this.containerElement.style.left = `${left}px`;
8426
- } else {
8427
- this.containerElement.style.removeProperty(`left`);
8428
- }
8429
- if (top !== void 0) {
8430
- this.containerElement.style.top = `${top}px`;
8431
- } else {
8432
- this.containerElement.style.removeProperty(`top`);
8433
- }
8434
- };
8435
8491
  this.getBoundingRectOfElementFromSelector = (selector) => {
8436
8492
  var _a2, _b2, _c, _d;
8437
8493
  const frameElement = this.renderer.getDocumentFrame();
@@ -8442,11 +8498,6 @@ class SpineItem extends DestroyableClass {
8442
8498
  return (_d = (_c = frameElement.contentDocument) == null ? void 0 : _c.querySelector(selector)) == null ? void 0 : _d.getBoundingClientRect();
8443
8499
  }
8444
8500
  };
8445
- this.layout = (params) => {
8446
- const nextResult = deferNextResult(this.layout$.pipe(first()));
8447
- this.layoutTriggerSubject.next(params);
8448
- return nextResult();
8449
- };
8450
8501
  this.load = () => {
8451
8502
  this.renderer.load();
8452
8503
  };
@@ -8490,52 +8541,21 @@ class SpineItem extends DestroyableClass {
8490
8541
  resourcesHandler: this.resourcesHandler
8491
8542
  };
8492
8543
  this.renderer = rendererFactory ? rendererFactory(rendererParams) : new DefaultRenderer(rendererParams);
8493
- const layoutProcess$ = this.layoutTriggerSubject.pipe(
8494
- switchMap$1(({ blankPagePosition, minimumWidth, spreadPosition }) => {
8495
- this.hookManager.execute(`item.onBeforeLayout`, void 0, {
8496
- blankPagePosition,
8497
- item: this.item,
8498
- minimumWidth
8499
- });
8500
- const layout$ = this.renderer.layout({
8501
- blankPagePosition,
8502
- minPageSpread: minimumWidth / this.context.getPageSize().width,
8503
- minimumWidth,
8504
- spreadPosition
8505
- });
8506
- return merge(
8507
- of({ type: "start" }),
8508
- layout$.pipe(
8509
- map$1(({ height, width }) => {
8510
- this.containerElement.style.width = `${width}px`;
8511
- this.containerElement.style.height = `${height}px`;
8512
- this.hookManager.execute(`item.onAfterLayout`, void 0, {
8513
- blankPagePosition,
8514
- item: this.item,
8515
- minimumWidth
8516
- });
8517
- return {
8518
- type: "end",
8519
- data: { width, height }
8520
- };
8521
- })
8522
- )
8523
- );
8524
- }),
8525
- share$1()
8544
+ this.spineItemLayout = new SpineItemLayout(
8545
+ item,
8546
+ this.containerElement,
8547
+ context,
8548
+ hookManager,
8549
+ this.renderer
8526
8550
  );
8527
- this.isReady$ = layoutProcess$.pipe(
8551
+ this.isReady$ = this.spineItemLayout.layoutProcess$.pipe(
8528
8552
  withLatestFrom$1(this.renderer.isLoaded$),
8529
8553
  map$1(([event, loaded]) => !!(event.type === `end` && loaded)),
8530
8554
  startWith(false),
8531
8555
  distinctUntilChanged(),
8532
8556
  shareReplay({ refCount: true, bufferSize: 1 })
8533
8557
  );
8534
- this.layout$ = layoutProcess$.pipe(
8535
- filter$1((event) => event.type === `end`),
8536
- map$1((event) => event.data),
8537
- share$1()
8538
- );
8558
+ this.layout$ = this.spineItemLayout.layout$;
8539
8559
  this.needsLayout$ = merge(this.unloaded$, this.loaded$);
8540
8560
  merge(
8541
8561
  /**
@@ -8545,8 +8565,10 @@ class SpineItem extends DestroyableClass {
8545
8565
  * to layout changes may rely on the isReady value.
8546
8566
  */
8547
8567
  this.isReady$,
8548
- this.layout$
8568
+ this.spineItemLayout.layout$
8549
8569
  ).pipe(takeUntil$1(this.destroy$)).subscribe();
8570
+ this.layout = this.spineItemLayout.layout;
8571
+ this.adjustPositionOfElement = this.spineItemLayout.adjustPositionOfElement;
8550
8572
  }
8551
8573
  get element() {
8552
8574
  return this.containerElement;