slate-angular 20.2.0-next.3 → 20.2.0-next.4

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.
@@ -2647,6 +2647,8 @@ class SlateEditable {
2647
2647
  this.virtualVisibleIndexes = new Set();
2648
2648
  this.measuredHeights = new Map();
2649
2649
  this.measurePending = false;
2650
+ // the height from scroll container top to editor top height element
2651
+ this.businessHeight = 0;
2650
2652
  this.virtualScrollInitialized = false;
2651
2653
  }
2652
2654
  ngOnInit() {
@@ -2959,7 +2961,7 @@ class SlateEditable {
2959
2961
  this.elementRef.nativeElement.appendChild(this.virtualTopHeightElement);
2960
2962
  this.elementRef.nativeElement.appendChild(this.virtualCenterOutlet);
2961
2963
  this.elementRef.nativeElement.appendChild(this.virtualBottomHeightElement);
2962
- // businessHeight
2964
+ this.businessHeight = this.virtualTopHeightElement.getBoundingClientRect()?.top ?? 0;
2963
2965
  }
2964
2966
  }
2965
2967
  changeVirtualHeight(topHeight, bottomHeight) {
@@ -2980,10 +2982,9 @@ class SlateEditable {
2980
2982
  heights: []
2981
2983
  };
2982
2984
  }
2983
- const scrollTop = this.virtualConfig.scrollTop ?? 0;
2985
+ const scrollTop = this.virtualConfig.scrollTop;
2984
2986
  const viewportHeight = this.virtualConfig.viewportHeight ?? 0;
2985
2987
  if (!viewportHeight) {
2986
- // 已经启用虚拟滚动,但可视区域高度还未获取到,先置空不渲染
2987
2988
  return {
2988
2989
  renderedChildren: [],
2989
2990
  visibleIndexes: new Set(),
@@ -2992,36 +2993,33 @@ class SlateEditable {
2992
2993
  heights: []
2993
2994
  };
2994
2995
  }
2995
- const bufferCount = this.virtualConfig.bufferCount ?? VIRTUAL_SCROLL_DEFAULT_BUFFER_COUNT;
2996
- const heights = children.map((_, idx) => this.getBlockHeight(idx));
2997
- const accumulatedHeights = this.buildAccumulatedHeight(heights);
2998
- let visibleStart = 0;
2999
- // 按真实或估算高度往后累加,找到滚动起点所在块
3000
- while (visibleStart < heights.length && accumulatedHeights[visibleStart + 1] <= scrollTop) {
3001
- visibleStart++;
3002
- }
3003
- // 向上预留 bufferCount 块
3004
- const startIndex = Math.max(0, visibleStart - bufferCount);
3005
- const top = accumulatedHeights[startIndex];
3006
- const bufferBelowHeight = this.getBufferBelowHeight(viewportHeight, visibleStart, bufferCount);
3007
- const targetHeight = accumulatedHeights[visibleStart] - top + viewportHeight + bufferBelowHeight;
2996
+ const elementLength = children.length;
2997
+ const adjustedScrollTop = Math.max(0, scrollTop - this.businessHeight);
2998
+ const viewBottom = scrollTop + viewportHeight;
2999
+ let accumulatedOffset = 0;
3000
+ let visibleStartIndex = -1;
3008
3001
  const visible = [];
3009
3002
  const visibleIndexes = [];
3010
- let accumulated = 0;
3011
- let cursor = startIndex;
3012
- // 循环累计高度超出目标高度(可视高度 + 上下 buffer)
3013
- while (cursor < children.length && accumulated < targetHeight) {
3014
- visible.push(children[cursor]);
3015
- visibleIndexes.push(cursor);
3016
- accumulated += this.getBlockHeight(cursor);
3017
- cursor++;
3018
- }
3019
- const bottom = heights.slice(cursor).reduce((acc, height) => acc + height, 0);
3020
- const renderedChildren = visible.length ? visible : children;
3021
- const visibleIndexesSet = new Set(visibleIndexes);
3003
+ for (let i = 0; i < elementLength && accumulatedOffset < viewBottom; i++) {
3004
+ const currentHeight = this.getBlockHeight(i);
3005
+ const nextOffset = accumulatedOffset + currentHeight;
3006
+ // 可视区域有交集,加入渲染
3007
+ if (nextOffset > adjustedScrollTop && accumulatedOffset < viewBottom) {
3008
+ if (visibleStartIndex === -1)
3009
+ visibleStartIndex = i; // 第一个相交起始位置
3010
+ visible.push(children[i]);
3011
+ visibleIndexes.push(i);
3012
+ }
3013
+ accumulatedOffset = nextOffset;
3014
+ }
3015
+ const visibleEndIndex = visibleStartIndex === -1 ? elementLength - 1 : visibleIndexes.length - 1;
3016
+ const heights = children.map((_, idx) => this.getBlockHeight(idx));
3017
+ const accumulatedHeights = this.buildAccumulatedHeight(heights);
3018
+ const top = visibleStartIndex === -1 ? 0 : accumulatedHeights[visibleStartIndex];
3019
+ const bottom = accumulatedHeights[elementLength] - accumulatedHeights[visibleEndIndex];
3022
3020
  return {
3023
- renderedChildren,
3024
- visibleIndexes: visibleIndexesSet,
3021
+ renderedChildren: visible.length ? visible : children,
3022
+ visibleIndexes: new Set(visibleIndexes),
3025
3023
  top,
3026
3024
  bottom,
3027
3025
  heights