slate-angular 20.2.1 → 20.2.3

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 } from 'rxjs';
8
+ import { Subject, debounceTime } 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';
@@ -1491,11 +1491,7 @@ 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, isVisible) => {
1495
- const visible = isVisible ?? editor.isVisible(element);
1496
- if (!visible) {
1497
- return 0;
1498
- }
1494
+ const getRealHeightByElement = (editor, element, defaultHeight) => {
1499
1495
  const heights = ELEMENT_KEY_TO_HEIGHTS.get(editor);
1500
1496
  const key = AngularEditor.findKey(editor, element);
1501
1497
  const height = heights?.get(key.id);
@@ -1505,22 +1501,20 @@ const getRealHeightByElement = (editor, element, defaultHeight = VIRTUAL_SCROLL_
1505
1501
  if (heights?.has(key.id)) {
1506
1502
  console.error('getBlockHeight: invalid height value', key.id, height);
1507
1503
  }
1508
- return defaultHeight;
1504
+ return editor.getRoughHeight(element, defaultHeight);
1509
1505
  };
1510
1506
  const buildHeightsAndAccumulatedHeights = (editor) => {
1511
1507
  const children = (editor.children || []);
1512
1508
  const heights = new Array(children.length);
1513
- const visibles = new Array(children.length);
1509
+ const visibleStates = new Array(children.length);
1514
1510
  const accumulatedHeights = new Array(children.length + 1);
1515
1511
  accumulatedHeights[0] = 0;
1516
1512
  for (let i = 0; i < children.length; i++) {
1517
- const isVisible = editor.isVisible(children[i]);
1518
- visibles[i] = isVisible;
1519
- const height = getRealHeightByElement(editor, children[i], VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT, isVisible);
1513
+ const height = getRealHeightByElement(editor, children[i], VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT);
1520
1514
  heights[i] = height;
1521
1515
  accumulatedHeights[i + 1] = accumulatedHeights[i] + height;
1522
1516
  }
1523
- return { heights, accumulatedHeights, visibles };
1517
+ return { heights, accumulatedHeights, visibleStates };
1524
1518
  };
1525
1519
  const calculateVirtualTopHeight = (editor, startIndex) => {
1526
1520
  const { accumulatedHeights } = buildHeightsAndAccumulatedHeights(editor);
@@ -1737,6 +1731,9 @@ const withAngular = (editor, clipboardFormatKey = 'x-slate-fragment') => {
1737
1731
  e.isVisible = element => {
1738
1732
  return true;
1739
1733
  };
1734
+ e.getRoughHeight = (element, defaultHeight) => {
1735
+ return defaultHeight === undefined ? VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT : defaultHeight;
1736
+ };
1740
1737
  return e;
1741
1738
  };
1742
1739
 
@@ -2341,7 +2338,6 @@ class BaseElementFlavour extends BaseFlavour {
2341
2338
  this.getOutletElement = () => {
2342
2339
  return this.nativeElement.querySelector('.children-outlet');
2343
2340
  };
2344
- this.stableHeight = null;
2345
2341
  }
2346
2342
  get element() {
2347
2343
  return this._context && this._context.element;
@@ -2428,20 +2424,11 @@ class BaseElementFlavour extends BaseFlavour {
2428
2424
  readonly: this._context.readonly
2429
2425
  };
2430
2426
  }
2431
- isStableHeight() {
2432
- return false;
2433
- }
2434
2427
  getRealHeight() {
2435
- if (this.isStableHeight() && this.stableHeight !== null) {
2436
- return this.stableHeight;
2437
- }
2438
2428
  const blockCard = getBlockCardByNativeElement(this.nativeElement);
2439
2429
  const target = blockCard || this.nativeElement;
2440
2430
  const computedStyle = getComputedStyle(target);
2441
2431
  const height = Math.ceil(target.getBoundingClientRect().height) + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom);
2442
- if (this.isStableHeight()) {
2443
- this.stableHeight = height;
2444
- }
2445
2432
  return height;
2446
2433
  }
2447
2434
  }
@@ -2622,6 +2609,9 @@ class SlateStringRender {
2622
2609
  if (this.type === StringType.normalString) {
2623
2610
  this.nativeElement.textContent = this.leaf.text;
2624
2611
  }
2612
+ if (this.type === StringType.compatibleString) {
2613
+ updateCompatibleStringNode(this.nativeElement, this.leaf.text);
2614
+ }
2625
2615
  }
2626
2616
  getElementStringLength() {
2627
2617
  return Node.string(this.context.parent).length;
@@ -2656,6 +2646,12 @@ const createCompatibleStringNode = (text) => {
2656
2646
  stringNode.appendChild(zeroWidthSpan);
2657
2647
  return stringNode;
2658
2648
  };
2649
+ const updateCompatibleStringNode = (stringNode, text) => {
2650
+ const zeroWidthSpan = stringNode.querySelector('span');
2651
+ stringNode.textContent = text;
2652
+ stringNode.appendChild(zeroWidthSpan);
2653
+ return stringNode;
2654
+ };
2659
2655
  const createLineBreakEmptyStringDOM = (elementStringLength) => {
2660
2656
  const stringNode = document.createElement('span');
2661
2657
  stringNode.setAttribute('data-slate-zero-width', 'n');
@@ -3314,6 +3310,7 @@ class SlateEditable {
3314
3310
  this.inViewportChildren = [];
3315
3311
  this.inViewportIndics = [];
3316
3312
  this.keyHeightMap = new Map();
3313
+ this.viewportRefresh$ = new Subject();
3317
3314
  this.virtualScrollInitialized = false;
3318
3315
  }
3319
3316
  ngOnInit() {
@@ -3385,6 +3382,7 @@ class SlateEditable {
3385
3382
  const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering();
3386
3383
  this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount, childrenWithPreRenderingIndics);
3387
3384
  }
3385
+ this.viewportRefresh$.next();
3388
3386
  }
3389
3387
  else {
3390
3388
  if (!this.listRender.initialized) {
@@ -3628,21 +3626,28 @@ class SlateEditable {
3628
3626
  }
3629
3627
  }
3630
3628
  updateListRenderAndRemeasureHeights() {
3631
- const virtualView = this.calculateVirtualViewport();
3632
- const oldInViewportChildren = this.inViewportChildren;
3629
+ let virtualView = this.calculateVirtualViewport();
3630
+ let diff = this.diffVirtualViewport(virtualView, 'onChange');
3631
+ if (diff.isDifferent && diff.needRemoveOnTop) {
3632
+ const remeasureIndics = diff.changedIndexesOfTop;
3633
+ const changed = measureHeightByIndics(this.editor, remeasureIndics);
3634
+ if (changed) {
3635
+ virtualView = this.calculateVirtualViewport();
3636
+ diff = this.diffVirtualViewport(virtualView, 'second');
3637
+ }
3638
+ }
3639
+ // const oldInViewportChildren = this.inViewportChildren;
3633
3640
  this.applyVirtualView(virtualView);
3634
3641
  const { preRenderingCount, childrenWithPreRendering, childrenWithPreRenderingIndics } = this.handlePreRendering();
3635
3642
  this.listRender.update(childrenWithPreRendering, this.editor, this.context, preRenderingCount, childrenWithPreRenderingIndics);
3636
3643
  // 新增或者修改的才需要重算,计算出这个结果
3637
- const remeasureIndics = [];
3638
- this.inViewportChildren.forEach((child, index) => {
3639
- if (oldInViewportChildren.indexOf(child) === -1) {
3640
- remeasureIndics.push(this.inViewportIndics[index]);
3641
- }
3642
- });
3643
- if (isDebug && remeasureIndics.length > 0) {
3644
- console.log('remeasure height by indics: ', remeasureIndics);
3645
- }
3644
+ // const remeasureIndics = [];
3645
+ // this.inViewportChildren.forEach((child, index) => {
3646
+ // if (oldInViewportChildren.indexOf(child) === -1) {
3647
+ // remeasureIndics.push(this.inViewportIndics[index]);
3648
+ // }
3649
+ // });
3650
+ this.viewportRefresh$.next();
3646
3651
  }
3647
3652
  updateContext() {
3648
3653
  const decorations = this.generateDecorations();
@@ -3730,15 +3735,27 @@ class SlateEditable {
3730
3735
  if (entries.length > 0 && entries[0].contentRect.width !== editorResizeObserverRectWidth) {
3731
3736
  editorResizeObserverRectWidth = entries[0].contentRect.width;
3732
3737
  this.keyHeightMap.clear();
3733
- const remeasureIndics = this.inViewportIndics;
3734
- measureHeightByIndics(this.editor, remeasureIndics, true);
3735
3738
  EDITOR_TO_ROOT_NODE_WIDTH.set(this.editor, this.virtualTopHeightElement.getBoundingClientRect().width);
3739
+ this.viewportRefresh$.next();
3736
3740
  if (isDebug) {
3737
3741
  debugLog('log', 'editorResizeObserverRectWidth: ', editorResizeObserverRectWidth, 'EDITOR_TO_ROOT_NODE_WIDTH: ', EDITOR_TO_ROOT_NODE_WIDTH.get(this.editor));
3738
3742
  }
3739
3743
  }
3740
3744
  });
3741
3745
  this.editorResizeObserver.observe(this.elementRef.nativeElement);
3746
+ this.viewportRefresh$.pipe(debounceTime(1000)).subscribe(() => {
3747
+ // const res = measureHeightByIndics(this.editor, this.inViewportIndics);
3748
+ // if (isDebug) {
3749
+ // debugLog(
3750
+ // 'log',
3751
+ // 'viewportRefresh$ debounceTime 1000ms',
3752
+ // 'inViewportIndics: ',
3753
+ // this.inViewportIndics,
3754
+ // 'measureHeightByIndics height changed: ',
3755
+ // res
3756
+ // );
3757
+ // }
3758
+ });
3742
3759
  }
3743
3760
  }
3744
3761
  setVirtualSpaceHeight(topHeight, bottomHeight) {
@@ -3837,6 +3854,7 @@ class SlateEditable {
3837
3854
  if (!AngularEditor.isReadOnly(this.editor) && this.editor.selection) {
3838
3855
  this.toNativeSelection(false);
3839
3856
  }
3857
+ this.viewportRefresh$.next();
3840
3858
  }
3841
3859
  }
3842
3860
  if (isDebug) {
@@ -3881,7 +3899,7 @@ class SlateEditable {
3881
3899
  }, 100);
3882
3900
  }
3883
3901
  const adjustedScrollTop = Math.max(0, scrollTop - getBusinessTop(this.editor));
3884
- const { heights, accumulatedHeights, visibles } = buildHeightsAndAccumulatedHeights(this.editor);
3902
+ const { heights, accumulatedHeights, visibleStates } = buildHeightsAndAccumulatedHeights(this.editor);
3885
3903
  const totalHeight = accumulatedHeights[elementLength];
3886
3904
  const maxScrollTop = Math.max(0, totalHeight - viewportHeight);
3887
3905
  const limitedScrollTop = Math.min(adjustedScrollTop, maxScrollTop);
@@ -3893,7 +3911,7 @@ class SlateEditable {
3893
3911
  for (let i = 0; i < elementLength && accumulatedOffset < viewBottom; i++) {
3894
3912
  const currentHeight = heights[i];
3895
3913
  const nextOffset = accumulatedOffset + currentHeight;
3896
- if (!visibles[i]) {
3914
+ if (!visibleStates[i]) {
3897
3915
  accumulatedOffset = nextOffset;
3898
3916
  continue;
3899
3917
  }
@@ -4002,8 +4020,13 @@ class SlateEditable {
4002
4020
  debugLog('log', `====== diffVirtualViewport stage: ${stage} ======`);
4003
4021
  debugLog('log', 'oldIndexesInViewport:', oldIndexesInViewport);
4004
4022
  debugLog('log', 'newIndexesInViewport:', newIndexesInViewport);
4005
- debugLog('log', 'changedIndexesOfTop:', needRemoveOnTop ? '-' : needAddOnTop ? '+' : '-', changedIndexesOfTop, changedIndexesOfTop.map(index => getRealHeightByElement(this.editor, this.editor.children[index], 0)));
4006
- debugLog('log', 'changedIndexesOfBottom:', needAddOnBottom ? '+' : needRemoveOnBottom ? '-' : '+', changedIndexesOfBottom, changedIndexesOfBottom.map(index => getRealHeightByElement(this.editor, this.editor.children[index], 0)));
4023
+ // this.editor.children[index] will be undefined when it is removed
4024
+ debugLog('log', 'changedIndexesOfTop:', needRemoveOnTop ? '-' : needAddOnTop ? '+' : '-', changedIndexesOfTop, changedIndexesOfTop.map(index => (this.editor.children[index] &&
4025
+ getRealHeightByElement(this.editor, this.editor.children[index], 0)) ||
4026
+ 0));
4027
+ debugLog('log', 'changedIndexesOfBottom:', needAddOnBottom ? '+' : needRemoveOnBottom ? '-' : '+', changedIndexesOfBottom, changedIndexesOfBottom.map(index => (this.editor.children[index] &&
4028
+ getRealHeightByElement(this.editor, this.editor.children[index], 0)) ||
4029
+ 0));
4007
4030
  const needTop = virtualView.heights.slice(0, newIndexesInViewport[0]).reduce((acc, height) => acc + height, 0);
4008
4031
  const needBottom = virtualView.heights
4009
4032
  .slice(newIndexesInViewport[newIndexesInViewport.length - 1] + 1)
@@ -5003,7 +5026,6 @@ class BaseElementComponent extends BaseComponent {
5003
5026
  }
5004
5027
  return null;
5005
5028
  };
5006
- this.stableHeight = null;
5007
5029
  }
5008
5030
  get element() {
5009
5031
  return this._context && this._context.element;
@@ -5086,20 +5108,11 @@ class BaseElementComponent extends BaseComponent {
5086
5108
  readonly: this._context.readonly
5087
5109
  };
5088
5110
  }
5089
- isStableHeight() {
5090
- return false;
5091
- }
5092
5111
  getRealHeight() {
5093
- if (this.isStableHeight() && this.stableHeight !== null) {
5094
- return this.stableHeight;
5095
- }
5096
5112
  const blockCard = getBlockCardByNativeElement(this.nativeElement);
5097
5113
  const target = blockCard || this.nativeElement;
5098
5114
  const computedStyle = getComputedStyle(target);
5099
5115
  const height = Math.ceil(target.getBoundingClientRect().height) + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom);
5100
- if (this.isStableHeight()) {
5101
- this.stableHeight = height;
5102
- }
5103
5116
  return height;
5104
5117
  }
5105
5118
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BaseElementComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }