slate-angular 20.2.0-next.1 → 20.2.0-next.11
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 +502 -128
- package/fesm2022/slate-angular.mjs.map +1 -1
- package/index.d.ts +15 -5
- package/package.json +1 -1
|
@@ -1135,6 +1135,9 @@ const withAngular = (editor, clipboardFormatKey = 'x-slate-fragment') => {
|
|
|
1135
1135
|
NODE_TO_KEY.set(node, key);
|
|
1136
1136
|
}
|
|
1137
1137
|
};
|
|
1138
|
+
e.selectAll = () => {
|
|
1139
|
+
Transforms.select(e, []);
|
|
1140
|
+
};
|
|
1138
1141
|
return e;
|
|
1139
1142
|
};
|
|
1140
1143
|
|
|
@@ -1739,6 +1742,7 @@ class BaseElementFlavour extends BaseFlavour {
|
|
|
1739
1742
|
this.getOutletElement = () => {
|
|
1740
1743
|
return this.nativeElement.querySelector('.children-outlet');
|
|
1741
1744
|
};
|
|
1745
|
+
this.stableHeight = null;
|
|
1742
1746
|
}
|
|
1743
1747
|
get element() {
|
|
1744
1748
|
return this._context && this._context.element;
|
|
@@ -1824,11 +1828,21 @@ class BaseElementFlavour extends BaseFlavour {
|
|
|
1824
1828
|
readonly: this._context.readonly
|
|
1825
1829
|
};
|
|
1826
1830
|
}
|
|
1831
|
+
isStableHeight() {
|
|
1832
|
+
return false;
|
|
1833
|
+
}
|
|
1827
1834
|
getRealHeight() {
|
|
1835
|
+
if (this.isStableHeight() && this.stableHeight !== null) {
|
|
1836
|
+
return this.stableHeight;
|
|
1837
|
+
}
|
|
1828
1838
|
const blockCard = getBlockCardByNativeElement(this.nativeElement);
|
|
1829
1839
|
const target = blockCard || this.nativeElement;
|
|
1830
1840
|
const computedStyle = getComputedStyle(target);
|
|
1831
|
-
|
|
1841
|
+
const height = Math.ceil(target.getBoundingClientRect().height) + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom);
|
|
1842
|
+
if (this.isStableHeight()) {
|
|
1843
|
+
this.stableHeight = height;
|
|
1844
|
+
}
|
|
1845
|
+
return height;
|
|
1832
1846
|
}
|
|
1833
1847
|
}
|
|
1834
1848
|
|
|
@@ -2553,24 +2567,244 @@ function executeAfterViewInit(editor) {
|
|
|
2553
2567
|
clearAfterViewInitQueue(editor);
|
|
2554
2568
|
}
|
|
2555
2569
|
|
|
2570
|
+
class VirtualScrollDebugOverlay {
|
|
2571
|
+
constructor(doc) {
|
|
2572
|
+
this.doc = doc;
|
|
2573
|
+
this.originalConsoleLog = console.log.bind(console);
|
|
2574
|
+
this.originalConsoleWarn = console.warn.bind(console);
|
|
2575
|
+
this.dragOffsetX = 0;
|
|
2576
|
+
this.dragOffsetY = 0;
|
|
2577
|
+
this.isDragging = false;
|
|
2578
|
+
this.onDragging = (event) => {
|
|
2579
|
+
if (!this.isDragging || !this.container) {
|
|
2580
|
+
return;
|
|
2581
|
+
}
|
|
2582
|
+
const nextLeft = event.clientX - this.dragOffsetX;
|
|
2583
|
+
const nextTop = event.clientY - this.dragOffsetY;
|
|
2584
|
+
this.container.style.left = `${nextLeft}px`;
|
|
2585
|
+
this.container.style.top = `${nextTop}px`;
|
|
2586
|
+
this.container.style.right = 'auto';
|
|
2587
|
+
this.container.style.bottom = 'auto';
|
|
2588
|
+
};
|
|
2589
|
+
this.onDragEnd = () => {
|
|
2590
|
+
if (!this.isDragging) {
|
|
2591
|
+
return;
|
|
2592
|
+
}
|
|
2593
|
+
this.isDragging = false;
|
|
2594
|
+
this.doc.removeEventListener('mousemove', this.onDragging);
|
|
2595
|
+
this.doc.removeEventListener('mouseup', this.onDragEnd);
|
|
2596
|
+
if (this.container) {
|
|
2597
|
+
this.container.style.transition = '';
|
|
2598
|
+
}
|
|
2599
|
+
};
|
|
2600
|
+
}
|
|
2601
|
+
init() {
|
|
2602
|
+
if (!this.container) {
|
|
2603
|
+
this.createContainer();
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
log(type, ...args) {
|
|
2607
|
+
this.init();
|
|
2608
|
+
if (type === 'warn') {
|
|
2609
|
+
this.originalConsoleWarn(...args);
|
|
2610
|
+
}
|
|
2611
|
+
else {
|
|
2612
|
+
this.originalConsoleLog(...args);
|
|
2613
|
+
}
|
|
2614
|
+
this.appendLog(type, ...args);
|
|
2615
|
+
}
|
|
2616
|
+
dispose() {
|
|
2617
|
+
this.container?.remove();
|
|
2618
|
+
this.container = undefined;
|
|
2619
|
+
this.logList = undefined;
|
|
2620
|
+
this.selectorInput = undefined;
|
|
2621
|
+
this.distanceInput = undefined;
|
|
2622
|
+
this.doc.removeEventListener('mousemove', this.onDragging);
|
|
2623
|
+
this.doc.removeEventListener('mouseup', this.onDragEnd);
|
|
2624
|
+
this.isDragging = false;
|
|
2625
|
+
}
|
|
2626
|
+
createContainer() {
|
|
2627
|
+
const doc = this.doc;
|
|
2628
|
+
const container = doc.createElement('div');
|
|
2629
|
+
container.style.position = 'fixed';
|
|
2630
|
+
container.style.left = '16px';
|
|
2631
|
+
container.style.top = '16px';
|
|
2632
|
+
container.style.right = 'auto';
|
|
2633
|
+
container.style.bottom = 'auto';
|
|
2634
|
+
container.style.width = '360px';
|
|
2635
|
+
container.style.maxHeight = '70vh';
|
|
2636
|
+
container.style.padding = '12px';
|
|
2637
|
+
container.style.boxSizing = 'border-box';
|
|
2638
|
+
container.style.background = 'rgba(17, 24, 39, 0.95)';
|
|
2639
|
+
container.style.color = '#e5e7eb';
|
|
2640
|
+
container.style.fontSize = '12px';
|
|
2641
|
+
container.style.fontFamily = 'Menlo, Consolas, monospace';
|
|
2642
|
+
container.style.border = '1px solid #1f2937';
|
|
2643
|
+
container.style.borderRadius = '10px';
|
|
2644
|
+
container.style.boxShadow = '0 10px 30px rgba(0, 0, 0, 0.35)';
|
|
2645
|
+
container.style.zIndex = '9999';
|
|
2646
|
+
container.style.display = 'flex';
|
|
2647
|
+
container.style.flexDirection = 'column';
|
|
2648
|
+
container.style.gap = '10px';
|
|
2649
|
+
const header = doc.createElement('div');
|
|
2650
|
+
header.style.display = 'flex';
|
|
2651
|
+
header.style.alignItems = 'center';
|
|
2652
|
+
header.style.justifyContent = 'space-between';
|
|
2653
|
+
header.style.cursor = 'move';
|
|
2654
|
+
header.addEventListener('mousedown', event => {
|
|
2655
|
+
if (!this.container) {
|
|
2656
|
+
return;
|
|
2657
|
+
}
|
|
2658
|
+
const rect = this.container.getBoundingClientRect();
|
|
2659
|
+
this.isDragging = true;
|
|
2660
|
+
this.dragOffsetX = event.clientX - rect.left;
|
|
2661
|
+
this.dragOffsetY = event.clientY - rect.top;
|
|
2662
|
+
this.container.style.transition = 'none';
|
|
2663
|
+
this.doc.addEventListener('mousemove', this.onDragging);
|
|
2664
|
+
this.doc.addEventListener('mouseup', this.onDragEnd);
|
|
2665
|
+
event.preventDefault();
|
|
2666
|
+
});
|
|
2667
|
+
const title = doc.createElement('div');
|
|
2668
|
+
title.textContent = 'Virtual Scroll Debug';
|
|
2669
|
+
title.style.fontWeight = '600';
|
|
2670
|
+
title.style.letterSpacing = '0.3px';
|
|
2671
|
+
const clearButton = doc.createElement('button');
|
|
2672
|
+
clearButton.type = 'button';
|
|
2673
|
+
clearButton.textContent = '清除日志';
|
|
2674
|
+
clearButton.style.background = '#374151';
|
|
2675
|
+
clearButton.style.color = '#e5e7eb';
|
|
2676
|
+
clearButton.style.border = '1px solid #4b5563';
|
|
2677
|
+
clearButton.style.borderRadius = '6px';
|
|
2678
|
+
clearButton.style.padding = '4px 10px';
|
|
2679
|
+
clearButton.style.cursor = 'pointer';
|
|
2680
|
+
clearButton.addEventListener('click', () => {
|
|
2681
|
+
if (this.logList) {
|
|
2682
|
+
this.logList.innerHTML = '';
|
|
2683
|
+
}
|
|
2684
|
+
});
|
|
2685
|
+
header.appendChild(title);
|
|
2686
|
+
header.appendChild(clearButton);
|
|
2687
|
+
const scrollForm = doc.createElement('div');
|
|
2688
|
+
scrollForm.style.display = 'grid';
|
|
2689
|
+
scrollForm.style.gridTemplateColumns = '1fr 90px 70px';
|
|
2690
|
+
scrollForm.style.gap = '6px';
|
|
2691
|
+
scrollForm.style.alignItems = 'center';
|
|
2692
|
+
const selectorInput = doc.createElement('input');
|
|
2693
|
+
selectorInput.placeholder = '滚动容器 selector';
|
|
2694
|
+
selectorInput.style.padding = '6px 8px';
|
|
2695
|
+
selectorInput.style.borderRadius = '6px';
|
|
2696
|
+
selectorInput.style.border = '1px solid #4b5563';
|
|
2697
|
+
selectorInput.style.background = '#111827';
|
|
2698
|
+
selectorInput.style.color = '#e5e7eb';
|
|
2699
|
+
selectorInput.autocomplete = 'off';
|
|
2700
|
+
const distanceInput = doc.createElement('input');
|
|
2701
|
+
distanceInput.placeholder = '滚动距离(px)';
|
|
2702
|
+
distanceInput.type = 'number';
|
|
2703
|
+
distanceInput.style.padding = '6px 8px';
|
|
2704
|
+
distanceInput.style.borderRadius = '6px';
|
|
2705
|
+
distanceInput.style.border = '1px solid #4b5563';
|
|
2706
|
+
distanceInput.style.background = '#111827';
|
|
2707
|
+
distanceInput.style.color = '#e5e7eb';
|
|
2708
|
+
const scrollButton = doc.createElement('button');
|
|
2709
|
+
scrollButton.type = 'button';
|
|
2710
|
+
scrollButton.textContent = '滚动';
|
|
2711
|
+
scrollButton.style.background = '#10b981';
|
|
2712
|
+
scrollButton.style.color = '#0b1c15';
|
|
2713
|
+
scrollButton.style.border = 'none';
|
|
2714
|
+
scrollButton.style.borderRadius = '6px';
|
|
2715
|
+
scrollButton.style.padding = '6px 10px';
|
|
2716
|
+
scrollButton.style.cursor = 'pointer';
|
|
2717
|
+
scrollButton.addEventListener('click', () => {
|
|
2718
|
+
const selector = selectorInput.value.trim();
|
|
2719
|
+
const distanceValue = Number(distanceInput.value ?? 0);
|
|
2720
|
+
const distance = Number.isFinite(distanceValue) ? distanceValue : 0;
|
|
2721
|
+
if (!selector) {
|
|
2722
|
+
this.log('warn', '请先填写滚动容器 selector');
|
|
2723
|
+
return;
|
|
2724
|
+
}
|
|
2725
|
+
const target = doc.querySelector(selector);
|
|
2726
|
+
if (!target) {
|
|
2727
|
+
this.log('warn', `未找到滚动容器: ${selector}`);
|
|
2728
|
+
return;
|
|
2729
|
+
}
|
|
2730
|
+
if (typeof target.scrollTo === 'function') {
|
|
2731
|
+
target.scrollTo({ top: distance, behavior: 'auto' });
|
|
2732
|
+
}
|
|
2733
|
+
else if (Object.prototype.hasOwnProperty.call(target, 'scrollTop')) {
|
|
2734
|
+
target.scrollTop = distance;
|
|
2735
|
+
}
|
|
2736
|
+
else {
|
|
2737
|
+
this.log('warn', '目标元素不支持滚动:', selector);
|
|
2738
|
+
return;
|
|
2739
|
+
}
|
|
2740
|
+
this.log('log', `已将 ${selector} 滚动到`, distance);
|
|
2741
|
+
});
|
|
2742
|
+
scrollForm.appendChild(selectorInput);
|
|
2743
|
+
scrollForm.appendChild(distanceInput);
|
|
2744
|
+
scrollForm.appendChild(scrollButton);
|
|
2745
|
+
const logList = doc.createElement('div');
|
|
2746
|
+
logList.style.height = '260px';
|
|
2747
|
+
logList.style.overflowY = 'auto';
|
|
2748
|
+
logList.style.background = '#0b1220';
|
|
2749
|
+
logList.style.border = '1px solid #1f2937';
|
|
2750
|
+
logList.style.borderRadius = '8px';
|
|
2751
|
+
logList.style.padding = '8px';
|
|
2752
|
+
logList.style.display = 'flex';
|
|
2753
|
+
logList.style.flexDirection = 'column';
|
|
2754
|
+
logList.style.gap = '6px';
|
|
2755
|
+
container.appendChild(header);
|
|
2756
|
+
container.appendChild(scrollForm);
|
|
2757
|
+
container.appendChild(logList);
|
|
2758
|
+
doc.body.appendChild(container);
|
|
2759
|
+
this.container = container;
|
|
2760
|
+
this.logList = logList;
|
|
2761
|
+
this.selectorInput = selectorInput;
|
|
2762
|
+
this.distanceInput = distanceInput;
|
|
2763
|
+
}
|
|
2764
|
+
appendLog(type, ...args) {
|
|
2765
|
+
if (!this.logList) {
|
|
2766
|
+
return;
|
|
2767
|
+
}
|
|
2768
|
+
const item = this.doc.createElement('div');
|
|
2769
|
+
item.style.display = 'flex';
|
|
2770
|
+
item.style.gap = '6px';
|
|
2771
|
+
item.style.alignItems = 'flex-start';
|
|
2772
|
+
item.style.wordBreak = 'break-all';
|
|
2773
|
+
item.style.color = type === 'warn' ? '#fbbf24' : '#9ca3af';
|
|
2774
|
+
const time = this.doc.createElement('span');
|
|
2775
|
+
time.textContent = new Date().toLocaleTimeString();
|
|
2776
|
+
time.style.color = '#6b7280';
|
|
2777
|
+
time.style.flexShrink = '0';
|
|
2778
|
+
time.style.width = '72px';
|
|
2779
|
+
const text = this.doc.createElement('span');
|
|
2780
|
+
text.textContent = `[${type}] ${args.map(arg => this.formatValue(arg)).join(' ')}`;
|
|
2781
|
+
item.appendChild(time);
|
|
2782
|
+
item.appendChild(text);
|
|
2783
|
+
this.logList.appendChild(item);
|
|
2784
|
+
this.logList.scrollTop = this.logList.scrollHeight;
|
|
2785
|
+
}
|
|
2786
|
+
formatValue(value) {
|
|
2787
|
+
if (typeof value === 'string') {
|
|
2788
|
+
return value;
|
|
2789
|
+
}
|
|
2790
|
+
try {
|
|
2791
|
+
return JSON.stringify(value);
|
|
2792
|
+
}
|
|
2793
|
+
catch (error) {
|
|
2794
|
+
return String(value);
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
}
|
|
2798
|
+
|
|
2556
2799
|
const JUST_NOW_UPDATED_VIRTUAL_VIEW = new WeakMap();
|
|
2800
|
+
const ELEMENT_KEY_TO_HEIGHTS = new WeakMap();
|
|
2557
2801
|
// not correctly clipboardData on beforeinput
|
|
2558
2802
|
const forceOnDOMPaste = IS_SAFARI;
|
|
2803
|
+
const isDebug = localStorage.getItem(SLATE_DEBUG_KEY) === 'true';
|
|
2559
2804
|
class SlateEditable {
|
|
2560
2805
|
set virtualScroll(config) {
|
|
2561
2806
|
this.virtualConfig = config;
|
|
2562
|
-
this.
|
|
2563
|
-
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);
|
|
2570
|
-
}
|
|
2571
|
-
this.scheduleMeasureVisibleHeights();
|
|
2572
|
-
}
|
|
2573
|
-
});
|
|
2807
|
+
this.doVirtualScroll();
|
|
2574
2808
|
}
|
|
2575
2809
|
get hasBeforeInputSupport() {
|
|
2576
2810
|
return HAS_BEFORE_INPUT_SUPPORT;
|
|
@@ -2623,7 +2857,8 @@ class SlateEditable {
|
|
|
2623
2857
|
this.renderedChildren = [];
|
|
2624
2858
|
this.virtualVisibleIndexes = new Set();
|
|
2625
2859
|
this.measuredHeights = new Map();
|
|
2626
|
-
|
|
2860
|
+
// the height from scroll container top to editor top height element
|
|
2861
|
+
this.businessHeight = 0;
|
|
2627
2862
|
this.virtualScrollInitialized = false;
|
|
2628
2863
|
}
|
|
2629
2864
|
ngOnInit() {
|
|
@@ -2635,6 +2870,7 @@ class SlateEditable {
|
|
|
2635
2870
|
NODE_TO_ELEMENT.set(this.editor, this.elementRef.nativeElement);
|
|
2636
2871
|
ELEMENT_TO_NODE.set(this.elementRef.nativeElement, this.editor);
|
|
2637
2872
|
IS_READ_ONLY.set(this.editor, this.readonly);
|
|
2873
|
+
ELEMENT_KEY_TO_HEIGHTS.set(this.editor, this.measuredHeights);
|
|
2638
2874
|
EDITOR_TO_ON_CHANGE.set(this.editor, () => {
|
|
2639
2875
|
this.ngZone.run(() => {
|
|
2640
2876
|
this.onChange();
|
|
@@ -2722,7 +2958,25 @@ class SlateEditable {
|
|
|
2722
2958
|
}
|
|
2723
2959
|
toNativeSelection() {
|
|
2724
2960
|
try {
|
|
2725
|
-
|
|
2961
|
+
let { selection } = this.editor;
|
|
2962
|
+
if (this.virtualConfig?.enabled && selection) {
|
|
2963
|
+
const indics = Array.from(this.virtualVisibleIndexes.values());
|
|
2964
|
+
if (indics.length > 0) {
|
|
2965
|
+
const currentVisibleRange = {
|
|
2966
|
+
anchor: Editor.start(this.editor, [indics[0]]),
|
|
2967
|
+
focus: Editor.end(this.editor, [indics[indics.length - 1]])
|
|
2968
|
+
};
|
|
2969
|
+
const [start, end] = Range.edges(selection);
|
|
2970
|
+
const forwardSelection = { anchor: start, focus: end };
|
|
2971
|
+
const intersectedSelection = Range.intersection(forwardSelection, currentVisibleRange);
|
|
2972
|
+
if (!intersectedSelection || !Range.equals(intersectedSelection, forwardSelection)) {
|
|
2973
|
+
selection = intersectedSelection;
|
|
2974
|
+
if (isDebug) {
|
|
2975
|
+
this.debugLog('log', `selection is not in visible range, selection: ${JSON.stringify(selection)}, intersectedSelection: ${JSON.stringify(intersectedSelection)}`);
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2726
2980
|
const root = AngularEditor.findDocumentOrShadowRoot(this.editor);
|
|
2727
2981
|
const { activeElement } = root;
|
|
2728
2982
|
const domSelection = root.getSelection();
|
|
@@ -2812,8 +3066,9 @@ class SlateEditable {
|
|
|
2812
3066
|
this.updateContext();
|
|
2813
3067
|
const virtualView = this.refreshVirtualView();
|
|
2814
3068
|
this.applyVirtualView(virtualView);
|
|
2815
|
-
|
|
2816
|
-
this.
|
|
3069
|
+
const visibleIndexes = Array.from(this.virtualVisibleIndexes);
|
|
3070
|
+
this.listRender.update(this.renderedChildren, this.editor, this.context);
|
|
3071
|
+
this.remeasureHeightByIndics(visibleIndexes);
|
|
2817
3072
|
// repair collaborative editing when Chinese input is interrupted by other users' cursors
|
|
2818
3073
|
// when the DOMElement where the selection is located is removed
|
|
2819
3074
|
// the compositionupdate and compositionend events will no longer be fired
|
|
@@ -2929,13 +3184,29 @@ class SlateEditable {
|
|
|
2929
3184
|
this.virtualScrollInitialized = true;
|
|
2930
3185
|
this.virtualTopHeightElement = document.createElement('div');
|
|
2931
3186
|
this.virtualTopHeightElement.classList.add('virtual-top-height');
|
|
3187
|
+
this.virtualTopHeightElement.contentEditable = 'false';
|
|
2932
3188
|
this.virtualBottomHeightElement = document.createElement('div');
|
|
2933
3189
|
this.virtualBottomHeightElement.classList.add('virtual-bottom-height');
|
|
3190
|
+
this.virtualBottomHeightElement.contentEditable = 'false';
|
|
2934
3191
|
this.virtualCenterOutlet = document.createElement('div');
|
|
2935
3192
|
this.virtualCenterOutlet.classList.add('virtual-center-outlet');
|
|
2936
3193
|
this.elementRef.nativeElement.appendChild(this.virtualTopHeightElement);
|
|
2937
3194
|
this.elementRef.nativeElement.appendChild(this.virtualCenterOutlet);
|
|
2938
3195
|
this.elementRef.nativeElement.appendChild(this.virtualBottomHeightElement);
|
|
3196
|
+
this.businessHeight = this.virtualTopHeightElement.getBoundingClientRect()?.top ?? 0;
|
|
3197
|
+
let editorResizeObserverRectWidth = this.elementRef.nativeElement.getBoundingClientRect()?.width ?? 0;
|
|
3198
|
+
this.editorResizeObserver = new ResizeObserver(entries => {
|
|
3199
|
+
if (entries.length > 0 && entries[0].contentRect.width !== editorResizeObserverRectWidth) {
|
|
3200
|
+
editorResizeObserverRectWidth = entries[0].contentRect.width;
|
|
3201
|
+
this.remeasureHeightByIndics(Array.from(this.virtualVisibleIndexes));
|
|
3202
|
+
}
|
|
3203
|
+
});
|
|
3204
|
+
this.editorResizeObserver.observe(this.elementRef.nativeElement);
|
|
3205
|
+
if (isDebug) {
|
|
3206
|
+
const doc = this.elementRef?.nativeElement?.ownerDocument ?? document;
|
|
3207
|
+
this.debugOverlay = new VirtualScrollDebugOverlay(doc);
|
|
3208
|
+
this.debugOverlay.init();
|
|
3209
|
+
}
|
|
2939
3210
|
}
|
|
2940
3211
|
}
|
|
2941
3212
|
changeVirtualHeight(topHeight, bottomHeight) {
|
|
@@ -2945,6 +3216,41 @@ class SlateEditable {
|
|
|
2945
3216
|
this.virtualTopHeightElement.style.height = `${topHeight}px`;
|
|
2946
3217
|
this.virtualBottomHeightElement.style.height = `${bottomHeight}px`;
|
|
2947
3218
|
}
|
|
3219
|
+
debugLog(type, ...args) {
|
|
3220
|
+
if (!this.debugOverlay) {
|
|
3221
|
+
const doc = this.elementRef?.nativeElement?.ownerDocument ?? document;
|
|
3222
|
+
this.debugOverlay = new VirtualScrollDebugOverlay(doc);
|
|
3223
|
+
}
|
|
3224
|
+
this.debugOverlay.log(type, ...args);
|
|
3225
|
+
}
|
|
3226
|
+
doVirtualScroll() {
|
|
3227
|
+
this.refreshVirtualViewAnimId && cancelAnimationFrame(this.refreshVirtualViewAnimId);
|
|
3228
|
+
this.refreshVirtualViewAnimId = requestAnimationFrame(() => {
|
|
3229
|
+
let virtualView = this.refreshVirtualView();
|
|
3230
|
+
let diff = this.diffVirtualView(virtualView);
|
|
3231
|
+
if (!diff.isDiff) {
|
|
3232
|
+
return;
|
|
3233
|
+
}
|
|
3234
|
+
if (diff.isMissingTop) {
|
|
3235
|
+
const result = this.remeasureHeightByIndics(diff.diffTopRenderedIndexes);
|
|
3236
|
+
if (result) {
|
|
3237
|
+
virtualView = this.refreshVirtualView();
|
|
3238
|
+
diff = this.diffVirtualView(virtualView, 'second');
|
|
3239
|
+
if (!diff.isDiff) {
|
|
3240
|
+
return;
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
this.applyVirtualView(virtualView);
|
|
3245
|
+
if (this.listRender.initialized) {
|
|
3246
|
+
this.listRender.update(virtualView.renderedChildren, this.editor, this.context);
|
|
3247
|
+
if (!AngularEditor.isReadOnly(this.editor) && this.editor.selection) {
|
|
3248
|
+
this.toNativeSelection();
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
this.scheduleMeasureVisibleHeights();
|
|
3252
|
+
});
|
|
3253
|
+
}
|
|
2948
3254
|
refreshVirtualView() {
|
|
2949
3255
|
const children = (this.editor.children || []);
|
|
2950
3256
|
if (!children.length || !this.shouldUseVirtual()) {
|
|
@@ -2956,10 +3262,9 @@ class SlateEditable {
|
|
|
2956
3262
|
heights: []
|
|
2957
3263
|
};
|
|
2958
3264
|
}
|
|
2959
|
-
const scrollTop = this.virtualConfig.scrollTop
|
|
3265
|
+
const scrollTop = this.virtualConfig.scrollTop;
|
|
2960
3266
|
const viewportHeight = this.virtualConfig.viewportHeight ?? 0;
|
|
2961
3267
|
if (!viewportHeight) {
|
|
2962
|
-
// 已经启用虚拟滚动,但可视区域高度还未获取到,先置空不渲染
|
|
2963
3268
|
return {
|
|
2964
3269
|
renderedChildren: [],
|
|
2965
3270
|
visibleIndexes: new Set(),
|
|
@@ -2968,36 +3273,41 @@ class SlateEditable {
|
|
|
2968
3273
|
heights: []
|
|
2969
3274
|
};
|
|
2970
3275
|
}
|
|
2971
|
-
const
|
|
3276
|
+
const elementLength = children.length;
|
|
3277
|
+
const adjustedScrollTop = Math.max(0, scrollTop - this.businessHeight);
|
|
2972
3278
|
const heights = children.map((_, idx) => this.getBlockHeight(idx));
|
|
2973
3279
|
const accumulatedHeights = this.buildAccumulatedHeight(heights);
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
const startIndex = Math.max(0, visibleStart - bufferCount);
|
|
2981
|
-
const top = accumulatedHeights[startIndex];
|
|
2982
|
-
const bufferBelowHeight = this.getBufferBelowHeight(viewportHeight, visibleStart, bufferCount);
|
|
2983
|
-
const targetHeight = accumulatedHeights[visibleStart] - top + viewportHeight + bufferBelowHeight;
|
|
3280
|
+
const totalHeight = accumulatedHeights[elementLength];
|
|
3281
|
+
const maxScrollTop = Math.max(0, totalHeight - viewportHeight);
|
|
3282
|
+
const limitedScrollTop = Math.min(adjustedScrollTop, maxScrollTop);
|
|
3283
|
+
const viewBottom = limitedScrollTop + viewportHeight + this.businessHeight;
|
|
3284
|
+
let accumulatedOffset = 0;
|
|
3285
|
+
let visibleStartIndex = -1;
|
|
2984
3286
|
const visible = [];
|
|
2985
3287
|
const visibleIndexes = [];
|
|
2986
|
-
let
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
3288
|
+
for (let i = 0; i < elementLength && accumulatedOffset < viewBottom; i++) {
|
|
3289
|
+
const currentHeight = heights[i];
|
|
3290
|
+
const nextOffset = accumulatedOffset + currentHeight;
|
|
3291
|
+
// 可视区域有交集,加入渲染
|
|
3292
|
+
if (nextOffset > limitedScrollTop && accumulatedOffset < viewBottom) {
|
|
3293
|
+
if (visibleStartIndex === -1)
|
|
3294
|
+
visibleStartIndex = i; // 第一个相交起始位置
|
|
3295
|
+
visible.push(children[i]);
|
|
3296
|
+
visibleIndexes.push(i);
|
|
3297
|
+
}
|
|
3298
|
+
accumulatedOffset = nextOffset;
|
|
3299
|
+
}
|
|
3300
|
+
if (visibleStartIndex === -1 && elementLength) {
|
|
3301
|
+
visibleStartIndex = elementLength - 1;
|
|
3302
|
+
visible.push(children[visibleStartIndex]);
|
|
3303
|
+
visibleIndexes.push(visibleStartIndex);
|
|
3304
|
+
}
|
|
3305
|
+
const visibleEndIndex = visibleStartIndex === -1 ? elementLength - 1 : (visibleIndexes[visibleIndexes.length - 1] ?? visibleStartIndex);
|
|
3306
|
+
const top = visibleStartIndex === -1 ? 0 : accumulatedHeights[visibleStartIndex];
|
|
3307
|
+
const bottom = totalHeight - accumulatedHeights[visibleEndIndex + 1];
|
|
2998
3308
|
return {
|
|
2999
|
-
renderedChildren,
|
|
3000
|
-
visibleIndexes:
|
|
3309
|
+
renderedChildren: visible.length ? visible : children,
|
|
3310
|
+
visibleIndexes: new Set(visibleIndexes),
|
|
3001
3311
|
top,
|
|
3002
3312
|
bottom,
|
|
3003
3313
|
heights
|
|
@@ -3008,86 +3318,106 @@ class SlateEditable {
|
|
|
3008
3318
|
this.changeVirtualHeight(virtualView.top, virtualView.bottom);
|
|
3009
3319
|
this.virtualVisibleIndexes = virtualView.visibleIndexes;
|
|
3010
3320
|
}
|
|
3011
|
-
diffVirtualView(virtualView) {
|
|
3321
|
+
diffVirtualView(virtualView, stage = 'first') {
|
|
3012
3322
|
if (!this.renderedChildren.length) {
|
|
3013
|
-
return
|
|
3323
|
+
return {
|
|
3324
|
+
isDiff: true,
|
|
3325
|
+
diffTopRenderedIndexes: [],
|
|
3326
|
+
diffBottomRenderedIndexes: []
|
|
3327
|
+
};
|
|
3014
3328
|
}
|
|
3015
3329
|
const oldVisibleIndexes = [...this.virtualVisibleIndexes];
|
|
3016
3330
|
const newVisibleIndexes = [...virtualView.visibleIndexes];
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3331
|
+
const firstNewIndex = newVisibleIndexes[0];
|
|
3332
|
+
const lastNewIndex = newVisibleIndexes[newVisibleIndexes.length - 1];
|
|
3333
|
+
const firstOldIndex = oldVisibleIndexes[0];
|
|
3334
|
+
const lastOldIndex = oldVisibleIndexes[oldVisibleIndexes.length - 1];
|
|
3335
|
+
if (firstNewIndex !== firstOldIndex || lastNewIndex !== lastOldIndex) {
|
|
3336
|
+
const diffTopRenderedIndexes = [];
|
|
3337
|
+
const diffBottomRenderedIndexes = [];
|
|
3338
|
+
const isMissingTop = firstNewIndex !== firstOldIndex && firstNewIndex > firstOldIndex;
|
|
3339
|
+
const isAddedTop = firstNewIndex !== firstOldIndex && firstNewIndex < firstOldIndex;
|
|
3340
|
+
const isMissingBottom = lastNewIndex !== lastOldIndex && lastOldIndex > lastNewIndex;
|
|
3341
|
+
const isAddedBottom = lastNewIndex !== lastOldIndex && lastOldIndex < lastNewIndex;
|
|
3342
|
+
if (isMissingTop || isAddedBottom) {
|
|
3343
|
+
// 向下
|
|
3344
|
+
for (let index = 0; index < oldVisibleIndexes.length; index++) {
|
|
3345
|
+
const element = oldVisibleIndexes[index];
|
|
3346
|
+
if (!newVisibleIndexes.includes(element)) {
|
|
3347
|
+
diffTopRenderedIndexes.push(element);
|
|
3034
3348
|
}
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
if (!oldVisibleIndexes.includes(element)) {
|
|
3038
|
-
diffBottomRenderedIndexes.push(element);
|
|
3039
|
-
}
|
|
3040
|
-
else {
|
|
3041
|
-
break;
|
|
3042
|
-
}
|
|
3349
|
+
else {
|
|
3350
|
+
break;
|
|
3043
3351
|
}
|
|
3044
3352
|
}
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
const element = newVisibleIndexes[index];
|
|
3050
|
-
if (!oldVisibleIndexes.includes(element)) {
|
|
3051
|
-
diffTopRenderedIndexes.push(element);
|
|
3052
|
-
}
|
|
3053
|
-
else {
|
|
3054
|
-
break;
|
|
3055
|
-
}
|
|
3353
|
+
for (let index = newVisibleIndexes.length - 1; index >= 0; index--) {
|
|
3354
|
+
const element = newVisibleIndexes[index];
|
|
3355
|
+
if (!oldVisibleIndexes.includes(element)) {
|
|
3356
|
+
diffBottomRenderedIndexes.push(element);
|
|
3056
3357
|
}
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3358
|
+
else {
|
|
3359
|
+
break;
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
else if (isAddedTop || isMissingBottom) {
|
|
3364
|
+
// 向上
|
|
3365
|
+
for (let index = 0; index < newVisibleIndexes.length; index++) {
|
|
3366
|
+
const element = newVisibleIndexes[index];
|
|
3367
|
+
if (!oldVisibleIndexes.includes(element)) {
|
|
3368
|
+
diffTopRenderedIndexes.push(element);
|
|
3369
|
+
}
|
|
3370
|
+
else {
|
|
3371
|
+
break;
|
|
3065
3372
|
}
|
|
3066
3373
|
}
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3374
|
+
for (let index = oldVisibleIndexes.length - 1; index >= 0; index--) {
|
|
3375
|
+
const element = oldVisibleIndexes[index];
|
|
3376
|
+
if (!newVisibleIndexes.includes(element)) {
|
|
3377
|
+
diffBottomRenderedIndexes.push(element);
|
|
3378
|
+
}
|
|
3379
|
+
else {
|
|
3380
|
+
break;
|
|
3381
|
+
}
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
if (isDebug) {
|
|
3385
|
+
this.debugLog('log', `====== diffVirtualView stage: ${stage} ======`);
|
|
3386
|
+
this.debugLog('log', 'oldVisibleIndexes:', oldVisibleIndexes);
|
|
3387
|
+
this.debugLog('log', 'newVisibleIndexes:', newVisibleIndexes);
|
|
3388
|
+
this.debugLog('log', 'diffTopRenderedIndexes:', isMissingTop ? '-' : isAddedTop ? '+' : '-', diffTopRenderedIndexes, diffTopRenderedIndexes.map(index => this.getBlockHeight(index, 0)));
|
|
3389
|
+
this.debugLog('log', 'diffBottomRenderedIndexes:', isAddedBottom ? '+' : isMissingBottom ? '-' : '+', diffBottomRenderedIndexes, diffBottomRenderedIndexes.map(index => this.getBlockHeight(index, 0)));
|
|
3072
3390
|
const needTop = virtualView.heights.slice(0, newVisibleIndexes[0]).reduce((acc, height) => acc + height, 0);
|
|
3073
3391
|
const needBottom = virtualView.heights
|
|
3074
3392
|
.slice(newVisibleIndexes[newVisibleIndexes.length - 1] + 1)
|
|
3075
3393
|
.reduce((acc, height) => acc + height, 0);
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3394
|
+
this.debugLog('log', 'newTopHeight:', needTop, 'prevTopHeight:', parseFloat(this.virtualTopHeightElement.style.height));
|
|
3395
|
+
this.debugLog('log', 'newBottomHeight:', needBottom, 'prevBottomHeight:', parseFloat(this.virtualBottomHeightElement.style.height));
|
|
3396
|
+
this.debugLog('warn', '=========== Dividing line ===========');
|
|
3079
3397
|
}
|
|
3080
|
-
return
|
|
3398
|
+
return {
|
|
3399
|
+
isDiff: true,
|
|
3400
|
+
isMissingTop,
|
|
3401
|
+
isAddedTop,
|
|
3402
|
+
isMissingBottom,
|
|
3403
|
+
isAddedBottom,
|
|
3404
|
+
diffTopRenderedIndexes,
|
|
3405
|
+
diffBottomRenderedIndexes
|
|
3406
|
+
};
|
|
3081
3407
|
}
|
|
3082
|
-
return
|
|
3408
|
+
return {
|
|
3409
|
+
isDiff: false,
|
|
3410
|
+
diffTopRenderedIndexes: [],
|
|
3411
|
+
diffBottomRenderedIndexes: []
|
|
3412
|
+
};
|
|
3083
3413
|
}
|
|
3084
|
-
getBlockHeight(index) {
|
|
3414
|
+
getBlockHeight(index, defaultHeight = VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT) {
|
|
3085
3415
|
const node = this.editor.children[index];
|
|
3086
3416
|
if (!node) {
|
|
3087
|
-
return
|
|
3417
|
+
return defaultHeight;
|
|
3088
3418
|
}
|
|
3089
3419
|
const key = AngularEditor.findKey(this.editor, node);
|
|
3090
|
-
return this.measuredHeights.get(key.id) ??
|
|
3420
|
+
return this.measuredHeights.get(key.id) ?? defaultHeight;
|
|
3091
3421
|
}
|
|
3092
3422
|
buildAccumulatedHeight(heights) {
|
|
3093
3423
|
const accumulatedHeights = new Array(heights.length + 1).fill(0);
|
|
@@ -3097,32 +3427,13 @@ class SlateEditable {
|
|
|
3097
3427
|
}
|
|
3098
3428
|
return accumulatedHeights;
|
|
3099
3429
|
}
|
|
3100
|
-
getBufferBelowHeight(viewportHeight, visibleStart, bufferCount) {
|
|
3101
|
-
let blockHeight = 0;
|
|
3102
|
-
let start = visibleStart;
|
|
3103
|
-
// 循环累计高度超出视图高度代表找到向下缓冲区的起始位置
|
|
3104
|
-
while (blockHeight < viewportHeight) {
|
|
3105
|
-
blockHeight += this.getBlockHeight(start);
|
|
3106
|
-
start++;
|
|
3107
|
-
}
|
|
3108
|
-
let bufferHeight = 0;
|
|
3109
|
-
for (let i = start; i < start + bufferCount; i++) {
|
|
3110
|
-
bufferHeight += this.getBlockHeight(i);
|
|
3111
|
-
}
|
|
3112
|
-
return bufferHeight;
|
|
3113
|
-
}
|
|
3114
3430
|
scheduleMeasureVisibleHeights() {
|
|
3115
3431
|
if (!this.shouldUseVirtual()) {
|
|
3116
3432
|
return;
|
|
3117
3433
|
}
|
|
3118
|
-
if (this.measurePending) {
|
|
3119
|
-
return;
|
|
3120
|
-
}
|
|
3121
|
-
this.measurePending = true;
|
|
3122
3434
|
this.measureVisibleHeightsAnimId && cancelAnimationFrame(this.measureVisibleHeightsAnimId);
|
|
3123
3435
|
this.measureVisibleHeightsAnimId = requestAnimationFrame(() => {
|
|
3124
3436
|
this.measureVisibleHeights();
|
|
3125
|
-
this.measurePending = false;
|
|
3126
3437
|
});
|
|
3127
3438
|
}
|
|
3128
3439
|
measureVisibleHeights() {
|
|
@@ -3133,7 +3444,7 @@ class SlateEditable {
|
|
|
3133
3444
|
return;
|
|
3134
3445
|
}
|
|
3135
3446
|
const key = AngularEditor.findKey(this.editor, node);
|
|
3136
|
-
//
|
|
3447
|
+
// 跳过已测过的块,除非强制测量
|
|
3137
3448
|
if (this.measuredHeights.has(key.id)) {
|
|
3138
3449
|
return;
|
|
3139
3450
|
}
|
|
@@ -3141,10 +3452,54 @@ class SlateEditable {
|
|
|
3141
3452
|
if (!view) {
|
|
3142
3453
|
return;
|
|
3143
3454
|
}
|
|
3144
|
-
view.getRealHeight()
|
|
3145
|
-
|
|
3146
|
-
|
|
3455
|
+
const ret = view.getRealHeight();
|
|
3456
|
+
if (ret instanceof Promise) {
|
|
3457
|
+
ret.then(height => {
|
|
3458
|
+
this.measuredHeights.set(key.id, height);
|
|
3459
|
+
});
|
|
3460
|
+
}
|
|
3461
|
+
else {
|
|
3462
|
+
this.measuredHeights.set(key.id, ret);
|
|
3463
|
+
}
|
|
3464
|
+
});
|
|
3465
|
+
}
|
|
3466
|
+
remeasureHeightByIndics(indics) {
|
|
3467
|
+
const children = (this.editor.children || []);
|
|
3468
|
+
let isHeightChanged = false;
|
|
3469
|
+
indics.forEach(index => {
|
|
3470
|
+
const node = children[index];
|
|
3471
|
+
if (!node) {
|
|
3472
|
+
return;
|
|
3473
|
+
}
|
|
3474
|
+
const key = AngularEditor.findKey(this.editor, node);
|
|
3475
|
+
const view = ELEMENT_TO_COMPONENT.get(node);
|
|
3476
|
+
if (!view) {
|
|
3477
|
+
return;
|
|
3478
|
+
}
|
|
3479
|
+
const prevHeight = this.measuredHeights.get(key.id);
|
|
3480
|
+
const ret = view.getRealHeight();
|
|
3481
|
+
if (ret instanceof Promise) {
|
|
3482
|
+
ret.then(height => {
|
|
3483
|
+
if (height !== prevHeight) {
|
|
3484
|
+
this.measuredHeights.set(key.id, height);
|
|
3485
|
+
isHeightChanged = true;
|
|
3486
|
+
if (isDebug) {
|
|
3487
|
+
this.debugLog('log', `remeasureHeightByIndics, index: ${index} prevHeight: ${prevHeight} newHeight: ${height}`);
|
|
3488
|
+
}
|
|
3489
|
+
}
|
|
3490
|
+
});
|
|
3491
|
+
}
|
|
3492
|
+
else {
|
|
3493
|
+
if (ret !== prevHeight) {
|
|
3494
|
+
this.measuredHeights.set(key.id, ret);
|
|
3495
|
+
isHeightChanged = true;
|
|
3496
|
+
if (isDebug) {
|
|
3497
|
+
this.debugLog('log', `remeasureHeightByIndics, index: ${index} prevHeight: ${prevHeight} newHeight: ${ret}`);
|
|
3498
|
+
}
|
|
3499
|
+
}
|
|
3500
|
+
}
|
|
3147
3501
|
});
|
|
3502
|
+
return isHeightChanged;
|
|
3148
3503
|
}
|
|
3149
3504
|
//#region event proxy
|
|
3150
3505
|
addEventListener(eventName, listener, target = this.elementRef.nativeElement) {
|
|
@@ -3670,6 +4025,11 @@ class SlateEditable {
|
|
|
3670
4025
|
Transforms.move(editor, { unit: 'word', reverse: isRTL });
|
|
3671
4026
|
return;
|
|
3672
4027
|
}
|
|
4028
|
+
if (isKeyHotkey('mod+a', event)) {
|
|
4029
|
+
this.editor.selectAll();
|
|
4030
|
+
event.preventDefault();
|
|
4031
|
+
return;
|
|
4032
|
+
}
|
|
3673
4033
|
// COMPAT: Certain browsers don't support the `beforeinput` event, so we
|
|
3674
4034
|
// fall back to guessing at the input intention for hotkeys.
|
|
3675
4035
|
// COMPAT: In iOS, some of these hotkeys are handled in the
|
|
@@ -3837,6 +4197,9 @@ class SlateEditable {
|
|
|
3837
4197
|
}
|
|
3838
4198
|
//#endregion
|
|
3839
4199
|
ngOnDestroy() {
|
|
4200
|
+
this.editorResizeObserver?.disconnect();
|
|
4201
|
+
this.debugOverlay?.dispose();
|
|
4202
|
+
this.debugOverlay = undefined;
|
|
3840
4203
|
NODE_TO_ELEMENT.delete(this.editor);
|
|
3841
4204
|
this.manualListeners.forEach(manualListener => {
|
|
3842
4205
|
manualListener();
|
|
@@ -4096,6 +4459,7 @@ class BaseElementComponent extends BaseComponent {
|
|
|
4096
4459
|
}
|
|
4097
4460
|
return null;
|
|
4098
4461
|
};
|
|
4462
|
+
this.stableHeight = null;
|
|
4099
4463
|
}
|
|
4100
4464
|
get element() {
|
|
4101
4465
|
return this._context && this._context.element;
|
|
@@ -4177,11 +4541,21 @@ class BaseElementComponent extends BaseComponent {
|
|
|
4177
4541
|
readonly: this._context.readonly
|
|
4178
4542
|
};
|
|
4179
4543
|
}
|
|
4544
|
+
isStableHeight() {
|
|
4545
|
+
return false;
|
|
4546
|
+
}
|
|
4180
4547
|
getRealHeight() {
|
|
4548
|
+
if (this.isStableHeight() && this.stableHeight !== null) {
|
|
4549
|
+
return this.stableHeight;
|
|
4550
|
+
}
|
|
4181
4551
|
const blockCard = getBlockCardByNativeElement(this.nativeElement);
|
|
4182
4552
|
const target = blockCard || this.nativeElement;
|
|
4183
4553
|
const computedStyle = getComputedStyle(target);
|
|
4184
|
-
|
|
4554
|
+
const height = Math.ceil(target.getBoundingClientRect().height) + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom);
|
|
4555
|
+
if (this.isStableHeight()) {
|
|
4556
|
+
this.stableHeight = height;
|
|
4557
|
+
}
|
|
4558
|
+
return height;
|
|
4185
4559
|
}
|
|
4186
4560
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BaseElementComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4187
4561
|
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 }); }
|
|
@@ -4337,5 +4711,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
4337
4711
|
* Generated bundle index. Do not edit.
|
|
4338
4712
|
*/
|
|
4339
4713
|
|
|
4340
|
-
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 };
|
|
4714
|
+
export { AngularEditor, BaseComponent, BaseElementComponent, BaseElementFlavour, BaseFlavour, BaseLeafComponent, BaseLeafFlavour, BaseTextComponent, BaseTextFlavour, BlockCardRef, DEFAULT_ELEMENT_HEIGHT, DefaultTextFlavour, EDITOR_TO_AFTER_VIEW_INIT_QUEUE, ELEMENT_KEY_TO_HEIGHTS, 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 };
|
|
4341
4715
|
//# sourceMappingURL=slate-angular.mjs.map
|