slate-angular 20.2.0-next.1 → 20.2.0-next.10
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 +511 -130
- 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();
|
|
@@ -2810,10 +3064,18 @@ class SlateEditable {
|
|
|
2810
3064
|
ngDoCheck() { }
|
|
2811
3065
|
forceRender() {
|
|
2812
3066
|
this.updateContext();
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
3067
|
+
let visibleIndexes = Array.from(this.virtualVisibleIndexes);
|
|
3068
|
+
const isFirstRender = visibleIndexes.length === 0;
|
|
3069
|
+
if (isFirstRender) {
|
|
3070
|
+
const virtualView = this.refreshVirtualView();
|
|
3071
|
+
this.applyVirtualView(virtualView);
|
|
3072
|
+
visibleIndexes = Array.from(this.virtualVisibleIndexes);
|
|
3073
|
+
}
|
|
3074
|
+
else {
|
|
3075
|
+
this.renderedChildren = visibleIndexes.map(index => this.editor.children[index]);
|
|
3076
|
+
}
|
|
3077
|
+
this.listRender.update(this.renderedChildren, this.editor, this.context);
|
|
3078
|
+
this.remeasureHeightByIndics(visibleIndexes);
|
|
2817
3079
|
// repair collaborative editing when Chinese input is interrupted by other users' cursors
|
|
2818
3080
|
// when the DOMElement where the selection is located is removed
|
|
2819
3081
|
// the compositionupdate and compositionend events will no longer be fired
|
|
@@ -2929,13 +3191,29 @@ class SlateEditable {
|
|
|
2929
3191
|
this.virtualScrollInitialized = true;
|
|
2930
3192
|
this.virtualTopHeightElement = document.createElement('div');
|
|
2931
3193
|
this.virtualTopHeightElement.classList.add('virtual-top-height');
|
|
3194
|
+
this.virtualTopHeightElement.contentEditable = 'false';
|
|
2932
3195
|
this.virtualBottomHeightElement = document.createElement('div');
|
|
2933
3196
|
this.virtualBottomHeightElement.classList.add('virtual-bottom-height');
|
|
3197
|
+
this.virtualBottomHeightElement.contentEditable = 'false';
|
|
2934
3198
|
this.virtualCenterOutlet = document.createElement('div');
|
|
2935
3199
|
this.virtualCenterOutlet.classList.add('virtual-center-outlet');
|
|
2936
3200
|
this.elementRef.nativeElement.appendChild(this.virtualTopHeightElement);
|
|
2937
3201
|
this.elementRef.nativeElement.appendChild(this.virtualCenterOutlet);
|
|
2938
3202
|
this.elementRef.nativeElement.appendChild(this.virtualBottomHeightElement);
|
|
3203
|
+
this.businessHeight = this.virtualTopHeightElement.getBoundingClientRect()?.top ?? 0;
|
|
3204
|
+
let editorResizeObserverRectWidth = this.elementRef.nativeElement.getBoundingClientRect()?.width ?? 0;
|
|
3205
|
+
this.editorResizeObserver = new ResizeObserver(entries => {
|
|
3206
|
+
if (entries.length > 0 && entries[0].contentRect.width !== editorResizeObserverRectWidth) {
|
|
3207
|
+
editorResizeObserverRectWidth = entries[0].contentRect.width;
|
|
3208
|
+
this.remeasureHeightByIndics(Array.from(this.virtualVisibleIndexes));
|
|
3209
|
+
}
|
|
3210
|
+
});
|
|
3211
|
+
this.editorResizeObserver.observe(this.elementRef.nativeElement);
|
|
3212
|
+
if (isDebug) {
|
|
3213
|
+
const doc = this.elementRef?.nativeElement?.ownerDocument ?? document;
|
|
3214
|
+
this.debugOverlay = new VirtualScrollDebugOverlay(doc);
|
|
3215
|
+
this.debugOverlay.init();
|
|
3216
|
+
}
|
|
2939
3217
|
}
|
|
2940
3218
|
}
|
|
2941
3219
|
changeVirtualHeight(topHeight, bottomHeight) {
|
|
@@ -2945,6 +3223,41 @@ class SlateEditable {
|
|
|
2945
3223
|
this.virtualTopHeightElement.style.height = `${topHeight}px`;
|
|
2946
3224
|
this.virtualBottomHeightElement.style.height = `${bottomHeight}px`;
|
|
2947
3225
|
}
|
|
3226
|
+
debugLog(type, ...args) {
|
|
3227
|
+
if (!this.debugOverlay) {
|
|
3228
|
+
const doc = this.elementRef?.nativeElement?.ownerDocument ?? document;
|
|
3229
|
+
this.debugOverlay = new VirtualScrollDebugOverlay(doc);
|
|
3230
|
+
}
|
|
3231
|
+
this.debugOverlay.log(type, ...args);
|
|
3232
|
+
}
|
|
3233
|
+
doVirtualScroll() {
|
|
3234
|
+
this.refreshVirtualViewAnimId && cancelAnimationFrame(this.refreshVirtualViewAnimId);
|
|
3235
|
+
this.refreshVirtualViewAnimId = requestAnimationFrame(() => {
|
|
3236
|
+
let virtualView = this.refreshVirtualView();
|
|
3237
|
+
let diff = this.diffVirtualView(virtualView);
|
|
3238
|
+
if (!diff.isDiff) {
|
|
3239
|
+
return;
|
|
3240
|
+
}
|
|
3241
|
+
if (diff.isMissingTop) {
|
|
3242
|
+
const result = this.remeasureHeightByIndics(diff.diffTopRenderedIndexes);
|
|
3243
|
+
if (result) {
|
|
3244
|
+
virtualView = this.refreshVirtualView();
|
|
3245
|
+
diff = this.diffVirtualView(virtualView, 'second');
|
|
3246
|
+
if (!diff.isDiff) {
|
|
3247
|
+
return;
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
this.applyVirtualView(virtualView);
|
|
3252
|
+
if (this.listRender.initialized) {
|
|
3253
|
+
this.listRender.update(virtualView.renderedChildren, this.editor, this.context);
|
|
3254
|
+
if (!AngularEditor.isReadOnly(this.editor) && this.editor.selection) {
|
|
3255
|
+
this.toNativeSelection();
|
|
3256
|
+
}
|
|
3257
|
+
}
|
|
3258
|
+
this.scheduleMeasureVisibleHeights();
|
|
3259
|
+
});
|
|
3260
|
+
}
|
|
2948
3261
|
refreshVirtualView() {
|
|
2949
3262
|
const children = (this.editor.children || []);
|
|
2950
3263
|
if (!children.length || !this.shouldUseVirtual()) {
|
|
@@ -2956,10 +3269,9 @@ class SlateEditable {
|
|
|
2956
3269
|
heights: []
|
|
2957
3270
|
};
|
|
2958
3271
|
}
|
|
2959
|
-
const scrollTop = this.virtualConfig.scrollTop
|
|
3272
|
+
const scrollTop = this.virtualConfig.scrollTop;
|
|
2960
3273
|
const viewportHeight = this.virtualConfig.viewportHeight ?? 0;
|
|
2961
3274
|
if (!viewportHeight) {
|
|
2962
|
-
// 已经启用虚拟滚动,但可视区域高度还未获取到,先置空不渲染
|
|
2963
3275
|
return {
|
|
2964
3276
|
renderedChildren: [],
|
|
2965
3277
|
visibleIndexes: new Set(),
|
|
@@ -2968,36 +3280,41 @@ class SlateEditable {
|
|
|
2968
3280
|
heights: []
|
|
2969
3281
|
};
|
|
2970
3282
|
}
|
|
2971
|
-
const
|
|
3283
|
+
const elementLength = children.length;
|
|
3284
|
+
const adjustedScrollTop = Math.max(0, scrollTop - this.businessHeight);
|
|
2972
3285
|
const heights = children.map((_, idx) => this.getBlockHeight(idx));
|
|
2973
3286
|
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;
|
|
3287
|
+
const totalHeight = accumulatedHeights[elementLength];
|
|
3288
|
+
const maxScrollTop = Math.max(0, totalHeight - viewportHeight);
|
|
3289
|
+
const limitedScrollTop = Math.min(adjustedScrollTop, maxScrollTop);
|
|
3290
|
+
const viewBottom = limitedScrollTop + viewportHeight + this.businessHeight;
|
|
3291
|
+
let accumulatedOffset = 0;
|
|
3292
|
+
let visibleStartIndex = -1;
|
|
2984
3293
|
const visible = [];
|
|
2985
3294
|
const visibleIndexes = [];
|
|
2986
|
-
let
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
3295
|
+
for (let i = 0; i < elementLength && accumulatedOffset < viewBottom; i++) {
|
|
3296
|
+
const currentHeight = heights[i];
|
|
3297
|
+
const nextOffset = accumulatedOffset + currentHeight;
|
|
3298
|
+
// 可视区域有交集,加入渲染
|
|
3299
|
+
if (nextOffset > limitedScrollTop && accumulatedOffset < viewBottom) {
|
|
3300
|
+
if (visibleStartIndex === -1)
|
|
3301
|
+
visibleStartIndex = i; // 第一个相交起始位置
|
|
3302
|
+
visible.push(children[i]);
|
|
3303
|
+
visibleIndexes.push(i);
|
|
3304
|
+
}
|
|
3305
|
+
accumulatedOffset = nextOffset;
|
|
3306
|
+
}
|
|
3307
|
+
if (visibleStartIndex === -1 && elementLength) {
|
|
3308
|
+
visibleStartIndex = elementLength - 1;
|
|
3309
|
+
visible.push(children[visibleStartIndex]);
|
|
3310
|
+
visibleIndexes.push(visibleStartIndex);
|
|
3311
|
+
}
|
|
3312
|
+
const visibleEndIndex = visibleStartIndex === -1 ? elementLength - 1 : (visibleIndexes[visibleIndexes.length - 1] ?? visibleStartIndex);
|
|
3313
|
+
const top = visibleStartIndex === -1 ? 0 : accumulatedHeights[visibleStartIndex];
|
|
3314
|
+
const bottom = totalHeight - accumulatedHeights[visibleEndIndex + 1];
|
|
2998
3315
|
return {
|
|
2999
|
-
renderedChildren,
|
|
3000
|
-
visibleIndexes:
|
|
3316
|
+
renderedChildren: visible.length ? visible : children,
|
|
3317
|
+
visibleIndexes: new Set(visibleIndexes),
|
|
3001
3318
|
top,
|
|
3002
3319
|
bottom,
|
|
3003
3320
|
heights
|
|
@@ -3008,86 +3325,106 @@ class SlateEditable {
|
|
|
3008
3325
|
this.changeVirtualHeight(virtualView.top, virtualView.bottom);
|
|
3009
3326
|
this.virtualVisibleIndexes = virtualView.visibleIndexes;
|
|
3010
3327
|
}
|
|
3011
|
-
diffVirtualView(virtualView) {
|
|
3328
|
+
diffVirtualView(virtualView, stage = 'first') {
|
|
3012
3329
|
if (!this.renderedChildren.length) {
|
|
3013
|
-
return
|
|
3330
|
+
return {
|
|
3331
|
+
isDiff: true,
|
|
3332
|
+
diffTopRenderedIndexes: [],
|
|
3333
|
+
diffBottomRenderedIndexes: []
|
|
3334
|
+
};
|
|
3014
3335
|
}
|
|
3015
3336
|
const oldVisibleIndexes = [...this.virtualVisibleIndexes];
|
|
3016
3337
|
const newVisibleIndexes = [...virtualView.visibleIndexes];
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3338
|
+
const firstNewIndex = newVisibleIndexes[0];
|
|
3339
|
+
const lastNewIndex = newVisibleIndexes[newVisibleIndexes.length - 1];
|
|
3340
|
+
const firstOldIndex = oldVisibleIndexes[0];
|
|
3341
|
+
const lastOldIndex = oldVisibleIndexes[oldVisibleIndexes.length - 1];
|
|
3342
|
+
if (firstNewIndex !== firstOldIndex || lastNewIndex !== lastOldIndex) {
|
|
3343
|
+
const diffTopRenderedIndexes = [];
|
|
3344
|
+
const diffBottomRenderedIndexes = [];
|
|
3345
|
+
const isMissingTop = firstNewIndex !== firstOldIndex && firstNewIndex > firstOldIndex;
|
|
3346
|
+
const isAddedTop = firstNewIndex !== firstOldIndex && firstNewIndex < firstOldIndex;
|
|
3347
|
+
const isMissingBottom = lastNewIndex !== lastOldIndex && lastOldIndex > lastNewIndex;
|
|
3348
|
+
const isAddedBottom = lastNewIndex !== lastOldIndex && lastOldIndex < lastNewIndex;
|
|
3349
|
+
if (isMissingTop || isAddedBottom) {
|
|
3350
|
+
// 向下
|
|
3351
|
+
for (let index = 0; index < oldVisibleIndexes.length; index++) {
|
|
3352
|
+
const element = oldVisibleIndexes[index];
|
|
3353
|
+
if (!newVisibleIndexes.includes(element)) {
|
|
3354
|
+
diffTopRenderedIndexes.push(element);
|
|
3034
3355
|
}
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
if (!oldVisibleIndexes.includes(element)) {
|
|
3038
|
-
diffBottomRenderedIndexes.push(element);
|
|
3039
|
-
}
|
|
3040
|
-
else {
|
|
3041
|
-
break;
|
|
3042
|
-
}
|
|
3356
|
+
else {
|
|
3357
|
+
break;
|
|
3043
3358
|
}
|
|
3044
3359
|
}
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
const element = newVisibleIndexes[index];
|
|
3050
|
-
if (!oldVisibleIndexes.includes(element)) {
|
|
3051
|
-
diffTopRenderedIndexes.push(element);
|
|
3052
|
-
}
|
|
3053
|
-
else {
|
|
3054
|
-
break;
|
|
3055
|
-
}
|
|
3360
|
+
for (let index = newVisibleIndexes.length - 1; index >= 0; index--) {
|
|
3361
|
+
const element = newVisibleIndexes[index];
|
|
3362
|
+
if (!oldVisibleIndexes.includes(element)) {
|
|
3363
|
+
diffBottomRenderedIndexes.push(element);
|
|
3056
3364
|
}
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3365
|
+
else {
|
|
3366
|
+
break;
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
else if (isAddedTop || isMissingBottom) {
|
|
3371
|
+
// 向上
|
|
3372
|
+
for (let index = 0; index < newVisibleIndexes.length; index++) {
|
|
3373
|
+
const element = newVisibleIndexes[index];
|
|
3374
|
+
if (!oldVisibleIndexes.includes(element)) {
|
|
3375
|
+
diffTopRenderedIndexes.push(element);
|
|
3376
|
+
}
|
|
3377
|
+
else {
|
|
3378
|
+
break;
|
|
3065
3379
|
}
|
|
3066
3380
|
}
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3381
|
+
for (let index = oldVisibleIndexes.length - 1; index >= 0; index--) {
|
|
3382
|
+
const element = oldVisibleIndexes[index];
|
|
3383
|
+
if (!newVisibleIndexes.includes(element)) {
|
|
3384
|
+
diffBottomRenderedIndexes.push(element);
|
|
3385
|
+
}
|
|
3386
|
+
else {
|
|
3387
|
+
break;
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
}
|
|
3391
|
+
if (isDebug) {
|
|
3392
|
+
this.debugLog('log', `====== diffVirtualView stage: ${stage} ======`);
|
|
3393
|
+
this.debugLog('log', 'oldVisibleIndexes:', oldVisibleIndexes);
|
|
3394
|
+
this.debugLog('log', 'newVisibleIndexes:', newVisibleIndexes);
|
|
3395
|
+
this.debugLog('log', 'diffTopRenderedIndexes:', isMissingTop ? '-' : isAddedTop ? '+' : '-', diffTopRenderedIndexes, diffTopRenderedIndexes.map(index => this.getBlockHeight(index, 0)));
|
|
3396
|
+
this.debugLog('log', 'diffBottomRenderedIndexes:', isAddedBottom ? '+' : isMissingBottom ? '-' : '+', diffBottomRenderedIndexes, diffBottomRenderedIndexes.map(index => this.getBlockHeight(index, 0)));
|
|
3072
3397
|
const needTop = virtualView.heights.slice(0, newVisibleIndexes[0]).reduce((acc, height) => acc + height, 0);
|
|
3073
3398
|
const needBottom = virtualView.heights
|
|
3074
3399
|
.slice(newVisibleIndexes[newVisibleIndexes.length - 1] + 1)
|
|
3075
3400
|
.reduce((acc, height) => acc + height, 0);
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3401
|
+
this.debugLog('log', 'newTopHeight:', needTop, 'prevTopHeight:', parseFloat(this.virtualTopHeightElement.style.height));
|
|
3402
|
+
this.debugLog('log', 'newBottomHeight:', needBottom, 'prevBottomHeight:', parseFloat(this.virtualBottomHeightElement.style.height));
|
|
3403
|
+
this.debugLog('warn', '=========== Dividing line ===========');
|
|
3079
3404
|
}
|
|
3080
|
-
return
|
|
3405
|
+
return {
|
|
3406
|
+
isDiff: true,
|
|
3407
|
+
isMissingTop,
|
|
3408
|
+
isAddedTop,
|
|
3409
|
+
isMissingBottom,
|
|
3410
|
+
isAddedBottom,
|
|
3411
|
+
diffTopRenderedIndexes,
|
|
3412
|
+
diffBottomRenderedIndexes
|
|
3413
|
+
};
|
|
3081
3414
|
}
|
|
3082
|
-
return
|
|
3415
|
+
return {
|
|
3416
|
+
isDiff: false,
|
|
3417
|
+
diffTopRenderedIndexes: [],
|
|
3418
|
+
diffBottomRenderedIndexes: []
|
|
3419
|
+
};
|
|
3083
3420
|
}
|
|
3084
|
-
getBlockHeight(index) {
|
|
3421
|
+
getBlockHeight(index, defaultHeight = VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT) {
|
|
3085
3422
|
const node = this.editor.children[index];
|
|
3086
3423
|
if (!node) {
|
|
3087
|
-
return
|
|
3424
|
+
return defaultHeight;
|
|
3088
3425
|
}
|
|
3089
3426
|
const key = AngularEditor.findKey(this.editor, node);
|
|
3090
|
-
return this.measuredHeights.get(key.id) ??
|
|
3427
|
+
return this.measuredHeights.get(key.id) ?? defaultHeight;
|
|
3091
3428
|
}
|
|
3092
3429
|
buildAccumulatedHeight(heights) {
|
|
3093
3430
|
const accumulatedHeights = new Array(heights.length + 1).fill(0);
|
|
@@ -3097,32 +3434,13 @@ class SlateEditable {
|
|
|
3097
3434
|
}
|
|
3098
3435
|
return accumulatedHeights;
|
|
3099
3436
|
}
|
|
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
3437
|
scheduleMeasureVisibleHeights() {
|
|
3115
3438
|
if (!this.shouldUseVirtual()) {
|
|
3116
3439
|
return;
|
|
3117
3440
|
}
|
|
3118
|
-
if (this.measurePending) {
|
|
3119
|
-
return;
|
|
3120
|
-
}
|
|
3121
|
-
this.measurePending = true;
|
|
3122
3441
|
this.measureVisibleHeightsAnimId && cancelAnimationFrame(this.measureVisibleHeightsAnimId);
|
|
3123
3442
|
this.measureVisibleHeightsAnimId = requestAnimationFrame(() => {
|
|
3124
3443
|
this.measureVisibleHeights();
|
|
3125
|
-
this.measurePending = false;
|
|
3126
3444
|
});
|
|
3127
3445
|
}
|
|
3128
3446
|
measureVisibleHeights() {
|
|
@@ -3133,7 +3451,7 @@ class SlateEditable {
|
|
|
3133
3451
|
return;
|
|
3134
3452
|
}
|
|
3135
3453
|
const key = AngularEditor.findKey(this.editor, node);
|
|
3136
|
-
//
|
|
3454
|
+
// 跳过已测过的块,除非强制测量
|
|
3137
3455
|
if (this.measuredHeights.has(key.id)) {
|
|
3138
3456
|
return;
|
|
3139
3457
|
}
|
|
@@ -3141,11 +3459,55 @@ class SlateEditable {
|
|
|
3141
3459
|
if (!view) {
|
|
3142
3460
|
return;
|
|
3143
3461
|
}
|
|
3144
|
-
view.getRealHeight()
|
|
3145
|
-
|
|
3146
|
-
|
|
3462
|
+
const ret = view.getRealHeight();
|
|
3463
|
+
if (ret instanceof Promise) {
|
|
3464
|
+
ret.then(height => {
|
|
3465
|
+
this.measuredHeights.set(key.id, height);
|
|
3466
|
+
});
|
|
3467
|
+
}
|
|
3468
|
+
else {
|
|
3469
|
+
this.measuredHeights.set(key.id, ret);
|
|
3470
|
+
}
|
|
3147
3471
|
});
|
|
3148
3472
|
}
|
|
3473
|
+
remeasureHeightByIndics(indics) {
|
|
3474
|
+
const children = (this.editor.children || []);
|
|
3475
|
+
let isHeightChanged = false;
|
|
3476
|
+
indics.forEach(index => {
|
|
3477
|
+
const node = children[index];
|
|
3478
|
+
if (!node) {
|
|
3479
|
+
return;
|
|
3480
|
+
}
|
|
3481
|
+
const key = AngularEditor.findKey(this.editor, node);
|
|
3482
|
+
const view = ELEMENT_TO_COMPONENT.get(node);
|
|
3483
|
+
if (!view) {
|
|
3484
|
+
return;
|
|
3485
|
+
}
|
|
3486
|
+
const prevHeight = this.measuredHeights.get(key.id);
|
|
3487
|
+
const ret = view.getRealHeight();
|
|
3488
|
+
if (ret instanceof Promise) {
|
|
3489
|
+
ret.then(height => {
|
|
3490
|
+
if (height !== prevHeight) {
|
|
3491
|
+
this.measuredHeights.set(key.id, height);
|
|
3492
|
+
isHeightChanged = true;
|
|
3493
|
+
if (isDebug) {
|
|
3494
|
+
this.debugLog('log', `remeasureHeightByIndics, index: ${index} prevHeight: ${prevHeight} newHeight: ${height}`);
|
|
3495
|
+
}
|
|
3496
|
+
}
|
|
3497
|
+
});
|
|
3498
|
+
}
|
|
3499
|
+
else {
|
|
3500
|
+
if (ret !== prevHeight) {
|
|
3501
|
+
this.measuredHeights.set(key.id, ret);
|
|
3502
|
+
isHeightChanged = true;
|
|
3503
|
+
if (isDebug) {
|
|
3504
|
+
this.debugLog('log', `remeasureHeightByIndics, index: ${index} prevHeight: ${prevHeight} newHeight: ${ret}`);
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
}
|
|
3508
|
+
});
|
|
3509
|
+
return isHeightChanged;
|
|
3510
|
+
}
|
|
3149
3511
|
//#region event proxy
|
|
3150
3512
|
addEventListener(eventName, listener, target = this.elementRef.nativeElement) {
|
|
3151
3513
|
this.manualListeners.push(this.renderer2.listen(target, eventName, (event) => {
|
|
@@ -3670,6 +4032,11 @@ class SlateEditable {
|
|
|
3670
4032
|
Transforms.move(editor, { unit: 'word', reverse: isRTL });
|
|
3671
4033
|
return;
|
|
3672
4034
|
}
|
|
4035
|
+
if (isKeyHotkey('mod+a', event)) {
|
|
4036
|
+
this.editor.selectAll();
|
|
4037
|
+
event.preventDefault();
|
|
4038
|
+
return;
|
|
4039
|
+
}
|
|
3673
4040
|
// COMPAT: Certain browsers don't support the `beforeinput` event, so we
|
|
3674
4041
|
// fall back to guessing at the input intention for hotkeys.
|
|
3675
4042
|
// COMPAT: In iOS, some of these hotkeys are handled in the
|
|
@@ -3837,6 +4204,9 @@ class SlateEditable {
|
|
|
3837
4204
|
}
|
|
3838
4205
|
//#endregion
|
|
3839
4206
|
ngOnDestroy() {
|
|
4207
|
+
this.editorResizeObserver?.disconnect();
|
|
4208
|
+
this.debugOverlay?.dispose();
|
|
4209
|
+
this.debugOverlay = undefined;
|
|
3840
4210
|
NODE_TO_ELEMENT.delete(this.editor);
|
|
3841
4211
|
this.manualListeners.forEach(manualListener => {
|
|
3842
4212
|
manualListener();
|
|
@@ -4096,6 +4466,7 @@ class BaseElementComponent extends BaseComponent {
|
|
|
4096
4466
|
}
|
|
4097
4467
|
return null;
|
|
4098
4468
|
};
|
|
4469
|
+
this.stableHeight = null;
|
|
4099
4470
|
}
|
|
4100
4471
|
get element() {
|
|
4101
4472
|
return this._context && this._context.element;
|
|
@@ -4177,11 +4548,21 @@ class BaseElementComponent extends BaseComponent {
|
|
|
4177
4548
|
readonly: this._context.readonly
|
|
4178
4549
|
};
|
|
4179
4550
|
}
|
|
4551
|
+
isStableHeight() {
|
|
4552
|
+
return false;
|
|
4553
|
+
}
|
|
4180
4554
|
getRealHeight() {
|
|
4555
|
+
if (this.isStableHeight() && this.stableHeight !== null) {
|
|
4556
|
+
return this.stableHeight;
|
|
4557
|
+
}
|
|
4181
4558
|
const blockCard = getBlockCardByNativeElement(this.nativeElement);
|
|
4182
4559
|
const target = blockCard || this.nativeElement;
|
|
4183
4560
|
const computedStyle = getComputedStyle(target);
|
|
4184
|
-
|
|
4561
|
+
const height = Math.ceil(target.getBoundingClientRect().height) + parseFloat(computedStyle.marginTop) + parseFloat(computedStyle.marginBottom);
|
|
4562
|
+
if (this.isStableHeight()) {
|
|
4563
|
+
this.stableHeight = height;
|
|
4564
|
+
}
|
|
4565
|
+
return height;
|
|
4185
4566
|
}
|
|
4186
4567
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BaseElementComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
|
|
4187
4568
|
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 +4718,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
4337
4718
|
* Generated bundle index. Do not edit.
|
|
4338
4719
|
*/
|
|
4339
4720
|
|
|
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 };
|
|
4721
|
+
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
4722
|
//# sourceMappingURL=slate-angular.mjs.map
|