slate-angular 20.2.0-next.1 → 20.2.0-next.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.
@@ -1739,6 +1739,7 @@ class BaseElementFlavour extends BaseFlavour {
1739
1739
  this.getOutletElement = () => {
1740
1740
  return this.nativeElement.querySelector('.children-outlet');
1741
1741
  };
1742
+ this.stableHeight = null;
1742
1743
  }
1743
1744
  get element() {
1744
1745
  return this._context && this._context.element;
@@ -1824,11 +1825,21 @@ class BaseElementFlavour extends BaseFlavour {
1824
1825
  readonly: this._context.readonly
1825
1826
  };
1826
1827
  }
1828
+ isStableHeight() {
1829
+ return false;
1830
+ }
1827
1831
  getRealHeight() {
1832
+ if (this.isStableHeight() && this.stableHeight !== null) {
1833
+ return this.stableHeight;
1834
+ }
1828
1835
  const blockCard = getBlockCardByNativeElement(this.nativeElement);
1829
1836
  const target = blockCard || this.nativeElement;
1830
1837
  const computedStyle = getComputedStyle(target);
1831
- return Promise.resolve(target.offsetHeight + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom));
1838
+ const height = target.offsetHeight + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom);
1839
+ if (this.isStableHeight()) {
1840
+ this.stableHeight = height;
1841
+ }
1842
+ return height;
1832
1843
  }
1833
1844
  }
1834
1845
 
@@ -2556,20 +2567,32 @@ function executeAfterViewInit(editor) {
2556
2567
  const JUST_NOW_UPDATED_VIRTUAL_VIEW = new WeakMap();
2557
2568
  // not correctly clipboardData on beforeinput
2558
2569
  const forceOnDOMPaste = IS_SAFARI;
2570
+ const isDebug = localStorage.getItem(SLATE_DEBUG_KEY) === 'true';
2559
2571
  class SlateEditable {
2560
2572
  set virtualScroll(config) {
2561
2573
  this.virtualConfig = config;
2562
2574
  this.refreshVirtualViewAnimId && cancelAnimationFrame(this.refreshVirtualViewAnimId);
2563
2575
  this.refreshVirtualViewAnimId = requestAnimationFrame(() => {
2564
- const virtualView = this.refreshVirtualView();
2565
- const diff = this.diffVirtualView(virtualView);
2566
- if (diff) {
2567
- this.applyVirtualView(virtualView);
2568
- if (this.listRender.initialized) {
2569
- this.listRender.update(virtualView.renderedChildren, this.editor, this.context);
2576
+ let virtualView = this.refreshVirtualView();
2577
+ let diff = this.diffVirtualView(virtualView);
2578
+ if (!diff.isDiff) {
2579
+ return;
2580
+ }
2581
+ if (diff.isMissingTop) {
2582
+ const result = this.remeasureHeightByIndics([...diff.diffTopRenderedIndexes]);
2583
+ if (result) {
2584
+ virtualView = this.refreshVirtualView();
2585
+ diff = this.diffVirtualView(virtualView, 'second');
2586
+ if (!diff.isDiff) {
2587
+ return;
2588
+ }
2570
2589
  }
2571
- this.scheduleMeasureVisibleHeights();
2572
2590
  }
2591
+ this.applyVirtualView(virtualView);
2592
+ if (this.listRender.initialized) {
2593
+ this.listRender.update(virtualView.renderedChildren, this.editor, this.context);
2594
+ }
2595
+ this.scheduleMeasureVisibleHeights();
2573
2596
  });
2574
2597
  }
2575
2598
  get hasBeforeInputSupport() {
@@ -2936,6 +2959,7 @@ class SlateEditable {
2936
2959
  this.elementRef.nativeElement.appendChild(this.virtualTopHeightElement);
2937
2960
  this.elementRef.nativeElement.appendChild(this.virtualCenterOutlet);
2938
2961
  this.elementRef.nativeElement.appendChild(this.virtualBottomHeightElement);
2962
+ // businessHeight
2939
2963
  }
2940
2964
  }
2941
2965
  changeVirtualHeight(topHeight, bottomHeight) {
@@ -3008,67 +3032,75 @@ class SlateEditable {
3008
3032
  this.changeVirtualHeight(virtualView.top, virtualView.bottom);
3009
3033
  this.virtualVisibleIndexes = virtualView.visibleIndexes;
3010
3034
  }
3011
- diffVirtualView(virtualView) {
3035
+ diffVirtualView(virtualView, stage = 'first') {
3012
3036
  if (!this.renderedChildren.length) {
3013
- return true;
3037
+ return {
3038
+ isDiff: true,
3039
+ diffTopRenderedIndexes: [],
3040
+ diffBottomRenderedIndexes: []
3041
+ };
3014
3042
  }
3015
3043
  const oldVisibleIndexes = [...this.virtualVisibleIndexes];
3016
3044
  const newVisibleIndexes = [...virtualView.visibleIndexes];
3017
- if (newVisibleIndexes[0] !== oldVisibleIndexes[0] ||
3018
- newVisibleIndexes[newVisibleIndexes.length - 1] !== oldVisibleIndexes[oldVisibleIndexes.length - 1]) {
3019
- if (localStorage.getItem(SLATE_DEBUG_KEY) === 'true') {
3020
- const diffTopRenderedIndexes = [];
3021
- const diffBottomRenderedIndexes = [];
3022
- let direction = '';
3023
- if (newVisibleIndexes[0] > oldVisibleIndexes[0]) {
3024
- // 向下
3025
- direction = 'down';
3026
- for (let index = 0; index < oldVisibleIndexes.length; index++) {
3027
- const element = oldVisibleIndexes[index];
3028
- if (!newVisibleIndexes.includes(element)) {
3029
- diffTopRenderedIndexes.push(element);
3030
- }
3031
- else {
3032
- break;
3033
- }
3045
+ const firstNewIndex = newVisibleIndexes[0];
3046
+ const lastNewIndex = newVisibleIndexes[newVisibleIndexes.length - 1];
3047
+ const firstOldIndex = oldVisibleIndexes[0];
3048
+ const lastOldIndex = oldVisibleIndexes[oldVisibleIndexes.length - 1];
3049
+ if (firstNewIndex !== firstOldIndex || lastNewIndex !== lastOldIndex) {
3050
+ const diffTopRenderedIndexes = [];
3051
+ const diffBottomRenderedIndexes = [];
3052
+ const isMissingTop = firstNewIndex !== firstOldIndex && firstNewIndex > firstOldIndex;
3053
+ const isAddedTop = firstNewIndex !== firstOldIndex && firstNewIndex < firstOldIndex;
3054
+ const isMissingBottom = lastNewIndex !== lastOldIndex && lastOldIndex > lastNewIndex;
3055
+ const isAddedBottom = lastNewIndex !== lastOldIndex && lastOldIndex < lastNewIndex;
3056
+ if (isMissingTop || isAddedBottom) {
3057
+ // 向下
3058
+ for (let index = 0; index < oldVisibleIndexes.length; index++) {
3059
+ const element = oldVisibleIndexes[index];
3060
+ if (!newVisibleIndexes.includes(element)) {
3061
+ diffTopRenderedIndexes.push(element);
3034
3062
  }
3035
- for (let index = newVisibleIndexes.length - 1; index >= 0; index--) {
3036
- const element = newVisibleIndexes[index];
3037
- if (!oldVisibleIndexes.includes(element)) {
3038
- diffBottomRenderedIndexes.push(element);
3039
- }
3040
- else {
3041
- break;
3042
- }
3063
+ else {
3064
+ break;
3043
3065
  }
3044
3066
  }
3045
- else {
3046
- // 向上
3047
- direction = 'up';
3048
- for (let index = 0; index < newVisibleIndexes.length; index++) {
3049
- const element = newVisibleIndexes[index];
3050
- if (!oldVisibleIndexes.includes(element)) {
3051
- diffTopRenderedIndexes.push(element);
3052
- }
3053
- else {
3054
- break;
3055
- }
3067
+ for (let index = newVisibleIndexes.length - 1; index >= 0; index--) {
3068
+ const element = newVisibleIndexes[index];
3069
+ if (!oldVisibleIndexes.includes(element)) {
3070
+ diffBottomRenderedIndexes.push(element);
3056
3071
  }
3057
- for (let index = oldVisibleIndexes.length - 1; index >= 0; index--) {
3058
- const element = oldVisibleIndexes[index];
3059
- if (!newVisibleIndexes.includes(element)) {
3060
- diffBottomRenderedIndexes.push(element);
3061
- }
3062
- else {
3063
- break;
3064
- }
3072
+ else {
3073
+ break;
3074
+ }
3075
+ }
3076
+ }
3077
+ else if (isAddedTop || isMissingBottom) {
3078
+ // 向上
3079
+ for (let index = 0; index < newVisibleIndexes.length; index++) {
3080
+ const element = newVisibleIndexes[index];
3081
+ if (!oldVisibleIndexes.includes(element)) {
3082
+ diffTopRenderedIndexes.push(element);
3083
+ }
3084
+ else {
3085
+ break;
3086
+ }
3087
+ }
3088
+ for (let index = oldVisibleIndexes.length - 1; index >= 0; index--) {
3089
+ const element = oldVisibleIndexes[index];
3090
+ if (!newVisibleIndexes.includes(element)) {
3091
+ diffBottomRenderedIndexes.push(element);
3092
+ }
3093
+ else {
3094
+ break;
3065
3095
  }
3066
3096
  }
3097
+ }
3098
+ if (isDebug) {
3099
+ console.log(`====== diffVirtualView stage: ${stage} ======`);
3067
3100
  console.log('oldVisibleIndexes:', oldVisibleIndexes);
3068
3101
  console.log('newVisibleIndexes:', newVisibleIndexes);
3069
- const directionStr = direction === 'down' ? '+' : '-';
3070
- console.log('diffTopRenderedIndexes:', directionStr, diffTopRenderedIndexes, diffTopRenderedIndexes.map(index => virtualView.heights[index]));
3071
- console.log('diffBottomRenderedIndexes:', directionStr, diffBottomRenderedIndexes, diffBottomRenderedIndexes.map(index => virtualView.heights[index]));
3102
+ console.log('diffTopRenderedIndexes:', isMissingTop ? '-' : isAddedTop ? '+' : '-', diffTopRenderedIndexes, diffTopRenderedIndexes.map(index => this.getBlockHeight(index, 0)));
3103
+ console.log('diffBottomRenderedIndexes:', isAddedBottom ? '+' : isMissingBottom ? '-' : '+', diffBottomRenderedIndexes, diffBottomRenderedIndexes.map(index => this.getBlockHeight(index, 0)));
3072
3104
  const needTop = virtualView.heights.slice(0, newVisibleIndexes[0]).reduce((acc, height) => acc + height, 0);
3073
3105
  const needBottom = virtualView.heights
3074
3106
  .slice(newVisibleIndexes[newVisibleIndexes.length - 1] + 1)
@@ -3077,17 +3109,29 @@ class SlateEditable {
3077
3109
  console.log('newBottomHeight:', needBottom, 'prevBottomHeight:', parseFloat(this.virtualBottomHeightElement.style.height));
3078
3110
  console.warn('=========== Dividing line ===========');
3079
3111
  }
3080
- return true;
3112
+ return {
3113
+ isDiff: true,
3114
+ isMissingTop,
3115
+ isAddedTop,
3116
+ isMissingBottom,
3117
+ isAddedBottom,
3118
+ diffTopRenderedIndexes,
3119
+ diffBottomRenderedIndexes
3120
+ };
3081
3121
  }
3082
- return false;
3122
+ return {
3123
+ isDiff: false,
3124
+ diffTopRenderedIndexes: [],
3125
+ diffBottomRenderedIndexes: []
3126
+ };
3083
3127
  }
3084
- getBlockHeight(index) {
3128
+ getBlockHeight(index, defaultHeight = VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT) {
3085
3129
  const node = this.editor.children[index];
3086
3130
  if (!node) {
3087
- return VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT;
3131
+ return defaultHeight;
3088
3132
  }
3089
3133
  const key = AngularEditor.findKey(this.editor, node);
3090
- return this.measuredHeights.get(key.id) ?? VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT;
3134
+ return this.measuredHeights.get(key.id) ?? defaultHeight;
3091
3135
  }
3092
3136
  buildAccumulatedHeight(heights) {
3093
3137
  const accumulatedHeights = new Array(heights.length + 1).fill(0);
@@ -3115,14 +3159,9 @@ class SlateEditable {
3115
3159
  if (!this.shouldUseVirtual()) {
3116
3160
  return;
3117
3161
  }
3118
- if (this.measurePending) {
3119
- return;
3120
- }
3121
- this.measurePending = true;
3122
3162
  this.measureVisibleHeightsAnimId && cancelAnimationFrame(this.measureVisibleHeightsAnimId);
3123
3163
  this.measureVisibleHeightsAnimId = requestAnimationFrame(() => {
3124
3164
  this.measureVisibleHeights();
3125
- this.measurePending = false;
3126
3165
  });
3127
3166
  }
3128
3167
  measureVisibleHeights() {
@@ -3141,11 +3180,55 @@ class SlateEditable {
3141
3180
  if (!view) {
3142
3181
  return;
3143
3182
  }
3144
- view.getRealHeight()?.then(height => {
3145
- this.measuredHeights.set(key.id, height);
3146
- });
3183
+ const ret = view.getRealHeight();
3184
+ if (ret instanceof Promise) {
3185
+ ret.then(height => {
3186
+ this.measuredHeights.set(key.id, height);
3187
+ });
3188
+ }
3189
+ else {
3190
+ this.measuredHeights.set(key.id, ret);
3191
+ }
3147
3192
  });
3148
3193
  }
3194
+ remeasureHeightByIndics(indics) {
3195
+ const children = (this.editor.children || []);
3196
+ let isHeightChanged = false;
3197
+ indics.forEach(index => {
3198
+ const node = children[index];
3199
+ if (!node) {
3200
+ return;
3201
+ }
3202
+ const key = AngularEditor.findKey(this.editor, node);
3203
+ const view = ELEMENT_TO_COMPONENT.get(node);
3204
+ if (!view) {
3205
+ return;
3206
+ }
3207
+ const prevHeight = this.measuredHeights.get(key.id);
3208
+ const ret = view.getRealHeight();
3209
+ if (ret instanceof Promise) {
3210
+ ret.then(height => {
3211
+ if (height !== prevHeight) {
3212
+ this.measuredHeights.set(key.id, height);
3213
+ isHeightChanged = true;
3214
+ if (isDebug) {
3215
+ console.log(`remeasureHeightByIndics, index: ${index} prevHeight: ${prevHeight} newHeight: ${height}`);
3216
+ }
3217
+ }
3218
+ });
3219
+ }
3220
+ else {
3221
+ if (ret !== prevHeight) {
3222
+ this.measuredHeights.set(key.id, ret);
3223
+ isHeightChanged = true;
3224
+ if (isDebug) {
3225
+ console.log(`remeasureHeightByIndics, index: ${index} prevHeight: ${prevHeight} newHeight: ${ret}`);
3226
+ }
3227
+ }
3228
+ }
3229
+ });
3230
+ return isHeightChanged;
3231
+ }
3149
3232
  //#region event proxy
3150
3233
  addEventListener(eventName, listener, target = this.elementRef.nativeElement) {
3151
3234
  this.manualListeners.push(this.renderer2.listen(target, eventName, (event) => {
@@ -4096,6 +4179,7 @@ class BaseElementComponent extends BaseComponent {
4096
4179
  }
4097
4180
  return null;
4098
4181
  };
4182
+ this.stableHeight = null;
4099
4183
  }
4100
4184
  get element() {
4101
4185
  return this._context && this._context.element;
@@ -4177,11 +4261,21 @@ class BaseElementComponent extends BaseComponent {
4177
4261
  readonly: this._context.readonly
4178
4262
  };
4179
4263
  }
4264
+ isStableHeight() {
4265
+ return false;
4266
+ }
4180
4267
  getRealHeight() {
4268
+ if (this.isStableHeight() && this.stableHeight !== null) {
4269
+ return this.stableHeight;
4270
+ }
4181
4271
  const blockCard = getBlockCardByNativeElement(this.nativeElement);
4182
4272
  const target = blockCard || this.nativeElement;
4183
4273
  const computedStyle = getComputedStyle(target);
4184
- return Promise.resolve(target.offsetHeight + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom));
4274
+ const height = target.offsetHeight + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom);
4275
+ if (this.isStableHeight()) {
4276
+ this.stableHeight = height;
4277
+ }
4278
+ return height;
4185
4279
  }
4186
4280
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BaseElementComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
4187
4281
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.12", type: BaseElementComponent, isStandalone: true, viewQueries: [{ propertyName: "childrenOutletInstance", first: true, predicate: SlateChildrenOutlet, descendants: true, static: true }], usesInheritance: true, ngImport: i0 }); }