dockview-core 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/cjs/api/dockviewGroupPanelApi.d.ts +7 -0
- package/dist/cjs/api/dockviewPanelApi.d.ts +12 -0
- package/dist/cjs/dnd/dropTargetAnchorContainer.d.ts +6 -0
- package/dist/cjs/dockview/components/titlebar/tabReorderController.d.ts +8 -0
- package/dist/cjs/dockview/contextMenuService.d.ts +62 -0
- package/dist/cjs/dockview/dockviewComponent.d.ts +70 -0
- package/dist/cjs/dockview/dockviewShell.d.ts +15 -0
- package/dist/cjs/dockview/modules.d.ts +2 -2
- package/dist/cjs/dockview/optionsModules.d.ts +3 -4
- package/dist/cjs/gridview/baseComponentGridview.d.ts +2 -2
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/overlay/overlayRenderContainer.d.ts +13 -1
- package/dist/dockview-core.js +922 -185
- package/dist/dockview-core.min.js +2 -2
- package/dist/dockview-core.min.noStyle.js +2 -2
- package/dist/dockview-core.noStyle.js +922 -185
- package/dist/package/main.cjs.js +922 -185
- package/dist/package/main.cjs.min.js +2 -2
- package/dist/package/main.esm.min.mjs +2 -2
- package/dist/package/main.esm.mjs +921 -186
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dockview-core
|
|
3
|
-
* @version 8.
|
|
3
|
+
* @version 8.3.0
|
|
4
4
|
* @link https://github.com/dockview/dockview
|
|
5
5
|
* @license MIT
|
|
6
6
|
*/
|
|
@@ -1048,8 +1048,14 @@ var Splitview = class {
|
|
|
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: () => {
|
|
@@ -5794,7 +5800,7 @@ function resolveDndCapabilities(options) {
|
|
|
5794
5800
|
};
|
|
5795
5801
|
case "auto":
|
|
5796
5802
|
case void 0:
|
|
5797
|
-
default: return isCoarsePrimaryInput$
|
|
5803
|
+
default: return isCoarsePrimaryInput$2() ? {
|
|
5798
5804
|
html5: false,
|
|
5799
5805
|
pointer: true,
|
|
5800
5806
|
pointerHandlesMouse: true
|
|
@@ -5805,7 +5811,7 @@ function resolveDndCapabilities(options) {
|
|
|
5805
5811
|
};
|
|
5806
5812
|
}
|
|
5807
5813
|
}
|
|
5808
|
-
function isCoarsePrimaryInput$
|
|
5814
|
+
function isCoarsePrimaryInput$2() {
|
|
5809
5815
|
if (globalThis.window === void 0 || !globalThis.matchMedia) return false;
|
|
5810
5816
|
const coarse = globalThis.matchMedia("(pointer: coarse)").matches;
|
|
5811
5817
|
const fine = globalThis.matchMedia("(pointer: fine)").matches;
|
|
@@ -7960,11 +7966,28 @@ var TabReorderController = class extends CompositeDisposable {
|
|
|
7960
7966
|
if (this._voidContainer && related && (related === this._voidContainer || this._voidContainer.contains(related))) return;
|
|
7961
7967
|
this.resetTabTransforms();
|
|
7962
7968
|
if (this._animState.sourceIndex === -1) {
|
|
7963
|
-
|
|
7964
|
-
(_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();
|
|
7969
|
+
this.clearHeaderAnchorOverlay();
|
|
7965
7970
|
this._animState = null;
|
|
7966
7971
|
} else this._animState.currentInsertionIndex = null;
|
|
7967
7972
|
}
|
|
7973
|
+
/**
|
|
7974
|
+
* Clear the anchored overlay only when this header is what rendered it.
|
|
7975
|
+
* The container is shared with the group's content drop target, which
|
|
7976
|
+
* renders into it on the same frame the cursor leaves the strip: the
|
|
7977
|
+
* pointer backend calls `handleDragOver` on the new target before the
|
|
7978
|
+
* global `onDragMove` that reaches us (#1612).
|
|
7979
|
+
*/
|
|
7980
|
+
clearHeaderAnchorOverlay() {
|
|
7981
|
+
var _container$model;
|
|
7982
|
+
const container = this.group.model.dropTargetContainer;
|
|
7983
|
+
const outline = container === null || container === void 0 ? void 0 : container.renderedOutline;
|
|
7984
|
+
if (outline && ![
|
|
7985
|
+
this._tabsList,
|
|
7986
|
+
this._voidContainer,
|
|
7987
|
+
this._extendedDropZone
|
|
7988
|
+
].some((scope) => scope === null || scope === void 0 ? void 0 : scope.contains(outline))) return;
|
|
7989
|
+
container === null || container === void 0 || (_container$model = container.model) === null || _container$model === void 0 || _container$model.clear();
|
|
7990
|
+
}
|
|
7968
7991
|
handleDragOver(event) {
|
|
7969
7992
|
var _this$accessor$option2;
|
|
7970
7993
|
if (!this._animState) return;
|
|
@@ -10520,7 +10543,11 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
|
|
|
10520
10543
|
this.panels.forEach((panel) => {
|
|
10521
10544
|
this.rerender(panel);
|
|
10522
10545
|
});
|
|
10523
|
-
if (this._activePanel)
|
|
10546
|
+
if (this._activePanel) {
|
|
10547
|
+
this.contentContainer.renderPanel(this._activePanel, { asActive: true });
|
|
10548
|
+
const { width, height } = this.contentDimensions();
|
|
10549
|
+
this._activePanel.layout(width, height);
|
|
10550
|
+
}
|
|
10524
10551
|
}
|
|
10525
10552
|
get renderContainer() {
|
|
10526
10553
|
var _this$_overwriteRende;
|
|
@@ -11485,7 +11512,7 @@ var DockviewPanelApiImpl = class extends GridviewPanelApiImpl {
|
|
|
11485
11512
|
this._group = value;
|
|
11486
11513
|
this._onDidGroupChange.fire({});
|
|
11487
11514
|
this.setupGroupEventListeners(oldGroup);
|
|
11488
|
-
this.
|
|
11515
|
+
this.fireLocationChange();
|
|
11489
11516
|
}
|
|
11490
11517
|
}
|
|
11491
11518
|
get group() {
|
|
@@ -11561,6 +11588,23 @@ var DockviewPanelApiImpl = class extends GridviewPanelApiImpl {
|
|
|
11561
11588
|
exitMaximized() {
|
|
11562
11589
|
this.group.api.exitMaximized();
|
|
11563
11590
|
}
|
|
11591
|
+
/**
|
|
11592
|
+
* Report that this panel's location may have moved.
|
|
11593
|
+
*
|
|
11594
|
+
* A relocation touches the location more than once - the panel is
|
|
11595
|
+
* reparented into the destination group, then that group is tagged with
|
|
11596
|
+
* the location it ends up at - so the event is coalesced to the end of the
|
|
11597
|
+
* enclosing layout mutation and reports where the panel actually settled.
|
|
11598
|
+
* Firing each signal as it happened surfaced an intermediate `grid`
|
|
11599
|
+
* location the panel was never in, at a point where it was in neither
|
|
11600
|
+
* group's panel list. Outside a mutation this fires straight away.
|
|
11601
|
+
*/
|
|
11602
|
+
fireLocationChange() {
|
|
11603
|
+
this.accessor.deferLocationChange(this, () => {
|
|
11604
|
+
if (this.isDisposed) return;
|
|
11605
|
+
this._onDidLocationChange.fire({ location: this.location });
|
|
11606
|
+
});
|
|
11607
|
+
}
|
|
11564
11608
|
setupGroupEventListeners(previousGroup) {
|
|
11565
11609
|
var _previousGroup$isActi;
|
|
11566
11610
|
let _trackGroupActive = (_previousGroup$isActi = previousGroup === null || previousGroup === void 0 ? void 0 : previousGroup.isActive) !== null && _previousGroup$isActi !== void 0 ? _previousGroup$isActi : false;
|
|
@@ -11569,9 +11613,9 @@ var DockviewPanelApiImpl = class extends GridviewPanelApiImpl {
|
|
|
11569
11613
|
const hasBecomeVisible = event.isVisible && !this.isVisible;
|
|
11570
11614
|
const isActivePanel = this.group.model.isPanelActive(this.panel);
|
|
11571
11615
|
if (hasBecomeHidden || hasBecomeVisible && isActivePanel) this._onDidVisibilityChange.fire(event);
|
|
11572
|
-
}), this.group.api.onDidLocationChange((
|
|
11616
|
+
}), this.group.api.onDidLocationChange(() => {
|
|
11573
11617
|
if (this.group !== this.panel.group) return;
|
|
11574
|
-
this.
|
|
11618
|
+
this.fireLocationChange();
|
|
11575
11619
|
}), this.group.api.onDidActiveChange(() => {
|
|
11576
11620
|
if (this.group !== this.panel.group) return;
|
|
11577
11621
|
if (_trackGroupActive !== this.isGroupActive) {
|
|
@@ -12373,7 +12417,6 @@ const ENTERPRISE_MODULE_NAMES = /* @__PURE__ */ new Set([
|
|
|
12373
12417
|
"AdvancedOverflow",
|
|
12374
12418
|
"AutoEdgeGroup",
|
|
12375
12419
|
"AutoHideEdgeGroup",
|
|
12376
|
-
"ContextMenu",
|
|
12377
12420
|
"DndCompass",
|
|
12378
12421
|
"KeyboardDocking",
|
|
12379
12422
|
"KeyboardNavigation",
|
|
@@ -12455,8 +12498,8 @@ function logMissingModule(moduleName, reason) {
|
|
|
12455
12498
|
* case: calling `undo()` having never set the option at all.
|
|
12456
12499
|
*
|
|
12457
12500
|
* Interaction handlers are queries in this sense too: a right-click reaching an
|
|
12458
|
-
* absent
|
|
12459
|
-
*
|
|
12501
|
+
* absent module means the app never asked for that feature, so it stays silent
|
|
12502
|
+
* (`?.`) and the browser's own behaviour applies. Options are where intent is
|
|
12460
12503
|
* declared; see `optionsModules.ts`.
|
|
12461
12504
|
*/
|
|
12462
12505
|
function assertModule(service, moduleName, context) {
|
|
@@ -12536,10 +12579,9 @@ function clearRegisteredModules() {
|
|
|
12536
12579
|
*
|
|
12537
12580
|
* This is the "declared intent" diagnostic. It fires when the user asks for a
|
|
12538
12581
|
* feature via options, at construction and on every `updateOptions`. It
|
|
12539
|
-
* deliberately does *not* fire on user interaction:
|
|
12540
|
-
*
|
|
12541
|
-
*
|
|
12542
|
-
* app never wanted.
|
|
12582
|
+
* deliberately does *not* fire on user interaction: an interaction reaching an
|
|
12583
|
+
* absent module stays silent, because the `?.` service-slot call sites can't
|
|
12584
|
+
* tell a missing module from a feature the app never wanted.
|
|
12543
12585
|
*
|
|
12544
12586
|
* Rules are a flat list rather than a `Record<keyof DockviewOptions, ...>`
|
|
12545
12587
|
* because dockview's options are nested and value-gated: `overflow.mode:
|
|
@@ -12635,18 +12677,6 @@ const OPTION_MODULE_RULES = [
|
|
|
12635
12677
|
moduleName: "AutoEdgeGroup",
|
|
12636
12678
|
when: (o) => isAnyEdgeGroupEnabled(o.dockToEdgeGroups)
|
|
12637
12679
|
},
|
|
12638
|
-
{
|
|
12639
|
-
optionKey: "getTabContextMenuItems",
|
|
12640
|
-
reason: "getTabContextMenuItems",
|
|
12641
|
-
moduleName: "ContextMenu",
|
|
12642
|
-
when: (o) => o.getTabContextMenuItems != null
|
|
12643
|
-
},
|
|
12644
|
-
{
|
|
12645
|
-
optionKey: "getTabGroupChipContextMenuItems",
|
|
12646
|
-
reason: "getTabGroupChipContextMenuItems",
|
|
12647
|
-
moduleName: "ContextMenu",
|
|
12648
|
-
when: (o) => o.getTabGroupChipContextMenuItems != null
|
|
12649
|
-
},
|
|
12650
12680
|
{
|
|
12651
12681
|
optionKey: "dndCompass",
|
|
12652
12682
|
reason: "dndCompass",
|
|
@@ -13547,6 +13577,270 @@ const TabGroupChipsModule = defineModule({
|
|
|
13547
13577
|
}
|
|
13548
13578
|
});
|
|
13549
13579
|
|
|
13580
|
+
//#endregion
|
|
13581
|
+
//#region src/dockview/contextMenuService.ts
|
|
13582
|
+
function popoverZIndexFor(target, group) {
|
|
13583
|
+
var _group$api, _group$api$isPeeking;
|
|
13584
|
+
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)";
|
|
13585
|
+
if (!(target instanceof HTMLElement)) return;
|
|
13586
|
+
const relativeParent = findRelativeZIndexParent(target);
|
|
13587
|
+
return (relativeParent === null || relativeParent === void 0 ? void 0 : relativeParent.style.zIndex) ? `calc(${relativeParent.style.zIndex} * 2)` : void 0;
|
|
13588
|
+
}
|
|
13589
|
+
let _nextId = 0;
|
|
13590
|
+
const nextContextMenuItemId = () => `dv-ctx-menu-item-${_nextId++}`;
|
|
13591
|
+
function isItemConfig(item) {
|
|
13592
|
+
return typeof item === "object";
|
|
13593
|
+
}
|
|
13594
|
+
function buildItem(label, close, action, disabled) {
|
|
13595
|
+
const el = document.createElement("div");
|
|
13596
|
+
el.className = "dv-context-menu-item";
|
|
13597
|
+
el.setAttribute("role", "menuitem");
|
|
13598
|
+
if (disabled) {
|
|
13599
|
+
el.classList.add("dv-context-menu-item--disabled");
|
|
13600
|
+
el.setAttribute("aria-disabled", "true");
|
|
13601
|
+
}
|
|
13602
|
+
el.textContent = label;
|
|
13603
|
+
if (!disabled) el.addEventListener("click", () => {
|
|
13604
|
+
action();
|
|
13605
|
+
close();
|
|
13606
|
+
});
|
|
13607
|
+
return el;
|
|
13608
|
+
}
|
|
13609
|
+
function buildSeparator() {
|
|
13610
|
+
const el = document.createElement("div");
|
|
13611
|
+
el.className = "dv-context-menu-separator";
|
|
13612
|
+
el.setAttribute("role", "separator");
|
|
13613
|
+
return el;
|
|
13614
|
+
}
|
|
13615
|
+
function isCoarsePrimaryInput$1() {
|
|
13616
|
+
if (globalThis.window === void 0 || !globalThis.matchMedia) return false;
|
|
13617
|
+
const coarse = globalThis.matchMedia("(pointer: coarse)").matches;
|
|
13618
|
+
const fine = globalThis.matchMedia("(pointer: fine)").matches;
|
|
13619
|
+
return coarse && !fine;
|
|
13620
|
+
}
|
|
13621
|
+
function buildRenameInput(tabGroup) {
|
|
13622
|
+
const wrapper = document.createElement("div");
|
|
13623
|
+
wrapper.className = "dv-context-menu-rename";
|
|
13624
|
+
const input = document.createElement("input");
|
|
13625
|
+
input.className = "dv-context-menu-rename-input";
|
|
13626
|
+
input.type = "text";
|
|
13627
|
+
input.placeholder = "Name This Group";
|
|
13628
|
+
input.value = tabGroup.label;
|
|
13629
|
+
input.addEventListener("input", () => {
|
|
13630
|
+
tabGroup.setLabel(input.value);
|
|
13631
|
+
});
|
|
13632
|
+
input.addEventListener("keydown", (e) => {
|
|
13633
|
+
if (e.key !== "Escape" && e.key !== "Enter") e.stopPropagation();
|
|
13634
|
+
});
|
|
13635
|
+
input.addEventListener("click", (e) => {
|
|
13636
|
+
e.stopPropagation();
|
|
13637
|
+
});
|
|
13638
|
+
wrapper.appendChild(input);
|
|
13639
|
+
if (!isCoarsePrimaryInput$1()) requestAnimationFrame(() => {
|
|
13640
|
+
input.focus();
|
|
13641
|
+
input.select();
|
|
13642
|
+
});
|
|
13643
|
+
return wrapper;
|
|
13644
|
+
}
|
|
13645
|
+
function buildColorPicker(tabGroup, palette) {
|
|
13646
|
+
const wrapper = document.createElement("div");
|
|
13647
|
+
wrapper.className = "dv-context-menu-color-picker";
|
|
13648
|
+
if (!palette.enabled) return wrapper;
|
|
13649
|
+
for (const entry of palette.entries()) {
|
|
13650
|
+
const swatch = document.createElement("div");
|
|
13651
|
+
swatch.className = "dv-context-menu-color-swatch";
|
|
13652
|
+
swatch.style.setProperty("--dv-tab-group-color", entry.value);
|
|
13653
|
+
if (entry.label) swatch.title = entry.label;
|
|
13654
|
+
if (tabGroup.color === entry.id) swatch.classList.add("dv-context-menu-color-swatch--selected");
|
|
13655
|
+
swatch.addEventListener("click", () => {
|
|
13656
|
+
tabGroup.setColor(entry.id);
|
|
13657
|
+
});
|
|
13658
|
+
wrapper.appendChild(swatch);
|
|
13659
|
+
}
|
|
13660
|
+
return wrapper;
|
|
13661
|
+
}
|
|
13662
|
+
var ContextMenuController = class {
|
|
13663
|
+
constructor(accessor) {
|
|
13664
|
+
this.accessor = accessor;
|
|
13665
|
+
}
|
|
13666
|
+
/**
|
|
13667
|
+
* A single maximize/restore toggle whose label and behaviour track the
|
|
13668
|
+
* group's live state: it reads *Restore* + calls `exitMaximized` when the
|
|
13669
|
+
* group is maximized, otherwise *Maximize* + `maximize`. Only grid groups
|
|
13670
|
+
* can be maximized, so the item is disabled for floating / popout panels
|
|
13671
|
+
* that are not already maximized.
|
|
13672
|
+
*/
|
|
13673
|
+
buildMaximizeItem(panel, close) {
|
|
13674
|
+
const isMaximized = panel.api.isMaximized();
|
|
13675
|
+
return buildItem(isMaximized ? "Restore" : "Maximize", close, isMaximized ? () => panel.api.exitMaximized() : () => panel.api.maximize(), !isMaximized && panel.api.location.type !== "grid");
|
|
13676
|
+
}
|
|
13677
|
+
/**
|
|
13678
|
+
* A single collapse/expand toggle whose label tracks the tab group's live
|
|
13679
|
+
* state: *Expand* when the group is already collapsed, otherwise *Collapse*.
|
|
13680
|
+
*/
|
|
13681
|
+
buildCollapseItem(tabGroup, close) {
|
|
13682
|
+
return buildItem(tabGroup.collapsed ? "Expand" : "Collapse", close, () => tabGroup.toggle());
|
|
13683
|
+
}
|
|
13684
|
+
/**
|
|
13685
|
+
* Whether to auto-inject the built-in Pin/Unpin item at the top of the tab
|
|
13686
|
+
* menu. True only when the PinnedTabs module is registered, pinning is
|
|
13687
|
+
* enabled, and the app has not opted out via `pinnedTabs.contextMenuItem:
|
|
13688
|
+
* false` (the item is on by default). This keeps pinning reachable from the
|
|
13689
|
+
* menu without the app having to return `'pin'` from
|
|
13690
|
+
* `getTabContextMenuItems` itself.
|
|
13691
|
+
*/
|
|
13692
|
+
_shouldInjectPin() {
|
|
13693
|
+
const pinnedTabs = this.accessor.options.pinnedTabs;
|
|
13694
|
+
return !!this.accessor.pinnedTabsService && !!(pinnedTabs === null || pinnedTabs === void 0 ? void 0 : pinnedTabs.enabled) && pinnedTabs.contextMenuItem !== false;
|
|
13695
|
+
}
|
|
13696
|
+
/**
|
|
13697
|
+
* The tab menu items: the app's own items (if any) with the built-in
|
|
13698
|
+
* `'pin'` item prepended when {@link _shouldInjectPin} applies, so the app
|
|
13699
|
+
* keeps full control of its list, and pinning is added without disturbing
|
|
13700
|
+
* it. Reuses the existing `'pin'` token rendering below.
|
|
13701
|
+
*/
|
|
13702
|
+
_resolveTabItems(panel, group, event) {
|
|
13703
|
+
var _this$accessor$option, _this$accessor$option2, _this$accessor$option3;
|
|
13704
|
+
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, {
|
|
13705
|
+
panel,
|
|
13706
|
+
group,
|
|
13707
|
+
api: this.accessor.api,
|
|
13708
|
+
event
|
|
13709
|
+
})) !== null && _this$accessor$option !== void 0 ? _this$accessor$option : [];
|
|
13710
|
+
return this._shouldInjectPin() ? ["pin", ...appItems] : appItems;
|
|
13711
|
+
}
|
|
13712
|
+
/**
|
|
13713
|
+
* Render a custom `component` menu item and append it to `menuEl`. Builds
|
|
13714
|
+
* the framework renderer via the host's `createContextMenuItemComponent`
|
|
13715
|
+
* factory and initialises it. Shared by the tab menu and the chip menu,
|
|
13716
|
+
* which differ only in `identity`: the tab menu passes the `panel`, the chip
|
|
13717
|
+
* menu passes the `tabGroup`. No-op when no renderer could be created (no
|
|
13718
|
+
* factory configured, or the factory declined the component).
|
|
13719
|
+
*/
|
|
13720
|
+
appendComponentItem(menuEl, item, identity, group, close) {
|
|
13721
|
+
var _this$accessor$option4, _this$accessor$option5;
|
|
13722
|
+
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, {
|
|
13723
|
+
id: nextContextMenuItemId(),
|
|
13724
|
+
component: item.component
|
|
13725
|
+
});
|
|
13726
|
+
if (!renderer) return;
|
|
13727
|
+
renderer.init(_objectSpread2(_objectSpread2({}, identity), {}, {
|
|
13728
|
+
group,
|
|
13729
|
+
api: this.accessor.api,
|
|
13730
|
+
close,
|
|
13731
|
+
componentProps: item.componentProps
|
|
13732
|
+
}));
|
|
13733
|
+
menuEl.appendChild(renderer.element);
|
|
13734
|
+
}
|
|
13735
|
+
/**
|
|
13736
|
+
* The element for one built-in tab item, or `undefined` for a token this
|
|
13737
|
+
* version doesn't know (an app on a newer typings version, or plain JS):
|
|
13738
|
+
* an unrecognised token renders nothing rather than throwing.
|
|
13739
|
+
*/
|
|
13740
|
+
buildBuiltInTabItem(item, panel, group, close) {
|
|
13741
|
+
switch (item) {
|
|
13742
|
+
case "separator": return buildSeparator();
|
|
13743
|
+
case "close": return buildItem("Close", close, () => panel.api.close());
|
|
13744
|
+
case "closeOthers": return buildItem("Close Others", close, () => {
|
|
13745
|
+
group.panels.filter((p) => p !== panel).forEach((p) => p.api.close());
|
|
13746
|
+
});
|
|
13747
|
+
case "closeAll": return buildItem("Close All", close, () => {
|
|
13748
|
+
[...group.panels].forEach((p) => p.api.close());
|
|
13749
|
+
});
|
|
13750
|
+
case "closeLeft": {
|
|
13751
|
+
const index = group.panels.indexOf(panel);
|
|
13752
|
+
return buildItem("Close to the Left", close, () => {
|
|
13753
|
+
group.panels.filter((_, i) => i < index).forEach((p) => p.api.close());
|
|
13754
|
+
}, index <= 0);
|
|
13755
|
+
}
|
|
13756
|
+
case "closeRight": {
|
|
13757
|
+
const index = group.panels.indexOf(panel);
|
|
13758
|
+
return buildItem("Close to the Right", close, () => {
|
|
13759
|
+
group.panels.filter((_, i) => i > index).forEach((p) => p.api.close());
|
|
13760
|
+
}, index === -1 || index >= group.panels.length - 1);
|
|
13761
|
+
}
|
|
13762
|
+
case "maximize": return this.buildMaximizeItem(panel, close);
|
|
13763
|
+
case "float": return buildItem("Float", close, () => this.accessor.api.addFloatingGroup(panel), panel.api.location.type === "floating");
|
|
13764
|
+
case "popout": return buildItem("Open in New Window", close, () => {
|
|
13765
|
+
this.accessor.api.addPopoutGroup(panel);
|
|
13766
|
+
}, panel.api.location.type === "popout");
|
|
13767
|
+
case "pin": return buildItem(panel.api.isPinned ? "Unpin tab" : "Pin tab", close, () => panel.api.setPinned(!panel.api.isPinned));
|
|
13768
|
+
default: return;
|
|
13769
|
+
}
|
|
13770
|
+
}
|
|
13771
|
+
/**
|
|
13772
|
+
* Append one app-supplied item. A raw `element` is used as-is, a
|
|
13773
|
+
* `component` goes through the framework renderer, and a `label` builds the
|
|
13774
|
+
* default row; an item carrying none of the three renders nothing. Shared
|
|
13775
|
+
* by both menus, which differ only in `identity`.
|
|
13776
|
+
*/
|
|
13777
|
+
appendConfigItem(menuEl, item, identity, group, close) {
|
|
13778
|
+
if (item.element) menuEl.appendChild(item.element);
|
|
13779
|
+
else if (item.component) this.appendComponentItem(menuEl, item, identity, group, close);
|
|
13780
|
+
else if (item.label) menuEl.appendChild(buildItem(item.label, close, () => {
|
|
13781
|
+
var _item$action;
|
|
13782
|
+
return (_item$action = item.action) === null || _item$action === void 0 ? void 0 : _item$action.call(item);
|
|
13783
|
+
}, item.disabled));
|
|
13784
|
+
}
|
|
13785
|
+
show(panel, group, event) {
|
|
13786
|
+
const items = this._resolveTabItems(panel, group, event);
|
|
13787
|
+
if (items.length === 0) return;
|
|
13788
|
+
event.preventDefault();
|
|
13789
|
+
const popupService = this.accessor.getPopupServiceForGroup(group);
|
|
13790
|
+
const close = () => popupService.close();
|
|
13791
|
+
const menuEl = document.createElement("div");
|
|
13792
|
+
menuEl.className = "dv-context-menu";
|
|
13793
|
+
menuEl.setAttribute("role", "menu");
|
|
13794
|
+
for (const item of items) {
|
|
13795
|
+
if (isItemConfig(item)) {
|
|
13796
|
+
this.appendConfigItem(menuEl, item, { panel }, group, close);
|
|
13797
|
+
continue;
|
|
13798
|
+
}
|
|
13799
|
+
const el = this.buildBuiltInTabItem(item, panel, group, close);
|
|
13800
|
+
if (el) menuEl.appendChild(el);
|
|
13801
|
+
}
|
|
13802
|
+
popupService.openPopover(menuEl, {
|
|
13803
|
+
x: event.clientX,
|
|
13804
|
+
y: event.clientY,
|
|
13805
|
+
zIndex: popoverZIndexFor(event.target, group)
|
|
13806
|
+
});
|
|
13807
|
+
}
|
|
13808
|
+
showForChip(tabGroup, group, event) {
|
|
13809
|
+
if (!this.accessor.options.getTabGroupChipContextMenuItems) return;
|
|
13810
|
+
const items = this.accessor.options.getTabGroupChipContextMenuItems({
|
|
13811
|
+
tabGroup,
|
|
13812
|
+
group,
|
|
13813
|
+
api: this.accessor.api,
|
|
13814
|
+
event
|
|
13815
|
+
});
|
|
13816
|
+
if (items.length === 0) return;
|
|
13817
|
+
event.preventDefault();
|
|
13818
|
+
const popupService = this.accessor.getPopupServiceForGroup(group);
|
|
13819
|
+
const close = () => popupService.close();
|
|
13820
|
+
const menuEl = document.createElement("div");
|
|
13821
|
+
menuEl.className = "dv-context-menu";
|
|
13822
|
+
menuEl.setAttribute("role", "menu");
|
|
13823
|
+
for (const item of items) if (item === "separator") menuEl.appendChild(buildSeparator());
|
|
13824
|
+
else if (item === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
|
|
13825
|
+
else if (item === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
|
|
13826
|
+
else if (item === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
|
|
13827
|
+
else if (item === "close") menuEl.appendChild(buildItem("Close All", close, () => {
|
|
13828
|
+
group.panels.filter((p) => tabGroup.containsPanel(p.id)).forEach((p) => p.api.close());
|
|
13829
|
+
}));
|
|
13830
|
+
else if (isItemConfig(item)) this.appendConfigItem(menuEl, item, { tabGroup }, group, close);
|
|
13831
|
+
popupService.openPopover(menuEl, {
|
|
13832
|
+
x: event.clientX,
|
|
13833
|
+
y: event.clientY,
|
|
13834
|
+
zIndex: popoverZIndexFor(event.target, group)
|
|
13835
|
+
});
|
|
13836
|
+
}
|
|
13837
|
+
};
|
|
13838
|
+
const ContextMenuModule = defineModule({
|
|
13839
|
+
name: "ContextMenu",
|
|
13840
|
+
serviceKey: "contextMenuService",
|
|
13841
|
+
create: (host) => new ContextMenuController(host)
|
|
13842
|
+
});
|
|
13843
|
+
|
|
13550
13844
|
//#endregion
|
|
13551
13845
|
//#region src/dockview/allModules.ts
|
|
13552
13846
|
/**
|
|
@@ -13564,7 +13858,8 @@ const AllModules = [
|
|
|
13564
13858
|
HeaderActionsModule,
|
|
13565
13859
|
LiveRegionModule,
|
|
13566
13860
|
AdvancedDnDModule,
|
|
13567
|
-
TabGroupChipsModule
|
|
13861
|
+
TabGroupChipsModule,
|
|
13862
|
+
ContextMenuModule
|
|
13568
13863
|
];
|
|
13569
13864
|
|
|
13570
13865
|
//#endregion
|
|
@@ -13597,6 +13892,13 @@ var PositionCache = class {
|
|
|
13597
13892
|
});
|
|
13598
13893
|
}
|
|
13599
13894
|
};
|
|
13895
|
+
/**
|
|
13896
|
+
* Placeholder handle marking "a reposition frame has been requested but the
|
|
13897
|
+
* real handle is not known yet". Never passed to `cancelAnimationFrame` in
|
|
13898
|
+
* practice — it is replaced within the same synchronous block — and harmless
|
|
13899
|
+
* if it were, since no frame carries this id.
|
|
13900
|
+
*/
|
|
13901
|
+
const SCHEDULED = -1;
|
|
13600
13902
|
function createFocusableElement() {
|
|
13601
13903
|
const element = document.createElement("div");
|
|
13602
13904
|
element.tabIndex = -1;
|
|
@@ -13609,12 +13911,13 @@ var OverlayRenderContainer = class extends CompositeDisposable {
|
|
|
13609
13911
|
this.accessor = accessor;
|
|
13610
13912
|
this.map = {};
|
|
13611
13913
|
this._disposed = false;
|
|
13914
|
+
this._generation = 0;
|
|
13612
13915
|
this.positionCache = new PositionCache();
|
|
13613
|
-
this.pendingUpdates = /* @__PURE__ */ new Set();
|
|
13614
13916
|
this.addDisposables(Disposable.from(() => {
|
|
13615
13917
|
for (const value of Object.values(this.map)) {
|
|
13616
13918
|
value.disposable.dispose();
|
|
13617
13919
|
value.destroy.dispose();
|
|
13920
|
+
this.cancelPendingUpdate(value);
|
|
13618
13921
|
}
|
|
13619
13922
|
this._disposed = true;
|
|
13620
13923
|
}));
|
|
@@ -13641,11 +13944,24 @@ var OverlayRenderContainer = class extends CompositeDisposable {
|
|
|
13641
13944
|
this.positionCache.invalidate();
|
|
13642
13945
|
(_entry$resize = entry.resize) === null || _entry$resize === void 0 || _entry$resize.call(entry);
|
|
13643
13946
|
}
|
|
13947
|
+
/**
|
|
13948
|
+
* Drop the reposition frame queued for a panel, if any. A queued frame is
|
|
13949
|
+
* bound to the reference container that was current when it was scheduled,
|
|
13950
|
+
* so it must be discarded whenever that container stops being the one the
|
|
13951
|
+
* overlay should track.
|
|
13952
|
+
*/
|
|
13953
|
+
cancelPendingUpdate(entry) {
|
|
13954
|
+
if (entry.pendingUpdate !== void 0) {
|
|
13955
|
+
cancelAnimationFrame(entry.pendingUpdate);
|
|
13956
|
+
entry.pendingUpdate = void 0;
|
|
13957
|
+
}
|
|
13958
|
+
}
|
|
13644
13959
|
detatch(panel) {
|
|
13645
13960
|
if (this.map[panel.api.id]) {
|
|
13646
|
-
const
|
|
13647
|
-
disposable.dispose();
|
|
13648
|
-
destroy.dispose();
|
|
13961
|
+
const entry = this.map[panel.api.id];
|
|
13962
|
+
entry.disposable.dispose();
|
|
13963
|
+
entry.destroy.dispose();
|
|
13964
|
+
this.cancelPendingUpdate(entry);
|
|
13649
13965
|
delete this.map[panel.api.id];
|
|
13650
13966
|
return true;
|
|
13651
13967
|
}
|
|
@@ -13661,22 +13977,73 @@ var OverlayRenderContainer = class extends CompositeDisposable {
|
|
|
13661
13977
|
panel,
|
|
13662
13978
|
disposable: Disposable.NONE,
|
|
13663
13979
|
destroy: Disposable.NONE,
|
|
13664
|
-
element
|
|
13980
|
+
element,
|
|
13981
|
+
retainPreviousGeometry: false,
|
|
13982
|
+
positioned: false,
|
|
13983
|
+
generation: ++this._generation
|
|
13665
13984
|
};
|
|
13666
13985
|
}
|
|
13667
|
-
const
|
|
13986
|
+
const mapEntry = this.map[panel.api.id];
|
|
13987
|
+
/**
|
|
13988
|
+
* A *change* of reference container supersedes the previous `attach`:
|
|
13989
|
+
* take a fresh generation so its `resize` closure can no longer run,
|
|
13990
|
+
* and drop the frame it queued against the old container. During
|
|
13991
|
+
* `fromJSON({ reuseExistingPanels: true })` that old container is a
|
|
13992
|
+
* detached staging group measuring 0x0, so leaving its frame in flight
|
|
13993
|
+
* both wastes the update and delays the reposition against the real one.
|
|
13994
|
+
*
|
|
13995
|
+
* Re-attaching over the *same* container (re-open, active panel change)
|
|
13996
|
+
* deliberately leaves scheduled work alone: `repositionPanelOverlay`
|
|
13997
|
+
* (the auto-hide peek) schedules a frame carrying the sticky
|
|
13998
|
+
* `forceVisible`/`clip` state which `attach` does not re-apply, and a
|
|
13999
|
+
* peeked panel's `api.isVisible` is false — so discarding that frame
|
|
14000
|
+
* leaves `visibilityChanged` to hide the overlay and the peek renders
|
|
14001
|
+
* nothing. A newly created entry already holds a fresh generation, so
|
|
14002
|
+
* the stale closures a `detatch` left behind are fenced off either way.
|
|
14003
|
+
*/
|
|
14004
|
+
if (mapEntry.referenceContainer !== referenceContainer) {
|
|
14005
|
+
mapEntry.generation = ++this._generation;
|
|
14006
|
+
this.cancelPendingUpdate(mapEntry);
|
|
14007
|
+
mapEntry.referenceContainer = referenceContainer;
|
|
14008
|
+
/**
|
|
14009
|
+
* Arm the retain flag only here: it means "a replacement reference
|
|
14010
|
+
* container is awaiting layout", so the 0x0 early-return below
|
|
14011
|
+
* holds the last good box rather than blanking the panel mid-move.
|
|
14012
|
+
* Arming it on every re-attach instead would make a container that
|
|
14013
|
+
* genuinely collapses to zero keep its stale geometry forever.
|
|
14014
|
+
*
|
|
14015
|
+
* Gated on `positioned` because an overlay that has never been
|
|
14016
|
+
* positioned has no left/top/width/height, and `.dv-render-overlay`
|
|
14017
|
+
* defaults to 100%/100% — retaining "previous" geometry there would
|
|
14018
|
+
* pin the content over the whole container.
|
|
14019
|
+
*/
|
|
14020
|
+
mapEntry.retainPreviousGeometry = mapEntry.positioned;
|
|
14021
|
+
}
|
|
14022
|
+
const generation = mapEntry.generation;
|
|
14023
|
+
const focusContainer = mapEntry.element;
|
|
13668
14024
|
const contentElement = panel.view.content.element;
|
|
13669
14025
|
if (contentElement.parentElement !== focusContainer) focusContainer.appendChild(contentElement);
|
|
13670
14026
|
if (focusContainer.parentElement !== this.element) this.element.appendChild(focusContainer);
|
|
13671
14027
|
const resize = () => {
|
|
13672
14028
|
const panelId = panel.api.id;
|
|
13673
|
-
|
|
13674
|
-
|
|
13675
|
-
|
|
14029
|
+
const scheduling = this.map[panelId];
|
|
14030
|
+
if ((scheduling === null || scheduling === void 0 ? void 0 : scheduling.generation) !== generation) return;
|
|
14031
|
+
if (scheduling.pendingUpdate !== void 0) return;
|
|
14032
|
+
/**
|
|
14033
|
+
* Claim the slot *before* scheduling. `requestAnimationFrame` is
|
|
14034
|
+
* shimmed to run inline by some hosts (and by several suites here),
|
|
14035
|
+
* in which case the callback below clears `pendingUpdate` while
|
|
14036
|
+
* this call is still on the stack — assigning the handle afterwards
|
|
14037
|
+
* would resurrect a slot that is already spent and block every
|
|
14038
|
+
* later reposition. The sentinel is replaced by the real handle
|
|
14039
|
+
* only if the frame has not already run.
|
|
14040
|
+
*/
|
|
14041
|
+
scheduling.pendingUpdate = SCHEDULED;
|
|
14042
|
+
const handle = requestAnimationFrame(() => {
|
|
13676
14043
|
var _entry$forceVisible;
|
|
13677
|
-
this.pendingUpdates.delete(panelId);
|
|
13678
14044
|
const entry = this.map[panelId];
|
|
13679
|
-
if (
|
|
14045
|
+
if (entry) entry.pendingUpdate = void 0;
|
|
14046
|
+
if (this.isDisposed || (entry === null || entry === void 0 ? void 0 : entry.generation) !== generation) return;
|
|
13680
14047
|
const forceVisible = (_entry$forceVisible = entry.forceVisible) !== null && _entry$forceVisible !== void 0 ? _entry$forceVisible : false;
|
|
13681
14048
|
const clip = entry.clip;
|
|
13682
14049
|
const box = this.positionCache.getPosition(referenceContainer.element);
|
|
@@ -13685,6 +14052,15 @@ var OverlayRenderContainer = class extends CompositeDisposable {
|
|
|
13685
14052
|
const top = box.top - box2.top;
|
|
13686
14053
|
const width = box.width;
|
|
13687
14054
|
const height = box.height;
|
|
14055
|
+
if (entry.retainPreviousGeometry && (width === 0 || height === 0)) {
|
|
14056
|
+
if (!panel.api.isVisible && !forceVisible) {
|
|
14057
|
+
focusContainer.style.visibility = "hidden";
|
|
14058
|
+
focusContainer.style.pointerEvents = "none";
|
|
14059
|
+
}
|
|
14060
|
+
return;
|
|
14061
|
+
}
|
|
14062
|
+
entry.retainPreviousGeometry = false;
|
|
14063
|
+
entry.positioned = true;
|
|
13688
14064
|
focusContainer.style.left = `${left}px`;
|
|
13689
14065
|
focusContainer.style.top = `${top}px`;
|
|
13690
14066
|
focusContainer.style.width = `${width}px`;
|
|
@@ -13713,11 +14089,30 @@ var OverlayRenderContainer = class extends CompositeDisposable {
|
|
|
13713
14089
|
} else focusContainer.style.clipPath = "";
|
|
13714
14090
|
toggleClass(focusContainer, "dv-render-overlay-float", panel.group.api.location.type === "floating");
|
|
13715
14091
|
});
|
|
14092
|
+
if (scheduling.pendingUpdate === SCHEDULED) scheduling.pendingUpdate = handle;
|
|
13716
14093
|
};
|
|
13717
14094
|
const visibilityChanged = () => {
|
|
13718
14095
|
if (panel.api.isVisible) {
|
|
14096
|
+
var _this$map$panel$api$i;
|
|
13719
14097
|
this.positionCache.invalidate();
|
|
13720
14098
|
resize();
|
|
14099
|
+
/**
|
|
14100
|
+
* Existing geometry is safe to show while its replacement lays
|
|
14101
|
+
* out. `retainPreviousGeometry` is only set when geometry has
|
|
14102
|
+
* actually been written (see `attach`), so this can never
|
|
14103
|
+
* un-hide an overlay whose left/top/width/height are unset —
|
|
14104
|
+
* `.dv-render-overlay` is 100%/100% by default and would
|
|
14105
|
+
* otherwise cover the whole dock.
|
|
14106
|
+
*
|
|
14107
|
+
* The retained geometry is the panel's position in the previous
|
|
14108
|
+
* layout, so restoring a layout that moves the panel does paint
|
|
14109
|
+
* it at stale coordinates until the reposition lands. That is
|
|
14110
|
+
* bounded to the next frame now that a superseded `attach` can
|
|
14111
|
+
* no longer swallow the reposition (see `attach`); showing
|
|
14112
|
+
* stale-but-real geometry for a frame is the deliberate
|
|
14113
|
+
* trade-off against blanking the panel for the whole rebuild.
|
|
14114
|
+
*/
|
|
14115
|
+
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 = "";
|
|
13721
14116
|
focusContainer.style.pointerEvents = "";
|
|
13722
14117
|
} else {
|
|
13723
14118
|
focusContainer.style.visibility = "hidden";
|
|
@@ -13940,7 +14335,17 @@ var PopoutWindow = class extends CompositeDisposable {
|
|
|
13940
14335
|
window: externalWindow
|
|
13941
14336
|
});
|
|
13942
14337
|
return new Promise((resolve, reject) => {
|
|
13943
|
-
externalWindow.addEventListener("unload", (
|
|
14338
|
+
externalWindow.addEventListener("unload", () => {});
|
|
14339
|
+
/**
|
|
14340
|
+
* `load` is the only event that resolves this promise with a
|
|
14341
|
+
* container, so a window that goes away first would leave the
|
|
14342
|
+
* caller awaiting a promise that never settles - and
|
|
14343
|
+
* `addPopoutGroup` holds its layout transaction open until it does.
|
|
14344
|
+
* Settle with `null` on close, the same signal a blocked popup
|
|
14345
|
+
* gives and one the caller already handles. `resolve` after the
|
|
14346
|
+
* fact is a no-op, so a `load` that arrived first still wins.
|
|
14347
|
+
*/
|
|
14348
|
+
disposable.addDisposables(_this.onWillClose(() => resolve(null)));
|
|
13944
14349
|
externalWindow.addEventListener("load", () => {
|
|
13945
14350
|
/**
|
|
13946
14351
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
|
|
@@ -14146,6 +14551,14 @@ var PopupService = class extends CompositeDisposable {
|
|
|
14146
14551
|
//#endregion
|
|
14147
14552
|
//#region src/dnd/dropTargetAnchorContainer.ts
|
|
14148
14553
|
var DropTargetAnchorContainer = class extends CompositeDisposable {
|
|
14554
|
+
/**
|
|
14555
|
+
* The element the live overlay was rendered for, `undefined` when nothing
|
|
14556
|
+
* is showing. The container is shared by every drop target, so a caller
|
|
14557
|
+
* tearing down only its own overlay must check this before `clear()`.
|
|
14558
|
+
*/
|
|
14559
|
+
get renderedOutline() {
|
|
14560
|
+
return this._model ? this._outline : void 0;
|
|
14561
|
+
}
|
|
14149
14562
|
get disabled() {
|
|
14150
14563
|
return this._disabled;
|
|
14151
14564
|
}
|
|
@@ -14450,6 +14863,10 @@ var MiddleColumnView = class {
|
|
|
14450
14863
|
const index = position === "top" ? this._topIndex : this._bottomIndex;
|
|
14451
14864
|
if (index !== void 0) this._splitview.resizeView(index, size);
|
|
14452
14865
|
}
|
|
14866
|
+
/** The inner splitview's primary-axis (height) extent; zero until laid out. */
|
|
14867
|
+
get axisSize() {
|
|
14868
|
+
return this._splitview.size;
|
|
14869
|
+
}
|
|
14453
14870
|
updateMargin(gap) {
|
|
14454
14871
|
this._splitview.margin = gap;
|
|
14455
14872
|
}
|
|
@@ -14462,6 +14879,7 @@ var ShellManager = class {
|
|
|
14462
14879
|
constructor(container, dockviewElement, layoutGrid, gap = 0, defaultCollapsedSize = 35) {
|
|
14463
14880
|
this._disposables = new CompositeDisposable();
|
|
14464
14881
|
this._viewConfigs = /* @__PURE__ */ new Map();
|
|
14882
|
+
this._pendingSizes = /* @__PURE__ */ new Map();
|
|
14465
14883
|
this._currentWidth = 0;
|
|
14466
14884
|
this._currentHeight = 0;
|
|
14467
14885
|
this._gap = gap;
|
|
@@ -14552,11 +14970,13 @@ var ShellManager = class {
|
|
|
14552
14970
|
break;
|
|
14553
14971
|
}
|
|
14554
14972
|
this._disposables.addDisposables(view);
|
|
14973
|
+
if (!view.isCollapsed && !this._canResize(position)) this._pendingSizes.set(position, initialSize);
|
|
14555
14974
|
this.updateTheme(this._gap, this._defaultCollapsedSize);
|
|
14556
14975
|
return view;
|
|
14557
14976
|
}
|
|
14558
14977
|
layout(width, height) {
|
|
14559
14978
|
this._outerSplitview.layout(width, height);
|
|
14979
|
+
this._flushPendingSizes();
|
|
14560
14980
|
}
|
|
14561
14981
|
/**
|
|
14562
14982
|
* Called when the active theme changes. Updates splitview margins and
|
|
@@ -14620,6 +15040,7 @@ var ShellManager = class {
|
|
|
14620
15040
|
this._disposables.removeDisposable(view);
|
|
14621
15041
|
view.dispose();
|
|
14622
15042
|
this._viewConfigs.delete(position);
|
|
15043
|
+
this._pendingSizes.delete(position);
|
|
14623
15044
|
this.updateTheme(this._gap, this._defaultCollapsedSize);
|
|
14624
15045
|
}
|
|
14625
15046
|
hasEdgeGroup(position) {
|
|
@@ -14643,6 +15064,7 @@ var ShellManager = class {
|
|
|
14643
15064
|
this._middleColumn.setViewVisible(position, visible);
|
|
14644
15065
|
break;
|
|
14645
15066
|
}
|
|
15067
|
+
if (visible) this._flushPendingSizes();
|
|
14646
15068
|
}
|
|
14647
15069
|
isEdgeGroupVisible(position) {
|
|
14648
15070
|
switch (position) {
|
|
@@ -14660,20 +15082,63 @@ var ShellManager = class {
|
|
|
14660
15082
|
const view = this._getView(position);
|
|
14661
15083
|
if (!view) return;
|
|
14662
15084
|
view.setCollapsed(collapsed);
|
|
14663
|
-
|
|
15085
|
+
if (collapsed) {
|
|
15086
|
+
this._pendingSizes.delete(position);
|
|
15087
|
+
this._resizeView(position, view.collapsedSize);
|
|
15088
|
+
} else this.resizeEdgeGroup(position, view.lastExpandedSize);
|
|
15089
|
+
}
|
|
15090
|
+
/**
|
|
15091
|
+
* Resize the edge group at `position` along its primary axis (width for
|
|
15092
|
+
* `left`/`right`, height for `top`/`bottom`), clamped by the group's
|
|
15093
|
+
* constraints and the space available. Where `groupApi.setSize` lands.
|
|
15094
|
+
*
|
|
15095
|
+
* The size becomes the group's expanded size, so a collapsed group keeps
|
|
15096
|
+
* its strip and takes it on expand, and it survives a `toJSON` round-trip.
|
|
15097
|
+
*/
|
|
15098
|
+
resizeEdgeGroup(position, size) {
|
|
15099
|
+
const view = this._getView(position);
|
|
15100
|
+
if (!view || !Number.isFinite(size)) return;
|
|
15101
|
+
const target = Math.round(size);
|
|
15102
|
+
if (target <= 0) return;
|
|
15103
|
+
view.restoreExpandedSize(target);
|
|
15104
|
+
if (view.isCollapsed) {
|
|
15105
|
+
this._pendingSizes.delete(position);
|
|
15106
|
+
return;
|
|
15107
|
+
}
|
|
15108
|
+
if (this._canResize(position)) {
|
|
15109
|
+
this._pendingSizes.delete(position);
|
|
15110
|
+
this._resizeView(position, target);
|
|
15111
|
+
} else this._pendingSizes.set(position, target);
|
|
15112
|
+
}
|
|
15113
|
+
/** A resize lands only on a visible view (a hidden one is pinned to zero)
|
|
15114
|
+
* whose splitview has extent to distribute. */
|
|
15115
|
+
_canResize(position) {
|
|
15116
|
+
if (!this.isEdgeGroupVisible(position)) return false;
|
|
15117
|
+
return (position === "left" || position === "right" ? this._outerSplitview.size : this._middleColumn.axisSize) > 0;
|
|
15118
|
+
}
|
|
15119
|
+
_resizeView(position, size) {
|
|
14664
15120
|
switch (position) {
|
|
14665
15121
|
case "left":
|
|
14666
|
-
if (this._leftIndex !== void 0) this._outerSplitview.resizeView(this._leftIndex,
|
|
15122
|
+
if (this._leftIndex !== void 0) this._outerSplitview.resizeView(this._leftIndex, size);
|
|
14667
15123
|
break;
|
|
14668
15124
|
case "right":
|
|
14669
|
-
if (this._rightIndex !== void 0) this._outerSplitview.resizeView(this._rightIndex,
|
|
15125
|
+
if (this._rightIndex !== void 0) this._outerSplitview.resizeView(this._rightIndex, size);
|
|
14670
15126
|
break;
|
|
14671
15127
|
case "top":
|
|
14672
15128
|
case "bottom":
|
|
14673
|
-
this._middleColumn.resizeView(position,
|
|
15129
|
+
this._middleColumn.resizeView(position, size);
|
|
14674
15130
|
break;
|
|
14675
15131
|
}
|
|
14676
15132
|
}
|
|
15133
|
+
_flushPendingSizes() {
|
|
15134
|
+
if (this._pendingSizes.size === 0) return;
|
|
15135
|
+
for (const [position, size] of this._pendingSizes) {
|
|
15136
|
+
const view = this._getView(position);
|
|
15137
|
+
if (!view || view.isCollapsed || !this._canResize(position)) continue;
|
|
15138
|
+
this._pendingSizes.delete(position);
|
|
15139
|
+
this._resizeView(position, size);
|
|
15140
|
+
}
|
|
15141
|
+
}
|
|
14677
15142
|
isEdgeGroupCollapsed(position) {
|
|
14678
15143
|
var _this$_getView$isColl, _this$_getView;
|
|
14679
15144
|
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;
|
|
@@ -14699,15 +15164,17 @@ var ShellManager = class {
|
|
|
14699
15164
|
maximumSize: Number.isFinite(view.configuredMaximumSize) ? view.configuredMaximumSize : void 0,
|
|
14700
15165
|
collapsedSize: view.configuredCollapsedSize
|
|
14701
15166
|
});
|
|
14702
|
-
const expandedSize = (view, isVisible, liveSize, cachedVisibleSize) => {
|
|
15167
|
+
const expandedSize = (view, position, isVisible, liveSize, cachedVisibleSize) => {
|
|
14703
15168
|
if (view.isCollapsed) return view.lastExpandedSize;
|
|
15169
|
+
const pending = this._pendingSizes.get(position);
|
|
15170
|
+
if (pending !== void 0) return pending;
|
|
14704
15171
|
if (!isVisible) return cachedVisibleSize !== null && cachedVisibleSize !== void 0 ? cachedVisibleSize : view.lastExpandedSize;
|
|
14705
15172
|
return liveSize;
|
|
14706
15173
|
};
|
|
14707
15174
|
if (this._leftView && this._leftIndex !== void 0) {
|
|
14708
15175
|
const visible = this._outerSplitview.isViewVisible(this._leftIndex);
|
|
14709
15176
|
edgeGroups.left = _objectSpread2({
|
|
14710
|
-
size: expandedSize(this._leftView, visible, this._outerSplitview.getViewSize(this._leftIndex), this._outerSplitview.getViewCachedVisibleSize(this._leftIndex)),
|
|
15177
|
+
size: expandedSize(this._leftView, "left", visible, this._outerSplitview.getViewSize(this._leftIndex), this._outerSplitview.getViewCachedVisibleSize(this._leftIndex)),
|
|
14711
15178
|
visible,
|
|
14712
15179
|
collapsed: this._leftView.isCollapsed || void 0
|
|
14713
15180
|
}, constraints(this._leftView));
|
|
@@ -14715,7 +15182,7 @@ var ShellManager = class {
|
|
|
14715
15182
|
if (this._rightView && this._rightIndex !== void 0) {
|
|
14716
15183
|
const visible = this._outerSplitview.isViewVisible(this._rightIndex);
|
|
14717
15184
|
edgeGroups.right = _objectSpread2({
|
|
14718
|
-
size: expandedSize(this._rightView, visible, this._outerSplitview.getViewSize(this._rightIndex), this._outerSplitview.getViewCachedVisibleSize(this._rightIndex)),
|
|
15185
|
+
size: expandedSize(this._rightView, "right", visible, this._outerSplitview.getViewSize(this._rightIndex), this._outerSplitview.getViewCachedVisibleSize(this._rightIndex)),
|
|
14719
15186
|
visible,
|
|
14720
15187
|
collapsed: this._rightView.isCollapsed || void 0
|
|
14721
15188
|
}, constraints(this._rightView));
|
|
@@ -14723,7 +15190,7 @@ var ShellManager = class {
|
|
|
14723
15190
|
if (this._topView) {
|
|
14724
15191
|
const visible = this._middleColumn.isViewVisible("top");
|
|
14725
15192
|
edgeGroups.top = _objectSpread2({
|
|
14726
|
-
size: expandedSize(this._topView, visible, this._middleColumn.getViewSize("top"), this._middleColumn.getViewCachedVisibleSize("top")),
|
|
15193
|
+
size: expandedSize(this._topView, "top", visible, this._middleColumn.getViewSize("top"), this._middleColumn.getViewCachedVisibleSize("top")),
|
|
14727
15194
|
visible,
|
|
14728
15195
|
collapsed: this._topView.isCollapsed || void 0
|
|
14729
15196
|
}, constraints(this._topView));
|
|
@@ -14731,7 +15198,7 @@ var ShellManager = class {
|
|
|
14731
15198
|
if (this._bottomView) {
|
|
14732
15199
|
const visible = this._middleColumn.isViewVisible("bottom");
|
|
14733
15200
|
edgeGroups.bottom = _objectSpread2({
|
|
14734
|
-
size: expandedSize(this._bottomView, visible, this._middleColumn.getViewSize("bottom"), this._middleColumn.getViewCachedVisibleSize("bottom")),
|
|
15201
|
+
size: expandedSize(this._bottomView, "bottom", visible, this._middleColumn.getViewSize("bottom"), this._middleColumn.getViewCachedVisibleSize("bottom")),
|
|
14735
15202
|
visible,
|
|
14736
15203
|
collapsed: this._bottomView.isCollapsed || void 0
|
|
14737
15204
|
}, constraints(this._bottomView));
|
|
@@ -14739,33 +15206,23 @@ var ShellManager = class {
|
|
|
14739
15206
|
return edgeGroups;
|
|
14740
15207
|
}
|
|
14741
15208
|
fromJSON(data) {
|
|
14742
|
-
|
|
14743
|
-
|
|
14744
|
-
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14750
|
-
|
|
14751
|
-
(
|
|
14752
|
-
|
|
14753
|
-
|
|
14754
|
-
if (
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
|
|
14759
|
-
(_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);
|
|
14760
|
-
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);
|
|
14761
|
-
if (!data.top.visible) this._middleColumn.setViewVisible("top", false);
|
|
14762
|
-
}
|
|
14763
|
-
if (data.bottom) {
|
|
14764
|
-
var _this$_bottomView2, _this$_bottomView3, _data$bottom$collapse, _this$_bottomView$col, _this$_bottomView4;
|
|
14765
|
-
(_this$_bottomView2 = this._bottomView) === null || _this$_bottomView2 === void 0 || _this$_bottomView2.restoreExpandedSize(data.bottom.size);
|
|
14766
|
-
(_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);
|
|
14767
|
-
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);
|
|
14768
|
-
if (!data.bottom.visible) this._middleColumn.setViewVisible("bottom", false);
|
|
15209
|
+
for (const position of [
|
|
15210
|
+
"left",
|
|
15211
|
+
"right",
|
|
15212
|
+
"top",
|
|
15213
|
+
"bottom"
|
|
15214
|
+
]) {
|
|
15215
|
+
var _state$collapsed;
|
|
15216
|
+
const state = data[position];
|
|
15217
|
+
const view = this._getView(position);
|
|
15218
|
+
if (!state || !view) continue;
|
|
15219
|
+
view.restoreExpandedSize(state.size);
|
|
15220
|
+
view.setCollapsed((_state$collapsed = state.collapsed) !== null && _state$collapsed !== void 0 ? _state$collapsed : false);
|
|
15221
|
+
if (state.collapsed) {
|
|
15222
|
+
this._pendingSizes.delete(position);
|
|
15223
|
+
this._resizeView(position, view.collapsedSize);
|
|
15224
|
+
} else this.resizeEdgeGroup(position, state.size);
|
|
15225
|
+
this.setEdgeGroupVisible(position, !!state.visible);
|
|
14769
15226
|
}
|
|
14770
15227
|
}
|
|
14771
15228
|
dispose() {
|
|
@@ -15358,6 +15815,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15358
15815
|
this._onWillDrop = new Emitter();
|
|
15359
15816
|
this.onWillDrop = this._onWillDrop.event;
|
|
15360
15817
|
this._mutationDepth = 0;
|
|
15818
|
+
this._pendingLocationChanges = /* @__PURE__ */ new Map();
|
|
15361
15819
|
this._origin = "user";
|
|
15362
15820
|
this._originDepth = 0;
|
|
15363
15821
|
this._onWillMutateLayout = new Emitter();
|
|
@@ -15455,7 +15913,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15455
15913
|
toggleClass(this.element, "dv-debug", !!options.debug);
|
|
15456
15914
|
this.updateTheme();
|
|
15457
15915
|
if (options.debug) this.addDisposables(new StrictEventsSequencing(this));
|
|
15458
|
-
this.addDisposables(this.rootDropTargetContainer, this.floatingDropTargetContainer, addDisposableListener(this._shellManager.element, "dragend", () => {
|
|
15916
|
+
this.addDisposables(Disposable.from(() => this._pendingLocationChanges.clear()), this.rootDropTargetContainer, this.floatingDropTargetContainer, addDisposableListener(this._shellManager.element, "dragend", () => {
|
|
15459
15917
|
var _this$rootDropTargetC2, _this$floatingDropTar;
|
|
15460
15918
|
(_this$rootDropTargetC2 = this.rootDropTargetContainer.model) === null || _this$rootDropTargetC2 === void 0 || _this$rootDropTargetC2.clear();
|
|
15461
15919
|
(_this$floatingDropTar = this.floatingDropTargetContainer.model) === null || _this$floatingDropTar === void 0 || _this$floatingDropTar.clear();
|
|
@@ -15529,7 +15987,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15529
15987
|
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;
|
|
15530
15988
|
}
|
|
15531
15989
|
addPopoutGroup(itemToPopout, options) {
|
|
15532
|
-
return this.
|
|
15990
|
+
return this.mutationAsync("popout", () => this._doAddPopoutGroup(itemToPopout, options));
|
|
15533
15991
|
}
|
|
15534
15992
|
/** Enumerate the popout groups currently open in their own windows. */
|
|
15535
15993
|
getPopouts() {
|
|
@@ -15626,15 +16084,32 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15626
16084
|
}
|
|
15627
16085
|
};
|
|
15628
16086
|
let floatingBox;
|
|
15629
|
-
|
|
15630
|
-
|
|
15631
|
-
|
|
15632
|
-
|
|
15633
|
-
|
|
16087
|
+
/**
|
|
16088
|
+
* Popping out rehomes panels into `group`, so like the floating
|
|
16089
|
+
* case it owes the caller an `onDidMovePanel` per panel. The
|
|
16090
|
+
* events are deferred until the window is wired up so listeners
|
|
16091
|
+
* observe the panels' final `popout` location.
|
|
16092
|
+
*/
|
|
16093
|
+
let movedPanels = [];
|
|
16094
|
+
if (!(options === null || options === void 0 ? void 0 : options.overridePopoutGroup) && !(options === null || options === void 0 ? void 0 : options.overridePopoutGridview) && isGroupAddedToDom) if (itemToPopout instanceof DockviewPanel) {
|
|
16095
|
+
const sourceGroup = itemToPopout.group;
|
|
16096
|
+
this.movingLock(() => {
|
|
16097
|
+
const panel = referenceGroup.model.removePanel(itemToPopout);
|
|
16098
|
+
group.model.openPanel(panel);
|
|
16099
|
+
});
|
|
16100
|
+
movedPanels = [{
|
|
16101
|
+
panel: itemToPopout,
|
|
16102
|
+
from: sourceGroup
|
|
16103
|
+
}];
|
|
16104
|
+
} else {
|
|
15634
16105
|
this.movingLock(() => moveGroupWithoutDestroying({
|
|
15635
16106
|
from: referenceGroup,
|
|
15636
16107
|
to: group
|
|
15637
16108
|
}));
|
|
16109
|
+
movedPanels = group.panels.map((panel) => ({
|
|
16110
|
+
panel,
|
|
16111
|
+
from: referenceGroup
|
|
16112
|
+
}));
|
|
15638
16113
|
switch (referenceLocation) {
|
|
15639
16114
|
case "grid":
|
|
15640
16115
|
referenceGroup.api.setVisible(false);
|
|
@@ -15743,6 +16218,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15743
16218
|
group: value.popoutGroup,
|
|
15744
16219
|
window: value.getWindow()
|
|
15745
16220
|
});
|
|
16221
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15746
16222
|
return true;
|
|
15747
16223
|
}).catch((err) => {
|
|
15748
16224
|
console.error("dockview: failed to create popout.", err);
|
|
@@ -15820,6 +16296,16 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15820
16296
|
const members = this.groups.filter((candidate) => popoutGridview.element.contains(candidate.element));
|
|
15821
16297
|
const anchorPresent = members.includes(group);
|
|
15822
16298
|
const anchorIsSoleMember = anchorPresent && members.length === 1;
|
|
16299
|
+
/**
|
|
16300
|
+
* Popping a group out fires `onDidMovePanel` per panel, so closing the
|
|
16301
|
+
* window owes the caller the same: every panel in it is rehomed, into
|
|
16302
|
+
* the reference group the popout left behind or into a fresh grid slot.
|
|
16303
|
+
* `movingLock` suppresses onDidAddPanel / onDidRemovePanel on these
|
|
16304
|
+
* paths, so `onDidMovePanel` is the only event that can carry it. The
|
|
16305
|
+
* events are deferred to the end so listeners observe the panels at
|
|
16306
|
+
* their final group and location.
|
|
16307
|
+
*/
|
|
16308
|
+
const movedPanels = [];
|
|
15823
16309
|
if (genuineClose) for (const member of members) {
|
|
15824
16310
|
if (member === group) continue;
|
|
15825
16311
|
this.movingLock(() => {
|
|
@@ -15830,12 +16316,21 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15830
16316
|
});
|
|
15831
16317
|
this.redockGroupToMainGrid(member);
|
|
15832
16318
|
});
|
|
16319
|
+
for (const panel of member.panels) movedPanels.push({
|
|
16320
|
+
panel,
|
|
16321
|
+
from: member
|
|
16322
|
+
});
|
|
15833
16323
|
}
|
|
15834
16324
|
if (anchorPresent && isGroupAddedToDom && this.getPanel(referenceGroup.id)) {
|
|
16325
|
+
const rehomed = [...group.panels];
|
|
15835
16326
|
this.movingLock(() => moveGroupWithoutDestroying({
|
|
15836
16327
|
from: group,
|
|
15837
16328
|
to: referenceGroup
|
|
15838
16329
|
}));
|
|
16330
|
+
for (const panel of rehomed) movedPanels.push({
|
|
16331
|
+
panel,
|
|
16332
|
+
from: group
|
|
16333
|
+
});
|
|
15839
16334
|
if (!referenceGroup.api.isVisible) referenceGroup.api.setVisible(true);
|
|
15840
16335
|
if (this.getPanel(group.id)) this.doRemoveGroup(group, { skipPopoutAssociated: true });
|
|
15841
16336
|
} else if (anchorPresent && this.getPanel(group.id)) {
|
|
@@ -15866,10 +16361,15 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15866
16361
|
this.movingLock(() => {
|
|
15867
16362
|
this.doAddGroup(group, [0]);
|
|
15868
16363
|
});
|
|
16364
|
+
for (const panel of group.panels) movedPanels.push({
|
|
16365
|
+
panel,
|
|
16366
|
+
from: group
|
|
16367
|
+
});
|
|
15869
16368
|
}
|
|
15870
16369
|
this.doSetGroupAndPanelActive(group);
|
|
15871
16370
|
}
|
|
15872
16371
|
disposePopoutGridview();
|
|
16372
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15873
16373
|
}
|
|
15874
16374
|
addFloatingGroup(item, options) {
|
|
15875
16375
|
this.mutation("float", () => this._doAddFloatingGroup(item, options));
|
|
@@ -15878,7 +16378,15 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15878
16378
|
if (!assertModule(this._floatingGroupService, "FloatingGroup", "api.addFloatingGroup")) return;
|
|
15879
16379
|
if (item instanceof DockviewGroupPanel && item.model.location.type === "edge") return;
|
|
15880
16380
|
let group;
|
|
16381
|
+
/**
|
|
16382
|
+
* Floating relocates panels exactly like a drop onto the grid does, so
|
|
16383
|
+
* it owes the caller an `onDidMovePanel` per panel. The events are
|
|
16384
|
+
* deferred until the window is mounted below: only then do the panels
|
|
16385
|
+
* report their final `floating` location.
|
|
16386
|
+
*/
|
|
16387
|
+
let movedPanels = [];
|
|
15881
16388
|
if (item instanceof DockviewPanel) {
|
|
16389
|
+
const sourceGroup = item.group;
|
|
15882
16390
|
group = this.createGroup();
|
|
15883
16391
|
this._onDidAddGroup.fire(group);
|
|
15884
16392
|
this.movingLock(() => this.removePanel(item, {
|
|
@@ -15887,6 +16395,10 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15887
16395
|
skipSetActiveGroup: true
|
|
15888
16396
|
}));
|
|
15889
16397
|
this.movingLock(() => group.model.openPanel(item, { skipSetGroupActive: true }));
|
|
16398
|
+
movedPanels = [{
|
|
16399
|
+
panel: item,
|
|
16400
|
+
from: sourceGroup
|
|
16401
|
+
}];
|
|
15890
16402
|
} else {
|
|
15891
16403
|
var _this$_popoutWindowSe8;
|
|
15892
16404
|
group = item;
|
|
@@ -15903,11 +16415,21 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15903
16415
|
});
|
|
15904
16416
|
this.doRemoveGroup(popoutReferenceGroup, { skipDispose: true });
|
|
15905
16417
|
group = popoutReferenceGroup;
|
|
15906
|
-
|
|
15907
|
-
|
|
15908
|
-
|
|
15909
|
-
|
|
15910
|
-
}
|
|
16418
|
+
movedPanels = group.panels.map((panel) => ({
|
|
16419
|
+
panel,
|
|
16420
|
+
from: item
|
|
16421
|
+
}));
|
|
16422
|
+
} else {
|
|
16423
|
+
this.doRemoveGroup(item, {
|
|
16424
|
+
skipDispose: true,
|
|
16425
|
+
skipPopoutReturn: true,
|
|
16426
|
+
skipPopoutAssociated: false
|
|
16427
|
+
});
|
|
16428
|
+
movedPanels = group.panels.map((panel) => ({
|
|
16429
|
+
panel,
|
|
16430
|
+
from: group
|
|
16431
|
+
}));
|
|
16432
|
+
}
|
|
15911
16433
|
}
|
|
15912
16434
|
function getAnchoredBox() {
|
|
15913
16435
|
if (options === null || options === void 0 ? void 0 : options.position) {
|
|
@@ -15940,6 +16462,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15940
16462
|
skipActiveGroup: options === null || options === void 0 ? void 0 : options.skipActiveGroup,
|
|
15941
16463
|
disableSmartGuides: options === null || options === void 0 ? void 0 : options.disableSmartGuides
|
|
15942
16464
|
});
|
|
16465
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15943
16466
|
}
|
|
15944
16467
|
/**
|
|
15945
16468
|
* Build an empty gridview configured to match the main grid's styling, for
|
|
@@ -16084,6 +16607,13 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16084
16607
|
position
|
|
16085
16608
|
};
|
|
16086
16609
|
group.model.headerPosition = position;
|
|
16610
|
+
const resizeDisposable = group.onDidChange((event) => {
|
|
16611
|
+
var _this$_shellManager3;
|
|
16612
|
+
if (!event) return;
|
|
16613
|
+
const size = position === "left" || position === "right" ? event.width : event.height;
|
|
16614
|
+
if (typeof size !== "number") return;
|
|
16615
|
+
(_this$_shellManager3 = this._shellManager) === null || _this$_shellManager3 === void 0 || _this$_shellManager3.resizeEdgeGroup(position, size);
|
|
16616
|
+
});
|
|
16087
16617
|
const autoCollapseDisposable = group.model.onDidRemovePanel(() => {
|
|
16088
16618
|
if (!group.model.isEmpty) return;
|
|
16089
16619
|
if (service.isAutoReveal(group)) queueMicrotask(() => {
|
|
@@ -16092,7 +16622,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16092
16622
|
});
|
|
16093
16623
|
else this.setEdgeGroupCollapsed(group, true);
|
|
16094
16624
|
});
|
|
16095
|
-
service.add(position, group, autoCollapseDisposable);
|
|
16625
|
+
service.add(position, group, new CompositeDisposable(autoCollapseDisposable, resizeDisposable));
|
|
16096
16626
|
if (options.autoHide !== void 0) service.setAutoHide(group, options.autoHide);
|
|
16097
16627
|
if (options.autoReveal !== void 0) service.setAutoReveal(group, options.autoReveal);
|
|
16098
16628
|
this._onDidAddGroup.fire(group);
|
|
@@ -16187,8 +16717,8 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16187
16717
|
}
|
|
16188
16718
|
/** The size an edge group expands to (pre-collapse); sizes the peek. */
|
|
16189
16719
|
getEdgeGroupExpandedSize(position) {
|
|
16190
|
-
var _this$_shellManager$g, _this$
|
|
16191
|
-
return (_this$_shellManager$g = (_this$
|
|
16720
|
+
var _this$_shellManager$g, _this$_shellManager4;
|
|
16721
|
+
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;
|
|
16192
16722
|
}
|
|
16193
16723
|
/** Reposition a single `renderer:'always'` panel's overlay over its
|
|
16194
16724
|
* reference container, optionally forcing it visible (the auto-hide peek
|
|
@@ -16371,35 +16901,119 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16371
16901
|
if (typeof data !== "object" || data === null) throw new Error("dockview: serialized layout must be a non-null object");
|
|
16372
16902
|
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");
|
|
16373
16903
|
const existingPanels = /* @__PURE__ */ new Map();
|
|
16374
|
-
|
|
16904
|
+
const temporaryGroups = /* @__PURE__ */ new Map();
|
|
16905
|
+
const stagedPanels = [];
|
|
16906
|
+
const temporaryGroupDisposables = [];
|
|
16907
|
+
/**
|
|
16908
|
+
* The staging groups are detached from `_groups` and never enter the
|
|
16909
|
+
* grid, so nothing else will ever tear them down.
|
|
16910
|
+
*
|
|
16911
|
+
* `dispose()` reaches consumer `IContentRenderer.dispose()`, so one
|
|
16912
|
+
* throwing renderer must not abort the rest of the cleanup — that would
|
|
16913
|
+
* re-introduce the very leak this reclaims — nor replace the
|
|
16914
|
+
* deserialization error the caller is being given. Draining the list
|
|
16915
|
+
* also makes this safe to call more than once.
|
|
16916
|
+
*/
|
|
16917
|
+
const disposeTemporaryGroups = () => {
|
|
16918
|
+
for (const disposable of temporaryGroupDisposables) try {
|
|
16919
|
+
disposable.dispose();
|
|
16920
|
+
} catch (err) {
|
|
16921
|
+
console.error("dockview: failed to dispose a temporary group created for reuseExistingPanels", err);
|
|
16922
|
+
}
|
|
16923
|
+
temporaryGroupDisposables.length = 0;
|
|
16924
|
+
};
|
|
16375
16925
|
if (options === null || options === void 0 ? void 0 : options.reuseExistingPanels) {
|
|
16376
16926
|
/**
|
|
16377
|
-
*
|
|
16378
|
-
*
|
|
16379
|
-
*
|
|
16380
|
-
* 2. Remove that temporary group from the group mapping so that it doesn't get cleared when we clear the layout
|
|
16927
|
+
* Visible, always-rendered panels need individual staging groups
|
|
16928
|
+
* to remain active. Other reused panels can share a staging group.
|
|
16929
|
+
* The staging groups are excluded from the layout clear below.
|
|
16381
16930
|
*/
|
|
16382
|
-
tempGroup = this.createGroup();
|
|
16383
|
-
this._groups.delete(tempGroup.api.id);
|
|
16384
16931
|
const newPanels = Object.keys(data.panels);
|
|
16385
|
-
|
|
16386
|
-
|
|
16387
|
-
|
|
16388
|
-
|
|
16389
|
-
|
|
16390
|
-
|
|
16391
|
-
|
|
16392
|
-
|
|
16393
|
-
|
|
16394
|
-
|
|
16395
|
-
|
|
16396
|
-
|
|
16397
|
-
|
|
16932
|
+
let sharedTemporaryGroup;
|
|
16933
|
+
const createTemporaryGroup = () => {
|
|
16934
|
+
const temporaryGroup = this.createGroup();
|
|
16935
|
+
/**
|
|
16936
|
+
* Removing the group from `_groups` also drops the record's
|
|
16937
|
+
* `CompositeDisposable`, so capture it first and tear both it
|
|
16938
|
+
* and the group down in the `finally` below. Left undisposed a
|
|
16939
|
+
* staging group leaks its `ResizeObserver`, its
|
|
16940
|
+
* `onDidOptionsChange` subscription (retained by this
|
|
16941
|
+
* component's emitter) and the watermark its model mounts when
|
|
16942
|
+
* the group empties — once per reused panel, per `fromJSON`.
|
|
16943
|
+
*/
|
|
16944
|
+
const record = this._groups.get(temporaryGroup.api.id);
|
|
16945
|
+
this._groups.delete(temporaryGroup.api.id);
|
|
16946
|
+
temporaryGroupDisposables.push(Disposable.from(() => {
|
|
16947
|
+
/**
|
|
16948
|
+
* Reclaim the group's own resources, never its panels.
|
|
16949
|
+
* Staging is driven by the ids in `data.panels` while
|
|
16950
|
+
* reclaiming is driven by the group `views` that
|
|
16951
|
+
* reference them, so a panel whose state is present but
|
|
16952
|
+
* unreferenced is still staged here — and `dispose()`
|
|
16953
|
+
* on a non-empty group reaches the consumer's
|
|
16954
|
+
* `IContentRenderer.dispose()`. Emptying the group
|
|
16955
|
+
* first leaves those panels exactly as they were before
|
|
16956
|
+
* this teardown existed, which also keeps this safe
|
|
16957
|
+
* against any future path that rebuilds a panel under
|
|
16958
|
+
* an id that is live in the new layout.
|
|
16959
|
+
*/
|
|
16960
|
+
this.movingLock(() => {
|
|
16961
|
+
for (const panel of temporaryGroup.panels.slice()) temporaryGroup.model.removePanel(panel);
|
|
16962
|
+
});
|
|
16963
|
+
record === null || record === void 0 || record.disposable.dispose();
|
|
16964
|
+
temporaryGroup.dispose();
|
|
16965
|
+
}));
|
|
16966
|
+
return temporaryGroup;
|
|
16967
|
+
};
|
|
16968
|
+
/**
|
|
16969
|
+
* Staging and the clear below run before the deserialization
|
|
16970
|
+
* `try`, so a throw here (a consumer `onDidRemovePanel` handler, a
|
|
16971
|
+
* renderer teardown during `clear`) would escape without reclaiming
|
|
16972
|
+
* the staging groups already created.
|
|
16973
|
+
*
|
|
16974
|
+
* The creation loop is inside the guard too, not just the moves and
|
|
16975
|
+
* the clear: `createGroup()` reaches consumer code of its own —
|
|
16976
|
+
* `initialize()` mounts the watermark through
|
|
16977
|
+
* `createWatermarkComponent()` — so a throw on the n-th panel would
|
|
16978
|
+
* otherwise strand the n-1 staging groups already built.
|
|
16979
|
+
*/
|
|
16980
|
+
try {
|
|
16981
|
+
for (const panel of this.panels) if (newPanels.includes(panel.api.id)) {
|
|
16982
|
+
existingPanels.set(panel.api.id, panel);
|
|
16983
|
+
let temporaryGroup;
|
|
16984
|
+
if (panel.api.renderer === "always" && panel.api.isVisible) temporaryGroup = createTemporaryGroup();
|
|
16985
|
+
else {
|
|
16986
|
+
var _sharedTemporaryGroup;
|
|
16987
|
+
(_sharedTemporaryGroup = sharedTemporaryGroup) !== null && _sharedTemporaryGroup !== void 0 || (sharedTemporaryGroup = createTemporaryGroup());
|
|
16988
|
+
temporaryGroup = sharedTemporaryGroup;
|
|
16989
|
+
}
|
|
16990
|
+
temporaryGroups.set(panel.api.id, temporaryGroup);
|
|
16991
|
+
stagedPanels.push({
|
|
16992
|
+
panel,
|
|
16993
|
+
temporaryGroup
|
|
16994
|
+
});
|
|
16995
|
+
}
|
|
16996
|
+
this.movingLock(() => {
|
|
16997
|
+
stagedPanels.forEach(({ panel, temporaryGroup }) => {
|
|
16998
|
+
this.moveGroupOrPanel({
|
|
16999
|
+
from: {
|
|
17000
|
+
groupId: panel.api.group.api.id,
|
|
17001
|
+
panelId: panel.api.id
|
|
17002
|
+
},
|
|
17003
|
+
to: {
|
|
17004
|
+
group: temporaryGroup,
|
|
17005
|
+
position: "center"
|
|
17006
|
+
},
|
|
17007
|
+
keepEmptyGroups: true
|
|
17008
|
+
});
|
|
16398
17009
|
});
|
|
16399
17010
|
});
|
|
16400
|
-
|
|
16401
|
-
|
|
16402
|
-
|
|
17011
|
+
this.clear();
|
|
17012
|
+
} catch (err) {
|
|
17013
|
+
disposeTemporaryGroups();
|
|
17014
|
+
throw err;
|
|
17015
|
+
}
|
|
17016
|
+
} else this.clear();
|
|
16403
17017
|
const { grid, panels, activeGroup } = data;
|
|
16404
17018
|
try {
|
|
16405
17019
|
var _data$floatingGroups, _data$popoutGroups, _this$_popoutWindowSe12, _this$_floatingGroupS5, _this$_watermarkServi2;
|
|
@@ -16431,9 +17045,10 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16431
17045
|
* due to a corruption of input data.
|
|
16432
17046
|
*/
|
|
16433
17047
|
const existingPanel = existingPanels.get(child);
|
|
16434
|
-
|
|
17048
|
+
const temporaryGroup = temporaryGroups.get(child);
|
|
17049
|
+
if (temporaryGroup && existingPanel) {
|
|
16435
17050
|
this.movingLock(() => {
|
|
16436
|
-
|
|
17051
|
+
temporaryGroup.model.removePanel(existingPanel);
|
|
16437
17052
|
});
|
|
16438
17053
|
createdPanels.push(existingPanel);
|
|
16439
17054
|
existingPanel.updateFromStateModel(panels[child]);
|
|
@@ -16463,7 +17078,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16463
17078
|
return createGroupFromSerializedState(node.data);
|
|
16464
17079
|
} });
|
|
16465
17080
|
this._layoutFromShell(width, height);
|
|
16466
|
-
if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels);
|
|
17081
|
+
if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels, existingPanels, temporaryGroups);
|
|
16467
17082
|
this.deserializeFloatingWindows((_data$floatingGroups = data.floatingGroups) !== null && _data$floatingGroups !== void 0 ? _data$floatingGroups : [], createGroupFromSerializedState);
|
|
16468
17083
|
const popoutPromises = this.deserializePopoutWindows((_data$popoutGroups = data.popoutGroups) !== null && _data$popoutGroups !== void 0 ? _data$popoutGroups : [], createGroupFromSerializedState);
|
|
16469
17084
|
(_this$_popoutWindowSe12 = this._popoutWindowService) === null || _this$_popoutWindowSe12 === void 0 || _this$_popoutWindowSe12.finishRestoration(popoutPromises);
|
|
@@ -16500,6 +17115,8 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16500
17115
|
* expect trying to load a corrupted layout to result in an error and not silently fail...
|
|
16501
17116
|
*/
|
|
16502
17117
|
throw err;
|
|
17118
|
+
} finally {
|
|
17119
|
+
disposeTemporaryGroups();
|
|
16503
17120
|
}
|
|
16504
17121
|
this.debouncedUpdateAllPositions();
|
|
16505
17122
|
this._onDidLayoutFromJSON.fire();
|
|
@@ -16522,7 +17139,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16522
17139
|
members
|
|
16523
17140
|
};
|
|
16524
17141
|
}
|
|
16525
|
-
deserializeEdgeGroups(edgeGroups, panels) {
|
|
17142
|
+
deserializeEdgeGroups(edgeGroups, panels, existingPanels, temporaryGroups) {
|
|
16526
17143
|
const edgeService = assertModule(this._edgeGroupService, "EdgeGroup", "fromJSON edge restoration");
|
|
16527
17144
|
if (!edgeService) return;
|
|
16528
17145
|
for (const _position of [
|
|
@@ -16552,13 +17169,40 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16552
17169
|
if (groupState) {
|
|
16553
17170
|
const { views, activeView } = groupState;
|
|
16554
17171
|
const createdPanels = [];
|
|
16555
|
-
for (const panelId of views)
|
|
16556
|
-
|
|
16557
|
-
|
|
17172
|
+
for (const panelId of views) {
|
|
17173
|
+
if (!panels[panelId]) continue;
|
|
17174
|
+
/**
|
|
17175
|
+
* Reclaim a staged panel rather than rebuilding it, the
|
|
17176
|
+
* same way the grid path does. Deserializing here instead
|
|
17177
|
+
* would honour `reuseExistingPanels` everywhere except edge
|
|
17178
|
+
* groups: the live panel keeps sitting in its staging group
|
|
17179
|
+
* while a second panel is built under the same id, so the
|
|
17180
|
+
* consumer's renderer for the original is orphaned — never
|
|
17181
|
+
* disposed, and its element left inside the id-keyed
|
|
17182
|
+
* overlay entry the replacement now shares.
|
|
17183
|
+
*/
|
|
17184
|
+
const existingPanel = existingPanels.get(panelId);
|
|
17185
|
+
const temporaryGroup = temporaryGroups.get(panelId);
|
|
17186
|
+
if (temporaryGroup && existingPanel) {
|
|
17187
|
+
this.movingLock(() => {
|
|
17188
|
+
temporaryGroup.model.removePanel(existingPanel);
|
|
17189
|
+
});
|
|
17190
|
+
createdPanels.push(existingPanel);
|
|
17191
|
+
existingPanel.updateFromStateModel(panels[panelId]);
|
|
17192
|
+
} else {
|
|
17193
|
+
const panel = this._deserializer.fromJSON(panels[panelId], edgeGroup);
|
|
17194
|
+
createdPanels.push(panel);
|
|
17195
|
+
}
|
|
16558
17196
|
}
|
|
16559
17197
|
for (const panel of createdPanels) {
|
|
16560
17198
|
const isActive = activeView === panel.id;
|
|
16561
|
-
|
|
17199
|
+
if (existingPanels.has(panel.api.id)) this.movingLock(() => {
|
|
17200
|
+
edgeGroup.model.openPanel(panel, {
|
|
17201
|
+
skipSetActive: !isActive,
|
|
17202
|
+
skipSetGroupActive: true
|
|
17203
|
+
});
|
|
17204
|
+
});
|
|
17205
|
+
else edgeGroup.model.openPanel(panel, {
|
|
16562
17206
|
skipSetActive: !isActive,
|
|
16563
17207
|
skipSetGroupActive: true
|
|
16564
17208
|
});
|
|
@@ -16982,22 +17626,100 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16982
17626
|
* outermost mutation.
|
|
16983
17627
|
*/
|
|
16984
17628
|
mutation(kind, func) {
|
|
16985
|
-
const
|
|
17629
|
+
const close = this.openMutation(kind);
|
|
17630
|
+
try {
|
|
17631
|
+
return func();
|
|
17632
|
+
} finally {
|
|
17633
|
+
close();
|
|
17634
|
+
}
|
|
17635
|
+
}
|
|
17636
|
+
/**
|
|
17637
|
+
* `mutation()` for an operation whose work continues after the synchronous
|
|
17638
|
+
* call returns. The transaction stays open until the returned promise
|
|
17639
|
+
* settles, so everything the operation does - the group it adds, the panels
|
|
17640
|
+
* it relocates - lands inside the bracket, matching the synchronous
|
|
17641
|
+
* move / float paths.
|
|
17642
|
+
*/
|
|
17643
|
+
mutationAsync(kind, func) {
|
|
17644
|
+
var _this = this;
|
|
17645
|
+
return _asyncToGenerator(function* () {
|
|
17646
|
+
const close = _this.openMutation(kind);
|
|
17647
|
+
try {
|
|
17648
|
+
return yield func();
|
|
17649
|
+
} finally {
|
|
17650
|
+
close();
|
|
17651
|
+
}
|
|
17652
|
+
})();
|
|
17653
|
+
}
|
|
17654
|
+
/**
|
|
17655
|
+
* Open a transaction and return the function that closes it. Shared by the
|
|
17656
|
+
* synchronous and asynchronous brackets; the returned function must be
|
|
17657
|
+
* called exactly once.
|
|
17658
|
+
*
|
|
17659
|
+
* Both ends key off the depth counter reaching zero rather than off which
|
|
17660
|
+
* bracket opened first. For synchronous nesting the two are the same thing
|
|
17661
|
+
* - brackets close in the order they opened - but asynchronous transactions
|
|
17662
|
+
* can *overlap* rather than nest (two `addPopoutGroup` calls in flight at
|
|
17663
|
+
* once, or a restore staggering several), and there the first to open is
|
|
17664
|
+
* not the last to close. Reporting on the opener would fire `didMutate`
|
|
17665
|
+
* while the other transaction was still doing structural work, which is the
|
|
17666
|
+
* very thing the async bracket exists to prevent. Overlapping transactions
|
|
17667
|
+
* therefore report as one, tagged with the kind of the last to finish.
|
|
17668
|
+
*/
|
|
17669
|
+
openMutation(kind) {
|
|
16986
17670
|
const origin = this._origin;
|
|
16987
|
-
if (
|
|
17671
|
+
if (this._mutationDepth === 0) this._onWillMutateLayout.fire({
|
|
16988
17672
|
kind,
|
|
16989
17673
|
origin
|
|
16990
17674
|
});
|
|
16991
17675
|
this._mutationDepth++;
|
|
16992
|
-
|
|
16993
|
-
return func();
|
|
16994
|
-
} finally {
|
|
17676
|
+
return () => {
|
|
16995
17677
|
this._mutationDepth--;
|
|
16996
|
-
if (
|
|
16997
|
-
|
|
16998
|
-
|
|
16999
|
-
|
|
17678
|
+
if (this._mutationDepth === 0) {
|
|
17679
|
+
this.flushLocationChanges();
|
|
17680
|
+
this._onDidMutateLayout.fire({
|
|
17681
|
+
kind,
|
|
17682
|
+
origin
|
|
17683
|
+
});
|
|
17684
|
+
}
|
|
17685
|
+
};
|
|
17686
|
+
}
|
|
17687
|
+
/**
|
|
17688
|
+
* Coalesce a panel's `onDidLocationChange` to the end of the enclosing
|
|
17689
|
+
* transaction, or fire it immediately when no transaction is in flight.
|
|
17690
|
+
*
|
|
17691
|
+
* Relocating a panel touches its location twice: once as it is reparented
|
|
17692
|
+
* into the destination group - which, when that group has just been created
|
|
17693
|
+
* for a floating or popout window, has not been told where it lives yet -
|
|
17694
|
+
* and once as the group is tagged with its final location. Reporting each
|
|
17695
|
+
* signal as it happens therefore leaks an intermediate `grid` location the
|
|
17696
|
+
* panel was never in, at a moment when it belongs to neither group's panel
|
|
17697
|
+
* list and so is missing from `api.panels`.
|
|
17698
|
+
*
|
|
17699
|
+
* Deferring collapses those signals into a single event carrying the
|
|
17700
|
+
* settled location. Note the signals are deliberately *not* compared
|
|
17701
|
+
* against the panel's previous location: a panel can move between two
|
|
17702
|
+
* floating windows without its location type changing, and this event is
|
|
17703
|
+
* the only signal `OverlayRenderContainer` has to re-resolve the panel's
|
|
17704
|
+
* z-index against its new host window.
|
|
17705
|
+
*/
|
|
17706
|
+
deferLocationChange(key, fire) {
|
|
17707
|
+
if (this._mutationDepth === 0) {
|
|
17708
|
+
fire();
|
|
17709
|
+
return;
|
|
17000
17710
|
}
|
|
17711
|
+
this._pendingLocationChanges.set(key, fire);
|
|
17712
|
+
}
|
|
17713
|
+
/**
|
|
17714
|
+
* Report every panel whose location moved during the transaction that has
|
|
17715
|
+
* just closed. Each callback reads the panel's location at this point, so
|
|
17716
|
+
* what it reports is where the panel ended up.
|
|
17717
|
+
*/
|
|
17718
|
+
flushLocationChanges() {
|
|
17719
|
+
if (this._pendingLocationChanges.size === 0) return;
|
|
17720
|
+
const pending = Array.from(this._pendingLocationChanges.values());
|
|
17721
|
+
this._pendingLocationChanges.clear();
|
|
17722
|
+
for (const fire of pending) fire();
|
|
17001
17723
|
}
|
|
17002
17724
|
/**
|
|
17003
17725
|
* The origin of the operation currently in progress (`'user'` by default).
|
|
@@ -17038,6 +17760,18 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17038
17760
|
origin: this._origin
|
|
17039
17761
|
});
|
|
17040
17762
|
}
|
|
17763
|
+
/**
|
|
17764
|
+
* Announce that `panel` has finished relocating. Must be called once the
|
|
17765
|
+
* move has settled: `to` is read from the panel's current group, so an
|
|
17766
|
+
* early call would report the source group as the destination.
|
|
17767
|
+
*/
|
|
17768
|
+
fireDidMovePanel(panel, from) {
|
|
17769
|
+
this._onDidMovePanel.fire({
|
|
17770
|
+
panel,
|
|
17771
|
+
from,
|
|
17772
|
+
to: panel.group
|
|
17773
|
+
});
|
|
17774
|
+
}
|
|
17041
17775
|
moveGroupOrPanel(options) {
|
|
17042
17776
|
this.mutation("move", () => this._doMoveGroupOrPanel(options));
|
|
17043
17777
|
}
|
|
@@ -17098,10 +17832,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17098
17832
|
});
|
|
17099
17833
|
});
|
|
17100
17834
|
if (!options.skipSetActive) this.doSetGroupAndPanelActive(destinationGroup);
|
|
17101
|
-
this.
|
|
17102
|
-
panel: removedPanel,
|
|
17103
|
-
from: sourceGroup
|
|
17104
|
-
});
|
|
17835
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
17105
17836
|
} else {
|
|
17106
17837
|
/**
|
|
17107
17838
|
* Dropping a panel to the extremities of a group which will place that panel
|
|
@@ -17120,10 +17851,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17120
17851
|
const [sourceParentLocation, from] = tail(getGridLocation(sourceGroup.element));
|
|
17121
17852
|
if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
|
|
17122
17853
|
this.gridview.moveView(sourceParentLocation, from, to);
|
|
17123
|
-
this.
|
|
17124
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
17125
|
-
from: sourceGroup
|
|
17126
|
-
});
|
|
17854
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
17127
17855
|
return;
|
|
17128
17856
|
}
|
|
17129
17857
|
}
|
|
@@ -17151,13 +17879,10 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17151
17879
|
}));
|
|
17152
17880
|
this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
17153
17881
|
const updatedTargetLocation = getRelativeLocation(destinationGridview.orientation, getGridLocation(destinationGroup.element), destinationTarget);
|
|
17154
|
-
const newGroup = this.createGroupAtLocation(updatedTargetLocation,
|
|
17882
|
+
const newGroup = this.createGroupAtLocation(updatedTargetLocation, this.dropSizing(getGridLocation(destinationGroup.element)), void 0, destinationGridview);
|
|
17155
17883
|
this.movingLock(() => newGroup.model.openPanel(removedPanel, { skipSetActive: true }));
|
|
17156
17884
|
this.doSetGroupAndPanelActive(newGroup);
|
|
17157
|
-
this.
|
|
17158
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
17159
|
-
from: sourceGroup
|
|
17160
|
-
});
|
|
17885
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
17161
17886
|
return;
|
|
17162
17887
|
}
|
|
17163
17888
|
if (sourceGroup.api.location.type === "edge") {
|
|
@@ -17171,13 +17896,10 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17171
17896
|
skipSetActiveGroup: true
|
|
17172
17897
|
}));
|
|
17173
17898
|
if (!removedPanel) throw new Error(`dockview: No panel with id ${sourceItemId}`);
|
|
17174
|
-
const newGroup = this.createGroupAtLocation(targetLocation,
|
|
17899
|
+
const newGroup = this.createGroupAtLocation(targetLocation, this.dropSizing(referenceLocation), void 0, destinationGridview);
|
|
17175
17900
|
this.movingLock(() => newGroup.model.openPanel(removedPanel, { skipSetGroupActive: true }));
|
|
17176
17901
|
this.doSetGroupAndPanelActive(newGroup);
|
|
17177
|
-
this.
|
|
17178
|
-
panel: removedPanel,
|
|
17179
|
-
from: sourceGroup
|
|
17180
|
-
});
|
|
17902
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
17181
17903
|
return;
|
|
17182
17904
|
}
|
|
17183
17905
|
const targetGroup = this.movingLock(() => this.doRemoveGroup(sourceGroup, {
|
|
@@ -17186,13 +17908,10 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17186
17908
|
}));
|
|
17187
17909
|
const updatedReferenceLocation = getGridLocation(destinationGroup.element);
|
|
17188
17910
|
const location = getRelativeLocation(destinationGridview.orientation, updatedReferenceLocation, destinationTarget);
|
|
17189
|
-
this.movingLock(() => this.doAddGroup(targetGroup, location,
|
|
17911
|
+
this.movingLock(() => this.doAddGroup(targetGroup, location, this.dropSizing(updatedReferenceLocation), destinationGridview));
|
|
17190
17912
|
this.setGroupLocationForRoot(targetGroup, destinationGridview);
|
|
17191
17913
|
this.doSetGroupAndPanelActive(targetGroup);
|
|
17192
|
-
this.
|
|
17193
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
17194
|
-
from: sourceGroup
|
|
17195
|
-
});
|
|
17914
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
17196
17915
|
} else {
|
|
17197
17916
|
/**
|
|
17198
17917
|
* The group we are removing from has many panels, we need to remove the panels we are moving,
|
|
@@ -17204,13 +17923,10 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17204
17923
|
}));
|
|
17205
17924
|
if (!removedPanel) throw new Error(`dockview: No panel with id ${sourceItemId}`);
|
|
17206
17925
|
const dropLocation = getRelativeLocation(destinationGridview.orientation, referenceLocation, destinationTarget);
|
|
17207
|
-
const group = this.createGroupAtLocation(dropLocation,
|
|
17926
|
+
const group = this.createGroupAtLocation(dropLocation, this.dropSizing(referenceLocation), void 0, destinationGridview);
|
|
17208
17927
|
this.movingLock(() => group.model.openPanel(removedPanel, { skipSetGroupActive: true }));
|
|
17209
17928
|
this.doSetGroupAndPanelActive(group);
|
|
17210
|
-
this.
|
|
17211
|
-
panel: removedPanel,
|
|
17212
|
-
from: sourceGroup
|
|
17213
|
-
});
|
|
17929
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
17214
17930
|
}
|
|
17215
17931
|
}
|
|
17216
17932
|
}
|
|
@@ -17245,16 +17961,13 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17245
17961
|
});
|
|
17246
17962
|
for (const panel of removedPanels) targetGroup.model.addPanelToTabGroup(newTabGroup.id, panel.id);
|
|
17247
17963
|
if (!options.skipSetActive) this.doSetGroupAndPanelActive(targetGroup);
|
|
17248
|
-
for (const panel of removedPanels) this.
|
|
17249
|
-
panel,
|
|
17250
|
-
from: sourceGroup
|
|
17251
|
-
});
|
|
17964
|
+
for (const panel of removedPanels) this.fireDidMovePanel(panel, sourceGroup);
|
|
17252
17965
|
};
|
|
17253
17966
|
let targetGroup;
|
|
17254
17967
|
if (!destinationTarget || destinationTarget === "center" || !referenceLocation) targetGroup = destinationGroup;
|
|
17255
17968
|
else {
|
|
17256
17969
|
const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
|
|
17257
|
-
targetGroup = this.createGroupAtLocation(dropLocation);
|
|
17970
|
+
targetGroup = this.createGroupAtLocation(dropLocation, this.dropSizing(referenceLocation));
|
|
17258
17971
|
}
|
|
17259
17972
|
if (!options.keepEmptyGroups && sourceGroup.model.size === 0 && sourceGroup !== targetGroup) this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
17260
17973
|
addPanelsToGroup(targetGroup);
|
|
@@ -17269,10 +17982,12 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17269
17982
|
this.mutation("maximize", () => super.exitMaximizedGroup());
|
|
17270
17983
|
}
|
|
17271
17984
|
_doMoveGroup(options) {
|
|
17985
|
+
var _mergedPanels;
|
|
17272
17986
|
const from = options.from.group;
|
|
17273
17987
|
const to = options.to.group;
|
|
17274
17988
|
const target = options.to.position;
|
|
17275
17989
|
let source = from;
|
|
17990
|
+
let mergedPanels;
|
|
17276
17991
|
if (target === "center") {
|
|
17277
17992
|
const activePanel = from.activePanel;
|
|
17278
17993
|
const tabGroupSnapshots = from.model.getTabGroups().map((tg) => ({
|
|
@@ -17290,6 +18005,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17290
18005
|
skipSetGroupActive: true
|
|
17291
18006
|
});
|
|
17292
18007
|
});
|
|
18008
|
+
mergedPanels = panels;
|
|
17293
18009
|
for (const snapshot of tabGroupSnapshots) {
|
|
17294
18010
|
const newTabGroup = to.model.createTabGroup({
|
|
17295
18011
|
label: snapshot.label,
|
|
@@ -17302,6 +18018,21 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17302
18018
|
if (options.skipSetActive !== true) this.doSetGroupAndPanelActive(to);
|
|
17303
18019
|
else if (!this.activePanel) this.doSetGroupAndPanelActive(to);
|
|
17304
18020
|
} else {
|
|
18021
|
+
const isReorderWithinBranch = (() => {
|
|
18022
|
+
if (from.api.location.type === "edge" || to.api.location.type === "edge") return false;
|
|
18023
|
+
const root = this.getGridviewForGroup(from);
|
|
18024
|
+
if (root !== this.getGridviewForGroup(to)) return false;
|
|
18025
|
+
let fromLocation;
|
|
18026
|
+
let toLocation;
|
|
18027
|
+
try {
|
|
18028
|
+
fromLocation = getGridLocation(from.element);
|
|
18029
|
+
toLocation = getGridLocation(to.element);
|
|
18030
|
+
} catch (_unused) {
|
|
18031
|
+
return false;
|
|
18032
|
+
}
|
|
18033
|
+
if (fromLocation.length === 0 || toLocation.length === 0) return false;
|
|
18034
|
+
return sequenceEquals(tail(fromLocation)[0], tail(toLocation)[0]) && getLocationOrientation(root.orientation, toLocation) === getDirectionOrientation(target);
|
|
18035
|
+
})();
|
|
17305
18036
|
if (from.api.location.type === "edge") {
|
|
17306
18037
|
/**
|
|
17307
18038
|
* Edge groups are permanent structural elements and must
|
|
@@ -17367,23 +18098,17 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17367
18098
|
const referenceLocation = getGridLocation(to.element);
|
|
17368
18099
|
const dropLocation = getRelativeLocation(destGridview.orientation, referenceLocation, target);
|
|
17369
18100
|
let size;
|
|
17370
|
-
|
|
17371
|
-
|
|
17372
|
-
|
|
17373
|
-
|
|
17374
|
-
case "HORIZONTAL":
|
|
17375
|
-
size = referenceLocation.length % 2 == 0 ? from.api.height : from.api.width;
|
|
17376
|
-
break;
|
|
18101
|
+
if (isReorderWithinBranch) size = getDirectionOrientation(target) === "HORIZONTAL" ? from.api.width : from.api.height;
|
|
18102
|
+
else {
|
|
18103
|
+
var _referenceLocation;
|
|
18104
|
+
size = Sizing.Split((_referenceLocation = referenceLocation[referenceLocation.length - 1]) !== null && _referenceLocation !== void 0 ? _referenceLocation : 0);
|
|
17377
18105
|
}
|
|
17378
18106
|
destGridview.addView(source, size, dropLocation);
|
|
17379
18107
|
this.setGroupLocationForRoot(source, destGridview);
|
|
17380
18108
|
}
|
|
17381
18109
|
}
|
|
17382
|
-
source.panels.forEach((panel) => {
|
|
17383
|
-
this.
|
|
17384
|
-
panel,
|
|
17385
|
-
from
|
|
17386
|
-
});
|
|
18110
|
+
((_mergedPanels = mergedPanels) !== null && _mergedPanels !== void 0 ? _mergedPanels : source.panels).forEach((panel) => {
|
|
18111
|
+
this.fireDidMovePanel(panel, from);
|
|
17387
18112
|
});
|
|
17388
18113
|
this.debouncedUpdateAllPositions();
|
|
17389
18114
|
if (options.skipSetActive === false) {
|
|
@@ -17501,6 +18226,16 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17501
18226
|
});
|
|
17502
18227
|
return panel;
|
|
17503
18228
|
}
|
|
18229
|
+
/**
|
|
18230
|
+
* Sizing for a group created by a drop next to `referenceLocation`: half
|
|
18231
|
+
* of the group the overlay was drawn over, leaving its siblings alone, so
|
|
18232
|
+
* the panel lands in the region the overlay indicated (#1612). Gridview
|
|
18233
|
+
* rewrites the index to 0 when a cross-axis drop wraps the reference in a
|
|
18234
|
+
* new branch, so one value serves both paths.
|
|
18235
|
+
*/
|
|
18236
|
+
dropSizing(referenceLocation) {
|
|
18237
|
+
return Sizing.Split(referenceLocation.length === 0 ? 0 : referenceLocation[referenceLocation.length - 1]);
|
|
18238
|
+
}
|
|
17504
18239
|
createGroupAtLocation(location, size, options, gridview = this.gridview) {
|
|
17505
18240
|
const group = this.createGroup(options);
|
|
17506
18241
|
this.doAddGroup(group, location, size, gridview);
|
|
@@ -17560,22 +18295,22 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17560
18295
|
return location.length % 2 == 1 ? rootOrientation : orthogonal(rootOrientation);
|
|
17561
18296
|
}
|
|
17562
18297
|
updateTheme() {
|
|
17563
|
-
var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe23, _this$_popoutWindowSe24, _this$
|
|
18298
|
+
var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe23, _this$_popoutWindowSe24, _this$_shellManager5, _theme$edgeGroupColla, _theme$tabGroupIndica;
|
|
17564
18299
|
const theme = (_this$_options$theme = this._options.theme) !== null && _this$_options$theme !== void 0 ? _this$_options$theme : themeAbyss;
|
|
17565
18300
|
(_this$_shellThemeClas = this._shellThemeClassnames) === null || _this$_shellThemeClas === void 0 || _this$_shellThemeClas.setClassNames(theme.className);
|
|
17566
18301
|
const gap = (_theme$gap = theme.gap) !== null && _theme$gap !== void 0 ? _theme$gap : 0;
|
|
17567
18302
|
this.gridview.margin = gap;
|
|
17568
18303
|
for (const floating of this.floatingGroups) floating.gridview.margin = gap;
|
|
17569
18304
|
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;
|
|
17570
|
-
(_this$
|
|
18305
|
+
(_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);
|
|
17571
18306
|
if (theme.dndOverlayBorder === void 0) {
|
|
17572
|
-
var _this$
|
|
18307
|
+
var _this$_shellManager6;
|
|
17573
18308
|
this.element.style.removeProperty("--dv-drag-over-border");
|
|
17574
|
-
(_this$
|
|
18309
|
+
(_this$_shellManager6 = this._shellManager) === null || _this$_shellManager6 === void 0 || _this$_shellManager6.element.style.removeProperty("--dv-drag-over-border");
|
|
17575
18310
|
} else {
|
|
17576
|
-
var _this$
|
|
18311
|
+
var _this$_shellManager7;
|
|
17577
18312
|
this.element.style.setProperty("--dv-drag-over-border", theme.dndOverlayBorder);
|
|
17578
|
-
(_this$
|
|
18313
|
+
(_this$_shellManager7 = this._shellManager) === null || _this$_shellManager7 === void 0 || _this$_shellManager7.element.style.setProperty("--dv-drag-over-border", theme.dndOverlayBorder);
|
|
17579
18314
|
}
|
|
17580
18315
|
switch (theme.dndOverlayMounting) {
|
|
17581
18316
|
case "absolute":
|
|
@@ -18474,4 +19209,4 @@ function createPaneview(element, options) {
|
|
|
18474
19209
|
}
|
|
18475
19210
|
|
|
18476
19211
|
//#endregion
|
|
18477
|
-
export { AdvancedDnDModule, AdvancedDnDService, BaseGrid, ContentContainer, DEFAULT_TAB_GROUP_COLORS, DefaultDockviewDeserialzier, DefaultTab, DockviewApi, DockviewComponent, CompositeDisposable as DockviewCompositeDisposable, DockviewDidDropEvent, Disposable as DockviewDisposable, Emitter as DockviewEmitter, Event as DockviewEvent, DockviewGroupPanel, DockviewGroupPanelModel, MutableDisposable as DockviewMutableDisposable, DockviewPanel, DockviewUnhandledDragOverEvent, DockviewWillDropEvent, DockviewWillShowOverlayLocationEvent, DraggablePaneviewPanel, EdgeGroupModule, FloatingGroupModule, Gridview, GridviewApi, GridviewComponent, GridviewPanel, LayoutPriority, LiveRegionModule, LocalSelectionTransfer, OVERFLOW_MAX_TAB_ROWS_VARIABLE, OVERFLOW_WRAP_TABS_CAPPED_CLASS, OVERFLOW_WRAP_TABS_CLASS, OVERFLOW_WRAP_TABS_VERTICAL_TAB_HEIGHT_VARIABLE, Orientation, PROPERTY_KEYS_DOCKVIEW, PROPERTY_KEYS_GRIDVIEW, PROPERTY_KEYS_PANEVIEW, PROPERTY_KEYS_SPLITVIEW, PaneFramework, PaneTransfer, PanelTransfer, Paneview, PaneviewApi, PaneviewComponent, PaneviewPanel, PaneviewUnhandledDragOverEvent, SashState, Sizing, Splitview, SplitviewApi, SplitviewComponent, SplitviewPanel, Tab, TabGroupChipsModule, TabGroupChipsService, TabGroupColorPalette, applyTabGroupAccent, clearRegisteredModules, createCloseButton, createDismissableLayer, createDockview, createGridview, createPaneview, createPinButton, createSplitview, defineModule, directionToPosition, findRelativeZIndexParent, getDirectionOrientation, getGridLocation, getLocationOrientation, getPaneData, getPanelData, getRegisteredModules, getRelativeLocation, indexInParent, isAnyEdgeGroupEnabled, isEdgeGroupEnabled, isGridBranchNode, isGroupOptionsWithGroup, isGroupOptionsWithPanel, isPanelOptionsWithGroup, isPanelOptionsWithPanel, orthogonal, positionToDirection, prefersReducedMotion, registerModules, resolveMessages, resolveOpaqueBackground, resolveTabGroupAccent, themeAbyss, themeAbyssSpaced, themeCatppuccinMocha, themeCatppuccinMochaSpaced, themeDark, themeDracula, themeGithubDark, themeGithubDarkSpaced, themeGithubLight, themeGithubLightSpaced, themeLight, themeLightSpaced, themeMonokai, themeNord, themeNordSpaced, themeSolarizedLight, themeSolarizedLightSpaced, themeVisualStudio, toTarget };
|
|
19212
|
+
export { AdvancedDnDModule, AdvancedDnDService, BaseGrid, ContentContainer, ContextMenuController, ContextMenuModule, DEFAULT_TAB_GROUP_COLORS, DefaultDockviewDeserialzier, DefaultTab, DockviewApi, DockviewComponent, CompositeDisposable as DockviewCompositeDisposable, DockviewDidDropEvent, Disposable as DockviewDisposable, Emitter as DockviewEmitter, Event as DockviewEvent, DockviewGroupPanel, DockviewGroupPanelModel, MutableDisposable as DockviewMutableDisposable, DockviewPanel, DockviewUnhandledDragOverEvent, DockviewWillDropEvent, DockviewWillShowOverlayLocationEvent, DraggablePaneviewPanel, EdgeGroupModule, FloatingGroupModule, Gridview, GridviewApi, GridviewComponent, GridviewPanel, LayoutPriority, LiveRegionModule, LocalSelectionTransfer, OVERFLOW_MAX_TAB_ROWS_VARIABLE, OVERFLOW_WRAP_TABS_CAPPED_CLASS, OVERFLOW_WRAP_TABS_CLASS, OVERFLOW_WRAP_TABS_VERTICAL_TAB_HEIGHT_VARIABLE, Orientation, PROPERTY_KEYS_DOCKVIEW, PROPERTY_KEYS_GRIDVIEW, PROPERTY_KEYS_PANEVIEW, PROPERTY_KEYS_SPLITVIEW, PaneFramework, PaneTransfer, PanelTransfer, Paneview, PaneviewApi, PaneviewComponent, PaneviewPanel, PaneviewUnhandledDragOverEvent, SashState, Sizing, Splitview, SplitviewApi, SplitviewComponent, SplitviewPanel, Tab, TabGroupChipsModule, TabGroupChipsService, TabGroupColorPalette, applyTabGroupAccent, clearRegisteredModules, createCloseButton, createDismissableLayer, createDockview, createGridview, createPaneview, createPinButton, createSplitview, defineModule, directionToPosition, findRelativeZIndexParent, getDirectionOrientation, getGridLocation, getLocationOrientation, getPaneData, getPanelData, getRegisteredModules, getRelativeLocation, indexInParent, isAnyEdgeGroupEnabled, isEdgeGroupEnabled, isGridBranchNode, isGroupOptionsWithGroup, isGroupOptionsWithPanel, isPanelOptionsWithGroup, isPanelOptionsWithPanel, orthogonal, positionToDirection, prefersReducedMotion, registerModules, resolveMessages, resolveOpaqueBackground, resolveTabGroupAccent, themeAbyss, themeAbyssSpaced, themeCatppuccinMocha, themeCatppuccinMochaSpaced, themeDark, themeDracula, themeGithubDark, themeGithubDarkSpaced, themeGithubLight, themeGithubLightSpaced, themeLight, themeLightSpaced, themeMonokai, themeNord, themeNordSpaced, themeSolarizedLight, themeSolarizedLightSpaced, themeVisualStudio, toTarget };
|