dockview-core 8.0.0 → 8.2.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/dockviewPanelApi.d.ts +12 -0
- package/dist/cjs/dnd/dataTransfer.d.ts +1 -0
- package/dist/cjs/dockview/advancedDnDService.d.ts +3 -18
- package/dist/cjs/dockview/dockviewComponent.d.ts +71 -5
- package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +24 -0
- package/dist/cjs/dockview/moduleContracts.d.ts +5 -0
- package/dist/cjs/dockview/options.d.ts +0 -1
- package/dist/cjs/dockview/tabGroup.d.ts +3 -0
- package/dist/cjs/events.d.ts +1 -1
- package/dist/cjs/gridview/branchNode.d.ts +16 -0
- package/dist/cjs/overlay/overlayRenderContainer.d.ts +13 -1
- package/dist/cjs/scrollbar.d.ts +10 -0
- package/dist/cjs/splitview/viewItem.d.ts +10 -0
- package/dist/dockview-core.js +757 -255
- package/dist/dockview-core.min.js +2 -2
- package/dist/dockview-core.min.noStyle.js +2 -2
- package/dist/dockview-core.noStyle.js +757 -255
- package/dist/package/main.cjs.js +757 -255
- package/dist/package/main.cjs.min.js +2 -2
- package/dist/package/main.esm.min.mjs +2 -2
- package/dist/package/main.esm.mjs +757 -255
- package/package.json +1 -1
package/dist/package/main.cjs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dockview-core
|
|
3
|
-
* @version 8.
|
|
3
|
+
* @version 8.2.0
|
|
4
4
|
* @link https://github.com/dockview/dockview
|
|
5
5
|
* @license MIT
|
|
6
6
|
*/
|
|
@@ -8,7 +8,9 @@ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toString
|
|
|
8
8
|
|
|
9
9
|
//#region src/dnd/dataTransfer.ts
|
|
10
10
|
var _LocalSelectionTransfer;
|
|
11
|
-
var TransferObject = class {
|
|
11
|
+
var TransferObject = class {
|
|
12
|
+
constructor() {}
|
|
13
|
+
};
|
|
12
14
|
var PanelTransfer = class extends TransferObject {
|
|
13
15
|
constructor(viewId, groupId, panelId, tabGroupId) {
|
|
14
16
|
super();
|
|
@@ -201,7 +203,6 @@ var Emitter = class Emitter {
|
|
|
201
203
|
this.options = options;
|
|
202
204
|
this._listeners = [];
|
|
203
205
|
this._disposed = false;
|
|
204
|
-
this._pauseTokens = /* @__PURE__ */ new Set();
|
|
205
206
|
}
|
|
206
207
|
get event() {
|
|
207
208
|
if (!this._event) {
|
|
@@ -222,14 +223,26 @@ var Emitter = class Emitter {
|
|
|
222
223
|
}
|
|
223
224
|
fire(e) {
|
|
224
225
|
var _this$options2;
|
|
225
|
-
if (this._pauseTokens.size > 0) return;
|
|
226
|
+
if (this._pauseTokens !== void 0 && this._pauseTokens.size > 0) return;
|
|
226
227
|
if ((_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.replay) this._last = e;
|
|
227
|
-
|
|
228
|
+
const listeners = this._listeners;
|
|
229
|
+
const length = listeners.length;
|
|
230
|
+
if (length === 0) return;
|
|
231
|
+
if (length === 1) {
|
|
232
|
+
listeners[0].callback(e);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
for (const listener of listeners.slice()) listener.callback(e);
|
|
228
236
|
}
|
|
229
237
|
pause() {
|
|
238
|
+
var _this$_pauseTokens;
|
|
230
239
|
const token = {};
|
|
240
|
+
(_this$_pauseTokens = this._pauseTokens) !== null && _this$_pauseTokens !== void 0 || (this._pauseTokens = /* @__PURE__ */ new Set());
|
|
231
241
|
this._pauseTokens.add(token);
|
|
232
|
-
return Disposable.from(() =>
|
|
242
|
+
return Disposable.from(() => {
|
|
243
|
+
var _this$_pauseTokens2;
|
|
244
|
+
return (_this$_pauseTokens2 = this._pauseTokens) === null || _this$_pauseTokens2 === void 0 ? void 0 : _this$_pauseTokens2.delete(token);
|
|
245
|
+
});
|
|
233
246
|
}
|
|
234
247
|
dispose() {
|
|
235
248
|
if (!this._disposed) {
|
|
@@ -532,8 +545,10 @@ function onDidWindowMoveEnd(window) {
|
|
|
532
545
|
let previousScreenX = window.screenX;
|
|
533
546
|
let previousScreenY = window.screenY;
|
|
534
547
|
let timeout;
|
|
548
|
+
let rafHandle = 0;
|
|
549
|
+
let stopped = false;
|
|
535
550
|
const checkMovement = () => {
|
|
536
|
-
if (window.closed) return;
|
|
551
|
+
if (stopped || window.closed) return;
|
|
537
552
|
const currentScreenX = window.screenX;
|
|
538
553
|
const currentScreenY = window.screenY;
|
|
539
554
|
if (currentScreenX !== previousScreenX || currentScreenY !== previousScreenY) {
|
|
@@ -544,9 +559,18 @@ function onDidWindowMoveEnd(window) {
|
|
|
544
559
|
previousScreenX = currentScreenX;
|
|
545
560
|
previousScreenY = currentScreenY;
|
|
546
561
|
}
|
|
547
|
-
requestAnimationFrame(checkMovement);
|
|
562
|
+
rafHandle = requestAnimationFrame(checkMovement);
|
|
548
563
|
};
|
|
549
564
|
checkMovement();
|
|
565
|
+
const disposeEmitter = emitter.dispose.bind(emitter);
|
|
566
|
+
emitter.dispose = () => {
|
|
567
|
+
if (!stopped) {
|
|
568
|
+
stopped = true;
|
|
569
|
+
cancelAnimationFrame(rafHandle);
|
|
570
|
+
clearTimeout(timeout);
|
|
571
|
+
}
|
|
572
|
+
disposeEmitter();
|
|
573
|
+
};
|
|
550
574
|
return emitter;
|
|
551
575
|
}
|
|
552
576
|
function onDidWindowResizeEnd(element, cb) {
|
|
@@ -682,6 +706,11 @@ var ViewItem = class {
|
|
|
682
706
|
set size(size) {
|
|
683
707
|
this._size = size;
|
|
684
708
|
}
|
|
709
|
+
setContainerGeometry(prop, value) {
|
|
710
|
+
if (this._appliedStyles[prop] === value) return;
|
|
711
|
+
this._appliedStyles[prop] = value;
|
|
712
|
+
this.container.style[prop] = value;
|
|
713
|
+
}
|
|
685
714
|
get size() {
|
|
686
715
|
return this._size;
|
|
687
716
|
}
|
|
@@ -717,6 +746,7 @@ var ViewItem = class {
|
|
|
717
746
|
this.view = view;
|
|
718
747
|
this.disposable = disposable;
|
|
719
748
|
this._cachedVisibleSize = void 0;
|
|
749
|
+
this._appliedStyles = {};
|
|
720
750
|
if (typeof size === "number") {
|
|
721
751
|
this._size = size;
|
|
722
752
|
this._cachedVisibleSize = void 0;
|
|
@@ -765,6 +795,16 @@ let LayoutPriority = /* @__PURE__ */ function(LayoutPriority) {
|
|
|
765
795
|
LayoutPriority["Normal"] = "normal";
|
|
766
796
|
return LayoutPriority;
|
|
767
797
|
}({});
|
|
798
|
+
function setSashPosition(sash, left, top) {
|
|
799
|
+
if (sash.appliedLeft !== left) {
|
|
800
|
+
sash.appliedLeft = left;
|
|
801
|
+
sash.container.style.left = left;
|
|
802
|
+
}
|
|
803
|
+
if (sash.appliedTop !== top) {
|
|
804
|
+
sash.appliedTop = top;
|
|
805
|
+
sash.container.style.top = top;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
768
808
|
let Sizing;
|
|
769
809
|
(function(_Sizing) {
|
|
770
810
|
_Sizing.Distribute = { type: "distribute" };
|
|
@@ -883,10 +923,6 @@ var Splitview = class {
|
|
|
883
923
|
pushToEnd(upIndexes, i);
|
|
884
924
|
pushToEnd(downIndexes, i);
|
|
885
925
|
}
|
|
886
|
-
const upItems = upIndexes.map((i) => this.viewItems[i]);
|
|
887
|
-
const upSizes = upIndexes.map((i) => sizes[i]);
|
|
888
|
-
const downItems = downIndexes.map((i) => this.viewItems[i]);
|
|
889
|
-
const downSizes = downIndexes.map((i) => sizes[i]);
|
|
890
926
|
const minDeltaUp = upIndexes.reduce((_, i) => _ + this.viewItems[i].minimumSize - sizes[i], 0);
|
|
891
927
|
const maxDeltaUp = upIndexes.reduce((_, i) => _ + this.viewItems[i].maximumSize - sizes[i], 0);
|
|
892
928
|
const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((_, i) => _ + sizes[i] - this.viewItems[i].minimumSize, 0);
|
|
@@ -910,19 +946,21 @@ var Splitview = class {
|
|
|
910
946
|
const tentativeDelta = clamp(delta, minDelta, maxDelta);
|
|
911
947
|
let actualDelta = 0;
|
|
912
948
|
let deltaUp = tentativeDelta;
|
|
913
|
-
for (
|
|
914
|
-
const item =
|
|
915
|
-
const
|
|
916
|
-
const
|
|
949
|
+
for (const upIndex of upIndexes) {
|
|
950
|
+
const item = this.viewItems[upIndex];
|
|
951
|
+
const priorSize = sizes[upIndex];
|
|
952
|
+
const size = clamp(priorSize + deltaUp, item.minimumSize, item.maximumSize);
|
|
953
|
+
const viewDelta = size - priorSize;
|
|
917
954
|
actualDelta += viewDelta;
|
|
918
955
|
deltaUp -= viewDelta;
|
|
919
956
|
item.size = size;
|
|
920
957
|
}
|
|
921
958
|
let deltaDown = actualDelta;
|
|
922
|
-
for (
|
|
923
|
-
const item =
|
|
924
|
-
const
|
|
925
|
-
const
|
|
959
|
+
for (const downIndex of downIndexes) {
|
|
960
|
+
const item = this.viewItems[downIndex];
|
|
961
|
+
const priorSize = sizes[downIndex];
|
|
962
|
+
const size = clamp(priorSize - deltaDown, item.minimumSize, item.maximumSize);
|
|
963
|
+
const viewDelta = size - priorSize;
|
|
926
964
|
deltaDown += viewDelta;
|
|
927
965
|
item.size = size;
|
|
928
966
|
}
|
|
@@ -1170,13 +1208,22 @@ var Splitview = class {
|
|
|
1170
1208
|
this.saveProportions();
|
|
1171
1209
|
}
|
|
1172
1210
|
distributeEmptySpace(lowPriorityIndex) {
|
|
1173
|
-
|
|
1211
|
+
let contentSize = 0;
|
|
1212
|
+
for (const item of this.viewItems) contentSize += item.size;
|
|
1174
1213
|
let emptyDelta = this.size - contentSize;
|
|
1214
|
+
if (emptyDelta === 0) return;
|
|
1175
1215
|
const indexes = range(this.viewItems.length - 1, -1);
|
|
1176
|
-
|
|
1177
|
-
const
|
|
1178
|
-
|
|
1179
|
-
|
|
1216
|
+
let hasPriority = false;
|
|
1217
|
+
for (const item of this.viewItems) if (item.priority === "low" || item.priority === "high") {
|
|
1218
|
+
hasPriority = true;
|
|
1219
|
+
break;
|
|
1220
|
+
}
|
|
1221
|
+
if (hasPriority) {
|
|
1222
|
+
const lowPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === "low");
|
|
1223
|
+
const highPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === "high");
|
|
1224
|
+
for (const index of highPriorityIndexes) pushToStart(indexes, index);
|
|
1225
|
+
for (const index of lowPriorityIndexes) pushToEnd(indexes, index);
|
|
1226
|
+
}
|
|
1180
1227
|
if (typeof lowPriorityIndex === "number") pushToEnd(indexes, lowPriorityIndex);
|
|
1181
1228
|
for (let i = 0; emptyDelta !== 0 && i < indexes.length; i++) {
|
|
1182
1229
|
const item = this.viewItems[indexes[i]];
|
|
@@ -1199,49 +1246,45 @@ var Splitview = class {
|
|
|
1199
1246
|
* For each view `i` the offet must be adjusted by `m * i/(n - 1)`.
|
|
1200
1247
|
*/
|
|
1201
1248
|
layoutViews() {
|
|
1202
|
-
|
|
1249
|
+
let contentSize = 0;
|
|
1250
|
+
let visibleViewCount = 0;
|
|
1251
|
+
for (const item of this.viewItems) {
|
|
1252
|
+
contentSize += item.size;
|
|
1253
|
+
if (item.visible) visibleViewCount++;
|
|
1254
|
+
}
|
|
1255
|
+
this._contentSize = contentSize;
|
|
1203
1256
|
this.updateSashEnablement();
|
|
1204
1257
|
if (this.viewItems.length === 0) return;
|
|
1205
|
-
const
|
|
1206
|
-
const
|
|
1207
|
-
const marginReducedSize = this.margin * sashCount / Math.max(1, visibleViewItems.length);
|
|
1258
|
+
const sashCount = Math.max(0, visibleViewCount - 1);
|
|
1259
|
+
const marginReducedSize = this.margin * sashCount / Math.max(1, visibleViewCount);
|
|
1208
1260
|
let totalLeftOffset = 0;
|
|
1209
1261
|
const viewLeftOffsets = [];
|
|
1210
1262
|
const sashWidth = 4;
|
|
1211
|
-
|
|
1212
|
-
const flag = viewItem.visible ? 1 : 0;
|
|
1213
|
-
if (i === 0) arr.push(flag);
|
|
1214
|
-
else arr.push(arr[i - 1] + flag);
|
|
1215
|
-
return arr;
|
|
1216
|
-
}, []);
|
|
1263
|
+
let runningVisiblePanelCount = 0;
|
|
1217
1264
|
this.viewItems.forEach((view, i) => {
|
|
1218
1265
|
totalLeftOffset += this.viewItems[i].size;
|
|
1219
1266
|
viewLeftOffsets.push(totalLeftOffset);
|
|
1267
|
+
runningVisiblePanelCount += view.visible ? 1 : 0;
|
|
1220
1268
|
const size = view.visible ? view.size - marginReducedSize : 0;
|
|
1221
|
-
const visiblePanelsBeforeThisView = Math.max(0, runningVisiblePanelCount
|
|
1269
|
+
const visiblePanelsBeforeThisView = Math.max(0, runningVisiblePanelCount - 1);
|
|
1222
1270
|
const offset = i === 0 || visiblePanelsBeforeThisView === 0 ? 0 : viewLeftOffsets[i - 1] + visiblePanelsBeforeThisView / sashCount * marginReducedSize;
|
|
1223
1271
|
if (i < this.viewItems.length - 1) {
|
|
1224
1272
|
const newSize = view.visible ? offset + size - sashWidth / 2 + this.margin / 2 : offset;
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
}
|
|
1229
|
-
if (this._orientation === "VERTICAL") {
|
|
1230
|
-
this.sashes[i].container.style.left = `0px`;
|
|
1231
|
-
this.sashes[i].container.style.top = `${newSize}px`;
|
|
1232
|
-
}
|
|
1273
|
+
const sash = this.sashes[i];
|
|
1274
|
+
if (this._orientation === "HORIZONTAL") setSashPosition(sash, `${newSize}px`, `0px`);
|
|
1275
|
+
if (this._orientation === "VERTICAL") setSashPosition(sash, `0px`, `${newSize}px`);
|
|
1233
1276
|
}
|
|
1234
1277
|
if (this._orientation === "HORIZONTAL") {
|
|
1235
|
-
view.
|
|
1236
|
-
view.
|
|
1237
|
-
view.
|
|
1238
|
-
view.
|
|
1278
|
+
view.setContainerGeometry("width", `${size}px`);
|
|
1279
|
+
view.setContainerGeometry("left", `${offset}px`);
|
|
1280
|
+
view.setContainerGeometry("top", "");
|
|
1281
|
+
view.setContainerGeometry("height", "");
|
|
1239
1282
|
}
|
|
1240
1283
|
if (this._orientation === "VERTICAL") {
|
|
1241
|
-
view.
|
|
1242
|
-
view.
|
|
1243
|
-
view.
|
|
1244
|
-
view.
|
|
1284
|
+
view.setContainerGeometry("height", `${size}px`);
|
|
1285
|
+
view.setContainerGeometry("top", `${offset}px`);
|
|
1286
|
+
view.setContainerGeometry("width", "");
|
|
1287
|
+
view.setContainerGeometry("left", "");
|
|
1245
1288
|
}
|
|
1246
1289
|
view.view.layout(view.size - marginReducedSize, this._orthogonalSize);
|
|
1247
1290
|
});
|
|
@@ -1259,6 +1302,7 @@ var Splitview = class {
|
|
|
1259
1302
|
}
|
|
1260
1303
|
}
|
|
1261
1304
|
updateSashEnablement() {
|
|
1305
|
+
if (this.sashes.length === 0) return;
|
|
1262
1306
|
let previous = false;
|
|
1263
1307
|
const collapsesDown = this.viewItems.map((i) => previous = i.size - i.minimumSize > 0 || previous);
|
|
1264
1308
|
previous = false;
|
|
@@ -1565,10 +1609,20 @@ var BranchNode = class BranchNode extends CompositeDisposable {
|
|
|
1565
1609
|
return this.orientation === "HORIZONTAL" ? this.orthogonalSize : this.size;
|
|
1566
1610
|
}
|
|
1567
1611
|
get minimumSize() {
|
|
1568
|
-
|
|
1612
|
+
if (this._cachedMinimumSize === void 0) {
|
|
1613
|
+
let value = 0;
|
|
1614
|
+
for (let index = 0; index < this.children.length; index++) if (this.splitview.isViewVisible(index)) value = Math.max(value, this.children[index].minimumOrthogonalSize);
|
|
1615
|
+
this._cachedMinimumSize = value;
|
|
1616
|
+
}
|
|
1617
|
+
return this._cachedMinimumSize;
|
|
1569
1618
|
}
|
|
1570
1619
|
get maximumSize() {
|
|
1571
|
-
|
|
1620
|
+
if (this._cachedMaximumSize === void 0) {
|
|
1621
|
+
let value = Number.POSITIVE_INFINITY;
|
|
1622
|
+
for (let index = 0; index < this.children.length; index++) if (this.splitview.isViewVisible(index)) value = Math.min(value, this.children[index].maximumOrthogonalSize);
|
|
1623
|
+
this._cachedMaximumSize = value;
|
|
1624
|
+
}
|
|
1625
|
+
return this._cachedMaximumSize;
|
|
1572
1626
|
}
|
|
1573
1627
|
get minimumOrthogonalSize() {
|
|
1574
1628
|
return this.splitview.minimumSize;
|
|
@@ -1595,15 +1649,29 @@ var BranchNode = class BranchNode extends CompositeDisposable {
|
|
|
1595
1649
|
return this.orientation === "HORIZONTAL" ? this.maximumSize : this.maximumOrthogonalSize;
|
|
1596
1650
|
}
|
|
1597
1651
|
get priority() {
|
|
1652
|
+
var _this$_cachedPriority;
|
|
1653
|
+
(_this$_cachedPriority = this._cachedPriority) !== null && _this$_cachedPriority !== void 0 || (this._cachedPriority = this.computePriority());
|
|
1654
|
+
return this._cachedPriority;
|
|
1655
|
+
}
|
|
1656
|
+
computePriority() {
|
|
1598
1657
|
if (this.children.length === 0) return "normal";
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1658
|
+
let hasHigh = false;
|
|
1659
|
+
let hasLow = false;
|
|
1660
|
+
for (const child of this.children) {
|
|
1661
|
+
var _child$priority;
|
|
1662
|
+
const priority = (_child$priority = child.priority) !== null && _child$priority !== void 0 ? _child$priority : "normal";
|
|
1663
|
+
if (priority === "high") hasHigh = true;
|
|
1664
|
+
else if (priority === "low") hasLow = true;
|
|
1665
|
+
}
|
|
1666
|
+
if (hasHigh) return "high";
|
|
1667
|
+
else if (hasLow) return "low";
|
|
1605
1668
|
return "normal";
|
|
1606
1669
|
}
|
|
1670
|
+
invalidateCachedSizes() {
|
|
1671
|
+
this._cachedMinimumSize = void 0;
|
|
1672
|
+
this._cachedMaximumSize = void 0;
|
|
1673
|
+
this._cachedPriority = void 0;
|
|
1674
|
+
}
|
|
1607
1675
|
get disabled() {
|
|
1608
1676
|
return this.splitview.disabled;
|
|
1609
1677
|
}
|
|
@@ -1679,6 +1747,7 @@ var BranchNode = class BranchNode extends CompositeDisposable {
|
|
|
1679
1747
|
if (this.splitview.isViewVisible(index) === visible) return;
|
|
1680
1748
|
const wereAllChildrenHidden = this.splitview.contentSize === 0;
|
|
1681
1749
|
this.splitview.setViewVisible(index, visible);
|
|
1750
|
+
this.invalidateCachedSizes();
|
|
1682
1751
|
const areAllChildrenHidden = this.splitview.contentSize === 0;
|
|
1683
1752
|
if (visible && wereAllChildrenHidden || !visible && areAllChildrenHidden) this._onDidVisibilityChange.fire({ visible });
|
|
1684
1753
|
}
|
|
@@ -1727,12 +1796,14 @@ var BranchNode = class BranchNode extends CompositeDisposable {
|
|
|
1727
1796
|
return child;
|
|
1728
1797
|
}
|
|
1729
1798
|
setupChildrenEvents() {
|
|
1799
|
+
this.invalidateCachedSizes();
|
|
1730
1800
|
this._childrenDisposable.dispose();
|
|
1731
1801
|
this._childrenDisposable = new CompositeDisposable(Event.any(...this.children.map((c) => c.onDidChange))((e) => {
|
|
1732
1802
|
/**
|
|
1733
1803
|
* indicate a change has occured to allows any re-rendering but don't bubble
|
|
1734
1804
|
* event because that was specific to this branch
|
|
1735
1805
|
*/
|
|
1806
|
+
this.invalidateCachedSizes();
|
|
1736
1807
|
this._onDidChange.fire({ size: e.orthogonalSize });
|
|
1737
1808
|
}), ...this.children.map((c, i) => {
|
|
1738
1809
|
if (c instanceof BranchNode) return c.onDidVisibilityChange(({ visible }) => {
|
|
@@ -3409,7 +3480,7 @@ var DockviewApi = class {
|
|
|
3409
3480
|
* Add a group and return the created object.
|
|
3410
3481
|
*/
|
|
3411
3482
|
addGroup(options) {
|
|
3412
|
-
return this.component.addGroup(options);
|
|
3483
|
+
return this.component.withOrigin("api", () => this.component.addGroup(options));
|
|
3413
3484
|
}
|
|
3414
3485
|
/**
|
|
3415
3486
|
* Close all groups and panels.
|
|
@@ -3547,13 +3618,13 @@ var DockviewApi = class {
|
|
|
3547
3618
|
this.activatePrevious(options);
|
|
3548
3619
|
}
|
|
3549
3620
|
maximizeGroup(panel) {
|
|
3550
|
-
this.component.maximizeGroup(panel.group);
|
|
3621
|
+
this.component.withOrigin("api", () => this.component.maximizeGroup(panel.group));
|
|
3551
3622
|
}
|
|
3552
3623
|
hasMaximizedGroup() {
|
|
3553
3624
|
return this.component.hasMaximizedGroup();
|
|
3554
3625
|
}
|
|
3555
3626
|
exitMaximizedGroup() {
|
|
3556
|
-
this.component.exitMaximizedGroup();
|
|
3627
|
+
this.component.withOrigin("api", () => this.component.exitMaximizedGroup());
|
|
3557
3628
|
}
|
|
3558
3629
|
get onDidMaximizedGroupChange() {
|
|
3559
3630
|
return this.component.onDidMaximizedGroupChange;
|
|
@@ -5508,9 +5579,6 @@ var ContentContainer = class extends CompositeDisposable {
|
|
|
5508
5579
|
const doRender = ((_options$asActive = options === null || options === void 0 ? void 0 : options.asActive) !== null && _options$asActive !== void 0 ? _options$asActive : true) || this.panel && this.group.isPanelActive(this.panel);
|
|
5509
5580
|
if (((_this$panel = this.panel) === null || _this$panel === void 0 ? void 0 : _this$panel.view.content.element.parentElement) === this._element) {
|
|
5510
5581
|
var _this$panel$view$cont, _this$panel$view$cont2;
|
|
5511
|
-
/**
|
|
5512
|
-
* If the currently attached panel is mounted directly to the content then remove it
|
|
5513
|
-
*/
|
|
5514
5582
|
this.panel.view.content.element.remove();
|
|
5515
5583
|
(_this$panel$view$cont = (_this$panel$view$cont2 = this.panel.view.content).onHide) === null || _this$panel$view$cont === void 0 || _this$panel$view$cont.call(_this$panel$view$cont2);
|
|
5516
5584
|
}
|
|
@@ -6251,7 +6319,7 @@ var Scrollbar = class Scrollbar extends CompositeDisposable {
|
|
|
6251
6319
|
this.element.appendChild(this._scrollbar);
|
|
6252
6320
|
this.addDisposables(addDisposableListener(this.element, "wheel", (event) => {
|
|
6253
6321
|
this._scrollOffset += event.deltaY * Scrollbar.MouseWheelSpeed;
|
|
6254
|
-
this.
|
|
6322
|
+
this.scheduleStyleUpdate();
|
|
6255
6323
|
}), addDisposableListener(this._scrollbar, "pointerdown", (event) => {
|
|
6256
6324
|
var _this$_scrollbar$owne;
|
|
6257
6325
|
event.preventDefault();
|
|
@@ -6263,7 +6331,7 @@ var Scrollbar = class Scrollbar extends CompositeDisposable {
|
|
|
6263
6331
|
const delta = this._orientation === "horizontal" ? event.clientX - originalClient : event.clientY - originalClient;
|
|
6264
6332
|
const p = (this._orientation === "horizontal" ? this.element.clientWidth : this.element.clientHeight) / (this._orientation === "horizontal" ? this.scrollableElement.scrollWidth : this.scrollableElement.scrollHeight);
|
|
6265
6333
|
this._scrollOffset = originalScrollOffset + delta / p;
|
|
6266
|
-
this.
|
|
6334
|
+
this.scheduleStyleUpdate();
|
|
6267
6335
|
};
|
|
6268
6336
|
const onEnd = () => {
|
|
6269
6337
|
toggleClass(this.element, "dv-scrollable-scrolling", false);
|
|
@@ -6275,10 +6343,10 @@ var Scrollbar = class Scrollbar extends CompositeDisposable {
|
|
|
6275
6343
|
doc.addEventListener("pointerup", onEnd);
|
|
6276
6344
|
doc.addEventListener("pointercancel", onEnd);
|
|
6277
6345
|
}), addDisposableListener(this.element, "scroll", () => {
|
|
6278
|
-
this.
|
|
6346
|
+
this.scheduleStyleUpdate();
|
|
6279
6347
|
}), addDisposableListener(this.scrollableElement, "scroll", () => {
|
|
6280
6348
|
this._scrollOffset = this._orientation === "horizontal" ? this.scrollableElement.scrollLeft : this.scrollableElement.scrollTop;
|
|
6281
|
-
this.
|
|
6349
|
+
this.scheduleStyleUpdate();
|
|
6282
6350
|
}), watchElementResize(this.element, () => {
|
|
6283
6351
|
toggleClass(this.element, "dv-scrollable-resizing", true);
|
|
6284
6352
|
if (this._animationTimer) clearTimeout(this._animationTimer);
|
|
@@ -6286,9 +6354,29 @@ var Scrollbar = class Scrollbar extends CompositeDisposable {
|
|
|
6286
6354
|
clearTimeout(this._animationTimer);
|
|
6287
6355
|
toggleClass(this.element, "dv-scrollable-resizing", false);
|
|
6288
6356
|
}, 500);
|
|
6289
|
-
this.
|
|
6357
|
+
this.scheduleStyleUpdate();
|
|
6358
|
+
}), Disposable.from(() => {
|
|
6359
|
+
if (this._pendingStyleFrame !== void 0) {
|
|
6360
|
+
cancelAnimationFrame(this._pendingStyleFrame);
|
|
6361
|
+
this._pendingStyleFrame = void 0;
|
|
6362
|
+
}
|
|
6290
6363
|
}));
|
|
6291
6364
|
}
|
|
6365
|
+
/**
|
|
6366
|
+
* Coalesce the scrollbar restyle to one pass per animation frame. The
|
|
6367
|
+
* wheel / scroll / pointermove handlers can each fire many times per frame,
|
|
6368
|
+
* and `calculateScrollbarStyles` both reads layout (`clientWidth`/
|
|
6369
|
+
* `scrollWidth`) and writes styles + `scrollLeft`/`scrollTop`; running it
|
|
6370
|
+
* synchronously per event caused repeated read→write→read reflow. Batching
|
|
6371
|
+
* to a frame keeps a burst of events to a single measure+write.
|
|
6372
|
+
*/
|
|
6373
|
+
scheduleStyleUpdate() {
|
|
6374
|
+
if (this._pendingStyleFrame !== void 0) return;
|
|
6375
|
+
this._pendingStyleFrame = requestAnimationFrame(() => {
|
|
6376
|
+
this._pendingStyleFrame = void 0;
|
|
6377
|
+
this.calculateScrollbarStyles();
|
|
6378
|
+
});
|
|
6379
|
+
}
|
|
6292
6380
|
calculateScrollbarStyles() {
|
|
6293
6381
|
const clientSize = this._orientation === "horizontal" ? this.element.clientWidth : this.element.clientHeight;
|
|
6294
6382
|
const scrollSize = this._orientation === "horizontal" ? this.scrollableElement.scrollWidth : this.scrollableElement.scrollHeight;
|
|
@@ -8749,8 +8837,8 @@ var Tabs = class extends CompositeDisposable {
|
|
|
8749
8837
|
}, true), addDisposableListener(this._tabsList, "dragend", () => {
|
|
8750
8838
|
this._reorder.resetDragAnimation();
|
|
8751
8839
|
}), addDisposableListener(this._tabsList, "drop", (event) => {
|
|
8752
|
-
var _this$accessor$option, _this$group$model$dro;
|
|
8753
|
-
if (
|
|
8840
|
+
var _this$_animState3, _this$accessor$option, _this$group$model$dro;
|
|
8841
|
+
if (((_this$_animState3 = this._animState) === null || _this$_animState3 === void 0 ? void 0 : _this$_animState3.currentInsertionIndex) == null) return;
|
|
8754
8842
|
if (((_this$accessor$option = this.accessor.options.theme) === null || _this$accessor$option === void 0 ? void 0 : _this$accessor$option.tabAnimation) !== "smooth" && !this._animState.sourceTabGroupId) return;
|
|
8755
8843
|
event.stopPropagation();
|
|
8756
8844
|
event.preventDefault();
|
|
@@ -8955,7 +9043,7 @@ var Tabs = class extends CompositeDisposable {
|
|
|
8955
9043
|
};
|
|
8956
9044
|
this._pendingCollapse = true;
|
|
8957
9045
|
requestAnimationFrame(() => {
|
|
8958
|
-
var _this$
|
|
9046
|
+
var _this$_animState4, _this$_animState4$cur;
|
|
8959
9047
|
this._pendingCollapse = false;
|
|
8960
9048
|
if (!this._animState) return;
|
|
8961
9049
|
if (!this._tabsList.classList.contains("dv-tabs-container--wrap")) {
|
|
@@ -8963,7 +9051,7 @@ var Tabs = class extends CompositeDisposable {
|
|
|
8963
9051
|
toggleClass(tab.element, "dv-tab--dragging", true);
|
|
8964
9052
|
tab.element.offsetHeight;
|
|
8965
9053
|
}
|
|
8966
|
-
(_this$
|
|
9054
|
+
(_this$_animState4$cur = (_this$_animState4 = this._animState).currentInsertionIndex) !== null && _this$_animState4$cur !== void 0 || (_this$_animState4.currentInsertionIndex = sourceIndex);
|
|
8967
9055
|
this.applyDragOverTransforms(true);
|
|
8968
9056
|
tab.element.style.removeProperty("transition");
|
|
8969
9057
|
});
|
|
@@ -9052,8 +9140,8 @@ var Tabs = class extends CompositeDisposable {
|
|
|
9052
9140
|
}
|
|
9053
9141
|
}
|
|
9054
9142
|
delete(id) {
|
|
9055
|
-
var _this$
|
|
9056
|
-
if (((_this$
|
|
9143
|
+
var _this$_animState5;
|
|
9144
|
+
if (((_this$_animState5 = this._animState) === null || _this$_animState5 === void 0 ? void 0 : _this$_animState5.sourceTabId) === id) {
|
|
9057
9145
|
this.resetTabTransforms();
|
|
9058
9146
|
this._animState = null;
|
|
9059
9147
|
}
|
|
@@ -9170,7 +9258,7 @@ var Tabs = class extends CompositeDisposable {
|
|
|
9170
9258
|
const groupPanelIds = new Set(tabGroup.panelIds);
|
|
9171
9259
|
this._pendingCollapse = true;
|
|
9172
9260
|
requestAnimationFrame(() => {
|
|
9173
|
-
var _this$
|
|
9261
|
+
var _this$_animState6, _this$_animState6$cur;
|
|
9174
9262
|
this._pendingCollapse = false;
|
|
9175
9263
|
if (!this._animState) return;
|
|
9176
9264
|
for (const t of this._tabs) if (groupPanelIds.has(t.value.panel.id)) {
|
|
@@ -9185,7 +9273,7 @@ var Tabs = class extends CompositeDisposable {
|
|
|
9185
9273
|
this._tabsList.offsetHeight;
|
|
9186
9274
|
const underline = this._tabGroupManager.groupUnderlines.get(tabGroup.id);
|
|
9187
9275
|
if (underline) underline.style.display = "none";
|
|
9188
|
-
(_this$
|
|
9276
|
+
(_this$_animState6$cur = (_this$_animState6 = this._animState).currentInsertionIndex) !== null && _this$_animState6$cur !== void 0 || (_this$_animState6.currentInsertionIndex = firstIdx);
|
|
9189
9277
|
this.applyDragOverTransforms(true);
|
|
9190
9278
|
for (const t of this._tabs) if (groupPanelIds.has(t.value.panel.id)) t.value.element.style.removeProperty("transition");
|
|
9191
9279
|
if (chipEntry) chipEntry.chip.element.style.removeProperty("transition");
|
|
@@ -9920,6 +10008,7 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
|
|
|
9920
10008
|
set headerPosition(value) {
|
|
9921
10009
|
var _this$_activePanel;
|
|
9922
10010
|
this._headerPosition = value;
|
|
10011
|
+
this.invalidateHeaderSize();
|
|
9923
10012
|
removeClasses(this.container, "dv-groupview-header-top", "dv-groupview-header-bottom", "dv-groupview-header-left", "dv-groupview-header-right");
|
|
9924
10013
|
addClasses(this.container, `dv-groupview-header-${value}`);
|
|
9925
10014
|
const direction = value === "top" || value === "bottom" ? "horizontal" : "vertical";
|
|
@@ -10061,7 +10150,14 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
|
|
|
10061
10150
|
this.header.hidden = !!options.hideHeader;
|
|
10062
10151
|
this.locked = (_options$locked = options.locked) !== null && _options$locked !== void 0 ? _options$locked : false;
|
|
10063
10152
|
this.headerPosition = (_options$headerPositi = options.headerPosition) !== null && _options$headerPositi !== void 0 ? _options$headerPositi : accessor.defaultHeaderPosition;
|
|
10064
|
-
this.addDisposables(
|
|
10153
|
+
this.addDisposables(watchElementResize(this.tabsContainer.element, () => {
|
|
10154
|
+
if (this.isDisposed) return;
|
|
10155
|
+
const size = this.measureHeaderSize();
|
|
10156
|
+
if (size !== this._cachedHeaderSize) {
|
|
10157
|
+
this._cachedHeaderSize = size;
|
|
10158
|
+
this.layout(this._width, this._height);
|
|
10159
|
+
}
|
|
10160
|
+
}), this._onDidPanelTitleChange.event(() => this.updateAccessibleLabel()), this._onTabDragStart, this._onGroupDragStart, this._onWillShowOverlay, this.tabsContainer.onTabDragStart((event) => {
|
|
10065
10161
|
this._onTabDragStart.fire(event);
|
|
10066
10162
|
}), this.tabsContainer.onGroupDragStart((event) => {
|
|
10067
10163
|
this._onGroupDragStart.fire(event);
|
|
@@ -10426,7 +10522,11 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
|
|
|
10426
10522
|
this.panels.forEach((panel) => {
|
|
10427
10523
|
this.rerender(panel);
|
|
10428
10524
|
});
|
|
10429
|
-
if (this._activePanel)
|
|
10525
|
+
if (this._activePanel) {
|
|
10526
|
+
this.contentContainer.renderPanel(this._activePanel, { asActive: true });
|
|
10527
|
+
const { width, height } = this.contentDimensions();
|
|
10528
|
+
this._activePanel.layout(width, height);
|
|
10529
|
+
}
|
|
10430
10530
|
}
|
|
10431
10531
|
get renderContainer() {
|
|
10432
10532
|
var _this$_overwriteRende;
|
|
@@ -10518,16 +10618,11 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
|
|
|
10518
10618
|
(_this$_activePanel3 = this._activePanel) === null || _this$_activePanel3 === void 0 || _this$_activePanel3.focus();
|
|
10519
10619
|
}
|
|
10520
10620
|
openPanel(panel, options = {}) {
|
|
10521
|
-
/**
|
|
10522
|
-
* set the panel group
|
|
10523
|
-
* add the panel
|
|
10524
|
-
* check if group active
|
|
10525
|
-
* check if panel active
|
|
10526
|
-
*/
|
|
10527
10621
|
if (typeof options.index !== "number" || options.index > this.panels.length) options.index = this.panels.length;
|
|
10528
10622
|
const skipSetActive = !!options.skipSetActive;
|
|
10529
10623
|
panel.updateParentGroup(this.groupPanel, { skipSetActive: options.skipSetActive });
|
|
10530
10624
|
this.doAddPanel(panel, options.index, { skipSetActive });
|
|
10625
|
+
this.invalidateHeaderSize();
|
|
10531
10626
|
if (this._activePanel === panel) {
|
|
10532
10627
|
this.contentContainer.renderPanel(panel, { asActive: true });
|
|
10533
10628
|
return;
|
|
@@ -10590,6 +10685,7 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
|
|
|
10590
10685
|
* changing) down to the content + active panel.
|
|
10591
10686
|
*/
|
|
10592
10687
|
relayout() {
|
|
10688
|
+
this.invalidateHeaderSize();
|
|
10593
10689
|
this.layout(this._width, this._height);
|
|
10594
10690
|
}
|
|
10595
10691
|
/**
|
|
@@ -10599,17 +10695,32 @@ var DockviewGroupPanelModel = class extends CompositeDisposable {
|
|
|
10599
10695
|
* width); a hidden header has `display:none` so its `offset*` is 0 and
|
|
10600
10696
|
* nothing is subtracted.
|
|
10601
10697
|
*/
|
|
10602
|
-
|
|
10698
|
+
/**
|
|
10699
|
+
* Measure the header's extent along its occupied axis. This is the single
|
|
10700
|
+
* forced-reflow read; it now runs only on a cache miss (first layout after
|
|
10701
|
+
* a header change) and inside the header's ResizeObserver — not on every
|
|
10702
|
+
* layout frame.
|
|
10703
|
+
*/
|
|
10704
|
+
measureHeaderSize() {
|
|
10603
10705
|
const headerEl = this.tabsContainer.element;
|
|
10706
|
+
return this.headerPosition === "top" || this.headerPosition === "bottom" ? headerEl.offsetHeight : headerEl.offsetWidth;
|
|
10707
|
+
}
|
|
10708
|
+
invalidateHeaderSize() {
|
|
10709
|
+
this._cachedHeaderSize = void 0;
|
|
10710
|
+
}
|
|
10711
|
+
contentDimensions() {
|
|
10712
|
+
var _this$_cachedHeaderSi;
|
|
10604
10713
|
const horizontal = this.headerPosition === "top" || this.headerPosition === "bottom";
|
|
10714
|
+
const headerSize = (_this$_cachedHeaderSi = this._cachedHeaderSize) !== null && _this$_cachedHeaderSi !== void 0 ? _this$_cachedHeaderSi : this._cachedHeaderSize = this.measureHeaderSize();
|
|
10605
10715
|
return {
|
|
10606
|
-
width: horizontal ? this._width : Math.max(0, this._width -
|
|
10607
|
-
height: horizontal ? Math.max(0, this._height -
|
|
10716
|
+
width: horizontal ? this._width : Math.max(0, this._width - headerSize),
|
|
10717
|
+
height: horizontal ? Math.max(0, this._height - headerSize) : this._height
|
|
10608
10718
|
};
|
|
10609
10719
|
}
|
|
10610
10720
|
_removePanel(panel, options) {
|
|
10611
10721
|
const isActivePanel = this._activePanel === panel;
|
|
10612
10722
|
this.doRemovePanel(panel);
|
|
10723
|
+
this.invalidateHeaderSize();
|
|
10613
10724
|
if (isActivePanel && this.panels.length > 0) {
|
|
10614
10725
|
const nextPanel = this.mostRecentlyUsed[0];
|
|
10615
10726
|
this.openPanel(nextPanel, {
|
|
@@ -10935,6 +11046,7 @@ var GridviewPanel = class extends BasePanelView {
|
|
|
10935
11046
|
if (typeof event.minimumHeight === "number" || typeof event.minimumHeight === "function") this._minimumHeight = event.minimumHeight;
|
|
10936
11047
|
if (typeof event.maximumWidth === "number" || typeof event.maximumWidth === "function") this._maximumWidth = event.maximumWidth;
|
|
10937
11048
|
if (typeof event.maximumHeight === "number" || typeof event.maximumHeight === "function") this._maximumHeight = event.maximumHeight;
|
|
11049
|
+
this._onDidChange.fire(void 0);
|
|
10938
11050
|
}), this.api.onDidSizeChange((event) => {
|
|
10939
11051
|
this._onDidChange.fire({
|
|
10940
11052
|
height: event.height,
|
|
@@ -11054,20 +11166,22 @@ var DockviewGroupPanelApiImpl = class extends GridviewPanelApiImpl {
|
|
|
11054
11166
|
return this._group.model.headerPosition;
|
|
11055
11167
|
}
|
|
11056
11168
|
moveTo(options) {
|
|
11057
|
-
var _options$group, _options$position, _options$skipSetActiv, _options$position2;
|
|
11058
11169
|
if (!this._group) throw new Error(NOT_INITIALIZED_MESSAGE);
|
|
11059
|
-
|
|
11060
|
-
|
|
11061
|
-
|
|
11062
|
-
|
|
11063
|
-
|
|
11064
|
-
|
|
11065
|
-
|
|
11066
|
-
|
|
11067
|
-
|
|
11068
|
-
|
|
11069
|
-
|
|
11070
|
-
|
|
11170
|
+
this.accessor.withOrigin("api", () => {
|
|
11171
|
+
var _options$group, _options$position, _options$skipSetActiv, _options$position2;
|
|
11172
|
+
const group = (_options$group = options.group) !== null && _options$group !== void 0 ? _options$group : this.accessor.addGroup({
|
|
11173
|
+
direction: positionToDirection((_options$position = options.position) !== null && _options$position !== void 0 ? _options$position : "right"),
|
|
11174
|
+
skipSetActive: (_options$skipSetActiv = options.skipSetActive) !== null && _options$skipSetActiv !== void 0 ? _options$skipSetActiv : false
|
|
11175
|
+
});
|
|
11176
|
+
this.accessor.moveGroupOrPanel({
|
|
11177
|
+
from: { groupId: this._group.id },
|
|
11178
|
+
to: {
|
|
11179
|
+
group,
|
|
11180
|
+
position: options.group ? (_options$position2 = options.position) !== null && _options$position2 !== void 0 ? _options$position2 : "center" : "center",
|
|
11181
|
+
index: options.index
|
|
11182
|
+
},
|
|
11183
|
+
skipSetActive: options.skipSetActive
|
|
11184
|
+
});
|
|
11071
11185
|
});
|
|
11072
11186
|
}
|
|
11073
11187
|
maximize() {
|
|
@@ -11377,7 +11491,7 @@ var DockviewPanelApiImpl = class extends GridviewPanelApiImpl {
|
|
|
11377
11491
|
this._group = value;
|
|
11378
11492
|
this._onDidGroupChange.fire({});
|
|
11379
11493
|
this.setupGroupEventListeners(oldGroup);
|
|
11380
|
-
this.
|
|
11494
|
+
this.fireLocationChange();
|
|
11381
11495
|
}
|
|
11382
11496
|
}
|
|
11383
11497
|
get group() {
|
|
@@ -11416,18 +11530,20 @@ var DockviewPanelApiImpl = class extends GridviewPanelApiImpl {
|
|
|
11416
11530
|
this.accessor.withOrigin("api", () => super.setActive());
|
|
11417
11531
|
}
|
|
11418
11532
|
moveTo(options) {
|
|
11419
|
-
|
|
11420
|
-
|
|
11421
|
-
|
|
11422
|
-
|
|
11423
|
-
|
|
11424
|
-
|
|
11425
|
-
|
|
11426
|
-
|
|
11427
|
-
|
|
11428
|
-
|
|
11429
|
-
|
|
11430
|
-
|
|
11533
|
+
this.accessor.withOrigin("api", () => {
|
|
11534
|
+
var _options$group, _options$position;
|
|
11535
|
+
return this.accessor.moveGroupOrPanel({
|
|
11536
|
+
from: {
|
|
11537
|
+
groupId: this._group.id,
|
|
11538
|
+
panelId: this.panel.id
|
|
11539
|
+
},
|
|
11540
|
+
to: {
|
|
11541
|
+
group: (_options$group = options.group) !== null && _options$group !== void 0 ? _options$group : this._group,
|
|
11542
|
+
position: options.group ? (_options$position = options.position) !== null && _options$position !== void 0 ? _options$position : "center" : "center",
|
|
11543
|
+
index: options.index
|
|
11544
|
+
},
|
|
11545
|
+
skipSetActive: options.skipSetActive
|
|
11546
|
+
});
|
|
11431
11547
|
});
|
|
11432
11548
|
}
|
|
11433
11549
|
setTitle(title) {
|
|
@@ -11451,6 +11567,23 @@ var DockviewPanelApiImpl = class extends GridviewPanelApiImpl {
|
|
|
11451
11567
|
exitMaximized() {
|
|
11452
11568
|
this.group.api.exitMaximized();
|
|
11453
11569
|
}
|
|
11570
|
+
/**
|
|
11571
|
+
* Report that this panel's location may have moved.
|
|
11572
|
+
*
|
|
11573
|
+
* A relocation touches the location more than once - the panel is
|
|
11574
|
+
* reparented into the destination group, then that group is tagged with
|
|
11575
|
+
* the location it ends up at - so the event is coalesced to the end of the
|
|
11576
|
+
* enclosing layout mutation and reports where the panel actually settled.
|
|
11577
|
+
* Firing each signal as it happened surfaced an intermediate `grid`
|
|
11578
|
+
* location the panel was never in, at a point where it was in neither
|
|
11579
|
+
* group's panel list. Outside a mutation this fires straight away.
|
|
11580
|
+
*/
|
|
11581
|
+
fireLocationChange() {
|
|
11582
|
+
this.accessor.deferLocationChange(this, () => {
|
|
11583
|
+
if (this.isDisposed) return;
|
|
11584
|
+
this._onDidLocationChange.fire({ location: this.location });
|
|
11585
|
+
});
|
|
11586
|
+
}
|
|
11454
11587
|
setupGroupEventListeners(previousGroup) {
|
|
11455
11588
|
var _previousGroup$isActi;
|
|
11456
11589
|
let _trackGroupActive = (_previousGroup$isActi = previousGroup === null || previousGroup === void 0 ? void 0 : previousGroup.isActive) !== null && _previousGroup$isActi !== void 0 ? _previousGroup$isActi : false;
|
|
@@ -11459,9 +11592,9 @@ var DockviewPanelApiImpl = class extends GridviewPanelApiImpl {
|
|
|
11459
11592
|
const hasBecomeVisible = event.isVisible && !this.isVisible;
|
|
11460
11593
|
const isActivePanel = this.group.model.isPanelActive(this.panel);
|
|
11461
11594
|
if (hasBecomeHidden || hasBecomeVisible && isActivePanel) this._onDidVisibilityChange.fire(event);
|
|
11462
|
-
}), this.group.api.onDidLocationChange((
|
|
11595
|
+
}), this.group.api.onDidLocationChange(() => {
|
|
11463
11596
|
if (this.group !== this.panel.group) return;
|
|
11464
|
-
this.
|
|
11597
|
+
this.fireLocationChange();
|
|
11465
11598
|
}), this.group.api.onDidActiveChange(() => {
|
|
11466
11599
|
if (this.group !== this.panel.group) return;
|
|
11467
11600
|
if (_trackGroupActive !== this.isGroupActive) {
|
|
@@ -12537,12 +12670,6 @@ const OPTION_MODULE_RULES = [
|
|
|
12537
12670
|
moduleName: "ContextMenu",
|
|
12538
12671
|
when: (o) => o.getTabGroupChipContextMenuItems != null
|
|
12539
12672
|
},
|
|
12540
|
-
{
|
|
12541
|
-
optionKey: "createContextMenuItemComponent",
|
|
12542
|
-
reason: "createContextMenuItemComponent",
|
|
12543
|
-
moduleName: "ContextMenu",
|
|
12544
|
-
when: (o) => o.createContextMenuItemComponent != null
|
|
12545
|
-
},
|
|
12546
12673
|
{
|
|
12547
12674
|
optionKey: "dndCompass",
|
|
12548
12675
|
reason: "dndCompass",
|
|
@@ -13271,7 +13398,18 @@ var LiveRegionService = class extends CompositeDisposable {
|
|
|
13271
13398
|
prev = next;
|
|
13272
13399
|
const panel = group.activePanel;
|
|
13273
13400
|
if (!panel) return;
|
|
13274
|
-
|
|
13401
|
+
let kind;
|
|
13402
|
+
switch (next) {
|
|
13403
|
+
case "floating":
|
|
13404
|
+
kind = "float";
|
|
13405
|
+
break;
|
|
13406
|
+
case "popout":
|
|
13407
|
+
kind = "popout";
|
|
13408
|
+
break;
|
|
13409
|
+
default:
|
|
13410
|
+
kind = "dock";
|
|
13411
|
+
break;
|
|
13412
|
+
}
|
|
13275
13413
|
this._announce(panel, kind);
|
|
13276
13414
|
});
|
|
13277
13415
|
this._locationSubs.set(group.id, sub);
|
|
@@ -13323,29 +13461,14 @@ const LiveRegionModule = defineModule({
|
|
|
13323
13461
|
|
|
13324
13462
|
//#endregion
|
|
13325
13463
|
//#region src/dockview/advancedDnDService.ts
|
|
13326
|
-
/** Cursor offset of the group drag ghost
|
|
13464
|
+
/** Cursor offset of the group drag ghost. */
|
|
13327
13465
|
const GROUP_DRAG_GHOST_OFFSET_X = 30;
|
|
13328
13466
|
const GROUP_DRAG_GHOST_OFFSET_Y = -10;
|
|
13329
13467
|
/**
|
|
13330
|
-
* The narrow surface the {@link AdvancedDnDService} needs from the host
|
|
13331
|
-
* (the `DockviewComponent`).
|
|
13332
|
-
*
|
|
13333
|
-
* The `onWill*` emitters stay on the component so the public event shape is
|
|
13334
|
-
* unchanged whether or not this module is registered; the service is only the
|
|
13335
|
-
* dispatch point those fires are routed through. Engine policy (e.g. the
|
|
13336
|
-
* `disableDnd` guard) stays on the component, ahead of the dispatch.
|
|
13337
|
-
*/
|
|
13338
|
-
/**
|
|
13339
13468
|
* Owns the dispatch of the advanced drag-and-drop hooks: `onWillDragPanel`,
|
|
13340
|
-
* `onWillDragGroup`, `onWillDrop` and `onWillShowOverlay
|
|
13341
|
-
*
|
|
13342
|
-
*
|
|
13343
|
-
* emitters; the customisation surface it gates (custom drop overlays, custom
|
|
13344
|
-
* group drag ghosts, hook veto/transform behaviour) is currently inlined in
|
|
13345
|
-
* core and is extracted into this service in later phases. Routing the
|
|
13346
|
-
* dispatch through a module slot is what lets that customisation layer move
|
|
13347
|
-
* into a separately-distributed package in a future major version without
|
|
13348
|
-
* changing the public event surface.
|
|
13469
|
+
* `onWillDragGroup`, `onWillDrop` and `onWillShowOverlay`, forwarding each to
|
|
13470
|
+
* the host's emitters so the public event shape is unchanged whether or not
|
|
13471
|
+
* this module is registered.
|
|
13349
13472
|
*
|
|
13350
13473
|
* The service holds no drag state of its own. The gesture is driven by the
|
|
13351
13474
|
* DnD backends, and the per-group subscriptions live on the component's group
|
|
@@ -13471,7 +13594,7 @@ const AllModules = [
|
|
|
13471
13594
|
//#region src/overlay/overlayRenderContainer.ts
|
|
13472
13595
|
var PositionCache = class {
|
|
13473
13596
|
constructor() {
|
|
13474
|
-
this.cache = /* @__PURE__ */ new
|
|
13597
|
+
this.cache = /* @__PURE__ */ new WeakMap();
|
|
13475
13598
|
this.currentFrameId = 0;
|
|
13476
13599
|
this.rafId = null;
|
|
13477
13600
|
}
|
|
@@ -13497,6 +13620,13 @@ var PositionCache = class {
|
|
|
13497
13620
|
});
|
|
13498
13621
|
}
|
|
13499
13622
|
};
|
|
13623
|
+
/**
|
|
13624
|
+
* Placeholder handle marking "a reposition frame has been requested but the
|
|
13625
|
+
* real handle is not known yet". Never passed to `cancelAnimationFrame` in
|
|
13626
|
+
* practice — it is replaced within the same synchronous block — and harmless
|
|
13627
|
+
* if it were, since no frame carries this id.
|
|
13628
|
+
*/
|
|
13629
|
+
const SCHEDULED = -1;
|
|
13500
13630
|
function createFocusableElement() {
|
|
13501
13631
|
const element = document.createElement("div");
|
|
13502
13632
|
element.tabIndex = -1;
|
|
@@ -13509,12 +13639,13 @@ var OverlayRenderContainer = class extends CompositeDisposable {
|
|
|
13509
13639
|
this.accessor = accessor;
|
|
13510
13640
|
this.map = {};
|
|
13511
13641
|
this._disposed = false;
|
|
13642
|
+
this._generation = 0;
|
|
13512
13643
|
this.positionCache = new PositionCache();
|
|
13513
|
-
this.pendingUpdates = /* @__PURE__ */ new Set();
|
|
13514
13644
|
this.addDisposables(Disposable.from(() => {
|
|
13515
13645
|
for (const value of Object.values(this.map)) {
|
|
13516
13646
|
value.disposable.dispose();
|
|
13517
13647
|
value.destroy.dispose();
|
|
13648
|
+
this.cancelPendingUpdate(value);
|
|
13518
13649
|
}
|
|
13519
13650
|
this._disposed = true;
|
|
13520
13651
|
}));
|
|
@@ -13541,11 +13672,24 @@ var OverlayRenderContainer = class extends CompositeDisposable {
|
|
|
13541
13672
|
this.positionCache.invalidate();
|
|
13542
13673
|
(_entry$resize = entry.resize) === null || _entry$resize === void 0 || _entry$resize.call(entry);
|
|
13543
13674
|
}
|
|
13675
|
+
/**
|
|
13676
|
+
* Drop the reposition frame queued for a panel, if any. A queued frame is
|
|
13677
|
+
* bound to the reference container that was current when it was scheduled,
|
|
13678
|
+
* so it must be discarded whenever that container stops being the one the
|
|
13679
|
+
* overlay should track.
|
|
13680
|
+
*/
|
|
13681
|
+
cancelPendingUpdate(entry) {
|
|
13682
|
+
if (entry.pendingUpdate !== void 0) {
|
|
13683
|
+
cancelAnimationFrame(entry.pendingUpdate);
|
|
13684
|
+
entry.pendingUpdate = void 0;
|
|
13685
|
+
}
|
|
13686
|
+
}
|
|
13544
13687
|
detatch(panel) {
|
|
13545
13688
|
if (this.map[panel.api.id]) {
|
|
13546
|
-
const
|
|
13547
|
-
disposable.dispose();
|
|
13548
|
-
destroy.dispose();
|
|
13689
|
+
const entry = this.map[panel.api.id];
|
|
13690
|
+
entry.disposable.dispose();
|
|
13691
|
+
entry.destroy.dispose();
|
|
13692
|
+
this.cancelPendingUpdate(entry);
|
|
13549
13693
|
delete this.map[panel.api.id];
|
|
13550
13694
|
return true;
|
|
13551
13695
|
}
|
|
@@ -13561,22 +13705,73 @@ var OverlayRenderContainer = class extends CompositeDisposable {
|
|
|
13561
13705
|
panel,
|
|
13562
13706
|
disposable: Disposable.NONE,
|
|
13563
13707
|
destroy: Disposable.NONE,
|
|
13564
|
-
element
|
|
13708
|
+
element,
|
|
13709
|
+
retainPreviousGeometry: false,
|
|
13710
|
+
positioned: false,
|
|
13711
|
+
generation: ++this._generation
|
|
13565
13712
|
};
|
|
13566
13713
|
}
|
|
13567
|
-
const
|
|
13714
|
+
const mapEntry = this.map[panel.api.id];
|
|
13715
|
+
/**
|
|
13716
|
+
* A *change* of reference container supersedes the previous `attach`:
|
|
13717
|
+
* take a fresh generation so its `resize` closure can no longer run,
|
|
13718
|
+
* and drop the frame it queued against the old container. During
|
|
13719
|
+
* `fromJSON({ reuseExistingPanels: true })` that old container is a
|
|
13720
|
+
* detached staging group measuring 0x0, so leaving its frame in flight
|
|
13721
|
+
* both wastes the update and delays the reposition against the real one.
|
|
13722
|
+
*
|
|
13723
|
+
* Re-attaching over the *same* container (re-open, active panel change)
|
|
13724
|
+
* deliberately leaves scheduled work alone: `repositionPanelOverlay`
|
|
13725
|
+
* (the auto-hide peek) schedules a frame carrying the sticky
|
|
13726
|
+
* `forceVisible`/`clip` state which `attach` does not re-apply, and a
|
|
13727
|
+
* peeked panel's `api.isVisible` is false — so discarding that frame
|
|
13728
|
+
* leaves `visibilityChanged` to hide the overlay and the peek renders
|
|
13729
|
+
* nothing. A newly created entry already holds a fresh generation, so
|
|
13730
|
+
* the stale closures a `detatch` left behind are fenced off either way.
|
|
13731
|
+
*/
|
|
13732
|
+
if (mapEntry.referenceContainer !== referenceContainer) {
|
|
13733
|
+
mapEntry.generation = ++this._generation;
|
|
13734
|
+
this.cancelPendingUpdate(mapEntry);
|
|
13735
|
+
mapEntry.referenceContainer = referenceContainer;
|
|
13736
|
+
/**
|
|
13737
|
+
* Arm the retain flag only here: it means "a replacement reference
|
|
13738
|
+
* container is awaiting layout", so the 0x0 early-return below
|
|
13739
|
+
* holds the last good box rather than blanking the panel mid-move.
|
|
13740
|
+
* Arming it on every re-attach instead would make a container that
|
|
13741
|
+
* genuinely collapses to zero keep its stale geometry forever.
|
|
13742
|
+
*
|
|
13743
|
+
* Gated on `positioned` because an overlay that has never been
|
|
13744
|
+
* positioned has no left/top/width/height, and `.dv-render-overlay`
|
|
13745
|
+
* defaults to 100%/100% — retaining "previous" geometry there would
|
|
13746
|
+
* pin the content over the whole container.
|
|
13747
|
+
*/
|
|
13748
|
+
mapEntry.retainPreviousGeometry = mapEntry.positioned;
|
|
13749
|
+
}
|
|
13750
|
+
const generation = mapEntry.generation;
|
|
13751
|
+
const focusContainer = mapEntry.element;
|
|
13568
13752
|
const contentElement = panel.view.content.element;
|
|
13569
13753
|
if (contentElement.parentElement !== focusContainer) focusContainer.appendChild(contentElement);
|
|
13570
13754
|
if (focusContainer.parentElement !== this.element) this.element.appendChild(focusContainer);
|
|
13571
13755
|
const resize = () => {
|
|
13572
13756
|
const panelId = panel.api.id;
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13757
|
+
const scheduling = this.map[panelId];
|
|
13758
|
+
if ((scheduling === null || scheduling === void 0 ? void 0 : scheduling.generation) !== generation) return;
|
|
13759
|
+
if (scheduling.pendingUpdate !== void 0) return;
|
|
13760
|
+
/**
|
|
13761
|
+
* Claim the slot *before* scheduling. `requestAnimationFrame` is
|
|
13762
|
+
* shimmed to run inline by some hosts (and by several suites here),
|
|
13763
|
+
* in which case the callback below clears `pendingUpdate` while
|
|
13764
|
+
* this call is still on the stack — assigning the handle afterwards
|
|
13765
|
+
* would resurrect a slot that is already spent and block every
|
|
13766
|
+
* later reposition. The sentinel is replaced by the real handle
|
|
13767
|
+
* only if the frame has not already run.
|
|
13768
|
+
*/
|
|
13769
|
+
scheduling.pendingUpdate = SCHEDULED;
|
|
13770
|
+
const handle = requestAnimationFrame(() => {
|
|
13576
13771
|
var _entry$forceVisible;
|
|
13577
|
-
this.pendingUpdates.delete(panelId);
|
|
13578
13772
|
const entry = this.map[panelId];
|
|
13579
|
-
if (
|
|
13773
|
+
if (entry) entry.pendingUpdate = void 0;
|
|
13774
|
+
if (this.isDisposed || (entry === null || entry === void 0 ? void 0 : entry.generation) !== generation) return;
|
|
13580
13775
|
const forceVisible = (_entry$forceVisible = entry.forceVisible) !== null && _entry$forceVisible !== void 0 ? _entry$forceVisible : false;
|
|
13581
13776
|
const clip = entry.clip;
|
|
13582
13777
|
const box = this.positionCache.getPosition(referenceContainer.element);
|
|
@@ -13585,6 +13780,15 @@ var OverlayRenderContainer = class extends CompositeDisposable {
|
|
|
13585
13780
|
const top = box.top - box2.top;
|
|
13586
13781
|
const width = box.width;
|
|
13587
13782
|
const height = box.height;
|
|
13783
|
+
if (entry.retainPreviousGeometry && (width === 0 || height === 0)) {
|
|
13784
|
+
if (!panel.api.isVisible && !forceVisible) {
|
|
13785
|
+
focusContainer.style.visibility = "hidden";
|
|
13786
|
+
focusContainer.style.pointerEvents = "none";
|
|
13787
|
+
}
|
|
13788
|
+
return;
|
|
13789
|
+
}
|
|
13790
|
+
entry.retainPreviousGeometry = false;
|
|
13791
|
+
entry.positioned = true;
|
|
13588
13792
|
focusContainer.style.left = `${left}px`;
|
|
13589
13793
|
focusContainer.style.top = `${top}px`;
|
|
13590
13794
|
focusContainer.style.width = `${width}px`;
|
|
@@ -13613,11 +13817,30 @@ var OverlayRenderContainer = class extends CompositeDisposable {
|
|
|
13613
13817
|
} else focusContainer.style.clipPath = "";
|
|
13614
13818
|
toggleClass(focusContainer, "dv-render-overlay-float", panel.group.api.location.type === "floating");
|
|
13615
13819
|
});
|
|
13820
|
+
if (scheduling.pendingUpdate === SCHEDULED) scheduling.pendingUpdate = handle;
|
|
13616
13821
|
};
|
|
13617
13822
|
const visibilityChanged = () => {
|
|
13618
13823
|
if (panel.api.isVisible) {
|
|
13824
|
+
var _this$map$panel$api$i;
|
|
13619
13825
|
this.positionCache.invalidate();
|
|
13620
13826
|
resize();
|
|
13827
|
+
/**
|
|
13828
|
+
* Existing geometry is safe to show while its replacement lays
|
|
13829
|
+
* out. `retainPreviousGeometry` is only set when geometry has
|
|
13830
|
+
* actually been written (see `attach`), so this can never
|
|
13831
|
+
* un-hide an overlay whose left/top/width/height are unset —
|
|
13832
|
+
* `.dv-render-overlay` is 100%/100% by default and would
|
|
13833
|
+
* otherwise cover the whole dock.
|
|
13834
|
+
*
|
|
13835
|
+
* The retained geometry is the panel's position in the previous
|
|
13836
|
+
* layout, so restoring a layout that moves the panel does paint
|
|
13837
|
+
* it at stale coordinates until the reposition lands. That is
|
|
13838
|
+
* bounded to the next frame now that a superseded `attach` can
|
|
13839
|
+
* no longer swallow the reposition (see `attach`); showing
|
|
13840
|
+
* stale-but-real geometry for a frame is the deliberate
|
|
13841
|
+
* trade-off against blanking the panel for the whole rebuild.
|
|
13842
|
+
*/
|
|
13843
|
+
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 = "";
|
|
13621
13844
|
focusContainer.style.pointerEvents = "";
|
|
13622
13845
|
} else {
|
|
13623
13846
|
focusContainer.style.visibility = "hidden";
|
|
@@ -13840,7 +14063,17 @@ var PopoutWindow = class extends CompositeDisposable {
|
|
|
13840
14063
|
window: externalWindow
|
|
13841
14064
|
});
|
|
13842
14065
|
return new Promise((resolve, reject) => {
|
|
13843
|
-
externalWindow.addEventListener("unload", (
|
|
14066
|
+
externalWindow.addEventListener("unload", () => {});
|
|
14067
|
+
/**
|
|
14068
|
+
* `load` is the only event that resolves this promise with a
|
|
14069
|
+
* container, so a window that goes away first would leave the
|
|
14070
|
+
* caller awaiting a promise that never settles - and
|
|
14071
|
+
* `addPopoutGroup` holds its layout transaction open until it does.
|
|
14072
|
+
* Settle with `null` on close, the same signal a blocked popup
|
|
14073
|
+
* gives and one the caller already handles. `resolve` after the
|
|
14074
|
+
* fact is a no-op, so a `load` that arrived first still wins.
|
|
14075
|
+
*/
|
|
14076
|
+
disposable.addDisposables(_this.onWillClose(() => resolve(null)));
|
|
13844
14077
|
externalWindow.addEventListener("load", () => {
|
|
13845
14078
|
/**
|
|
13846
14079
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
|
|
@@ -15140,7 +15373,22 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15140
15373
|
const rect = candidate.element.getBoundingClientRect();
|
|
15141
15374
|
const dx = rect.left + rect.width / 2 - fromX;
|
|
15142
15375
|
const dy = rect.top + rect.height / 2 - fromY;
|
|
15143
|
-
|
|
15376
|
+
let inDirection;
|
|
15377
|
+
switch (direction) {
|
|
15378
|
+
case "left":
|
|
15379
|
+
inDirection = dx < 0 && Math.abs(dx) >= Math.abs(dy);
|
|
15380
|
+
break;
|
|
15381
|
+
case "right":
|
|
15382
|
+
inDirection = dx > 0 && Math.abs(dx) >= Math.abs(dy);
|
|
15383
|
+
break;
|
|
15384
|
+
case "up":
|
|
15385
|
+
inDirection = dy < 0 && Math.abs(dy) >= Math.abs(dx);
|
|
15386
|
+
break;
|
|
15387
|
+
default:
|
|
15388
|
+
inDirection = dy > 0 && Math.abs(dy) >= Math.abs(dx);
|
|
15389
|
+
break;
|
|
15390
|
+
}
|
|
15391
|
+
if (!inDirection) continue;
|
|
15144
15392
|
const distance = dx * dx + dy * dy;
|
|
15145
15393
|
if (distance < bestDistance) {
|
|
15146
15394
|
bestDistance = distance;
|
|
@@ -15243,6 +15491,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15243
15491
|
this._onWillDrop = new Emitter();
|
|
15244
15492
|
this.onWillDrop = this._onWillDrop.event;
|
|
15245
15493
|
this._mutationDepth = 0;
|
|
15494
|
+
this._pendingLocationChanges = /* @__PURE__ */ new Map();
|
|
15246
15495
|
this._origin = "user";
|
|
15247
15496
|
this._originDepth = 0;
|
|
15248
15497
|
this._onWillMutateLayout = new Emitter();
|
|
@@ -15340,7 +15589,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15340
15589
|
toggleClass(this.element, "dv-debug", !!options.debug);
|
|
15341
15590
|
this.updateTheme();
|
|
15342
15591
|
if (options.debug) this.addDisposables(new StrictEventsSequencing(this));
|
|
15343
|
-
this.addDisposables(this.rootDropTargetContainer, this.floatingDropTargetContainer, addDisposableListener(this._shellManager.element, "dragend", () => {
|
|
15592
|
+
this.addDisposables(Disposable.from(() => this._pendingLocationChanges.clear()), this.rootDropTargetContainer, this.floatingDropTargetContainer, addDisposableListener(this._shellManager.element, "dragend", () => {
|
|
15344
15593
|
var _this$rootDropTargetC2, _this$floatingDropTar;
|
|
15345
15594
|
(_this$rootDropTargetC2 = this.rootDropTargetContainer.model) === null || _this$rootDropTargetC2 === void 0 || _this$rootDropTargetC2.clear();
|
|
15346
15595
|
(_this$floatingDropTar = this.floatingDropTargetContainer.model) === null || _this$floatingDropTar === void 0 || _this$floatingDropTar.clear();
|
|
@@ -15414,7 +15663,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15414
15663
|
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;
|
|
15415
15664
|
}
|
|
15416
15665
|
addPopoutGroup(itemToPopout, options) {
|
|
15417
|
-
return this.
|
|
15666
|
+
return this.mutationAsync("popout", () => this._doAddPopoutGroup(itemToPopout, options));
|
|
15418
15667
|
}
|
|
15419
15668
|
/** Enumerate the popout groups currently open in their own windows. */
|
|
15420
15669
|
getPopouts() {
|
|
@@ -15511,15 +15760,32 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15511
15760
|
}
|
|
15512
15761
|
};
|
|
15513
15762
|
let floatingBox;
|
|
15514
|
-
|
|
15515
|
-
|
|
15516
|
-
|
|
15517
|
-
|
|
15518
|
-
|
|
15763
|
+
/**
|
|
15764
|
+
* Popping out rehomes panels into `group`, so like the floating
|
|
15765
|
+
* case it owes the caller an `onDidMovePanel` per panel. The
|
|
15766
|
+
* events are deferred until the window is wired up so listeners
|
|
15767
|
+
* observe the panels' final `popout` location.
|
|
15768
|
+
*/
|
|
15769
|
+
let movedPanels = [];
|
|
15770
|
+
if (!(options === null || options === void 0 ? void 0 : options.overridePopoutGroup) && !(options === null || options === void 0 ? void 0 : options.overridePopoutGridview) && isGroupAddedToDom) if (itemToPopout instanceof DockviewPanel) {
|
|
15771
|
+
const sourceGroup = itemToPopout.group;
|
|
15772
|
+
this.movingLock(() => {
|
|
15773
|
+
const panel = referenceGroup.model.removePanel(itemToPopout);
|
|
15774
|
+
group.model.openPanel(panel);
|
|
15775
|
+
});
|
|
15776
|
+
movedPanels = [{
|
|
15777
|
+
panel: itemToPopout,
|
|
15778
|
+
from: sourceGroup
|
|
15779
|
+
}];
|
|
15780
|
+
} else {
|
|
15519
15781
|
this.movingLock(() => moveGroupWithoutDestroying({
|
|
15520
15782
|
from: referenceGroup,
|
|
15521
15783
|
to: group
|
|
15522
15784
|
}));
|
|
15785
|
+
movedPanels = group.panels.map((panel) => ({
|
|
15786
|
+
panel,
|
|
15787
|
+
from: referenceGroup
|
|
15788
|
+
}));
|
|
15523
15789
|
switch (referenceLocation) {
|
|
15524
15790
|
case "grid":
|
|
15525
15791
|
referenceGroup.api.setVisible(false);
|
|
@@ -15628,6 +15894,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15628
15894
|
group: value.popoutGroup,
|
|
15629
15895
|
window: value.getWindow()
|
|
15630
15896
|
});
|
|
15897
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15631
15898
|
return true;
|
|
15632
15899
|
}).catch((err) => {
|
|
15633
15900
|
console.error("dockview: failed to create popout.", err);
|
|
@@ -15705,6 +15972,16 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15705
15972
|
const members = this.groups.filter((candidate) => popoutGridview.element.contains(candidate.element));
|
|
15706
15973
|
const anchorPresent = members.includes(group);
|
|
15707
15974
|
const anchorIsSoleMember = anchorPresent && members.length === 1;
|
|
15975
|
+
/**
|
|
15976
|
+
* Popping a group out fires `onDidMovePanel` per panel, so closing the
|
|
15977
|
+
* window owes the caller the same: every panel in it is rehomed, into
|
|
15978
|
+
* the reference group the popout left behind or into a fresh grid slot.
|
|
15979
|
+
* `movingLock` suppresses onDidAddPanel / onDidRemovePanel on these
|
|
15980
|
+
* paths, so `onDidMovePanel` is the only event that can carry it. The
|
|
15981
|
+
* events are deferred to the end so listeners observe the panels at
|
|
15982
|
+
* their final group and location.
|
|
15983
|
+
*/
|
|
15984
|
+
const movedPanels = [];
|
|
15708
15985
|
if (genuineClose) for (const member of members) {
|
|
15709
15986
|
if (member === group) continue;
|
|
15710
15987
|
this.movingLock(() => {
|
|
@@ -15715,12 +15992,21 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15715
15992
|
});
|
|
15716
15993
|
this.redockGroupToMainGrid(member);
|
|
15717
15994
|
});
|
|
15995
|
+
for (const panel of member.panels) movedPanels.push({
|
|
15996
|
+
panel,
|
|
15997
|
+
from: member
|
|
15998
|
+
});
|
|
15718
15999
|
}
|
|
15719
16000
|
if (anchorPresent && isGroupAddedToDom && this.getPanel(referenceGroup.id)) {
|
|
16001
|
+
const rehomed = [...group.panels];
|
|
15720
16002
|
this.movingLock(() => moveGroupWithoutDestroying({
|
|
15721
16003
|
from: group,
|
|
15722
16004
|
to: referenceGroup
|
|
15723
16005
|
}));
|
|
16006
|
+
for (const panel of rehomed) movedPanels.push({
|
|
16007
|
+
panel,
|
|
16008
|
+
from: group
|
|
16009
|
+
});
|
|
15724
16010
|
if (!referenceGroup.api.isVisible) referenceGroup.api.setVisible(true);
|
|
15725
16011
|
if (this.getPanel(group.id)) this.doRemoveGroup(group, { skipPopoutAssociated: true });
|
|
15726
16012
|
} else if (anchorPresent && this.getPanel(group.id)) {
|
|
@@ -15751,10 +16037,15 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15751
16037
|
this.movingLock(() => {
|
|
15752
16038
|
this.doAddGroup(group, [0]);
|
|
15753
16039
|
});
|
|
16040
|
+
for (const panel of group.panels) movedPanels.push({
|
|
16041
|
+
panel,
|
|
16042
|
+
from: group
|
|
16043
|
+
});
|
|
15754
16044
|
}
|
|
15755
16045
|
this.doSetGroupAndPanelActive(group);
|
|
15756
16046
|
}
|
|
15757
16047
|
disposePopoutGridview();
|
|
16048
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15758
16049
|
}
|
|
15759
16050
|
addFloatingGroup(item, options) {
|
|
15760
16051
|
this.mutation("float", () => this._doAddFloatingGroup(item, options));
|
|
@@ -15763,7 +16054,15 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15763
16054
|
if (!assertModule(this._floatingGroupService, "FloatingGroup", "api.addFloatingGroup")) return;
|
|
15764
16055
|
if (item instanceof DockviewGroupPanel && item.model.location.type === "edge") return;
|
|
15765
16056
|
let group;
|
|
16057
|
+
/**
|
|
16058
|
+
* Floating relocates panels exactly like a drop onto the grid does, so
|
|
16059
|
+
* it owes the caller an `onDidMovePanel` per panel. The events are
|
|
16060
|
+
* deferred until the window is mounted below: only then do the panels
|
|
16061
|
+
* report their final `floating` location.
|
|
16062
|
+
*/
|
|
16063
|
+
let movedPanels = [];
|
|
15766
16064
|
if (item instanceof DockviewPanel) {
|
|
16065
|
+
const sourceGroup = item.group;
|
|
15767
16066
|
group = this.createGroup();
|
|
15768
16067
|
this._onDidAddGroup.fire(group);
|
|
15769
16068
|
this.movingLock(() => this.removePanel(item, {
|
|
@@ -15772,6 +16071,10 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15772
16071
|
skipSetActiveGroup: true
|
|
15773
16072
|
}));
|
|
15774
16073
|
this.movingLock(() => group.model.openPanel(item, { skipSetGroupActive: true }));
|
|
16074
|
+
movedPanels = [{
|
|
16075
|
+
panel: item,
|
|
16076
|
+
from: sourceGroup
|
|
16077
|
+
}];
|
|
15775
16078
|
} else {
|
|
15776
16079
|
var _this$_popoutWindowSe8;
|
|
15777
16080
|
group = item;
|
|
@@ -15788,11 +16091,21 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15788
16091
|
});
|
|
15789
16092
|
this.doRemoveGroup(popoutReferenceGroup, { skipDispose: true });
|
|
15790
16093
|
group = popoutReferenceGroup;
|
|
15791
|
-
|
|
15792
|
-
|
|
15793
|
-
|
|
15794
|
-
|
|
15795
|
-
}
|
|
16094
|
+
movedPanels = group.panels.map((panel) => ({
|
|
16095
|
+
panel,
|
|
16096
|
+
from: item
|
|
16097
|
+
}));
|
|
16098
|
+
} else {
|
|
16099
|
+
this.doRemoveGroup(item, {
|
|
16100
|
+
skipDispose: true,
|
|
16101
|
+
skipPopoutReturn: true,
|
|
16102
|
+
skipPopoutAssociated: false
|
|
16103
|
+
});
|
|
16104
|
+
movedPanels = group.panels.map((panel) => ({
|
|
16105
|
+
panel,
|
|
16106
|
+
from: group
|
|
16107
|
+
}));
|
|
16108
|
+
}
|
|
15796
16109
|
}
|
|
15797
16110
|
function getAnchoredBox() {
|
|
15798
16111
|
if (options === null || options === void 0 ? void 0 : options.position) {
|
|
@@ -15825,6 +16138,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15825
16138
|
skipActiveGroup: options === null || options === void 0 ? void 0 : options.skipActiveGroup,
|
|
15826
16139
|
disableSmartGuides: options === null || options === void 0 ? void 0 : options.disableSmartGuides
|
|
15827
16140
|
});
|
|
16141
|
+
for (const { panel, from } of movedPanels) this.fireDidMovePanel(panel, from);
|
|
15828
16142
|
}
|
|
15829
16143
|
/**
|
|
15830
16144
|
* Build an empty gridview configured to match the main grid's styling, for
|
|
@@ -15988,11 +16302,15 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
15988
16302
|
/**
|
|
15989
16303
|
* Reveal (create-or-fill) the edge group at `position` and move the dragged
|
|
15990
16304
|
* item described by `data` into it. A newly created edge group is created
|
|
15991
|
-
* collapsed
|
|
15992
|
-
* later emptied
|
|
15993
|
-
*
|
|
15994
|
-
*
|
|
15995
|
-
*
|
|
16305
|
+
* collapsed, flagged `autoReveal` so it tears down to zero footprint when
|
|
16306
|
+
* later emptied, and takes its auto-hide state from `options.autoHide`. If an
|
|
16307
|
+
* edge group already exists there it is reused: the panel is added to its
|
|
16308
|
+
* tabs and its collapsed/toggled *and auto-hide* state are left as-is (never
|
|
16309
|
+
* re-created; `addEdgeGroup` throws on a duplicate position). This keeps a
|
|
16310
|
+
* drag-reveal from silently converting a static edge group into an
|
|
16311
|
+
* auto-hiding one; to change an existing group's auto-hide, call
|
|
16312
|
+
* `api.getEdgeGroup(position)?.setAutoHide(...)` directly. No-op if the
|
|
16313
|
+
* EdgeGroup module is absent.
|
|
15996
16314
|
*
|
|
15997
16315
|
* This is the primitive behind the dock-to-edge groups: the two-band
|
|
15998
16316
|
* drag-reveal affordance routes its outer-band drops here.
|
|
@@ -16011,7 +16329,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16011
16329
|
collapsed: true
|
|
16012
16330
|
});
|
|
16013
16331
|
group = service.get(position);
|
|
16014
|
-
}
|
|
16332
|
+
}
|
|
16015
16333
|
if (!group) return;
|
|
16016
16334
|
this.moveGroupOrPanel({
|
|
16017
16335
|
from: {
|
|
@@ -16252,35 +16570,119 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16252
16570
|
if (typeof data !== "object" || data === null) throw new Error("dockview: serialized layout must be a non-null object");
|
|
16253
16571
|
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");
|
|
16254
16572
|
const existingPanels = /* @__PURE__ */ new Map();
|
|
16255
|
-
|
|
16573
|
+
const temporaryGroups = /* @__PURE__ */ new Map();
|
|
16574
|
+
const stagedPanels = [];
|
|
16575
|
+
const temporaryGroupDisposables = [];
|
|
16576
|
+
/**
|
|
16577
|
+
* The staging groups are detached from `_groups` and never enter the
|
|
16578
|
+
* grid, so nothing else will ever tear them down.
|
|
16579
|
+
*
|
|
16580
|
+
* `dispose()` reaches consumer `IContentRenderer.dispose()`, so one
|
|
16581
|
+
* throwing renderer must not abort the rest of the cleanup — that would
|
|
16582
|
+
* re-introduce the very leak this reclaims — nor replace the
|
|
16583
|
+
* deserialization error the caller is being given. Draining the list
|
|
16584
|
+
* also makes this safe to call more than once.
|
|
16585
|
+
*/
|
|
16586
|
+
const disposeTemporaryGroups = () => {
|
|
16587
|
+
for (const disposable of temporaryGroupDisposables) try {
|
|
16588
|
+
disposable.dispose();
|
|
16589
|
+
} catch (err) {
|
|
16590
|
+
console.error("dockview: failed to dispose a temporary group created for reuseExistingPanels", err);
|
|
16591
|
+
}
|
|
16592
|
+
temporaryGroupDisposables.length = 0;
|
|
16593
|
+
};
|
|
16256
16594
|
if (options === null || options === void 0 ? void 0 : options.reuseExistingPanels) {
|
|
16257
16595
|
/**
|
|
16258
|
-
*
|
|
16259
|
-
*
|
|
16260
|
-
*
|
|
16261
|
-
* 2. Remove that temporary group from the group mapping so that it doesn't get cleared when we clear the layout
|
|
16596
|
+
* Visible, always-rendered panels need individual staging groups
|
|
16597
|
+
* to remain active. Other reused panels can share a staging group.
|
|
16598
|
+
* The staging groups are excluded from the layout clear below.
|
|
16262
16599
|
*/
|
|
16263
|
-
tempGroup = this.createGroup();
|
|
16264
|
-
this._groups.delete(tempGroup.api.id);
|
|
16265
16600
|
const newPanels = Object.keys(data.panels);
|
|
16266
|
-
|
|
16267
|
-
|
|
16268
|
-
|
|
16269
|
-
|
|
16270
|
-
|
|
16271
|
-
|
|
16272
|
-
|
|
16273
|
-
|
|
16274
|
-
|
|
16275
|
-
|
|
16276
|
-
|
|
16277
|
-
|
|
16278
|
-
|
|
16601
|
+
let sharedTemporaryGroup;
|
|
16602
|
+
const createTemporaryGroup = () => {
|
|
16603
|
+
const temporaryGroup = this.createGroup();
|
|
16604
|
+
/**
|
|
16605
|
+
* Removing the group from `_groups` also drops the record's
|
|
16606
|
+
* `CompositeDisposable`, so capture it first and tear both it
|
|
16607
|
+
* and the group down in the `finally` below. Left undisposed a
|
|
16608
|
+
* staging group leaks its `ResizeObserver`, its
|
|
16609
|
+
* `onDidOptionsChange` subscription (retained by this
|
|
16610
|
+
* component's emitter) and the watermark its model mounts when
|
|
16611
|
+
* the group empties — once per reused panel, per `fromJSON`.
|
|
16612
|
+
*/
|
|
16613
|
+
const record = this._groups.get(temporaryGroup.api.id);
|
|
16614
|
+
this._groups.delete(temporaryGroup.api.id);
|
|
16615
|
+
temporaryGroupDisposables.push(Disposable.from(() => {
|
|
16616
|
+
/**
|
|
16617
|
+
* Reclaim the group's own resources, never its panels.
|
|
16618
|
+
* Staging is driven by the ids in `data.panels` while
|
|
16619
|
+
* reclaiming is driven by the group `views` that
|
|
16620
|
+
* reference them, so a panel whose state is present but
|
|
16621
|
+
* unreferenced is still staged here — and `dispose()`
|
|
16622
|
+
* on a non-empty group reaches the consumer's
|
|
16623
|
+
* `IContentRenderer.dispose()`. Emptying the group
|
|
16624
|
+
* first leaves those panels exactly as they were before
|
|
16625
|
+
* this teardown existed, which also keeps this safe
|
|
16626
|
+
* against any future path that rebuilds a panel under
|
|
16627
|
+
* an id that is live in the new layout.
|
|
16628
|
+
*/
|
|
16629
|
+
this.movingLock(() => {
|
|
16630
|
+
for (const panel of temporaryGroup.panels.slice()) temporaryGroup.model.removePanel(panel);
|
|
16631
|
+
});
|
|
16632
|
+
record === null || record === void 0 || record.disposable.dispose();
|
|
16633
|
+
temporaryGroup.dispose();
|
|
16634
|
+
}));
|
|
16635
|
+
return temporaryGroup;
|
|
16636
|
+
};
|
|
16637
|
+
/**
|
|
16638
|
+
* Staging and the clear below run before the deserialization
|
|
16639
|
+
* `try`, so a throw here (a consumer `onDidRemovePanel` handler, a
|
|
16640
|
+
* renderer teardown during `clear`) would escape without reclaiming
|
|
16641
|
+
* the staging groups already created.
|
|
16642
|
+
*
|
|
16643
|
+
* The creation loop is inside the guard too, not just the moves and
|
|
16644
|
+
* the clear: `createGroup()` reaches consumer code of its own —
|
|
16645
|
+
* `initialize()` mounts the watermark through
|
|
16646
|
+
* `createWatermarkComponent()` — so a throw on the n-th panel would
|
|
16647
|
+
* otherwise strand the n-1 staging groups already built.
|
|
16648
|
+
*/
|
|
16649
|
+
try {
|
|
16650
|
+
for (const panel of this.panels) if (newPanels.includes(panel.api.id)) {
|
|
16651
|
+
existingPanels.set(panel.api.id, panel);
|
|
16652
|
+
let temporaryGroup;
|
|
16653
|
+
if (panel.api.renderer === "always" && panel.api.isVisible) temporaryGroup = createTemporaryGroup();
|
|
16654
|
+
else {
|
|
16655
|
+
var _sharedTemporaryGroup;
|
|
16656
|
+
(_sharedTemporaryGroup = sharedTemporaryGroup) !== null && _sharedTemporaryGroup !== void 0 || (sharedTemporaryGroup = createTemporaryGroup());
|
|
16657
|
+
temporaryGroup = sharedTemporaryGroup;
|
|
16658
|
+
}
|
|
16659
|
+
temporaryGroups.set(panel.api.id, temporaryGroup);
|
|
16660
|
+
stagedPanels.push({
|
|
16661
|
+
panel,
|
|
16662
|
+
temporaryGroup
|
|
16663
|
+
});
|
|
16664
|
+
}
|
|
16665
|
+
this.movingLock(() => {
|
|
16666
|
+
stagedPanels.forEach(({ panel, temporaryGroup }) => {
|
|
16667
|
+
this.moveGroupOrPanel({
|
|
16668
|
+
from: {
|
|
16669
|
+
groupId: panel.api.group.api.id,
|
|
16670
|
+
panelId: panel.api.id
|
|
16671
|
+
},
|
|
16672
|
+
to: {
|
|
16673
|
+
group: temporaryGroup,
|
|
16674
|
+
position: "center"
|
|
16675
|
+
},
|
|
16676
|
+
keepEmptyGroups: true
|
|
16677
|
+
});
|
|
16279
16678
|
});
|
|
16280
16679
|
});
|
|
16281
|
-
|
|
16282
|
-
|
|
16283
|
-
|
|
16680
|
+
this.clear();
|
|
16681
|
+
} catch (err) {
|
|
16682
|
+
disposeTemporaryGroups();
|
|
16683
|
+
throw err;
|
|
16684
|
+
}
|
|
16685
|
+
} else this.clear();
|
|
16284
16686
|
const { grid, panels, activeGroup } = data;
|
|
16285
16687
|
try {
|
|
16286
16688
|
var _data$floatingGroups, _data$popoutGroups, _this$_popoutWindowSe12, _this$_floatingGroupS5, _this$_watermarkServi2;
|
|
@@ -16312,9 +16714,10 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16312
16714
|
* due to a corruption of input data.
|
|
16313
16715
|
*/
|
|
16314
16716
|
const existingPanel = existingPanels.get(child);
|
|
16315
|
-
|
|
16717
|
+
const temporaryGroup = temporaryGroups.get(child);
|
|
16718
|
+
if (temporaryGroup && existingPanel) {
|
|
16316
16719
|
this.movingLock(() => {
|
|
16317
|
-
|
|
16720
|
+
temporaryGroup.model.removePanel(existingPanel);
|
|
16318
16721
|
});
|
|
16319
16722
|
createdPanels.push(existingPanel);
|
|
16320
16723
|
existingPanel.updateFromStateModel(panels[child]);
|
|
@@ -16344,7 +16747,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16344
16747
|
return createGroupFromSerializedState(node.data);
|
|
16345
16748
|
} });
|
|
16346
16749
|
this._layoutFromShell(width, height);
|
|
16347
|
-
if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels);
|
|
16750
|
+
if (data.edgeGroups) this.deserializeEdgeGroups(data.edgeGroups, panels, existingPanels, temporaryGroups);
|
|
16348
16751
|
this.deserializeFloatingWindows((_data$floatingGroups = data.floatingGroups) !== null && _data$floatingGroups !== void 0 ? _data$floatingGroups : [], createGroupFromSerializedState);
|
|
16349
16752
|
const popoutPromises = this.deserializePopoutWindows((_data$popoutGroups = data.popoutGroups) !== null && _data$popoutGroups !== void 0 ? _data$popoutGroups : [], createGroupFromSerializedState);
|
|
16350
16753
|
(_this$_popoutWindowSe12 = this._popoutWindowService) === null || _this$_popoutWindowSe12 === void 0 || _this$_popoutWindowSe12.finishRestoration(popoutPromises);
|
|
@@ -16381,6 +16784,8 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16381
16784
|
* expect trying to load a corrupted layout to result in an error and not silently fail...
|
|
16382
16785
|
*/
|
|
16383
16786
|
throw err;
|
|
16787
|
+
} finally {
|
|
16788
|
+
disposeTemporaryGroups();
|
|
16384
16789
|
}
|
|
16385
16790
|
this.debouncedUpdateAllPositions();
|
|
16386
16791
|
this._onDidLayoutFromJSON.fire();
|
|
@@ -16403,7 +16808,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16403
16808
|
members
|
|
16404
16809
|
};
|
|
16405
16810
|
}
|
|
16406
|
-
deserializeEdgeGroups(edgeGroups, panels) {
|
|
16811
|
+
deserializeEdgeGroups(edgeGroups, panels, existingPanels, temporaryGroups) {
|
|
16407
16812
|
const edgeService = assertModule(this._edgeGroupService, "EdgeGroup", "fromJSON edge restoration");
|
|
16408
16813
|
if (!edgeService) return;
|
|
16409
16814
|
for (const _position of [
|
|
@@ -16433,13 +16838,40 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16433
16838
|
if (groupState) {
|
|
16434
16839
|
const { views, activeView } = groupState;
|
|
16435
16840
|
const createdPanels = [];
|
|
16436
|
-
for (const panelId of views)
|
|
16437
|
-
|
|
16438
|
-
|
|
16841
|
+
for (const panelId of views) {
|
|
16842
|
+
if (!panels[panelId]) continue;
|
|
16843
|
+
/**
|
|
16844
|
+
* Reclaim a staged panel rather than rebuilding it, the
|
|
16845
|
+
* same way the grid path does. Deserializing here instead
|
|
16846
|
+
* would honour `reuseExistingPanels` everywhere except edge
|
|
16847
|
+
* groups: the live panel keeps sitting in its staging group
|
|
16848
|
+
* while a second panel is built under the same id, so the
|
|
16849
|
+
* consumer's renderer for the original is orphaned — never
|
|
16850
|
+
* disposed, and its element left inside the id-keyed
|
|
16851
|
+
* overlay entry the replacement now shares.
|
|
16852
|
+
*/
|
|
16853
|
+
const existingPanel = existingPanels.get(panelId);
|
|
16854
|
+
const temporaryGroup = temporaryGroups.get(panelId);
|
|
16855
|
+
if (temporaryGroup && existingPanel) {
|
|
16856
|
+
this.movingLock(() => {
|
|
16857
|
+
temporaryGroup.model.removePanel(existingPanel);
|
|
16858
|
+
});
|
|
16859
|
+
createdPanels.push(existingPanel);
|
|
16860
|
+
existingPanel.updateFromStateModel(panels[panelId]);
|
|
16861
|
+
} else {
|
|
16862
|
+
const panel = this._deserializer.fromJSON(panels[panelId], edgeGroup);
|
|
16863
|
+
createdPanels.push(panel);
|
|
16864
|
+
}
|
|
16439
16865
|
}
|
|
16440
16866
|
for (const panel of createdPanels) {
|
|
16441
16867
|
const isActive = activeView === panel.id;
|
|
16442
|
-
|
|
16868
|
+
if (existingPanels.has(panel.api.id)) this.movingLock(() => {
|
|
16869
|
+
edgeGroup.model.openPanel(panel, {
|
|
16870
|
+
skipSetActive: !isActive,
|
|
16871
|
+
skipSetGroupActive: true
|
|
16872
|
+
});
|
|
16873
|
+
});
|
|
16874
|
+
else edgeGroup.model.openPanel(panel, {
|
|
16443
16875
|
skipSetActive: !isActive,
|
|
16444
16876
|
skipSetGroupActive: true
|
|
16445
16877
|
});
|
|
@@ -16542,6 +16974,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16542
16974
|
height: options.initialHeight
|
|
16543
16975
|
};
|
|
16544
16976
|
let index;
|
|
16977
|
+
const shouldSkipSetActive = (group) => !!options.inactive && group.model.size > 0;
|
|
16545
16978
|
if (options.position) if (isPanelOptionsWithPanel(options.position)) {
|
|
16546
16979
|
const referencePanel = typeof options.position.referencePanel === "string" ? this.getGroupPanel(options.position.referencePanel) : options.position.referencePanel;
|
|
16547
16980
|
index = options.position.index;
|
|
@@ -16564,7 +16997,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16564
16997
|
const group = this.orthogonalize(directionToPosition(options.position.direction));
|
|
16565
16998
|
const panel = this.createPanel(options, group);
|
|
16566
16999
|
group.model.openPanel(panel, {
|
|
16567
|
-
skipSetActive:
|
|
17000
|
+
skipSetActive: shouldSkipSetActive(group),
|
|
16568
17001
|
skipSetGroupActive: options.inactive,
|
|
16569
17002
|
index
|
|
16570
17003
|
});
|
|
@@ -16591,14 +17024,14 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16591
17024
|
}));
|
|
16592
17025
|
panel = this.createPanel(options, group);
|
|
16593
17026
|
group.model.openPanel(panel, {
|
|
16594
|
-
skipSetActive:
|
|
17027
|
+
skipSetActive: shouldSkipSetActive(group),
|
|
16595
17028
|
skipSetGroupActive: options.inactive,
|
|
16596
17029
|
index
|
|
16597
17030
|
});
|
|
16598
17031
|
} else if (referenceGroup.api.location.type === "floating" || referenceGroup.api.location.type === "edge" || target === "center") {
|
|
16599
17032
|
panel = this.createPanel(options, referenceGroup);
|
|
16600
17033
|
referenceGroup.model.openPanel(panel, {
|
|
16601
|
-
skipSetActive:
|
|
17034
|
+
skipSetActive: shouldSkipSetActive(referenceGroup),
|
|
16602
17035
|
skipSetGroupActive: options.inactive,
|
|
16603
17036
|
index
|
|
16604
17037
|
});
|
|
@@ -16613,7 +17046,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16613
17046
|
const group = this.createGroupAtLocation(relativeLocation, this.orientationAtLocation(relativeLocation) === "VERTICAL" ? initial === null || initial === void 0 ? void 0 : initial.height : initial === null || initial === void 0 ? void 0 : initial.width);
|
|
16614
17047
|
panel = this.createPanel(options, group);
|
|
16615
17048
|
group.model.openPanel(panel, {
|
|
16616
|
-
skipSetActive:
|
|
17049
|
+
skipSetActive: shouldSkipSetActive(group),
|
|
16617
17050
|
skipSetGroupActive: options.inactive,
|
|
16618
17051
|
index
|
|
16619
17052
|
});
|
|
@@ -16630,7 +17063,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16630
17063
|
}));
|
|
16631
17064
|
panel = this.createPanel(options, group);
|
|
16632
17065
|
group.model.openPanel(panel, {
|
|
16633
|
-
skipSetActive:
|
|
17066
|
+
skipSetActive: shouldSkipSetActive(group),
|
|
16634
17067
|
skipSetGroupActive: options.inactive,
|
|
16635
17068
|
index
|
|
16636
17069
|
});
|
|
@@ -16638,7 +17071,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16638
17071
|
const group = this.createGroupAtLocation([0], this.gridview.orientation === "VERTICAL" ? initial === null || initial === void 0 ? void 0 : initial.height : initial === null || initial === void 0 ? void 0 : initial.width);
|
|
16639
17072
|
panel = this.createPanel(options, group);
|
|
16640
17073
|
group.model.openPanel(panel, {
|
|
16641
|
-
skipSetActive:
|
|
17074
|
+
skipSetActive: shouldSkipSetActive(group),
|
|
16642
17075
|
skipSetGroupActive: options.inactive,
|
|
16643
17076
|
index
|
|
16644
17077
|
});
|
|
@@ -16862,22 +17295,100 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16862
17295
|
* outermost mutation.
|
|
16863
17296
|
*/
|
|
16864
17297
|
mutation(kind, func) {
|
|
16865
|
-
const
|
|
17298
|
+
const close = this.openMutation(kind);
|
|
17299
|
+
try {
|
|
17300
|
+
return func();
|
|
17301
|
+
} finally {
|
|
17302
|
+
close();
|
|
17303
|
+
}
|
|
17304
|
+
}
|
|
17305
|
+
/**
|
|
17306
|
+
* `mutation()` for an operation whose work continues after the synchronous
|
|
17307
|
+
* call returns. The transaction stays open until the returned promise
|
|
17308
|
+
* settles, so everything the operation does - the group it adds, the panels
|
|
17309
|
+
* it relocates - lands inside the bracket, matching the synchronous
|
|
17310
|
+
* move / float paths.
|
|
17311
|
+
*/
|
|
17312
|
+
mutationAsync(kind, func) {
|
|
17313
|
+
var _this = this;
|
|
17314
|
+
return _asyncToGenerator(function* () {
|
|
17315
|
+
const close = _this.openMutation(kind);
|
|
17316
|
+
try {
|
|
17317
|
+
return yield func();
|
|
17318
|
+
} finally {
|
|
17319
|
+
close();
|
|
17320
|
+
}
|
|
17321
|
+
})();
|
|
17322
|
+
}
|
|
17323
|
+
/**
|
|
17324
|
+
* Open a transaction and return the function that closes it. Shared by the
|
|
17325
|
+
* synchronous and asynchronous brackets; the returned function must be
|
|
17326
|
+
* called exactly once.
|
|
17327
|
+
*
|
|
17328
|
+
* Both ends key off the depth counter reaching zero rather than off which
|
|
17329
|
+
* bracket opened first. For synchronous nesting the two are the same thing
|
|
17330
|
+
* - brackets close in the order they opened - but asynchronous transactions
|
|
17331
|
+
* can *overlap* rather than nest (two `addPopoutGroup` calls in flight at
|
|
17332
|
+
* once, or a restore staggering several), and there the first to open is
|
|
17333
|
+
* not the last to close. Reporting on the opener would fire `didMutate`
|
|
17334
|
+
* while the other transaction was still doing structural work, which is the
|
|
17335
|
+
* very thing the async bracket exists to prevent. Overlapping transactions
|
|
17336
|
+
* therefore report as one, tagged with the kind of the last to finish.
|
|
17337
|
+
*/
|
|
17338
|
+
openMutation(kind) {
|
|
16866
17339
|
const origin = this._origin;
|
|
16867
|
-
if (
|
|
17340
|
+
if (this._mutationDepth === 0) this._onWillMutateLayout.fire({
|
|
16868
17341
|
kind,
|
|
16869
17342
|
origin
|
|
16870
17343
|
});
|
|
16871
17344
|
this._mutationDepth++;
|
|
16872
|
-
|
|
16873
|
-
return func();
|
|
16874
|
-
} finally {
|
|
17345
|
+
return () => {
|
|
16875
17346
|
this._mutationDepth--;
|
|
16876
|
-
if (
|
|
16877
|
-
|
|
16878
|
-
|
|
16879
|
-
|
|
17347
|
+
if (this._mutationDepth === 0) {
|
|
17348
|
+
this.flushLocationChanges();
|
|
17349
|
+
this._onDidMutateLayout.fire({
|
|
17350
|
+
kind,
|
|
17351
|
+
origin
|
|
17352
|
+
});
|
|
17353
|
+
}
|
|
17354
|
+
};
|
|
17355
|
+
}
|
|
17356
|
+
/**
|
|
17357
|
+
* Coalesce a panel's `onDidLocationChange` to the end of the enclosing
|
|
17358
|
+
* transaction, or fire it immediately when no transaction is in flight.
|
|
17359
|
+
*
|
|
17360
|
+
* Relocating a panel touches its location twice: once as it is reparented
|
|
17361
|
+
* into the destination group - which, when that group has just been created
|
|
17362
|
+
* for a floating or popout window, has not been told where it lives yet -
|
|
17363
|
+
* and once as the group is tagged with its final location. Reporting each
|
|
17364
|
+
* signal as it happens therefore leaks an intermediate `grid` location the
|
|
17365
|
+
* panel was never in, at a moment when it belongs to neither group's panel
|
|
17366
|
+
* list and so is missing from `api.panels`.
|
|
17367
|
+
*
|
|
17368
|
+
* Deferring collapses those signals into a single event carrying the
|
|
17369
|
+
* settled location. Note the signals are deliberately *not* compared
|
|
17370
|
+
* against the panel's previous location: a panel can move between two
|
|
17371
|
+
* floating windows without its location type changing, and this event is
|
|
17372
|
+
* the only signal `OverlayRenderContainer` has to re-resolve the panel's
|
|
17373
|
+
* z-index against its new host window.
|
|
17374
|
+
*/
|
|
17375
|
+
deferLocationChange(key, fire) {
|
|
17376
|
+
if (this._mutationDepth === 0) {
|
|
17377
|
+
fire();
|
|
17378
|
+
return;
|
|
16880
17379
|
}
|
|
17380
|
+
this._pendingLocationChanges.set(key, fire);
|
|
17381
|
+
}
|
|
17382
|
+
/**
|
|
17383
|
+
* Report every panel whose location moved during the transaction that has
|
|
17384
|
+
* just closed. Each callback reads the panel's location at this point, so
|
|
17385
|
+
* what it reports is where the panel ended up.
|
|
17386
|
+
*/
|
|
17387
|
+
flushLocationChanges() {
|
|
17388
|
+
if (this._pendingLocationChanges.size === 0) return;
|
|
17389
|
+
const pending = Array.from(this._pendingLocationChanges.values());
|
|
17390
|
+
this._pendingLocationChanges.clear();
|
|
17391
|
+
for (const fire of pending) fire();
|
|
16881
17392
|
}
|
|
16882
17393
|
/**
|
|
16883
17394
|
* The origin of the operation currently in progress (`'user'` by default).
|
|
@@ -16918,6 +17429,18 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16918
17429
|
origin: this._origin
|
|
16919
17430
|
});
|
|
16920
17431
|
}
|
|
17432
|
+
/**
|
|
17433
|
+
* Announce that `panel` has finished relocating. Must be called once the
|
|
17434
|
+
* move has settled: `to` is read from the panel's current group, so an
|
|
17435
|
+
* early call would report the source group as the destination.
|
|
17436
|
+
*/
|
|
17437
|
+
fireDidMovePanel(panel, from) {
|
|
17438
|
+
this._onDidMovePanel.fire({
|
|
17439
|
+
panel,
|
|
17440
|
+
from,
|
|
17441
|
+
to: panel.group
|
|
17442
|
+
});
|
|
17443
|
+
}
|
|
16921
17444
|
moveGroupOrPanel(options) {
|
|
16922
17445
|
this.mutation("move", () => this._doMoveGroupOrPanel(options));
|
|
16923
17446
|
}
|
|
@@ -16978,10 +17501,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
16978
17501
|
});
|
|
16979
17502
|
});
|
|
16980
17503
|
if (!options.skipSetActive) this.doSetGroupAndPanelActive(destinationGroup);
|
|
16981
|
-
this.
|
|
16982
|
-
panel: removedPanel,
|
|
16983
|
-
from: sourceGroup
|
|
16984
|
-
});
|
|
17504
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
16985
17505
|
} else {
|
|
16986
17506
|
/**
|
|
16987
17507
|
* Dropping a panel to the extremities of a group which will place that panel
|
|
@@ -17000,10 +17520,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17000
17520
|
const [sourceParentLocation, from] = tail(getGridLocation(sourceGroup.element));
|
|
17001
17521
|
if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
|
|
17002
17522
|
this.gridview.moveView(sourceParentLocation, from, to);
|
|
17003
|
-
this.
|
|
17004
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
17005
|
-
from: sourceGroup
|
|
17006
|
-
});
|
|
17523
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
17007
17524
|
return;
|
|
17008
17525
|
}
|
|
17009
17526
|
}
|
|
@@ -17034,10 +17551,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17034
17551
|
const newGroup = this.createGroupAtLocation(updatedTargetLocation, void 0, void 0, destinationGridview);
|
|
17035
17552
|
this.movingLock(() => newGroup.model.openPanel(removedPanel, { skipSetActive: true }));
|
|
17036
17553
|
this.doSetGroupAndPanelActive(newGroup);
|
|
17037
|
-
this.
|
|
17038
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
17039
|
-
from: sourceGroup
|
|
17040
|
-
});
|
|
17554
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
17041
17555
|
return;
|
|
17042
17556
|
}
|
|
17043
17557
|
if (sourceGroup.api.location.type === "edge") {
|
|
@@ -17054,10 +17568,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17054
17568
|
const newGroup = this.createGroupAtLocation(targetLocation, void 0, void 0, destinationGridview);
|
|
17055
17569
|
this.movingLock(() => newGroup.model.openPanel(removedPanel, { skipSetGroupActive: true }));
|
|
17056
17570
|
this.doSetGroupAndPanelActive(newGroup);
|
|
17057
|
-
this.
|
|
17058
|
-
panel: removedPanel,
|
|
17059
|
-
from: sourceGroup
|
|
17060
|
-
});
|
|
17571
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
17061
17572
|
return;
|
|
17062
17573
|
}
|
|
17063
17574
|
const targetGroup = this.movingLock(() => this.doRemoveGroup(sourceGroup, {
|
|
@@ -17069,10 +17580,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17069
17580
|
this.movingLock(() => this.doAddGroup(targetGroup, location, void 0, destinationGridview));
|
|
17070
17581
|
this.setGroupLocationForRoot(targetGroup, destinationGridview);
|
|
17071
17582
|
this.doSetGroupAndPanelActive(targetGroup);
|
|
17072
|
-
this.
|
|
17073
|
-
panel: this.getGroupPanel(sourceItemId),
|
|
17074
|
-
from: sourceGroup
|
|
17075
|
-
});
|
|
17583
|
+
this.fireDidMovePanel(this.getGroupPanel(sourceItemId), sourceGroup);
|
|
17076
17584
|
} else {
|
|
17077
17585
|
/**
|
|
17078
17586
|
* The group we are removing from has many panels, we need to remove the panels we are moving,
|
|
@@ -17087,10 +17595,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17087
17595
|
const group = this.createGroupAtLocation(dropLocation, void 0, void 0, destinationGridview);
|
|
17088
17596
|
this.movingLock(() => group.model.openPanel(removedPanel, { skipSetGroupActive: true }));
|
|
17089
17597
|
this.doSetGroupAndPanelActive(group);
|
|
17090
|
-
this.
|
|
17091
|
-
panel: removedPanel,
|
|
17092
|
-
from: sourceGroup
|
|
17093
|
-
});
|
|
17598
|
+
this.fireDidMovePanel(removedPanel, sourceGroup);
|
|
17094
17599
|
}
|
|
17095
17600
|
}
|
|
17096
17601
|
}
|
|
@@ -17125,10 +17630,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17125
17630
|
});
|
|
17126
17631
|
for (const panel of removedPanels) targetGroup.model.addPanelToTabGroup(newTabGroup.id, panel.id);
|
|
17127
17632
|
if (!options.skipSetActive) this.doSetGroupAndPanelActive(targetGroup);
|
|
17128
|
-
for (const panel of removedPanels) this.
|
|
17129
|
-
panel,
|
|
17130
|
-
from: sourceGroup
|
|
17131
|
-
});
|
|
17633
|
+
for (const panel of removedPanels) this.fireDidMovePanel(panel, sourceGroup);
|
|
17132
17634
|
};
|
|
17133
17635
|
let targetGroup;
|
|
17134
17636
|
if (!destinationTarget || destinationTarget === "center" || !referenceLocation) targetGroup = destinationGroup;
|
|
@@ -17149,10 +17651,12 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17149
17651
|
this.mutation("maximize", () => super.exitMaximizedGroup());
|
|
17150
17652
|
}
|
|
17151
17653
|
_doMoveGroup(options) {
|
|
17654
|
+
var _mergedPanels;
|
|
17152
17655
|
const from = options.from.group;
|
|
17153
17656
|
const to = options.to.group;
|
|
17154
17657
|
const target = options.to.position;
|
|
17155
17658
|
let source = from;
|
|
17659
|
+
let mergedPanels;
|
|
17156
17660
|
if (target === "center") {
|
|
17157
17661
|
const activePanel = from.activePanel;
|
|
17158
17662
|
const tabGroupSnapshots = from.model.getTabGroups().map((tg) => ({
|
|
@@ -17170,6 +17674,7 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17170
17674
|
skipSetGroupActive: true
|
|
17171
17675
|
});
|
|
17172
17676
|
});
|
|
17677
|
+
mergedPanels = panels;
|
|
17173
17678
|
for (const snapshot of tabGroupSnapshots) {
|
|
17174
17679
|
const newTabGroup = to.model.createTabGroup({
|
|
17175
17680
|
label: snapshot.label,
|
|
@@ -17259,11 +17764,8 @@ var DockviewComponent = class extends BaseGrid {
|
|
|
17259
17764
|
this.setGroupLocationForRoot(source, destGridview);
|
|
17260
17765
|
}
|
|
17261
17766
|
}
|
|
17262
|
-
source.panels.forEach((panel) => {
|
|
17263
|
-
this.
|
|
17264
|
-
panel,
|
|
17265
|
-
from
|
|
17266
|
-
});
|
|
17767
|
+
((_mergedPanels = mergedPanels) !== null && _mergedPanels !== void 0 ? _mergedPanels : source.panels).forEach((panel) => {
|
|
17768
|
+
this.fireDidMovePanel(panel, from);
|
|
17267
17769
|
});
|
|
17268
17770
|
this.debouncedUpdateAllPositions();
|
|
17269
17771
|
if (options.skipSetActive === false) {
|