dockview 8.1.0 → 8.3.0
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.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dockview
|
|
3
|
-
* @version 8.
|
|
3
|
+
* @version 8.3.0
|
|
4
4
|
* @link https://github.com/dockview/dockview
|
|
5
5
|
* @license MIT
|
|
6
6
|
*/
|
|
@@ -22,7 +22,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
22
22
|
//#region ../dockview-core/dist/package/main.esm.mjs
|
|
23
23
|
/**
|
|
24
24
|
* dockview-core
|
|
25
|
-
* @version 8.
|
|
25
|
+
* @version 8.3.0
|
|
26
26
|
* @link https://github.com/dockview/dockview
|
|
27
27
|
* @license MIT
|
|
28
28
|
*/
|
|
@@ -1048,8 +1048,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1048
1048
|
container.appendChild(view.element);
|
|
1049
1049
|
let viewSize;
|
|
1050
1050
|
if (typeof size === "number") viewSize = size;
|
|
1051
|
-
else if (size.type === "split")
|
|
1052
|
-
|
|
1051
|
+
else if (size.type === "split") {
|
|
1052
|
+
const splitTarget = this.viewItems[size.index];
|
|
1053
|
+
if (splitTarget) {
|
|
1054
|
+
const half = Math.floor(splitTarget.size / 2);
|
|
1055
|
+
viewSize = splitTarget.size - half;
|
|
1056
|
+
splitTarget.size = half;
|
|
1057
|
+
} else viewSize = this.getViewSize(size.index) / 2;
|
|
1058
|
+
} else if (size.type === "invisible") viewSize = { cachedVisibleSize: size.cachedVisibleSize };
|
|
1053
1059
|
else viewSize = view.minimumSize;
|
|
1054
1060
|
const disposable = view.onDidChange((newSize) => this.onDidChange(viewItem, newSize.size));
|
|
1055
1061
|
const viewItem = new ViewItem(container, view, viewSize, { dispose: () => {
|
|
@@ -5689,7 +5695,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
5689
5695
|
};
|
|
5690
5696
|
case "auto":
|
|
5691
5697
|
case void 0:
|
|
5692
|
-
default: return isCoarsePrimaryInput$
|
|
5698
|
+
default: return isCoarsePrimaryInput$2() ? {
|
|
5693
5699
|
html5: false,
|
|
5694
5700
|
pointer: true,
|
|
5695
5701
|
pointerHandlesMouse: true
|
|
@@ -5700,7 +5706,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
5700
5706
|
};
|
|
5701
5707
|
}
|
|
5702
5708
|
}
|
|
5703
|
-
function isCoarsePrimaryInput$
|
|
5709
|
+
function isCoarsePrimaryInput$2() {
|
|
5704
5710
|
if (globalThis.window === void 0 || !globalThis.matchMedia) return false;
|
|
5705
5711
|
const coarse = globalThis.matchMedia("(pointer: coarse)").matches;
|
|
5706
5712
|
const fine = globalThis.matchMedia("(pointer: fine)").matches;
|
|
@@ -7821,11 +7827,28 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
7821
7827
|
if (this._voidContainer && related && (related === this._voidContainer || this._voidContainer.contains(related))) return;
|
|
7822
7828
|
this.resetTabTransforms();
|
|
7823
7829
|
if (this._animState.sourceIndex === -1) {
|
|
7824
|
-
|
|
7825
|
-
(_this$group$model$dro2 = this.group.model.dropTargetContainer) === null || _this$group$model$dro2 === void 0 || (_this$group$model$dro2 = _this$group$model$dro2.model) === null || _this$group$model$dro2 === void 0 || _this$group$model$dro2.clear();
|
|
7830
|
+
this.clearHeaderAnchorOverlay();
|
|
7826
7831
|
this._animState = null;
|
|
7827
7832
|
} else this._animState.currentInsertionIndex = null;
|
|
7828
7833
|
}
|
|
7834
|
+
/**
|
|
7835
|
+
* Clear the anchored overlay only when this header is what rendered it.
|
|
7836
|
+
* The container is shared with the group's content drop target, which
|
|
7837
|
+
* renders into it on the same frame the cursor leaves the strip: the
|
|
7838
|
+
* pointer backend calls `handleDragOver` on the new target before the
|
|
7839
|
+
* global `onDragMove` that reaches us (#1612).
|
|
7840
|
+
*/
|
|
7841
|
+
clearHeaderAnchorOverlay() {
|
|
7842
|
+
var _container$model;
|
|
7843
|
+
const container = this.group.model.dropTargetContainer;
|
|
7844
|
+
const outline = container === null || container === void 0 ? void 0 : container.renderedOutline;
|
|
7845
|
+
if (outline && ![
|
|
7846
|
+
this._tabsList,
|
|
7847
|
+
this._voidContainer,
|
|
7848
|
+
this._extendedDropZone
|
|
7849
|
+
].some((scope) => scope === null || scope === void 0 ? void 0 : scope.contains(outline))) return;
|
|
7850
|
+
container === null || container === void 0 || (_container$model = container.model) === null || _container$model === void 0 || _container$model.clear();
|
|
7851
|
+
}
|
|
7829
7852
|
handleDragOver(event) {
|
|
7830
7853
|
var _this$accessor$option2;
|
|
7831
7854
|
if (!this._animState) return;
|
|
@@ -10366,7 +10389,11 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
10366
10389
|
this.panels.forEach((panel) => {
|
|
10367
10390
|
this.rerender(panel);
|
|
10368
10391
|
});
|
|
10369
|
-
if (this._activePanel)
|
|
10392
|
+
if (this._activePanel) {
|
|
10393
|
+
this.contentContainer.renderPanel(this._activePanel, { asActive: true });
|
|
10394
|
+
const { width, height } = this.contentDimensions();
|
|
10395
|
+
this._activePanel.layout(width, height);
|
|
10396
|
+
}
|
|
10370
10397
|
}
|
|
10371
10398
|
get renderContainer() {
|
|
10372
10399
|
var _this$_overwriteRende;
|
|
@@ -11313,7 +11340,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
11313
11340
|
this._group = value;
|
|
11314
11341
|
this._onDidGroupChange.fire({});
|
|
11315
11342
|
this.setupGroupEventListeners(oldGroup);
|
|
11316
|
-
this.
|
|
11343
|
+
this.fireLocationChange();
|
|
11317
11344
|
}
|
|
11318
11345
|
}
|
|
11319
11346
|
get group() {
|
|
@@ -11389,6 +11416,23 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
11389
11416
|
exitMaximized() {
|
|
11390
11417
|
this.group.api.exitMaximized();
|
|
11391
11418
|
}
|
|
11419
|
+
/**
|
|
11420
|
+
* Report that this panel's location may have moved.
|
|
11421
|
+
*
|
|
11422
|
+
* A relocation touches the location more than once - the panel is
|
|
11423
|
+
* reparented into the destination group, then that group is tagged with
|
|
11424
|
+
* the location it ends up at - so the event is coalesced to the end of the
|
|
11425
|
+
* enclosing layout mutation and reports where the panel actually settled.
|
|
11426
|
+
* Firing each signal as it happened surfaced an intermediate `grid`
|
|
11427
|
+
* location the panel was never in, at a point where it was in neither
|
|
11428
|
+
* group's panel list. Outside a mutation this fires straight away.
|
|
11429
|
+
*/
|
|
11430
|
+
fireLocationChange() {
|
|
11431
|
+
this.accessor.deferLocationChange(this, () => {
|
|
11432
|
+
if (this.isDisposed) return;
|
|
11433
|
+
this._onDidLocationChange.fire({ location: this.location });
|
|
11434
|
+
});
|
|
11435
|
+
}
|
|
11392
11436
|
setupGroupEventListeners(previousGroup) {
|
|
11393
11437
|
var _previousGroup$isActi;
|
|
11394
11438
|
let _trackGroupActive = (_previousGroup$isActi = previousGroup === null || previousGroup === void 0 ? void 0 : previousGroup.isActive) !== null && _previousGroup$isActi !== void 0 ? _previousGroup$isActi : false;
|
|
@@ -11397,9 +11441,9 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
11397
11441
|
const hasBecomeVisible = event.isVisible && !this.isVisible;
|
|
11398
11442
|
const isActivePanel = this.group.model.isPanelActive(this.panel);
|
|
11399
11443
|
if (hasBecomeHidden || hasBecomeVisible && isActivePanel) this._onDidVisibilityChange.fire(event);
|
|
11400
|
-
}), this.group.api.onDidLocationChange((
|
|
11444
|
+
}), this.group.api.onDidLocationChange(() => {
|
|
11401
11445
|
if (this.group !== this.panel.group) return;
|
|
11402
|
-
this.
|
|
11446
|
+
this.fireLocationChange();
|
|
11403
11447
|
}), this.group.api.onDidActiveChange(() => {
|
|
11404
11448
|
if (this.group !== this.panel.group) return;
|
|
11405
11449
|
if (_trackGroupActive !== this.isGroupActive) {
|
|
@@ -12177,7 +12221,6 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
12177
12221
|
"AdvancedOverflow",
|
|
12178
12222
|
"AutoEdgeGroup",
|
|
12179
12223
|
"AutoHideEdgeGroup",
|
|
12180
|
-
"ContextMenu",
|
|
12181
12224
|
"DndCompass",
|
|
12182
12225
|
"KeyboardDocking",
|
|
12183
12226
|
"KeyboardNavigation",
|
|
@@ -12259,8 +12302,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
12259
12302
|
* case: calling `undo()` having never set the option at all.
|
|
12260
12303
|
*
|
|
12261
12304
|
* Interaction handlers are queries in this sense too: a right-click reaching an
|
|
12262
|
-
* absent
|
|
12263
|
-
*
|
|
12305
|
+
* absent module means the app never asked for that feature, so it stays silent
|
|
12306
|
+
* (`?.`) and the browser's own behaviour applies. Options are where intent is
|
|
12264
12307
|
* declared; see `optionsModules.ts`.
|
|
12265
12308
|
*/
|
|
12266
12309
|
function assertModule(service, moduleName, context) {
|
|
@@ -12337,10 +12380,9 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
12337
12380
|
*
|
|
12338
12381
|
* This is the "declared intent" diagnostic. It fires when the user asks for a
|
|
12339
12382
|
* feature via options, at construction and on every `updateOptions`. It
|
|
12340
|
-
* deliberately does *not* fire on user interaction:
|
|
12341
|
-
*
|
|
12342
|
-
*
|
|
12343
|
-
* app never wanted.
|
|
12383
|
+
* deliberately does *not* fire on user interaction: an interaction reaching an
|
|
12384
|
+
* absent module stays silent, because the `?.` service-slot call sites can't
|
|
12385
|
+
* tell a missing module from a feature the app never wanted.
|
|
12344
12386
|
*
|
|
12345
12387
|
* Rules are a flat list rather than a `Record<keyof DockviewOptions, ...>`
|
|
12346
12388
|
* because dockview's options are nested and value-gated: `overflow.mode:
|
|
@@ -12436,18 +12478,6 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
12436
12478
|
moduleName: "AutoEdgeGroup",
|
|
12437
12479
|
when: (o) => isAnyEdgeGroupEnabled(o.dockToEdgeGroups)
|
|
12438
12480
|
},
|
|
12439
|
-
{
|
|
12440
|
-
optionKey: "getTabContextMenuItems",
|
|
12441
|
-
reason: "getTabContextMenuItems",
|
|
12442
|
-
moduleName: "ContextMenu",
|
|
12443
|
-
when: (o) => o.getTabContextMenuItems != null
|
|
12444
|
-
},
|
|
12445
|
-
{
|
|
12446
|
-
optionKey: "getTabGroupChipContextMenuItems",
|
|
12447
|
-
reason: "getTabGroupChipContextMenuItems",
|
|
12448
|
-
moduleName: "ContextMenu",
|
|
12449
|
-
when: (o) => o.getTabGroupChipContextMenuItems != null
|
|
12450
|
-
},
|
|
12451
12481
|
{
|
|
12452
12482
|
optionKey: "dndCompass",
|
|
12453
12483
|
reason: "dndCompass",
|
|
@@ -13314,6 +13344,267 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13314
13344
|
} });
|
|
13315
13345
|
}
|
|
13316
13346
|
});
|
|
13347
|
+
function popoverZIndexFor(target, group) {
|
|
13348
|
+
var _group$api, _group$api$isPeeking;
|
|
13349
|
+
if ((_group$api = group.api) === null || _group$api === void 0 || (_group$api$isPeeking = _group$api.isPeeking) === null || _group$api$isPeeking === void 0 ? void 0 : _group$api$isPeeking.call(_group$api)) return "calc(var(--dv-overlay-z-index, 999) + 100)";
|
|
13350
|
+
if (!(target instanceof HTMLElement)) return;
|
|
13351
|
+
const relativeParent = findRelativeZIndexParent(target);
|
|
13352
|
+
return (relativeParent === null || relativeParent === void 0 ? void 0 : relativeParent.style.zIndex) ? `calc(${relativeParent.style.zIndex} * 2)` : void 0;
|
|
13353
|
+
}
|
|
13354
|
+
let _nextId = 0;
|
|
13355
|
+
const nextContextMenuItemId = () => `dv-ctx-menu-item-${_nextId++}`;
|
|
13356
|
+
function isItemConfig(item) {
|
|
13357
|
+
return typeof item === "object";
|
|
13358
|
+
}
|
|
13359
|
+
function buildItem(label, close, action, disabled) {
|
|
13360
|
+
const el = document.createElement("div");
|
|
13361
|
+
el.className = "dv-context-menu-item";
|
|
13362
|
+
el.setAttribute("role", "menuitem");
|
|
13363
|
+
if (disabled) {
|
|
13364
|
+
el.classList.add("dv-context-menu-item--disabled");
|
|
13365
|
+
el.setAttribute("aria-disabled", "true");
|
|
13366
|
+
}
|
|
13367
|
+
el.textContent = label;
|
|
13368
|
+
if (!disabled) el.addEventListener("click", () => {
|
|
13369
|
+
action();
|
|
13370
|
+
close();
|
|
13371
|
+
});
|
|
13372
|
+
return el;
|
|
13373
|
+
}
|
|
13374
|
+
function buildSeparator() {
|
|
13375
|
+
const el = document.createElement("div");
|
|
13376
|
+
el.className = "dv-context-menu-separator";
|
|
13377
|
+
el.setAttribute("role", "separator");
|
|
13378
|
+
return el;
|
|
13379
|
+
}
|
|
13380
|
+
function isCoarsePrimaryInput$1() {
|
|
13381
|
+
if (globalThis.window === void 0 || !globalThis.matchMedia) return false;
|
|
13382
|
+
const coarse = globalThis.matchMedia("(pointer: coarse)").matches;
|
|
13383
|
+
const fine = globalThis.matchMedia("(pointer: fine)").matches;
|
|
13384
|
+
return coarse && !fine;
|
|
13385
|
+
}
|
|
13386
|
+
function buildRenameInput(tabGroup) {
|
|
13387
|
+
const wrapper = document.createElement("div");
|
|
13388
|
+
wrapper.className = "dv-context-menu-rename";
|
|
13389
|
+
const input = document.createElement("input");
|
|
13390
|
+
input.className = "dv-context-menu-rename-input";
|
|
13391
|
+
input.type = "text";
|
|
13392
|
+
input.placeholder = "Name This Group";
|
|
13393
|
+
input.value = tabGroup.label;
|
|
13394
|
+
input.addEventListener("input", () => {
|
|
13395
|
+
tabGroup.setLabel(input.value);
|
|
13396
|
+
});
|
|
13397
|
+
input.addEventListener("keydown", (e) => {
|
|
13398
|
+
if (e.key !== "Escape" && e.key !== "Enter") e.stopPropagation();
|
|
13399
|
+
});
|
|
13400
|
+
input.addEventListener("click", (e) => {
|
|
13401
|
+
e.stopPropagation();
|
|
13402
|
+
});
|
|
13403
|
+
wrapper.appendChild(input);
|
|
13404
|
+
if (!isCoarsePrimaryInput$1()) requestAnimationFrame(() => {
|
|
13405
|
+
input.focus();
|
|
13406
|
+
input.select();
|
|
13407
|
+
});
|
|
13408
|
+
return wrapper;
|
|
13409
|
+
}
|
|
13410
|
+
function buildColorPicker(tabGroup, palette) {
|
|
13411
|
+
const wrapper = document.createElement("div");
|
|
13412
|
+
wrapper.className = "dv-context-menu-color-picker";
|
|
13413
|
+
if (!palette.enabled) return wrapper;
|
|
13414
|
+
for (const entry of palette.entries()) {
|
|
13415
|
+
const swatch = document.createElement("div");
|
|
13416
|
+
swatch.className = "dv-context-menu-color-swatch";
|
|
13417
|
+
swatch.style.setProperty("--dv-tab-group-color", entry.value);
|
|
13418
|
+
if (entry.label) swatch.title = entry.label;
|
|
13419
|
+
if (tabGroup.color === entry.id) swatch.classList.add("dv-context-menu-color-swatch--selected");
|
|
13420
|
+
swatch.addEventListener("click", () => {
|
|
13421
|
+
tabGroup.setColor(entry.id);
|
|
13422
|
+
});
|
|
13423
|
+
wrapper.appendChild(swatch);
|
|
13424
|
+
}
|
|
13425
|
+
return wrapper;
|
|
13426
|
+
}
|
|
13427
|
+
var ContextMenuController = class {
|
|
13428
|
+
constructor(accessor) {
|
|
13429
|
+
this.accessor = accessor;
|
|
13430
|
+
}
|
|
13431
|
+
/**
|
|
13432
|
+
* A single maximize/restore toggle whose label and behaviour track the
|
|
13433
|
+
* group's live state: it reads *Restore* + calls `exitMaximized` when the
|
|
13434
|
+
* group is maximized, otherwise *Maximize* + `maximize`. Only grid groups
|
|
13435
|
+
* can be maximized, so the item is disabled for floating / popout panels
|
|
13436
|
+
* that are not already maximized.
|
|
13437
|
+
*/
|
|
13438
|
+
buildMaximizeItem(panel, close) {
|
|
13439
|
+
const isMaximized = panel.api.isMaximized();
|
|
13440
|
+
return buildItem(isMaximized ? "Restore" : "Maximize", close, isMaximized ? () => panel.api.exitMaximized() : () => panel.api.maximize(), !isMaximized && panel.api.location.type !== "grid");
|
|
13441
|
+
}
|
|
13442
|
+
/**
|
|
13443
|
+
* A single collapse/expand toggle whose label tracks the tab group's live
|
|
13444
|
+
* state: *Expand* when the group is already collapsed, otherwise *Collapse*.
|
|
13445
|
+
*/
|
|
13446
|
+
buildCollapseItem(tabGroup, close) {
|
|
13447
|
+
return buildItem(tabGroup.collapsed ? "Expand" : "Collapse", close, () => tabGroup.toggle());
|
|
13448
|
+
}
|
|
13449
|
+
/**
|
|
13450
|
+
* Whether to auto-inject the built-in Pin/Unpin item at the top of the tab
|
|
13451
|
+
* menu. True only when the PinnedTabs module is registered, pinning is
|
|
13452
|
+
* enabled, and the app has not opted out via `pinnedTabs.contextMenuItem:
|
|
13453
|
+
* false` (the item is on by default). This keeps pinning reachable from the
|
|
13454
|
+
* menu without the app having to return `'pin'` from
|
|
13455
|
+
* `getTabContextMenuItems` itself.
|
|
13456
|
+
*/
|
|
13457
|
+
_shouldInjectPin() {
|
|
13458
|
+
const pinnedTabs = this.accessor.options.pinnedTabs;
|
|
13459
|
+
return !!this.accessor.pinnedTabsService && !!(pinnedTabs === null || pinnedTabs === void 0 ? void 0 : pinnedTabs.enabled) && pinnedTabs.contextMenuItem !== false;
|
|
13460
|
+
}
|
|
13461
|
+
/**
|
|
13462
|
+
* The tab menu items: the app's own items (if any) with the built-in
|
|
13463
|
+
* `'pin'` item prepended when {@link _shouldInjectPin} applies, so the app
|
|
13464
|
+
* keeps full control of its list, and pinning is added without disturbing
|
|
13465
|
+
* it. Reuses the existing `'pin'` token rendering below.
|
|
13466
|
+
*/
|
|
13467
|
+
_resolveTabItems(panel, group, event) {
|
|
13468
|
+
var _this$accessor$option, _this$accessor$option2, _this$accessor$option3;
|
|
13469
|
+
const appItems = (_this$accessor$option = (_this$accessor$option2 = (_this$accessor$option3 = this.accessor.options).getTabContextMenuItems) === null || _this$accessor$option2 === void 0 ? void 0 : _this$accessor$option2.call(_this$accessor$option3, {
|
|
13470
|
+
panel,
|
|
13471
|
+
group,
|
|
13472
|
+
api: this.accessor.api,
|
|
13473
|
+
event
|
|
13474
|
+
})) !== null && _this$accessor$option !== void 0 ? _this$accessor$option : [];
|
|
13475
|
+
return this._shouldInjectPin() ? ["pin", ...appItems] : appItems;
|
|
13476
|
+
}
|
|
13477
|
+
/**
|
|
13478
|
+
* Render a custom `component` menu item and append it to `menuEl`. Builds
|
|
13479
|
+
* the framework renderer via the host's `createContextMenuItemComponent`
|
|
13480
|
+
* factory and initialises it. Shared by the tab menu and the chip menu,
|
|
13481
|
+
* which differ only in `identity`: the tab menu passes the `panel`, the chip
|
|
13482
|
+
* menu passes the `tabGroup`. No-op when no renderer could be created (no
|
|
13483
|
+
* factory configured, or the factory declined the component).
|
|
13484
|
+
*/
|
|
13485
|
+
appendComponentItem(menuEl, item, identity, group, close) {
|
|
13486
|
+
var _this$accessor$option4, _this$accessor$option5;
|
|
13487
|
+
const renderer = (_this$accessor$option4 = (_this$accessor$option5 = this.accessor.options).createContextMenuItemComponent) === null || _this$accessor$option4 === void 0 ? void 0 : _this$accessor$option4.call(_this$accessor$option5, {
|
|
13488
|
+
id: nextContextMenuItemId(),
|
|
13489
|
+
component: item.component
|
|
13490
|
+
});
|
|
13491
|
+
if (!renderer) return;
|
|
13492
|
+
renderer.init(_objectSpread2(_objectSpread2({}, identity), {}, {
|
|
13493
|
+
group,
|
|
13494
|
+
api: this.accessor.api,
|
|
13495
|
+
close,
|
|
13496
|
+
componentProps: item.componentProps
|
|
13497
|
+
}));
|
|
13498
|
+
menuEl.appendChild(renderer.element);
|
|
13499
|
+
}
|
|
13500
|
+
/**
|
|
13501
|
+
* The element for one built-in tab item, or `undefined` for a token this
|
|
13502
|
+
* version doesn't know (an app on a newer typings version, or plain JS):
|
|
13503
|
+
* an unrecognised token renders nothing rather than throwing.
|
|
13504
|
+
*/
|
|
13505
|
+
buildBuiltInTabItem(item, panel, group, close) {
|
|
13506
|
+
switch (item) {
|
|
13507
|
+
case "separator": return buildSeparator();
|
|
13508
|
+
case "close": return buildItem("Close", close, () => panel.api.close());
|
|
13509
|
+
case "closeOthers": return buildItem("Close Others", close, () => {
|
|
13510
|
+
group.panels.filter((p) => p !== panel).forEach((p) => p.api.close());
|
|
13511
|
+
});
|
|
13512
|
+
case "closeAll": return buildItem("Close All", close, () => {
|
|
13513
|
+
[...group.panels].forEach((p) => p.api.close());
|
|
13514
|
+
});
|
|
13515
|
+
case "closeLeft": {
|
|
13516
|
+
const index = group.panels.indexOf(panel);
|
|
13517
|
+
return buildItem("Close to the Left", close, () => {
|
|
13518
|
+
group.panels.filter((_, i) => i < index).forEach((p) => p.api.close());
|
|
13519
|
+
}, index <= 0);
|
|
13520
|
+
}
|
|
13521
|
+
case "closeRight": {
|
|
13522
|
+
const index = group.panels.indexOf(panel);
|
|
13523
|
+
return buildItem("Close to the Right", close, () => {
|
|
13524
|
+
group.panels.filter((_, i) => i > index).forEach((p) => p.api.close());
|
|
13525
|
+
}, index === -1 || index >= group.panels.length - 1);
|
|
13526
|
+
}
|
|
13527
|
+
case "maximize": return this.buildMaximizeItem(panel, close);
|
|
13528
|
+
case "float": return buildItem("Float", close, () => this.accessor.api.addFloatingGroup(panel), panel.api.location.type === "floating");
|
|
13529
|
+
case "popout": return buildItem("Open in New Window", close, () => {
|
|
13530
|
+
this.accessor.api.addPopoutGroup(panel);
|
|
13531
|
+
}, panel.api.location.type === "popout");
|
|
13532
|
+
case "pin": return buildItem(panel.api.isPinned ? "Unpin tab" : "Pin tab", close, () => panel.api.setPinned(!panel.api.isPinned));
|
|
13533
|
+
default: return;
|
|
13534
|
+
}
|
|
13535
|
+
}
|
|
13536
|
+
/**
|
|
13537
|
+
* Append one app-supplied item. A raw `element` is used as-is, a
|
|
13538
|
+
* `component` goes through the framework renderer, and a `label` builds the
|
|
13539
|
+
* default row; an item carrying none of the three renders nothing. Shared
|
|
13540
|
+
* by both menus, which differ only in `identity`.
|
|
13541
|
+
*/
|
|
13542
|
+
appendConfigItem(menuEl, item, identity, group, close) {
|
|
13543
|
+
if (item.element) menuEl.appendChild(item.element);
|
|
13544
|
+
else if (item.component) this.appendComponentItem(menuEl, item, identity, group, close);
|
|
13545
|
+
else if (item.label) menuEl.appendChild(buildItem(item.label, close, () => {
|
|
13546
|
+
var _item$action;
|
|
13547
|
+
return (_item$action = item.action) === null || _item$action === void 0 ? void 0 : _item$action.call(item);
|
|
13548
|
+
}, item.disabled));
|
|
13549
|
+
}
|
|
13550
|
+
show(panel, group, event) {
|
|
13551
|
+
const items = this._resolveTabItems(panel, group, event);
|
|
13552
|
+
if (items.length === 0) return;
|
|
13553
|
+
event.preventDefault();
|
|
13554
|
+
const popupService = this.accessor.getPopupServiceForGroup(group);
|
|
13555
|
+
const close = () => popupService.close();
|
|
13556
|
+
const menuEl = document.createElement("div");
|
|
13557
|
+
menuEl.className = "dv-context-menu";
|
|
13558
|
+
menuEl.setAttribute("role", "menu");
|
|
13559
|
+
for (const item of items) {
|
|
13560
|
+
if (isItemConfig(item)) {
|
|
13561
|
+
this.appendConfigItem(menuEl, item, { panel }, group, close);
|
|
13562
|
+
continue;
|
|
13563
|
+
}
|
|
13564
|
+
const el = this.buildBuiltInTabItem(item, panel, group, close);
|
|
13565
|
+
if (el) menuEl.appendChild(el);
|
|
13566
|
+
}
|
|
13567
|
+
popupService.openPopover(menuEl, {
|
|
13568
|
+
x: event.clientX,
|
|
13569
|
+
y: event.clientY,
|
|
13570
|
+
zIndex: popoverZIndexFor(event.target, group)
|
|
13571
|
+
});
|
|
13572
|
+
}
|
|
13573
|
+
showForChip(tabGroup, group, event) {
|
|
13574
|
+
if (!this.accessor.options.getTabGroupChipContextMenuItems) return;
|
|
13575
|
+
const items = this.accessor.options.getTabGroupChipContextMenuItems({
|
|
13576
|
+
tabGroup,
|
|
13577
|
+
group,
|
|
13578
|
+
api: this.accessor.api,
|
|
13579
|
+
event
|
|
13580
|
+
});
|
|
13581
|
+
if (items.length === 0) return;
|
|
13582
|
+
event.preventDefault();
|
|
13583
|
+
const popupService = this.accessor.getPopupServiceForGroup(group);
|
|
13584
|
+
const close = () => popupService.close();
|
|
13585
|
+
const menuEl = document.createElement("div");
|
|
13586
|
+
menuEl.className = "dv-context-menu";
|
|
13587
|
+
menuEl.setAttribute("role", "menu");
|
|
13588
|
+
for (const item of items) if (item === "separator") menuEl.appendChild(buildSeparator());
|
|
13589
|
+
else if (item === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
|
|
13590
|
+
else if (item === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
|
|
13591
|
+
else if (item === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
|
|
13592
|
+
else if (item === "close") menuEl.appendChild(buildItem("Close All", close, () => {
|
|
13593
|
+
group.panels.filter((p) => tabGroup.containsPanel(p.id)).forEach((p) => p.api.close());
|
|
13594
|
+
}));
|
|
13595
|
+
else if (isItemConfig(item)) this.appendConfigItem(menuEl, item, { tabGroup }, group, close);
|
|
13596
|
+
popupService.openPopover(menuEl, {
|
|
13597
|
+
x: event.clientX,
|
|
13598
|
+
y: event.clientY,
|
|
13599
|
+
zIndex: popoverZIndexFor(event.target, group)
|
|
13600
|
+
});
|
|
13601
|
+
}
|
|
13602
|
+
};
|
|
13603
|
+
const ContextMenuModule = defineModule({
|
|
13604
|
+
name: "ContextMenu",
|
|
13605
|
+
serviceKey: "contextMenuService",
|
|
13606
|
+
create: (host) => new ContextMenuController(host)
|
|
13607
|
+
});
|
|
13317
13608
|
/**
|
|
13318
13609
|
* Internal list of the built-in modules that ship with the core. Registered
|
|
13319
13610
|
* automatically by DockviewComponent at construction time; not exported from
|
|
@@ -13329,7 +13620,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13329
13620
|
HeaderActionsModule,
|
|
13330
13621
|
LiveRegionModule,
|
|
13331
13622
|
AdvancedDnDModule,
|
|
13332
|
-
TabGroupChipsModule
|
|
13623
|
+
TabGroupChipsModule,
|
|
13624
|
+
ContextMenuModule
|
|
13333
13625
|
];
|
|
13334
13626
|
var PositionCache = class {
|
|
13335
13627
|
constructor() {
|
|
@@ -13359,6 +13651,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13359
13651
|
});
|
|
13360
13652
|
}
|
|
13361
13653
|
};
|
|
13654
|
+
/**
|
|
13655
|
+
* Placeholder handle marking "a reposition frame has been requested but the
|
|
13656
|
+
* real handle is not known yet". Never passed to `cancelAnimationFrame` in
|
|
13657
|
+
* practice — it is replaced within the same synchronous block — and harmless
|
|
13658
|
+
* if it were, since no frame carries this id.
|
|
13659
|
+
*/
|
|
13660
|
+
const SCHEDULED = -1;
|
|
13362
13661
|
function createFocusableElement() {
|
|
13363
13662
|
const element = document.createElement("div");
|
|
13364
13663
|
element.tabIndex = -1;
|
|
@@ -13371,12 +13670,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13371
13670
|
this.accessor = accessor;
|
|
13372
13671
|
this.map = {};
|
|
13373
13672
|
this._disposed = false;
|
|
13673
|
+
this._generation = 0;
|
|
13374
13674
|
this.positionCache = new PositionCache();
|
|
13375
|
-
this.pendingUpdates = /* @__PURE__ */ new Set();
|
|
13376
13675
|
this.addDisposables(Disposable.from(() => {
|
|
13377
13676
|
for (const value of Object.values(this.map)) {
|
|
13378
13677
|
value.disposable.dispose();
|
|
13379
13678
|
value.destroy.dispose();
|
|
13679
|
+
this.cancelPendingUpdate(value);
|
|
13380
13680
|
}
|
|
13381
13681
|
this._disposed = true;
|
|
13382
13682
|
}));
|
|
@@ -13403,11 +13703,24 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13403
13703
|
this.positionCache.invalidate();
|
|
13404
13704
|
(_entry$resize = entry.resize) === null || _entry$resize === void 0 || _entry$resize.call(entry);
|
|
13405
13705
|
}
|
|
13706
|
+
/**
|
|
13707
|
+
* Drop the reposition frame queued for a panel, if any. A queued frame is
|
|
13708
|
+
* bound to the reference container that was current when it was scheduled,
|
|
13709
|
+
* so it must be discarded whenever that container stops being the one the
|
|
13710
|
+
* overlay should track.
|
|
13711
|
+
*/
|
|
13712
|
+
cancelPendingUpdate(entry) {
|
|
13713
|
+
if (entry.pendingUpdate !== void 0) {
|
|
13714
|
+
cancelAnimationFrame(entry.pendingUpdate);
|
|
13715
|
+
entry.pendingUpdate = void 0;
|
|
13716
|
+
}
|
|
13717
|
+
}
|
|
13406
13718
|
detatch(panel) {
|
|
13407
13719
|
if (this.map[panel.api.id]) {
|
|
13408
|
-
const
|
|
13409
|
-
disposable.dispose();
|
|
13410
|
-
destroy.dispose();
|
|
13720
|
+
const entry = this.map[panel.api.id];
|
|
13721
|
+
entry.disposable.dispose();
|
|
13722
|
+
entry.destroy.dispose();
|
|
13723
|
+
this.cancelPendingUpdate(entry);
|
|
13411
13724
|
delete this.map[panel.api.id];
|
|
13412
13725
|
return true;
|
|
13413
13726
|
}
|
|
@@ -13423,22 +13736,73 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13423
13736
|
panel,
|
|
13424
13737
|
disposable: Disposable.NONE,
|
|
13425
13738
|
destroy: Disposable.NONE,
|
|
13426
|
-
element
|
|
13739
|
+
element,
|
|
13740
|
+
retainPreviousGeometry: false,
|
|
13741
|
+
positioned: false,
|
|
13742
|
+
generation: ++this._generation
|
|
13427
13743
|
};
|
|
13428
13744
|
}
|
|
13429
|
-
const
|
|
13745
|
+
const mapEntry = this.map[panel.api.id];
|
|
13746
|
+
/**
|
|
13747
|
+
* A *change* of reference container supersedes the previous `attach`:
|
|
13748
|
+
* take a fresh generation so its `resize` closure can no longer run,
|
|
13749
|
+
* and drop the frame it queued against the old container. During
|
|
13750
|
+
* `fromJSON({ reuseExistingPanels: true })` that old container is a
|
|
13751
|
+
* detached staging group measuring 0x0, so leaving its frame in flight
|
|
13752
|
+
* both wastes the update and delays the reposition against the real one.
|
|
13753
|
+
*
|
|
13754
|
+
* Re-attaching over the *same* container (re-open, active panel change)
|
|
13755
|
+
* deliberately leaves scheduled work alone: `repositionPanelOverlay`
|
|
13756
|
+
* (the auto-hide peek) schedules a frame carrying the sticky
|
|
13757
|
+
* `forceVisible`/`clip` state which `attach` does not re-apply, and a
|
|
13758
|
+
* peeked panel's `api.isVisible` is false — so discarding that frame
|
|
13759
|
+
* leaves `visibilityChanged` to hide the overlay and the peek renders
|
|
13760
|
+
* nothing. A newly created entry already holds a fresh generation, so
|
|
13761
|
+
* the stale closures a `detatch` left behind are fenced off either way.
|
|
13762
|
+
*/
|
|
13763
|
+
if (mapEntry.referenceContainer !== referenceContainer) {
|
|
13764
|
+
mapEntry.generation = ++this._generation;
|
|
13765
|
+
this.cancelPendingUpdate(mapEntry);
|
|
13766
|
+
mapEntry.referenceContainer = referenceContainer;
|
|
13767
|
+
/**
|
|
13768
|
+
* Arm the retain flag only here: it means "a replacement reference
|
|
13769
|
+
* container is awaiting layout", so the 0x0 early-return below
|
|
13770
|
+
* holds the last good box rather than blanking the panel mid-move.
|
|
13771
|
+
* Arming it on every re-attach instead would make a container that
|
|
13772
|
+
* genuinely collapses to zero keep its stale geometry forever.
|
|
13773
|
+
*
|
|
13774
|
+
* Gated on `positioned` because an overlay that has never been
|
|
13775
|
+
* positioned has no left/top/width/height, and `.dv-render-overlay`
|
|
13776
|
+
* defaults to 100%/100% — retaining "previous" geometry there would
|
|
13777
|
+
* pin the content over the whole container.
|
|
13778
|
+
*/
|
|
13779
|
+
mapEntry.retainPreviousGeometry = mapEntry.positioned;
|
|
13780
|
+
}
|
|
13781
|
+
const generation = mapEntry.generation;
|
|
13782
|
+
const focusContainer = mapEntry.element;
|
|
13430
13783
|
const contentElement = panel.view.content.element;
|
|
13431
13784
|
if (contentElement.parentElement !== focusContainer) focusContainer.appendChild(contentElement);
|
|
13432
13785
|
if (focusContainer.parentElement !== this.element) this.element.appendChild(focusContainer);
|
|
13433
13786
|
const resize = () => {
|
|
13434
13787
|
const panelId = panel.api.id;
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13788
|
+
const scheduling = this.map[panelId];
|
|
13789
|
+
if ((scheduling === null || scheduling === void 0 ? void 0 : scheduling.generation) !== generation) return;
|
|
13790
|
+
if (scheduling.pendingUpdate !== void 0) return;
|
|
13791
|
+
/**
|
|
13792
|
+
* Claim the slot *before* scheduling. `requestAnimationFrame` is
|
|
13793
|
+
* shimmed to run inline by some hosts (and by several suites here),
|
|
13794
|
+
* in which case the callback below clears `pendingUpdate` while
|
|
13795
|
+
* this call is still on the stack — assigning the handle afterwards
|
|
13796
|
+
* would resurrect a slot that is already spent and block every
|
|
13797
|
+
* later reposition. The sentinel is replaced by the real handle
|
|
13798
|
+
* only if the frame has not already run.
|
|
13799
|
+
*/
|
|
13800
|
+
scheduling.pendingUpdate = SCHEDULED;
|
|
13801
|
+
const handle = requestAnimationFrame(() => {
|
|
13438
13802
|
var _entry$forceVisible;
|
|
13439
|
-
this.pendingUpdates.delete(panelId);
|
|
13440
13803
|
const entry = this.map[panelId];
|
|
13441
|
-
if (
|
|
13804
|
+
if (entry) entry.pendingUpdate = void 0;
|
|
13805
|
+
if (this.isDisposed || (entry === null || entry === void 0 ? void 0 : entry.generation) !== generation) return;
|
|
13442
13806
|
const forceVisible = (_entry$forceVisible = entry.forceVisible) !== null && _entry$forceVisible !== void 0 ? _entry$forceVisible : false;
|
|
13443
13807
|
const clip = entry.clip;
|
|
13444
13808
|
const box = this.positionCache.getPosition(referenceContainer.element);
|
|
@@ -13447,6 +13811,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13447
13811
|
const top = box.top - box2.top;
|
|
13448
13812
|
const width = box.width;
|
|
13449
13813
|
const height = box.height;
|
|
13814
|
+
if (entry.retainPreviousGeometry && (width === 0 || height === 0)) {
|
|
13815
|
+
if (!panel.api.isVisible && !forceVisible) {
|
|
13816
|
+
focusContainer.style.visibility = "hidden";
|
|
13817
|
+
focusContainer.style.pointerEvents = "none";
|
|
13818
|
+
}
|
|
13819
|
+
return;
|
|
13820
|
+
}
|
|
13821
|
+
entry.retainPreviousGeometry = false;
|
|
13822
|
+
entry.positioned = true;
|
|
13450
13823
|
focusContainer.style.left = `${left}px`;
|
|
13451
13824
|
focusContainer.style.top = `${top}px`;
|
|
13452
13825
|
focusContainer.style.width = `${width}px`;
|
|
@@ -13475,11 +13848,30 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13475
13848
|
} else focusContainer.style.clipPath = "";
|
|
13476
13849
|
toggleClass(focusContainer, "dv-render-overlay-float", panel.group.api.location.type === "floating");
|
|
13477
13850
|
});
|
|
13851
|
+
if (scheduling.pendingUpdate === SCHEDULED) scheduling.pendingUpdate = handle;
|
|
13478
13852
|
};
|
|
13479
13853
|
const visibilityChanged = () => {
|
|
13480
13854
|
if (panel.api.isVisible) {
|
|
13855
|
+
var _this$map$panel$api$i;
|
|
13481
13856
|
this.positionCache.invalidate();
|
|
13482
13857
|
resize();
|
|
13858
|
+
/**
|
|
13859
|
+
* Existing geometry is safe to show while its replacement lays
|
|
13860
|
+
* out. `retainPreviousGeometry` is only set when geometry has
|
|
13861
|
+
* actually been written (see `attach`), so this can never
|
|
13862
|
+
* un-hide an overlay whose left/top/width/height are unset —
|
|
13863
|
+
* `.dv-render-overlay` is 100%/100% by default and would
|
|
13864
|
+
* otherwise cover the whole dock.
|
|
13865
|
+
*
|
|
13866
|
+
* The retained geometry is the panel's position in the previous
|
|
13867
|
+
* layout, so restoring a layout that moves the panel does paint
|
|
13868
|
+
* it at stale coordinates until the reposition lands. That is
|
|
13869
|
+
* bounded to the next frame now that a superseded `attach` can
|
|
13870
|
+
* no longer swallow the reposition (see `attach`); showing
|
|
13871
|
+
* stale-but-real geometry for a frame is the deliberate
|
|
13872
|
+
* trade-off against blanking the panel for the whole rebuild.
|
|
13873
|
+
*/
|
|
13874
|
+
if ((_this$map$panel$api$i = this.map[panel.api.id]) === null || _this$map$panel$api$i === void 0 ? void 0 : _this$map$panel$api$i.retainPreviousGeometry) focusContainer.style.visibility = "";
|
|
13483
13875
|
focusContainer.style.pointerEvents = "";
|
|
13484
13876
|
} else {
|
|
13485
13877
|
focusContainer.style.visibility = "hidden";
|
|
@@ -13696,7 +14088,17 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13696
14088
|
window: externalWindow
|
|
13697
14089
|
});
|
|
13698
14090
|
return new Promise((resolve, reject) => {
|
|
13699
|
-
externalWindow.addEventListener("unload", (
|
|
14091
|
+
externalWindow.addEventListener("unload", () => {});
|
|
14092
|
+
/**
|
|
14093
|
+
* `load` is the only event that resolves this promise with a
|
|
14094
|
+
* container, so a window that goes away first would leave the
|
|
14095
|
+
* caller awaiting a promise that never settles - and
|
|
14096
|
+
* `addPopoutGroup` holds its layout transaction open until it does.
|
|
14097
|
+
* Settle with `null` on close, the same signal a blocked popup
|
|
14098
|
+
* gives and one the caller already handles. `resolve` after the
|
|
14099
|
+
* fact is a no-op, so a `load` that arrived first still wins.
|
|
14100
|
+
*/
|
|
14101
|
+
disposable.addDisposables(_this.onWillClose(() => resolve(null)));
|
|
13700
14102
|
externalWindow.addEventListener("load", () => {
|
|
13701
14103
|
/**
|
|
13702
14104
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
|
|
@@ -13890,6 +14292,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13890
14292
|
}
|
|
13891
14293
|
};
|
|
13892
14294
|
var DropTargetAnchorContainer = class extends CompositeDisposable {
|
|
14295
|
+
/**
|
|
14296
|
+
* The element the live overlay was rendered for, `undefined` when nothing
|
|
14297
|
+
* is showing. The container is shared by every drop target, so a caller
|
|
14298
|
+
* tearing down only its own overlay must check this before `clear()`.
|
|
14299
|
+
*/
|
|
14300
|
+
get renderedOutline() {
|
|
14301
|
+
return this._model ? this._outline : void 0;
|
|
14302
|
+
}
|
|
13893
14303
|
get disabled() {
|
|
13894
14304
|
return this._disabled;
|
|
13895
14305
|
}
|
|
@@ -14191,6 +14601,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14191
14601
|
const index = position === "top" ? this._topIndex : this._bottomIndex;
|
|
14192
14602
|
if (index !== void 0) this._splitview.resizeView(index, size);
|
|
14193
14603
|
}
|
|
14604
|
+
/** The inner splitview's primary-axis (height) extent; zero until laid out. */
|
|
14605
|
+
get axisSize() {
|
|
14606
|
+
return this._splitview.size;
|
|
14607
|
+
}
|
|
14194
14608
|
updateMargin(gap) {
|
|
14195
14609
|
this._splitview.margin = gap;
|
|
14196
14610
|
}
|
|
@@ -14203,6 +14617,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14203
14617
|
constructor(container, dockviewElement, layoutGrid, gap = 0, defaultCollapsedSize = 35) {
|
|
14204
14618
|
this._disposables = new CompositeDisposable();
|
|
14205
14619
|
this._viewConfigs = /* @__PURE__ */ new Map();
|
|
14620
|
+
this._pendingSizes = /* @__PURE__ */ new Map();
|
|
14206
14621
|
this._currentWidth = 0;
|
|
14207
14622
|
this._currentHeight = 0;
|
|
14208
14623
|
this._gap = gap;
|
|
@@ -14293,11 +14708,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14293
14708
|
break;
|
|
14294
14709
|
}
|
|
14295
14710
|
this._disposables.addDisposables(view);
|
|
14711
|
+
if (!view.isCollapsed && !this._canResize(position)) this._pendingSizes.set(position, initialSize);
|
|
14296
14712
|
this.updateTheme(this._gap, this._defaultCollapsedSize);
|
|
14297
14713
|
return view;
|
|
14298
14714
|
}
|
|
14299
14715
|
layout(width, height) {
|
|
14300
14716
|
this._outerSplitview.layout(width, height);
|
|
14717
|
+
this._flushPendingSizes();
|
|
14301
14718
|
}
|
|
14302
14719
|
/**
|
|
14303
14720
|
* Called when the active theme changes. Updates splitview margins and
|
|
@@ -14361,6 +14778,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14361
14778
|
this._disposables.removeDisposable(view);
|
|
14362
14779
|
view.dispose();
|
|
14363
14780
|
this._viewConfigs.delete(position);
|
|
14781
|
+
this._pendingSizes.delete(position);
|
|
14364
14782
|
this.updateTheme(this._gap, this._defaultCollapsedSize);
|
|
14365
14783
|
}
|
|
14366
14784
|
hasEdgeGroup(position) {
|
|
@@ -14384,6 +14802,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14384
14802
|
this._middleColumn.setViewVisible(position, visible);
|
|
14385
14803
|
break;
|
|
14386
14804
|
}
|
|
14805
|
+
if (visible) this._flushPendingSizes();
|
|
14387
14806
|
}
|
|
14388
14807
|
isEdgeGroupVisible(position) {
|
|
14389
14808
|
switch (position) {
|
|
@@ -14401,20 +14820,63 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14401
14820
|
const view = this._getView(position);
|
|
14402
14821
|
if (!view) return;
|
|
14403
14822
|
view.setCollapsed(collapsed);
|
|
14404
|
-
|
|
14823
|
+
if (collapsed) {
|
|
14824
|
+
this._pendingSizes.delete(position);
|
|
14825
|
+
this._resizeView(position, view.collapsedSize);
|
|
14826
|
+
} else this.resizeEdgeGroup(position, view.lastExpandedSize);
|
|
14827
|
+
}
|
|
14828
|
+
/**
|
|
14829
|
+
* Resize the edge group at `position` along its primary axis (width for
|
|
14830
|
+
* `left`/`right`, height for `top`/`bottom`), clamped by the group's
|
|
14831
|
+
* constraints and the space available. Where `groupApi.setSize` lands.
|
|
14832
|
+
*
|
|
14833
|
+
* The size becomes the group's expanded size, so a collapsed group keeps
|
|
14834
|
+
* its strip and takes it on expand, and it survives a `toJSON` round-trip.
|
|
14835
|
+
*/
|
|
14836
|
+
resizeEdgeGroup(position, size) {
|
|
14837
|
+
const view = this._getView(position);
|
|
14838
|
+
if (!view || !Number.isFinite(size)) return;
|
|
14839
|
+
const target = Math.round(size);
|
|
14840
|
+
if (target <= 0) return;
|
|
14841
|
+
view.restoreExpandedSize(target);
|
|
14842
|
+
if (view.isCollapsed) {
|
|
14843
|
+
this._pendingSizes.delete(position);
|
|
14844
|
+
return;
|
|
14845
|
+
}
|
|
14846
|
+
if (this._canResize(position)) {
|
|
14847
|
+
this._pendingSizes.delete(position);
|
|
14848
|
+
this._resizeView(position, target);
|
|
14849
|
+
} else this._pendingSizes.set(position, target);
|
|
14850
|
+
}
|
|
14851
|
+
/** A resize lands only on a visible view (a hidden one is pinned to zero)
|
|
14852
|
+
* whose splitview has extent to distribute. */
|
|
14853
|
+
_canResize(position) {
|
|
14854
|
+
if (!this.isEdgeGroupVisible(position)) return false;
|
|
14855
|
+
return (position === "left" || position === "right" ? this._outerSplitview.size : this._middleColumn.axisSize) > 0;
|
|
14856
|
+
}
|
|
14857
|
+
_resizeView(position, size) {
|
|
14405
14858
|
switch (position) {
|
|
14406
14859
|
case "left":
|
|
14407
|
-
if (this._leftIndex !== void 0) this._outerSplitview.resizeView(this._leftIndex,
|
|
14860
|
+
if (this._leftIndex !== void 0) this._outerSplitview.resizeView(this._leftIndex, size);
|
|
14408
14861
|
break;
|
|
14409
14862
|
case "right":
|
|
14410
|
-
if (this._rightIndex !== void 0) this._outerSplitview.resizeView(this._rightIndex,
|
|
14863
|
+
if (this._rightIndex !== void 0) this._outerSplitview.resizeView(this._rightIndex, size);
|
|
14411
14864
|
break;
|
|
14412
14865
|
case "top":
|
|
14413
14866
|
case "bottom":
|
|
14414
|
-
this._middleColumn.resizeView(position,
|
|
14867
|
+
this._middleColumn.resizeView(position, size);
|
|
14415
14868
|
break;
|
|
14416
14869
|
}
|
|
14417
14870
|
}
|
|
14871
|
+
_flushPendingSizes() {
|
|
14872
|
+
if (this._pendingSizes.size === 0) return;
|
|
14873
|
+
for (const [position, size] of this._pendingSizes) {
|
|
14874
|
+
const view = this._getView(position);
|
|
14875
|
+
if (!view || view.isCollapsed || !this._canResize(position)) continue;
|
|
14876
|
+
this._pendingSizes.delete(position);
|
|
14877
|
+
this._resizeView(position, size);
|
|
14878
|
+
}
|
|
14879
|
+
}
|
|
14418
14880
|
isEdgeGroupCollapsed(position) {
|
|
14419
14881
|
var _this$_getView$isColl, _this$_getView;
|
|
14420
14882
|
return (_this$_getView$isColl = (_this$_getView = this._getView(position)) === null || _this$_getView === void 0 ? void 0 : _this$_getView.isCollapsed) !== null && _this$_getView$isColl !== void 0 ? _this$_getView$isColl : false;
|
|
@@ -14440,15 +14902,17 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14440
14902
|
maximumSize: Number.isFinite(view.configuredMaximumSize) ? view.configuredMaximumSize : void 0,
|
|
14441
14903
|
collapsedSize: view.configuredCollapsedSize
|
|
14442
14904
|
});
|
|
14443
|
-
const expandedSize = (view, isVisible, liveSize, cachedVisibleSize) => {
|
|
14905
|
+
const expandedSize = (view, position, isVisible, liveSize, cachedVisibleSize) => {
|
|
14444
14906
|
if (view.isCollapsed) return view.lastExpandedSize;
|
|
14907
|
+
const pending = this._pendingSizes.get(position);
|
|
14908
|
+
if (pending !== void 0) return pending;
|
|
14445
14909
|
if (!isVisible) return cachedVisibleSize !== null && cachedVisibleSize !== void 0 ? cachedVisibleSize : view.lastExpandedSize;
|
|
14446
14910
|
return liveSize;
|
|
14447
14911
|
};
|
|
14448
14912
|
if (this._leftView && this._leftIndex !== void 0) {
|
|
14449
14913
|
const visible = this._outerSplitview.isViewVisible(this._leftIndex);
|
|
14450
14914
|
edgeGroups.left = _objectSpread2({
|
|
14451
|
-
size: expandedSize(this._leftView, visible, this._outerSplitview.getViewSize(this._leftIndex), this._outerSplitview.getViewCachedVisibleSize(this._leftIndex)),
|
|
14915
|
+
size: expandedSize(this._leftView, "left", visible, this._outerSplitview.getViewSize(this._leftIndex), this._outerSplitview.getViewCachedVisibleSize(this._leftIndex)),
|
|
14452
14916
|
visible,
|
|
14453
14917
|
collapsed: this._leftView.isCollapsed || void 0
|
|
14454
14918
|
}, constraints(this._leftView));
|
|
@@ -14456,7 +14920,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14456
14920
|
if (this._rightView && this._rightIndex !== void 0) {
|
|
14457
14921
|
const visible = this._outerSplitview.isViewVisible(this._rightIndex);
|
|
14458
14922
|
edgeGroups.right = _objectSpread2({
|
|
14459
|
-
size: expandedSize(this._rightView, visible, this._outerSplitview.getViewSize(this._rightIndex), this._outerSplitview.getViewCachedVisibleSize(this._rightIndex)),
|
|
14923
|
+
size: expandedSize(this._rightView, "right", visible, this._outerSplitview.getViewSize(this._rightIndex), this._outerSplitview.getViewCachedVisibleSize(this._rightIndex)),
|
|
14460
14924
|
visible,
|
|
14461
14925
|
collapsed: this._rightView.isCollapsed || void 0
|
|
14462
14926
|
}, constraints(this._rightView));
|
|
@@ -14464,7 +14928,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14464
14928
|
if (this._topView) {
|
|
14465
14929
|
const visible = this._middleColumn.isViewVisible("top");
|
|
14466
14930
|
edgeGroups.top = _objectSpread2({
|
|
14467
|
-
size: expandedSize(this._topView, visible, this._middleColumn.getViewSize("top"), this._middleColumn.getViewCachedVisibleSize("top")),
|
|
14931
|
+
size: expandedSize(this._topView, "top", visible, this._middleColumn.getViewSize("top"), this._middleColumn.getViewCachedVisibleSize("top")),
|
|
14468
14932
|
visible,
|
|
14469
14933
|
collapsed: this._topView.isCollapsed || void 0
|
|
14470
14934
|
}, constraints(this._topView));
|
|
@@ -14472,7 +14936,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14472
14936
|
if (this._bottomView) {
|
|
14473
14937
|
const visible = this._middleColumn.isViewVisible("bottom");
|
|
14474
14938
|
edgeGroups.bottom = _objectSpread2({
|
|
14475
|
-
size: expandedSize(this._bottomView, visible, this._middleColumn.getViewSize("bottom"), this._middleColumn.getViewCachedVisibleSize("bottom")),
|
|
14939
|
+
size: expandedSize(this._bottomView, "bottom", visible, this._middleColumn.getViewSize("bottom"), this._middleColumn.getViewCachedVisibleSize("bottom")),
|
|
14476
14940
|
visible,
|
|
14477
14941
|
collapsed: this._bottomView.isCollapsed || void 0
|
|
14478
14942
|
}, constraints(this._bottomView));
|
|
@@ -14480,33 +14944,23 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14480
14944
|
return edgeGroups;
|
|
14481
14945
|
}
|
|
14482
14946
|
fromJSON(data) {
|
|
14483
|
-
|
|
14484
|
-
|
|
14485
|
-
|
|
14486
|
-
|
|
14487
|
-
|
|
14488
|
-
|
|
14489
|
-
|
|
14490
|
-
|
|
14491
|
-
|
|
14492
|
-
(
|
|
14493
|
-
|
|
14494
|
-
|
|
14495
|
-
if (
|
|
14496
|
-
|
|
14497
|
-
|
|
14498
|
-
|
|
14499
|
-
|
|
14500
|
-
(_this$_topView3 = this._topView) === null || _this$_topView3 === void 0 || _this$_topView3.setCollapsed((_data$top$collapsed = data.top.collapsed) !== null && _data$top$collapsed !== void 0 ? _data$top$collapsed : false);
|
|
14501
|
-
this._middleColumn.resizeView("top", data.top.collapsed ? (_this$_topView$collap = (_this$_topView4 = this._topView) === null || _this$_topView4 === void 0 ? void 0 : _this$_topView4.collapsedSize) !== null && _this$_topView$collap !== void 0 ? _this$_topView$collap : data.top.size : data.top.size);
|
|
14502
|
-
if (!data.top.visible) this._middleColumn.setViewVisible("top", false);
|
|
14503
|
-
}
|
|
14504
|
-
if (data.bottom) {
|
|
14505
|
-
var _this$_bottomView2, _this$_bottomView3, _data$bottom$collapse, _this$_bottomView$col, _this$_bottomView4;
|
|
14506
|
-
(_this$_bottomView2 = this._bottomView) === null || _this$_bottomView2 === void 0 || _this$_bottomView2.restoreExpandedSize(data.bottom.size);
|
|
14507
|
-
(_this$_bottomView3 = this._bottomView) === null || _this$_bottomView3 === void 0 || _this$_bottomView3.setCollapsed((_data$bottom$collapse = data.bottom.collapsed) !== null && _data$bottom$collapse !== void 0 ? _data$bottom$collapse : false);
|
|
14508
|
-
this._middleColumn.resizeView("bottom", data.bottom.collapsed ? (_this$_bottomView$col = (_this$_bottomView4 = this._bottomView) === null || _this$_bottomView4 === void 0 ? void 0 : _this$_bottomView4.collapsedSize) !== null && _this$_bottomView$col !== void 0 ? _this$_bottomView$col : data.bottom.size : data.bottom.size);
|
|
14509
|
-
if (!data.bottom.visible) this._middleColumn.setViewVisible("bottom", false);
|
|
14947
|
+
for (const position of [
|
|
14948
|
+
"left",
|
|
14949
|
+
"right",
|
|
14950
|
+
"top",
|
|
14951
|
+
"bottom"
|
|
14952
|
+
]) {
|
|
14953
|
+
var _state$collapsed;
|
|
14954
|
+
const state = data[position];
|
|
14955
|
+
const view = this._getView(position);
|
|
14956
|
+
if (!state || !view) continue;
|
|
14957
|
+
view.restoreExpandedSize(state.size);
|
|
14958
|
+
view.setCollapsed((_state$collapsed = state.collapsed) !== null && _state$collapsed !== void 0 ? _state$collapsed : false);
|
|
14959
|
+
if (state.collapsed) {
|
|
14960
|
+
this._pendingSizes.delete(position);
|
|
14961
|
+
this._resizeView(position, view.collapsedSize);
|
|
14962
|
+
} else this.resizeEdgeGroup(position, state.size);
|
|
14963
|
+
this.setEdgeGroupVisible(position, !!state.visible);
|
|
14510
14964
|
}
|
|
14511
14965
|
}
|
|
14512
14966
|
dispose() {
|
|
@@ -15096,6 +15550,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15096
15550
|
this._onWillDrop = new Emitter();
|
|
15097
15551
|
this.onWillDrop = this._onWillDrop.event;
|
|
15098
15552
|
this._mutationDepth = 0;
|
|
15553
|
+
this._pendingLocationChanges = /* @__PURE__ */ new Map();
|
|
15099
15554
|
this._origin = "user";
|
|
15100
15555
|
this._originDepth = 0;
|
|
15101
15556
|
this._onWillMutateLayout = new Emitter();
|
|
@@ -15193,7 +15648,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15193
15648
|
toggleClass(this.element, "dv-debug", !!options.debug);
|
|
15194
15649
|
this.updateTheme();
|
|
15195
15650
|
if (options.debug) this.addDisposables(new StrictEventsSequencing(this));
|
|
15196
|
-
this.addDisposables(this.rootDropTargetContainer, this.floatingDropTargetContainer, addDisposableListener(this._shellManager.element, "dragend", () => {
|
|
15651
|
+
this.addDisposables(Disposable.from(() => this._pendingLocationChanges.clear()), this.rootDropTargetContainer, this.floatingDropTargetContainer, addDisposableListener(this._shellManager.element, "dragend", () => {
|
|
15197
15652
|
var _this$rootDropTargetC2, _this$floatingDropTar;
|
|
15198
15653
|
(_this$rootDropTargetC2 = this.rootDropTargetContainer.model) === null || _this$rootDropTargetC2 === void 0 || _this$rootDropTargetC2.clear();
|
|
15199
15654
|
(_this$floatingDropTar = this.floatingDropTargetContainer.model) === null || _this$floatingDropTar === void 0 || _this$floatingDropTar.clear();
|
|
@@ -15267,7 +15722,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15267
15722
|
return (_this$_popoutWindowSe3 = (_this$_popoutWindowSe4 = this._popoutWindowService) === null || _this$_popoutWindowSe4 === void 0 || (_this$_popoutWindowSe4 = _this$_popoutWindowSe4.findByGroup(group)) === null || _this$_popoutWindowSe4 === void 0 ? void 0 : _this$_popoutWindowSe4.popupService) !== null && _this$_popoutWindowSe3 !== void 0 ? _this$_popoutWindowSe3 : this.popupService;
|
|
15268
15723
|
}
|
|
15269
15724
|
addPopoutGroup(itemToPopout, options) {
|
|
15270
|
-
return this.
|
|
15725
|
+
return this.mutationAsync("popout", () => this._doAddPopoutGroup(itemToPopout, options));
|
|
15271
15726
|
}
|
|
15272
15727
|
/** Enumerate the popout groups currently open in their own windows. */
|
|
15273
15728
|
getPopouts() {
|
|
@@ -15364,15 +15819,32 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15364
15819
|
}
|
|
15365
15820
|
};
|
|
15366
15821
|
let floatingBox;
|
|
15367
|
-
|
|
15368
|
-
|
|
15369
|
-
|
|
15370
|
-
|
|
15371
|
-
|
|
15822
|
+
/**
|
|
15823
|
+
* Popping out rehomes panels into `group`, so like the floating
|
|
15824
|
+
* case it owes the caller an `onDidMovePanel` per panel. The
|
|
15825
|
+
* events are deferred until the window is wired up so listeners
|
|
15826
|
+
* observe the panels' final `popout` location.
|
|
15827
|
+
*/
|
|
15828
|
+
let movedPanels = [];
|
|
15829
|
+
if (!(options === null || options === void 0 ? void 0 : options.overridePopoutGroup) && !(options === null || options === void 0 ? void 0 : options.overridePopoutGridview) && isGroupAddedToDom) if (itemToPopout instanceof DockviewPanel) {
|
|
15830
|
+
const sourceGroup = itemToPopout.group;
|
|
15831
|
+
this.movingLock(() => {
|
|
15832
|
+
const panel = referenceGroup.model.removePanel(itemToPopout);
|
|
15833
|
+
group.model.openPanel(panel);
|
|
15834
|
+
});
|
|
15835
|
+
movedPanels = [{
|
|
15836
|
+
panel: itemToPopout,
|
|
15837
|
+
from: sourceGroup
|
|
15838
|
+
}];
|
|
15839
|
+
} else {
|
|
15372
15840
|
this.movingLock(() => moveGroupWithoutDestroying({
|
|
15373
15841
|
from: referenceGroup,
|
|
15374
15842
|
to: group
|
|
15375
15843
|
}));
|
|
15844
|
+
movedPanels = group.panels.map((panel) => ({
|
|
15845
|
+
panel,
|
|
15846
|
+
from: referenceGroup
|
|
15847
|
+
}));
|
|
15376
15848
|
switch (referenceLocation) {
|
|
15377
15849
|
case "grid":
|
|
15378
15850
|
referenceGroup.api.setVisible(false);
|
|
@@ -15481,6 +15953,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15481
15953
|
group: value.popoutGroup,
|
|
15482
15954
|
window: value.getWindow()
|
|
15483
15955
|
});
|
|
15956
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15484
15957
|
return true;
|
|
15485
15958
|
}).catch((err) => {
|
|
15486
15959
|
console.error("dockview: failed to create popout.", err);
|
|
@@ -15558,6 +16031,16 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15558
16031
|
const members = this.groups.filter((candidate) => popoutGridview.element.contains(candidate.element));
|
|
15559
16032
|
const anchorPresent = members.includes(group);
|
|
15560
16033
|
const anchorIsSoleMember = anchorPresent && members.length === 1;
|
|
16034
|
+
/**
|
|
16035
|
+
* Popping a group out fires `onDidMovePanel` per panel, so closing the
|
|
16036
|
+
* window owes the caller the same: every panel in it is rehomed, into
|
|
16037
|
+
* the reference group the popout left behind or into a fresh grid slot.
|
|
16038
|
+
* `movingLock` suppresses onDidAddPanel / onDidRemovePanel on these
|
|
16039
|
+
* paths, so `onDidMovePanel` is the only event that can carry it. The
|
|
16040
|
+
* events are deferred to the end so listeners observe the panels at
|
|
16041
|
+
* their final group and location.
|
|
16042
|
+
*/
|
|
16043
|
+
const movedPanels = [];
|
|
15561
16044
|
if (genuineClose) for (const member of members) {
|
|
15562
16045
|
if (member === group) continue;
|
|
15563
16046
|
this.movingLock(() => {
|
|
@@ -15568,12 +16051,21 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15568
16051
|
});
|
|
15569
16052
|
this.redockGroupToMainGrid(member);
|
|
15570
16053
|
});
|
|
16054
|
+
for (const panel of member.panels) movedPanels.push({
|
|
16055
|
+
panel,
|
|
16056
|
+
from: member
|
|
16057
|
+
});
|
|
15571
16058
|
}
|
|
15572
16059
|
if (anchorPresent && isGroupAddedToDom && this.getPanel(referenceGroup.id)) {
|
|
16060
|
+
const rehomed = [...group.panels];
|
|
15573
16061
|
this.movingLock(() => moveGroupWithoutDestroying({
|
|
15574
16062
|
from: group,
|
|
15575
16063
|
to: referenceGroup
|
|
15576
16064
|
}));
|
|
16065
|
+
for (const panel of rehomed) movedPanels.push({
|
|
16066
|
+
panel,
|
|
16067
|
+
from: group
|
|
16068
|
+
});
|
|
15577
16069
|
if (!referenceGroup.api.isVisible) referenceGroup.api.setVisible(true);
|
|
15578
16070
|
if (this.getPanel(group.id)) this.doRemoveGroup(group, { skipPopoutAssociated: true });
|
|
15579
16071
|
} else if (anchorPresent && this.getPanel(group.id)) {
|
|
@@ -15604,10 +16096,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15604
16096
|
this.movingLock(() => {
|
|
15605
16097
|
this.doAddGroup(group, [0]);
|
|
15606
16098
|
});
|
|
16099
|
+
for (const panel of group.panels) movedPanels.push({
|
|
16100
|
+
panel,
|
|
16101
|
+
from: group
|
|
16102
|
+
});
|
|
15607
16103
|
}
|
|
15608
16104
|
this.doSetGroupAndPanelActive(group);
|
|
15609
16105
|
}
|
|
15610
16106
|
disposePopoutGridview();
|
|
16107
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15611
16108
|
}
|
|
15612
16109
|
addFloatingGroup(item, options) {
|
|
15613
16110
|
this.mutation("float", () => this._doAddFloatingGroup(item, options));
|
|
@@ -15616,7 +16113,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15616
16113
|
if (!assertModule(this._floatingGroupService, "FloatingGroup", "api.addFloatingGroup")) return;
|
|
15617
16114
|
if (item instanceof DockviewGroupPanel && item.model.location.type === "edge") return;
|
|
15618
16115
|
let group;
|
|
16116
|
+
/**
|
|
16117
|
+
* Floating relocates panels exactly like a drop onto the grid does, so
|
|
16118
|
+
* it owes the caller an `onDidMovePanel` per panel. The events are
|
|
16119
|
+
* deferred until the window is mounted below: only then do the panels
|
|
16120
|
+
* report their final `floating` location.
|
|
16121
|
+
*/
|
|
16122
|
+
let movedPanels = [];
|
|
15619
16123
|
if (item instanceof DockviewPanel) {
|
|
16124
|
+
const sourceGroup = item.group;
|
|
15620
16125
|
group = this.createGroup();
|
|
15621
16126
|
this._onDidAddGroup.fire(group);
|
|
15622
16127
|
this.movingLock(() => this.removePanel(item, {
|
|
@@ -15625,6 +16130,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15625
16130
|
skipSetActiveGroup: true
|
|
15626
16131
|
}));
|
|
15627
16132
|
this.movingLock(() => group.model.openPanel(item, { skipSetGroupActive: true }));
|
|
16133
|
+
movedPanels = [{
|
|
16134
|
+
panel: item,
|
|
16135
|
+
from: sourceGroup
|
|
16136
|
+
}];
|
|
15628
16137
|
} else {
|
|
15629
16138
|
var _this$_popoutWindowSe8;
|
|
15630
16139
|
group = item;
|
|
@@ -15641,11 +16150,21 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15641
16150
|
});
|
|
15642
16151
|
this.doRemoveGroup(popoutReferenceGroup, { skipDispose: true });
|
|
15643
16152
|
group = popoutReferenceGroup;
|
|
15644
|
-
|
|
15645
|
-
|
|
15646
|
-
|
|
15647
|
-
|
|
15648
|
-
}
|
|
16153
|
+
movedPanels = group.panels.map((panel) => ({
|
|
16154
|
+
panel,
|
|
16155
|
+
from: item
|
|
16156
|
+
}));
|
|
16157
|
+
} else {
|
|
16158
|
+
this.doRemoveGroup(item, {
|
|
16159
|
+
skipDispose: true,
|
|
16160
|
+
skipPopoutReturn: true,
|
|
16161
|
+
skipPopoutAssociated: false
|
|
16162
|
+
});
|
|
16163
|
+
movedPanels = group.panels.map((panel) => ({
|
|
16164
|
+
panel,
|
|
16165
|
+
from: group
|
|
16166
|
+
}));
|
|
16167
|
+
}
|
|
15649
16168
|
}
|
|
15650
16169
|
function getAnchoredBox() {
|
|
15651
16170
|
if (options === null || options === void 0 ? void 0 : options.position) {
|
|
@@ -15678,6 +16197,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15678
16197
|
skipActiveGroup: options === null || options === void 0 ? void 0 : options.skipActiveGroup,
|
|
15679
16198
|
disableSmartGuides: options === null || options === void 0 ? void 0 : options.disableSmartGuides
|
|
15680
16199
|
});
|
|
16200
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15681
16201
|
}
|
|
15682
16202
|
/**
|
|
15683
16203
|
* Build an empty gridview configured to match the main grid's styling, for
|
|
@@ -15822,6 +16342,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15822
16342
|
position
|
|
15823
16343
|
};
|
|
15824
16344
|
group.model.headerPosition = position;
|
|
16345
|
+
const resizeDisposable = group.onDidChange((event) => {
|
|
16346
|
+
var _this$_shellManager3;
|
|
16347
|
+
if (!event) return;
|
|
16348
|
+
const size = position === "left" || position === "right" ? event.width : event.height;
|
|
16349
|
+
if (typeof size !== "number") return;
|
|
16350
|
+
(_this$_shellManager3 = this._shellManager) === null || _this$_shellManager3 === void 0 || _this$_shellManager3.resizeEdgeGroup(position, size);
|
|
16351
|
+
});
|
|
15825
16352
|
const autoCollapseDisposable = group.model.onDidRemovePanel(() => {
|
|
15826
16353
|
if (!group.model.isEmpty) return;
|
|
15827
16354
|
if (service.isAutoReveal(group)) queueMicrotask(() => {
|
|
@@ -15830,7 +16357,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15830
16357
|
});
|
|
15831
16358
|
else this.setEdgeGroupCollapsed(group, true);
|
|
15832
16359
|
});
|
|
15833
|
-
service.add(position, group, autoCollapseDisposable);
|
|
16360
|
+
service.add(position, group, new CompositeDisposable(autoCollapseDisposable, resizeDisposable));
|
|
15834
16361
|
if (options.autoHide !== void 0) service.setAutoHide(group, options.autoHide);
|
|
15835
16362
|
if (options.autoReveal !== void 0) service.setAutoReveal(group, options.autoReveal);
|
|
15836
16363
|
this._onDidAddGroup.fire(group);
|
|
@@ -15925,8 +16452,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15925
16452
|
}
|
|
15926
16453
|
/** The size an edge group expands to (pre-collapse); sizes the peek. */
|
|
15927
16454
|
getEdgeGroupExpandedSize(position) {
|
|
15928
|
-
var _this$_shellManager$g, _this$
|
|
15929
|
-
return (_this$_shellManager$g = (_this$
|
|
16455
|
+
var _this$_shellManager$g, _this$_shellManager4;
|
|
16456
|
+
return (_this$_shellManager$g = (_this$_shellManager4 = this._shellManager) === null || _this$_shellManager4 === void 0 ? void 0 : _this$_shellManager4.getEdgeGroupExpandedSize(position)) !== null && _this$_shellManager$g !== void 0 ? _this$_shellManager$g : 0;
|
|
15930
16457
|
}
|
|
15931
16458
|
/** Reposition a single `renderer:'always'` panel's overlay over its
|
|
15932
16459
|
* reference container, optionally forcing it visible (the auto-hide peek
|
|
@@ -16109,35 +16636,119 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16109
16636
|
if (typeof data !== "object" || data === null) throw new Error("dockview: serialized layout must be a non-null object");
|
|
16110
16637
|
if (!data.grid || ((_data$grid$root = data.grid.root) === null || _data$grid$root === void 0 ? void 0 : _data$grid$root.type) !== "branch" || !Array.isArray(data.grid.root.data)) throw new Error("dockview: root must be of type branch");
|
|
16111
16638
|
const existingPanels = /* @__PURE__ */ new Map();
|
|
16112
|
-
|
|
16639
|
+
const temporaryGroups = /* @__PURE__ */ new Map();
|
|
16640
|
+
const stagedPanels = [];
|
|
16641
|
+
const temporaryGroupDisposables = [];
|
|
16642
|
+
/**
|
|
16643
|
+
* The staging groups are detached from `_groups` and never enter the
|
|
16644
|
+
* grid, so nothing else will ever tear them down.
|
|
16645
|
+
*
|
|
16646
|
+
* `dispose()` reaches consumer `IContentRenderer.dispose()`, so one
|
|
16647
|
+
* throwing renderer must not abort the rest of the cleanup — that would
|
|
16648
|
+
* re-introduce the very leak this reclaims — nor replace the
|
|
16649
|
+
* deserialization error the caller is being given. Draining the list
|
|
16650
|
+
* also makes this safe to call more than once.
|
|
16651
|
+
*/
|
|
16652
|
+
const disposeTemporaryGroups = () => {
|
|
16653
|
+
for (const disposable of temporaryGroupDisposables) try {
|
|
16654
|
+
disposable.dispose();
|
|
16655
|
+
} catch (err) {
|
|
16656
|
+
console.error("dockview: failed to dispose a temporary group created for reuseExistingPanels", err);
|
|
16657
|
+
}
|
|
16658
|
+
temporaryGroupDisposables.length = 0;
|
|
16659
|
+
};
|
|
16113
16660
|
if (options === null || options === void 0 ? void 0 : options.reuseExistingPanels) {
|
|
16114
16661
|
/**
|
|
16115
|
-
*
|
|
16116
|
-
*
|
|
16117
|
-
*
|
|
16118
|
-
* 2. Remove that temporary group from the group mapping so that it doesn't get cleared when we clear the layout
|
|
16662
|
+
* Visible, always-rendered panels need individual staging groups
|
|
16663
|
+
* to remain active. Other reused panels can share a staging group.
|
|
16664
|
+
* The staging groups are excluded from the layout clear below.
|
|
16119
16665
|
*/
|
|
16120
|
-
tempGroup = this.createGroup();
|
|
16121
|
-
this._groups.delete(tempGroup.api.id);
|
|
16122
16666
|
const newPanels = Object.keys(data.panels);
|
|
16123
|
-
|
|
16124
|
-
|
|
16125
|
-
|
|
16126
|
-
|
|
16127
|
-
|
|
16128
|
-
|
|
16129
|
-
|
|
16130
|
-
|
|
16131
|
-
|
|
16132
|
-
|
|
16133
|
-
|
|
16134
|
-
|
|
16135
|
-
|
|
16667
|
+
let sharedTemporaryGroup;
|
|
16668
|
+
const createTemporaryGroup = () => {
|
|
16669
|
+
const temporaryGroup = this.createGroup();
|
|
16670
|
+
/**
|
|
16671
|
+
* Removing the group from `_groups` also drops the record's
|
|
16672
|
+
* `CompositeDisposable`, so capture it first and tear both it
|
|
16673
|
+
* and the group down in the `finally` below. Left undisposed a
|
|
16674
|
+
* staging group leaks its `ResizeObserver`, its
|
|
16675
|
+
* `onDidOptionsChange` subscription (retained by this
|
|
16676
|
+
* component's emitter) and the watermark its model mounts when
|
|
16677
|
+
* the group empties — once per reused panel, per `fromJSON`.
|
|
16678
|
+
*/
|
|
16679
|
+
const record = this._groups.get(temporaryGroup.api.id);
|
|
16680
|
+
this._groups.delete(temporaryGroup.api.id);
|
|
16681
|
+
temporaryGroupDisposables.push(Disposable.from(() => {
|
|
16682
|
+
/**
|
|
16683
|
+
* Reclaim the group's own resources, never its panels.
|
|
16684
|
+
* Staging is driven by the ids in `data.panels` while
|
|
16685
|
+
* reclaiming is driven by the group `views` that
|
|
16686
|
+
* reference them, so a panel whose state is present but
|
|
16687
|
+
* unreferenced is still staged here — and `dispose()`
|
|
16688
|
+
* on a non-empty group reaches the consumer's
|
|
16689
|
+
* `IContentRenderer.dispose()`. Emptying the group
|
|
16690
|
+
* first leaves those panels exactly as they were before
|
|
16691
|
+
* this teardown existed, which also keeps this safe
|
|
16692
|
+
* against any future path that rebuilds a panel under
|
|
16693
|
+
* an id that is live in the new layout.
|
|
16694
|
+
*/
|
|
16695
|
+
this.movingLock(() => {
|
|
16696
|
+
for (const panel of temporaryGroup.panels.slice()) temporaryGroup.model.removePanel(panel);
|
|
16697
|
+
});
|
|
16698
|
+
record === null || record === void 0 || record.disposable.dispose();
|
|
16699
|
+
temporaryGroup.dispose();
|
|
16700
|
+
}));
|
|
16701
|
+
return temporaryGroup;
|
|
16702
|
+
};
|
|
16703
|
+
/**
|
|
16704
|
+
* Staging and the clear below run before the deserialization
|
|
16705
|
+
* `try`, so a throw here (a consumer `onDidRemovePanel` handler, a
|
|
16706
|
+
* renderer teardown during `clear`) would escape without reclaiming
|
|
16707
|
+
* the staging groups already created.
|
|
16708
|
+
*
|
|
16709
|
+
* The creation loop is inside the guard too, not just the moves and
|
|
16710
|
+
* the clear: `createGroup()` reaches consumer code of its own —
|
|
16711
|
+
* `initialize()` mounts the watermark through
|
|
16712
|
+
* `createWatermarkComponent()` — so a throw on the n-th panel would
|
|
16713
|
+
* otherwise strand the n-1 staging groups already built.
|
|
16714
|
+
*/
|
|
16715
|
+
try {
|
|
16716
|
+
for (const panel of this.panels) if (newPanels.includes(panel.api.id)) {
|
|
16717
|
+
existingPanels.set(panel.api.id, panel);
|
|
16718
|
+
let temporaryGroup;
|
|
16719
|
+
if (panel.api.renderer === "always" && panel.api.isVisible) temporaryGroup = createTemporaryGroup();
|
|
16720
|
+
else {
|
|
16721
|
+
var _sharedTemporaryGroup;
|
|
16722
|
+
(_sharedTemporaryGroup = sharedTemporaryGroup) !== null && _sharedTemporaryGroup !== void 0 || (sharedTemporaryGroup = createTemporaryGroup());
|
|
16723
|
+
temporaryGroup = sharedTemporaryGroup;
|
|
16724
|
+
}
|
|
16725
|
+
temporaryGroups.set(panel.api.id, temporaryGroup);
|
|
16726
|
+
stagedPanels.push({
|
|
16727
|
+
panel,
|
|
16728
|
+
temporaryGroup
|
|
16729
|
+
});
|
|
16730
|
+
}
|
|
16731
|
+
this.movingLock(() => {
|
|
16732
|
+
stagedPanels.forEach(({ panel, temporaryGroup }) => {
|
|
16733
|
+
this.moveGroupOrPanel({
|
|
16734
|
+
from: {
|
|
16735
|
+
groupId: panel.api.group.api.id,
|
|
16736
|
+
panelId: panel.api.id
|
|
16737
|
+
},
|
|
16738
|
+
to: {
|
|
16739
|
+
group: temporaryGroup,
|
|
16740
|
+
position: "center"
|
|
16741
|
+
},
|
|
16742
|
+
keepEmptyGroups: true
|
|
16743
|
+
});
|
|
16136
16744
|
});
|
|
16137
16745
|
});
|
|
16138
|
-
|
|
16139
|
-
|
|
16140
|
-
|
|
16746
|
+
this.clear();
|
|
16747
|
+
} catch (err) {
|
|
16748
|
+
disposeTemporaryGroups();
|
|
16749
|
+
throw err;
|
|
16750
|
+
}
|
|
16751
|
+
} else this.clear();
|
|
16141
16752
|
const { grid, panels, activeGroup } = data;
|
|
16142
16753
|
try {
|
|
16143
16754
|
var _data$floatingGroups, _data$popoutGroups, _this$_popoutWindowSe12, _this$_floatingGroupS5, _this$_watermarkServi2;
|
|
@@ -16169,9 +16780,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16169
16780
|
* due to a corruption of input data.
|
|
16170
16781
|
*/
|
|
16171
16782
|
const existingPanel = existingPanels.get(child);
|
|
16172
|
-
|
|
16783
|
+
const temporaryGroup = temporaryGroups.get(child);
|
|
16784
|
+
if (temporaryGroup && existingPanel) {
|
|
16173
16785
|
this.movingLock(() => {
|
|
16174
|
-
|
|
16786
|
+
temporaryGroup.model.removePanel(existingPanel);
|
|
16175
16787
|
});
|
|
16176
16788
|
createdPanels.push(existingPanel);
|
|
16177
16789
|
existingPanel.updateFromStateModel(panels[child]);
|
|
@@ -16201,7 +16813,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16201
16813
|
return createGroupFromSerializedState(node.data);
|
|
16202
16814
|
} });
|
|
16203
16815
|
this._layoutFromShell(width, height);
|
|
16204
|
-
if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels);
|
|
16816
|
+
if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels, existingPanels, temporaryGroups);
|
|
16205
16817
|
this.deserializeFloatingWindows((_data$floatingGroups = data.floatingGroups) !== null && _data$floatingGroups !== void 0 ? _data$floatingGroups : [], createGroupFromSerializedState);
|
|
16206
16818
|
const popoutPromises = this.deserializePopoutWindows((_data$popoutGroups = data.popoutGroups) !== null && _data$popoutGroups !== void 0 ? _data$popoutGroups : [], createGroupFromSerializedState);
|
|
16207
16819
|
(_this$_popoutWindowSe12 = this._popoutWindowService) === null || _this$_popoutWindowSe12 === void 0 || _this$_popoutWindowSe12.finishRestoration(popoutPromises);
|
|
@@ -16238,6 +16850,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16238
16850
|
* expect trying to load a corrupted layout to result in an error and not silently fail...
|
|
16239
16851
|
*/
|
|
16240
16852
|
throw err;
|
|
16853
|
+
} finally {
|
|
16854
|
+
disposeTemporaryGroups();
|
|
16241
16855
|
}
|
|
16242
16856
|
this.debouncedUpdateAllPositions();
|
|
16243
16857
|
this._onDidLayoutFromJSON.fire();
|
|
@@ -16260,7 +16874,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16260
16874
|
members
|
|
16261
16875
|
};
|
|
16262
16876
|
}
|
|
16263
|
-
deserializeEdgeGroups(edgeGroups, panels) {
|
|
16877
|
+
deserializeEdgeGroups(edgeGroups, panels, existingPanels, temporaryGroups) {
|
|
16264
16878
|
const edgeService = assertModule(this._edgeGroupService, "EdgeGroup", "fromJSON edge restoration");
|
|
16265
16879
|
if (!edgeService) return;
|
|
16266
16880
|
for (const _position of [
|
|
@@ -16290,13 +16904,40 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16290
16904
|
if (groupState) {
|
|
16291
16905
|
const { views, activeView } = groupState;
|
|
16292
16906
|
const createdPanels = [];
|
|
16293
|
-
for (const panelId of views)
|
|
16294
|
-
|
|
16295
|
-
|
|
16907
|
+
for (const panelId of views) {
|
|
16908
|
+
if (!panels[panelId]) continue;
|
|
16909
|
+
/**
|
|
16910
|
+
* Reclaim a staged panel rather than rebuilding it, the
|
|
16911
|
+
* same way the grid path does. Deserializing here instead
|
|
16912
|
+
* would honour `reuseExistingPanels` everywhere except edge
|
|
16913
|
+
* groups: the live panel keeps sitting in its staging group
|
|
16914
|
+
* while a second panel is built under the same id, so the
|
|
16915
|
+
* consumer's renderer for the original is orphaned — never
|
|
16916
|
+
* disposed, and its element left inside the id-keyed
|
|
16917
|
+
* overlay entry the replacement now shares.
|
|
16918
|
+
*/
|
|
16919
|
+
const existingPanel = existingPanels.get(panelId);
|
|
16920
|
+
const temporaryGroup = temporaryGroups.get(panelId);
|
|
16921
|
+
if (temporaryGroup && existingPanel) {
|
|
16922
|
+
this.movingLock(() => {
|
|
16923
|
+
temporaryGroup.model.removePanel(existingPanel);
|
|
16924
|
+
});
|
|
16925
|
+
createdPanels.push(existingPanel);
|
|
16926
|
+
existingPanel.updateFromStateModel(panels[panelId]);
|
|
16927
|
+
} else {
|
|
16928
|
+
const panel = this._deserializer.fromJSON(panels[panelId], edgeGroup);
|
|
16929
|
+
createdPanels.push(panel);
|
|
16930
|
+
}
|
|
16296
16931
|
}
|
|
16297
16932
|
for (const panel of createdPanels) {
|
|
16298
16933
|
const isActive = activeView === panel.id;
|
|
16299
|
-
|
|
16934
|
+
if (existingPanels.has(panel.api.id)) this.movingLock(() => {
|
|
16935
|
+
edgeGroup.model.openPanel(panel, {
|
|
16936
|
+
skipSetActive: !isActive,
|
|
16937
|
+
skipSetGroupActive: true
|
|
16938
|
+
});
|
|
16939
|
+
});
|
|
16940
|
+
else edgeGroup.model.openPanel(panel, {
|
|
16300
16941
|
skipSetActive: !isActive,
|
|
16301
16942
|
skipSetGroupActive: true
|
|
16302
16943
|
});
|
|
@@ -16720,22 +17361,100 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16720
17361
|
* outermost mutation.
|
|
16721
17362
|
*/
|
|
16722
17363
|
mutation(kind, func) {
|
|
16723
|
-
const
|
|
17364
|
+
const close = this.openMutation(kind);
|
|
17365
|
+
try {
|
|
17366
|
+
return func();
|
|
17367
|
+
} finally {
|
|
17368
|
+
close();
|
|
17369
|
+
}
|
|
17370
|
+
}
|
|
17371
|
+
/**
|
|
17372
|
+
* `mutation()` for an operation whose work continues after the synchronous
|
|
17373
|
+
* call returns. The transaction stays open until the returned promise
|
|
17374
|
+
* settles, so everything the operation does - the group it adds, the panels
|
|
17375
|
+
* it relocates - lands inside the bracket, matching the synchronous
|
|
17376
|
+
* move / float paths.
|
|
17377
|
+
*/
|
|
17378
|
+
mutationAsync(kind, func) {
|
|
17379
|
+
var _this = this;
|
|
17380
|
+
return _asyncToGenerator(function* () {
|
|
17381
|
+
const close = _this.openMutation(kind);
|
|
17382
|
+
try {
|
|
17383
|
+
return yield func();
|
|
17384
|
+
} finally {
|
|
17385
|
+
close();
|
|
17386
|
+
}
|
|
17387
|
+
})();
|
|
17388
|
+
}
|
|
17389
|
+
/**
|
|
17390
|
+
* Open a transaction and return the function that closes it. Shared by the
|
|
17391
|
+
* synchronous and asynchronous brackets; the returned function must be
|
|
17392
|
+
* called exactly once.
|
|
17393
|
+
*
|
|
17394
|
+
* Both ends key off the depth counter reaching zero rather than off which
|
|
17395
|
+
* bracket opened first. For synchronous nesting the two are the same thing
|
|
17396
|
+
* - brackets close in the order they opened - but asynchronous transactions
|
|
17397
|
+
* can *overlap* rather than nest (two `addPopoutGroup` calls in flight at
|
|
17398
|
+
* once, or a restore staggering several), and there the first to open is
|
|
17399
|
+
* not the last to close. Reporting on the opener would fire `didMutate`
|
|
17400
|
+
* while the other transaction was still doing structural work, which is the
|
|
17401
|
+
* very thing the async bracket exists to prevent. Overlapping transactions
|
|
17402
|
+
* therefore report as one, tagged with the kind of the last to finish.
|
|
17403
|
+
*/
|
|
17404
|
+
openMutation(kind) {
|
|
16724
17405
|
const origin = this._origin;
|
|
16725
|
-
if (
|
|
17406
|
+
if (this._mutationDepth === 0) this._onWillMutateLayout.fire({
|
|
16726
17407
|
kind,
|
|
16727
17408
|
origin
|
|
16728
17409
|
});
|
|
16729
17410
|
this._mutationDepth++;
|
|
16730
|
-
|
|
16731
|
-
return func();
|
|
16732
|
-
} finally {
|
|
17411
|
+
return () => {
|
|
16733
17412
|
this._mutationDepth--;
|
|
16734
|
-
if (
|
|
16735
|
-
|
|
16736
|
-
|
|
16737
|
-
|
|
17413
|
+
if (this._mutationDepth === 0) {
|
|
17414
|
+
this.flushLocationChanges();
|
|
17415
|
+
this._onDidMutateLayout.fire({
|
|
17416
|
+
kind,
|
|
17417
|
+
origin
|
|
17418
|
+
});
|
|
17419
|
+
}
|
|
17420
|
+
};
|
|
17421
|
+
}
|
|
17422
|
+
/**
|
|
17423
|
+
* Coalesce a panel's `onDidLocationChange` to the end of the enclosing
|
|
17424
|
+
* transaction, or fire it immediately when no transaction is in flight.
|
|
17425
|
+
*
|
|
17426
|
+
* Relocating a panel touches its location twice: once as it is reparented
|
|
17427
|
+
* into the destination group - which, when that group has just been created
|
|
17428
|
+
* for a floating or popout window, has not been told where it lives yet -
|
|
17429
|
+
* and once as the group is tagged with its final location. Reporting each
|
|
17430
|
+
* signal as it happens therefore leaks an intermediate `grid` location the
|
|
17431
|
+
* panel was never in, at a moment when it belongs to neither group's panel
|
|
17432
|
+
* list and so is missing from `api.panels`.
|
|
17433
|
+
*
|
|
17434
|
+
* Deferring collapses those signals into a single event carrying the
|
|
17435
|
+
* settled location. Note the signals are deliberately *not* compared
|
|
17436
|
+
* against the panel's previous location: a panel can move between two
|
|
17437
|
+
* floating windows without its location type changing, and this event is
|
|
17438
|
+
* the only signal `OverlayRenderContainer` has to re-resolve the panel's
|
|
17439
|
+
* z-index against its new host window.
|
|
17440
|
+
*/
|
|
17441
|
+
deferLocationChange(key, fire) {
|
|
17442
|
+
if (this._mutationDepth === 0) {
|
|
17443
|
+
fire();
|
|
17444
|
+
return;
|
|
16738
17445
|
}
|
|
17446
|
+
this._pendingLocationChanges.set(key, fire);
|
|
17447
|
+
}
|
|
17448
|
+
/**
|
|
17449
|
+
* Report every panel whose location moved during the transaction that has
|
|
17450
|
+
* just closed. Each callback reads the panel's location at this point, so
|
|
17451
|
+
* what it reports is where the panel ended up.
|
|
17452
|
+
*/
|
|
17453
|
+
flushLocationChanges() {
|
|
17454
|
+
if (this._pendingLocationChanges.size === 0) return;
|
|
17455
|
+
const pending = Array.from(this._pendingLocationChanges.values());
|
|
17456
|
+
this._pendingLocationChanges.clear();
|
|
17457
|
+
for (const fire of pending) fire();
|
|
16739
17458
|
}
|
|
16740
17459
|
/**
|
|
16741
17460
|
* The origin of the operation currently in progress (`'user'` by default).
|
|
@@ -16776,6 +17495,18 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16776
17495
|
origin: this._origin
|
|
16777
17496
|
});
|
|
16778
17497
|
}
|
|
17498
|
+
/**
|
|
17499
|
+
* Announce that `panel` has finished relocating. Must be called once the
|
|
17500
|
+
* move has settled: `to` is read from the panel's current group, so an
|
|
17501
|
+
* early call would report the source group as the destination.
|
|
17502
|
+
*/
|
|
17503
|
+
fireDidMovePanel(panel, from) {
|
|
17504
|
+
this._onDidMovePanel.fire({
|
|
17505
|
+
panel,
|
|
17506
|
+
from,
|
|
17507
|
+
to: panel.group
|
|
17508
|
+
});
|
|
17509
|
+
}
|
|
16779
17510
|
moveGroupOrPanel(options) {
|
|
16780
17511
|
this.mutation("move", () => this._doMoveGroupOrPanel(options));
|
|
16781
17512
|
}
|
|
@@ -16836,10 +17567,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16836
17567
|
});
|
|
16837
17568
|
});
|
|
16838
17569
|
if (!options.skipSetActive) this.doSetGroupAndPanelActive(destinationGroup);
|
|
16839
|
-
this.
|
|
16840
|
-
panel: removedPanel,
|
|
16841
|
-
from: sourceGroup
|
|
16842
|
-
});
|
|
17570
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
16843
17571
|
} else {
|
|
16844
17572
|
/**
|
|
16845
17573
|
* Dropping a panel to the extremities of a group which will place that panel
|
|
@@ -16858,10 +17586,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16858
17586
|
const [sourceParentLocation, from] = tail(getGridLocation(sourceGroup.element));
|
|
16859
17587
|
if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
|
|
16860
17588
|
this.gridview.moveView(sourceParentLocation, from, to);
|
|
16861
|
-
this.
|
|
16862
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
16863
|
-
from: sourceGroup
|
|
16864
|
-
});
|
|
17589
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
16865
17590
|
return;
|
|
16866
17591
|
}
|
|
16867
17592
|
}
|
|
@@ -16889,13 +17614,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16889
17614
|
}));
|
|
16890
17615
|
this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
16891
17616
|
const updatedTargetLocation = getRelativeLocation(destinationGridview.orientation, getGridLocation(destinationGroup.element), destinationTarget);
|
|
16892
|
-
const newGroup = this.createGroupAtLocation(updatedTargetLocation,
|
|
17617
|
+
const newGroup = this.createGroupAtLocation(updatedTargetLocation, this.dropSizing(getGridLocation(destinationGroup.element)), void 0, destinationGridview);
|
|
16893
17618
|
this.movingLock(() => newGroup.model.openPanel(removedPanel, { skipSetActive: true }));
|
|
16894
17619
|
this.doSetGroupAndPanelActive(newGroup);
|
|
16895
|
-
this.
|
|
16896
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
16897
|
-
from: sourceGroup
|
|
16898
|
-
});
|
|
17620
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
16899
17621
|
return;
|
|
16900
17622
|
}
|
|
16901
17623
|
if (sourceGroup.api.location.type === "edge") {
|
|
@@ -16909,13 +17631,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16909
17631
|
skipSetActiveGroup: true
|
|
16910
17632
|
}));
|
|
16911
17633
|
if (!removedPanel) throw new Error(`dockview: No panel with id ${sourceItemId}`);
|
|
16912
|
-
const newGroup = this.createGroupAtLocation(targetLocation,
|
|
17634
|
+
const newGroup = this.createGroupAtLocation(targetLocation, this.dropSizing(referenceLocation), void 0, destinationGridview);
|
|
16913
17635
|
this.movingLock(() => newGroup.model.openPanel(removedPanel, { skipSetGroupActive: true }));
|
|
16914
17636
|
this.doSetGroupAndPanelActive(newGroup);
|
|
16915
|
-
this.
|
|
16916
|
-
panel: removedPanel,
|
|
16917
|
-
from: sourceGroup
|
|
16918
|
-
});
|
|
17637
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
16919
17638
|
return;
|
|
16920
17639
|
}
|
|
16921
17640
|
const targetGroup = this.movingLock(() => this.doRemoveGroup(sourceGroup, {
|
|
@@ -16924,13 +17643,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16924
17643
|
}));
|
|
16925
17644
|
const updatedReferenceLocation = getGridLocation(destinationGroup.element);
|
|
16926
17645
|
const location = getRelativeLocation(destinationGridview.orientation, updatedReferenceLocation, destinationTarget);
|
|
16927
|
-
this.movingLock(() => this.doAddGroup(targetGroup, location,
|
|
17646
|
+
this.movingLock(() => this.doAddGroup(targetGroup, location, this.dropSizing(updatedReferenceLocation), destinationGridview));
|
|
16928
17647
|
this.setGroupLocationForRoot(targetGroup, destinationGridview);
|
|
16929
17648
|
this.doSetGroupAndPanelActive(targetGroup);
|
|
16930
|
-
this.
|
|
16931
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
16932
|
-
from: sourceGroup
|
|
16933
|
-
});
|
|
17649
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
16934
17650
|
} else {
|
|
16935
17651
|
/**
|
|
16936
17652
|
* The group we are removing from has many panels, we need to remove the panels we are moving,
|
|
@@ -16942,13 +17658,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16942
17658
|
}));
|
|
16943
17659
|
if (!removedPanel) throw new Error(`dockview: No panel with id ${sourceItemId}`);
|
|
16944
17660
|
const dropLocation = getRelativeLocation(destinationGridview.orientation, referenceLocation, destinationTarget);
|
|
16945
|
-
const group = this.createGroupAtLocation(dropLocation,
|
|
17661
|
+
const group = this.createGroupAtLocation(dropLocation, this.dropSizing(referenceLocation), void 0, destinationGridview);
|
|
16946
17662
|
this.movingLock(() => group.model.openPanel(removedPanel, { skipSetGroupActive: true }));
|
|
16947
17663
|
this.doSetGroupAndPanelActive(group);
|
|
16948
|
-
this.
|
|
16949
|
-
panel: removedPanel,
|
|
16950
|
-
from: sourceGroup
|
|
16951
|
-
});
|
|
17664
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
16952
17665
|
}
|
|
16953
17666
|
}
|
|
16954
17667
|
}
|
|
@@ -16983,16 +17696,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16983
17696
|
});
|
|
16984
17697
|
for (const panel of removedPanels) targetGroup.model.addPanelToTabGroup(newTabGroup.id, panel.id);
|
|
16985
17698
|
if (!options.skipSetActive) this.doSetGroupAndPanelActive(targetGroup);
|
|
16986
|
-
for (const panel of removedPanels) this.
|
|
16987
|
-
panel,
|
|
16988
|
-
from: sourceGroup
|
|
16989
|
-
});
|
|
17699
|
+
for (const panel of removedPanels) this.fireDidMovePanel(panel, sourceGroup);
|
|
16990
17700
|
};
|
|
16991
17701
|
let targetGroup;
|
|
16992
17702
|
if (!destinationTarget || destinationTarget === "center" || !referenceLocation) targetGroup = destinationGroup;
|
|
16993
17703
|
else {
|
|
16994
17704
|
const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
|
|
16995
|
-
targetGroup = this.createGroupAtLocation(dropLocation);
|
|
17705
|
+
targetGroup = this.createGroupAtLocation(dropLocation, this.dropSizing(referenceLocation));
|
|
16996
17706
|
}
|
|
16997
17707
|
if (!options.keepEmptyGroups && sourceGroup.model.size === 0 && sourceGroup !== targetGroup) this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
16998
17708
|
addPanelsToGroup(targetGroup);
|
|
@@ -17007,10 +17717,12 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17007
17717
|
this.mutation("maximize", () => super.exitMaximizedGroup());
|
|
17008
17718
|
}
|
|
17009
17719
|
_doMoveGroup(options) {
|
|
17720
|
+
var _mergedPanels;
|
|
17010
17721
|
const from = options.from.group;
|
|
17011
17722
|
const to = options.to.group;
|
|
17012
17723
|
const target = options.to.position;
|
|
17013
17724
|
let source = from;
|
|
17725
|
+
let mergedPanels;
|
|
17014
17726
|
if (target === "center") {
|
|
17015
17727
|
const activePanel = from.activePanel;
|
|
17016
17728
|
const tabGroupSnapshots = from.model.getTabGroups().map((tg) => ({
|
|
@@ -17028,6 +17740,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17028
17740
|
skipSetGroupActive: true
|
|
17029
17741
|
});
|
|
17030
17742
|
});
|
|
17743
|
+
mergedPanels = panels;
|
|
17031
17744
|
for (const snapshot of tabGroupSnapshots) {
|
|
17032
17745
|
const newTabGroup = to.model.createTabGroup({
|
|
17033
17746
|
label: snapshot.label,
|
|
@@ -17040,6 +17753,21 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17040
17753
|
if (options.skipSetActive !== true) this.doSetGroupAndPanelActive(to);
|
|
17041
17754
|
else if (!this.activePanel) this.doSetGroupAndPanelActive(to);
|
|
17042
17755
|
} else {
|
|
17756
|
+
const isReorderWithinBranch = (() => {
|
|
17757
|
+
if (from.api.location.type === "edge" || to.api.location.type === "edge") return false;
|
|
17758
|
+
const root = this.getGridviewForGroup(from);
|
|
17759
|
+
if (root !== this.getGridviewForGroup(to)) return false;
|
|
17760
|
+
let fromLocation;
|
|
17761
|
+
let toLocation;
|
|
17762
|
+
try {
|
|
17763
|
+
fromLocation = getGridLocation(from.element);
|
|
17764
|
+
toLocation = getGridLocation(to.element);
|
|
17765
|
+
} catch (_unused) {
|
|
17766
|
+
return false;
|
|
17767
|
+
}
|
|
17768
|
+
if (fromLocation.length === 0 || toLocation.length === 0) return false;
|
|
17769
|
+
return sequenceEquals(tail(fromLocation)[0], tail(toLocation)[0]) && getLocationOrientation(root.orientation, toLocation) === getDirectionOrientation(target);
|
|
17770
|
+
})();
|
|
17043
17771
|
if (from.api.location.type === "edge") {
|
|
17044
17772
|
/**
|
|
17045
17773
|
* Edge groups are permanent structural elements and must
|
|
@@ -17105,23 +17833,17 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17105
17833
|
const referenceLocation = getGridLocation(to.element);
|
|
17106
17834
|
const dropLocation = getRelativeLocation(destGridview.orientation, referenceLocation, target);
|
|
17107
17835
|
let size;
|
|
17108
|
-
|
|
17109
|
-
|
|
17110
|
-
|
|
17111
|
-
|
|
17112
|
-
case "HORIZONTAL":
|
|
17113
|
-
size = referenceLocation.length % 2 == 0 ? from.api.height : from.api.width;
|
|
17114
|
-
break;
|
|
17836
|
+
if (isReorderWithinBranch) size = getDirectionOrientation(target) === "HORIZONTAL" ? from.api.width : from.api.height;
|
|
17837
|
+
else {
|
|
17838
|
+
var _referenceLocation;
|
|
17839
|
+
size = Sizing.Split((_referenceLocation = referenceLocation[referenceLocation.length - 1]) !== null && _referenceLocation !== void 0 ? _referenceLocation : 0);
|
|
17115
17840
|
}
|
|
17116
17841
|
destGridview.addView(source, size, dropLocation);
|
|
17117
17842
|
this.setGroupLocationForRoot(source, destGridview);
|
|
17118
17843
|
}
|
|
17119
17844
|
}
|
|
17120
|
-
source.panels.forEach((panel) => {
|
|
17121
|
-
this.
|
|
17122
|
-
panel,
|
|
17123
|
-
from
|
|
17124
|
-
});
|
|
17845
|
+
((_mergedPanels = mergedPanels) !== null && _mergedPanels !== void 0 ? _mergedPanels : source.panels).forEach((panel) => {
|
|
17846
|
+
this.fireDidMovePanel(panel, from);
|
|
17125
17847
|
});
|
|
17126
17848
|
this.debouncedUpdateAllPositions();
|
|
17127
17849
|
if (options.skipSetActive === false) {
|
|
@@ -17239,6 +17961,16 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17239
17961
|
});
|
|
17240
17962
|
return panel;
|
|
17241
17963
|
}
|
|
17964
|
+
/**
|
|
17965
|
+
* Sizing for a group created by a drop next to `referenceLocation`: half
|
|
17966
|
+
* of the group the overlay was drawn over, leaving its siblings alone, so
|
|
17967
|
+
* the panel lands in the region the overlay indicated (#1612). Gridview
|
|
17968
|
+
* rewrites the index to 0 when a cross-axis drop wraps the reference in a
|
|
17969
|
+
* new branch, so one value serves both paths.
|
|
17970
|
+
*/
|
|
17971
|
+
dropSizing(referenceLocation) {
|
|
17972
|
+
return Sizing.Split(referenceLocation.length === 0 ? 0 : referenceLocation[referenceLocation.length - 1]);
|
|
17973
|
+
}
|
|
17242
17974
|
createGroupAtLocation(location, size, options, gridview = this.gridview) {
|
|
17243
17975
|
const group = this.createGroup(options);
|
|
17244
17976
|
this.doAddGroup(group, location, size, gridview);
|
|
@@ -17298,22 +18030,22 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17298
18030
|
return location.length % 2 == 1 ? rootOrientation : orthogonal(rootOrientation);
|
|
17299
18031
|
}
|
|
17300
18032
|
updateTheme() {
|
|
17301
|
-
var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe23, _this$_popoutWindowSe24, _this$
|
|
18033
|
+
var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe23, _this$_popoutWindowSe24, _this$_shellManager5, _theme$edgeGroupColla, _theme$tabGroupIndica;
|
|
17302
18034
|
const theme = (_this$_options$theme = this._options.theme) !== null && _this$_options$theme !== void 0 ? _this$_options$theme : themeAbyss;
|
|
17303
18035
|
(_this$_shellThemeClas = this._shellThemeClassnames) === null || _this$_shellThemeClas === void 0 || _this$_shellThemeClas.setClassNames(theme.className);
|
|
17304
18036
|
const gap = (_theme$gap = theme.gap) !== null && _theme$gap !== void 0 ? _theme$gap : 0;
|
|
17305
18037
|
this.gridview.margin = gap;
|
|
17306
18038
|
for (const floating of this.floatingGroups) floating.gridview.margin = gap;
|
|
17307
18039
|
for (const entry of (_this$_popoutWindowSe23 = (_this$_popoutWindowSe24 = this._popoutWindowService) === null || _this$_popoutWindowSe24 === void 0 ? void 0 : _this$_popoutWindowSe24.entries) !== null && _this$_popoutWindowSe23 !== void 0 ? _this$_popoutWindowSe23 : []) entry.gridview.margin = gap;
|
|
17308
|
-
(_this$
|
|
18040
|
+
(_this$_shellManager5 = this._shellManager) === null || _this$_shellManager5 === void 0 || _this$_shellManager5.updateTheme(gap, (_theme$edgeGroupColla = theme.edgeGroupCollapsedSize) !== null && _theme$edgeGroupColla !== void 0 ? _theme$edgeGroupColla : 35);
|
|
17309
18041
|
if (theme.dndOverlayBorder === void 0) {
|
|
17310
|
-
var _this$
|
|
18042
|
+
var _this$_shellManager6;
|
|
17311
18043
|
this.element.style.removeProperty("--dv-drag-over-border");
|
|
17312
|
-
(_this$
|
|
18044
|
+
(_this$_shellManager6 = this._shellManager) === null || _this$_shellManager6 === void 0 || _this$_shellManager6.element.style.removeProperty("--dv-drag-over-border");
|
|
17313
18045
|
} else {
|
|
17314
|
-
var _this$
|
|
18046
|
+
var _this$_shellManager7;
|
|
17315
18047
|
this.element.style.setProperty("--dv-drag-over-border", theme.dndOverlayBorder);
|
|
17316
|
-
(_this$
|
|
18048
|
+
(_this$_shellManager7 = this._shellManager) === null || _this$_shellManager7 === void 0 || _this$_shellManager7.element.style.setProperty("--dv-drag-over-border", theme.dndOverlayBorder);
|
|
17317
18049
|
}
|
|
17318
18050
|
switch (theme.dndOverlayMounting) {
|
|
17319
18051
|
case "absolute":
|
|
@@ -18198,6 +18930,8 @@ exports.AdvancedDnDModule = AdvancedDnDModule;
|
|
|
18198
18930
|
exports.AdvancedDnDService = AdvancedDnDService;
|
|
18199
18931
|
exports.BaseGrid = BaseGrid;
|
|
18200
18932
|
exports.ContentContainer = ContentContainer;
|
|
18933
|
+
exports.ContextMenuController = ContextMenuController;
|
|
18934
|
+
exports.ContextMenuModule = ContextMenuModule;
|
|
18201
18935
|
exports.DEFAULT_TAB_GROUP_COLORS = DEFAULT_TAB_GROUP_COLORS;
|
|
18202
18936
|
exports.DefaultDockviewDeserialzier = DefaultDockviewDeserialzier;
|
|
18203
18937
|
exports.DefaultTab = DefaultTab;
|