dockview-react 4.6.2 → 4.7.1
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/dist/dockview-react.amd.js +235 -67
- package/dist/dockview-react.amd.js.map +1 -1
- package/dist/dockview-react.amd.min.js +2 -2
- package/dist/dockview-react.amd.min.js.map +1 -1
- package/dist/dockview-react.amd.min.noStyle.js +2 -2
- package/dist/dockview-react.amd.min.noStyle.js.map +1 -1
- package/dist/dockview-react.amd.noStyle.js +234 -66
- package/dist/dockview-react.amd.noStyle.js.map +1 -1
- package/dist/dockview-react.cjs.js +235 -67
- package/dist/dockview-react.cjs.js.map +1 -1
- package/dist/dockview-react.esm.js +235 -67
- package/dist/dockview-react.esm.js.map +1 -1
- package/dist/dockview-react.esm.min.js +2 -2
- package/dist/dockview-react.esm.min.js.map +1 -1
- package/dist/dockview-react.js +235 -67
- package/dist/dockview-react.js.map +1 -1
- package/dist/dockview-react.min.js +2 -2
- package/dist/dockview-react.min.js.map +1 -1
- package/dist/dockview-react.min.noStyle.js +2 -2
- package/dist/dockview-react.min.noStyle.js.map +1 -1
- package/dist/dockview-react.noStyle.js +234 -66
- package/dist/dockview-react.noStyle.js.map +1 -1
- package/dist/styles/dockview.css +37 -5
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dockview-react
|
|
3
|
-
* @version 4.
|
|
3
|
+
* @version 4.7.1
|
|
4
4
|
* @link https://github.com/mathuo/dockview
|
|
5
5
|
* @license MIT
|
|
6
6
|
*/
|
|
@@ -2139,6 +2139,19 @@
|
|
|
2139
2139
|
}
|
|
2140
2140
|
throw new Error('invalid node');
|
|
2141
2141
|
}
|
|
2142
|
+
function cloneNode(node, size, orthogonalSize) {
|
|
2143
|
+
if (node instanceof BranchNode) {
|
|
2144
|
+
const result = new BranchNode(node.orientation, node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled, node.margin);
|
|
2145
|
+
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
2146
|
+
const child = node.children[i];
|
|
2147
|
+
result.addChild(cloneNode(child, child.size, child.orthogonalSize), child.size, 0, true);
|
|
2148
|
+
}
|
|
2149
|
+
return result;
|
|
2150
|
+
}
|
|
2151
|
+
else {
|
|
2152
|
+
return new LeafNode(node.view, node.orientation, orthogonalSize);
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2142
2155
|
function flipNode(node, size, orthogonalSize) {
|
|
2143
2156
|
if (node instanceof BranchNode) {
|
|
2144
2157
|
const result = new BranchNode(orthogonal(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled, node.margin);
|
|
@@ -2489,6 +2502,29 @@
|
|
|
2489
2502
|
this._onDidChange.fire(e);
|
|
2490
2503
|
});
|
|
2491
2504
|
}
|
|
2505
|
+
normalize() {
|
|
2506
|
+
if (!this._root) {
|
|
2507
|
+
return;
|
|
2508
|
+
}
|
|
2509
|
+
if (this._root.children.length !== 1) {
|
|
2510
|
+
return;
|
|
2511
|
+
}
|
|
2512
|
+
const oldRoot = this.root;
|
|
2513
|
+
// can remove one level of redundant branching if there is only a single child
|
|
2514
|
+
const childReference = oldRoot.children[0];
|
|
2515
|
+
if (childReference instanceof LeafNode) {
|
|
2516
|
+
return;
|
|
2517
|
+
}
|
|
2518
|
+
oldRoot.element.remove();
|
|
2519
|
+
const child = oldRoot.removeChild(0); // Remove child to prevent double disposal
|
|
2520
|
+
oldRoot.dispose(); // Dispose old root (won't dispose removed child)
|
|
2521
|
+
child.dispose(); // Dispose the removed child
|
|
2522
|
+
this._root = cloneNode(childReference, childReference.size, childReference.orthogonalSize);
|
|
2523
|
+
this.element.appendChild(this._root.element);
|
|
2524
|
+
this.disposable.value = this._root.onDidChange((e) => {
|
|
2525
|
+
this._onDidChange.fire(e);
|
|
2526
|
+
});
|
|
2527
|
+
}
|
|
2492
2528
|
/**
|
|
2493
2529
|
* If the root is orientated as a VERTICAL node then nest the existing root within a new HORIZIONTAL root node
|
|
2494
2530
|
* If the root is orientated as a HORIZONTAL node then nest the existing root within a new VERITCAL root node
|
|
@@ -3776,9 +3812,10 @@
|
|
|
3776
3812
|
}
|
|
3777
3813
|
|
|
3778
3814
|
class DragHandler extends CompositeDisposable {
|
|
3779
|
-
constructor(el) {
|
|
3815
|
+
constructor(el, disabled) {
|
|
3780
3816
|
super();
|
|
3781
3817
|
this.el = el;
|
|
3818
|
+
this.disabled = disabled;
|
|
3782
3819
|
this.dataDisposable = new MutableDisposable();
|
|
3783
3820
|
this.pointerEventsDisposable = new MutableDisposable();
|
|
3784
3821
|
this._onDragStart = new Emitter();
|
|
@@ -3786,12 +3823,15 @@
|
|
|
3786
3823
|
this.addDisposables(this._onDragStart, this.dataDisposable, this.pointerEventsDisposable);
|
|
3787
3824
|
this.configure();
|
|
3788
3825
|
}
|
|
3826
|
+
setDisabled(disabled) {
|
|
3827
|
+
this.disabled = disabled;
|
|
3828
|
+
}
|
|
3789
3829
|
isCancelled(_event) {
|
|
3790
3830
|
return false;
|
|
3791
3831
|
}
|
|
3792
3832
|
configure() {
|
|
3793
3833
|
this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
|
|
3794
|
-
if (event.defaultPrevented || this.isCancelled(event)) {
|
|
3834
|
+
if (event.defaultPrevented || this.isCancelled(event) || this.disabled) {
|
|
3795
3835
|
event.preventDefault();
|
|
3796
3836
|
return;
|
|
3797
3837
|
}
|
|
@@ -3880,6 +3920,48 @@
|
|
|
3880
3920
|
}
|
|
3881
3921
|
}
|
|
3882
3922
|
|
|
3923
|
+
function setGPUOptimizedBounds(element, bounds) {
|
|
3924
|
+
const { top, left, width, height } = bounds;
|
|
3925
|
+
const topPx = `${Math.round(top)}px`;
|
|
3926
|
+
const leftPx = `${Math.round(left)}px`;
|
|
3927
|
+
const widthPx = `${Math.round(width)}px`;
|
|
3928
|
+
const heightPx = `${Math.round(height)}px`;
|
|
3929
|
+
// Use traditional positioning but maintain GPU layer
|
|
3930
|
+
element.style.top = topPx;
|
|
3931
|
+
element.style.left = leftPx;
|
|
3932
|
+
element.style.width = widthPx;
|
|
3933
|
+
element.style.height = heightPx;
|
|
3934
|
+
element.style.visibility = 'visible';
|
|
3935
|
+
// Ensure GPU layer is maintained
|
|
3936
|
+
if (!element.style.transform || element.style.transform === '') {
|
|
3937
|
+
element.style.transform = 'translate3d(0, 0, 0)';
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
function setGPUOptimizedBoundsFromStrings(element, bounds) {
|
|
3941
|
+
const { top, left, width, height } = bounds;
|
|
3942
|
+
// Use traditional positioning but maintain GPU layer
|
|
3943
|
+
element.style.top = top;
|
|
3944
|
+
element.style.left = left;
|
|
3945
|
+
element.style.width = width;
|
|
3946
|
+
element.style.height = height;
|
|
3947
|
+
element.style.visibility = 'visible';
|
|
3948
|
+
// Ensure GPU layer is maintained
|
|
3949
|
+
if (!element.style.transform || element.style.transform === '') {
|
|
3950
|
+
element.style.transform = 'translate3d(0, 0, 0)';
|
|
3951
|
+
}
|
|
3952
|
+
}
|
|
3953
|
+
function checkBoundsChanged(element, bounds) {
|
|
3954
|
+
const { top, left, width, height } = bounds;
|
|
3955
|
+
const topPx = `${Math.round(top)}px`;
|
|
3956
|
+
const leftPx = `${Math.round(left)}px`;
|
|
3957
|
+
const widthPx = `${Math.round(width)}px`;
|
|
3958
|
+
const heightPx = `${Math.round(height)}px`;
|
|
3959
|
+
// Check if position or size changed (back to traditional method)
|
|
3960
|
+
return element.style.top !== topPx ||
|
|
3961
|
+
element.style.left !== leftPx ||
|
|
3962
|
+
element.style.width !== widthPx ||
|
|
3963
|
+
element.style.height !== heightPx;
|
|
3964
|
+
}
|
|
3883
3965
|
class WillShowOverlayEvent extends DockviewEvent {
|
|
3884
3966
|
get nativeEvent() {
|
|
3885
3967
|
return this.options.nativeEvent;
|
|
@@ -4161,21 +4243,11 @@
|
|
|
4161
4243
|
box.left = rootLeft + width - 4;
|
|
4162
4244
|
box.width = 4;
|
|
4163
4245
|
}
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
const widthPx = `${Math.round(box.width)}px`;
|
|
4167
|
-
const heightPx = `${Math.round(box.height)}px`;
|
|
4168
|
-
if (overlay.style.top === topPx &&
|
|
4169
|
-
overlay.style.left === leftPx &&
|
|
4170
|
-
overlay.style.width === widthPx &&
|
|
4171
|
-
overlay.style.height === heightPx) {
|
|
4246
|
+
// Use GPU-optimized bounds checking and setting
|
|
4247
|
+
if (!checkBoundsChanged(overlay, box)) {
|
|
4172
4248
|
return;
|
|
4173
4249
|
}
|
|
4174
|
-
overlay
|
|
4175
|
-
overlay.style.left = leftPx;
|
|
4176
|
-
overlay.style.width = widthPx;
|
|
4177
|
-
overlay.style.height = heightPx;
|
|
4178
|
-
overlay.style.visibility = 'visible';
|
|
4250
|
+
setGPUOptimizedBounds(overlay, box);
|
|
4179
4251
|
overlay.className = `dv-drop-target-anchor${this.options.className ? ` ${this.options.className}` : ''}`;
|
|
4180
4252
|
toggleClass(overlay, 'dv-drop-target-left', isLeft);
|
|
4181
4253
|
toggleClass(overlay, 'dv-drop-target-right', isRight);
|
|
@@ -4227,10 +4299,7 @@
|
|
|
4227
4299
|
box.top = `${100 * (1 - size)}%`;
|
|
4228
4300
|
box.height = `${100 * size}%`;
|
|
4229
4301
|
}
|
|
4230
|
-
this.overlayElement
|
|
4231
|
-
this.overlayElement.style.left = box.left;
|
|
4232
|
-
this.overlayElement.style.width = box.width;
|
|
4233
|
-
this.overlayElement.style.height = box.height;
|
|
4302
|
+
setGPUOptimizedBoundsFromStrings(this.overlayElement, box);
|
|
4234
4303
|
toggleClass(this.overlayElement, 'dv-drop-target-small-vertical', isSmallY);
|
|
4235
4304
|
toggleClass(this.overlayElement, 'dv-drop-target-small-horizontal', isSmallX);
|
|
4236
4305
|
toggleClass(this.overlayElement, 'dv-drop-target-left', isLeft);
|
|
@@ -4962,8 +5031,8 @@
|
|
|
4962
5031
|
}
|
|
4963
5032
|
|
|
4964
5033
|
class TabDragHandler extends DragHandler {
|
|
4965
|
-
constructor(element, accessor, group, panel) {
|
|
4966
|
-
super(element);
|
|
5034
|
+
constructor(element, accessor, group, panel, disabled) {
|
|
5035
|
+
super(element, disabled);
|
|
4967
5036
|
this.accessor = accessor;
|
|
4968
5037
|
this.group = group;
|
|
4969
5038
|
this.panel = panel;
|
|
@@ -4999,7 +5068,7 @@
|
|
|
4999
5068
|
this._element.tabIndex = 0;
|
|
5000
5069
|
this._element.draggable = !this.accessor.options.disableDnd;
|
|
5001
5070
|
toggleClass(this.element, 'dv-inactive-tab', true);
|
|
5002
|
-
|
|
5071
|
+
this.dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel, !!this.accessor.options.disableDnd);
|
|
5003
5072
|
this.dropTarget = new Droptarget(this._element, {
|
|
5004
5073
|
acceptedTargetZones: ['left', 'right'],
|
|
5005
5074
|
overlayModel: { activationSize: { value: 50, type: 'percentage' } },
|
|
@@ -5016,7 +5085,7 @@
|
|
|
5016
5085
|
getOverrideTarget: () => { var _a; return (_a = group.model.dropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
|
|
5017
5086
|
});
|
|
5018
5087
|
this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
|
|
5019
|
-
this.addDisposables(this._onPointDown, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
|
|
5088
|
+
this.addDisposables(this._onPointDown, this._onDropped, this._onDragStart, this.dragHandler.onDragStart((event) => {
|
|
5020
5089
|
if (event.dataTransfer) {
|
|
5021
5090
|
const style = getComputedStyle(this.element);
|
|
5022
5091
|
const newNode = this.element.cloneNode(true);
|
|
@@ -5028,7 +5097,7 @@
|
|
|
5028
5097
|
});
|
|
5029
5098
|
}
|
|
5030
5099
|
this._onDragStart.fire(event);
|
|
5031
|
-
}), dragHandler, addDisposableListener(this._element, 'pointerdown', (event) => {
|
|
5100
|
+
}), this.dragHandler, addDisposableListener(this._element, 'pointerdown', (event) => {
|
|
5032
5101
|
this._onPointDown.fire(event);
|
|
5033
5102
|
}), this.dropTarget.onDrop((event) => {
|
|
5034
5103
|
this._onDropped.fire(event);
|
|
@@ -5047,6 +5116,7 @@
|
|
|
5047
5116
|
}
|
|
5048
5117
|
updateDragAndDropState() {
|
|
5049
5118
|
this._element.draggable = !this.accessor.options.disableDnd;
|
|
5119
|
+
this.dragHandler.setDisabled(!!this.accessor.options.disableDnd);
|
|
5050
5120
|
}
|
|
5051
5121
|
dispose() {
|
|
5052
5122
|
super.dispose();
|
|
@@ -5088,8 +5158,8 @@
|
|
|
5088
5158
|
}
|
|
5089
5159
|
|
|
5090
5160
|
class GroupDragHandler extends DragHandler {
|
|
5091
|
-
constructor(element, accessor, group) {
|
|
5092
|
-
super(element);
|
|
5161
|
+
constructor(element, accessor, group, disabled) {
|
|
5162
|
+
super(element, disabled);
|
|
5093
5163
|
this.accessor = accessor;
|
|
5094
5164
|
this.group = group;
|
|
5095
5165
|
this.panelTransfer = LocalSelectionTransfer.getInstance();
|
|
@@ -5158,7 +5228,7 @@
|
|
|
5158
5228
|
this.addDisposables(this._onDrop, this._onDragStart, addDisposableListener(this._element, 'pointerdown', () => {
|
|
5159
5229
|
this.accessor.doSetGroupActive(this.group);
|
|
5160
5230
|
}));
|
|
5161
|
-
|
|
5231
|
+
this.handler = new GroupDragHandler(this._element, accessor, group, !!this.accessor.options.disableDnd);
|
|
5162
5232
|
this.dropTarget = new Droptarget(this._element, {
|
|
5163
5233
|
acceptedTargetZones: ['center'],
|
|
5164
5234
|
canDisplayOverlay: (event, position) => {
|
|
@@ -5171,7 +5241,7 @@
|
|
|
5171
5241
|
getOverrideTarget: () => { var _a; return (_a = group.model.dropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; },
|
|
5172
5242
|
});
|
|
5173
5243
|
this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
|
|
5174
|
-
this.addDisposables(handler, handler.onDragStart((event) => {
|
|
5244
|
+
this.addDisposables(this.handler, this.handler.onDragStart((event) => {
|
|
5175
5245
|
this._onDragStart.fire(event);
|
|
5176
5246
|
}), this.dropTarget.onDrop((event) => {
|
|
5177
5247
|
this._onDrop.fire(event);
|
|
@@ -5180,6 +5250,7 @@
|
|
|
5180
5250
|
updateDragAndDropState() {
|
|
5181
5251
|
this._element.draggable = !this.accessor.options.disableDnd;
|
|
5182
5252
|
toggleClass(this._element, 'dv-draggable', !this.accessor.options.disableDnd);
|
|
5253
|
+
this.handler.setDisabled(!!this.accessor.options.disableDnd);
|
|
5183
5254
|
}
|
|
5184
5255
|
}
|
|
5185
5256
|
|
|
@@ -7673,7 +7744,36 @@
|
|
|
7673
7744
|
|
|
7674
7745
|
const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
|
|
7675
7746
|
const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100, width: 300, height: 300 };
|
|
7747
|
+
const DESERIALIZATION_POPOUT_DELAY_MS = 100;
|
|
7676
7748
|
|
|
7749
|
+
class PositionCache {
|
|
7750
|
+
constructor() {
|
|
7751
|
+
this.cache = new Map();
|
|
7752
|
+
this.currentFrameId = 0;
|
|
7753
|
+
this.rafId = null;
|
|
7754
|
+
}
|
|
7755
|
+
getPosition(element) {
|
|
7756
|
+
const cached = this.cache.get(element);
|
|
7757
|
+
if (cached && cached.frameId === this.currentFrameId) {
|
|
7758
|
+
return cached.rect;
|
|
7759
|
+
}
|
|
7760
|
+
this.scheduleFrameUpdate();
|
|
7761
|
+
const rect = getDomNodePagePosition(element);
|
|
7762
|
+
this.cache.set(element, { rect, frameId: this.currentFrameId });
|
|
7763
|
+
return rect;
|
|
7764
|
+
}
|
|
7765
|
+
invalidate() {
|
|
7766
|
+
this.currentFrameId++;
|
|
7767
|
+
}
|
|
7768
|
+
scheduleFrameUpdate() {
|
|
7769
|
+
if (this.rafId)
|
|
7770
|
+
return;
|
|
7771
|
+
this.rafId = requestAnimationFrame(() => {
|
|
7772
|
+
this.currentFrameId++;
|
|
7773
|
+
this.rafId = null;
|
|
7774
|
+
});
|
|
7775
|
+
}
|
|
7776
|
+
}
|
|
7677
7777
|
function createFocusableElement() {
|
|
7678
7778
|
const element = document.createElement('div');
|
|
7679
7779
|
element.tabIndex = -1;
|
|
@@ -7686,6 +7786,8 @@
|
|
|
7686
7786
|
this.accessor = accessor;
|
|
7687
7787
|
this.map = {};
|
|
7688
7788
|
this._disposed = false;
|
|
7789
|
+
this.positionCache = new PositionCache();
|
|
7790
|
+
this.pendingUpdates = new Set();
|
|
7689
7791
|
this.addDisposables(exports.DockviewDisposable.from(() => {
|
|
7690
7792
|
for (const value of Object.values(this.map)) {
|
|
7691
7793
|
value.disposable.dispose();
|
|
@@ -7694,6 +7796,19 @@
|
|
|
7694
7796
|
this._disposed = true;
|
|
7695
7797
|
}));
|
|
7696
7798
|
}
|
|
7799
|
+
updateAllPositions() {
|
|
7800
|
+
if (this._disposed) {
|
|
7801
|
+
return;
|
|
7802
|
+
}
|
|
7803
|
+
// Invalidate position cache to force recalculation
|
|
7804
|
+
this.positionCache.invalidate();
|
|
7805
|
+
// Call resize function directly for all visible panels
|
|
7806
|
+
for (const entry of Object.values(this.map)) {
|
|
7807
|
+
if (entry.panel.api.isVisible && entry.resize) {
|
|
7808
|
+
entry.resize();
|
|
7809
|
+
}
|
|
7810
|
+
}
|
|
7811
|
+
}
|
|
7697
7812
|
detatch(panel) {
|
|
7698
7813
|
if (this.map[panel.api.id]) {
|
|
7699
7814
|
const { disposable, destroy } = this.map[panel.api.id];
|
|
@@ -7724,17 +7839,33 @@
|
|
|
7724
7839
|
this.element.appendChild(focusContainer);
|
|
7725
7840
|
}
|
|
7726
7841
|
const resize = () => {
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7842
|
+
const panelId = panel.api.id;
|
|
7843
|
+
if (this.pendingUpdates.has(panelId)) {
|
|
7844
|
+
return; // Update already scheduled
|
|
7845
|
+
}
|
|
7846
|
+
this.pendingUpdates.add(panelId);
|
|
7847
|
+
requestAnimationFrame(() => {
|
|
7848
|
+
this.pendingUpdates.delete(panelId);
|
|
7849
|
+
if (this.isDisposed || !this.map[panelId]) {
|
|
7850
|
+
return;
|
|
7851
|
+
}
|
|
7852
|
+
const box = this.positionCache.getPosition(referenceContainer.element);
|
|
7853
|
+
const box2 = this.positionCache.getPosition(this.element);
|
|
7854
|
+
// Use traditional positioning for overlay containers
|
|
7855
|
+
const left = box.left - box2.left;
|
|
7856
|
+
const top = box.top - box2.top;
|
|
7857
|
+
const width = box.width;
|
|
7858
|
+
const height = box.height;
|
|
7859
|
+
focusContainer.style.left = `${left}px`;
|
|
7860
|
+
focusContainer.style.top = `${top}px`;
|
|
7861
|
+
focusContainer.style.width = `${width}px`;
|
|
7862
|
+
focusContainer.style.height = `${height}px`;
|
|
7863
|
+
toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location.type === 'floating');
|
|
7864
|
+
});
|
|
7735
7865
|
};
|
|
7736
7866
|
const visibilityChanged = () => {
|
|
7737
7867
|
if (panel.api.isVisible) {
|
|
7868
|
+
this.positionCache.invalidate();
|
|
7738
7869
|
resize();
|
|
7739
7870
|
}
|
|
7740
7871
|
focusContainer.style.display = panel.api.isVisible ? '' : 'none';
|
|
@@ -7829,6 +7960,8 @@
|
|
|
7829
7960
|
this.map[panel.api.id].disposable.dispose();
|
|
7830
7961
|
// and reset the disposable to the active reference-container
|
|
7831
7962
|
this.map[panel.api.id].disposable = disposable;
|
|
7963
|
+
// store the resize function for direct access
|
|
7964
|
+
this.map[panel.api.id].resize = resize;
|
|
7832
7965
|
return focusContainer;
|
|
7833
7966
|
}
|
|
7834
7967
|
}
|
|
@@ -8198,6 +8331,13 @@
|
|
|
8198
8331
|
get floatingGroups() {
|
|
8199
8332
|
return this._floatingGroups;
|
|
8200
8333
|
}
|
|
8334
|
+
/**
|
|
8335
|
+
* Promise that resolves when all popout groups from the last fromJSON call are restored.
|
|
8336
|
+
* Useful for tests that need to wait for delayed popout creation.
|
|
8337
|
+
*/
|
|
8338
|
+
get popoutRestorationPromise() {
|
|
8339
|
+
return this._popoutRestorationPromise;
|
|
8340
|
+
}
|
|
8201
8341
|
constructor(container, options) {
|
|
8202
8342
|
var _a, _b, _c;
|
|
8203
8343
|
super(container, {
|
|
@@ -8246,6 +8386,7 @@
|
|
|
8246
8386
|
this.onDidMaximizedGroupChange = this._onDidMaximizedGroupChange.event;
|
|
8247
8387
|
this._floatingGroups = [];
|
|
8248
8388
|
this._popoutGroups = [];
|
|
8389
|
+
this._popoutRestorationPromise = Promise.resolve();
|
|
8249
8390
|
this._onDidRemoveGroup = new Emitter();
|
|
8250
8391
|
this.onDidRemoveGroup = this._onDidRemoveGroup.event;
|
|
8251
8392
|
this._onDidAddGroup = new Emitter();
|
|
@@ -8795,6 +8936,7 @@
|
|
|
8795
8936
|
this.updateWatermark();
|
|
8796
8937
|
}
|
|
8797
8938
|
orthogonalize(position, options) {
|
|
8939
|
+
this.gridview.normalize();
|
|
8798
8940
|
switch (position) {
|
|
8799
8941
|
case 'top':
|
|
8800
8942
|
case 'bottom':
|
|
@@ -9038,18 +9180,30 @@
|
|
|
9038
9180
|
});
|
|
9039
9181
|
}
|
|
9040
9182
|
const serializedPopoutGroups = (_b = data.popoutGroups) !== null && _b !== void 0 ? _b : [];
|
|
9041
|
-
|
|
9183
|
+
// Create a promise that resolves when all popout groups are created
|
|
9184
|
+
const popoutPromises = [];
|
|
9185
|
+
// Queue popup group creation with delays to avoid browser blocking
|
|
9186
|
+
serializedPopoutGroups.forEach((serializedPopoutGroup, index) => {
|
|
9042
9187
|
const { data, position, gridReferenceGroup, url } = serializedPopoutGroup;
|
|
9043
9188
|
const group = createGroupFromSerializedState(data);
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9189
|
+
// Add a small delay for each popup after the first to avoid browser popup blocking
|
|
9190
|
+
const popoutPromise = new Promise((resolve) => {
|
|
9191
|
+
setTimeout(() => {
|
|
9192
|
+
this.addPopoutGroup(group, {
|
|
9193
|
+
position: position !== null && position !== void 0 ? position : undefined,
|
|
9194
|
+
overridePopoutGroup: gridReferenceGroup ? group : undefined,
|
|
9195
|
+
referenceGroup: gridReferenceGroup
|
|
9196
|
+
? this.getPanel(gridReferenceGroup)
|
|
9197
|
+
: undefined,
|
|
9198
|
+
popoutUrl: url,
|
|
9199
|
+
});
|
|
9200
|
+
resolve();
|
|
9201
|
+
}, index * DESERIALIZATION_POPOUT_DELAY_MS); // 100ms delay between each popup
|
|
9051
9202
|
});
|
|
9052
|
-
|
|
9203
|
+
popoutPromises.push(popoutPromise);
|
|
9204
|
+
});
|
|
9205
|
+
// Store the promise for tests to wait on
|
|
9206
|
+
this._popoutRestorationPromise = Promise.all(popoutPromises).then(() => void 0);
|
|
9053
9207
|
for (const floatingGroup of this._floatingGroups) {
|
|
9054
9208
|
floatingGroup.overlay.setBounds();
|
|
9055
9209
|
}
|
|
@@ -9096,6 +9250,10 @@
|
|
|
9096
9250
|
throw err;
|
|
9097
9251
|
}
|
|
9098
9252
|
this.updateWatermark();
|
|
9253
|
+
// Force position updates for always visible panels after DOM layout is complete
|
|
9254
|
+
requestAnimationFrame(() => {
|
|
9255
|
+
this.overlayRenderContainer.updateAllPositions();
|
|
9256
|
+
});
|
|
9099
9257
|
this._onDidLayoutFromJSON.fire();
|
|
9100
9258
|
}
|
|
9101
9259
|
clear() {
|
|
@@ -9483,11 +9641,13 @@
|
|
|
9483
9641
|
// remove the group and do not set a new group as active
|
|
9484
9642
|
this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
9485
9643
|
}
|
|
9644
|
+
// Check if destination group is empty - if so, force render the component
|
|
9645
|
+
const isDestinationGroupEmpty = destinationGroup.model.size === 0;
|
|
9486
9646
|
this.movingLock(() => {
|
|
9487
9647
|
var _a;
|
|
9488
9648
|
return destinationGroup.model.openPanel(removedPanel, {
|
|
9489
9649
|
index: destinationIndex,
|
|
9490
|
-
skipSetActive: (_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false,
|
|
9650
|
+
skipSetActive: ((_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false) && !isDestinationGroupEmpty,
|
|
9491
9651
|
skipSetGroupActive: true,
|
|
9492
9652
|
});
|
|
9493
9653
|
});
|
|
@@ -9596,7 +9756,6 @@
|
|
|
9596
9756
|
const target = options.to.position;
|
|
9597
9757
|
if (target === 'center') {
|
|
9598
9758
|
const activePanel = from.activePanel;
|
|
9599
|
-
const targetActivePanel = to.activePanel;
|
|
9600
9759
|
const panels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, {
|
|
9601
9760
|
skipSetActive: true,
|
|
9602
9761
|
})));
|
|
@@ -9606,22 +9765,21 @@
|
|
|
9606
9765
|
this.movingLock(() => {
|
|
9607
9766
|
for (const panel of panels) {
|
|
9608
9767
|
to.model.openPanel(panel, {
|
|
9609
|
-
skipSetActive:
|
|
9768
|
+
skipSetActive: panel !== activePanel,
|
|
9610
9769
|
skipSetGroupActive: true,
|
|
9611
9770
|
});
|
|
9612
9771
|
}
|
|
9613
9772
|
});
|
|
9614
|
-
|
|
9615
|
-
|
|
9616
|
-
|
|
9617
|
-
|
|
9618
|
-
|
|
9773
|
+
// Ensure group becomes active after move
|
|
9774
|
+
if (options.skipSetActive !== true) {
|
|
9775
|
+
// For center moves (merges), we need to ensure the target group is active
|
|
9776
|
+
// unless explicitly told not to (skipSetActive: true)
|
|
9777
|
+
this.doSetGroupAndPanelActive(to);
|
|
9619
9778
|
}
|
|
9620
|
-
else if (
|
|
9621
|
-
//
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
});
|
|
9779
|
+
else if (!this.activePanel) {
|
|
9780
|
+
// Even with skipSetActive: true, ensure there's an active panel if none exists
|
|
9781
|
+
// This maintains basic functionality while respecting skipSetActive
|
|
9782
|
+
this.doSetGroupAndPanelActive(to);
|
|
9625
9783
|
}
|
|
9626
9784
|
}
|
|
9627
9785
|
else {
|
|
@@ -9651,20 +9809,26 @@
|
|
|
9651
9809
|
if (selectedPopoutGroup.referenceGroup) {
|
|
9652
9810
|
const referenceGroup = this.getPanel(selectedPopoutGroup.referenceGroup);
|
|
9653
9811
|
if (referenceGroup && !referenceGroup.api.isVisible) {
|
|
9654
|
-
this.doRemoveGroup(referenceGroup, {
|
|
9812
|
+
this.doRemoveGroup(referenceGroup, {
|
|
9813
|
+
skipActive: true,
|
|
9814
|
+
});
|
|
9655
9815
|
}
|
|
9656
9816
|
}
|
|
9657
9817
|
// Manually dispose the window without triggering restoration
|
|
9658
9818
|
selectedPopoutGroup.window.dispose();
|
|
9659
9819
|
// Update group's location and containers for target
|
|
9660
9820
|
if (to.api.location.type === 'grid') {
|
|
9661
|
-
from.model.renderContainer =
|
|
9662
|
-
|
|
9821
|
+
from.model.renderContainer =
|
|
9822
|
+
this.overlayRenderContainer;
|
|
9823
|
+
from.model.dropTargetContainer =
|
|
9824
|
+
this.rootDropTargetContainer;
|
|
9663
9825
|
from.model.location = { type: 'grid' };
|
|
9664
9826
|
}
|
|
9665
9827
|
else if (to.api.location.type === 'floating') {
|
|
9666
|
-
from.model.renderContainer =
|
|
9667
|
-
|
|
9828
|
+
from.model.renderContainer =
|
|
9829
|
+
this.overlayRenderContainer;
|
|
9830
|
+
from.model.dropTargetContainer =
|
|
9831
|
+
this.rootDropTargetContainer;
|
|
9668
9832
|
from.model.location = { type: 'floating' };
|
|
9669
9833
|
}
|
|
9670
9834
|
break;
|
|
@@ -9732,8 +9896,12 @@
|
|
|
9732
9896
|
from.panels.forEach((panel) => {
|
|
9733
9897
|
this._onDidMovePanel.fire({ panel, from });
|
|
9734
9898
|
});
|
|
9735
|
-
|
|
9736
|
-
|
|
9899
|
+
// Ensure group becomes active after move
|
|
9900
|
+
if (options.skipSetActive === false) {
|
|
9901
|
+
// Only activate when explicitly requested (skipSetActive: false)
|
|
9902
|
+
// Use 'to' group for non-center moves since 'from' may have been destroyed
|
|
9903
|
+
const targetGroup = to !== null && to !== void 0 ? to : from;
|
|
9904
|
+
this.doSetGroupAndPanelActive(targetGroup);
|
|
9737
9905
|
}
|
|
9738
9906
|
}
|
|
9739
9907
|
doSetGroupActive(group) {
|