slate-angular 20.2.0-next.11 → 20.2.0-next.13
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 +363 -83
- package/fesm2022/slate-angular.mjs.map +1 -1
- package/index.d.ts +12 -12
- package/package.json +1 -1
|
@@ -1138,6 +1138,9 @@ const withAngular = (editor, clipboardFormatKey = 'x-slate-fragment') => {
|
|
|
1138
1138
|
e.selectAll = () => {
|
|
1139
1139
|
Transforms.select(e, []);
|
|
1140
1140
|
};
|
|
1141
|
+
e.isVisible = element => {
|
|
1142
|
+
return true;
|
|
1143
|
+
};
|
|
1141
1144
|
return e;
|
|
1142
1145
|
};
|
|
1143
1146
|
|
|
@@ -2568,17 +2571,51 @@ function executeAfterViewInit(editor) {
|
|
|
2568
2571
|
}
|
|
2569
2572
|
|
|
2570
2573
|
class VirtualScrollDebugOverlay {
|
|
2574
|
+
static { this.storageKey = 'slate_virtual_scroll_debug_overlay_state'; }
|
|
2575
|
+
static { this.minWidth = 320; }
|
|
2576
|
+
static { this.minHeight = 240; }
|
|
2577
|
+
static { this.defaultWidth = 410; }
|
|
2578
|
+
static { this.defaultHeight = 480; }
|
|
2579
|
+
static getInstance(doc) {
|
|
2580
|
+
if (!this.instance) {
|
|
2581
|
+
this.instance = new VirtualScrollDebugOverlay(doc);
|
|
2582
|
+
}
|
|
2583
|
+
this.instance.init();
|
|
2584
|
+
return this.instance;
|
|
2585
|
+
}
|
|
2586
|
+
static log(doc, type, ...args) {
|
|
2587
|
+
this.getInstance(doc).log(type, ...args);
|
|
2588
|
+
}
|
|
2589
|
+
static syncScrollTop(doc, value) {
|
|
2590
|
+
const instance = this.getInstance(doc);
|
|
2591
|
+
instance.setScrollTopValue(value);
|
|
2592
|
+
}
|
|
2571
2593
|
constructor(doc) {
|
|
2572
2594
|
this.doc = doc;
|
|
2595
|
+
this.state = {
|
|
2596
|
+
left: 16,
|
|
2597
|
+
top: 16,
|
|
2598
|
+
collapsed: false,
|
|
2599
|
+
width: VirtualScrollDebugOverlay.defaultWidth,
|
|
2600
|
+
height: VirtualScrollDebugOverlay.defaultHeight
|
|
2601
|
+
};
|
|
2573
2602
|
this.originalConsoleLog = console.log.bind(console);
|
|
2574
2603
|
this.originalConsoleWarn = console.warn.bind(console);
|
|
2575
2604
|
this.dragOffsetX = 0;
|
|
2576
2605
|
this.dragOffsetY = 0;
|
|
2577
2606
|
this.isDragging = false;
|
|
2607
|
+
this.isResizing = false;
|
|
2608
|
+
this.resizeStartX = 0;
|
|
2609
|
+
this.resizeStartY = 0;
|
|
2610
|
+
this.resizeStartWidth = 0;
|
|
2611
|
+
this.resizeStartHeight = 0;
|
|
2612
|
+
this.dragMoved = false;
|
|
2613
|
+
this.wasDragged = false;
|
|
2578
2614
|
this.onDragging = (event) => {
|
|
2579
2615
|
if (!this.isDragging || !this.container) {
|
|
2580
2616
|
return;
|
|
2581
2617
|
}
|
|
2618
|
+
this.dragMoved = true;
|
|
2582
2619
|
const nextLeft = event.clientX - this.dragOffsetX;
|
|
2583
2620
|
const nextTop = event.clientY - this.dragOffsetY;
|
|
2584
2621
|
this.container.style.left = `${nextLeft}px`;
|
|
@@ -2591,17 +2628,47 @@ class VirtualScrollDebugOverlay {
|
|
|
2591
2628
|
return;
|
|
2592
2629
|
}
|
|
2593
2630
|
this.isDragging = false;
|
|
2631
|
+
this.wasDragged = this.dragMoved;
|
|
2632
|
+
this.dragMoved = false;
|
|
2594
2633
|
this.doc.removeEventListener('mousemove', this.onDragging);
|
|
2595
2634
|
this.doc.removeEventListener('mouseup', this.onDragEnd);
|
|
2596
2635
|
if (this.container) {
|
|
2636
|
+
const rect = this.container.getBoundingClientRect();
|
|
2637
|
+
this.state.left = rect.left;
|
|
2638
|
+
this.state.top = rect.top;
|
|
2639
|
+
this.persistState();
|
|
2597
2640
|
this.container.style.transition = '';
|
|
2598
2641
|
}
|
|
2599
2642
|
};
|
|
2643
|
+
this.onResizing = (event) => {
|
|
2644
|
+
if (!this.isResizing || !this.container) {
|
|
2645
|
+
return;
|
|
2646
|
+
}
|
|
2647
|
+
const deltaX = event.clientX - this.resizeStartX;
|
|
2648
|
+
const deltaY = event.clientY - this.resizeStartY;
|
|
2649
|
+
const nextWidth = Math.max(VirtualScrollDebugOverlay.minWidth, this.resizeStartWidth + deltaX);
|
|
2650
|
+
const nextHeight = Math.max(VirtualScrollDebugOverlay.minHeight, this.resizeStartHeight + deltaY);
|
|
2651
|
+
this.state.width = nextWidth;
|
|
2652
|
+
this.state.height = nextHeight;
|
|
2653
|
+
this.applySize();
|
|
2654
|
+
};
|
|
2655
|
+
this.onResizeEnd = () => {
|
|
2656
|
+
if (!this.isResizing) {
|
|
2657
|
+
return;
|
|
2658
|
+
}
|
|
2659
|
+
this.isResizing = false;
|
|
2660
|
+
this.doc.removeEventListener('mousemove', this.onResizing);
|
|
2661
|
+
this.doc.removeEventListener('mouseup', this.onResizeEnd);
|
|
2662
|
+
this.persistState();
|
|
2663
|
+
};
|
|
2600
2664
|
}
|
|
2601
2665
|
init() {
|
|
2602
2666
|
if (!this.container) {
|
|
2603
2667
|
this.createContainer();
|
|
2604
2668
|
}
|
|
2669
|
+
else {
|
|
2670
|
+
this.applyState();
|
|
2671
|
+
}
|
|
2605
2672
|
}
|
|
2606
2673
|
log(type, ...args) {
|
|
2607
2674
|
this.init();
|
|
@@ -2616,58 +2683,75 @@ class VirtualScrollDebugOverlay {
|
|
|
2616
2683
|
dispose() {
|
|
2617
2684
|
this.container?.remove();
|
|
2618
2685
|
this.container = undefined;
|
|
2686
|
+
this.contentWrapper = undefined;
|
|
2687
|
+
this.bubble = undefined;
|
|
2619
2688
|
this.logList = undefined;
|
|
2620
2689
|
this.selectorInput = undefined;
|
|
2621
2690
|
this.distanceInput = undefined;
|
|
2691
|
+
this.collapseToggle = undefined;
|
|
2692
|
+
this.resizeHandle = undefined;
|
|
2622
2693
|
this.doc.removeEventListener('mousemove', this.onDragging);
|
|
2623
2694
|
this.doc.removeEventListener('mouseup', this.onDragEnd);
|
|
2695
|
+
this.doc.removeEventListener('mousemove', this.onResizing);
|
|
2696
|
+
this.doc.removeEventListener('mouseup', this.onResizeEnd);
|
|
2624
2697
|
this.isDragging = false;
|
|
2698
|
+
this.isResizing = false;
|
|
2625
2699
|
}
|
|
2626
2700
|
createContainer() {
|
|
2701
|
+
this.loadState();
|
|
2627
2702
|
const doc = this.doc;
|
|
2628
2703
|
const container = doc.createElement('div');
|
|
2629
2704
|
container.style.position = 'fixed';
|
|
2630
|
-
container.style.left = '16px';
|
|
2631
|
-
container.style.top = '16px';
|
|
2632
2705
|
container.style.right = 'auto';
|
|
2633
2706
|
container.style.bottom = 'auto';
|
|
2634
|
-
container.style.width = '360px';
|
|
2635
|
-
container.style.maxHeight = '70vh';
|
|
2636
|
-
container.style.padding = '12px';
|
|
2637
2707
|
container.style.boxSizing = 'border-box';
|
|
2638
2708
|
container.style.background = 'rgba(17, 24, 39, 0.95)';
|
|
2639
2709
|
container.style.color = '#e5e7eb';
|
|
2640
2710
|
container.style.fontSize = '12px';
|
|
2641
|
-
container.style.fontFamily = 'Menlo, Consolas, monospace';
|
|
2642
2711
|
container.style.border = '1px solid #1f2937';
|
|
2643
2712
|
container.style.borderRadius = '10px';
|
|
2713
|
+
container.style.fontFamily = 'Menlo, Consolas, monospace';
|
|
2644
2714
|
container.style.boxShadow = '0 10px 30px rgba(0, 0, 0, 0.35)';
|
|
2645
2715
|
container.style.zIndex = '9999';
|
|
2646
2716
|
container.style.display = 'flex';
|
|
2647
2717
|
container.style.flexDirection = 'column';
|
|
2648
2718
|
container.style.gap = '10px';
|
|
2719
|
+
container.style.minWidth = `${VirtualScrollDebugOverlay.minWidth}px`;
|
|
2720
|
+
container.style.minHeight = `${VirtualScrollDebugOverlay.minHeight}px`;
|
|
2721
|
+
container.style.maxHeight = '80vh';
|
|
2722
|
+
container.style.cursor = 'default';
|
|
2723
|
+
container.addEventListener('mousedown', event => {
|
|
2724
|
+
if (this.state.collapsed) {
|
|
2725
|
+
this.startDrag(event);
|
|
2726
|
+
}
|
|
2727
|
+
});
|
|
2649
2728
|
const header = doc.createElement('div');
|
|
2650
2729
|
header.style.display = 'flex';
|
|
2651
2730
|
header.style.alignItems = 'center';
|
|
2652
2731
|
header.style.justifyContent = 'space-between';
|
|
2653
2732
|
header.style.cursor = 'move';
|
|
2654
2733
|
header.addEventListener('mousedown', event => {
|
|
2655
|
-
|
|
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();
|
|
2734
|
+
this.startDrag(event);
|
|
2666
2735
|
});
|
|
2667
2736
|
const title = doc.createElement('div');
|
|
2668
2737
|
title.textContent = 'Virtual Scroll Debug';
|
|
2669
2738
|
title.style.fontWeight = '600';
|
|
2670
2739
|
title.style.letterSpacing = '0.3px';
|
|
2740
|
+
const actions = doc.createElement('div');
|
|
2741
|
+
actions.style.display = 'flex';
|
|
2742
|
+
actions.style.gap = '6px';
|
|
2743
|
+
const collapseButton = doc.createElement('button');
|
|
2744
|
+
collapseButton.type = 'button';
|
|
2745
|
+
collapseButton.textContent = '折叠';
|
|
2746
|
+
collapseButton.style.background = '#1f2937';
|
|
2747
|
+
collapseButton.style.color = '#e5e7eb';
|
|
2748
|
+
collapseButton.style.border = '1px solid #374151';
|
|
2749
|
+
collapseButton.style.borderRadius = '6px';
|
|
2750
|
+
collapseButton.style.padding = '4px 8px';
|
|
2751
|
+
collapseButton.style.cursor = 'pointer';
|
|
2752
|
+
collapseButton.addEventListener('click', () => {
|
|
2753
|
+
this.setCollapsed(!this.state.collapsed);
|
|
2754
|
+
});
|
|
2671
2755
|
const clearButton = doc.createElement('button');
|
|
2672
2756
|
clearButton.type = 'button';
|
|
2673
2757
|
clearButton.textContent = '清除日志';
|
|
@@ -2682,11 +2766,13 @@ class VirtualScrollDebugOverlay {
|
|
|
2682
2766
|
this.logList.innerHTML = '';
|
|
2683
2767
|
}
|
|
2684
2768
|
});
|
|
2769
|
+
actions.appendChild(collapseButton);
|
|
2770
|
+
actions.appendChild(clearButton);
|
|
2685
2771
|
header.appendChild(title);
|
|
2686
|
-
header.appendChild(
|
|
2772
|
+
header.appendChild(actions);
|
|
2687
2773
|
const scrollForm = doc.createElement('div');
|
|
2688
2774
|
scrollForm.style.display = 'grid';
|
|
2689
|
-
scrollForm.style.gridTemplateColumns = '1fr
|
|
2775
|
+
scrollForm.style.gridTemplateColumns = '1fr 110px 50px';
|
|
2690
2776
|
scrollForm.style.gap = '6px';
|
|
2691
2777
|
scrollForm.style.alignItems = 'center';
|
|
2692
2778
|
const selectorInput = doc.createElement('input');
|
|
@@ -2752,14 +2838,194 @@ class VirtualScrollDebugOverlay {
|
|
|
2752
2838
|
logList.style.display = 'flex';
|
|
2753
2839
|
logList.style.flexDirection = 'column';
|
|
2754
2840
|
logList.style.gap = '6px';
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2841
|
+
logList.style.flex = '1';
|
|
2842
|
+
logList.style.minHeight = '160px';
|
|
2843
|
+
const bubble = doc.createElement('div');
|
|
2844
|
+
bubble.textContent = 'VS';
|
|
2845
|
+
bubble.style.display = 'none';
|
|
2846
|
+
bubble.style.alignItems = 'center';
|
|
2847
|
+
bubble.style.justifyContent = 'center';
|
|
2848
|
+
bubble.style.fontWeight = '700';
|
|
2849
|
+
bubble.style.fontSize = '14px';
|
|
2850
|
+
bubble.style.letterSpacing = '0.5px';
|
|
2851
|
+
bubble.style.width = '100%';
|
|
2852
|
+
bubble.style.height = '100%';
|
|
2853
|
+
bubble.style.userSelect = 'none';
|
|
2854
|
+
bubble.addEventListener('click', () => {
|
|
2855
|
+
if (this.wasDragged) {
|
|
2856
|
+
this.wasDragged = false;
|
|
2857
|
+
return;
|
|
2858
|
+
}
|
|
2859
|
+
this.setCollapsed(false);
|
|
2860
|
+
});
|
|
2861
|
+
const contentWrapper = doc.createElement('div');
|
|
2862
|
+
contentWrapper.style.display = 'flex';
|
|
2863
|
+
contentWrapper.style.flexDirection = 'column';
|
|
2864
|
+
contentWrapper.style.gap = '10px';
|
|
2865
|
+
contentWrapper.style.width = '100%';
|
|
2866
|
+
contentWrapper.style.height = '100%';
|
|
2867
|
+
contentWrapper.appendChild(header);
|
|
2868
|
+
contentWrapper.appendChild(scrollForm);
|
|
2869
|
+
contentWrapper.appendChild(logList);
|
|
2870
|
+
container.appendChild(contentWrapper);
|
|
2871
|
+
container.appendChild(bubble);
|
|
2872
|
+
const resizeHandle = doc.createElement('div');
|
|
2873
|
+
resizeHandle.style.position = 'absolute';
|
|
2874
|
+
resizeHandle.style.right = '6px';
|
|
2875
|
+
resizeHandle.style.bottom = '6px';
|
|
2876
|
+
resizeHandle.style.width = '14px';
|
|
2877
|
+
resizeHandle.style.height = '14px';
|
|
2878
|
+
resizeHandle.style.cursor = 'nwse-resize';
|
|
2879
|
+
resizeHandle.style.borderRight = '2px solid #4b5563';
|
|
2880
|
+
resizeHandle.style.borderBottom = '2px solid #4b5563';
|
|
2881
|
+
resizeHandle.addEventListener('mousedown', event => {
|
|
2882
|
+
this.startResize(event);
|
|
2883
|
+
});
|
|
2884
|
+
container.appendChild(resizeHandle);
|
|
2758
2885
|
doc.body.appendChild(container);
|
|
2759
2886
|
this.container = container;
|
|
2887
|
+
this.contentWrapper = contentWrapper;
|
|
2888
|
+
this.bubble = bubble;
|
|
2760
2889
|
this.logList = logList;
|
|
2761
2890
|
this.selectorInput = selectorInput;
|
|
2762
2891
|
this.distanceInput = distanceInput;
|
|
2892
|
+
this.collapseToggle = collapseButton;
|
|
2893
|
+
this.resizeHandle = resizeHandle;
|
|
2894
|
+
this.applyState();
|
|
2895
|
+
}
|
|
2896
|
+
startDrag(event) {
|
|
2897
|
+
if (event.button !== 0) {
|
|
2898
|
+
return;
|
|
2899
|
+
}
|
|
2900
|
+
if (!this.container) {
|
|
2901
|
+
return;
|
|
2902
|
+
}
|
|
2903
|
+
const rect = this.container.getBoundingClientRect();
|
|
2904
|
+
this.isDragging = true;
|
|
2905
|
+
this.wasDragged = false;
|
|
2906
|
+
this.dragMoved = false;
|
|
2907
|
+
this.dragOffsetX = event.clientX - rect.left;
|
|
2908
|
+
this.dragOffsetY = event.clientY - rect.top;
|
|
2909
|
+
this.container.style.transition = 'none';
|
|
2910
|
+
this.doc.addEventListener('mousemove', this.onDragging);
|
|
2911
|
+
this.doc.addEventListener('mouseup', this.onDragEnd);
|
|
2912
|
+
if (!this.state.collapsed) {
|
|
2913
|
+
event.preventDefault();
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
startResize(event) {
|
|
2917
|
+
if (event.button !== 0 || this.state.collapsed) {
|
|
2918
|
+
return;
|
|
2919
|
+
}
|
|
2920
|
+
if (!this.container) {
|
|
2921
|
+
return;
|
|
2922
|
+
}
|
|
2923
|
+
const rect = this.container.getBoundingClientRect();
|
|
2924
|
+
this.isResizing = true;
|
|
2925
|
+
this.resizeStartX = event.clientX;
|
|
2926
|
+
this.resizeStartY = event.clientY;
|
|
2927
|
+
this.resizeStartWidth = rect.width;
|
|
2928
|
+
this.resizeStartHeight = rect.height;
|
|
2929
|
+
this.doc.addEventListener('mousemove', this.onResizing);
|
|
2930
|
+
this.doc.addEventListener('mouseup', this.onResizeEnd);
|
|
2931
|
+
event.preventDefault();
|
|
2932
|
+
event.stopPropagation();
|
|
2933
|
+
}
|
|
2934
|
+
applyPosition() {
|
|
2935
|
+
if (!this.container) {
|
|
2936
|
+
return;
|
|
2937
|
+
}
|
|
2938
|
+
this.container.style.left = `${this.state.left}px`;
|
|
2939
|
+
this.container.style.top = `${this.state.top}px`;
|
|
2940
|
+
}
|
|
2941
|
+
applySize() {
|
|
2942
|
+
if (!this.container) {
|
|
2943
|
+
return;
|
|
2944
|
+
}
|
|
2945
|
+
const width = Math.max(VirtualScrollDebugOverlay.minWidth, this.state.width || VirtualScrollDebugOverlay.defaultWidth);
|
|
2946
|
+
const height = Math.max(VirtualScrollDebugOverlay.minHeight, this.state.height || VirtualScrollDebugOverlay.defaultHeight);
|
|
2947
|
+
this.state.width = width;
|
|
2948
|
+
this.state.height = height;
|
|
2949
|
+
this.container.style.width = `${width}px`;
|
|
2950
|
+
this.container.style.height = `${height}px`;
|
|
2951
|
+
}
|
|
2952
|
+
applyCollapsedState() {
|
|
2953
|
+
if (!this.container || !this.contentWrapper || !this.bubble || !this.collapseToggle) {
|
|
2954
|
+
return;
|
|
2955
|
+
}
|
|
2956
|
+
if (this.state.collapsed) {
|
|
2957
|
+
this.container.style.width = '36px';
|
|
2958
|
+
this.container.style.height = '36px';
|
|
2959
|
+
this.container.style.minWidth = '';
|
|
2960
|
+
this.container.style.minHeight = '';
|
|
2961
|
+
this.container.style.padding = '0';
|
|
2962
|
+
this.container.style.borderRadius = '50%';
|
|
2963
|
+
this.container.style.display = 'flex';
|
|
2964
|
+
this.container.style.flexDirection = 'row';
|
|
2965
|
+
this.container.style.alignItems = 'center';
|
|
2966
|
+
this.container.style.justifyContent = 'center';
|
|
2967
|
+
this.container.style.cursor = 'move';
|
|
2968
|
+
this.contentWrapper.style.display = 'none';
|
|
2969
|
+
this.bubble.style.display = 'flex';
|
|
2970
|
+
this.collapseToggle.textContent = '展开';
|
|
2971
|
+
this.resizeHandle.style.display = 'none';
|
|
2972
|
+
}
|
|
2973
|
+
else {
|
|
2974
|
+
this.applySize();
|
|
2975
|
+
this.container.style.padding = '12px';
|
|
2976
|
+
this.container.style.borderRadius = '10px';
|
|
2977
|
+
this.container.style.display = 'flex';
|
|
2978
|
+
this.container.style.flexDirection = 'column';
|
|
2979
|
+
this.container.style.gap = '10px';
|
|
2980
|
+
this.container.style.cursor = 'default';
|
|
2981
|
+
this.contentWrapper.style.display = 'flex';
|
|
2982
|
+
this.bubble.style.display = 'none';
|
|
2983
|
+
this.collapseToggle.textContent = '折叠';
|
|
2984
|
+
this.resizeHandle.style.display = 'block';
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
setCollapsed(collapsed) {
|
|
2988
|
+
this.state.collapsed = collapsed;
|
|
2989
|
+
this.applyCollapsedState();
|
|
2990
|
+
this.persistState();
|
|
2991
|
+
}
|
|
2992
|
+
applyState() {
|
|
2993
|
+
this.applyPosition();
|
|
2994
|
+
this.applyCollapsedState();
|
|
2995
|
+
}
|
|
2996
|
+
loadState() {
|
|
2997
|
+
try {
|
|
2998
|
+
const raw = this.doc.defaultView?.localStorage?.getItem(VirtualScrollDebugOverlay.storageKey);
|
|
2999
|
+
if (raw) {
|
|
3000
|
+
const parsed = JSON.parse(raw);
|
|
3001
|
+
if (typeof parsed.left === 'number') {
|
|
3002
|
+
this.state.left = parsed.left;
|
|
3003
|
+
}
|
|
3004
|
+
if (typeof parsed.top === 'number') {
|
|
3005
|
+
this.state.top = parsed.top;
|
|
3006
|
+
}
|
|
3007
|
+
if (typeof parsed.collapsed === 'boolean') {
|
|
3008
|
+
this.state.collapsed = parsed.collapsed;
|
|
3009
|
+
}
|
|
3010
|
+
if (typeof parsed.width === 'number') {
|
|
3011
|
+
this.state.width = parsed.width;
|
|
3012
|
+
}
|
|
3013
|
+
if (typeof parsed.height === 'number') {
|
|
3014
|
+
this.state.height = parsed.height;
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
3018
|
+
catch {
|
|
3019
|
+
// ignore storage errors
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
persistState() {
|
|
3023
|
+
try {
|
|
3024
|
+
this.doc.defaultView?.localStorage?.setItem(VirtualScrollDebugOverlay.storageKey, JSON.stringify(this.state));
|
|
3025
|
+
}
|
|
3026
|
+
catch {
|
|
3027
|
+
// ignore storage errors
|
|
3028
|
+
}
|
|
2763
3029
|
}
|
|
2764
3030
|
appendLog(type, ...args) {
|
|
2765
3031
|
if (!this.logList) {
|
|
@@ -2794,6 +3060,11 @@ class VirtualScrollDebugOverlay {
|
|
|
2794
3060
|
return String(value);
|
|
2795
3061
|
}
|
|
2796
3062
|
}
|
|
3063
|
+
setScrollTopValue(value) {
|
|
3064
|
+
if (this.distanceInput) {
|
|
3065
|
+
this.distanceInput.value = String(value ?? 0);
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
2797
3068
|
}
|
|
2798
3069
|
|
|
2799
3070
|
const JUST_NOW_UPDATED_VIRTUAL_VIEW = new WeakMap();
|
|
@@ -2803,8 +3074,8 @@ const forceOnDOMPaste = IS_SAFARI;
|
|
|
2803
3074
|
const isDebug = localStorage.getItem(SLATE_DEBUG_KEY) === 'true';
|
|
2804
3075
|
class SlateEditable {
|
|
2805
3076
|
set virtualScroll(config) {
|
|
2806
|
-
this.
|
|
2807
|
-
this.
|
|
3077
|
+
this.virtualScrollConfig = config;
|
|
3078
|
+
this.tryUpdateVirtualViewport();
|
|
2808
3079
|
}
|
|
2809
3080
|
get hasBeforeInputSupport() {
|
|
2810
3081
|
return HAS_BEFORE_INPUT_SUPPORT;
|
|
@@ -2849,14 +3120,14 @@ class SlateEditable {
|
|
|
2849
3120
|
return null;
|
|
2850
3121
|
}
|
|
2851
3122
|
};
|
|
2852
|
-
this.
|
|
3123
|
+
this.virtualScrollConfig = {
|
|
2853
3124
|
enabled: false,
|
|
2854
3125
|
scrollTop: 0,
|
|
2855
3126
|
viewportHeight: 0
|
|
2856
3127
|
};
|
|
2857
|
-
this.
|
|
2858
|
-
this.
|
|
2859
|
-
this.
|
|
3128
|
+
this.inViewportChildren = [];
|
|
3129
|
+
this.inViewportIndics = new Set();
|
|
3130
|
+
this.keyHeightMap = new Map();
|
|
2860
3131
|
// the height from scroll container top to editor top height element
|
|
2861
3132
|
this.businessHeight = 0;
|
|
2862
3133
|
this.virtualScrollInitialized = false;
|
|
@@ -2870,7 +3141,7 @@ class SlateEditable {
|
|
|
2870
3141
|
NODE_TO_ELEMENT.set(this.editor, this.elementRef.nativeElement);
|
|
2871
3142
|
ELEMENT_TO_NODE.set(this.elementRef.nativeElement, this.editor);
|
|
2872
3143
|
IS_READ_ONLY.set(this.editor, this.readonly);
|
|
2873
|
-
ELEMENT_KEY_TO_HEIGHTS.set(this.editor, this.
|
|
3144
|
+
ELEMENT_KEY_TO_HEIGHTS.set(this.editor, this.keyHeightMap);
|
|
2874
3145
|
EDITOR_TO_ON_CHANGE.set(this.editor, () => {
|
|
2875
3146
|
this.ngZone.run(() => {
|
|
2876
3147
|
this.onChange();
|
|
@@ -2884,7 +3155,7 @@ class SlateEditable {
|
|
|
2884
3155
|
// add browser class
|
|
2885
3156
|
let browserClass = IS_FIREFOX ? 'firefox' : IS_SAFARI ? 'safari' : '';
|
|
2886
3157
|
browserClass && this.elementRef.nativeElement.classList.add(browserClass);
|
|
2887
|
-
this.
|
|
3158
|
+
this.initializeVirtualScroll();
|
|
2888
3159
|
this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
|
|
2889
3160
|
}
|
|
2890
3161
|
ngOnChanges(simpleChanges) {
|
|
@@ -2916,9 +3187,9 @@ class SlateEditable {
|
|
|
2916
3187
|
if (value && value.length) {
|
|
2917
3188
|
this.editor.children = value;
|
|
2918
3189
|
this.initializeContext();
|
|
2919
|
-
const virtualView = this.
|
|
3190
|
+
const virtualView = this.calculateVirtualViewport();
|
|
2920
3191
|
this.applyVirtualView(virtualView);
|
|
2921
|
-
const childrenForRender = virtualView.
|
|
3192
|
+
const childrenForRender = virtualView.inViewportChildren;
|
|
2922
3193
|
if (!this.listRender.initialized) {
|
|
2923
3194
|
this.listRender.initialize(childrenForRender, this.editor, this.context);
|
|
2924
3195
|
}
|
|
@@ -2959,8 +3230,8 @@ class SlateEditable {
|
|
|
2959
3230
|
toNativeSelection() {
|
|
2960
3231
|
try {
|
|
2961
3232
|
let { selection } = this.editor;
|
|
2962
|
-
if (this.
|
|
2963
|
-
const indics = Array.from(this.
|
|
3233
|
+
if (this.virtualScrollConfig?.enabled && selection) {
|
|
3234
|
+
const indics = Array.from(this.inViewportIndics.values());
|
|
2964
3235
|
if (indics.length > 0) {
|
|
2965
3236
|
const currentVisibleRange = {
|
|
2966
3237
|
anchor: Editor.start(this.editor, [indics[0]]),
|
|
@@ -3064,10 +3335,10 @@ class SlateEditable {
|
|
|
3064
3335
|
ngDoCheck() { }
|
|
3065
3336
|
forceRender() {
|
|
3066
3337
|
this.updateContext();
|
|
3067
|
-
const virtualView = this.
|
|
3338
|
+
const virtualView = this.calculateVirtualViewport();
|
|
3068
3339
|
this.applyVirtualView(virtualView);
|
|
3069
|
-
const visibleIndexes = Array.from(this.
|
|
3070
|
-
this.listRender.update(this.
|
|
3340
|
+
const visibleIndexes = Array.from(this.inViewportIndics);
|
|
3341
|
+
this.listRender.update(this.inViewportChildren, this.editor, this.context);
|
|
3071
3342
|
this.remeasureHeightByIndics(visibleIndexes);
|
|
3072
3343
|
// repair collaborative editing when Chinese input is interrupted by other users' cursors
|
|
3073
3344
|
// when the DOMElement where the selection is located is removed
|
|
@@ -3107,9 +3378,9 @@ class SlateEditable {
|
|
|
3107
3378
|
render() {
|
|
3108
3379
|
const changed = this.updateContext();
|
|
3109
3380
|
if (changed) {
|
|
3110
|
-
const virtualView = this.
|
|
3381
|
+
const virtualView = this.calculateVirtualViewport();
|
|
3111
3382
|
this.applyVirtualView(virtualView);
|
|
3112
|
-
this.listRender.update(virtualView.
|
|
3383
|
+
this.listRender.update(virtualView.inViewportChildren, this.editor, this.context);
|
|
3113
3384
|
this.scheduleMeasureVisibleHeights();
|
|
3114
3385
|
}
|
|
3115
3386
|
}
|
|
@@ -3173,14 +3444,14 @@ class SlateEditable {
|
|
|
3173
3444
|
decorations.push(...placeholderDecorations);
|
|
3174
3445
|
return decorations;
|
|
3175
3446
|
}
|
|
3176
|
-
|
|
3177
|
-
return !!(this.
|
|
3447
|
+
isEnabledVirtualScroll() {
|
|
3448
|
+
return !!(this.virtualScrollConfig && this.virtualScrollConfig.enabled);
|
|
3178
3449
|
}
|
|
3179
|
-
|
|
3450
|
+
initializeVirtualScroll() {
|
|
3180
3451
|
if (this.virtualScrollInitialized) {
|
|
3181
3452
|
return;
|
|
3182
3453
|
}
|
|
3183
|
-
if (this.
|
|
3454
|
+
if (this.virtualScrollConfig && this.virtualScrollConfig.enabled) {
|
|
3184
3455
|
this.virtualScrollInitialized = true;
|
|
3185
3456
|
this.virtualTopHeightElement = document.createElement('div');
|
|
3186
3457
|
this.virtualTopHeightElement.classList.add('virtual-top-height');
|
|
@@ -3198,18 +3469,17 @@ class SlateEditable {
|
|
|
3198
3469
|
this.editorResizeObserver = new ResizeObserver(entries => {
|
|
3199
3470
|
if (entries.length > 0 && entries[0].contentRect.width !== editorResizeObserverRectWidth) {
|
|
3200
3471
|
editorResizeObserverRectWidth = entries[0].contentRect.width;
|
|
3201
|
-
this.remeasureHeightByIndics(Array.from(this.
|
|
3472
|
+
this.remeasureHeightByIndics(Array.from(this.inViewportIndics));
|
|
3202
3473
|
}
|
|
3203
3474
|
});
|
|
3204
3475
|
this.editorResizeObserver.observe(this.elementRef.nativeElement);
|
|
3205
3476
|
if (isDebug) {
|
|
3206
3477
|
const doc = this.elementRef?.nativeElement?.ownerDocument ?? document;
|
|
3207
|
-
|
|
3208
|
-
this.debugOverlay.init();
|
|
3478
|
+
VirtualScrollDebugOverlay.getInstance(doc);
|
|
3209
3479
|
}
|
|
3210
3480
|
}
|
|
3211
3481
|
}
|
|
3212
|
-
|
|
3482
|
+
setVirtualSpaceHeight(topHeight, bottomHeight) {
|
|
3213
3483
|
if (!this.virtualScrollInitialized) {
|
|
3214
3484
|
return;
|
|
3215
3485
|
}
|
|
@@ -3217,25 +3487,22 @@ class SlateEditable {
|
|
|
3217
3487
|
this.virtualBottomHeightElement.style.height = `${bottomHeight}px`;
|
|
3218
3488
|
}
|
|
3219
3489
|
debugLog(type, ...args) {
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
this.debugOverlay = new VirtualScrollDebugOverlay(doc);
|
|
3223
|
-
}
|
|
3224
|
-
this.debugOverlay.log(type, ...args);
|
|
3490
|
+
const doc = this.elementRef?.nativeElement?.ownerDocument ?? document;
|
|
3491
|
+
VirtualScrollDebugOverlay.log(doc, type, ...args);
|
|
3225
3492
|
}
|
|
3226
|
-
|
|
3493
|
+
tryUpdateVirtualViewport() {
|
|
3227
3494
|
this.refreshVirtualViewAnimId && cancelAnimationFrame(this.refreshVirtualViewAnimId);
|
|
3228
3495
|
this.refreshVirtualViewAnimId = requestAnimationFrame(() => {
|
|
3229
|
-
let virtualView = this.
|
|
3230
|
-
let diff = this.
|
|
3496
|
+
let virtualView = this.calculateVirtualViewport();
|
|
3497
|
+
let diff = this.diffVirtualViewport(virtualView);
|
|
3231
3498
|
if (!diff.isDiff) {
|
|
3232
3499
|
return;
|
|
3233
3500
|
}
|
|
3234
3501
|
if (diff.isMissingTop) {
|
|
3235
3502
|
const result = this.remeasureHeightByIndics(diff.diffTopRenderedIndexes);
|
|
3236
3503
|
if (result) {
|
|
3237
|
-
virtualView = this.
|
|
3238
|
-
diff = this.
|
|
3504
|
+
virtualView = this.calculateVirtualViewport();
|
|
3505
|
+
diff = this.diffVirtualViewport(virtualView, 'second');
|
|
3239
3506
|
if (!diff.isDiff) {
|
|
3240
3507
|
return;
|
|
3241
3508
|
}
|
|
@@ -3243,7 +3510,7 @@ class SlateEditable {
|
|
|
3243
3510
|
}
|
|
3244
3511
|
this.applyVirtualView(virtualView);
|
|
3245
3512
|
if (this.listRender.initialized) {
|
|
3246
|
-
this.listRender.update(virtualView.
|
|
3513
|
+
this.listRender.update(virtualView.inViewportChildren, this.editor, this.context);
|
|
3247
3514
|
if (!AngularEditor.isReadOnly(this.editor) && this.editor.selection) {
|
|
3248
3515
|
this.toNativeSelection();
|
|
3249
3516
|
}
|
|
@@ -3251,22 +3518,26 @@ class SlateEditable {
|
|
|
3251
3518
|
this.scheduleMeasureVisibleHeights();
|
|
3252
3519
|
});
|
|
3253
3520
|
}
|
|
3254
|
-
|
|
3521
|
+
calculateVirtualViewport() {
|
|
3255
3522
|
const children = (this.editor.children || []);
|
|
3256
|
-
if (!children.length || !this.
|
|
3523
|
+
if (!children.length || !this.isEnabledVirtualScroll()) {
|
|
3257
3524
|
return {
|
|
3258
|
-
|
|
3525
|
+
inViewportChildren: children,
|
|
3259
3526
|
visibleIndexes: new Set(),
|
|
3260
3527
|
top: 0,
|
|
3261
3528
|
bottom: 0,
|
|
3262
3529
|
heights: []
|
|
3263
3530
|
};
|
|
3264
3531
|
}
|
|
3265
|
-
const scrollTop = this.
|
|
3266
|
-
|
|
3532
|
+
const scrollTop = this.virtualScrollConfig.scrollTop;
|
|
3533
|
+
if (isDebug) {
|
|
3534
|
+
const doc = this.elementRef?.nativeElement?.ownerDocument ?? document;
|
|
3535
|
+
VirtualScrollDebugOverlay.syncScrollTop(doc, Number.isFinite(scrollTop) ? scrollTop : 0);
|
|
3536
|
+
}
|
|
3537
|
+
const viewportHeight = this.virtualScrollConfig.viewportHeight ?? 0;
|
|
3267
3538
|
if (!viewportHeight) {
|
|
3268
3539
|
return {
|
|
3269
|
-
|
|
3540
|
+
inViewportChildren: [],
|
|
3270
3541
|
visibleIndexes: new Set(),
|
|
3271
3542
|
top: 0,
|
|
3272
3543
|
bottom: 0,
|
|
@@ -3306,7 +3577,7 @@ class SlateEditable {
|
|
|
3306
3577
|
const top = visibleStartIndex === -1 ? 0 : accumulatedHeights[visibleStartIndex];
|
|
3307
3578
|
const bottom = totalHeight - accumulatedHeights[visibleEndIndex + 1];
|
|
3308
3579
|
return {
|
|
3309
|
-
|
|
3580
|
+
inViewportChildren: visible.length ? visible : children,
|
|
3310
3581
|
visibleIndexes: new Set(visibleIndexes),
|
|
3311
3582
|
top,
|
|
3312
3583
|
bottom,
|
|
@@ -3314,19 +3585,19 @@ class SlateEditable {
|
|
|
3314
3585
|
};
|
|
3315
3586
|
}
|
|
3316
3587
|
applyVirtualView(virtualView) {
|
|
3317
|
-
this.
|
|
3318
|
-
this.
|
|
3319
|
-
this.
|
|
3588
|
+
this.inViewportChildren = virtualView.inViewportChildren;
|
|
3589
|
+
this.setVirtualSpaceHeight(virtualView.top, virtualView.bottom);
|
|
3590
|
+
this.inViewportIndics = virtualView.visibleIndexes;
|
|
3320
3591
|
}
|
|
3321
|
-
|
|
3322
|
-
if (!this.
|
|
3592
|
+
diffVirtualViewport(virtualView, stage = 'first') {
|
|
3593
|
+
if (!this.inViewportChildren.length) {
|
|
3323
3594
|
return {
|
|
3324
3595
|
isDiff: true,
|
|
3325
3596
|
diffTopRenderedIndexes: [],
|
|
3326
3597
|
diffBottomRenderedIndexes: []
|
|
3327
3598
|
};
|
|
3328
3599
|
}
|
|
3329
|
-
const oldVisibleIndexes = [...this.
|
|
3600
|
+
const oldVisibleIndexes = [...this.inViewportIndics];
|
|
3330
3601
|
const newVisibleIndexes = [...virtualView.visibleIndexes];
|
|
3331
3602
|
const firstNewIndex = newVisibleIndexes[0];
|
|
3332
3603
|
const lastNewIndex = newVisibleIndexes[newVisibleIndexes.length - 1];
|
|
@@ -3382,7 +3653,7 @@ class SlateEditable {
|
|
|
3382
3653
|
}
|
|
3383
3654
|
}
|
|
3384
3655
|
if (isDebug) {
|
|
3385
|
-
this.debugLog('log', `======
|
|
3656
|
+
this.debugLog('log', `====== diffVirtualViewport stage: ${stage} ======`);
|
|
3386
3657
|
this.debugLog('log', 'oldVisibleIndexes:', oldVisibleIndexes);
|
|
3387
3658
|
this.debugLog('log', 'newVisibleIndexes:', newVisibleIndexes);
|
|
3388
3659
|
this.debugLog('log', 'diffTopRenderedIndexes:', isMissingTop ? '-' : isAddedTop ? '+' : '-', diffTopRenderedIndexes, diffTopRenderedIndexes.map(index => this.getBlockHeight(index, 0)));
|
|
@@ -3413,11 +3684,22 @@ class SlateEditable {
|
|
|
3413
3684
|
}
|
|
3414
3685
|
getBlockHeight(index, defaultHeight = VIRTUAL_SCROLL_DEFAULT_BLOCK_HEIGHT) {
|
|
3415
3686
|
const node = this.editor.children[index];
|
|
3687
|
+
const isVisible = this.editor.isVisible(node);
|
|
3688
|
+
if (!isVisible) {
|
|
3689
|
+
return 0;
|
|
3690
|
+
}
|
|
3416
3691
|
if (!node) {
|
|
3417
3692
|
return defaultHeight;
|
|
3418
3693
|
}
|
|
3419
3694
|
const key = AngularEditor.findKey(this.editor, node);
|
|
3420
|
-
|
|
3695
|
+
const height = this.keyHeightMap.get(key.id);
|
|
3696
|
+
if (typeof height === 'number') {
|
|
3697
|
+
return height;
|
|
3698
|
+
}
|
|
3699
|
+
if (this.keyHeightMap.has(key.id)) {
|
|
3700
|
+
console.error('getBlockHeight: invalid height value', key.id, height);
|
|
3701
|
+
}
|
|
3702
|
+
return defaultHeight;
|
|
3421
3703
|
}
|
|
3422
3704
|
buildAccumulatedHeight(heights) {
|
|
3423
3705
|
const accumulatedHeights = new Array(heights.length + 1).fill(0);
|
|
@@ -3428,7 +3710,7 @@ class SlateEditable {
|
|
|
3428
3710
|
return accumulatedHeights;
|
|
3429
3711
|
}
|
|
3430
3712
|
scheduleMeasureVisibleHeights() {
|
|
3431
|
-
if (!this.
|
|
3713
|
+
if (!this.isEnabledVirtualScroll()) {
|
|
3432
3714
|
return;
|
|
3433
3715
|
}
|
|
3434
3716
|
this.measureVisibleHeightsAnimId && cancelAnimationFrame(this.measureVisibleHeightsAnimId);
|
|
@@ -3438,14 +3720,14 @@ class SlateEditable {
|
|
|
3438
3720
|
}
|
|
3439
3721
|
measureVisibleHeights() {
|
|
3440
3722
|
const children = (this.editor.children || []);
|
|
3441
|
-
this.
|
|
3723
|
+
this.inViewportIndics.forEach(index => {
|
|
3442
3724
|
const node = children[index];
|
|
3443
3725
|
if (!node) {
|
|
3444
3726
|
return;
|
|
3445
3727
|
}
|
|
3446
3728
|
const key = AngularEditor.findKey(this.editor, node);
|
|
3447
3729
|
// 跳过已测过的块,除非强制测量
|
|
3448
|
-
if (this.
|
|
3730
|
+
if (this.keyHeightMap.has(key.id)) {
|
|
3449
3731
|
return;
|
|
3450
3732
|
}
|
|
3451
3733
|
const view = ELEMENT_TO_COMPONENT.get(node);
|
|
@@ -3455,11 +3737,11 @@ class SlateEditable {
|
|
|
3455
3737
|
const ret = view.getRealHeight();
|
|
3456
3738
|
if (ret instanceof Promise) {
|
|
3457
3739
|
ret.then(height => {
|
|
3458
|
-
this.
|
|
3740
|
+
this.keyHeightMap.set(key.id, height);
|
|
3459
3741
|
});
|
|
3460
3742
|
}
|
|
3461
3743
|
else {
|
|
3462
|
-
this.
|
|
3744
|
+
this.keyHeightMap.set(key.id, ret);
|
|
3463
3745
|
}
|
|
3464
3746
|
});
|
|
3465
3747
|
}
|
|
@@ -3476,12 +3758,12 @@ class SlateEditable {
|
|
|
3476
3758
|
if (!view) {
|
|
3477
3759
|
return;
|
|
3478
3760
|
}
|
|
3479
|
-
const prevHeight = this.
|
|
3761
|
+
const prevHeight = this.keyHeightMap.get(key.id);
|
|
3480
3762
|
const ret = view.getRealHeight();
|
|
3481
3763
|
if (ret instanceof Promise) {
|
|
3482
3764
|
ret.then(height => {
|
|
3483
3765
|
if (height !== prevHeight) {
|
|
3484
|
-
this.
|
|
3766
|
+
this.keyHeightMap.set(key.id, height);
|
|
3485
3767
|
isHeightChanged = true;
|
|
3486
3768
|
if (isDebug) {
|
|
3487
3769
|
this.debugLog('log', `remeasureHeightByIndics, index: ${index} prevHeight: ${prevHeight} newHeight: ${height}`);
|
|
@@ -3491,7 +3773,7 @@ class SlateEditable {
|
|
|
3491
3773
|
}
|
|
3492
3774
|
else {
|
|
3493
3775
|
if (ret !== prevHeight) {
|
|
3494
|
-
this.
|
|
3776
|
+
this.keyHeightMap.set(key.id, ret);
|
|
3495
3777
|
isHeightChanged = true;
|
|
3496
3778
|
if (isDebug) {
|
|
3497
3779
|
this.debugLog('log', `remeasureHeightByIndics, index: ${index} prevHeight: ${prevHeight} newHeight: ${ret}`);
|
|
@@ -4198,8 +4480,6 @@ class SlateEditable {
|
|
|
4198
4480
|
//#endregion
|
|
4199
4481
|
ngOnDestroy() {
|
|
4200
4482
|
this.editorResizeObserver?.disconnect();
|
|
4201
|
-
this.debugOverlay?.dispose();
|
|
4202
|
-
this.debugOverlay = undefined;
|
|
4203
4483
|
NODE_TO_ELEMENT.delete(this.editor);
|
|
4204
4484
|
this.manualListeners.forEach(manualListener => {
|
|
4205
4485
|
manualListener();
|