slate-angular 20.2.10 → 20.2.12

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.
@@ -5,7 +5,7 @@ import * as i0 from '@angular/core';
5
5
  import { TemplateRef, ComponentRef, IterableDiffers, inject, ViewContainerRef, forwardRef, HostBinding, Input, ChangeDetectionStrategy, Component, NgModule, ElementRef, ChangeDetectorRef, Directive, ViewChild } from '@angular/core';
6
6
  import { direction } from 'direction';
7
7
  import scrollIntoView from 'scroll-into-view-if-needed';
8
- import { Subject, debounceTime } from 'rxjs';
8
+ import { Subject, tap, debounceTime, filter } from 'rxjs';
9
9
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
10
10
  import { HistoryEditor } from 'slate-history';
11
11
  import { CommonModule } from '@angular/common';
@@ -1566,7 +1566,10 @@ const measureHeightByIndics = (editor, indics, force = false) => {
1566
1566
  return;
1567
1567
  }
1568
1568
  hasChanged = true;
1569
- calcHeightByElement(editor, element);
1569
+ const currentHeight = calcHeightByElement(editor, element);
1570
+ if (isDebug) {
1571
+ debugLog('log', 'measureHeightByIndics: height not equal, index: ', index, 'preHeight: ', preHeight, 'height: ', currentHeight);
1572
+ }
1570
1573
  });
1571
1574
  return hasChanged;
1572
1575
  };
@@ -1585,13 +1588,13 @@ const getCachedHeightByElement = (editor, element) => {
1585
1588
  }
1586
1589
  return null;
1587
1590
  };
1588
- const buildHeightsAndAccumulatedHeights = (editor) => {
1591
+ const buildHeightsAndAccumulatedHeights = (editor, visibleStates) => {
1589
1592
  const children = (editor.children || []);
1590
1593
  const heights = new Array(children.length);
1591
1594
  const accumulatedHeights = new Array(children.length + 1);
1592
1595
  accumulatedHeights[0] = 0;
1593
1596
  for (let i = 0; i < children.length; i++) {
1594
- const isVisible = editor.isVisible(children[i]);
1597
+ const isVisible = visibleStates[i];
1595
1598
  let height = isVisible ? getCachedHeightByElement(editor, children[i]) : 0;
1596
1599
  if (height === null) {
1597
1600
  try {
@@ -1606,8 +1609,8 @@ const buildHeightsAndAccumulatedHeights = (editor) => {
1606
1609
  }
1607
1610
  return { heights, accumulatedHeights };
1608
1611
  };
1609
- const calculateVirtualTopHeight = (editor, startIndex) => {
1610
- const { accumulatedHeights } = buildHeightsAndAccumulatedHeights(editor);
1612
+ const calculateVirtualTopHeight = (editor, startIndex, visibleStates) => {
1613
+ const { accumulatedHeights } = buildHeightsAndAccumulatedHeights(editor, visibleStates);
1611
1614
  return accumulatedHeights[startIndex] ?? 0;
1612
1615
  };
1613
1616
  const scrollToElement = (editor, element, scrollTo) => {
@@ -1619,7 +1622,8 @@ const scrollToElement = (editor, element, scrollTo) => {
1619
1622
  if (anchorIndex < 0) {
1620
1623
  return;
1621
1624
  }
1622
- const { accumulatedHeights } = buildHeightsAndAccumulatedHeights(editor);
1625
+ const visibleStates = editor.getAllVisibleStates();
1626
+ const { accumulatedHeights } = buildHeightsAndAccumulatedHeights(editor, visibleStates);
1623
1627
  scrollTo((accumulatedHeights[anchorIndex] ?? 0) + getBusinessTop(editor));
1624
1628
  EDITOR_TO_IS_FROM_SCROLL_TO.set(editor, true);
1625
1629
  setTimeout(() => {
@@ -1826,6 +1830,9 @@ const withAngular = (editor, clipboardFormatKey = 'x-slate-fragment') => {
1826
1830
  e.isVisible = element => {
1827
1831
  return true;
1828
1832
  };
1833
+ e.getAllVisibleStates = () => {
1834
+ return new Array(e.children.length).fill(true);
1835
+ };
1829
1836
  e.getRoughHeight = (element, defaultHeight) => {
1830
1837
  return defaultHeight === undefined ? VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT : defaultHeight;
1831
1838
  };
@@ -3379,7 +3386,7 @@ class SlateEditable {
3379
3386
  this.inViewportChildren = [];
3380
3387
  this.inViewportIndics = [];
3381
3388
  this.keyHeightMap = new Map();
3382
- this.viewportRefresh$ = new Subject();
3389
+ this.indicsOfNeedBeMeasured$ = new Subject();
3383
3390
  this.virtualScrollInitialized = false;
3384
3391
  }
3385
3392
  ngOnInit() {
@@ -3438,7 +3445,9 @@ class SlateEditable {
3438
3445
  this.editor.children = value;
3439
3446
  this.initializeContext();
3440
3447
  if (this.isEnabledVirtualScroll()) {
3441
- const virtualView = this.calculateVirtualViewport();
3448
+ const previousInViewportChildren = [...this.inViewportChildren];
3449
+ const visibleStates = this.editor.getAllVisibleStates();
3450
+ const virtualView = this.calculateVirtualViewport(visibleStates);
3442
3451
  this.applyVirtualView(virtualView);
3443
3452
  const childrenForRender = virtualView.inViewportChildren;
3444
3453
  if (isDebug) {
@@ -3448,10 +3457,13 @@ class SlateEditable {
3448
3457
  this.listRender.initialize(childrenForRender, this.editor, this.context, 0, virtualView.inViewportIndics);
3449
3458
  }
3450
3459
  else {
3451
- const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering();
3460
+ const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering(visibleStates);
3452
3461
  this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount, childrenWithPreRenderingIndics);
3453
3462
  }
3454
- this.viewportRefresh$.next();
3463
+ const remeasureIndics = this.getChangedIndics(previousInViewportChildren);
3464
+ if (remeasureIndics.length) {
3465
+ this.indicsOfNeedBeMeasured$.next(remeasureIndics);
3466
+ }
3455
3467
  }
3456
3468
  else {
3457
3469
  if (!this.listRender.initialized) {
@@ -3695,28 +3707,25 @@ class SlateEditable {
3695
3707
  }
3696
3708
  }
3697
3709
  updateListRenderAndRemeasureHeights() {
3698
- let virtualView = this.calculateVirtualViewport();
3710
+ const visibleStates = this.editor.getAllVisibleStates();
3711
+ const previousInViewportChildren = [...this.inViewportChildren];
3712
+ let virtualView = this.calculateVirtualViewport(visibleStates);
3699
3713
  let diff = this.diffVirtualViewport(virtualView, 'onChange');
3700
3714
  if (diff.isDifferent && diff.needRemoveOnTop) {
3701
3715
  const remeasureIndics = diff.changedIndexesOfTop;
3702
3716
  const changed = measureHeightByIndics(this.editor, remeasureIndics);
3703
3717
  if (changed) {
3704
- virtualView = this.calculateVirtualViewport();
3718
+ virtualView = this.calculateVirtualViewport(visibleStates);
3705
3719
  diff = this.diffVirtualViewport(virtualView, 'second');
3706
3720
  }
3707
3721
  }
3708
- // const oldInViewportChildren = this.inViewportChildren;
3709
3722
  this.applyVirtualView(virtualView);
3710
- const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering();
3723
+ const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering(visibleStates);
3711
3724
  this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount, childrenWithPreRenderingIndics);
3712
- // 新增或者修改的才需要重算,计算出这个结果
3713
- // const remeasureIndics = [];
3714
- // this.inViewportChildren.forEach((child, index) => {
3715
- // if (oldInViewportChildren.indexOf(child) === -1) {
3716
- // remeasureIndics.push(this.inViewportIndics[index]);
3717
- // }
3718
- // });
3719
- this.viewportRefresh$.next();
3725
+ const remeasureIndics = this.getChangedIndics(previousInViewportChildren);
3726
+ if (remeasureIndics.length) {
3727
+ this.indicsOfNeedBeMeasured$.next(remeasureIndics);
3728
+ }
3720
3729
  }
3721
3730
  updateContext() {
3722
3731
  const decorations = this.generateDecorations();
@@ -3809,28 +3818,40 @@ class SlateEditable {
3809
3818
  const target = firstDomElement || this.virtualTopHeightElement;
3810
3819
  EDITOR_TO_ROOT_NODE_WIDTH.set(this.editor, target.offsetWidth);
3811
3820
  updatePreRenderingElementWidth(this.editor);
3812
- this.viewportRefresh$.next();
3813
3821
  if (isDebug) {
3814
3822
  debugLog('log', 'editorResizeObserverRectWidth: ', editorResizeObserverRectWidth, 'EDITOR_TO_ROOT_NODE_WIDTH: ', EDITOR_TO_ROOT_NODE_WIDTH.get(this.editor));
3815
3823
  }
3816
3824
  }
3817
3825
  });
3818
3826
  this.editorResizeObserver.observe(this.elementRef.nativeElement);
3819
- this.viewportRefresh$.pipe(debounceTime(1000)).subscribe(() => {
3820
- // const res = measureHeightByIndics(this.editor, this.inViewportIndics);
3821
- // if (isDebug) {
3822
- // debugLog(
3823
- // 'log',
3824
- // 'viewportRefresh$ debounceTime 1000ms',
3825
- // 'inViewportIndics: ',
3826
- // this.inViewportIndics,
3827
- // 'measureHeightByIndics height changed: ',
3828
- // res
3829
- // );
3830
- // }
3827
+ let pendingRemeasureIndics = [];
3828
+ this.indicsOfNeedBeMeasured$
3829
+ .pipe(tap((previousValue) => {
3830
+ previousValue.forEach((index) => {
3831
+ if (!pendingRemeasureIndics.includes(index)) {
3832
+ pendingRemeasureIndics.push(index);
3833
+ }
3834
+ });
3835
+ }), debounceTime(500), filter(() => pendingRemeasureIndics.length > 0))
3836
+ .subscribe(() => {
3837
+ measureHeightByIndics(this.editor, pendingRemeasureIndics, true);
3838
+ pendingRemeasureIndics = [];
3839
+ if (isDebug) {
3840
+ debugLog('log', 'exist pendingRemeasureIndics: ', pendingRemeasureIndics, 'will try to update virtual viewport');
3841
+ }
3842
+ this.tryUpdateVirtualViewport();
3831
3843
  });
3832
3844
  }
3833
3845
  }
3846
+ getChangedIndics(previousValue) {
3847
+ const remeasureIndics = [];
3848
+ this.inViewportChildren.forEach((child, index) => {
3849
+ if (previousValue.indexOf(child) === -1) {
3850
+ remeasureIndics.push(this.inViewportIndics[index]);
3851
+ }
3852
+ });
3853
+ return remeasureIndics;
3854
+ }
3834
3855
  setVirtualSpaceHeight(topHeight, bottomHeight) {
3835
3856
  if (!this.virtualScrollInitialized) {
3836
3857
  return;
@@ -3846,14 +3867,14 @@ class SlateEditable {
3846
3867
  }
3847
3868
  return parseFloat(this.virtualTopHeightElement.style.height.replace('px', ''));
3848
3869
  }
3849
- handlePreRendering() {
3870
+ handlePreRendering(visibleStates) {
3850
3871
  let preRenderingCount = 0;
3851
3872
  const childrenWithPreRendering = [...this.inViewportChildren];
3852
3873
  const childrenWithPreRenderingIndics = [...this.inViewportIndics];
3853
3874
  const firstIndex = this.inViewportIndics[0];
3854
3875
  for (let index = firstIndex - 1; index >= 0; index--) {
3855
3876
  const element = this.editor.children[index];
3856
- if (this.editor.isVisible(element)) {
3877
+ if (visibleStates[index]) {
3857
3878
  childrenWithPreRendering.unshift(element);
3858
3879
  childrenWithPreRenderingIndics.unshift(index);
3859
3880
  preRenderingCount = 1;
@@ -3863,7 +3884,7 @@ class SlateEditable {
3863
3884
  const lastIndex = this.inViewportIndics[this.inViewportIndics.length - 1];
3864
3885
  for (let index = lastIndex + 1; index < this.editor.children.length; index++) {
3865
3886
  const element = this.editor.children[index];
3866
- if (this.editor.isVisible(element)) {
3887
+ if (visibleStates[index]) {
3867
3888
  childrenWithPreRendering.push(element);
3868
3889
  childrenWithPreRenderingIndics.push(index);
3869
3890
  break;
@@ -3878,7 +3899,8 @@ class SlateEditable {
3878
3899
  const isFromScrollTo = EDITOR_TO_IS_FROM_SCROLL_TO.get(this.editor);
3879
3900
  if (this.inViewportIndics.length > 0 && !isFromScrollTo) {
3880
3901
  const topHeight = this.getActualVirtualTopHeight();
3881
- const refreshVirtualTopHeight = calculateVirtualTopHeight(this.editor, this.inViewportIndics[0]);
3902
+ const visibleStates = this.editor.getAllVisibleStates();
3903
+ const refreshVirtualTopHeight = calculateVirtualTopHeight(this.editor, this.inViewportIndics[0], visibleStates);
3882
3904
  if (topHeight !== refreshVirtualTopHeight) {
3883
3905
  if (isDebug) {
3884
3906
  debugLog('log', 'update top height since dirty state(正数减去高度,负数代表增加高度): ', topHeight - refreshVirtualTopHeight);
@@ -3892,20 +3914,21 @@ class SlateEditable {
3892
3914
  if (isDebug) {
3893
3915
  debugLog('log', 'tryUpdateVirtualViewport Anim start');
3894
3916
  }
3895
- let virtualView = this.calculateVirtualViewport();
3917
+ const visibleStates = this.editor.getAllVisibleStates();
3918
+ let virtualView = this.calculateVirtualViewport(visibleStates);
3896
3919
  let diff = this.diffVirtualViewport(virtualView);
3897
3920
  if (diff.isDifferent && diff.needRemoveOnTop && !isFromScrollTo) {
3898
3921
  const remeasureIndics = diff.changedIndexesOfTop;
3899
3922
  const changed = measureHeightByIndics(this.editor, remeasureIndics);
3900
3923
  if (changed) {
3901
- virtualView = this.calculateVirtualViewport();
3924
+ virtualView = this.calculateVirtualViewport(visibleStates);
3902
3925
  diff = this.diffVirtualViewport(virtualView, 'second');
3903
3926
  }
3904
3927
  }
3905
3928
  if (diff.isDifferent) {
3906
3929
  this.applyVirtualView(virtualView);
3907
3930
  if (this.listRender.initialized) {
3908
- const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering();
3931
+ const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering(visibleStates);
3909
3932
  this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount, childrenWithPreRenderingIndics);
3910
3933
  if (diff.needAddOnTop && !isFromScrollTo) {
3911
3934
  const remeasureAddedIndics = diff.changedIndexesOfTop;
@@ -3916,7 +3939,7 @@ class SlateEditable {
3916
3939
  const topHeightBeforeAdd = virtualView.accumulatedHeights[startIndexBeforeAdd];
3917
3940
  const changed = measureHeightByIndics(this.editor, remeasureAddedIndics);
3918
3941
  if (changed) {
3919
- const newHeights = buildHeightsAndAccumulatedHeights(this.editor);
3942
+ const newHeights = buildHeightsAndAccumulatedHeights(this.editor, visibleStates);
3920
3943
  const actualTopHeightAfterAdd = newHeights.accumulatedHeights[startIndexBeforeAdd];
3921
3944
  const newTopHeight = virtualView.top - (actualTopHeightAfterAdd - topHeightBeforeAdd);
3922
3945
  this.setVirtualSpaceHeight(newTopHeight);
@@ -3928,7 +3951,6 @@ class SlateEditable {
3928
3951
  if (!AngularEditor.isReadOnly(this.editor) && this.editor.selection) {
3929
3952
  this.toNativeSelection(false);
3930
3953
  }
3931
- this.viewportRefresh$.next();
3932
3954
  }
3933
3955
  }
3934
3956
  if (isDebug) {
@@ -3936,7 +3958,7 @@ class SlateEditable {
3936
3958
  }
3937
3959
  });
3938
3960
  }
3939
- calculateVirtualViewport() {
3961
+ calculateVirtualViewport(visibleStates) {
3940
3962
  const children = (this.editor.children || []);
3941
3963
  if (!children.length || !this.isEnabledVirtualScroll()) {
3942
3964
  return {
@@ -3973,7 +3995,7 @@ class SlateEditable {
3973
3995
  }, 100);
3974
3996
  }
3975
3997
  const adjustedScrollTop = Math.max(0, scrollTop - getBusinessTop(this.editor));
3976
- const { heights, accumulatedHeights } = buildHeightsAndAccumulatedHeights(this.editor);
3998
+ const { heights, accumulatedHeights } = buildHeightsAndAccumulatedHeights(this.editor, visibleStates);
3977
3999
  const totalHeight = accumulatedHeights[elementLength];
3978
4000
  const maxScrollTop = Math.max(0, totalHeight - viewportHeight);
3979
4001
  const limitedScrollTop = Math.min(adjustedScrollTop, maxScrollTop);
@@ -3985,7 +4007,7 @@ class SlateEditable {
3985
4007
  for (let i = 0; i < elementLength && accumulatedOffset < viewBottom; i++) {
3986
4008
  const currentHeight = heights[i];
3987
4009
  const nextOffset = accumulatedOffset + currentHeight;
3988
- const isVisible = this.editor.isVisible(children[i]);
4010
+ const isVisible = visibleStates[i];
3989
4011
  if (!isVisible) {
3990
4012
  accumulatedOffset = nextOffset;
3991
4013
  continue;