slate-angular 20.2.0-next.23 → 20.2.0-next.25

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.
@@ -2352,8 +2352,9 @@ class ListRender {
2352
2352
  this.viewTypes = [];
2353
2353
  this.differ = null;
2354
2354
  this.initialized = false;
2355
+ this.preRenderingHTMLElement = [];
2355
2356
  }
2356
- initialize(children, parent, childrenContext) {
2357
+ initialize(children, parent, childrenContext, preRenderingCount = 0) {
2357
2358
  this.initialized = true;
2358
2359
  this.children = children;
2359
2360
  const isRoot = parent === this.viewContext.editor;
@@ -2379,15 +2380,26 @@ class ListRender {
2379
2380
  executeAfterViewInit(this.viewContext.editor);
2380
2381
  }
2381
2382
  }
2382
- update(children, parent, childrenContext) {
2383
+ update(children, parent, childrenContext, preRenderingCount = 0) {
2383
2384
  if (!this.initialized || this.children.length === 0) {
2384
- this.initialize(children, parent, childrenContext);
2385
+ this.initialize(children, parent, childrenContext, preRenderingCount);
2385
2386
  return;
2386
2387
  }
2387
2388
  if (!this.differ) {
2388
2389
  throw new Error('Exception: Can not find differ ');
2389
2390
  }
2390
2391
  const outletParent = this.getOutletParent();
2392
+ if (this.preRenderingHTMLElement.length > 0) {
2393
+ const preRenderingElement = [...this.preRenderingHTMLElement];
2394
+ preRenderingElement.forEach((rootNodes, index) => {
2395
+ rootNodes.forEach(rootNode => {
2396
+ rootNode.style.position = '';
2397
+ rootNode.style.top = '';
2398
+ rootNode.style.width = '';
2399
+ });
2400
+ });
2401
+ this.preRenderingHTMLElement = [];
2402
+ }
2391
2403
  const diffResult = this.differ.diff(children);
2392
2404
  const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
2393
2405
  const isRoot = parent === this.viewContext.editor;
@@ -2485,6 +2497,15 @@ class ListRender {
2485
2497
  });
2486
2498
  this.contexts = newContexts;
2487
2499
  }
2500
+ if (preRenderingCount > 0) {
2501
+ for (let i = 0; i < preRenderingCount; i++) {
2502
+ const rootNodes = [...getRootNodes(this.views[i], this.blockCards[i])];
2503
+ rootNodes.forEach(rootNode => {
2504
+ rootNode.style = `position: absolute;top: -100%;`;
2505
+ });
2506
+ this.preRenderingHTMLElement.push(rootNodes);
2507
+ }
2508
+ }
2488
2509
  }
2489
2510
  destroy() {
2490
2511
  this.children.forEach((element, index) => {
@@ -3200,7 +3221,7 @@ class SlateEditable {
3200
3221
  viewportBoundingTop: 0
3201
3222
  };
3202
3223
  this.inViewportChildren = [];
3203
- this.inViewportIndics = new Set();
3224
+ this.inViewportIndics = [];
3204
3225
  this.keyHeightMap = new Map();
3205
3226
  this.virtualScrollInitialized = false;
3206
3227
  }
@@ -3267,7 +3288,8 @@ class SlateEditable {
3267
3288
  this.listRender.initialize(childrenForRender, this.editor, this.context);
3268
3289
  }
3269
3290
  else {
3270
- this.listRender.update(childrenForRender, this.editor, this.context);
3291
+ const { preRenderingCount, childrenWithPreRendering } = this.handlePreRendering();
3292
+ this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount);
3271
3293
  }
3272
3294
  this.tryMeasureInViewportChildrenHeights();
3273
3295
  }
@@ -3311,7 +3333,7 @@ class SlateEditable {
3311
3333
  }
3312
3334
  calculateVirtualScrollSelection(selection) {
3313
3335
  if (selection) {
3314
- const indics = Array.from(this.inViewportIndics.values());
3336
+ const indics = this.inViewportIndics;
3315
3337
  if (indics.length > 0) {
3316
3338
  const currentVisibleRange = {
3317
3339
  anchor: Editor.start(this.editor, [indics[0]]),
@@ -3482,13 +3504,13 @@ class SlateEditable {
3482
3504
  const virtualView = this.calculateVirtualViewport();
3483
3505
  const oldInViewportChildren = this.inViewportChildren;
3484
3506
  this.applyVirtualView(virtualView);
3485
- this.listRender.update(this.inViewportChildren, this.editor, this.context);
3507
+ const { preRenderingCount, childrenWithPreRendering } = this.handlePreRendering();
3508
+ this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount);
3486
3509
  // 新增或者修改的才需要重算,计算出这个结果
3487
3510
  const remeasureIndics = [];
3488
- const newInViewportIndics = Array.from(this.inViewportIndics);
3489
3511
  this.inViewportChildren.forEach((child, index) => {
3490
3512
  if (oldInViewportChildren.indexOf(child) === -1) {
3491
- remeasureIndics.push(newInViewportIndics[index]);
3513
+ remeasureIndics.push(this.inViewportIndics[index]);
3492
3514
  }
3493
3515
  });
3494
3516
  if (isDebug && remeasureIndics.length > 0) {
@@ -3581,7 +3603,7 @@ class SlateEditable {
3581
3603
  if (entries.length > 0 && entries[0].contentRect.width !== editorResizeObserverRectWidth) {
3582
3604
  editorResizeObserverRectWidth = entries[0].contentRect.width;
3583
3605
  this.keyHeightMap.clear();
3584
- const remeasureIndics = Array.from(this.inViewportIndics);
3606
+ const remeasureIndics = this.inViewportIndics;
3585
3607
  this.remeasureHeightByIndics(remeasureIndics);
3586
3608
  }
3587
3609
  });
@@ -3597,62 +3619,83 @@ class SlateEditable {
3597
3619
  return;
3598
3620
  }
3599
3621
  this.virtualTopHeightElement.style.height = `${topHeight}px`;
3600
- this.virtualBottomHeightElement.style.height = `${bottomHeight}px`;
3622
+ if (bottomHeight !== undefined) {
3623
+ this.virtualBottomHeightElement.style.height = `${bottomHeight}px`;
3624
+ }
3625
+ }
3626
+ getVirtualTopHeight() {
3627
+ if (!this.virtualScrollInitialized) {
3628
+ return 0;
3629
+ }
3630
+ return parseFloat(this.virtualTopHeightElement.style.height.replace('px', ''));
3601
3631
  }
3602
3632
  debugLog(type, ...args) {
3603
3633
  const doc = this.elementRef?.nativeElement?.ownerDocument ?? document;
3604
3634
  VirtualScrollDebugOverlay.log(doc, type, ...args);
3605
3635
  }
3636
+ handlePreRendering() {
3637
+ let preRenderingCount = 1;
3638
+ const childrenWithPreRendering = [...this.inViewportChildren];
3639
+ if (this.inViewportIndics[0] !== 0) {
3640
+ childrenWithPreRendering.unshift(this.editor.children[this.inViewportIndics[0] - 1]);
3641
+ }
3642
+ else {
3643
+ preRenderingCount = 0;
3644
+ }
3645
+ const lastIndex = this.inViewportIndics[this.inViewportIndics.length - 1];
3646
+ if (lastIndex !== this.editor.children.length - 1) {
3647
+ childrenWithPreRendering.push(this.editor.children[lastIndex + 1]);
3648
+ }
3649
+ return { preRenderingCount, childrenWithPreRendering };
3650
+ }
3606
3651
  tryUpdateVirtualViewport() {
3652
+ if (isDebug) {
3653
+ this.debugLog('log', 'tryUpdateVirtualViewport');
3654
+ }
3607
3655
  this.tryUpdateVirtualViewportAnimId && cancelAnimationFrame(this.tryUpdateVirtualViewportAnimId);
3608
3656
  this.tryUpdateVirtualViewportAnimId = requestAnimationFrame(() => {
3657
+ if (isDebug) {
3658
+ this.debugLog('log', 'tryUpdateVirtualViewport Anim start');
3659
+ }
3609
3660
  let virtualView = this.calculateVirtualViewport();
3610
3661
  let diff = this.diffVirtualViewport(virtualView);
3611
- if (!diff.isDiff) {
3612
- return;
3613
- }
3614
- // diff.isAddedTop
3615
- if (diff.isMissingTop) {
3616
- const remeasureIndics = diff.diffTopRenderedIndexes;
3617
- const result = this.remeasureHeightByIndics(remeasureIndics);
3618
- if (result) {
3619
- virtualView = this.calculateVirtualViewport();
3620
- diff = this.diffVirtualViewport(virtualView, 'second');
3621
- if (!diff.isDiff) {
3622
- return;
3662
+ if (diff.isDifferent) {
3663
+ this.applyVirtualView(virtualView);
3664
+ if (this.listRender.initialized) {
3665
+ const { preRenderingCount, childrenWithPreRendering } = this.handlePreRendering();
3666
+ this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount);
3667
+ if (!AngularEditor.isReadOnly(this.editor) && this.editor.selection) {
3668
+ this.toNativeSelection();
3623
3669
  }
3624
3670
  }
3625
- }
3626
- this.applyVirtualView(virtualView);
3627
- if (this.listRender.initialized) {
3628
- this.listRender.update(virtualView.inViewportChildren, this.editor, this.context);
3629
- if (!AngularEditor.isReadOnly(this.editor) && this.editor.selection) {
3630
- this.toNativeSelection();
3671
+ if (diff.needAddOnTop) {
3672
+ const remeasureAddedIndics = diff.changedIndexesOfTop;
3673
+ if (isDebug) {
3674
+ this.debugLog('log', 'needAddOnTop to remeasure heights: ', remeasureAddedIndics);
3675
+ }
3676
+ const startIndexBeforeAdd = diff.changedIndexesOfTop[diff.changedIndexesOfTop.length - 1] + 1;
3677
+ const topHeightBeforeAdd = virtualView.accumulatedHeights[startIndexBeforeAdd];
3678
+ const result = this.remeasureHeightByIndics(remeasureAddedIndics);
3679
+ if (result) {
3680
+ const newHeights = buildHeightsAndAccumulatedHeights(this.editor);
3681
+ const actualTopHeightAfterAdd = newHeights.accumulatedHeights[startIndexBeforeAdd];
3682
+ const newTopHeight = virtualView.top - (actualTopHeightAfterAdd - topHeightBeforeAdd);
3683
+ this.setVirtualSpaceHeight(newTopHeight);
3684
+ this.debugLog('log', `update top height cause added element in top, 减去: ${actualTopHeightAfterAdd - topHeightBeforeAdd}`);
3685
+ }
3631
3686
  }
3687
+ this.tryMeasureInViewportChildrenHeights();
3632
3688
  }
3633
- if (diff.isAddedTop) {
3634
- const remeasureAddedIndics = diff.diffTopRenderedIndexes;
3635
- if (isDebug) {
3636
- this.debugLog('log', 'isAddedTop to remeasure heights: ', remeasureAddedIndics);
3637
- }
3638
- const startIndexBeforeAdd = diff.diffTopRenderedIndexes[diff.diffTopRenderedIndexes.length - 1] + 1;
3639
- const topHeightBeforeAdd = virtualView.accumulatedHeights[startIndexBeforeAdd];
3640
- const result = this.remeasureHeightByIndics(remeasureAddedIndics);
3641
- if (result) {
3642
- const newHeights = buildHeightsAndAccumulatedHeights(this.editor);
3643
- const visibleStartIndex = diff.diffTopRenderedIndexes[0];
3644
- const actualTopHeightAfterAdd = newHeights.accumulatedHeights[startIndexBeforeAdd];
3645
- const adjustedTopHeight = (visibleStartIndex === -1 ? 0 : newHeights.accumulatedHeights[visibleStartIndex]) -
3646
- (actualTopHeightAfterAdd - topHeightBeforeAdd);
3647
- if (adjustedTopHeight !== virtualView.top) {
3648
- if (isDebug) {
3649
- this.debugLog('log', `update top height cause added element in top: ${adjustedTopHeight}, old height: ${virtualView.top}`);
3650
- }
3651
- this.virtualTopHeightElement.style.height = `${adjustedTopHeight}px`;
3652
- }
3689
+ else {
3690
+ const topHeight = this.getVirtualTopHeight();
3691
+ if (virtualView.top !== topHeight) {
3692
+ this.debugLog('log', 'update top height: ', virtualView.top - topHeight, 'start index', this.inViewportIndics[0]);
3693
+ this.setVirtualSpaceHeight(virtualView.top);
3653
3694
  }
3654
3695
  }
3655
- this.tryMeasureInViewportChildrenHeights();
3696
+ if (isDebug) {
3697
+ this.debugLog('log', 'tryUpdateVirtualViewport Anim end');
3698
+ }
3656
3699
  });
3657
3700
  }
3658
3701
  calculateVirtualViewport() {
@@ -3660,7 +3703,7 @@ class SlateEditable {
3660
3703
  if (!children.length || !this.isEnabledVirtualScroll()) {
3661
3704
  return {
3662
3705
  inViewportChildren: children,
3663
- visibleIndexes: new Set(),
3706
+ visibleIndexes: [],
3664
3707
  top: 0,
3665
3708
  bottom: 0,
3666
3709
  heights: []
@@ -3675,7 +3718,7 @@ class SlateEditable {
3675
3718
  if (!viewportHeight) {
3676
3719
  return {
3677
3720
  inViewportChildren: [],
3678
- visibleIndexes: new Set(),
3721
+ visibleIndexes: [],
3679
3722
  top: 0,
3680
3723
  bottom: 0,
3681
3724
  heights: []
@@ -3727,7 +3770,7 @@ class SlateEditable {
3727
3770
  const bottom = totalHeight - accumulatedHeights[visibleEndIndex + 1];
3728
3771
  return {
3729
3772
  inViewportChildren: visible.length ? visible : children,
3730
- visibleIndexes: new Set(visibleIndexes),
3773
+ visibleIndexes,
3731
3774
  top,
3732
3775
  bottom,
3733
3776
  heights,
@@ -3742,60 +3785,60 @@ class SlateEditable {
3742
3785
  diffVirtualViewport(virtualView, stage = 'first') {
3743
3786
  if (!this.inViewportChildren.length) {
3744
3787
  return {
3745
- isDiff: true,
3746
- diffTopRenderedIndexes: [],
3747
- diffBottomRenderedIndexes: []
3788
+ isDifferent: true,
3789
+ changedIndexesOfTop: [],
3790
+ changedIndexesOfBottom: []
3748
3791
  };
3749
3792
  }
3750
- const oldVisibleIndexes = [...this.inViewportIndics];
3751
- const newVisibleIndexes = [...virtualView.visibleIndexes];
3752
- const firstNewIndex = newVisibleIndexes[0];
3753
- const lastNewIndex = newVisibleIndexes[newVisibleIndexes.length - 1];
3754
- const firstOldIndex = oldVisibleIndexes[0];
3755
- const lastOldIndex = oldVisibleIndexes[oldVisibleIndexes.length - 1];
3793
+ const oldIndexesInViewport = [...this.inViewportIndics];
3794
+ const newIndexesInViewport = [...virtualView.visibleIndexes];
3795
+ const firstNewIndex = newIndexesInViewport[0];
3796
+ const lastNewIndex = newIndexesInViewport[newIndexesInViewport.length - 1];
3797
+ const firstOldIndex = oldIndexesInViewport[0];
3798
+ const lastOldIndex = oldIndexesInViewport[oldIndexesInViewport.length - 1];
3756
3799
  if (firstNewIndex !== firstOldIndex || lastNewIndex !== lastOldIndex) {
3757
- const diffTopRenderedIndexes = [];
3758
- const diffBottomRenderedIndexes = [];
3759
- const isMissingTop = firstNewIndex !== firstOldIndex && firstNewIndex > firstOldIndex;
3760
- const isAddedTop = firstNewIndex !== firstOldIndex && firstNewIndex < firstOldIndex;
3761
- const isMissingBottom = lastNewIndex !== lastOldIndex && lastOldIndex > lastNewIndex;
3762
- const isAddedBottom = lastNewIndex !== lastOldIndex && lastOldIndex < lastNewIndex;
3763
- if (isMissingTop || isAddedBottom) {
3800
+ const changedIndexesOfTop = [];
3801
+ const changedIndexesOfBottom = [];
3802
+ const needRemoveOnTop = firstNewIndex !== firstOldIndex && firstNewIndex > firstOldIndex;
3803
+ const needAddOnTop = firstNewIndex !== firstOldIndex && firstNewIndex < firstOldIndex;
3804
+ const needRemoveOnBottom = lastNewIndex !== lastOldIndex && lastOldIndex > lastNewIndex;
3805
+ const needAddOnBottom = lastNewIndex !== lastOldIndex && lastOldIndex < lastNewIndex;
3806
+ if (needRemoveOnTop || needAddOnBottom) {
3764
3807
  // 向下
3765
- for (let index = 0; index < oldVisibleIndexes.length; index++) {
3766
- const element = oldVisibleIndexes[index];
3767
- if (!newVisibleIndexes.includes(element)) {
3768
- diffTopRenderedIndexes.push(element);
3808
+ for (let index = 0; index < oldIndexesInViewport.length; index++) {
3809
+ const element = oldIndexesInViewport[index];
3810
+ if (!newIndexesInViewport.includes(element)) {
3811
+ changedIndexesOfTop.push(element);
3769
3812
  }
3770
3813
  else {
3771
3814
  break;
3772
3815
  }
3773
3816
  }
3774
- for (let index = newVisibleIndexes.length - 1; index >= 0; index--) {
3775
- const element = newVisibleIndexes[index];
3776
- if (!oldVisibleIndexes.includes(element)) {
3777
- diffBottomRenderedIndexes.push(element);
3817
+ for (let index = newIndexesInViewport.length - 1; index >= 0; index--) {
3818
+ const element = newIndexesInViewport[index];
3819
+ if (!oldIndexesInViewport.includes(element)) {
3820
+ changedIndexesOfBottom.push(element);
3778
3821
  }
3779
3822
  else {
3780
3823
  break;
3781
3824
  }
3782
3825
  }
3783
3826
  }
3784
- else if (isAddedTop || isMissingBottom) {
3827
+ else if (needAddOnTop || needRemoveOnBottom) {
3785
3828
  // 向上
3786
- for (let index = 0; index < newVisibleIndexes.length; index++) {
3787
- const element = newVisibleIndexes[index];
3788
- if (!oldVisibleIndexes.includes(element)) {
3789
- diffTopRenderedIndexes.push(element);
3829
+ for (let index = 0; index < newIndexesInViewport.length; index++) {
3830
+ const element = newIndexesInViewport[index];
3831
+ if (!oldIndexesInViewport.includes(element)) {
3832
+ changedIndexesOfTop.push(element);
3790
3833
  }
3791
3834
  else {
3792
3835
  break;
3793
3836
  }
3794
3837
  }
3795
- for (let index = oldVisibleIndexes.length - 1; index >= 0; index--) {
3796
- const element = oldVisibleIndexes[index];
3797
- if (!newVisibleIndexes.includes(element)) {
3798
- diffBottomRenderedIndexes.push(element);
3838
+ for (let index = oldIndexesInViewport.length - 1; index >= 0; index--) {
3839
+ const element = oldIndexesInViewport[index];
3840
+ if (!newIndexesInViewport.includes(element)) {
3841
+ changedIndexesOfBottom.push(element);
3799
3842
  }
3800
3843
  else {
3801
3844
  break;
@@ -3804,32 +3847,32 @@ class SlateEditable {
3804
3847
  }
3805
3848
  if (isDebug) {
3806
3849
  this.debugLog('log', `====== diffVirtualViewport stage: ${stage} ======`);
3807
- this.debugLog('log', 'oldVisibleIndexes:', oldVisibleIndexes);
3808
- this.debugLog('log', 'newVisibleIndexes:', newVisibleIndexes);
3809
- this.debugLog('log', 'diffTopRenderedIndexes:', isMissingTop ? '-' : isAddedTop ? '+' : '-', diffTopRenderedIndexes, diffTopRenderedIndexes.map(index => getRealHeightByElement(this.editor, this.editor.children[index], 0)));
3810
- this.debugLog('log', 'diffBottomRenderedIndexes:', isAddedBottom ? '+' : isMissingBottom ? '-' : '+', diffBottomRenderedIndexes, diffBottomRenderedIndexes.map(index => getRealHeightByElement(this.editor, this.editor.children[index], 0)));
3811
- const needTop = virtualView.heights.slice(0, newVisibleIndexes[0]).reduce((acc, height) => acc + height, 0);
3850
+ this.debugLog('log', 'oldIndexesInViewport:', oldIndexesInViewport);
3851
+ this.debugLog('log', 'newIndexesInViewport:', newIndexesInViewport);
3852
+ this.debugLog('log', 'changedIndexesOfTop:', needRemoveOnTop ? '-' : needAddOnTop ? '+' : '-', changedIndexesOfTop, changedIndexesOfTop.map(index => getRealHeightByElement(this.editor, this.editor.children[index], 0)));
3853
+ this.debugLog('log', 'changedIndexesOfBottom:', needAddOnBottom ? '+' : needRemoveOnBottom ? '-' : '+', changedIndexesOfBottom, changedIndexesOfBottom.map(index => getRealHeightByElement(this.editor, this.editor.children[index], 0)));
3854
+ const needTop = virtualView.heights.slice(0, newIndexesInViewport[0]).reduce((acc, height) => acc + height, 0);
3812
3855
  const needBottom = virtualView.heights
3813
- .slice(newVisibleIndexes[newVisibleIndexes.length - 1] + 1)
3856
+ .slice(newIndexesInViewport[newIndexesInViewport.length - 1] + 1)
3814
3857
  .reduce((acc, height) => acc + height, 0);
3815
- this.debugLog('log', 'newTopHeight:', needTop, 'prevTopHeight:', parseFloat(this.virtualTopHeightElement.style.height));
3858
+ this.debugLog('log', needTop - parseFloat(this.virtualTopHeightElement.style.height), 'newTopHeight:', needTop, 'prevTopHeight:', parseFloat(this.virtualTopHeightElement.style.height));
3816
3859
  this.debugLog('log', 'newBottomHeight:', needBottom, 'prevBottomHeight:', parseFloat(this.virtualBottomHeightElement.style.height));
3817
3860
  this.debugLog('warn', '=========== Dividing line ===========');
3818
3861
  }
3819
3862
  return {
3820
- isDiff: true,
3821
- isMissingTop,
3822
- isAddedTop,
3823
- isMissingBottom,
3824
- isAddedBottom,
3825
- diffTopRenderedIndexes,
3826
- diffBottomRenderedIndexes
3863
+ isDifferent: true,
3864
+ needRemoveOnTop,
3865
+ needAddOnTop,
3866
+ needRemoveOnBottom,
3867
+ needAddOnBottom,
3868
+ changedIndexesOfTop,
3869
+ changedIndexesOfBottom
3827
3870
  };
3828
3871
  }
3829
3872
  return {
3830
- isDiff: false,
3831
- diffTopRenderedIndexes: [],
3832
- diffBottomRenderedIndexes: []
3873
+ isDifferent: false,
3874
+ changedIndexesOfTop: [],
3875
+ changedIndexesOfBottom: []
3833
3876
  };
3834
3877
  }
3835
3878
  tryMeasureInViewportChildrenHeights() {
@@ -3843,7 +3886,8 @@ class SlateEditable {
3843
3886
  }
3844
3887
  measureVisibleHeights() {
3845
3888
  const children = (this.editor.children || []);
3846
- this.inViewportIndics.forEach(index => {
3889
+ const inViewportIndics = [...this.inViewportIndics];
3890
+ inViewportIndics.forEach(index => {
3847
3891
  const node = children[index];
3848
3892
  if (!node) {
3849
3893
  return;