slate-angular 20.2.0 → 20.2.2

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.
@@ -1491,9 +1491,9 @@ const measureHeightByIndics = (editor, indics, force = false) => {
1491
1491
  const getBusinessTop = (editor) => {
1492
1492
  return EDITOR_TO_BUSINESS_TOP.get(editor) ?? 0;
1493
1493
  };
1494
- const getRealHeightByElement = (editor, element, defaultHeight = VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT) => {
1495
- const isVisible = editor.isVisible(element);
1496
- if (!isVisible) {
1494
+ const getRealHeightByElement = (editor, element, defaultHeight = VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT, isVisible) => {
1495
+ const visible = isVisible ?? editor.isVisible(element);
1496
+ if (!visible) {
1497
1497
  return 0;
1498
1498
  }
1499
1499
  const heights = ELEMENT_KEY_TO_HEIGHTS.get(editor);
@@ -1510,14 +1510,17 @@ const getRealHeightByElement = (editor, element, defaultHeight = VIRTUAL_SCROLL_
1510
1510
  const buildHeightsAndAccumulatedHeights = (editor) => {
1511
1511
  const children = (editor.children || []);
1512
1512
  const heights = new Array(children.length);
1513
+ const visibleStates = new Array(children.length);
1513
1514
  const accumulatedHeights = new Array(children.length + 1);
1514
1515
  accumulatedHeights[0] = 0;
1515
1516
  for (let i = 0; i < children.length; i++) {
1516
- const height = getRealHeightByElement(editor, children[i]);
1517
+ const isVisible = editor.isVisible(children[i]);
1518
+ visibleStates[i] = isVisible;
1519
+ const height = getRealHeightByElement(editor, children[i], VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT, isVisible);
1517
1520
  heights[i] = height;
1518
1521
  accumulatedHeights[i + 1] = accumulatedHeights[i] + height;
1519
1522
  }
1520
- return { heights, accumulatedHeights };
1523
+ return { heights, accumulatedHeights, visibleStates };
1521
1524
  };
1522
1525
  const calculateVirtualTopHeight = (editor, startIndex) => {
1523
1526
  const { accumulatedHeights } = buildHeightsAndAccumulatedHeights(editor);
@@ -2619,6 +2622,9 @@ class SlateStringRender {
2619
2622
  if (this.type === StringType.normalString) {
2620
2623
  this.nativeElement.textContent = this.leaf.text;
2621
2624
  }
2625
+ if (this.type === StringType.compatibleString) {
2626
+ updateCompatibleStringNode(this.nativeElement, this.leaf.text);
2627
+ }
2622
2628
  }
2623
2629
  getElementStringLength() {
2624
2630
  return Node.string(this.context.parent).length;
@@ -2653,6 +2659,12 @@ const createCompatibleStringNode = (text) => {
2653
2659
  stringNode.appendChild(zeroWidthSpan);
2654
2660
  return stringNode;
2655
2661
  };
2662
+ const updateCompatibleStringNode = (stringNode, text) => {
2663
+ const zeroWidthSpan = stringNode.querySelector('span');
2664
+ stringNode.textContent = text;
2665
+ stringNode.appendChild(zeroWidthSpan);
2666
+ return stringNode;
2667
+ };
2656
2668
  const createLineBreakEmptyStringDOM = (elementStringLength) => {
2657
2669
  const stringNode = document.createElement('span');
2658
2670
  stringNode.setAttribute('data-slate-zero-width', 'n');
@@ -2903,16 +2915,23 @@ class ListRender {
2903
2915
  this.initialized = false;
2904
2916
  this.preRenderingHTMLElement = [];
2905
2917
  }
2906
- initialize(children, parent, childrenContext, preRenderingCount = 0) {
2918
+ initialize(children, parent, childrenContext, preRenderingCount = 0, childrenIndics) {
2907
2919
  this.initialized = true;
2908
2920
  this.children = children;
2909
2921
  const isRoot = parent === this.viewContext.editor;
2910
2922
  const firstIndex = isRoot ? this.viewContext.editor.children.indexOf(children[0]) : 0;
2911
2923
  const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
2924
+ const getBlockIndex = (index) => {
2925
+ if (childrenIndics && childrenIndics[index] !== undefined) {
2926
+ return childrenIndics[index];
2927
+ }
2928
+ return isRoot ? firstIndex + index : index;
2929
+ };
2912
2930
  children.forEach((descendant, _index) => {
2913
- NODE_TO_INDEX.set(descendant, firstIndex + _index);
2931
+ const currentIndex = getBlockIndex(_index);
2932
+ NODE_TO_INDEX.set(descendant, currentIndex);
2914
2933
  NODE_TO_PARENT.set(descendant, parent);
2915
- const context = getContext(firstIndex + _index, descendant, parentPath, childrenContext, this.viewContext);
2934
+ const context = getContext(currentIndex, descendant, parentPath, childrenContext, this.viewContext);
2916
2935
  const viewType = getViewType(descendant, parent, this.viewContext);
2917
2936
  const view = createEmbeddedViewOrComponentOrFlavour(viewType, context, this.viewContext, this.viewContainerRef);
2918
2937
  const blockCard = createBlockCard(descendant, view, this.viewContext);
@@ -2929,9 +2948,9 @@ class ListRender {
2929
2948
  executeAfterViewInit(this.viewContext.editor);
2930
2949
  }
2931
2950
  }
2932
- update(children, parent, childrenContext, preRenderingCount = 0) {
2951
+ update(children, parent, childrenContext, preRenderingCount = 0, childrenIndics) {
2933
2952
  if (!this.initialized || this.children.length === 0) {
2934
- this.initialize(children, parent, childrenContext, preRenderingCount);
2953
+ this.initialize(children, parent, childrenContext, preRenderingCount, childrenIndics);
2935
2954
  return;
2936
2955
  }
2937
2956
  if (!this.differ) {
@@ -2961,7 +2980,13 @@ class ListRender {
2961
2980
  const diffResult = this.differ.diff(children);
2962
2981
  const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
2963
2982
  const isRoot = parent === this.viewContext.editor;
2964
- const firstIndex = isRoot ? this.viewContext.editor.children.indexOf(children[0]) : 0;
2983
+ const firstIndex = isRoot && children.length ? this.viewContext.editor.children.indexOf(children[0]) : 0;
2984
+ const getBlockIndex = (index) => {
2985
+ if (childrenIndics && childrenIndics[index] !== undefined) {
2986
+ return childrenIndics[index];
2987
+ }
2988
+ return isRoot ? firstIndex + index : index;
2989
+ };
2965
2990
  if (diffResult) {
2966
2991
  let firstRootNode = getRootNodes(this.views[0], this.blockCards[0])[0];
2967
2992
  const newContexts = [];
@@ -2969,7 +2994,7 @@ class ListRender {
2969
2994
  const newViews = [];
2970
2995
  const newBlockCards = [];
2971
2996
  diffResult.forEachItem(record => {
2972
- const currentIndex = firstIndex + record.currentIndex;
2997
+ const currentIndex = getBlockIndex(record.currentIndex);
2973
2998
  NODE_TO_INDEX.set(record.item, currentIndex);
2974
2999
  NODE_TO_PARENT.set(record.item, parent);
2975
3000
  let context = getContext(currentIndex, record.item, parentPath, childrenContext, this.viewContext);
@@ -3041,9 +3066,10 @@ class ListRender {
3041
3066
  else {
3042
3067
  const newContexts = [];
3043
3068
  this.children.forEach((child, _index) => {
3044
- NODE_TO_INDEX.set(child, firstIndex + _index);
3069
+ const currentIndex = getBlockIndex(_index);
3070
+ NODE_TO_INDEX.set(child, currentIndex);
3045
3071
  NODE_TO_PARENT.set(child, parent);
3046
- let context = getContext(firstIndex + _index, child, parentPath, childrenContext, this.viewContext);
3072
+ let context = getContext(currentIndex, child, parentPath, childrenContext, this.viewContext);
3047
3073
  const previousContext = this.contexts[_index];
3048
3074
  if (memoizedContext(this.viewContext, child, previousContext, context)) {
3049
3075
  context = previousContext;
@@ -3362,11 +3388,11 @@ class SlateEditable {
3362
3388
  debugLog('log', 'writeValue calculate: ', virtualView.inViewportIndics, 'initialized: ', this.listRender.initialized);
3363
3389
  }
3364
3390
  if (!this.listRender.initialized) {
3365
- this.listRender.initialize(childrenForRender, this.editor, this.context);
3391
+ this.listRender.initialize(childrenForRender, this.editor, this.context, 0, virtualView.inViewportIndics);
3366
3392
  }
3367
3393
  else {
3368
- const { preRenderingCount, childrenWithPreRendering } = this.handlePreRendering();
3369
- this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount);
3394
+ const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering();
3395
+ this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount, childrenWithPreRenderingIndics);
3370
3396
  }
3371
3397
  }
3372
3398
  else {
@@ -3441,6 +3467,13 @@ class SlateEditable {
3441
3467
  EDITOR_TO_VIRTUAL_SCROLL_SELECTION.set(this.editor, null);
3442
3468
  return selection;
3443
3469
  }
3470
+ isSelectionInvisible(selection) {
3471
+ const anchorIndex = selection.anchor.path[0];
3472
+ const focusIndex = selection.focus.path[0];
3473
+ const anchorElement = this.editor.children[anchorIndex];
3474
+ const focusElement = this.editor.children[focusIndex];
3475
+ return !anchorElement || !focusElement || !this.editor.isVisible(anchorElement) || !this.editor.isVisible(focusElement);
3476
+ }
3444
3477
  toNativeSelection(autoScroll = true) {
3445
3478
  try {
3446
3479
  let { selection } = this.editor;
@@ -3584,7 +3617,13 @@ class SlateEditable {
3584
3617
  }
3585
3618
  }, 0);
3586
3619
  }
3587
- this.toNativeSelection();
3620
+ if (this.editor.selection && this.isSelectionInvisible(this.editor.selection)) {
3621
+ Transforms.deselect(this.editor);
3622
+ return;
3623
+ }
3624
+ else {
3625
+ this.toNativeSelection();
3626
+ }
3588
3627
  }
3589
3628
  render() {
3590
3629
  const changed = this.updateContext();
@@ -3598,11 +3637,20 @@ class SlateEditable {
3598
3637
  }
3599
3638
  }
3600
3639
  updateListRenderAndRemeasureHeights() {
3601
- const virtualView = this.calculateVirtualViewport();
3640
+ let virtualView = this.calculateVirtualViewport();
3641
+ let diff = this.diffVirtualViewport(virtualView, 'onChange');
3642
+ if (diff.isDifferent && diff.needRemoveOnTop) {
3643
+ const remeasureIndics = diff.changedIndexesOfTop;
3644
+ const changed = measureHeightByIndics(this.editor, remeasureIndics);
3645
+ if (changed) {
3646
+ virtualView = this.calculateVirtualViewport();
3647
+ diff = this.diffVirtualViewport(virtualView, 'second');
3648
+ }
3649
+ }
3602
3650
  const oldInViewportChildren = this.inViewportChildren;
3603
3651
  this.applyVirtualView(virtualView);
3604
- const { preRenderingCount, childrenWithPreRendering } = this.handlePreRendering();
3605
- this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount);
3652
+ const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering();
3653
+ this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount, childrenWithPreRenderingIndics);
3606
3654
  // 新增或者修改的才需要重算,计算出这个结果
3607
3655
  const remeasureIndics = [];
3608
3656
  this.inViewportChildren.forEach((child, index) => {
@@ -3610,9 +3658,6 @@ class SlateEditable {
3610
3658
  remeasureIndics.push(this.inViewportIndics[index]);
3611
3659
  }
3612
3660
  });
3613
- if (isDebug && remeasureIndics.length > 0) {
3614
- console.log('remeasure height by indics: ', remeasureIndics);
3615
- }
3616
3661
  }
3617
3662
  updateContext() {
3618
3663
  const decorations = this.generateDecorations();
@@ -3727,19 +3772,29 @@ class SlateEditable {
3727
3772
  return parseFloat(this.virtualTopHeightElement.style.height.replace('px', ''));
3728
3773
  }
3729
3774
  handlePreRendering() {
3730
- let preRenderingCount = 1;
3775
+ let preRenderingCount = 0;
3731
3776
  const childrenWithPreRendering = [...this.inViewportChildren];
3732
- if (this.inViewportIndics[0] !== 0) {
3733
- childrenWithPreRendering.unshift(this.editor.children[this.inViewportIndics[0] - 1]);
3734
- }
3735
- else {
3736
- preRenderingCount = 0;
3777
+ const childrenWithPreRenderingIndics = [...this.inViewportIndics];
3778
+ const firstIndex = this.inViewportIndics[0];
3779
+ for (let index = firstIndex - 1; index >= 0; index--) {
3780
+ const element = this.editor.children[index];
3781
+ if (this.editor.isVisible(element)) {
3782
+ childrenWithPreRendering.unshift(element);
3783
+ childrenWithPreRenderingIndics.unshift(index);
3784
+ preRenderingCount = 1;
3785
+ break;
3786
+ }
3737
3787
  }
3738
3788
  const lastIndex = this.inViewportIndics[this.inViewportIndics.length - 1];
3739
- if (lastIndex !== this.editor.children.length - 1) {
3740
- childrenWithPreRendering.push(this.editor.children[lastIndex + 1]);
3789
+ for (let index = lastIndex + 1; index < this.editor.children.length; index++) {
3790
+ const element = this.editor.children[index];
3791
+ if (this.editor.isVisible(element)) {
3792
+ childrenWithPreRendering.push(element);
3793
+ childrenWithPreRenderingIndics.push(index);
3794
+ break;
3795
+ }
3741
3796
  }
3742
- return { preRenderingCount, childrenWithPreRendering };
3797
+ return { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics };
3743
3798
  }
3744
3799
  tryUpdateVirtualViewport() {
3745
3800
  if (isDebug) {
@@ -3774,8 +3829,8 @@ class SlateEditable {
3774
3829
  if (diff.isDifferent) {
3775
3830
  this.applyVirtualView(virtualView);
3776
3831
  if (this.listRender.initialized) {
3777
- const { preRenderingCount, childrenWithPreRendering } = this.handlePreRendering();
3778
- this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount);
3832
+ const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering();
3833
+ this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount, childrenWithPreRenderingIndics);
3779
3834
  if (diff.needAddOnTop) {
3780
3835
  const remeasureAddedIndics = diff.changedIndexesOfTop;
3781
3836
  if (isDebug) {
@@ -3841,7 +3896,7 @@ class SlateEditable {
3841
3896
  }, 100);
3842
3897
  }
3843
3898
  const adjustedScrollTop = Math.max(0, scrollTop - getBusinessTop(this.editor));
3844
- const { heights, accumulatedHeights } = buildHeightsAndAccumulatedHeights(this.editor);
3899
+ const { heights, accumulatedHeights, visibleStates } = buildHeightsAndAccumulatedHeights(this.editor);
3845
3900
  const totalHeight = accumulatedHeights[elementLength];
3846
3901
  const maxScrollTop = Math.max(0, totalHeight - viewportHeight);
3847
3902
  const limitedScrollTop = Math.min(adjustedScrollTop, maxScrollTop);
@@ -3853,6 +3908,10 @@ class SlateEditable {
3853
3908
  for (let i = 0; i < elementLength && accumulatedOffset < viewBottom; i++) {
3854
3909
  const currentHeight = heights[i];
3855
3910
  const nextOffset = accumulatedOffset + currentHeight;
3911
+ if (!visibleStates[i]) {
3912
+ accumulatedOffset = nextOffset;
3913
+ continue;
3914
+ }
3856
3915
  // 可视区域有交集,加入渲染
3857
3916
  if (nextOffset > limitedScrollTop && accumulatedOffset < viewBottom) {
3858
3917
  if (inViewportStartIndex === -1)
@@ -3862,11 +3921,6 @@ class SlateEditable {
3862
3921
  }
3863
3922
  accumulatedOffset = nextOffset;
3864
3923
  }
3865
- if (inViewportStartIndex === -1 && elementLength) {
3866
- inViewportStartIndex = elementLength - 1;
3867
- visible.push(children[inViewportStartIndex]);
3868
- inViewportIndics.push(inViewportStartIndex);
3869
- }
3870
3924
  const inViewportEndIndex = inViewportStartIndex === -1 ? elementLength - 1 : (inViewportIndics[inViewportIndics.length - 1] ?? inViewportStartIndex);
3871
3925
  const top = inViewportStartIndex === -1 ? 0 : accumulatedHeights[inViewportStartIndex];
3872
3926
  const bottom = totalHeight - accumulatedHeights[inViewportEndIndex + 1];
@@ -3901,6 +3955,15 @@ class SlateEditable {
3901
3955
  const lastNewIndex = newIndexesInViewport[newIndexesInViewport.length - 1];
3902
3956
  const firstOldIndex = oldIndexesInViewport[0];
3903
3957
  const lastOldIndex = oldIndexesInViewport[oldIndexesInViewport.length - 1];
3958
+ const isSameViewport = oldIndexesInViewport.length === newIndexesInViewport.length &&
3959
+ oldIndexesInViewport.every((index, i) => index === newIndexesInViewport[i]);
3960
+ if (firstNewIndex === firstOldIndex && lastNewIndex === lastOldIndex) {
3961
+ return {
3962
+ isDifferent: !isSameViewport,
3963
+ changedIndexesOfTop: [],
3964
+ changedIndexesOfBottom: []
3965
+ };
3966
+ }
3904
3967
  if (firstNewIndex !== firstOldIndex || lastNewIndex !== lastOldIndex) {
3905
3968
  const changedIndexesOfTop = [];
3906
3969
  const changedIndexesOfBottom = [];
@@ -3954,8 +4017,13 @@ class SlateEditable {
3954
4017
  debugLog('log', `====== diffVirtualViewport stage: ${stage} ======`);
3955
4018
  debugLog('log', 'oldIndexesInViewport:', oldIndexesInViewport);
3956
4019
  debugLog('log', 'newIndexesInViewport:', newIndexesInViewport);
3957
- debugLog('log', 'changedIndexesOfTop:', needRemoveOnTop ? '-' : needAddOnTop ? '+' : '-', changedIndexesOfTop, changedIndexesOfTop.map(index => getRealHeightByElement(this.editor, this.editor.children[index], 0)));
3958
- debugLog('log', 'changedIndexesOfBottom:', needAddOnBottom ? '+' : needRemoveOnBottom ? '-' : '+', changedIndexesOfBottom, changedIndexesOfBottom.map(index => getRealHeightByElement(this.editor, this.editor.children[index], 0)));
4020
+ // this.editor.children[index] will be undefined when it is removed
4021
+ debugLog('log', 'changedIndexesOfTop:', needRemoveOnTop ? '-' : needAddOnTop ? '+' : '-', changedIndexesOfTop, changedIndexesOfTop.map(index => (this.editor.children[index] &&
4022
+ getRealHeightByElement(this.editor, this.editor.children[index], 0)) ||
4023
+ 0));
4024
+ debugLog('log', 'changedIndexesOfBottom:', needAddOnBottom ? '+' : needRemoveOnBottom ? '-' : '+', changedIndexesOfBottom, changedIndexesOfBottom.map(index => (this.editor.children[index] &&
4025
+ getRealHeightByElement(this.editor, this.editor.children[index], 0)) ||
4026
+ 0));
3959
4027
  const needTop = virtualView.heights.slice(0, newIndexesInViewport[0]).reduce((acc, height) => acc + height, 0);
3960
4028
  const needBottom = virtualView.heights
3961
4029
  .slice(newIndexesInViewport[newIndexesInViewport.length - 1] + 1)