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
|
*/
|
|
@@ -1055,8 +1055,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
1055
1055
|
container.appendChild(view.element);
|
|
1056
1056
|
let viewSize;
|
|
1057
1057
|
if (typeof size === "number") viewSize = size;
|
|
1058
|
-
else if (size.type === "split")
|
|
1059
|
-
|
|
1058
|
+
else if (size.type === "split") {
|
|
1059
|
+
const splitTarget = this.viewItems[size.index];
|
|
1060
|
+
if (splitTarget) {
|
|
1061
|
+
const half = Math.floor(splitTarget.size / 2);
|
|
1062
|
+
viewSize = splitTarget.size - half;
|
|
1063
|
+
splitTarget.size = half;
|
|
1064
|
+
} else viewSize = this.getViewSize(size.index) / 2;
|
|
1065
|
+
} else if (size.type === "invisible") viewSize = { cachedVisibleSize: size.cachedVisibleSize };
|
|
1060
1066
|
else viewSize = view.minimumSize;
|
|
1061
1067
|
const disposable = view.onDidChange((newSize) => this.onDidChange(viewItem, newSize.size));
|
|
1062
1068
|
const viewItem = new ViewItem(container, view, viewSize, { dispose: () => {
|
|
@@ -5801,7 +5807,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
5801
5807
|
};
|
|
5802
5808
|
case "auto":
|
|
5803
5809
|
case void 0:
|
|
5804
|
-
default: return isCoarsePrimaryInput$
|
|
5810
|
+
default: return isCoarsePrimaryInput$2() ? {
|
|
5805
5811
|
html5: false,
|
|
5806
5812
|
pointer: true,
|
|
5807
5813
|
pointerHandlesMouse: true
|
|
@@ -5812,7 +5818,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
5812
5818
|
};
|
|
5813
5819
|
}
|
|
5814
5820
|
}
|
|
5815
|
-
function isCoarsePrimaryInput$
|
|
5821
|
+
function isCoarsePrimaryInput$2() {
|
|
5816
5822
|
if (globalThis.window === void 0 || !globalThis.matchMedia) return false;
|
|
5817
5823
|
const coarse = globalThis.matchMedia("(pointer: coarse)").matches;
|
|
5818
5824
|
const fine = globalThis.matchMedia("(pointer: fine)").matches;
|
|
@@ -7967,11 +7973,28 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
7967
7973
|
if (this._voidContainer && related && (related === this._voidContainer || this._voidContainer.contains(related))) return;
|
|
7968
7974
|
this.resetTabTransforms();
|
|
7969
7975
|
if (this._animState.sourceIndex === -1) {
|
|
7970
|
-
|
|
7971
|
-
(_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();
|
|
7976
|
+
this.clearHeaderAnchorOverlay();
|
|
7972
7977
|
this._animState = null;
|
|
7973
7978
|
} else this._animState.currentInsertionIndex = null;
|
|
7974
7979
|
}
|
|
7980
|
+
/**
|
|
7981
|
+
* Clear the anchored overlay only when this header is what rendered it.
|
|
7982
|
+
* The container is shared with the group's content drop target, which
|
|
7983
|
+
* renders into it on the same frame the cursor leaves the strip: the
|
|
7984
|
+
* pointer backend calls `handleDragOver` on the new target before the
|
|
7985
|
+
* global `onDragMove` that reaches us (#1612).
|
|
7986
|
+
*/
|
|
7987
|
+
clearHeaderAnchorOverlay() {
|
|
7988
|
+
var _container$model;
|
|
7989
|
+
const container = this.group.model.dropTargetContainer;
|
|
7990
|
+
const outline = container === null || container === void 0 ? void 0 : container.renderedOutline;
|
|
7991
|
+
if (outline && ![
|
|
7992
|
+
this._tabsList,
|
|
7993
|
+
this._voidContainer,
|
|
7994
|
+
this._extendedDropZone
|
|
7995
|
+
].some((scope) => scope === null || scope === void 0 ? void 0 : scope.contains(outline))) return;
|
|
7996
|
+
container === null || container === void 0 || (_container$model = container.model) === null || _container$model === void 0 || _container$model.clear();
|
|
7997
|
+
}
|
|
7975
7998
|
handleDragOver(event) {
|
|
7976
7999
|
var _this$accessor$option2;
|
|
7977
8000
|
if (!this._animState) return;
|
|
@@ -10527,7 +10550,11 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
10527
10550
|
this.panels.forEach((panel) => {
|
|
10528
10551
|
this.rerender(panel);
|
|
10529
10552
|
});
|
|
10530
|
-
if (this._activePanel)
|
|
10553
|
+
if (this._activePanel) {
|
|
10554
|
+
this.contentContainer.renderPanel(this._activePanel, { asActive: true });
|
|
10555
|
+
const { width, height } = this.contentDimensions();
|
|
10556
|
+
this._activePanel.layout(width, height);
|
|
10557
|
+
}
|
|
10531
10558
|
}
|
|
10532
10559
|
get renderContainer() {
|
|
10533
10560
|
var _this$_overwriteRende;
|
|
@@ -11492,7 +11519,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
11492
11519
|
this._group = value;
|
|
11493
11520
|
this._onDidGroupChange.fire({});
|
|
11494
11521
|
this.setupGroupEventListeners(oldGroup);
|
|
11495
|
-
this.
|
|
11522
|
+
this.fireLocationChange();
|
|
11496
11523
|
}
|
|
11497
11524
|
}
|
|
11498
11525
|
get group() {
|
|
@@ -11568,6 +11595,23 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
11568
11595
|
exitMaximized() {
|
|
11569
11596
|
this.group.api.exitMaximized();
|
|
11570
11597
|
}
|
|
11598
|
+
/**
|
|
11599
|
+
* Report that this panel's location may have moved.
|
|
11600
|
+
*
|
|
11601
|
+
* A relocation touches the location more than once - the panel is
|
|
11602
|
+
* reparented into the destination group, then that group is tagged with
|
|
11603
|
+
* the location it ends up at - so the event is coalesced to the end of the
|
|
11604
|
+
* enclosing layout mutation and reports where the panel actually settled.
|
|
11605
|
+
* Firing each signal as it happened surfaced an intermediate `grid`
|
|
11606
|
+
* location the panel was never in, at a point where it was in neither
|
|
11607
|
+
* group's panel list. Outside a mutation this fires straight away.
|
|
11608
|
+
*/
|
|
11609
|
+
fireLocationChange() {
|
|
11610
|
+
this.accessor.deferLocationChange(this, () => {
|
|
11611
|
+
if (this.isDisposed) return;
|
|
11612
|
+
this._onDidLocationChange.fire({ location: this.location });
|
|
11613
|
+
});
|
|
11614
|
+
}
|
|
11571
11615
|
setupGroupEventListeners(previousGroup) {
|
|
11572
11616
|
var _previousGroup$isActi;
|
|
11573
11617
|
let _trackGroupActive = (_previousGroup$isActi = previousGroup === null || previousGroup === void 0 ? void 0 : previousGroup.isActive) !== null && _previousGroup$isActi !== void 0 ? _previousGroup$isActi : false;
|
|
@@ -11576,9 +11620,9 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
11576
11620
|
const hasBecomeVisible = event.isVisible && !this.isVisible;
|
|
11577
11621
|
const isActivePanel = this.group.model.isPanelActive(this.panel);
|
|
11578
11622
|
if (hasBecomeHidden || hasBecomeVisible && isActivePanel) this._onDidVisibilityChange.fire(event);
|
|
11579
|
-
}), this.group.api.onDidLocationChange((
|
|
11623
|
+
}), this.group.api.onDidLocationChange(() => {
|
|
11580
11624
|
if (this.group !== this.panel.group) return;
|
|
11581
|
-
this.
|
|
11625
|
+
this.fireLocationChange();
|
|
11582
11626
|
}), this.group.api.onDidActiveChange(() => {
|
|
11583
11627
|
if (this.group !== this.panel.group) return;
|
|
11584
11628
|
if (_trackGroupActive !== this.isGroupActive) {
|
|
@@ -12380,7 +12424,6 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
12380
12424
|
"AdvancedOverflow",
|
|
12381
12425
|
"AutoEdgeGroup",
|
|
12382
12426
|
"AutoHideEdgeGroup",
|
|
12383
|
-
"ContextMenu",
|
|
12384
12427
|
"DndCompass",
|
|
12385
12428
|
"KeyboardDocking",
|
|
12386
12429
|
"KeyboardNavigation",
|
|
@@ -12462,8 +12505,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
12462
12505
|
* case: calling `undo()` having never set the option at all.
|
|
12463
12506
|
*
|
|
12464
12507
|
* Interaction handlers are queries in this sense too: a right-click reaching an
|
|
12465
|
-
* absent
|
|
12466
|
-
*
|
|
12508
|
+
* absent module means the app never asked for that feature, so it stays silent
|
|
12509
|
+
* (`?.`) and the browser's own behaviour applies. Options are where intent is
|
|
12467
12510
|
* declared; see `optionsModules.ts`.
|
|
12468
12511
|
*/
|
|
12469
12512
|
function assertModule(service, moduleName, context) {
|
|
@@ -12543,10 +12586,9 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
12543
12586
|
*
|
|
12544
12587
|
* This is the "declared intent" diagnostic. It fires when the user asks for a
|
|
12545
12588
|
* feature via options, at construction and on every `updateOptions`. It
|
|
12546
|
-
* deliberately does *not* fire on user interaction:
|
|
12547
|
-
*
|
|
12548
|
-
*
|
|
12549
|
-
* app never wanted.
|
|
12589
|
+
* deliberately does *not* fire on user interaction: an interaction reaching an
|
|
12590
|
+
* absent module stays silent, because the `?.` service-slot call sites can't
|
|
12591
|
+
* tell a missing module from a feature the app never wanted.
|
|
12550
12592
|
*
|
|
12551
12593
|
* Rules are a flat list rather than a `Record<keyof DockviewOptions, ...>`
|
|
12552
12594
|
* because dockview's options are nested and value-gated: `overflow.mode:
|
|
@@ -12642,18 +12684,6 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
12642
12684
|
moduleName: "AutoEdgeGroup",
|
|
12643
12685
|
when: (o) => isAnyEdgeGroupEnabled(o.dockToEdgeGroups)
|
|
12644
12686
|
},
|
|
12645
|
-
{
|
|
12646
|
-
optionKey: "getTabContextMenuItems",
|
|
12647
|
-
reason: "getTabContextMenuItems",
|
|
12648
|
-
moduleName: "ContextMenu",
|
|
12649
|
-
when: (o) => o.getTabContextMenuItems != null
|
|
12650
|
-
},
|
|
12651
|
-
{
|
|
12652
|
-
optionKey: "getTabGroupChipContextMenuItems",
|
|
12653
|
-
reason: "getTabGroupChipContextMenuItems",
|
|
12654
|
-
moduleName: "ContextMenu",
|
|
12655
|
-
when: (o) => o.getTabGroupChipContextMenuItems != null
|
|
12656
|
-
},
|
|
12657
12687
|
{
|
|
12658
12688
|
optionKey: "dndCompass",
|
|
12659
12689
|
reason: "dndCompass",
|
|
@@ -13554,6 +13584,270 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13554
13584
|
}
|
|
13555
13585
|
});
|
|
13556
13586
|
|
|
13587
|
+
//#endregion
|
|
13588
|
+
//#region src/dockview/contextMenuService.ts
|
|
13589
|
+
function popoverZIndexFor(target, group) {
|
|
13590
|
+
var _group$api, _group$api$isPeeking;
|
|
13591
|
+
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)";
|
|
13592
|
+
if (!(target instanceof HTMLElement)) return;
|
|
13593
|
+
const relativeParent = findRelativeZIndexParent(target);
|
|
13594
|
+
return (relativeParent === null || relativeParent === void 0 ? void 0 : relativeParent.style.zIndex) ? `calc(${relativeParent.style.zIndex} * 2)` : void 0;
|
|
13595
|
+
}
|
|
13596
|
+
let _nextId = 0;
|
|
13597
|
+
const nextContextMenuItemId = () => `dv-ctx-menu-item-${_nextId++}`;
|
|
13598
|
+
function isItemConfig(item) {
|
|
13599
|
+
return typeof item === "object";
|
|
13600
|
+
}
|
|
13601
|
+
function buildItem(label, close, action, disabled) {
|
|
13602
|
+
const el = document.createElement("div");
|
|
13603
|
+
el.className = "dv-context-menu-item";
|
|
13604
|
+
el.setAttribute("role", "menuitem");
|
|
13605
|
+
if (disabled) {
|
|
13606
|
+
el.classList.add("dv-context-menu-item--disabled");
|
|
13607
|
+
el.setAttribute("aria-disabled", "true");
|
|
13608
|
+
}
|
|
13609
|
+
el.textContent = label;
|
|
13610
|
+
if (!disabled) el.addEventListener("click", () => {
|
|
13611
|
+
action();
|
|
13612
|
+
close();
|
|
13613
|
+
});
|
|
13614
|
+
return el;
|
|
13615
|
+
}
|
|
13616
|
+
function buildSeparator() {
|
|
13617
|
+
const el = document.createElement("div");
|
|
13618
|
+
el.className = "dv-context-menu-separator";
|
|
13619
|
+
el.setAttribute("role", "separator");
|
|
13620
|
+
return el;
|
|
13621
|
+
}
|
|
13622
|
+
function isCoarsePrimaryInput$1() {
|
|
13623
|
+
if (globalThis.window === void 0 || !globalThis.matchMedia) return false;
|
|
13624
|
+
const coarse = globalThis.matchMedia("(pointer: coarse)").matches;
|
|
13625
|
+
const fine = globalThis.matchMedia("(pointer: fine)").matches;
|
|
13626
|
+
return coarse && !fine;
|
|
13627
|
+
}
|
|
13628
|
+
function buildRenameInput(tabGroup) {
|
|
13629
|
+
const wrapper = document.createElement("div");
|
|
13630
|
+
wrapper.className = "dv-context-menu-rename";
|
|
13631
|
+
const input = document.createElement("input");
|
|
13632
|
+
input.className = "dv-context-menu-rename-input";
|
|
13633
|
+
input.type = "text";
|
|
13634
|
+
input.placeholder = "Name This Group";
|
|
13635
|
+
input.value = tabGroup.label;
|
|
13636
|
+
input.addEventListener("input", () => {
|
|
13637
|
+
tabGroup.setLabel(input.value);
|
|
13638
|
+
});
|
|
13639
|
+
input.addEventListener("keydown", (e) => {
|
|
13640
|
+
if (e.key !== "Escape" && e.key !== "Enter") e.stopPropagation();
|
|
13641
|
+
});
|
|
13642
|
+
input.addEventListener("click", (e) => {
|
|
13643
|
+
e.stopPropagation();
|
|
13644
|
+
});
|
|
13645
|
+
wrapper.appendChild(input);
|
|
13646
|
+
if (!isCoarsePrimaryInput$1()) requestAnimationFrame(() => {
|
|
13647
|
+
input.focus();
|
|
13648
|
+
input.select();
|
|
13649
|
+
});
|
|
13650
|
+
return wrapper;
|
|
13651
|
+
}
|
|
13652
|
+
function buildColorPicker(tabGroup, palette) {
|
|
13653
|
+
const wrapper = document.createElement("div");
|
|
13654
|
+
wrapper.className = "dv-context-menu-color-picker";
|
|
13655
|
+
if (!palette.enabled) return wrapper;
|
|
13656
|
+
for (const entry of palette.entries()) {
|
|
13657
|
+
const swatch = document.createElement("div");
|
|
13658
|
+
swatch.className = "dv-context-menu-color-swatch";
|
|
13659
|
+
swatch.style.setProperty("--dv-tab-group-color", entry.value);
|
|
13660
|
+
if (entry.label) swatch.title = entry.label;
|
|
13661
|
+
if (tabGroup.color === entry.id) swatch.classList.add("dv-context-menu-color-swatch--selected");
|
|
13662
|
+
swatch.addEventListener("click", () => {
|
|
13663
|
+
tabGroup.setColor(entry.id);
|
|
13664
|
+
});
|
|
13665
|
+
wrapper.appendChild(swatch);
|
|
13666
|
+
}
|
|
13667
|
+
return wrapper;
|
|
13668
|
+
}
|
|
13669
|
+
var ContextMenuController = class {
|
|
13670
|
+
constructor(accessor) {
|
|
13671
|
+
this.accessor = accessor;
|
|
13672
|
+
}
|
|
13673
|
+
/**
|
|
13674
|
+
* A single maximize/restore toggle whose label and behaviour track the
|
|
13675
|
+
* group's live state: it reads *Restore* + calls `exitMaximized` when the
|
|
13676
|
+
* group is maximized, otherwise *Maximize* + `maximize`. Only grid groups
|
|
13677
|
+
* can be maximized, so the item is disabled for floating / popout panels
|
|
13678
|
+
* that are not already maximized.
|
|
13679
|
+
*/
|
|
13680
|
+
buildMaximizeItem(panel, close) {
|
|
13681
|
+
const isMaximized = panel.api.isMaximized();
|
|
13682
|
+
return buildItem(isMaximized ? "Restore" : "Maximize", close, isMaximized ? () => panel.api.exitMaximized() : () => panel.api.maximize(), !isMaximized && panel.api.location.type !== "grid");
|
|
13683
|
+
}
|
|
13684
|
+
/**
|
|
13685
|
+
* A single collapse/expand toggle whose label tracks the tab group's live
|
|
13686
|
+
* state: *Expand* when the group is already collapsed, otherwise *Collapse*.
|
|
13687
|
+
*/
|
|
13688
|
+
buildCollapseItem(tabGroup, close) {
|
|
13689
|
+
return buildItem(tabGroup.collapsed ? "Expand" : "Collapse", close, () => tabGroup.toggle());
|
|
13690
|
+
}
|
|
13691
|
+
/**
|
|
13692
|
+
* Whether to auto-inject the built-in Pin/Unpin item at the top of the tab
|
|
13693
|
+
* menu. True only when the PinnedTabs module is registered, pinning is
|
|
13694
|
+
* enabled, and the app has not opted out via `pinnedTabs.contextMenuItem:
|
|
13695
|
+
* false` (the item is on by default). This keeps pinning reachable from the
|
|
13696
|
+
* menu without the app having to return `'pin'` from
|
|
13697
|
+
* `getTabContextMenuItems` itself.
|
|
13698
|
+
*/
|
|
13699
|
+
_shouldInjectPin() {
|
|
13700
|
+
const pinnedTabs = this.accessor.options.pinnedTabs;
|
|
13701
|
+
return !!this.accessor.pinnedTabsService && !!(pinnedTabs === null || pinnedTabs === void 0 ? void 0 : pinnedTabs.enabled) && pinnedTabs.contextMenuItem !== false;
|
|
13702
|
+
}
|
|
13703
|
+
/**
|
|
13704
|
+
* The tab menu items: the app's own items (if any) with the built-in
|
|
13705
|
+
* `'pin'` item prepended when {@link _shouldInjectPin} applies, so the app
|
|
13706
|
+
* keeps full control of its list, and pinning is added without disturbing
|
|
13707
|
+
* it. Reuses the existing `'pin'` token rendering below.
|
|
13708
|
+
*/
|
|
13709
|
+
_resolveTabItems(panel, group, event) {
|
|
13710
|
+
var _this$accessor$option, _this$accessor$option2, _this$accessor$option3;
|
|
13711
|
+
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, {
|
|
13712
|
+
panel,
|
|
13713
|
+
group,
|
|
13714
|
+
api: this.accessor.api,
|
|
13715
|
+
event
|
|
13716
|
+
})) !== null && _this$accessor$option !== void 0 ? _this$accessor$option : [];
|
|
13717
|
+
return this._shouldInjectPin() ? ["pin", ...appItems] : appItems;
|
|
13718
|
+
}
|
|
13719
|
+
/**
|
|
13720
|
+
* Render a custom `component` menu item and append it to `menuEl`. Builds
|
|
13721
|
+
* the framework renderer via the host's `createContextMenuItemComponent`
|
|
13722
|
+
* factory and initialises it. Shared by the tab menu and the chip menu,
|
|
13723
|
+
* which differ only in `identity`: the tab menu passes the `panel`, the chip
|
|
13724
|
+
* menu passes the `tabGroup`. No-op when no renderer could be created (no
|
|
13725
|
+
* factory configured, or the factory declined the component).
|
|
13726
|
+
*/
|
|
13727
|
+
appendComponentItem(menuEl, item, identity, group, close) {
|
|
13728
|
+
var _this$accessor$option4, _this$accessor$option5;
|
|
13729
|
+
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, {
|
|
13730
|
+
id: nextContextMenuItemId(),
|
|
13731
|
+
component: item.component
|
|
13732
|
+
});
|
|
13733
|
+
if (!renderer) return;
|
|
13734
|
+
renderer.init(_objectSpread2(_objectSpread2({}, identity), {}, {
|
|
13735
|
+
group,
|
|
13736
|
+
api: this.accessor.api,
|
|
13737
|
+
close,
|
|
13738
|
+
componentProps: item.componentProps
|
|
13739
|
+
}));
|
|
13740
|
+
menuEl.appendChild(renderer.element);
|
|
13741
|
+
}
|
|
13742
|
+
/**
|
|
13743
|
+
* The element for one built-in tab item, or `undefined` for a token this
|
|
13744
|
+
* version doesn't know (an app on a newer typings version, or plain JS):
|
|
13745
|
+
* an unrecognised token renders nothing rather than throwing.
|
|
13746
|
+
*/
|
|
13747
|
+
buildBuiltInTabItem(item, panel, group, close) {
|
|
13748
|
+
switch (item) {
|
|
13749
|
+
case "separator": return buildSeparator();
|
|
13750
|
+
case "close": return buildItem("Close", close, () => panel.api.close());
|
|
13751
|
+
case "closeOthers": return buildItem("Close Others", close, () => {
|
|
13752
|
+
group.panels.filter((p) => p !== panel).forEach((p) => p.api.close());
|
|
13753
|
+
});
|
|
13754
|
+
case "closeAll": return buildItem("Close All", close, () => {
|
|
13755
|
+
[...group.panels].forEach((p) => p.api.close());
|
|
13756
|
+
});
|
|
13757
|
+
case "closeLeft": {
|
|
13758
|
+
const index = group.panels.indexOf(panel);
|
|
13759
|
+
return buildItem("Close to the Left", close, () => {
|
|
13760
|
+
group.panels.filter((_, i) => i < index).forEach((p) => p.api.close());
|
|
13761
|
+
}, index <= 0);
|
|
13762
|
+
}
|
|
13763
|
+
case "closeRight": {
|
|
13764
|
+
const index = group.panels.indexOf(panel);
|
|
13765
|
+
return buildItem("Close to the Right", close, () => {
|
|
13766
|
+
group.panels.filter((_, i) => i > index).forEach((p) => p.api.close());
|
|
13767
|
+
}, index === -1 || index >= group.panels.length - 1);
|
|
13768
|
+
}
|
|
13769
|
+
case "maximize": return this.buildMaximizeItem(panel, close);
|
|
13770
|
+
case "float": return buildItem("Float", close, () => this.accessor.api.addFloatingGroup(panel), panel.api.location.type === "floating");
|
|
13771
|
+
case "popout": return buildItem("Open in New Window", close, () => {
|
|
13772
|
+
this.accessor.api.addPopoutGroup(panel);
|
|
13773
|
+
}, panel.api.location.type === "popout");
|
|
13774
|
+
case "pin": return buildItem(panel.api.isPinned ? "Unpin tab" : "Pin tab", close, () => panel.api.setPinned(!panel.api.isPinned));
|
|
13775
|
+
default: return;
|
|
13776
|
+
}
|
|
13777
|
+
}
|
|
13778
|
+
/**
|
|
13779
|
+
* Append one app-supplied item. A raw `element` is used as-is, a
|
|
13780
|
+
* `component` goes through the framework renderer, and a `label` builds the
|
|
13781
|
+
* default row; an item carrying none of the three renders nothing. Shared
|
|
13782
|
+
* by both menus, which differ only in `identity`.
|
|
13783
|
+
*/
|
|
13784
|
+
appendConfigItem(menuEl, item, identity, group, close) {
|
|
13785
|
+
if (item.element) menuEl.appendChild(item.element);
|
|
13786
|
+
else if (item.component) this.appendComponentItem(menuEl, item, identity, group, close);
|
|
13787
|
+
else if (item.label) menuEl.appendChild(buildItem(item.label, close, () => {
|
|
13788
|
+
var _item$action;
|
|
13789
|
+
return (_item$action = item.action) === null || _item$action === void 0 ? void 0 : _item$action.call(item);
|
|
13790
|
+
}, item.disabled));
|
|
13791
|
+
}
|
|
13792
|
+
show(panel, group, event) {
|
|
13793
|
+
const items = this._resolveTabItems(panel, group, event);
|
|
13794
|
+
if (items.length === 0) return;
|
|
13795
|
+
event.preventDefault();
|
|
13796
|
+
const popupService = this.accessor.getPopupServiceForGroup(group);
|
|
13797
|
+
const close = () => popupService.close();
|
|
13798
|
+
const menuEl = document.createElement("div");
|
|
13799
|
+
menuEl.className = "dv-context-menu";
|
|
13800
|
+
menuEl.setAttribute("role", "menu");
|
|
13801
|
+
for (const item of items) {
|
|
13802
|
+
if (isItemConfig(item)) {
|
|
13803
|
+
this.appendConfigItem(menuEl, item, { panel }, group, close);
|
|
13804
|
+
continue;
|
|
13805
|
+
}
|
|
13806
|
+
const el = this.buildBuiltInTabItem(item, panel, group, close);
|
|
13807
|
+
if (el) menuEl.appendChild(el);
|
|
13808
|
+
}
|
|
13809
|
+
popupService.openPopover(menuEl, {
|
|
13810
|
+
x: event.clientX,
|
|
13811
|
+
y: event.clientY,
|
|
13812
|
+
zIndex: popoverZIndexFor(event.target, group)
|
|
13813
|
+
});
|
|
13814
|
+
}
|
|
13815
|
+
showForChip(tabGroup, group, event) {
|
|
13816
|
+
if (!this.accessor.options.getTabGroupChipContextMenuItems) return;
|
|
13817
|
+
const items = this.accessor.options.getTabGroupChipContextMenuItems({
|
|
13818
|
+
tabGroup,
|
|
13819
|
+
group,
|
|
13820
|
+
api: this.accessor.api,
|
|
13821
|
+
event
|
|
13822
|
+
});
|
|
13823
|
+
if (items.length === 0) return;
|
|
13824
|
+
event.preventDefault();
|
|
13825
|
+
const popupService = this.accessor.getPopupServiceForGroup(group);
|
|
13826
|
+
const close = () => popupService.close();
|
|
13827
|
+
const menuEl = document.createElement("div");
|
|
13828
|
+
menuEl.className = "dv-context-menu";
|
|
13829
|
+
menuEl.setAttribute("role", "menu");
|
|
13830
|
+
for (const item of items) if (item === "separator") menuEl.appendChild(buildSeparator());
|
|
13831
|
+
else if (item === "rename") menuEl.appendChild(buildRenameInput(tabGroup));
|
|
13832
|
+
else if (item === "colorPicker") menuEl.appendChild(buildColorPicker(tabGroup, this.accessor.tabGroupColorPalette));
|
|
13833
|
+
else if (item === "collapse") menuEl.appendChild(this.buildCollapseItem(tabGroup, close));
|
|
13834
|
+
else if (item === "close") menuEl.appendChild(buildItem("Close All", close, () => {
|
|
13835
|
+
group.panels.filter((p) => tabGroup.containsPanel(p.id)).forEach((p) => p.api.close());
|
|
13836
|
+
}));
|
|
13837
|
+
else if (isItemConfig(item)) this.appendConfigItem(menuEl, item, { tabGroup }, group, close);
|
|
13838
|
+
popupService.openPopover(menuEl, {
|
|
13839
|
+
x: event.clientX,
|
|
13840
|
+
y: event.clientY,
|
|
13841
|
+
zIndex: popoverZIndexFor(event.target, group)
|
|
13842
|
+
});
|
|
13843
|
+
}
|
|
13844
|
+
};
|
|
13845
|
+
const ContextMenuModule = defineModule({
|
|
13846
|
+
name: "ContextMenu",
|
|
13847
|
+
serviceKey: "contextMenuService",
|
|
13848
|
+
create: (host) => new ContextMenuController(host)
|
|
13849
|
+
});
|
|
13850
|
+
|
|
13557
13851
|
//#endregion
|
|
13558
13852
|
//#region src/dockview/allModules.ts
|
|
13559
13853
|
/**
|
|
@@ -13571,7 +13865,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13571
13865
|
HeaderActionsModule,
|
|
13572
13866
|
LiveRegionModule,
|
|
13573
13867
|
AdvancedDnDModule,
|
|
13574
|
-
TabGroupChipsModule
|
|
13868
|
+
TabGroupChipsModule,
|
|
13869
|
+
ContextMenuModule
|
|
13575
13870
|
];
|
|
13576
13871
|
|
|
13577
13872
|
//#endregion
|
|
@@ -13604,6 +13899,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13604
13899
|
});
|
|
13605
13900
|
}
|
|
13606
13901
|
};
|
|
13902
|
+
/**
|
|
13903
|
+
* Placeholder handle marking "a reposition frame has been requested but the
|
|
13904
|
+
* real handle is not known yet". Never passed to `cancelAnimationFrame` in
|
|
13905
|
+
* practice — it is replaced within the same synchronous block — and harmless
|
|
13906
|
+
* if it were, since no frame carries this id.
|
|
13907
|
+
*/
|
|
13908
|
+
const SCHEDULED = -1;
|
|
13607
13909
|
function createFocusableElement() {
|
|
13608
13910
|
const element = document.createElement("div");
|
|
13609
13911
|
element.tabIndex = -1;
|
|
@@ -13616,12 +13918,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13616
13918
|
this.accessor = accessor;
|
|
13617
13919
|
this.map = {};
|
|
13618
13920
|
this._disposed = false;
|
|
13921
|
+
this._generation = 0;
|
|
13619
13922
|
this.positionCache = new PositionCache();
|
|
13620
|
-
this.pendingUpdates = /* @__PURE__ */ new Set();
|
|
13621
13923
|
this.addDisposables(Disposable.from(() => {
|
|
13622
13924
|
for (const value of Object.values(this.map)) {
|
|
13623
13925
|
value.disposable.dispose();
|
|
13624
13926
|
value.destroy.dispose();
|
|
13927
|
+
this.cancelPendingUpdate(value);
|
|
13625
13928
|
}
|
|
13626
13929
|
this._disposed = true;
|
|
13627
13930
|
}));
|
|
@@ -13648,11 +13951,24 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13648
13951
|
this.positionCache.invalidate();
|
|
13649
13952
|
(_entry$resize = entry.resize) === null || _entry$resize === void 0 || _entry$resize.call(entry);
|
|
13650
13953
|
}
|
|
13954
|
+
/**
|
|
13955
|
+
* Drop the reposition frame queued for a panel, if any. A queued frame is
|
|
13956
|
+
* bound to the reference container that was current when it was scheduled,
|
|
13957
|
+
* so it must be discarded whenever that container stops being the one the
|
|
13958
|
+
* overlay should track.
|
|
13959
|
+
*/
|
|
13960
|
+
cancelPendingUpdate(entry) {
|
|
13961
|
+
if (entry.pendingUpdate !== void 0) {
|
|
13962
|
+
cancelAnimationFrame(entry.pendingUpdate);
|
|
13963
|
+
entry.pendingUpdate = void 0;
|
|
13964
|
+
}
|
|
13965
|
+
}
|
|
13651
13966
|
detatch(panel) {
|
|
13652
13967
|
if (this.map[panel.api.id]) {
|
|
13653
|
-
const
|
|
13654
|
-
disposable.dispose();
|
|
13655
|
-
destroy.dispose();
|
|
13968
|
+
const entry = this.map[panel.api.id];
|
|
13969
|
+
entry.disposable.dispose();
|
|
13970
|
+
entry.destroy.dispose();
|
|
13971
|
+
this.cancelPendingUpdate(entry);
|
|
13656
13972
|
delete this.map[panel.api.id];
|
|
13657
13973
|
return true;
|
|
13658
13974
|
}
|
|
@@ -13668,22 +13984,73 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13668
13984
|
panel,
|
|
13669
13985
|
disposable: Disposable.NONE,
|
|
13670
13986
|
destroy: Disposable.NONE,
|
|
13671
|
-
element
|
|
13987
|
+
element,
|
|
13988
|
+
retainPreviousGeometry: false,
|
|
13989
|
+
positioned: false,
|
|
13990
|
+
generation: ++this._generation
|
|
13672
13991
|
};
|
|
13673
13992
|
}
|
|
13674
|
-
const
|
|
13993
|
+
const mapEntry = this.map[panel.api.id];
|
|
13994
|
+
/**
|
|
13995
|
+
* A *change* of reference container supersedes the previous `attach`:
|
|
13996
|
+
* take a fresh generation so its `resize` closure can no longer run,
|
|
13997
|
+
* and drop the frame it queued against the old container. During
|
|
13998
|
+
* `fromJSON({ reuseExistingPanels: true })` that old container is a
|
|
13999
|
+
* detached staging group measuring 0x0, so leaving its frame in flight
|
|
14000
|
+
* both wastes the update and delays the reposition against the real one.
|
|
14001
|
+
*
|
|
14002
|
+
* Re-attaching over the *same* container (re-open, active panel change)
|
|
14003
|
+
* deliberately leaves scheduled work alone: `repositionPanelOverlay`
|
|
14004
|
+
* (the auto-hide peek) schedules a frame carrying the sticky
|
|
14005
|
+
* `forceVisible`/`clip` state which `attach` does not re-apply, and a
|
|
14006
|
+
* peeked panel's `api.isVisible` is false — so discarding that frame
|
|
14007
|
+
* leaves `visibilityChanged` to hide the overlay and the peek renders
|
|
14008
|
+
* nothing. A newly created entry already holds a fresh generation, so
|
|
14009
|
+
* the stale closures a `detatch` left behind are fenced off either way.
|
|
14010
|
+
*/
|
|
14011
|
+
if (mapEntry.referenceContainer !== referenceContainer) {
|
|
14012
|
+
mapEntry.generation = ++this._generation;
|
|
14013
|
+
this.cancelPendingUpdate(mapEntry);
|
|
14014
|
+
mapEntry.referenceContainer = referenceContainer;
|
|
14015
|
+
/**
|
|
14016
|
+
* Arm the retain flag only here: it means "a replacement reference
|
|
14017
|
+
* container is awaiting layout", so the 0x0 early-return below
|
|
14018
|
+
* holds the last good box rather than blanking the panel mid-move.
|
|
14019
|
+
* Arming it on every re-attach instead would make a container that
|
|
14020
|
+
* genuinely collapses to zero keep its stale geometry forever.
|
|
14021
|
+
*
|
|
14022
|
+
* Gated on `positioned` because an overlay that has never been
|
|
14023
|
+
* positioned has no left/top/width/height, and `.dv-render-overlay`
|
|
14024
|
+
* defaults to 100%/100% — retaining "previous" geometry there would
|
|
14025
|
+
* pin the content over the whole container.
|
|
14026
|
+
*/
|
|
14027
|
+
mapEntry.retainPreviousGeometry = mapEntry.positioned;
|
|
14028
|
+
}
|
|
14029
|
+
const generation = mapEntry.generation;
|
|
14030
|
+
const focusContainer = mapEntry.element;
|
|
13675
14031
|
const contentElement = panel.view.content.element;
|
|
13676
14032
|
if (contentElement.parentElement !== focusContainer) focusContainer.appendChild(contentElement);
|
|
13677
14033
|
if (focusContainer.parentElement !== this.element) this.element.appendChild(focusContainer);
|
|
13678
14034
|
const resize = () => {
|
|
13679
14035
|
const panelId = panel.api.id;
|
|
13680
|
-
|
|
13681
|
-
|
|
13682
|
-
|
|
14036
|
+
const scheduling = this.map[panelId];
|
|
14037
|
+
if ((scheduling === null || scheduling === void 0 ? void 0 : scheduling.generation) !== generation) return;
|
|
14038
|
+
if (scheduling.pendingUpdate !== void 0) return;
|
|
14039
|
+
/**
|
|
14040
|
+
* Claim the slot *before* scheduling. `requestAnimationFrame` is
|
|
14041
|
+
* shimmed to run inline by some hosts (and by several suites here),
|
|
14042
|
+
* in which case the callback below clears `pendingUpdate` while
|
|
14043
|
+
* this call is still on the stack — assigning the handle afterwards
|
|
14044
|
+
* would resurrect a slot that is already spent and block every
|
|
14045
|
+
* later reposition. The sentinel is replaced by the real handle
|
|
14046
|
+
* only if the frame has not already run.
|
|
14047
|
+
*/
|
|
14048
|
+
scheduling.pendingUpdate = SCHEDULED;
|
|
14049
|
+
const handle = requestAnimationFrame(() => {
|
|
13683
14050
|
var _entry$forceVisible;
|
|
13684
|
-
this.pendingUpdates.delete(panelId);
|
|
13685
14051
|
const entry = this.map[panelId];
|
|
13686
|
-
if (
|
|
14052
|
+
if (entry) entry.pendingUpdate = void 0;
|
|
14053
|
+
if (this.isDisposed || (entry === null || entry === void 0 ? void 0 : entry.generation) !== generation) return;
|
|
13687
14054
|
const forceVisible = (_entry$forceVisible = entry.forceVisible) !== null && _entry$forceVisible !== void 0 ? _entry$forceVisible : false;
|
|
13688
14055
|
const clip = entry.clip;
|
|
13689
14056
|
const box = this.positionCache.getPosition(referenceContainer.element);
|
|
@@ -13692,6 +14059,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13692
14059
|
const top = box.top - box2.top;
|
|
13693
14060
|
const width = box.width;
|
|
13694
14061
|
const height = box.height;
|
|
14062
|
+
if (entry.retainPreviousGeometry && (width === 0 || height === 0)) {
|
|
14063
|
+
if (!panel.api.isVisible && !forceVisible) {
|
|
14064
|
+
focusContainer.style.visibility = "hidden";
|
|
14065
|
+
focusContainer.style.pointerEvents = "none";
|
|
14066
|
+
}
|
|
14067
|
+
return;
|
|
14068
|
+
}
|
|
14069
|
+
entry.retainPreviousGeometry = false;
|
|
14070
|
+
entry.positioned = true;
|
|
13695
14071
|
focusContainer.style.left = `${left}px`;
|
|
13696
14072
|
focusContainer.style.top = `${top}px`;
|
|
13697
14073
|
focusContainer.style.width = `${width}px`;
|
|
@@ -13720,11 +14096,30 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13720
14096
|
} else focusContainer.style.clipPath = "";
|
|
13721
14097
|
toggleClass(focusContainer, "dv-render-overlay-float", panel.group.api.location.type === "floating");
|
|
13722
14098
|
});
|
|
14099
|
+
if (scheduling.pendingUpdate === SCHEDULED) scheduling.pendingUpdate = handle;
|
|
13723
14100
|
};
|
|
13724
14101
|
const visibilityChanged = () => {
|
|
13725
14102
|
if (panel.api.isVisible) {
|
|
14103
|
+
var _this$map$panel$api$i;
|
|
13726
14104
|
this.positionCache.invalidate();
|
|
13727
14105
|
resize();
|
|
14106
|
+
/**
|
|
14107
|
+
* Existing geometry is safe to show while its replacement lays
|
|
14108
|
+
* out. `retainPreviousGeometry` is only set when geometry has
|
|
14109
|
+
* actually been written (see `attach`), so this can never
|
|
14110
|
+
* un-hide an overlay whose left/top/width/height are unset —
|
|
14111
|
+
* `.dv-render-overlay` is 100%/100% by default and would
|
|
14112
|
+
* otherwise cover the whole dock.
|
|
14113
|
+
*
|
|
14114
|
+
* The retained geometry is the panel's position in the previous
|
|
14115
|
+
* layout, so restoring a layout that moves the panel does paint
|
|
14116
|
+
* it at stale coordinates until the reposition lands. That is
|
|
14117
|
+
* bounded to the next frame now that a superseded `attach` can
|
|
14118
|
+
* no longer swallow the reposition (see `attach`); showing
|
|
14119
|
+
* stale-but-real geometry for a frame is the deliberate
|
|
14120
|
+
* trade-off against blanking the panel for the whole rebuild.
|
|
14121
|
+
*/
|
|
14122
|
+
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 = "";
|
|
13728
14123
|
focusContainer.style.pointerEvents = "";
|
|
13729
14124
|
} else {
|
|
13730
14125
|
focusContainer.style.visibility = "hidden";
|
|
@@ -13947,7 +14342,17 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
13947
14342
|
window: externalWindow
|
|
13948
14343
|
});
|
|
13949
14344
|
return new Promise((resolve, reject) => {
|
|
13950
|
-
externalWindow.addEventListener("unload", (
|
|
14345
|
+
externalWindow.addEventListener("unload", () => {});
|
|
14346
|
+
/**
|
|
14347
|
+
* `load` is the only event that resolves this promise with a
|
|
14348
|
+
* container, so a window that goes away first would leave the
|
|
14349
|
+
* caller awaiting a promise that never settles - and
|
|
14350
|
+
* `addPopoutGroup` holds its layout transaction open until it does.
|
|
14351
|
+
* Settle with `null` on close, the same signal a blocked popup
|
|
14352
|
+
* gives and one the caller already handles. `resolve` after the
|
|
14353
|
+
* fact is a no-op, so a `load` that arrived first still wins.
|
|
14354
|
+
*/
|
|
14355
|
+
disposable.addDisposables(_this.onWillClose(() => resolve(null)));
|
|
13951
14356
|
externalWindow.addEventListener("load", () => {
|
|
13952
14357
|
/**
|
|
13953
14358
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
|
|
@@ -14153,6 +14558,14 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14153
14558
|
//#endregion
|
|
14154
14559
|
//#region src/dnd/dropTargetAnchorContainer.ts
|
|
14155
14560
|
var DropTargetAnchorContainer = class extends CompositeDisposable {
|
|
14561
|
+
/**
|
|
14562
|
+
* The element the live overlay was rendered for, `undefined` when nothing
|
|
14563
|
+
* is showing. The container is shared by every drop target, so a caller
|
|
14564
|
+
* tearing down only its own overlay must check this before `clear()`.
|
|
14565
|
+
*/
|
|
14566
|
+
get renderedOutline() {
|
|
14567
|
+
return this._model ? this._outline : void 0;
|
|
14568
|
+
}
|
|
14156
14569
|
get disabled() {
|
|
14157
14570
|
return this._disabled;
|
|
14158
14571
|
}
|
|
@@ -14457,6 +14870,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14457
14870
|
const index = position === "top" ? this._topIndex : this._bottomIndex;
|
|
14458
14871
|
if (index !== void 0) this._splitview.resizeView(index, size);
|
|
14459
14872
|
}
|
|
14873
|
+
/** The inner splitview's primary-axis (height) extent; zero until laid out. */
|
|
14874
|
+
get axisSize() {
|
|
14875
|
+
return this._splitview.size;
|
|
14876
|
+
}
|
|
14460
14877
|
updateMargin(gap) {
|
|
14461
14878
|
this._splitview.margin = gap;
|
|
14462
14879
|
}
|
|
@@ -14469,6 +14886,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14469
14886
|
constructor(container, dockviewElement, layoutGrid, gap = 0, defaultCollapsedSize = 35) {
|
|
14470
14887
|
this._disposables = new CompositeDisposable();
|
|
14471
14888
|
this._viewConfigs = /* @__PURE__ */ new Map();
|
|
14889
|
+
this._pendingSizes = /* @__PURE__ */ new Map();
|
|
14472
14890
|
this._currentWidth = 0;
|
|
14473
14891
|
this._currentHeight = 0;
|
|
14474
14892
|
this._gap = gap;
|
|
@@ -14559,11 +14977,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14559
14977
|
break;
|
|
14560
14978
|
}
|
|
14561
14979
|
this._disposables.addDisposables(view);
|
|
14980
|
+
if (!view.isCollapsed && !this._canResize(position)) this._pendingSizes.set(position, initialSize);
|
|
14562
14981
|
this.updateTheme(this._gap, this._defaultCollapsedSize);
|
|
14563
14982
|
return view;
|
|
14564
14983
|
}
|
|
14565
14984
|
layout(width, height) {
|
|
14566
14985
|
this._outerSplitview.layout(width, height);
|
|
14986
|
+
this._flushPendingSizes();
|
|
14567
14987
|
}
|
|
14568
14988
|
/**
|
|
14569
14989
|
* Called when the active theme changes. Updates splitview margins and
|
|
@@ -14627,6 +15047,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14627
15047
|
this._disposables.removeDisposable(view);
|
|
14628
15048
|
view.dispose();
|
|
14629
15049
|
this._viewConfigs.delete(position);
|
|
15050
|
+
this._pendingSizes.delete(position);
|
|
14630
15051
|
this.updateTheme(this._gap, this._defaultCollapsedSize);
|
|
14631
15052
|
}
|
|
14632
15053
|
hasEdgeGroup(position) {
|
|
@@ -14650,6 +15071,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14650
15071
|
this._middleColumn.setViewVisible(position, visible);
|
|
14651
15072
|
break;
|
|
14652
15073
|
}
|
|
15074
|
+
if (visible) this._flushPendingSizes();
|
|
14653
15075
|
}
|
|
14654
15076
|
isEdgeGroupVisible(position) {
|
|
14655
15077
|
switch (position) {
|
|
@@ -14667,20 +15089,63 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14667
15089
|
const view = this._getView(position);
|
|
14668
15090
|
if (!view) return;
|
|
14669
15091
|
view.setCollapsed(collapsed);
|
|
14670
|
-
|
|
15092
|
+
if (collapsed) {
|
|
15093
|
+
this._pendingSizes.delete(position);
|
|
15094
|
+
this._resizeView(position, view.collapsedSize);
|
|
15095
|
+
} else this.resizeEdgeGroup(position, view.lastExpandedSize);
|
|
15096
|
+
}
|
|
15097
|
+
/**
|
|
15098
|
+
* Resize the edge group at `position` along its primary axis (width for
|
|
15099
|
+
* `left`/`right`, height for `top`/`bottom`), clamped by the group's
|
|
15100
|
+
* constraints and the space available. Where `groupApi.setSize` lands.
|
|
15101
|
+
*
|
|
15102
|
+
* The size becomes the group's expanded size, so a collapsed group keeps
|
|
15103
|
+
* its strip and takes it on expand, and it survives a `toJSON` round-trip.
|
|
15104
|
+
*/
|
|
15105
|
+
resizeEdgeGroup(position, size) {
|
|
15106
|
+
const view = this._getView(position);
|
|
15107
|
+
if (!view || !Number.isFinite(size)) return;
|
|
15108
|
+
const target = Math.round(size);
|
|
15109
|
+
if (target <= 0) return;
|
|
15110
|
+
view.restoreExpandedSize(target);
|
|
15111
|
+
if (view.isCollapsed) {
|
|
15112
|
+
this._pendingSizes.delete(position);
|
|
15113
|
+
return;
|
|
15114
|
+
}
|
|
15115
|
+
if (this._canResize(position)) {
|
|
15116
|
+
this._pendingSizes.delete(position);
|
|
15117
|
+
this._resizeView(position, target);
|
|
15118
|
+
} else this._pendingSizes.set(position, target);
|
|
15119
|
+
}
|
|
15120
|
+
/** A resize lands only on a visible view (a hidden one is pinned to zero)
|
|
15121
|
+
* whose splitview has extent to distribute. */
|
|
15122
|
+
_canResize(position) {
|
|
15123
|
+
if (!this.isEdgeGroupVisible(position)) return false;
|
|
15124
|
+
return (position === "left" || position === "right" ? this._outerSplitview.size : this._middleColumn.axisSize) > 0;
|
|
15125
|
+
}
|
|
15126
|
+
_resizeView(position, size) {
|
|
14671
15127
|
switch (position) {
|
|
14672
15128
|
case "left":
|
|
14673
|
-
if (this._leftIndex !== void 0) this._outerSplitview.resizeView(this._leftIndex,
|
|
15129
|
+
if (this._leftIndex !== void 0) this._outerSplitview.resizeView(this._leftIndex, size);
|
|
14674
15130
|
break;
|
|
14675
15131
|
case "right":
|
|
14676
|
-
if (this._rightIndex !== void 0) this._outerSplitview.resizeView(this._rightIndex,
|
|
15132
|
+
if (this._rightIndex !== void 0) this._outerSplitview.resizeView(this._rightIndex, size);
|
|
14677
15133
|
break;
|
|
14678
15134
|
case "top":
|
|
14679
15135
|
case "bottom":
|
|
14680
|
-
this._middleColumn.resizeView(position,
|
|
15136
|
+
this._middleColumn.resizeView(position, size);
|
|
14681
15137
|
break;
|
|
14682
15138
|
}
|
|
14683
15139
|
}
|
|
15140
|
+
_flushPendingSizes() {
|
|
15141
|
+
if (this._pendingSizes.size === 0) return;
|
|
15142
|
+
for (const [position, size] of this._pendingSizes) {
|
|
15143
|
+
const view = this._getView(position);
|
|
15144
|
+
if (!view || view.isCollapsed || !this._canResize(position)) continue;
|
|
15145
|
+
this._pendingSizes.delete(position);
|
|
15146
|
+
this._resizeView(position, size);
|
|
15147
|
+
}
|
|
15148
|
+
}
|
|
14684
15149
|
isEdgeGroupCollapsed(position) {
|
|
14685
15150
|
var _this$_getView$isColl, _this$_getView;
|
|
14686
15151
|
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;
|
|
@@ -14706,15 +15171,17 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14706
15171
|
maximumSize: Number.isFinite(view.configuredMaximumSize) ? view.configuredMaximumSize : void 0,
|
|
14707
15172
|
collapsedSize: view.configuredCollapsedSize
|
|
14708
15173
|
});
|
|
14709
|
-
const expandedSize = (view, isVisible, liveSize, cachedVisibleSize) => {
|
|
15174
|
+
const expandedSize = (view, position, isVisible, liveSize, cachedVisibleSize) => {
|
|
14710
15175
|
if (view.isCollapsed) return view.lastExpandedSize;
|
|
15176
|
+
const pending = this._pendingSizes.get(position);
|
|
15177
|
+
if (pending !== void 0) return pending;
|
|
14711
15178
|
if (!isVisible) return cachedVisibleSize !== null && cachedVisibleSize !== void 0 ? cachedVisibleSize : view.lastExpandedSize;
|
|
14712
15179
|
return liveSize;
|
|
14713
15180
|
};
|
|
14714
15181
|
if (this._leftView && this._leftIndex !== void 0) {
|
|
14715
15182
|
const visible = this._outerSplitview.isViewVisible(this._leftIndex);
|
|
14716
15183
|
edgeGroups.left = _objectSpread2({
|
|
14717
|
-
size: expandedSize(this._leftView, visible, this._outerSplitview.getViewSize(this._leftIndex), this._outerSplitview.getViewCachedVisibleSize(this._leftIndex)),
|
|
15184
|
+
size: expandedSize(this._leftView, "left", visible, this._outerSplitview.getViewSize(this._leftIndex), this._outerSplitview.getViewCachedVisibleSize(this._leftIndex)),
|
|
14718
15185
|
visible,
|
|
14719
15186
|
collapsed: this._leftView.isCollapsed || void 0
|
|
14720
15187
|
}, constraints(this._leftView));
|
|
@@ -14722,7 +15189,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14722
15189
|
if (this._rightView && this._rightIndex !== void 0) {
|
|
14723
15190
|
const visible = this._outerSplitview.isViewVisible(this._rightIndex);
|
|
14724
15191
|
edgeGroups.right = _objectSpread2({
|
|
14725
|
-
size: expandedSize(this._rightView, visible, this._outerSplitview.getViewSize(this._rightIndex), this._outerSplitview.getViewCachedVisibleSize(this._rightIndex)),
|
|
15192
|
+
size: expandedSize(this._rightView, "right", visible, this._outerSplitview.getViewSize(this._rightIndex), this._outerSplitview.getViewCachedVisibleSize(this._rightIndex)),
|
|
14726
15193
|
visible,
|
|
14727
15194
|
collapsed: this._rightView.isCollapsed || void 0
|
|
14728
15195
|
}, constraints(this._rightView));
|
|
@@ -14730,7 +15197,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14730
15197
|
if (this._topView) {
|
|
14731
15198
|
const visible = this._middleColumn.isViewVisible("top");
|
|
14732
15199
|
edgeGroups.top = _objectSpread2({
|
|
14733
|
-
size: expandedSize(this._topView, visible, this._middleColumn.getViewSize("top"), this._middleColumn.getViewCachedVisibleSize("top")),
|
|
15200
|
+
size: expandedSize(this._topView, "top", visible, this._middleColumn.getViewSize("top"), this._middleColumn.getViewCachedVisibleSize("top")),
|
|
14734
15201
|
visible,
|
|
14735
15202
|
collapsed: this._topView.isCollapsed || void 0
|
|
14736
15203
|
}, constraints(this._topView));
|
|
@@ -14738,7 +15205,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14738
15205
|
if (this._bottomView) {
|
|
14739
15206
|
const visible = this._middleColumn.isViewVisible("bottom");
|
|
14740
15207
|
edgeGroups.bottom = _objectSpread2({
|
|
14741
|
-
size: expandedSize(this._bottomView, visible, this._middleColumn.getViewSize("bottom"), this._middleColumn.getViewCachedVisibleSize("bottom")),
|
|
15208
|
+
size: expandedSize(this._bottomView, "bottom", visible, this._middleColumn.getViewSize("bottom"), this._middleColumn.getViewCachedVisibleSize("bottom")),
|
|
14742
15209
|
visible,
|
|
14743
15210
|
collapsed: this._bottomView.isCollapsed || void 0
|
|
14744
15211
|
}, constraints(this._bottomView));
|
|
@@ -14746,33 +15213,23 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
14746
15213
|
return edgeGroups;
|
|
14747
15214
|
}
|
|
14748
15215
|
fromJSON(data) {
|
|
14749
|
-
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14753
|
-
|
|
14754
|
-
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
(
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
if (
|
|
14762
|
-
|
|
14763
|
-
|
|
14764
|
-
|
|
14765
|
-
|
|
14766
|
-
(_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);
|
|
14767
|
-
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);
|
|
14768
|
-
if (!data.top.visible) this._middleColumn.setViewVisible("top", false);
|
|
14769
|
-
}
|
|
14770
|
-
if (data.bottom) {
|
|
14771
|
-
var _this$_bottomView2, _this$_bottomView3, _data$bottom$collapse, _this$_bottomView$col, _this$_bottomView4;
|
|
14772
|
-
(_this$_bottomView2 = this._bottomView) === null || _this$_bottomView2 === void 0 || _this$_bottomView2.restoreExpandedSize(data.bottom.size);
|
|
14773
|
-
(_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);
|
|
14774
|
-
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);
|
|
14775
|
-
if (!data.bottom.visible) this._middleColumn.setViewVisible("bottom", false);
|
|
15216
|
+
for (const position of [
|
|
15217
|
+
"left",
|
|
15218
|
+
"right",
|
|
15219
|
+
"top",
|
|
15220
|
+
"bottom"
|
|
15221
|
+
]) {
|
|
15222
|
+
var _state$collapsed;
|
|
15223
|
+
const state = data[position];
|
|
15224
|
+
const view = this._getView(position);
|
|
15225
|
+
if (!state || !view) continue;
|
|
15226
|
+
view.restoreExpandedSize(state.size);
|
|
15227
|
+
view.setCollapsed((_state$collapsed = state.collapsed) !== null && _state$collapsed !== void 0 ? _state$collapsed : false);
|
|
15228
|
+
if (state.collapsed) {
|
|
15229
|
+
this._pendingSizes.delete(position);
|
|
15230
|
+
this._resizeView(position, view.collapsedSize);
|
|
15231
|
+
} else this.resizeEdgeGroup(position, state.size);
|
|
15232
|
+
this.setEdgeGroupVisible(position, !!state.visible);
|
|
14776
15233
|
}
|
|
14777
15234
|
}
|
|
14778
15235
|
dispose() {
|
|
@@ -15365,6 +15822,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15365
15822
|
this._onWillDrop = new Emitter();
|
|
15366
15823
|
this.onWillDrop = this._onWillDrop.event;
|
|
15367
15824
|
this._mutationDepth = 0;
|
|
15825
|
+
this._pendingLocationChanges = /* @__PURE__ */ new Map();
|
|
15368
15826
|
this._origin = "user";
|
|
15369
15827
|
this._originDepth = 0;
|
|
15370
15828
|
this._onWillMutateLayout = new Emitter();
|
|
@@ -15462,7 +15920,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15462
15920
|
toggleClass(this.element, "dv-debug", !!options.debug);
|
|
15463
15921
|
this.updateTheme();
|
|
15464
15922
|
if (options.debug) this.addDisposables(new StrictEventsSequencing(this));
|
|
15465
|
-
this.addDisposables(this.rootDropTargetContainer, this.floatingDropTargetContainer, addDisposableListener(this._shellManager.element, "dragend", () => {
|
|
15923
|
+
this.addDisposables(Disposable.from(() => this._pendingLocationChanges.clear()), this.rootDropTargetContainer, this.floatingDropTargetContainer, addDisposableListener(this._shellManager.element, "dragend", () => {
|
|
15466
15924
|
var _this$rootDropTargetC2, _this$floatingDropTar;
|
|
15467
15925
|
(_this$rootDropTargetC2 = this.rootDropTargetContainer.model) === null || _this$rootDropTargetC2 === void 0 || _this$rootDropTargetC2.clear();
|
|
15468
15926
|
(_this$floatingDropTar = this.floatingDropTargetContainer.model) === null || _this$floatingDropTar === void 0 || _this$floatingDropTar.clear();
|
|
@@ -15536,7 +15994,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15536
15994
|
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;
|
|
15537
15995
|
}
|
|
15538
15996
|
addPopoutGroup(itemToPopout, options) {
|
|
15539
|
-
return this.
|
|
15997
|
+
return this.mutationAsync("popout", () => this._doAddPopoutGroup(itemToPopout, options));
|
|
15540
15998
|
}
|
|
15541
15999
|
/** Enumerate the popout groups currently open in their own windows. */
|
|
15542
16000
|
getPopouts() {
|
|
@@ -15633,15 +16091,32 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15633
16091
|
}
|
|
15634
16092
|
};
|
|
15635
16093
|
let floatingBox;
|
|
15636
|
-
|
|
15637
|
-
|
|
15638
|
-
|
|
15639
|
-
|
|
15640
|
-
|
|
16094
|
+
/**
|
|
16095
|
+
* Popping out rehomes panels into `group`, so like the floating
|
|
16096
|
+
* case it owes the caller an `onDidMovePanel` per panel. The
|
|
16097
|
+
* events are deferred until the window is wired up so listeners
|
|
16098
|
+
* observe the panels' final `popout` location.
|
|
16099
|
+
*/
|
|
16100
|
+
let movedPanels = [];
|
|
16101
|
+
if (!(options === null || options === void 0 ? void 0 : options.overridePopoutGroup) && !(options === null || options === void 0 ? void 0 : options.overridePopoutGridview) && isGroupAddedToDom) if (itemToPopout instanceof DockviewPanel) {
|
|
16102
|
+
const sourceGroup = itemToPopout.group;
|
|
16103
|
+
this.movingLock(() => {
|
|
16104
|
+
const panel = referenceGroup.model.removePanel(itemToPopout);
|
|
16105
|
+
group.model.openPanel(panel);
|
|
16106
|
+
});
|
|
16107
|
+
movedPanels = [{
|
|
16108
|
+
panel: itemToPopout,
|
|
16109
|
+
from: sourceGroup
|
|
16110
|
+
}];
|
|
16111
|
+
} else {
|
|
15641
16112
|
this.movingLock(() => moveGroupWithoutDestroying({
|
|
15642
16113
|
from: referenceGroup,
|
|
15643
16114
|
to: group
|
|
15644
16115
|
}));
|
|
16116
|
+
movedPanels = group.panels.map((panel) => ({
|
|
16117
|
+
panel,
|
|
16118
|
+
from: referenceGroup
|
|
16119
|
+
}));
|
|
15645
16120
|
switch (referenceLocation) {
|
|
15646
16121
|
case "grid":
|
|
15647
16122
|
referenceGroup.api.setVisible(false);
|
|
@@ -15750,6 +16225,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15750
16225
|
group: value.popoutGroup,
|
|
15751
16226
|
window: value.getWindow()
|
|
15752
16227
|
});
|
|
16228
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15753
16229
|
return true;
|
|
15754
16230
|
}).catch((err) => {
|
|
15755
16231
|
console.error("dockview: failed to create popout.", err);
|
|
@@ -15827,6 +16303,16 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15827
16303
|
const members = this.groups.filter((candidate) => popoutGridview.element.contains(candidate.element));
|
|
15828
16304
|
const anchorPresent = members.includes(group);
|
|
15829
16305
|
const anchorIsSoleMember = anchorPresent && members.length === 1;
|
|
16306
|
+
/**
|
|
16307
|
+
* Popping a group out fires `onDidMovePanel` per panel, so closing the
|
|
16308
|
+
* window owes the caller the same: every panel in it is rehomed, into
|
|
16309
|
+
* the reference group the popout left behind or into a fresh grid slot.
|
|
16310
|
+
* `movingLock` suppresses onDidAddPanel / onDidRemovePanel on these
|
|
16311
|
+
* paths, so `onDidMovePanel` is the only event that can carry it. The
|
|
16312
|
+
* events are deferred to the end so listeners observe the panels at
|
|
16313
|
+
* their final group and location.
|
|
16314
|
+
*/
|
|
16315
|
+
const movedPanels = [];
|
|
15830
16316
|
if (genuineClose) for (const member of members) {
|
|
15831
16317
|
if (member === group) continue;
|
|
15832
16318
|
this.movingLock(() => {
|
|
@@ -15837,12 +16323,21 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15837
16323
|
});
|
|
15838
16324
|
this.redockGroupToMainGrid(member);
|
|
15839
16325
|
});
|
|
16326
|
+
for (const panel of member.panels) movedPanels.push({
|
|
16327
|
+
panel,
|
|
16328
|
+
from: member
|
|
16329
|
+
});
|
|
15840
16330
|
}
|
|
15841
16331
|
if (anchorPresent && isGroupAddedToDom && this.getPanel(referenceGroup.id)) {
|
|
16332
|
+
const rehomed = [...group.panels];
|
|
15842
16333
|
this.movingLock(() => moveGroupWithoutDestroying({
|
|
15843
16334
|
from: group,
|
|
15844
16335
|
to: referenceGroup
|
|
15845
16336
|
}));
|
|
16337
|
+
for (const panel of rehomed) movedPanels.push({
|
|
16338
|
+
panel,
|
|
16339
|
+
from: group
|
|
16340
|
+
});
|
|
15846
16341
|
if (!referenceGroup.api.isVisible) referenceGroup.api.setVisible(true);
|
|
15847
16342
|
if (this.getPanel(group.id)) this.doRemoveGroup(group, { skipPopoutAssociated: true });
|
|
15848
16343
|
} else if (anchorPresent && this.getPanel(group.id)) {
|
|
@@ -15873,10 +16368,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15873
16368
|
this.movingLock(() => {
|
|
15874
16369
|
this.doAddGroup(group, [0]);
|
|
15875
16370
|
});
|
|
16371
|
+
for (const panel of group.panels) movedPanels.push({
|
|
16372
|
+
panel,
|
|
16373
|
+
from: group
|
|
16374
|
+
});
|
|
15876
16375
|
}
|
|
15877
16376
|
this.doSetGroupAndPanelActive(group);
|
|
15878
16377
|
}
|
|
15879
16378
|
disposePopoutGridview();
|
|
16379
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15880
16380
|
}
|
|
15881
16381
|
addFloatingGroup(item, options) {
|
|
15882
16382
|
this.mutation("float", () => this._doAddFloatingGroup(item, options));
|
|
@@ -15885,7 +16385,15 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15885
16385
|
if (!assertModule(this._floatingGroupService, "FloatingGroup", "api.addFloatingGroup")) return;
|
|
15886
16386
|
if (item instanceof DockviewGroupPanel && item.model.location.type === "edge") return;
|
|
15887
16387
|
let group;
|
|
16388
|
+
/**
|
|
16389
|
+
* Floating relocates panels exactly like a drop onto the grid does, so
|
|
16390
|
+
* it owes the caller an `onDidMovePanel` per panel. The events are
|
|
16391
|
+
* deferred until the window is mounted below: only then do the panels
|
|
16392
|
+
* report their final `floating` location.
|
|
16393
|
+
*/
|
|
16394
|
+
let movedPanels = [];
|
|
15888
16395
|
if (item instanceof DockviewPanel) {
|
|
16396
|
+
const sourceGroup = item.group;
|
|
15889
16397
|
group = this.createGroup();
|
|
15890
16398
|
this._onDidAddGroup.fire(group);
|
|
15891
16399
|
this.movingLock(() => this.removePanel(item, {
|
|
@@ -15894,6 +16402,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15894
16402
|
skipSetActiveGroup: true
|
|
15895
16403
|
}));
|
|
15896
16404
|
this.movingLock(() => group.model.openPanel(item, { skipSetGroupActive: true }));
|
|
16405
|
+
movedPanels = [{
|
|
16406
|
+
panel: item,
|
|
16407
|
+
from: sourceGroup
|
|
16408
|
+
}];
|
|
15897
16409
|
} else {
|
|
15898
16410
|
var _this$_popoutWindowSe8;
|
|
15899
16411
|
group = item;
|
|
@@ -15910,11 +16422,21 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15910
16422
|
});
|
|
15911
16423
|
this.doRemoveGroup(popoutReferenceGroup, { skipDispose: true });
|
|
15912
16424
|
group = popoutReferenceGroup;
|
|
15913
|
-
|
|
15914
|
-
|
|
15915
|
-
|
|
15916
|
-
|
|
15917
|
-
}
|
|
16425
|
+
movedPanels = group.panels.map((panel) => ({
|
|
16426
|
+
panel,
|
|
16427
|
+
from: item
|
|
16428
|
+
}));
|
|
16429
|
+
} else {
|
|
16430
|
+
this.doRemoveGroup(item, {
|
|
16431
|
+
skipDispose: true,
|
|
16432
|
+
skipPopoutReturn: true,
|
|
16433
|
+
skipPopoutAssociated: false
|
|
16434
|
+
});
|
|
16435
|
+
movedPanels = group.panels.map((panel) => ({
|
|
16436
|
+
panel,
|
|
16437
|
+
from: group
|
|
16438
|
+
}));
|
|
16439
|
+
}
|
|
15918
16440
|
}
|
|
15919
16441
|
function getAnchoredBox() {
|
|
15920
16442
|
if (options === null || options === void 0 ? void 0 : options.position) {
|
|
@@ -15947,6 +16469,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
15947
16469
|
skipActiveGroup: options === null || options === void 0 ? void 0 : options.skipActiveGroup,
|
|
15948
16470
|
disableSmartGuides: options === null || options === void 0 ? void 0 : options.disableSmartGuides
|
|
15949
16471
|
});
|
|
16472
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15950
16473
|
}
|
|
15951
16474
|
/**
|
|
15952
16475
|
* Build an empty gridview configured to match the main grid's styling, for
|
|
@@ -16091,6 +16614,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16091
16614
|
position
|
|
16092
16615
|
};
|
|
16093
16616
|
group.model.headerPosition = position;
|
|
16617
|
+
const resizeDisposable = group.onDidChange((event) => {
|
|
16618
|
+
var _this$_shellManager3;
|
|
16619
|
+
if (!event) return;
|
|
16620
|
+
const size = position === "left" || position === "right" ? event.width : event.height;
|
|
16621
|
+
if (typeof size !== "number") return;
|
|
16622
|
+
(_this$_shellManager3 = this._shellManager) === null || _this$_shellManager3 === void 0 || _this$_shellManager3.resizeEdgeGroup(position, size);
|
|
16623
|
+
});
|
|
16094
16624
|
const autoCollapseDisposable = group.model.onDidRemovePanel(() => {
|
|
16095
16625
|
if (!group.model.isEmpty) return;
|
|
16096
16626
|
if (service.isAutoReveal(group)) queueMicrotask(() => {
|
|
@@ -16099,7 +16629,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16099
16629
|
});
|
|
16100
16630
|
else this.setEdgeGroupCollapsed(group, true);
|
|
16101
16631
|
});
|
|
16102
|
-
service.add(position, group, autoCollapseDisposable);
|
|
16632
|
+
service.add(position, group, new CompositeDisposable(autoCollapseDisposable, resizeDisposable));
|
|
16103
16633
|
if (options.autoHide !== void 0) service.setAutoHide(group, options.autoHide);
|
|
16104
16634
|
if (options.autoReveal !== void 0) service.setAutoReveal(group, options.autoReveal);
|
|
16105
16635
|
this._onDidAddGroup.fire(group);
|
|
@@ -16194,8 +16724,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16194
16724
|
}
|
|
16195
16725
|
/** The size an edge group expands to (pre-collapse); sizes the peek. */
|
|
16196
16726
|
getEdgeGroupExpandedSize(position) {
|
|
16197
|
-
var _this$_shellManager$g, _this$
|
|
16198
|
-
return (_this$_shellManager$g = (_this$
|
|
16727
|
+
var _this$_shellManager$g, _this$_shellManager4;
|
|
16728
|
+
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;
|
|
16199
16729
|
}
|
|
16200
16730
|
/** Reposition a single `renderer:'always'` panel's overlay over its
|
|
16201
16731
|
* reference container, optionally forcing it visible (the auto-hide peek
|
|
@@ -16378,35 +16908,119 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16378
16908
|
if (typeof data !== "object" || data === null) throw new Error("dockview: serialized layout must be a non-null object");
|
|
16379
16909
|
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");
|
|
16380
16910
|
const existingPanels = /* @__PURE__ */ new Map();
|
|
16381
|
-
|
|
16911
|
+
const temporaryGroups = /* @__PURE__ */ new Map();
|
|
16912
|
+
const stagedPanels = [];
|
|
16913
|
+
const temporaryGroupDisposables = [];
|
|
16914
|
+
/**
|
|
16915
|
+
* The staging groups are detached from `_groups` and never enter the
|
|
16916
|
+
* grid, so nothing else will ever tear them down.
|
|
16917
|
+
*
|
|
16918
|
+
* `dispose()` reaches consumer `IContentRenderer.dispose()`, so one
|
|
16919
|
+
* throwing renderer must not abort the rest of the cleanup — that would
|
|
16920
|
+
* re-introduce the very leak this reclaims — nor replace the
|
|
16921
|
+
* deserialization error the caller is being given. Draining the list
|
|
16922
|
+
* also makes this safe to call more than once.
|
|
16923
|
+
*/
|
|
16924
|
+
const disposeTemporaryGroups = () => {
|
|
16925
|
+
for (const disposable of temporaryGroupDisposables) try {
|
|
16926
|
+
disposable.dispose();
|
|
16927
|
+
} catch (err) {
|
|
16928
|
+
console.error("dockview: failed to dispose a temporary group created for reuseExistingPanels", err);
|
|
16929
|
+
}
|
|
16930
|
+
temporaryGroupDisposables.length = 0;
|
|
16931
|
+
};
|
|
16382
16932
|
if (options === null || options === void 0 ? void 0 : options.reuseExistingPanels) {
|
|
16383
16933
|
/**
|
|
16384
|
-
*
|
|
16385
|
-
*
|
|
16386
|
-
*
|
|
16387
|
-
* 2. Remove that temporary group from the group mapping so that it doesn't get cleared when we clear the layout
|
|
16934
|
+
* Visible, always-rendered panels need individual staging groups
|
|
16935
|
+
* to remain active. Other reused panels can share a staging group.
|
|
16936
|
+
* The staging groups are excluded from the layout clear below.
|
|
16388
16937
|
*/
|
|
16389
|
-
tempGroup = this.createGroup();
|
|
16390
|
-
this._groups.delete(tempGroup.api.id);
|
|
16391
16938
|
const newPanels = Object.keys(data.panels);
|
|
16392
|
-
|
|
16393
|
-
|
|
16394
|
-
|
|
16395
|
-
|
|
16396
|
-
|
|
16397
|
-
|
|
16398
|
-
|
|
16399
|
-
|
|
16400
|
-
|
|
16401
|
-
|
|
16402
|
-
|
|
16403
|
-
|
|
16404
|
-
|
|
16939
|
+
let sharedTemporaryGroup;
|
|
16940
|
+
const createTemporaryGroup = () => {
|
|
16941
|
+
const temporaryGroup = this.createGroup();
|
|
16942
|
+
/**
|
|
16943
|
+
* Removing the group from `_groups` also drops the record's
|
|
16944
|
+
* `CompositeDisposable`, so capture it first and tear both it
|
|
16945
|
+
* and the group down in the `finally` below. Left undisposed a
|
|
16946
|
+
* staging group leaks its `ResizeObserver`, its
|
|
16947
|
+
* `onDidOptionsChange` subscription (retained by this
|
|
16948
|
+
* component's emitter) and the watermark its model mounts when
|
|
16949
|
+
* the group empties — once per reused panel, per `fromJSON`.
|
|
16950
|
+
*/
|
|
16951
|
+
const record = this._groups.get(temporaryGroup.api.id);
|
|
16952
|
+
this._groups.delete(temporaryGroup.api.id);
|
|
16953
|
+
temporaryGroupDisposables.push(Disposable.from(() => {
|
|
16954
|
+
/**
|
|
16955
|
+
* Reclaim the group's own resources, never its panels.
|
|
16956
|
+
* Staging is driven by the ids in `data.panels` while
|
|
16957
|
+
* reclaiming is driven by the group `views` that
|
|
16958
|
+
* reference them, so a panel whose state is present but
|
|
16959
|
+
* unreferenced is still staged here — and `dispose()`
|
|
16960
|
+
* on a non-empty group reaches the consumer's
|
|
16961
|
+
* `IContentRenderer.dispose()`. Emptying the group
|
|
16962
|
+
* first leaves those panels exactly as they were before
|
|
16963
|
+
* this teardown existed, which also keeps this safe
|
|
16964
|
+
* against any future path that rebuilds a panel under
|
|
16965
|
+
* an id that is live in the new layout.
|
|
16966
|
+
*/
|
|
16967
|
+
this.movingLock(() => {
|
|
16968
|
+
for (const panel of temporaryGroup.panels.slice()) temporaryGroup.model.removePanel(panel);
|
|
16969
|
+
});
|
|
16970
|
+
record === null || record === void 0 || record.disposable.dispose();
|
|
16971
|
+
temporaryGroup.dispose();
|
|
16972
|
+
}));
|
|
16973
|
+
return temporaryGroup;
|
|
16974
|
+
};
|
|
16975
|
+
/**
|
|
16976
|
+
* Staging and the clear below run before the deserialization
|
|
16977
|
+
* `try`, so a throw here (a consumer `onDidRemovePanel` handler, a
|
|
16978
|
+
* renderer teardown during `clear`) would escape without reclaiming
|
|
16979
|
+
* the staging groups already created.
|
|
16980
|
+
*
|
|
16981
|
+
* The creation loop is inside the guard too, not just the moves and
|
|
16982
|
+
* the clear: `createGroup()` reaches consumer code of its own —
|
|
16983
|
+
* `initialize()` mounts the watermark through
|
|
16984
|
+
* `createWatermarkComponent()` — so a throw on the n-th panel would
|
|
16985
|
+
* otherwise strand the n-1 staging groups already built.
|
|
16986
|
+
*/
|
|
16987
|
+
try {
|
|
16988
|
+
for (const panel of this.panels) if (newPanels.includes(panel.api.id)) {
|
|
16989
|
+
existingPanels.set(panel.api.id, panel);
|
|
16990
|
+
let temporaryGroup;
|
|
16991
|
+
if (panel.api.renderer === "always" && panel.api.isVisible) temporaryGroup = createTemporaryGroup();
|
|
16992
|
+
else {
|
|
16993
|
+
var _sharedTemporaryGroup;
|
|
16994
|
+
(_sharedTemporaryGroup = sharedTemporaryGroup) !== null && _sharedTemporaryGroup !== void 0 || (sharedTemporaryGroup = createTemporaryGroup());
|
|
16995
|
+
temporaryGroup = sharedTemporaryGroup;
|
|
16996
|
+
}
|
|
16997
|
+
temporaryGroups.set(panel.api.id, temporaryGroup);
|
|
16998
|
+
stagedPanels.push({
|
|
16999
|
+
panel,
|
|
17000
|
+
temporaryGroup
|
|
17001
|
+
});
|
|
17002
|
+
}
|
|
17003
|
+
this.movingLock(() => {
|
|
17004
|
+
stagedPanels.forEach(({ panel, temporaryGroup }) => {
|
|
17005
|
+
this.moveGroupOrPanel({
|
|
17006
|
+
from: {
|
|
17007
|
+
groupId: panel.api.group.api.id,
|
|
17008
|
+
panelId: panel.api.id
|
|
17009
|
+
},
|
|
17010
|
+
to: {
|
|
17011
|
+
group: temporaryGroup,
|
|
17012
|
+
position: "center"
|
|
17013
|
+
},
|
|
17014
|
+
keepEmptyGroups: true
|
|
17015
|
+
});
|
|
16405
17016
|
});
|
|
16406
17017
|
});
|
|
16407
|
-
|
|
16408
|
-
|
|
16409
|
-
|
|
17018
|
+
this.clear();
|
|
17019
|
+
} catch (err) {
|
|
17020
|
+
disposeTemporaryGroups();
|
|
17021
|
+
throw err;
|
|
17022
|
+
}
|
|
17023
|
+
} else this.clear();
|
|
16410
17024
|
const { grid, panels, activeGroup } = data;
|
|
16411
17025
|
try {
|
|
16412
17026
|
var _data$floatingGroups, _data$popoutGroups, _this$_popoutWindowSe12, _this$_floatingGroupS5, _this$_watermarkServi2;
|
|
@@ -16438,9 +17052,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16438
17052
|
* due to a corruption of input data.
|
|
16439
17053
|
*/
|
|
16440
17054
|
const existingPanel = existingPanels.get(child);
|
|
16441
|
-
|
|
17055
|
+
const temporaryGroup = temporaryGroups.get(child);
|
|
17056
|
+
if (temporaryGroup && existingPanel) {
|
|
16442
17057
|
this.movingLock(() => {
|
|
16443
|
-
|
|
17058
|
+
temporaryGroup.model.removePanel(existingPanel);
|
|
16444
17059
|
});
|
|
16445
17060
|
createdPanels.push(existingPanel);
|
|
16446
17061
|
existingPanel.updateFromStateModel(panels[child]);
|
|
@@ -16470,7 +17085,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16470
17085
|
return createGroupFromSerializedState(node.data);
|
|
16471
17086
|
} });
|
|
16472
17087
|
this._layoutFromShell(width, height);
|
|
16473
|
-
if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels);
|
|
17088
|
+
if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels, existingPanels, temporaryGroups);
|
|
16474
17089
|
this.deserializeFloatingWindows((_data$floatingGroups = data.floatingGroups) !== null && _data$floatingGroups !== void 0 ? _data$floatingGroups : [], createGroupFromSerializedState);
|
|
16475
17090
|
const popoutPromises = this.deserializePopoutWindows((_data$popoutGroups = data.popoutGroups) !== null && _data$popoutGroups !== void 0 ? _data$popoutGroups : [], createGroupFromSerializedState);
|
|
16476
17091
|
(_this$_popoutWindowSe12 = this._popoutWindowService) === null || _this$_popoutWindowSe12 === void 0 || _this$_popoutWindowSe12.finishRestoration(popoutPromises);
|
|
@@ -16507,6 +17122,8 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16507
17122
|
* expect trying to load a corrupted layout to result in an error and not silently fail...
|
|
16508
17123
|
*/
|
|
16509
17124
|
throw err;
|
|
17125
|
+
} finally {
|
|
17126
|
+
disposeTemporaryGroups();
|
|
16510
17127
|
}
|
|
16511
17128
|
this.debouncedUpdateAllPositions();
|
|
16512
17129
|
this._onDidLayoutFromJSON.fire();
|
|
@@ -16529,7 +17146,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16529
17146
|
members
|
|
16530
17147
|
};
|
|
16531
17148
|
}
|
|
16532
|
-
deserializeEdgeGroups(edgeGroups, panels) {
|
|
17149
|
+
deserializeEdgeGroups(edgeGroups, panels, existingPanels, temporaryGroups) {
|
|
16533
17150
|
const edgeService = assertModule(this._edgeGroupService, "EdgeGroup", "fromJSON edge restoration");
|
|
16534
17151
|
if (!edgeService) return;
|
|
16535
17152
|
for (const _position of [
|
|
@@ -16559,13 +17176,40 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16559
17176
|
if (groupState) {
|
|
16560
17177
|
const { views, activeView } = groupState;
|
|
16561
17178
|
const createdPanels = [];
|
|
16562
|
-
for (const panelId of views)
|
|
16563
|
-
|
|
16564
|
-
|
|
17179
|
+
for (const panelId of views) {
|
|
17180
|
+
if (!panels[panelId]) continue;
|
|
17181
|
+
/**
|
|
17182
|
+
* Reclaim a staged panel rather than rebuilding it, the
|
|
17183
|
+
* same way the grid path does. Deserializing here instead
|
|
17184
|
+
* would honour `reuseExistingPanels` everywhere except edge
|
|
17185
|
+
* groups: the live panel keeps sitting in its staging group
|
|
17186
|
+
* while a second panel is built under the same id, so the
|
|
17187
|
+
* consumer's renderer for the original is orphaned — never
|
|
17188
|
+
* disposed, and its element left inside the id-keyed
|
|
17189
|
+
* overlay entry the replacement now shares.
|
|
17190
|
+
*/
|
|
17191
|
+
const existingPanel = existingPanels.get(panelId);
|
|
17192
|
+
const temporaryGroup = temporaryGroups.get(panelId);
|
|
17193
|
+
if (temporaryGroup && existingPanel) {
|
|
17194
|
+
this.movingLock(() => {
|
|
17195
|
+
temporaryGroup.model.removePanel(existingPanel);
|
|
17196
|
+
});
|
|
17197
|
+
createdPanels.push(existingPanel);
|
|
17198
|
+
existingPanel.updateFromStateModel(panels[panelId]);
|
|
17199
|
+
} else {
|
|
17200
|
+
const panel = this._deserializer.fromJSON(panels[panelId], edgeGroup);
|
|
17201
|
+
createdPanels.push(panel);
|
|
17202
|
+
}
|
|
16565
17203
|
}
|
|
16566
17204
|
for (const panel of createdPanels) {
|
|
16567
17205
|
const isActive = activeView === panel.id;
|
|
16568
|
-
|
|
17206
|
+
if (existingPanels.has(panel.api.id)) this.movingLock(() => {
|
|
17207
|
+
edgeGroup.model.openPanel(panel, {
|
|
17208
|
+
skipSetActive: !isActive,
|
|
17209
|
+
skipSetGroupActive: true
|
|
17210
|
+
});
|
|
17211
|
+
});
|
|
17212
|
+
else edgeGroup.model.openPanel(panel, {
|
|
16569
17213
|
skipSetActive: !isActive,
|
|
16570
17214
|
skipSetGroupActive: true
|
|
16571
17215
|
});
|
|
@@ -16989,22 +17633,100 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
16989
17633
|
* outermost mutation.
|
|
16990
17634
|
*/
|
|
16991
17635
|
mutation(kind, func) {
|
|
16992
|
-
const
|
|
17636
|
+
const close = this.openMutation(kind);
|
|
17637
|
+
try {
|
|
17638
|
+
return func();
|
|
17639
|
+
} finally {
|
|
17640
|
+
close();
|
|
17641
|
+
}
|
|
17642
|
+
}
|
|
17643
|
+
/**
|
|
17644
|
+
* `mutation()` for an operation whose work continues after the synchronous
|
|
17645
|
+
* call returns. The transaction stays open until the returned promise
|
|
17646
|
+
* settles, so everything the operation does - the group it adds, the panels
|
|
17647
|
+
* it relocates - lands inside the bracket, matching the synchronous
|
|
17648
|
+
* move / float paths.
|
|
17649
|
+
*/
|
|
17650
|
+
mutationAsync(kind, func) {
|
|
17651
|
+
var _this = this;
|
|
17652
|
+
return _asyncToGenerator(function* () {
|
|
17653
|
+
const close = _this.openMutation(kind);
|
|
17654
|
+
try {
|
|
17655
|
+
return yield func();
|
|
17656
|
+
} finally {
|
|
17657
|
+
close();
|
|
17658
|
+
}
|
|
17659
|
+
})();
|
|
17660
|
+
}
|
|
17661
|
+
/**
|
|
17662
|
+
* Open a transaction and return the function that closes it. Shared by the
|
|
17663
|
+
* synchronous and asynchronous brackets; the returned function must be
|
|
17664
|
+
* called exactly once.
|
|
17665
|
+
*
|
|
17666
|
+
* Both ends key off the depth counter reaching zero rather than off which
|
|
17667
|
+
* bracket opened first. For synchronous nesting the two are the same thing
|
|
17668
|
+
* - brackets close in the order they opened - but asynchronous transactions
|
|
17669
|
+
* can *overlap* rather than nest (two `addPopoutGroup` calls in flight at
|
|
17670
|
+
* once, or a restore staggering several), and there the first to open is
|
|
17671
|
+
* not the last to close. Reporting on the opener would fire `didMutate`
|
|
17672
|
+
* while the other transaction was still doing structural work, which is the
|
|
17673
|
+
* very thing the async bracket exists to prevent. Overlapping transactions
|
|
17674
|
+
* therefore report as one, tagged with the kind of the last to finish.
|
|
17675
|
+
*/
|
|
17676
|
+
openMutation(kind) {
|
|
16993
17677
|
const origin = this._origin;
|
|
16994
|
-
if (
|
|
17678
|
+
if (this._mutationDepth === 0) this._onWillMutateLayout.fire({
|
|
16995
17679
|
kind,
|
|
16996
17680
|
origin
|
|
16997
17681
|
});
|
|
16998
17682
|
this._mutationDepth++;
|
|
16999
|
-
|
|
17000
|
-
return func();
|
|
17001
|
-
} finally {
|
|
17683
|
+
return () => {
|
|
17002
17684
|
this._mutationDepth--;
|
|
17003
|
-
if (
|
|
17004
|
-
|
|
17005
|
-
|
|
17006
|
-
|
|
17685
|
+
if (this._mutationDepth === 0) {
|
|
17686
|
+
this.flushLocationChanges();
|
|
17687
|
+
this._onDidMutateLayout.fire({
|
|
17688
|
+
kind,
|
|
17689
|
+
origin
|
|
17690
|
+
});
|
|
17691
|
+
}
|
|
17692
|
+
};
|
|
17693
|
+
}
|
|
17694
|
+
/**
|
|
17695
|
+
* Coalesce a panel's `onDidLocationChange` to the end of the enclosing
|
|
17696
|
+
* transaction, or fire it immediately when no transaction is in flight.
|
|
17697
|
+
*
|
|
17698
|
+
* Relocating a panel touches its location twice: once as it is reparented
|
|
17699
|
+
* into the destination group - which, when that group has just been created
|
|
17700
|
+
* for a floating or popout window, has not been told where it lives yet -
|
|
17701
|
+
* and once as the group is tagged with its final location. Reporting each
|
|
17702
|
+
* signal as it happens therefore leaks an intermediate `grid` location the
|
|
17703
|
+
* panel was never in, at a moment when it belongs to neither group's panel
|
|
17704
|
+
* list and so is missing from `api.panels`.
|
|
17705
|
+
*
|
|
17706
|
+
* Deferring collapses those signals into a single event carrying the
|
|
17707
|
+
* settled location. Note the signals are deliberately *not* compared
|
|
17708
|
+
* against the panel's previous location: a panel can move between two
|
|
17709
|
+
* floating windows without its location type changing, and this event is
|
|
17710
|
+
* the only signal `OverlayRenderContainer` has to re-resolve the panel's
|
|
17711
|
+
* z-index against its new host window.
|
|
17712
|
+
*/
|
|
17713
|
+
deferLocationChange(key, fire) {
|
|
17714
|
+
if (this._mutationDepth === 0) {
|
|
17715
|
+
fire();
|
|
17716
|
+
return;
|
|
17007
17717
|
}
|
|
17718
|
+
this._pendingLocationChanges.set(key, fire);
|
|
17719
|
+
}
|
|
17720
|
+
/**
|
|
17721
|
+
* Report every panel whose location moved during the transaction that has
|
|
17722
|
+
* just closed. Each callback reads the panel's location at this point, so
|
|
17723
|
+
* what it reports is where the panel ended up.
|
|
17724
|
+
*/
|
|
17725
|
+
flushLocationChanges() {
|
|
17726
|
+
if (this._pendingLocationChanges.size === 0) return;
|
|
17727
|
+
const pending = Array.from(this._pendingLocationChanges.values());
|
|
17728
|
+
this._pendingLocationChanges.clear();
|
|
17729
|
+
for (const fire of pending) fire();
|
|
17008
17730
|
}
|
|
17009
17731
|
/**
|
|
17010
17732
|
* The origin of the operation currently in progress (`'user'` by default).
|
|
@@ -17045,6 +17767,18 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17045
17767
|
origin: this._origin
|
|
17046
17768
|
});
|
|
17047
17769
|
}
|
|
17770
|
+
/**
|
|
17771
|
+
* Announce that `panel` has finished relocating. Must be called once the
|
|
17772
|
+
* move has settled: `to` is read from the panel's current group, so an
|
|
17773
|
+
* early call would report the source group as the destination.
|
|
17774
|
+
*/
|
|
17775
|
+
fireDidMovePanel(panel, from) {
|
|
17776
|
+
this._onDidMovePanel.fire({
|
|
17777
|
+
panel,
|
|
17778
|
+
from,
|
|
17779
|
+
to: panel.group
|
|
17780
|
+
});
|
|
17781
|
+
}
|
|
17048
17782
|
moveGroupOrPanel(options) {
|
|
17049
17783
|
this.mutation("move", () => this._doMoveGroupOrPanel(options));
|
|
17050
17784
|
}
|
|
@@ -17105,10 +17839,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17105
17839
|
});
|
|
17106
17840
|
});
|
|
17107
17841
|
if (!options.skipSetActive) this.doSetGroupAndPanelActive(destinationGroup);
|
|
17108
|
-
this.
|
|
17109
|
-
panel: removedPanel,
|
|
17110
|
-
from: sourceGroup
|
|
17111
|
-
});
|
|
17842
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
17112
17843
|
} else {
|
|
17113
17844
|
/**
|
|
17114
17845
|
* Dropping a panel to the extremities of a group which will place that panel
|
|
@@ -17127,10 +17858,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17127
17858
|
const [sourceParentLocation, from] = tail(getGridLocation(sourceGroup.element));
|
|
17128
17859
|
if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
|
|
17129
17860
|
this.gridview.moveView(sourceParentLocation, from, to);
|
|
17130
|
-
this.
|
|
17131
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
17132
|
-
from: sourceGroup
|
|
17133
|
-
});
|
|
17861
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
17134
17862
|
return;
|
|
17135
17863
|
}
|
|
17136
17864
|
}
|
|
@@ -17158,13 +17886,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17158
17886
|
}));
|
|
17159
17887
|
this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
17160
17888
|
const updatedTargetLocation = getRelativeLocation(destinationGridview.orientation, getGridLocation(destinationGroup.element), destinationTarget);
|
|
17161
|
-
const newGroup = this.createGroupAtLocation(updatedTargetLocation,
|
|
17889
|
+
const newGroup = this.createGroupAtLocation(updatedTargetLocation, this.dropSizing(getGridLocation(destinationGroup.element)), void 0, destinationGridview);
|
|
17162
17890
|
this.movingLock(() => newGroup.model.openPanel(removedPanel, { skipSetActive: true }));
|
|
17163
17891
|
this.doSetGroupAndPanelActive(newGroup);
|
|
17164
|
-
this.
|
|
17165
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
17166
|
-
from: sourceGroup
|
|
17167
|
-
});
|
|
17892
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
17168
17893
|
return;
|
|
17169
17894
|
}
|
|
17170
17895
|
if (sourceGroup.api.location.type === "edge") {
|
|
@@ -17178,13 +17903,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17178
17903
|
skipSetActiveGroup: true
|
|
17179
17904
|
}));
|
|
17180
17905
|
if (!removedPanel) throw new Error(`dockview: No panel with id ${sourceItemId}`);
|
|
17181
|
-
const newGroup = this.createGroupAtLocation(targetLocation,
|
|
17906
|
+
const newGroup = this.createGroupAtLocation(targetLocation, this.dropSizing(referenceLocation), void 0, destinationGridview);
|
|
17182
17907
|
this.movingLock(() => newGroup.model.openPanel(removedPanel, { skipSetGroupActive: true }));
|
|
17183
17908
|
this.doSetGroupAndPanelActive(newGroup);
|
|
17184
|
-
this.
|
|
17185
|
-
panel: removedPanel,
|
|
17186
|
-
from: sourceGroup
|
|
17187
|
-
});
|
|
17909
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
17188
17910
|
return;
|
|
17189
17911
|
}
|
|
17190
17912
|
const targetGroup = this.movingLock(() => this.doRemoveGroup(sourceGroup, {
|
|
@@ -17193,13 +17915,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17193
17915
|
}));
|
|
17194
17916
|
const updatedReferenceLocation = getGridLocation(destinationGroup.element);
|
|
17195
17917
|
const location = getRelativeLocation(destinationGridview.orientation, updatedReferenceLocation, destinationTarget);
|
|
17196
|
-
this.movingLock(() => this.doAddGroup(targetGroup, location,
|
|
17918
|
+
this.movingLock(() => this.doAddGroup(targetGroup, location, this.dropSizing(updatedReferenceLocation), destinationGridview));
|
|
17197
17919
|
this.setGroupLocationForRoot(targetGroup, destinationGridview);
|
|
17198
17920
|
this.doSetGroupAndPanelActive(targetGroup);
|
|
17199
|
-
this.
|
|
17200
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
17201
|
-
from: sourceGroup
|
|
17202
|
-
});
|
|
17921
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
17203
17922
|
} else {
|
|
17204
17923
|
/**
|
|
17205
17924
|
* The group we are removing from has many panels, we need to remove the panels we are moving,
|
|
@@ -17211,13 +17930,10 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17211
17930
|
}));
|
|
17212
17931
|
if (!removedPanel) throw new Error(`dockview: No panel with id ${sourceItemId}`);
|
|
17213
17932
|
const dropLocation = getRelativeLocation(destinationGridview.orientation, referenceLocation, destinationTarget);
|
|
17214
|
-
const group = this.createGroupAtLocation(dropLocation,
|
|
17933
|
+
const group = this.createGroupAtLocation(dropLocation, this.dropSizing(referenceLocation), void 0, destinationGridview);
|
|
17215
17934
|
this.movingLock(() => group.model.openPanel(removedPanel, { skipSetGroupActive: true }));
|
|
17216
17935
|
this.doSetGroupAndPanelActive(group);
|
|
17217
|
-
this.
|
|
17218
|
-
panel: removedPanel,
|
|
17219
|
-
from: sourceGroup
|
|
17220
|
-
});
|
|
17936
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
17221
17937
|
}
|
|
17222
17938
|
}
|
|
17223
17939
|
}
|
|
@@ -17252,16 +17968,13 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17252
17968
|
});
|
|
17253
17969
|
for (const panel of removedPanels) targetGroup.model.addPanelToTabGroup(newTabGroup.id, panel.id);
|
|
17254
17970
|
if (!options.skipSetActive) this.doSetGroupAndPanelActive(targetGroup);
|
|
17255
|
-
for (const panel of removedPanels) this.
|
|
17256
|
-
panel,
|
|
17257
|
-
from: sourceGroup
|
|
17258
|
-
});
|
|
17971
|
+
for (const panel of removedPanels) this.fireDidMovePanel(panel, sourceGroup);
|
|
17259
17972
|
};
|
|
17260
17973
|
let targetGroup;
|
|
17261
17974
|
if (!destinationTarget || destinationTarget === "center" || !referenceLocation) targetGroup = destinationGroup;
|
|
17262
17975
|
else {
|
|
17263
17976
|
const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
|
|
17264
|
-
targetGroup = this.createGroupAtLocation(dropLocation);
|
|
17977
|
+
targetGroup = this.createGroupAtLocation(dropLocation, this.dropSizing(referenceLocation));
|
|
17265
17978
|
}
|
|
17266
17979
|
if (!options.keepEmptyGroups && sourceGroup.model.size === 0 && sourceGroup !== targetGroup) this.doRemoveGroup(sourceGroup, { skipActive: true });
|
|
17267
17980
|
addPanelsToGroup(targetGroup);
|
|
@@ -17276,10 +17989,12 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17276
17989
|
this.mutation("maximize", () => super.exitMaximizedGroup());
|
|
17277
17990
|
}
|
|
17278
17991
|
_doMoveGroup(options) {
|
|
17992
|
+
var _mergedPanels;
|
|
17279
17993
|
const from = options.from.group;
|
|
17280
17994
|
const to = options.to.group;
|
|
17281
17995
|
const target = options.to.position;
|
|
17282
17996
|
let source = from;
|
|
17997
|
+
let mergedPanels;
|
|
17283
17998
|
if (target === "center") {
|
|
17284
17999
|
const activePanel = from.activePanel;
|
|
17285
18000
|
const tabGroupSnapshots = from.model.getTabGroups().map((tg) => ({
|
|
@@ -17297,6 +18012,7 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17297
18012
|
skipSetGroupActive: true
|
|
17298
18013
|
});
|
|
17299
18014
|
});
|
|
18015
|
+
mergedPanels = panels;
|
|
17300
18016
|
for (const snapshot of tabGroupSnapshots) {
|
|
17301
18017
|
const newTabGroup = to.model.createTabGroup({
|
|
17302
18018
|
label: snapshot.label,
|
|
@@ -17309,6 +18025,21 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17309
18025
|
if (options.skipSetActive !== true) this.doSetGroupAndPanelActive(to);
|
|
17310
18026
|
else if (!this.activePanel) this.doSetGroupAndPanelActive(to);
|
|
17311
18027
|
} else {
|
|
18028
|
+
const isReorderWithinBranch = (() => {
|
|
18029
|
+
if (from.api.location.type === "edge" || to.api.location.type === "edge") return false;
|
|
18030
|
+
const root = this.getGridviewForGroup(from);
|
|
18031
|
+
if (root !== this.getGridviewForGroup(to)) return false;
|
|
18032
|
+
let fromLocation;
|
|
18033
|
+
let toLocation;
|
|
18034
|
+
try {
|
|
18035
|
+
fromLocation = getGridLocation(from.element);
|
|
18036
|
+
toLocation = getGridLocation(to.element);
|
|
18037
|
+
} catch (_unused) {
|
|
18038
|
+
return false;
|
|
18039
|
+
}
|
|
18040
|
+
if (fromLocation.length === 0 || toLocation.length === 0) return false;
|
|
18041
|
+
return sequenceEquals(tail(fromLocation)[0], tail(toLocation)[0]) && getLocationOrientation(root.orientation, toLocation) === getDirectionOrientation(target);
|
|
18042
|
+
})();
|
|
17312
18043
|
if (from.api.location.type === "edge") {
|
|
17313
18044
|
/**
|
|
17314
18045
|
* Edge groups are permanent structural elements and must
|
|
@@ -17374,23 +18105,17 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17374
18105
|
const referenceLocation = getGridLocation(to.element);
|
|
17375
18106
|
const dropLocation = getRelativeLocation(destGridview.orientation, referenceLocation, target);
|
|
17376
18107
|
let size;
|
|
17377
|
-
|
|
17378
|
-
|
|
17379
|
-
|
|
17380
|
-
|
|
17381
|
-
case "HORIZONTAL":
|
|
17382
|
-
size = referenceLocation.length % 2 == 0 ? from.api.height : from.api.width;
|
|
17383
|
-
break;
|
|
18108
|
+
if (isReorderWithinBranch) size = getDirectionOrientation(target) === "HORIZONTAL" ? from.api.width : from.api.height;
|
|
18109
|
+
else {
|
|
18110
|
+
var _referenceLocation;
|
|
18111
|
+
size = Sizing.Split((_referenceLocation = referenceLocation[referenceLocation.length - 1]) !== null && _referenceLocation !== void 0 ? _referenceLocation : 0);
|
|
17384
18112
|
}
|
|
17385
18113
|
destGridview.addView(source, size, dropLocation);
|
|
17386
18114
|
this.setGroupLocationForRoot(source, destGridview);
|
|
17387
18115
|
}
|
|
17388
18116
|
}
|
|
17389
|
-
source.panels.forEach((panel) => {
|
|
17390
|
-
this.
|
|
17391
|
-
panel,
|
|
17392
|
-
from
|
|
17393
|
-
});
|
|
18117
|
+
((_mergedPanels = mergedPanels) !== null && _mergedPanels !== void 0 ? _mergedPanels : source.panels).forEach((panel) => {
|
|
18118
|
+
this.fireDidMovePanel(panel, from);
|
|
17394
18119
|
});
|
|
17395
18120
|
this.debouncedUpdateAllPositions();
|
|
17396
18121
|
if (options.skipSetActive === false) {
|
|
@@ -17508,6 +18233,16 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17508
18233
|
});
|
|
17509
18234
|
return panel;
|
|
17510
18235
|
}
|
|
18236
|
+
/**
|
|
18237
|
+
* Sizing for a group created by a drop next to `referenceLocation`: half
|
|
18238
|
+
* of the group the overlay was drawn over, leaving its siblings alone, so
|
|
18239
|
+
* the panel lands in the region the overlay indicated (#1612). Gridview
|
|
18240
|
+
* rewrites the index to 0 when a cross-axis drop wraps the reference in a
|
|
18241
|
+
* new branch, so one value serves both paths.
|
|
18242
|
+
*/
|
|
18243
|
+
dropSizing(referenceLocation) {
|
|
18244
|
+
return Sizing.Split(referenceLocation.length === 0 ? 0 : referenceLocation[referenceLocation.length - 1]);
|
|
18245
|
+
}
|
|
17511
18246
|
createGroupAtLocation(location, size, options, gridview = this.gridview) {
|
|
17512
18247
|
const group = this.createGroup(options);
|
|
17513
18248
|
this.doAddGroup(group, location, size, gridview);
|
|
@@ -17567,22 +18302,22 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
17567
18302
|
return location.length % 2 == 1 ? rootOrientation : orthogonal(rootOrientation);
|
|
17568
18303
|
}
|
|
17569
18304
|
updateTheme() {
|
|
17570
|
-
var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe23, _this$_popoutWindowSe24, _this$
|
|
18305
|
+
var _this$_options$theme, _this$_shellThemeClas, _theme$gap, _this$_popoutWindowSe23, _this$_popoutWindowSe24, _this$_shellManager5, _theme$edgeGroupColla, _theme$tabGroupIndica;
|
|
17571
18306
|
const theme = (_this$_options$theme = this._options.theme) !== null && _this$_options$theme !== void 0 ? _this$_options$theme : themeAbyss;
|
|
17572
18307
|
(_this$_shellThemeClas = this._shellThemeClassnames) === null || _this$_shellThemeClas === void 0 || _this$_shellThemeClas.setClassNames(theme.className);
|
|
17573
18308
|
const gap = (_theme$gap = theme.gap) !== null && _theme$gap !== void 0 ? _theme$gap : 0;
|
|
17574
18309
|
this.gridview.margin = gap;
|
|
17575
18310
|
for (const floating of this.floatingGroups) floating.gridview.margin = gap;
|
|
17576
18311
|
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;
|
|
17577
|
-
(_this$
|
|
18312
|
+
(_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);
|
|
17578
18313
|
if (theme.dndOverlayBorder === void 0) {
|
|
17579
|
-
var _this$
|
|
18314
|
+
var _this$_shellManager6;
|
|
17580
18315
|
this.element.style.removeProperty("--dv-drag-over-border");
|
|
17581
|
-
(_this$
|
|
18316
|
+
(_this$_shellManager6 = this._shellManager) === null || _this$_shellManager6 === void 0 || _this$_shellManager6.element.style.removeProperty("--dv-drag-over-border");
|
|
17582
18317
|
} else {
|
|
17583
|
-
var _this$
|
|
18318
|
+
var _this$_shellManager7;
|
|
17584
18319
|
this.element.style.setProperty("--dv-drag-over-border", theme.dndOverlayBorder);
|
|
17585
|
-
(_this$
|
|
18320
|
+
(_this$_shellManager7 = this._shellManager) === null || _this$_shellManager7 === void 0 || _this$_shellManager7.element.style.setProperty("--dv-drag-over-border", theme.dndOverlayBorder);
|
|
17586
18321
|
}
|
|
17587
18322
|
switch (theme.dndOverlayMounting) {
|
|
17588
18323
|
case "absolute":
|
|
@@ -18485,6 +19220,8 @@ exports.AdvancedDnDModule = AdvancedDnDModule;
|
|
|
18485
19220
|
exports.AdvancedDnDService = AdvancedDnDService;
|
|
18486
19221
|
exports.BaseGrid = BaseGrid;
|
|
18487
19222
|
exports.ContentContainer = ContentContainer;
|
|
19223
|
+
exports.ContextMenuController = ContextMenuController;
|
|
19224
|
+
exports.ContextMenuModule = ContextMenuModule;
|
|
18488
19225
|
exports.DEFAULT_TAB_GROUP_COLORS = DEFAULT_TAB_GROUP_COLORS;
|
|
18489
19226
|
exports.DefaultDockviewDeserialzier = DefaultDockviewDeserialzier;
|
|
18490
19227
|
exports.DefaultTab = DefaultTab;
|