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.
- package/fesm2022/slate-angular.mjs +283 -90
- package/fesm2022/slate-angular.mjs.map +1 -1
- package/index.d.ts +25 -6
- package/package.json +1 -1
- package/styles/index.scss +0 -13
|
@@ -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
|
-
|
|
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
|
-
|
|
2561
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
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
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
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 =
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
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
|
|
3121
|
+
return defaultHeight;
|
|
2959
3122
|
}
|
|
2960
3123
|
const key = AngularEditor.findKey(this.editor, node);
|
|
2961
|
-
return this.measuredHeights.get(key.id) ??
|
|
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
|
-
|
|
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", "
|
|
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
|
-
|
|
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
|