dockview-core 6.0.5 → 6.0.7
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/cjs/dockview/components/titlebar/tabs.js +29 -4
- package/dist/cjs/dockview/dockviewComponent.js +126 -20
- package/dist/cjs/dockview/dockviewGroupPanelModel.js +5 -3
- package/dist/dockview-core.js +111 -19
- package/dist/dockview-core.min.js +2 -2
- package/dist/dockview-core.min.js.map +1 -1
- package/dist/dockview-core.min.noStyle.js +2 -2
- package/dist/dockview-core.min.noStyle.js.map +1 -1
- package/dist/dockview-core.noStyle.js +111 -19
- package/dist/esm/dockview/components/titlebar/tabs.js +29 -4
- package/dist/esm/dockview/dockviewComponent.js +76 -11
- package/dist/esm/dockview/dockviewGroupPanelModel.js +5 -3
- package/dist/package/main.cjs.js +111 -19
- package/dist/package/main.cjs.min.js +2 -2
- package/dist/package/main.esm.min.mjs +2 -2
- package/dist/package/main.esm.mjs +111 -19
- package/package.json +1 -1
|
@@ -725,10 +725,12 @@ var Tabs = /** @class */ (function (_super) {
|
|
|
725
725
|
var index = this.indexOf(id);
|
|
726
726
|
var tabToRemove = this._tabs.splice(index, 1)[0];
|
|
727
727
|
this._tabMap.delete(id);
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
728
|
+
if (tabToRemove) {
|
|
729
|
+
var value = tabToRemove.value, disposable = tabToRemove.disposable;
|
|
730
|
+
disposable.dispose();
|
|
731
|
+
value.dispose();
|
|
732
|
+
value.element.remove();
|
|
733
|
+
}
|
|
732
734
|
// If a non-source tab was removed during active drag, refresh positions
|
|
733
735
|
if (this._animState) {
|
|
734
736
|
this._animState.tabPositions = this.snapshotTabPositions();
|
|
@@ -896,8 +898,23 @@ var Tabs = /** @class */ (function (_super) {
|
|
|
896
898
|
new dataTransfer_1.PanelTransfer(this.accessor.id, this.group.id, null, tabGroup.id),
|
|
897
899
|
], dataTransfer_1.PanelTransfer.prototype);
|
|
898
900
|
var iframes = (0, dom_1.disableIframePointEvents)();
|
|
901
|
+
// The dragend listener on `_tabsList` is unreachable for chip
|
|
902
|
+
// drags because cross-group drops detach the chip from the DOM
|
|
903
|
+
// before dragend fires (the source tab group becomes empty, so
|
|
904
|
+
// `_positionChipForGroup` removes the chip element). Without
|
|
905
|
+
// bubbling, the tabsList listener never runs and `_animState`,
|
|
906
|
+
// `_chipDragCleanup`, and the dragging CSS classes leak. Listen
|
|
907
|
+
// directly on the chip element so cleanup happens regardless of
|
|
908
|
+
// whether it's still attached. (Issue #1254.)
|
|
909
|
+
var chipElement = chip.element;
|
|
910
|
+
var onChipDragEnd = function () {
|
|
911
|
+
chipElement.removeEventListener('dragend', onChipDragEnd);
|
|
912
|
+
_this.resetDragAnimation();
|
|
913
|
+
};
|
|
914
|
+
chipElement.addEventListener('dragend', onChipDragEnd);
|
|
899
915
|
this._chipDragCleanup = {
|
|
900
916
|
dispose: function () {
|
|
917
|
+
chipElement.removeEventListener('dragend', onChipDragEnd);
|
|
901
918
|
panelTransfer.clearData(dataTransfer_1.PanelTransfer.prototype);
|
|
902
919
|
iframes.release();
|
|
903
920
|
},
|
|
@@ -1605,6 +1622,14 @@ var Tabs = /** @class */ (function (_super) {
|
|
|
1605
1622
|
// handles panel transfer and tab group recreation.
|
|
1606
1623
|
// Use the REAL tab group ID from transfer data, not the
|
|
1607
1624
|
// potentially stale one from _animState.
|
|
1625
|
+
//
|
|
1626
|
+
// Clear any inline gap margin / shifting class applied to
|
|
1627
|
+
// destination tabs during dragover. Cross-group moves don't
|
|
1628
|
+
// run the FLIP path, and `moveGroupOrPanel` only inserts new
|
|
1629
|
+
// panels — it doesn't recreate existing destination tabs, so
|
|
1630
|
+
// their inline `margin-left` would otherwise persist as a
|
|
1631
|
+
// visible gap (issue #1243).
|
|
1632
|
+
this.resetTabTransforms();
|
|
1608
1633
|
this.accessor.moveGroupOrPanel({
|
|
1609
1634
|
from: {
|
|
1610
1635
|
groupId: data.groupId,
|
|
@@ -1125,7 +1125,7 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
1125
1125
|
// Collapse when the group becomes empty
|
|
1126
1126
|
var autoCollapseDisposable = group.model.onDidRemovePanel(function () {
|
|
1127
1127
|
if (group.model.isEmpty) {
|
|
1128
|
-
_this.
|
|
1128
|
+
_this.setEdgeGroupCollapsed(group, true);
|
|
1129
1129
|
}
|
|
1130
1130
|
});
|
|
1131
1131
|
this._edgeGroupDisposables.set(position, autoCollapseDisposable);
|
|
@@ -1183,6 +1183,13 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
1183
1183
|
for (var _b = __values(this._edgeGroups), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1184
1184
|
var _d = __read(_c.value, 2), position = _d[0], edgeGroup = _d[1];
|
|
1185
1185
|
if (edgeGroup === group) {
|
|
1186
|
+
if (this._shellManager.isEdgeGroupCollapsed(position) ===
|
|
1187
|
+
collapsed) {
|
|
1188
|
+
// Skip the splitview resize on a no-op: with non-zero
|
|
1189
|
+
// theme gap, redundant resizeView calls accumulate
|
|
1190
|
+
// rounding drift that gradually shrinks the group.
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1186
1193
|
this._shellManager.setEdgeGroupCollapsed(position, collapsed);
|
|
1187
1194
|
edgeGroup.api._onDidCollapsedChange.fire({
|
|
1188
1195
|
isCollapsed: collapsed,
|
|
@@ -2360,7 +2367,14 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2360
2367
|
var label = tabGroup.label;
|
|
2361
2368
|
var color = tabGroup.color;
|
|
2362
2369
|
var collapsed = tabGroup.collapsed;
|
|
2370
|
+
var componentParams = tabGroup.componentParams;
|
|
2363
2371
|
var panelIds = __spreadArray([], __read(tabGroup.panelIds), false);
|
|
2372
|
+
// Capture the destination's grid location BEFORE potentially
|
|
2373
|
+
// removing the source group, in case source === destination and
|
|
2374
|
+
// the source becomes empty after panel removal.
|
|
2375
|
+
var referenceLocation = destinationTarget && destinationTarget !== 'center'
|
|
2376
|
+
? (0, gridview_1.getGridLocation)(destinationGroup.element)
|
|
2377
|
+
: undefined;
|
|
2364
2378
|
// Remove panels from the source group
|
|
2365
2379
|
var removedPanels = this.movingLock(function () {
|
|
2366
2380
|
return panelIds
|
|
@@ -2375,11 +2389,6 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2375
2389
|
if (removedPanels.length === 0) {
|
|
2376
2390
|
return;
|
|
2377
2391
|
}
|
|
2378
|
-
if (!options.keepEmptyGroups &&
|
|
2379
|
-
sourceGroup.model.size === 0 &&
|
|
2380
|
-
sourceGroup !== destinationGroup) {
|
|
2381
|
-
this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
2382
|
-
}
|
|
2383
2392
|
var addPanelsToGroup = function (targetGroup) {
|
|
2384
2393
|
var e_28, _a, e_29, _b;
|
|
2385
2394
|
_this.movingLock(function () {
|
|
@@ -2407,6 +2416,7 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2407
2416
|
label: label,
|
|
2408
2417
|
color: color,
|
|
2409
2418
|
collapsed: collapsed,
|
|
2419
|
+
componentParams: componentParams,
|
|
2410
2420
|
});
|
|
2411
2421
|
try {
|
|
2412
2422
|
for (var removedPanels_1 = __values(removedPanels), removedPanels_1_1 = removedPanels_1.next(); !removedPanels_1_1.done; removedPanels_1_1 = removedPanels_1.next()) {
|
|
@@ -2441,17 +2451,30 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2441
2451
|
finally { if (e_29) throw e_29.error; }
|
|
2442
2452
|
}
|
|
2443
2453
|
};
|
|
2444
|
-
|
|
2445
|
-
|
|
2454
|
+
var targetGroup;
|
|
2455
|
+
if (!destinationTarget ||
|
|
2456
|
+
destinationTarget === 'center' ||
|
|
2457
|
+
!referenceLocation) {
|
|
2458
|
+
targetGroup = destinationGroup;
|
|
2446
2459
|
}
|
|
2447
2460
|
else {
|
|
2448
|
-
var referenceLocation = (0, gridview_1.getGridLocation)(destinationGroup.element);
|
|
2449
2461
|
var dropLocation = (0, gridview_1.getRelativeLocation)(this.gridview.orientation, referenceLocation, destinationTarget);
|
|
2450
|
-
|
|
2451
|
-
addPanelsToGroup(newGroup);
|
|
2462
|
+
targetGroup = this.createGroupAtLocation(dropLocation);
|
|
2452
2463
|
}
|
|
2464
|
+
// Remove the source group if it became empty. We compare against
|
|
2465
|
+
// the actual targetGroup (which is a freshly-created group for
|
|
2466
|
+
// edge drops) rather than the originally-passed destinationGroup,
|
|
2467
|
+
// so a tab-group drag onto its own group's edge still cleans up
|
|
2468
|
+
// the now-empty source.
|
|
2469
|
+
if (!options.keepEmptyGroups &&
|
|
2470
|
+
sourceGroup.model.size === 0 &&
|
|
2471
|
+
sourceGroup !== targetGroup) {
|
|
2472
|
+
this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
2473
|
+
}
|
|
2474
|
+
addPanelsToGroup(targetGroup);
|
|
2453
2475
|
};
|
|
2454
2476
|
DockviewComponent.prototype.moveGroup = function (options) {
|
|
2477
|
+
var e_31, _a, e_32, _b, e_33, _c, e_34, _d;
|
|
2455
2478
|
var _this = this;
|
|
2456
2479
|
var from = options.from.group;
|
|
2457
2480
|
var to = options.to.group;
|
|
@@ -2462,6 +2485,16 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2462
2485
|
var source = from;
|
|
2463
2486
|
if (target === 'center') {
|
|
2464
2487
|
var activePanel_1 = from.activePanel;
|
|
2488
|
+
// Snapshot tab group metadata before removing panels so we
|
|
2489
|
+
// can recreate the tab groups in the destination after the
|
|
2490
|
+
// panels are merged in.
|
|
2491
|
+
var tabGroupSnapshots = from.model.getTabGroups().map(function (tg) { return ({
|
|
2492
|
+
label: tg.label,
|
|
2493
|
+
color: tg.color,
|
|
2494
|
+
collapsed: tg.collapsed,
|
|
2495
|
+
componentParams: tg.componentParams,
|
|
2496
|
+
panelIds: __spreadArray([], __read(tg.panelIds), false),
|
|
2497
|
+
}); });
|
|
2465
2498
|
var panels_3 = this.movingLock(function () {
|
|
2466
2499
|
return __spreadArray([], __read(from.panels), false).map(function (p) {
|
|
2467
2500
|
return from.model.removePanel(p.id, {
|
|
@@ -2473,7 +2506,7 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2473
2506
|
this.doRemoveGroup(from, { skipActive: true });
|
|
2474
2507
|
}
|
|
2475
2508
|
this.movingLock(function () {
|
|
2476
|
-
var
|
|
2509
|
+
var e_35, _a;
|
|
2477
2510
|
try {
|
|
2478
2511
|
for (var panels_4 = __values(panels_3), panels_4_1 = panels_4.next(); !panels_4_1.done; panels_4_1 = panels_4.next()) {
|
|
2479
2512
|
var panel = panels_4_1.value;
|
|
@@ -2483,14 +2516,45 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2483
2516
|
});
|
|
2484
2517
|
}
|
|
2485
2518
|
}
|
|
2486
|
-
catch (
|
|
2519
|
+
catch (e_35_1) { e_35 = { error: e_35_1 }; }
|
|
2487
2520
|
finally {
|
|
2488
2521
|
try {
|
|
2489
2522
|
if (panels_4_1 && !panels_4_1.done && (_a = panels_4.return)) _a.call(panels_4);
|
|
2490
2523
|
}
|
|
2491
|
-
finally { if (
|
|
2524
|
+
finally { if (e_35) throw e_35.error; }
|
|
2492
2525
|
}
|
|
2493
2526
|
});
|
|
2527
|
+
try {
|
|
2528
|
+
for (var tabGroupSnapshots_1 = __values(tabGroupSnapshots), tabGroupSnapshots_1_1 = tabGroupSnapshots_1.next(); !tabGroupSnapshots_1_1.done; tabGroupSnapshots_1_1 = tabGroupSnapshots_1.next()) {
|
|
2529
|
+
var snapshot = tabGroupSnapshots_1_1.value;
|
|
2530
|
+
var newTabGroup = to.model.createTabGroup({
|
|
2531
|
+
label: snapshot.label,
|
|
2532
|
+
color: snapshot.color,
|
|
2533
|
+
collapsed: snapshot.collapsed,
|
|
2534
|
+
componentParams: snapshot.componentParams,
|
|
2535
|
+
});
|
|
2536
|
+
try {
|
|
2537
|
+
for (var _e = (e_32 = void 0, __values(snapshot.panelIds)), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
2538
|
+
var panelId = _f.value;
|
|
2539
|
+
to.model.addPanelToTabGroup(newTabGroup.id, panelId);
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
catch (e_32_1) { e_32 = { error: e_32_1 }; }
|
|
2543
|
+
finally {
|
|
2544
|
+
try {
|
|
2545
|
+
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
|
2546
|
+
}
|
|
2547
|
+
finally { if (e_32) throw e_32.error; }
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
catch (e_31_1) { e_31 = { error: e_31_1 }; }
|
|
2552
|
+
finally {
|
|
2553
|
+
try {
|
|
2554
|
+
if (tabGroupSnapshots_1_1 && !tabGroupSnapshots_1_1.done && (_a = tabGroupSnapshots_1.return)) _a.call(tabGroupSnapshots_1);
|
|
2555
|
+
}
|
|
2556
|
+
finally { if (e_31) throw e_31.error; }
|
|
2557
|
+
}
|
|
2494
2558
|
// Ensure group becomes active after move
|
|
2495
2559
|
if (options.skipSetActive !== true) {
|
|
2496
2560
|
// For center moves (merges), we need to ensure the target group is active
|
|
@@ -2514,6 +2578,17 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2514
2578
|
* positions `source` like any other moved group.
|
|
2515
2579
|
*/
|
|
2516
2580
|
var activePanel_2 = from.activePanel;
|
|
2581
|
+
// Snapshot tab group metadata so the new group inherits
|
|
2582
|
+
// the tab grouping from the edge slot.
|
|
2583
|
+
var tabGroupSnapshots = from.model
|
|
2584
|
+
.getTabGroups()
|
|
2585
|
+
.map(function (tg) { return ({
|
|
2586
|
+
label: tg.label,
|
|
2587
|
+
color: tg.color,
|
|
2588
|
+
collapsed: tg.collapsed,
|
|
2589
|
+
componentParams: tg.componentParams,
|
|
2590
|
+
panelIds: __spreadArray([], __read(tg.panelIds), false),
|
|
2591
|
+
}); });
|
|
2517
2592
|
var movedPanels_1 = this.movingLock(function () {
|
|
2518
2593
|
return __spreadArray([], __read(from.panels), false).map(function (p) {
|
|
2519
2594
|
return from.model.removePanel(p.id, { skipSetActive: true });
|
|
@@ -2521,7 +2596,7 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2521
2596
|
});
|
|
2522
2597
|
source = this.createGroup();
|
|
2523
2598
|
this.movingLock(function () {
|
|
2524
|
-
var
|
|
2599
|
+
var e_36, _a;
|
|
2525
2600
|
try {
|
|
2526
2601
|
for (var movedPanels_2 = __values(movedPanels_1), movedPanels_2_1 = movedPanels_2.next(); !movedPanels_2_1.done; movedPanels_2_1 = movedPanels_2.next()) {
|
|
2527
2602
|
var panel = movedPanels_2_1.value;
|
|
@@ -2531,14 +2606,45 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2531
2606
|
});
|
|
2532
2607
|
}
|
|
2533
2608
|
}
|
|
2534
|
-
catch (
|
|
2609
|
+
catch (e_36_1) { e_36 = { error: e_36_1 }; }
|
|
2535
2610
|
finally {
|
|
2536
2611
|
try {
|
|
2537
2612
|
if (movedPanels_2_1 && !movedPanels_2_1.done && (_a = movedPanels_2.return)) _a.call(movedPanels_2);
|
|
2538
2613
|
}
|
|
2539
|
-
finally { if (
|
|
2614
|
+
finally { if (e_36) throw e_36.error; }
|
|
2540
2615
|
}
|
|
2541
2616
|
});
|
|
2617
|
+
try {
|
|
2618
|
+
for (var tabGroupSnapshots_2 = __values(tabGroupSnapshots), tabGroupSnapshots_2_1 = tabGroupSnapshots_2.next(); !tabGroupSnapshots_2_1.done; tabGroupSnapshots_2_1 = tabGroupSnapshots_2.next()) {
|
|
2619
|
+
var snapshot = tabGroupSnapshots_2_1.value;
|
|
2620
|
+
var newTabGroup = source.model.createTabGroup({
|
|
2621
|
+
label: snapshot.label,
|
|
2622
|
+
color: snapshot.color,
|
|
2623
|
+
collapsed: snapshot.collapsed,
|
|
2624
|
+
componentParams: snapshot.componentParams,
|
|
2625
|
+
});
|
|
2626
|
+
try {
|
|
2627
|
+
for (var _g = (e_34 = void 0, __values(snapshot.panelIds)), _h = _g.next(); !_h.done; _h = _g.next()) {
|
|
2628
|
+
var panelId = _h.value;
|
|
2629
|
+
source.model.addPanelToTabGroup(newTabGroup.id, panelId);
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
catch (e_34_1) { e_34 = { error: e_34_1 }; }
|
|
2633
|
+
finally {
|
|
2634
|
+
try {
|
|
2635
|
+
if (_h && !_h.done && (_d = _g.return)) _d.call(_g);
|
|
2636
|
+
}
|
|
2637
|
+
finally { if (e_34) throw e_34.error; }
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
catch (e_33_1) { e_33 = { error: e_33_1 }; }
|
|
2642
|
+
finally {
|
|
2643
|
+
try {
|
|
2644
|
+
if (tabGroupSnapshots_2_1 && !tabGroupSnapshots_2_1.done && (_c = tabGroupSnapshots_2.return)) _c.call(tabGroupSnapshots_2);
|
|
2645
|
+
}
|
|
2646
|
+
finally { if (e_33) throw e_33.error; }
|
|
2647
|
+
}
|
|
2542
2648
|
}
|
|
2543
2649
|
else {
|
|
2544
2650
|
switch (from.api.location.type) {
|
|
@@ -2841,7 +2947,7 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2841
2947
|
}
|
|
2842
2948
|
};
|
|
2843
2949
|
DockviewComponent.prototype.updateTheme = function () {
|
|
2844
|
-
var
|
|
2950
|
+
var e_37, _a;
|
|
2845
2951
|
var _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
2846
2952
|
var theme = (_b = this._options.theme) !== null && _b !== void 0 ? _b : theme_1.themeAbyss;
|
|
2847
2953
|
// Apply the theme class only to the shell so edge groups and the
|
|
@@ -2882,12 +2988,12 @@ var DockviewComponent = /** @class */ (function (_super) {
|
|
|
2882
2988
|
group.model.updateTabGroups();
|
|
2883
2989
|
}
|
|
2884
2990
|
}
|
|
2885
|
-
catch (
|
|
2991
|
+
catch (e_37_1) { e_37 = { error: e_37_1 }; }
|
|
2886
2992
|
finally {
|
|
2887
2993
|
try {
|
|
2888
2994
|
if (_m && !_m.done && (_a = _l.return)) _a.call(_l);
|
|
2889
2995
|
}
|
|
2890
|
-
finally { if (
|
|
2996
|
+
finally { if (e_37) throw e_37.error; }
|
|
2891
2997
|
}
|
|
2892
2998
|
};
|
|
2893
2999
|
return DockviewComponent;
|
|
@@ -1335,15 +1335,17 @@ var DockviewGroupPanelModel = /** @class */ (function (_super) {
|
|
|
1335
1335
|
if (position === 'center') {
|
|
1336
1336
|
return;
|
|
1337
1337
|
}
|
|
1338
|
-
if (data.panelId === null) {
|
|
1339
|
-
//
|
|
1338
|
+
if (data.panelId === null && !data.tabGroupId) {
|
|
1339
|
+
// Full-group drops on self are a no-op.
|
|
1340
|
+
// Tab-group drags are partial moves: an edge drop
|
|
1341
|
+
// splits the layout and creates a new group.
|
|
1340
1342
|
return;
|
|
1341
1343
|
}
|
|
1342
1344
|
}
|
|
1343
1345
|
}
|
|
1344
1346
|
if (type === 'header') {
|
|
1345
1347
|
if (data.groupId === this.id) {
|
|
1346
|
-
if (data.panelId === null) {
|
|
1348
|
+
if (data.panelId === null && !data.tabGroupId) {
|
|
1347
1349
|
return;
|
|
1348
1350
|
}
|
|
1349
1351
|
}
|
package/dist/dockview-core.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dockview-core
|
|
3
|
-
* @version 6.0.
|
|
3
|
+
* @version 6.0.7
|
|
4
4
|
* @link https://github.com/mathuo/dockview
|
|
5
5
|
* @license MIT
|
|
6
6
|
*/
|
|
@@ -7235,10 +7235,12 @@
|
|
|
7235
7235
|
const index = this.indexOf(id);
|
|
7236
7236
|
const tabToRemove = this._tabs.splice(index, 1)[0];
|
|
7237
7237
|
this._tabMap.delete(id);
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7238
|
+
if (tabToRemove) {
|
|
7239
|
+
const { value, disposable } = tabToRemove;
|
|
7240
|
+
disposable.dispose();
|
|
7241
|
+
value.dispose();
|
|
7242
|
+
value.element.remove();
|
|
7243
|
+
}
|
|
7242
7244
|
// If a non-source tab was removed during active drag, refresh positions
|
|
7243
7245
|
if (this._animState) {
|
|
7244
7246
|
this._animState.tabPositions = this.snapshotTabPositions();
|
|
@@ -7360,8 +7362,23 @@
|
|
|
7360
7362
|
new PanelTransfer(this.accessor.id, this.group.id, null, tabGroup.id),
|
|
7361
7363
|
], PanelTransfer.prototype);
|
|
7362
7364
|
const iframes = disableIframePointEvents();
|
|
7365
|
+
// The dragend listener on `_tabsList` is unreachable for chip
|
|
7366
|
+
// drags because cross-group drops detach the chip from the DOM
|
|
7367
|
+
// before dragend fires (the source tab group becomes empty, so
|
|
7368
|
+
// `_positionChipForGroup` removes the chip element). Without
|
|
7369
|
+
// bubbling, the tabsList listener never runs and `_animState`,
|
|
7370
|
+
// `_chipDragCleanup`, and the dragging CSS classes leak. Listen
|
|
7371
|
+
// directly on the chip element so cleanup happens regardless of
|
|
7372
|
+
// whether it's still attached. (Issue #1254.)
|
|
7373
|
+
const chipElement = chip.element;
|
|
7374
|
+
const onChipDragEnd = () => {
|
|
7375
|
+
chipElement.removeEventListener('dragend', onChipDragEnd);
|
|
7376
|
+
this.resetDragAnimation();
|
|
7377
|
+
};
|
|
7378
|
+
chipElement.addEventListener('dragend', onChipDragEnd);
|
|
7363
7379
|
this._chipDragCleanup = {
|
|
7364
7380
|
dispose: () => {
|
|
7381
|
+
chipElement.removeEventListener('dragend', onChipDragEnd);
|
|
7365
7382
|
panelTransfer.clearData(PanelTransfer.prototype);
|
|
7366
7383
|
iframes.release();
|
|
7367
7384
|
},
|
|
@@ -7910,6 +7927,14 @@
|
|
|
7910
7927
|
// handles panel transfer and tab group recreation.
|
|
7911
7928
|
// Use the REAL tab group ID from transfer data, not the
|
|
7912
7929
|
// potentially stale one from _animState.
|
|
7930
|
+
//
|
|
7931
|
+
// Clear any inline gap margin / shifting class applied to
|
|
7932
|
+
// destination tabs during dragover. Cross-group moves don't
|
|
7933
|
+
// run the FLIP path, and `moveGroupOrPanel` only inserts new
|
|
7934
|
+
// panels — it doesn't recreate existing destination tabs, so
|
|
7935
|
+
// their inline `margin-left` would otherwise persist as a
|
|
7936
|
+
// visible gap (issue #1243).
|
|
7937
|
+
this.resetTabTransforms();
|
|
7913
7938
|
this.accessor.moveGroupOrPanel({
|
|
7914
7939
|
from: {
|
|
7915
7940
|
groupId: data.groupId,
|
|
@@ -9690,15 +9715,17 @@
|
|
|
9690
9715
|
if (position === 'center') {
|
|
9691
9716
|
return;
|
|
9692
9717
|
}
|
|
9693
|
-
if (data.panelId === null) {
|
|
9694
|
-
//
|
|
9718
|
+
if (data.panelId === null && !data.tabGroupId) {
|
|
9719
|
+
// Full-group drops on self are a no-op.
|
|
9720
|
+
// Tab-group drags are partial moves: an edge drop
|
|
9721
|
+
// splits the layout and creates a new group.
|
|
9695
9722
|
return;
|
|
9696
9723
|
}
|
|
9697
9724
|
}
|
|
9698
9725
|
}
|
|
9699
9726
|
if (type === 'header') {
|
|
9700
9727
|
if (data.groupId === this.id) {
|
|
9701
|
-
if (data.panelId === null) {
|
|
9728
|
+
if (data.panelId === null && !data.tabGroupId) {
|
|
9702
9729
|
return;
|
|
9703
9730
|
}
|
|
9704
9731
|
}
|
|
@@ -13566,7 +13593,7 @@
|
|
|
13566
13593
|
// Collapse when the group becomes empty
|
|
13567
13594
|
const autoCollapseDisposable = group.model.onDidRemovePanel(() => {
|
|
13568
13595
|
if (group.model.isEmpty) {
|
|
13569
|
-
this.
|
|
13596
|
+
this.setEdgeGroupCollapsed(group, true);
|
|
13570
13597
|
}
|
|
13571
13598
|
});
|
|
13572
13599
|
this._edgeGroupDisposables.set(position, autoCollapseDisposable);
|
|
@@ -13610,6 +13637,13 @@
|
|
|
13610
13637
|
setEdgeGroupCollapsed(group, collapsed) {
|
|
13611
13638
|
for (const [position, edgeGroup] of this._edgeGroups) {
|
|
13612
13639
|
if (edgeGroup === group) {
|
|
13640
|
+
if (this._shellManager.isEdgeGroupCollapsed(position) ===
|
|
13641
|
+
collapsed) {
|
|
13642
|
+
// Skip the splitview resize on a no-op: with non-zero
|
|
13643
|
+
// theme gap, redundant resizeView calls accumulate
|
|
13644
|
+
// rounding drift that gradually shrinks the group.
|
|
13645
|
+
return;
|
|
13646
|
+
}
|
|
13613
13647
|
this._shellManager.setEdgeGroupCollapsed(position, collapsed);
|
|
13614
13648
|
edgeGroup.api._onDidCollapsedChange.fire({
|
|
13615
13649
|
isCollapsed: collapsed,
|
|
@@ -14562,7 +14596,14 @@
|
|
|
14562
14596
|
const label = tabGroup.label;
|
|
14563
14597
|
const color = tabGroup.color;
|
|
14564
14598
|
const collapsed = tabGroup.collapsed;
|
|
14599
|
+
const componentParams = tabGroup.componentParams;
|
|
14565
14600
|
const panelIds = [...tabGroup.panelIds];
|
|
14601
|
+
// Capture the destination's grid location BEFORE potentially
|
|
14602
|
+
// removing the source group, in case source === destination and
|
|
14603
|
+
// the source becomes empty after panel removal.
|
|
14604
|
+
const referenceLocation = destinationTarget && destinationTarget !== 'center'
|
|
14605
|
+
? getGridLocation(destinationGroup.element)
|
|
14606
|
+
: undefined;
|
|
14566
14607
|
// Remove panels from the source group
|
|
14567
14608
|
const removedPanels = this.movingLock(() => panelIds
|
|
14568
14609
|
.map((pid) => sourceGroup.model.removePanel(pid, {
|
|
@@ -14573,11 +14614,6 @@
|
|
|
14573
14614
|
if (removedPanels.length === 0) {
|
|
14574
14615
|
return;
|
|
14575
14616
|
}
|
|
14576
|
-
if (!options.keepEmptyGroups &&
|
|
14577
|
-
sourceGroup.model.size === 0 &&
|
|
14578
|
-
sourceGroup !== destinationGroup) {
|
|
14579
|
-
this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
14580
|
-
}
|
|
14581
14617
|
const addPanelsToGroup = (targetGroup) => {
|
|
14582
14618
|
this.movingLock(() => {
|
|
14583
14619
|
for (const panel of removedPanels) {
|
|
@@ -14593,6 +14629,7 @@
|
|
|
14593
14629
|
label,
|
|
14594
14630
|
color,
|
|
14595
14631
|
collapsed,
|
|
14632
|
+
componentParams,
|
|
14596
14633
|
});
|
|
14597
14634
|
for (const panel of removedPanels) {
|
|
14598
14635
|
targetGroup.model.addPanelToTabGroup(newTabGroup.id, panel.id);
|
|
@@ -14607,15 +14644,27 @@
|
|
|
14607
14644
|
});
|
|
14608
14645
|
}
|
|
14609
14646
|
};
|
|
14610
|
-
|
|
14611
|
-
|
|
14647
|
+
let targetGroup;
|
|
14648
|
+
if (!destinationTarget ||
|
|
14649
|
+
destinationTarget === 'center' ||
|
|
14650
|
+
!referenceLocation) {
|
|
14651
|
+
targetGroup = destinationGroup;
|
|
14612
14652
|
}
|
|
14613
14653
|
else {
|
|
14614
|
-
const referenceLocation = getGridLocation(destinationGroup.element);
|
|
14615
14654
|
const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
|
|
14616
|
-
|
|
14617
|
-
addPanelsToGroup(newGroup);
|
|
14655
|
+
targetGroup = this.createGroupAtLocation(dropLocation);
|
|
14618
14656
|
}
|
|
14657
|
+
// Remove the source group if it became empty. We compare against
|
|
14658
|
+
// the actual targetGroup (which is a freshly-created group for
|
|
14659
|
+
// edge drops) rather than the originally-passed destinationGroup,
|
|
14660
|
+
// so a tab-group drag onto its own group's edge still cleans up
|
|
14661
|
+
// the now-empty source.
|
|
14662
|
+
if (!options.keepEmptyGroups &&
|
|
14663
|
+
sourceGroup.model.size === 0 &&
|
|
14664
|
+
sourceGroup !== targetGroup) {
|
|
14665
|
+
this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
14666
|
+
}
|
|
14667
|
+
addPanelsToGroup(targetGroup);
|
|
14619
14668
|
}
|
|
14620
14669
|
moveGroup(options) {
|
|
14621
14670
|
const from = options.from.group;
|
|
@@ -14627,6 +14676,16 @@
|
|
|
14627
14676
|
let source = from;
|
|
14628
14677
|
if (target === 'center') {
|
|
14629
14678
|
const activePanel = from.activePanel;
|
|
14679
|
+
// Snapshot tab group metadata before removing panels so we
|
|
14680
|
+
// can recreate the tab groups in the destination after the
|
|
14681
|
+
// panels are merged in.
|
|
14682
|
+
const tabGroupSnapshots = from.model.getTabGroups().map((tg) => ({
|
|
14683
|
+
label: tg.label,
|
|
14684
|
+
color: tg.color,
|
|
14685
|
+
collapsed: tg.collapsed,
|
|
14686
|
+
componentParams: tg.componentParams,
|
|
14687
|
+
panelIds: [...tg.panelIds],
|
|
14688
|
+
}));
|
|
14630
14689
|
const panels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, {
|
|
14631
14690
|
skipSetActive: true,
|
|
14632
14691
|
})));
|
|
@@ -14641,6 +14700,17 @@
|
|
|
14641
14700
|
});
|
|
14642
14701
|
}
|
|
14643
14702
|
});
|
|
14703
|
+
for (const snapshot of tabGroupSnapshots) {
|
|
14704
|
+
const newTabGroup = to.model.createTabGroup({
|
|
14705
|
+
label: snapshot.label,
|
|
14706
|
+
color: snapshot.color,
|
|
14707
|
+
collapsed: snapshot.collapsed,
|
|
14708
|
+
componentParams: snapshot.componentParams,
|
|
14709
|
+
});
|
|
14710
|
+
for (const panelId of snapshot.panelIds) {
|
|
14711
|
+
to.model.addPanelToTabGroup(newTabGroup.id, panelId);
|
|
14712
|
+
}
|
|
14713
|
+
}
|
|
14644
14714
|
// Ensure group becomes active after move
|
|
14645
14715
|
if (options.skipSetActive !== true) {
|
|
14646
14716
|
// For center moves (merges), we need to ensure the target group is active
|
|
@@ -14664,6 +14734,17 @@
|
|
|
14664
14734
|
* positions `source` like any other moved group.
|
|
14665
14735
|
*/
|
|
14666
14736
|
const activePanel = from.activePanel;
|
|
14737
|
+
// Snapshot tab group metadata so the new group inherits
|
|
14738
|
+
// the tab grouping from the edge slot.
|
|
14739
|
+
const tabGroupSnapshots = from.model
|
|
14740
|
+
.getTabGroups()
|
|
14741
|
+
.map((tg) => ({
|
|
14742
|
+
label: tg.label,
|
|
14743
|
+
color: tg.color,
|
|
14744
|
+
collapsed: tg.collapsed,
|
|
14745
|
+
componentParams: tg.componentParams,
|
|
14746
|
+
panelIds: [...tg.panelIds],
|
|
14747
|
+
}));
|
|
14667
14748
|
const movedPanels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, { skipSetActive: true })));
|
|
14668
14749
|
source = this.createGroup();
|
|
14669
14750
|
this.movingLock(() => {
|
|
@@ -14674,6 +14755,17 @@
|
|
|
14674
14755
|
});
|
|
14675
14756
|
}
|
|
14676
14757
|
});
|
|
14758
|
+
for (const snapshot of tabGroupSnapshots) {
|
|
14759
|
+
const newTabGroup = source.model.createTabGroup({
|
|
14760
|
+
label: snapshot.label,
|
|
14761
|
+
color: snapshot.color,
|
|
14762
|
+
collapsed: snapshot.collapsed,
|
|
14763
|
+
componentParams: snapshot.componentParams,
|
|
14764
|
+
});
|
|
14765
|
+
for (const panelId of snapshot.panelIds) {
|
|
14766
|
+
source.model.addPanelToTabGroup(newTabGroup.id, panelId);
|
|
14767
|
+
}
|
|
14768
|
+
}
|
|
14677
14769
|
}
|
|
14678
14770
|
else {
|
|
14679
14771
|
switch (from.api.location.type) {
|