slate-angular 20.2.0-next.0 → 20.2.0-next.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.
@@ -472,6 +472,7 @@ const HAS_BEFORE_INPUT_SUPPORT = !IS_CHROME_LEGACY &&
472
472
  typeof globalThis.InputEvent.prototype.getTargetRanges === 'function';
473
473
  const VIRTUAL_SCROLL_DEFAULT_BUFFER_COUNT = 3;
474
474
  const VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT = 40;
475
+ const SLATE_DEBUG_KEY = '__SLATE_DEBUG__';
475
476
 
476
477
  /**
477
478
  * Hotkey mappings for each platform.
@@ -1685,6 +1686,49 @@ class BaseFlavour {
1685
1686
  }
1686
1687
  }
1687
1688
 
1689
+ const SLATE_BLOCK_CARD_CLASS_NAME = 'slate-block-card';
1690
+ class SlateBlockCard {
1691
+ onInit() {
1692
+ const nativeElement = document.createElement('div');
1693
+ nativeElement.classList.add(SLATE_BLOCK_CARD_CLASS_NAME);
1694
+ this.nativeElement = nativeElement;
1695
+ this.createContent();
1696
+ }
1697
+ createContent() {
1698
+ const leftCaret = document.createElement('span');
1699
+ leftCaret.setAttribute(`card-target`, 'card-left');
1700
+ leftCaret.classList.add('card-left');
1701
+ leftCaret.appendChild(getZeroTextNode());
1702
+ const rightCaret = document.createElement('span');
1703
+ rightCaret.setAttribute(`card-target`, 'card-right');
1704
+ rightCaret.classList.add('card-right');
1705
+ rightCaret.appendChild(getZeroTextNode());
1706
+ const center = document.createElement('div');
1707
+ center.setAttribute(`card-target`, 'card-center');
1708
+ this.nativeElement.appendChild(leftCaret);
1709
+ this.nativeElement.appendChild(center);
1710
+ this.nativeElement.appendChild(rightCaret);
1711
+ this.centerContainer = center;
1712
+ }
1713
+ append() {
1714
+ this.centerRootNodes.forEach(rootNode => !this.centerContainer.contains(rootNode) && this.centerContainer.appendChild(rootNode));
1715
+ }
1716
+ initializeCenter(rootNodes) {
1717
+ this.centerRootNodes = rootNodes;
1718
+ this.append();
1719
+ }
1720
+ onDestroy() {
1721
+ this.nativeElement.remove();
1722
+ }
1723
+ }
1724
+ const getBlockCardByNativeElement = (nativeElement) => {
1725
+ const blockCardElement = nativeElement?.parentElement?.parentElement;
1726
+ if (blockCardElement && blockCardElement.classList.contains(SLATE_BLOCK_CARD_CLASS_NAME)) {
1727
+ return blockCardElement;
1728
+ }
1729
+ return null;
1730
+ };
1731
+
1688
1732
  const DEFAULT_ELEMENT_HEIGHT = 24;
1689
1733
  class BaseElementFlavour extends BaseFlavour {
1690
1734
  constructor() {
@@ -1781,7 +1825,10 @@ class BaseElementFlavour extends BaseFlavour {
1781
1825
  };
1782
1826
  }
1783
1827
  getRealHeight() {
1784
- return Promise.resolve(this.nativeElement.offsetHeight);
1828
+ const blockCard = getBlockCardByNativeElement(this.nativeElement);
1829
+ const target = blockCard || this.nativeElement;
1830
+ const computedStyle = getComputedStyle(target);
1831
+ return Promise.resolve(target.offsetHeight + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom));
1785
1832
  }
1786
1833
  }
1787
1834
 
@@ -2209,49 +2256,6 @@ const createText = (text) => {
2209
2256
  return { nativeElement };
2210
2257
  };
2211
2258
 
2212
- const SLATE_BLOCK_CARD_CLASS_NAME = 'slate-block-card';
2213
- class SlateBlockCard {
2214
- onInit() {
2215
- const nativeElement = document.createElement('div');
2216
- nativeElement.classList.add(SLATE_BLOCK_CARD_CLASS_NAME);
2217
- this.nativeElement = nativeElement;
2218
- this.createContent();
2219
- }
2220
- createContent() {
2221
- const leftCaret = document.createElement('span');
2222
- leftCaret.setAttribute(`card-target`, 'card-left');
2223
- leftCaret.classList.add('card-left');
2224
- leftCaret.appendChild(getZeroTextNode());
2225
- const rightCaret = document.createElement('span');
2226
- rightCaret.setAttribute(`card-target`, 'card-right');
2227
- rightCaret.classList.add('card-right');
2228
- rightCaret.appendChild(getZeroTextNode());
2229
- const center = document.createElement('div');
2230
- center.setAttribute(`card-target`, 'card-center');
2231
- this.nativeElement.appendChild(leftCaret);
2232
- this.nativeElement.appendChild(center);
2233
- this.nativeElement.appendChild(rightCaret);
2234
- this.centerContainer = center;
2235
- }
2236
- append() {
2237
- this.centerRootNodes.forEach(rootNode => !this.centerContainer.contains(rootNode) && this.centerContainer.appendChild(rootNode));
2238
- }
2239
- initializeCenter(rootNodes) {
2240
- this.centerRootNodes = rootNodes;
2241
- this.append();
2242
- }
2243
- onDestroy() {
2244
- this.nativeElement.remove();
2245
- }
2246
- }
2247
- const getBlockCardByNativeElement = (nativeElement) => {
2248
- const blockCardElement = nativeElement?.parentElement?.parentElement;
2249
- if (blockCardElement && blockCardElement.classList.contains(SLATE_BLOCK_CARD_CLASS_NAME)) {
2250
- return blockCardElement;
2251
- }
2252
- return null;
2253
- };
2254
-
2255
2259
  class ListRender {
2256
2260
  constructor(viewContext, viewContainerRef, getOutletParent, getOutletElement) {
2257
2261
  this.viewContext = viewContext;
@@ -2549,18 +2553,38 @@ function executeAfterViewInit(editor) {
2549
2553
  clearAfterViewInitQueue(editor);
2550
2554
  }
2551
2555
 
2556
+ const JUST_NOW_UPDATED_VIRTUAL_VIEW = new WeakMap();
2552
2557
  // not correctly clipboardData on beforeinput
2553
2558
  const forceOnDOMPaste = IS_SAFARI;
2559
+ const isDebug = localStorage.getItem(SLATE_DEBUG_KEY) === 'true';
2554
2560
  class SlateEditable {
2555
2561
  set virtualScroll(config) {
2556
2562
  this.virtualConfig = config;
2557
2563
  this.refreshVirtualViewAnimId && cancelAnimationFrame(this.refreshVirtualViewAnimId);
2558
2564
  this.refreshVirtualViewAnimId = requestAnimationFrame(() => {
2559
- this.refreshVirtualView();
2560
- if (this.listRender.initialized) {
2561
- this.listRender.update(this.renderedChildren, this.editor, this.context);
2565
+ const virtualView = this.refreshVirtualView();
2566
+ const diff = this.diffVirtualView(virtualView);
2567
+ if (diff.isDiff) {
2568
+ if (diff.isMissingTop || diff.isMissingBottom) {
2569
+ this.measureHeightByIndexes([...diff.diffTopRenderedIndexes, ...diff.diffBottomRenderedIndexes], true).then(result => {
2570
+ if (isDebug) {
2571
+ console.log('async measureHeightByIndexes:', result);
2572
+ }
2573
+ this.applyVirtualView(result || virtualView);
2574
+ if (this.listRender.initialized) {
2575
+ this.listRender.update(this.renderedChildren, this.editor, this.context);
2576
+ }
2577
+ this.scheduleMeasureVisibleHeights();
2578
+ });
2579
+ }
2580
+ else {
2581
+ this.applyVirtualView(virtualView);
2582
+ if (this.listRender.initialized) {
2583
+ this.listRender.update(virtualView.renderedChildren, this.editor, this.context);
2584
+ }
2585
+ this.scheduleMeasureVisibleHeights();
2586
+ }
2562
2587
  }
2563
- this.scheduleMeasureVisibleHeights();
2564
2588
  });
2565
2589
  }
2566
2590
  get hasBeforeInputSupport() {
@@ -2585,8 +2609,6 @@ class SlateEditable {
2585
2609
  this.isStrictDecorate = true;
2586
2610
  this.trackBy = () => null;
2587
2611
  this.readonly = false;
2588
- this.virtualTopPadding = 0;
2589
- this.virtualBottomPadding = 0;
2590
2612
  //#endregion
2591
2613
  //#region DOM attr
2592
2614
  this.spellCheck = false;
@@ -2600,6 +2622,14 @@ class SlateEditable {
2600
2622
  this.getOutletParent = () => {
2601
2623
  return this.elementRef.nativeElement;
2602
2624
  };
2625
+ this.getOutletElement = () => {
2626
+ if (this.virtualScrollInitialized) {
2627
+ return this.virtualCenterOutlet;
2628
+ }
2629
+ else {
2630
+ return null;
2631
+ }
2632
+ };
2603
2633
  this.virtualConfig = {
2604
2634
  enabled: false,
2605
2635
  scrollTop: 0,
@@ -2609,6 +2639,7 @@ class SlateEditable {
2609
2639
  this.virtualVisibleIndexes = new Set();
2610
2640
  this.measuredHeights = new Map();
2611
2641
  this.measurePending = false;
2642
+ this.virtualScrollInitialized = false;
2612
2643
  }
2613
2644
  ngOnInit() {
2614
2645
  this.editor.injector = this.injector;
@@ -2632,7 +2663,8 @@ class SlateEditable {
2632
2663
  // add browser class
2633
2664
  let browserClass = IS_FIREFOX ? 'firefox' : IS_SAFARI ? 'safari' : '';
2634
2665
  browserClass && this.elementRef.nativeElement.classList.add(browserClass);
2635
- this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletParent, () => null);
2666
+ this.initializeVirtualScrolling();
2667
+ this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
2636
2668
  }
2637
2669
  ngOnChanges(simpleChanges) {
2638
2670
  if (!this.initialized) {
@@ -2663,8 +2695,9 @@ class SlateEditable {
2663
2695
  if (value && value.length) {
2664
2696
  this.editor.children = value;
2665
2697
  this.initializeContext();
2666
- this.refreshVirtualView();
2667
- const childrenForRender = this.renderedChildren;
2698
+ const virtualView = this.refreshVirtualView();
2699
+ this.applyVirtualView(virtualView);
2700
+ const childrenForRender = virtualView.renderedChildren;
2668
2701
  if (!this.listRender.initialized) {
2669
2702
  this.listRender.initialize(childrenForRender, this.editor, this.context);
2670
2703
  }
@@ -2792,8 +2825,9 @@ class SlateEditable {
2792
2825
  ngDoCheck() { }
2793
2826
  forceRender() {
2794
2827
  this.updateContext();
2795
- this.refreshVirtualView();
2796
- this.listRender.update(this.renderedChildren, this.editor, this.context);
2828
+ const virtualView = this.refreshVirtualView();
2829
+ this.applyVirtualView(virtualView);
2830
+ this.listRender.update(virtualView.renderedChildren, this.editor, this.context);
2797
2831
  this.scheduleMeasureVisibleHeights();
2798
2832
  // repair collaborative editing when Chinese input is interrupted by other users' cursors
2799
2833
  // when the DOMElement where the selection is located is removed
@@ -2833,8 +2867,9 @@ class SlateEditable {
2833
2867
  render() {
2834
2868
  const changed = this.updateContext();
2835
2869
  if (changed) {
2836
- this.refreshVirtualView();
2837
- this.listRender.update(this.renderedChildren, this.editor, this.context);
2870
+ const virtualView = this.refreshVirtualView();
2871
+ this.applyVirtualView(virtualView);
2872
+ this.listRender.update(virtualView.renderedChildren, this.editor, this.context);
2838
2873
  this.scheduleMeasureVisibleHeights();
2839
2874
  }
2840
2875
  }
@@ -2901,29 +2936,56 @@ class SlateEditable {
2901
2936
  shouldUseVirtual() {
2902
2937
  return !!(this.virtualConfig && this.virtualConfig.enabled);
2903
2938
  }
2939
+ initializeVirtualScrolling() {
2940
+ if (this.virtualScrollInitialized) {
2941
+ return;
2942
+ }
2943
+ if (this.virtualConfig && this.virtualConfig.enabled) {
2944
+ this.virtualScrollInitialized = true;
2945
+ this.virtualTopHeightElement = document.createElement('div');
2946
+ this.virtualTopHeightElement.classList.add('virtual-top-height');
2947
+ this.virtualBottomHeightElement = document.createElement('div');
2948
+ this.virtualBottomHeightElement.classList.add('virtual-bottom-height');
2949
+ this.virtualCenterOutlet = document.createElement('div');
2950
+ this.virtualCenterOutlet.classList.add('virtual-center-outlet');
2951
+ this.elementRef.nativeElement.appendChild(this.virtualTopHeightElement);
2952
+ this.elementRef.nativeElement.appendChild(this.virtualCenterOutlet);
2953
+ this.elementRef.nativeElement.appendChild(this.virtualBottomHeightElement);
2954
+ }
2955
+ }
2956
+ changeVirtualHeight(topHeight, bottomHeight) {
2957
+ if (!this.virtualScrollInitialized) {
2958
+ return;
2959
+ }
2960
+ this.virtualTopHeightElement.style.height = `${topHeight}px`;
2961
+ this.virtualBottomHeightElement.style.height = `${bottomHeight}px`;
2962
+ }
2904
2963
  refreshVirtualView() {
2905
2964
  const children = (this.editor.children || []);
2906
2965
  if (!children.length || !this.shouldUseVirtual()) {
2907
- this.renderedChildren = children;
2908
- this.virtualTopPadding = 0;
2909
- this.virtualBottomPadding = 0;
2910
- this.virtualVisibleIndexes.clear();
2911
- return;
2966
+ return {
2967
+ renderedChildren: children,
2968
+ visibleIndexes: new Set(),
2969
+ top: 0,
2970
+ bottom: 0,
2971
+ heights: []
2972
+ };
2912
2973
  }
2913
2974
  const scrollTop = this.virtualConfig.scrollTop ?? 0;
2914
2975
  const viewportHeight = this.virtualConfig.viewportHeight ?? 0;
2915
2976
  if (!viewportHeight) {
2916
2977
  // 已经启用虚拟滚动,但可视区域高度还未获取到,先置空不渲染
2917
- this.renderedChildren = [];
2918
- this.virtualTopPadding = 0;
2919
- this.virtualBottomPadding = 0;
2920
- this.virtualVisibleIndexes.clear();
2921
- return;
2978
+ return {
2979
+ renderedChildren: [],
2980
+ visibleIndexes: new Set(),
2981
+ top: 0,
2982
+ bottom: 0,
2983
+ heights: []
2984
+ };
2922
2985
  }
2923
2986
  const bufferCount = this.virtualConfig.bufferCount ?? VIRTUAL_SCROLL_DEFAULT_BUFFER_COUNT;
2924
2987
  const heights = children.map((_, idx) => this.getBlockHeight(idx));
2925
2988
  const accumulatedHeights = this.buildAccumulatedHeight(heights);
2926
- const total = accumulatedHeights[accumulatedHeights.length - 1] || 0;
2927
2989
  let visibleStart = 0;
2928
2990
  // 按真实或估算高度往后累加,找到滚动起点所在块
2929
2991
  while (visibleStart < heights.length && accumulatedHeights[visibleStart + 1] <= scrollTop) {
@@ -2945,20 +3007,121 @@ class SlateEditable {
2945
3007
  accumulated += this.getBlockHeight(cursor);
2946
3008
  cursor++;
2947
3009
  }
2948
- const bottom = Math.max(total - top - accumulated, 0); // 下占位高度
2949
- this.renderedChildren = visible.length ? visible : children;
2950
- // padding 占位
2951
- this.virtualTopPadding = this.renderedChildren === visible ? Math.round(top) : 0;
2952
- this.virtualBottomPadding = this.renderedChildren === visible ? Math.round(bottom) : 0;
2953
- this.virtualVisibleIndexes = new Set(visibleIndexes);
3010
+ const bottom = heights.slice(cursor).reduce((acc, height) => acc + height, 0);
3011
+ const renderedChildren = visible.length ? visible : children;
3012
+ const visibleIndexesSet = new Set(visibleIndexes);
3013
+ return {
3014
+ renderedChildren,
3015
+ visibleIndexes: visibleIndexesSet,
3016
+ top,
3017
+ bottom,
3018
+ heights
3019
+ };
3020
+ }
3021
+ applyVirtualView(virtualView) {
3022
+ this.renderedChildren = virtualView.renderedChildren;
3023
+ this.changeVirtualHeight(virtualView.top, virtualView.bottom);
3024
+ this.virtualVisibleIndexes = virtualView.visibleIndexes;
3025
+ }
3026
+ diffVirtualView(virtualView) {
3027
+ if (!this.renderedChildren.length) {
3028
+ return {
3029
+ isDiff: true,
3030
+ diffTopRenderedIndexes: [],
3031
+ diffBottomRenderedIndexes: []
3032
+ };
3033
+ }
3034
+ const oldVisibleIndexes = [...this.virtualVisibleIndexes];
3035
+ const newVisibleIndexes = [...virtualView.visibleIndexes];
3036
+ const firstNewIndex = newVisibleIndexes[0];
3037
+ const lastNewIndex = newVisibleIndexes[newVisibleIndexes.length - 1];
3038
+ const firstOldIndex = oldVisibleIndexes[0];
3039
+ const lastOldIndex = oldVisibleIndexes[oldVisibleIndexes.length - 1];
3040
+ if (firstNewIndex !== firstOldIndex || lastNewIndex !== lastOldIndex) {
3041
+ const diffTopRenderedIndexes = [];
3042
+ const diffBottomRenderedIndexes = [];
3043
+ const isMissingTop = firstNewIndex !== firstOldIndex && firstNewIndex > firstOldIndex;
3044
+ const isAddedTop = firstNewIndex !== firstOldIndex && firstNewIndex < firstOldIndex;
3045
+ const isMissingBottom = lastNewIndex !== lastOldIndex && lastOldIndex > lastNewIndex;
3046
+ const isAddedBottom = lastNewIndex !== lastOldIndex && lastOldIndex < lastNewIndex;
3047
+ if (isMissingTop || isAddedBottom) {
3048
+ // 向下
3049
+ for (let index = 0; index < oldVisibleIndexes.length; index++) {
3050
+ const element = oldVisibleIndexes[index];
3051
+ if (!newVisibleIndexes.includes(element)) {
3052
+ diffTopRenderedIndexes.push(element);
3053
+ }
3054
+ else {
3055
+ break;
3056
+ }
3057
+ }
3058
+ for (let index = newVisibleIndexes.length - 1; index >= 0; index--) {
3059
+ const element = newVisibleIndexes[index];
3060
+ if (!oldVisibleIndexes.includes(element)) {
3061
+ diffBottomRenderedIndexes.push(element);
3062
+ }
3063
+ else {
3064
+ break;
3065
+ }
3066
+ }
3067
+ }
3068
+ else if (isAddedTop || isMissingBottom) {
3069
+ // 向上
3070
+ for (let index = 0; index < newVisibleIndexes.length; index++) {
3071
+ const element = newVisibleIndexes[index];
3072
+ if (!oldVisibleIndexes.includes(element)) {
3073
+ diffTopRenderedIndexes.push(element);
3074
+ }
3075
+ else {
3076
+ break;
3077
+ }
3078
+ }
3079
+ for (let index = oldVisibleIndexes.length - 1; index >= 0; index--) {
3080
+ const element = oldVisibleIndexes[index];
3081
+ if (!newVisibleIndexes.includes(element)) {
3082
+ diffBottomRenderedIndexes.push(element);
3083
+ }
3084
+ else {
3085
+ break;
3086
+ }
3087
+ }
3088
+ }
3089
+ if (isDebug) {
3090
+ console.log('oldVisibleIndexes:', oldVisibleIndexes);
3091
+ console.log('newVisibleIndexes:', newVisibleIndexes);
3092
+ console.log('diffTopRenderedIndexes:', isMissingTop ? '-' : isAddedTop ? '+' : '-', diffTopRenderedIndexes, diffTopRenderedIndexes.map(index => this.getBlockHeight(index, 0)));
3093
+ console.log('diffBottomRenderedIndexes:', isAddedBottom ? '+' : isMissingBottom ? '-' : '+', diffBottomRenderedIndexes, diffBottomRenderedIndexes.map(index => this.getBlockHeight(index, 0)));
3094
+ const needTop = virtualView.heights.slice(0, newVisibleIndexes[0]).reduce((acc, height) => acc + height, 0);
3095
+ const needBottom = virtualView.heights
3096
+ .slice(newVisibleIndexes[newVisibleIndexes.length - 1] + 1)
3097
+ .reduce((acc, height) => acc + height, 0);
3098
+ console.log('newTopHeight:', needTop, 'prevTopHeight:', parseFloat(this.virtualTopHeightElement.style.height));
3099
+ console.log('newBottomHeight:', needBottom, 'prevBottomHeight:', parseFloat(this.virtualBottomHeightElement.style.height));
3100
+ console.warn('=========== Dividing line ===========');
3101
+ }
3102
+ return {
3103
+ isDiff: true,
3104
+ isMissingTop,
3105
+ isAddedTop,
3106
+ isMissingBottom,
3107
+ isAddedBottom,
3108
+ diffTopRenderedIndexes,
3109
+ diffBottomRenderedIndexes
3110
+ };
3111
+ }
3112
+ return {
3113
+ isDiff: false,
3114
+ diffTopRenderedIndexes: [],
3115
+ diffBottomRenderedIndexes: []
3116
+ };
2954
3117
  }
2955
- getBlockHeight(index) {
3118
+ getBlockHeight(index, defaultHeight = VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT) {
2956
3119
  const node = this.editor.children[index];
2957
3120
  if (!node) {
2958
- return VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT;
3121
+ return defaultHeight;
2959
3122
  }
2960
3123
  const key = AngularEditor.findKey(this.editor, node);
2961
- return this.measuredHeights.get(key.id) ?? VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT;
3124
+ return this.measuredHeights.get(key.id) ?? defaultHeight;
2962
3125
  }
2963
3126
  buildAccumulatedHeight(heights) {
2964
3127
  const accumulatedHeights = new Array(heights.length + 1).fill(0);
@@ -3013,13 +3176,46 @@ class SlateEditable {
3013
3176
  return;
3014
3177
  }
3015
3178
  view.getRealHeight()?.then(height => {
3016
- const actualHeight = height +
3017
- parseFloat(getComputedStyle(view.nativeElement).marginTop) +
3018
- parseFloat(getComputedStyle(view.nativeElement).marginBottom);
3019
- this.measuredHeights.set(key.id, actualHeight);
3179
+ this.measuredHeights.set(key.id, height);
3020
3180
  });
3021
3181
  });
3022
3182
  }
3183
+ async measureHeightByIndexes(indexes, isRefresh = false) {
3184
+ const children = (this.editor.children || []);
3185
+ let isHeightChanged = false;
3186
+ const promises = [];
3187
+ indexes.forEach(index => {
3188
+ const node = children[index];
3189
+ if (!node) {
3190
+ return;
3191
+ }
3192
+ const key = AngularEditor.findKey(this.editor, node);
3193
+ const view = ELEMENT_TO_COMPONENT.get(node);
3194
+ if (!view) {
3195
+ return;
3196
+ }
3197
+ const promise = view.getRealHeight()?.then(height => {
3198
+ const prevHeight = this.measuredHeights.get(key.id);
3199
+ if (isDebug) {
3200
+ console.log('measureHeightByIndexes: get index:', index, 'prevHeight:', prevHeight, 'newHeight:', height);
3201
+ }
3202
+ if (prevHeight && height !== prevHeight) {
3203
+ this.measuredHeights.set(key.id, height);
3204
+ isHeightChanged = true;
3205
+ }
3206
+ });
3207
+ if (promise) {
3208
+ promises.push(promise);
3209
+ }
3210
+ });
3211
+ if (promises.length > 0) {
3212
+ await Promise.all(promises);
3213
+ if (isHeightChanged && isRefresh) {
3214
+ return this.refreshVirtualView();
3215
+ }
3216
+ }
3217
+ return null;
3218
+ }
3023
3219
  //#region event proxy
3024
3220
  addEventListener(eventName, listener, target = this.elementRef.nativeElement) {
3025
3221
  this.manualListeners.push(this.renderer2.listen(target, eventName, (event) => {
@@ -3719,7 +3915,7 @@ class SlateEditable {
3719
3915
  EDITOR_TO_ON_CHANGE.delete(this.editor);
3720
3916
  }
3721
3917
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SlateEditable, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
3722
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.12", type: SlateEditable, isStandalone: true, selector: "slate-editable", inputs: { editor: "editor", renderElement: "renderElement", renderLeaf: "renderLeaf", renderText: "renderText", decorate: "decorate", placeholderDecorate: "placeholderDecorate", scrollSelectionIntoView: "scrollSelectionIntoView", isStrictDecorate: "isStrictDecorate", trackBy: "trackBy", readonly: "readonly", placeholder: "placeholder", virtualScroll: "virtualScroll", beforeInput: "beforeInput", blur: "blur", click: "click", compositionEnd: "compositionEnd", compositionUpdate: "compositionUpdate", compositionStart: "compositionStart", copy: "copy", cut: "cut", dragOver: "dragOver", dragStart: "dragStart", dragEnd: "dragEnd", drop: "drop", focus: "focus", keydown: "keydown", paste: "paste", spellCheck: "spellCheck", autoCorrect: "autoCorrect", autoCapitalize: "autoCapitalize" }, host: { properties: { "attr.contenteditable": "readonly ? undefined : true", "attr.role": "readonly ? undefined : 'textbox'", "attr.spellCheck": "!hasBeforeInputSupport ? false : spellCheck", "attr.autoCorrect": "!hasBeforeInputSupport ? 'false' : autoCorrect", "attr.autoCapitalize": "!hasBeforeInputSupport ? 'false' : autoCapitalize", "style.--virtual-top-padding.px": "this.virtualTopPadding", "style.--virtual-bottom-padding.px": "this.virtualBottomPadding", "attr.data-slate-editor": "this.dataSlateEditor", "attr.data-slate-node": "this.dataSlateNode", "attr.data-gramm": "this.dataGramm" }, classAttribute: "slate-editable-container" }, providers: [
3918
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.12", type: SlateEditable, isStandalone: true, selector: "slate-editable", inputs: { editor: "editor", renderElement: "renderElement", renderLeaf: "renderLeaf", renderText: "renderText", decorate: "decorate", placeholderDecorate: "placeholderDecorate", scrollSelectionIntoView: "scrollSelectionIntoView", isStrictDecorate: "isStrictDecorate", trackBy: "trackBy", readonly: "readonly", placeholder: "placeholder", virtualScroll: "virtualScroll", beforeInput: "beforeInput", blur: "blur", click: "click", compositionEnd: "compositionEnd", compositionUpdate: "compositionUpdate", compositionStart: "compositionStart", copy: "copy", cut: "cut", dragOver: "dragOver", dragStart: "dragStart", dragEnd: "dragEnd", drop: "drop", focus: "focus", keydown: "keydown", paste: "paste", spellCheck: "spellCheck", autoCorrect: "autoCorrect", autoCapitalize: "autoCapitalize" }, host: { properties: { "attr.contenteditable": "readonly ? undefined : true", "attr.role": "readonly ? undefined : 'textbox'", "attr.spellCheck": "!hasBeforeInputSupport ? false : spellCheck", "attr.autoCorrect": "!hasBeforeInputSupport ? 'false' : autoCorrect", "attr.autoCapitalize": "!hasBeforeInputSupport ? 'false' : autoCapitalize", "attr.data-slate-editor": "this.dataSlateEditor", "attr.data-slate-node": "this.dataSlateNode", "attr.data-gramm": "this.dataGramm" }, classAttribute: "slate-editable-container" }, providers: [
3723
3919
  {
3724
3920
  provide: NG_VALUE_ACCESSOR,
3725
3921
  useExisting: forwardRef(() => SlateEditable),
@@ -3774,12 +3970,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
3774
3970
  type: Input
3775
3971
  }], virtualScroll: [{
3776
3972
  type: Input
3777
- }], virtualTopPadding: [{
3778
- type: HostBinding,
3779
- args: ['style.--virtual-top-padding.px']
3780
- }], virtualBottomPadding: [{
3781
- type: HostBinding,
3782
- args: ['style.--virtual-bottom-padding.px']
3783
3973
  }], beforeInput: [{
3784
3974
  type: Input
3785
3975
  }], blur: [{
@@ -4058,7 +4248,10 @@ class BaseElementComponent extends BaseComponent {
4058
4248
  };
4059
4249
  }
4060
4250
  getRealHeight() {
4061
- return Promise.resolve(this.nativeElement.offsetHeight);
4251
+ const blockCard = getBlockCardByNativeElement(this.nativeElement);
4252
+ const target = blockCard || this.nativeElement;
4253
+ const computedStyle = getComputedStyle(target);
4254
+ return Promise.resolve(target.offsetHeight + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom));
4062
4255
  }
4063
4256
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BaseElementComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
4064
4257
  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 }); }
@@ -4214,5 +4407,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
4214
4407
  * Generated bundle index. Do not edit.
4215
4408
  */
4216
4409
 
4217
- export { AngularEditor, BaseComponent, BaseElementComponent, BaseElementFlavour, BaseFlavour, BaseLeafComponent, BaseLeafFlavour, BaseTextComponent, BaseTextFlavour, BlockCardRef, DEFAULT_ELEMENT_HEIGHT, DefaultTextFlavour, EDITOR_TO_AFTER_VIEW_INIT_QUEUE, ELEMENT_TO_COMPONENT, FAKE_LEFT_BLOCK_CARD_OFFSET, FAKE_RIGHT_BLOCK_CARD_OFFSET, FlavourRef, HAS_BEFORE_INPUT_SUPPORT, IS_ANDROID, IS_APPLE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_FIREFOX_LEGACY, IS_IOS, IS_QQBROWSER, IS_SAFARI, IS_UC_MOBILE, IS_WECHATBROWSER, PLACEHOLDER_SYMBOL, SLATE_BLOCK_CARD_CLASS_NAME, SlateBlockCard, SlateChildrenOutlet, SlateEditable, SlateErrorCode, SlateFragmentAttributeKey, SlateModule, VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT, VIRTUAL_SCROLL_DEFAULT_BUFFER_COUNT, VoidTextFlavour, blobAsString, buildHTMLText, check, completeTable, createClipboardData, createText, createThrottleRAF, defaultScrollSelectionIntoView, fallbackCopyText, getBlockCardByNativeElement, getCardTargetAttribute, getClipboardData, getClipboardFromHTMLText, getContentHeight, getDataTransferClipboard, getDataTransferClipboardText, getNavigatorClipboard, getPlainText, getSelection, getSlateFragmentAttribute, getZeroTextNode, hasAfterContextChange, hasBeforeContextChange, hasBlockCard, hasBlockCardWithNode, hotkeys, isCardCenterByTargetAttr, isCardLeft, isCardLeftByTargetAttr, isCardRightByTargetAttr, isClipboardFile, isClipboardReadSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isComponentType, isDOMText, isDecoratorRangeListEqual, isFlavourType, isInvalidTable, isTemplateRef, isValid, normalize, setClipboardData, setDataTransferClipboard, setDataTransferClipboardText, setNavigatorClipboard, shallowCompare, stripHtml, withAngular };
4410
+ export { AngularEditor, BaseComponent, BaseElementComponent, BaseElementFlavour, BaseFlavour, BaseLeafComponent, BaseLeafFlavour, BaseTextComponent, BaseTextFlavour, BlockCardRef, DEFAULT_ELEMENT_HEIGHT, DefaultTextFlavour, EDITOR_TO_AFTER_VIEW_INIT_QUEUE, ELEMENT_TO_COMPONENT, FAKE_LEFT_BLOCK_CARD_OFFSET, FAKE_RIGHT_BLOCK_CARD_OFFSET, FlavourRef, HAS_BEFORE_INPUT_SUPPORT, IS_ANDROID, IS_APPLE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_FIREFOX_LEGACY, IS_IOS, IS_QQBROWSER, IS_SAFARI, IS_UC_MOBILE, IS_WECHATBROWSER, JUST_NOW_UPDATED_VIRTUAL_VIEW, PLACEHOLDER_SYMBOL, SLATE_BLOCK_CARD_CLASS_NAME, SLATE_DEBUG_KEY, SlateBlockCard, SlateChildrenOutlet, SlateEditable, SlateErrorCode, SlateFragmentAttributeKey, SlateModule, VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT, VIRTUAL_SCROLL_DEFAULT_BUFFER_COUNT, VoidTextFlavour, blobAsString, buildHTMLText, check, completeTable, createClipboardData, createText, createThrottleRAF, defaultScrollSelectionIntoView, fallbackCopyText, getBlockCardByNativeElement, getCardTargetAttribute, getClipboardData, getClipboardFromHTMLText, getContentHeight, getDataTransferClipboard, getDataTransferClipboardText, getNavigatorClipboard, getPlainText, getSelection, getSlateFragmentAttribute, getZeroTextNode, hasAfterContextChange, hasBeforeContextChange, hasBlockCard, hasBlockCardWithNode, hotkeys, isCardCenterByTargetAttr, isCardLeft, isCardLeftByTargetAttr, isCardRightByTargetAttr, isClipboardFile, isClipboardReadSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isComponentType, isDOMText, isDecoratorRangeListEqual, isFlavourType, isInvalidTable, isTemplateRef, isValid, normalize, setClipboardData, setDataTransferClipboard, setDataTransferClipboardText, setNavigatorClipboard, shallowCompare, stripHtml, withAngular };
4218
4411
  //# sourceMappingURL=slate-angular.mjs.map