dockview 1.9.2 → 1.10.1

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.
Files changed (151) hide show
  1. package/dist/cjs/dockview/defaultTab.d.ts +0 -1
  2. package/dist/cjs/dockview/defaultTab.js +0 -1
  3. package/dist/cjs/dockview/dockview.d.ts +5 -3
  4. package/dist/cjs/dockview/dockview.js +31 -1
  5. package/dist/cjs/dockview/headerActionsRenderer.d.ts +0 -1
  6. package/dist/cjs/dockview/headerActionsRenderer.js +0 -1
  7. package/dist/cjs/dockview/reactContentPart.d.ts +0 -1
  8. package/dist/cjs/dockview/reactContentPart.js +0 -1
  9. package/dist/cjs/dockview/reactHeaderPart.d.ts +0 -1
  10. package/dist/cjs/dockview/reactHeaderPart.js +0 -1
  11. package/dist/cjs/dockview/reactWatermarkPart.d.ts +0 -1
  12. package/dist/cjs/dockview/reactWatermarkPart.js +0 -1
  13. package/dist/cjs/gridview/gridview.d.ts +0 -1
  14. package/dist/cjs/gridview/gridview.js +0 -1
  15. package/dist/cjs/gridview/view.d.ts +0 -1
  16. package/dist/cjs/gridview/view.js +3 -2
  17. package/dist/cjs/index.d.ts +0 -1
  18. package/dist/cjs/index.js +0 -1
  19. package/dist/cjs/paneview/paneview.d.ts +0 -1
  20. package/dist/cjs/paneview/paneview.js +0 -1
  21. package/dist/cjs/paneview/view.d.ts +0 -1
  22. package/dist/cjs/paneview/view.js +0 -1
  23. package/dist/cjs/react.d.ts +1 -2
  24. package/dist/cjs/react.js +13 -10
  25. package/dist/cjs/splitview/splitview.d.ts +0 -1
  26. package/dist/cjs/splitview/splitview.js +0 -1
  27. package/dist/cjs/splitview/view.d.ts +0 -1
  28. package/dist/cjs/splitview/view.js +0 -1
  29. package/dist/cjs/svg.d.ts +0 -1
  30. package/dist/cjs/svg.js +0 -1
  31. package/dist/cjs/types.d.ts +0 -1
  32. package/dist/cjs/types.js +0 -1
  33. package/dist/dockview.amd.js +1325 -544
  34. package/dist/dockview.amd.js.map +1 -1
  35. package/dist/dockview.amd.min.js +2 -2
  36. package/dist/dockview.amd.min.js.map +1 -1
  37. package/dist/dockview.amd.min.noStyle.js +2 -2
  38. package/dist/dockview.amd.min.noStyle.js.map +1 -1
  39. package/dist/dockview.amd.noStyle.js +1325 -544
  40. package/dist/dockview.amd.noStyle.js.map +1 -1
  41. package/dist/dockview.cjs.js +1325 -544
  42. package/dist/dockview.cjs.js.map +1 -1
  43. package/dist/dockview.esm.js +1322 -544
  44. package/dist/dockview.esm.js.map +1 -1
  45. package/dist/dockview.esm.min.js +2 -2
  46. package/dist/dockview.esm.min.js.map +1 -1
  47. package/dist/dockview.js +1325 -544
  48. package/dist/dockview.js.map +1 -1
  49. package/dist/dockview.min.js +2 -2
  50. package/dist/dockview.min.js.map +1 -1
  51. package/dist/dockview.min.noStyle.js +2 -2
  52. package/dist/dockview.min.noStyle.js.map +1 -1
  53. package/dist/dockview.noStyle.js +1325 -544
  54. package/dist/dockview.noStyle.js.map +1 -1
  55. package/dist/esm/dockview/defaultTab.d.ts +0 -1
  56. package/dist/esm/dockview/defaultTab.js +0 -1
  57. package/dist/esm/dockview/dockview.d.ts +5 -3
  58. package/dist/esm/dockview/dockview.js +31 -1
  59. package/dist/esm/dockview/headerActionsRenderer.d.ts +0 -1
  60. package/dist/esm/dockview/headerActionsRenderer.js +0 -1
  61. package/dist/esm/dockview/reactContentPart.d.ts +0 -1
  62. package/dist/esm/dockview/reactContentPart.js +0 -1
  63. package/dist/esm/dockview/reactHeaderPart.d.ts +0 -1
  64. package/dist/esm/dockview/reactHeaderPart.js +0 -1
  65. package/dist/esm/dockview/reactWatermarkPart.d.ts +0 -1
  66. package/dist/esm/dockview/reactWatermarkPart.js +0 -1
  67. package/dist/esm/gridview/gridview.d.ts +0 -1
  68. package/dist/esm/gridview/gridview.js +0 -1
  69. package/dist/esm/gridview/view.d.ts +0 -1
  70. package/dist/esm/gridview/view.js +3 -2
  71. package/dist/esm/index.d.ts +0 -1
  72. package/dist/esm/index.js +0 -1
  73. package/dist/esm/paneview/paneview.d.ts +0 -1
  74. package/dist/esm/paneview/paneview.js +0 -1
  75. package/dist/esm/paneview/view.d.ts +0 -1
  76. package/dist/esm/paneview/view.js +0 -1
  77. package/dist/esm/react.d.ts +1 -2
  78. package/dist/esm/react.js +11 -8
  79. package/dist/esm/splitview/splitview.d.ts +0 -1
  80. package/dist/esm/splitview/splitview.js +0 -1
  81. package/dist/esm/splitview/view.d.ts +0 -1
  82. package/dist/esm/splitview/view.js +0 -1
  83. package/dist/esm/svg.d.ts +0 -1
  84. package/dist/esm/svg.js +0 -1
  85. package/dist/esm/types.d.ts +0 -1
  86. package/dist/esm/types.js +0 -1
  87. package/package.json +4 -4
  88. package/dist/cjs/dockview/defaultTab.d.ts.map +0 -1
  89. package/dist/cjs/dockview/defaultTab.js.map +0 -1
  90. package/dist/cjs/dockview/dockview.d.ts.map +0 -1
  91. package/dist/cjs/dockview/dockview.js.map +0 -1
  92. package/dist/cjs/dockview/headerActionsRenderer.d.ts.map +0 -1
  93. package/dist/cjs/dockview/headerActionsRenderer.js.map +0 -1
  94. package/dist/cjs/dockview/reactContentPart.d.ts.map +0 -1
  95. package/dist/cjs/dockview/reactContentPart.js.map +0 -1
  96. package/dist/cjs/dockview/reactHeaderPart.d.ts.map +0 -1
  97. package/dist/cjs/dockview/reactHeaderPart.js.map +0 -1
  98. package/dist/cjs/dockview/reactWatermarkPart.d.ts.map +0 -1
  99. package/dist/cjs/dockview/reactWatermarkPart.js.map +0 -1
  100. package/dist/cjs/gridview/gridview.d.ts.map +0 -1
  101. package/dist/cjs/gridview/gridview.js.map +0 -1
  102. package/dist/cjs/gridview/view.d.ts.map +0 -1
  103. package/dist/cjs/gridview/view.js.map +0 -1
  104. package/dist/cjs/index.d.ts.map +0 -1
  105. package/dist/cjs/index.js.map +0 -1
  106. package/dist/cjs/paneview/paneview.d.ts.map +0 -1
  107. package/dist/cjs/paneview/paneview.js.map +0 -1
  108. package/dist/cjs/paneview/view.d.ts.map +0 -1
  109. package/dist/cjs/paneview/view.js.map +0 -1
  110. package/dist/cjs/react.d.ts.map +0 -1
  111. package/dist/cjs/react.js.map +0 -1
  112. package/dist/cjs/splitview/splitview.d.ts.map +0 -1
  113. package/dist/cjs/splitview/splitview.js.map +0 -1
  114. package/dist/cjs/splitview/view.d.ts.map +0 -1
  115. package/dist/cjs/splitview/view.js.map +0 -1
  116. package/dist/cjs/svg.d.ts.map +0 -1
  117. package/dist/cjs/svg.js.map +0 -1
  118. package/dist/cjs/types.d.ts.map +0 -1
  119. package/dist/cjs/types.js.map +0 -1
  120. package/dist/esm/dockview/defaultTab.d.ts.map +0 -1
  121. package/dist/esm/dockview/defaultTab.js.map +0 -1
  122. package/dist/esm/dockview/dockview.d.ts.map +0 -1
  123. package/dist/esm/dockview/dockview.js.map +0 -1
  124. package/dist/esm/dockview/headerActionsRenderer.d.ts.map +0 -1
  125. package/dist/esm/dockview/headerActionsRenderer.js.map +0 -1
  126. package/dist/esm/dockview/reactContentPart.d.ts.map +0 -1
  127. package/dist/esm/dockview/reactContentPart.js.map +0 -1
  128. package/dist/esm/dockview/reactHeaderPart.d.ts.map +0 -1
  129. package/dist/esm/dockview/reactHeaderPart.js.map +0 -1
  130. package/dist/esm/dockview/reactWatermarkPart.d.ts.map +0 -1
  131. package/dist/esm/dockview/reactWatermarkPart.js.map +0 -1
  132. package/dist/esm/gridview/gridview.d.ts.map +0 -1
  133. package/dist/esm/gridview/gridview.js.map +0 -1
  134. package/dist/esm/gridview/view.d.ts.map +0 -1
  135. package/dist/esm/gridview/view.js.map +0 -1
  136. package/dist/esm/index.d.ts.map +0 -1
  137. package/dist/esm/index.js.map +0 -1
  138. package/dist/esm/paneview/paneview.d.ts.map +0 -1
  139. package/dist/esm/paneview/paneview.js.map +0 -1
  140. package/dist/esm/paneview/view.d.ts.map +0 -1
  141. package/dist/esm/paneview/view.js.map +0 -1
  142. package/dist/esm/react.d.ts.map +0 -1
  143. package/dist/esm/react.js.map +0 -1
  144. package/dist/esm/splitview/splitview.d.ts.map +0 -1
  145. package/dist/esm/splitview/splitview.js.map +0 -1
  146. package/dist/esm/splitview/view.d.ts.map +0 -1
  147. package/dist/esm/splitview/view.js.map +0 -1
  148. package/dist/esm/svg.d.ts.map +0 -1
  149. package/dist/esm/svg.js.map +0 -1
  150. package/dist/esm/types.d.ts.map +0 -1
  151. package/dist/esm/types.js.map +0 -1
package/dist/dockview.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview
3
- * @version 1.9.2
3
+ * @version 1.10.1
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -142,6 +142,17 @@
142
142
  };
143
143
  };
144
144
  })(exports.DockviewEvent || (exports.DockviewEvent = {}));
145
+ class DockviewEvent {
146
+ constructor() {
147
+ this._defaultPrevented = false;
148
+ }
149
+ get defaultPrevented() {
150
+ return this._defaultPrevented;
151
+ }
152
+ preventDefault() {
153
+ this._defaultPrevented = true;
154
+ }
155
+ }
145
156
  class LeakageMonitor {
146
157
  constructor() {
147
158
  this.events = new Map();
@@ -185,6 +196,9 @@
185
196
  }
186
197
  Emitter.ENABLE_TRACKING = isEnabled;
187
198
  }
199
+ get value() {
200
+ return this._last;
201
+ }
188
202
  constructor(options) {
189
203
  this.options = options;
190
204
  this._listeners = [];
@@ -307,8 +321,12 @@
307
321
  args.forEach((arg) => this._disposables.push(arg));
308
322
  }
309
323
  dispose() {
310
- this._disposables.forEach((arg) => arg.dispose());
324
+ if (this._isDisposed) {
325
+ return;
326
+ }
311
327
  this._isDisposed = true;
328
+ this._disposables.forEach((arg) => arg.dispose());
329
+ this._disposables = [];
312
330
  }
313
331
  }
314
332
  class MutableDisposable {
@@ -792,6 +810,13 @@
792
810
  this._endSnappingEnabled = endSnappingEnabled;
793
811
  this.updateSashEnablement();
794
812
  }
813
+ get disabled() {
814
+ return this._disabled;
815
+ }
816
+ set disabled(value) {
817
+ this._disabled = value;
818
+ toggleClass(this.element, 'dv-splitview-disabled', value);
819
+ }
795
820
  constructor(container, options) {
796
821
  this.container = container;
797
822
  this.viewItems = [];
@@ -802,6 +827,7 @@
802
827
  this._proportions = undefined;
803
828
  this._startSnappingEnabled = true;
804
829
  this._endSnappingEnabled = true;
830
+ this._disabled = false;
805
831
  this._onDidSashEnd = new Emitter();
806
832
  this.onDidSashEnd = this._onDidSashEnd.event;
807
833
  this._onDidAddView = new Emitter();
@@ -1476,6 +1502,9 @@
1476
1502
  this._onDidChange.fire();
1477
1503
  }));
1478
1504
  }
1505
+ setViewVisible(index, visible) {
1506
+ this.splitview.setViewVisible(index, visible);
1507
+ }
1479
1508
  addPane(pane, size, index = this.splitview.length, skipLayout = false) {
1480
1509
  const disposable = pane.onDidChangeExpansionState(() => {
1481
1510
  this.setupAnimation();
@@ -1729,7 +1758,13 @@
1729
1758
  }
1730
1759
  return exports.LayoutPriority.Normal;
1731
1760
  }
1732
- constructor(orientation, proportionalLayout, styles, size, orthogonalSize, childDescriptors) {
1761
+ get disabled() {
1762
+ return this.splitview.disabled;
1763
+ }
1764
+ set disabled(value) {
1765
+ this.splitview.disabled = value;
1766
+ }
1767
+ constructor(orientation, proportionalLayout, styles, size, orthogonalSize, disabled, childDescriptors) {
1733
1768
  super();
1734
1769
  this.orientation = orientation;
1735
1770
  this.proportionalLayout = proportionalLayout;
@@ -1774,6 +1809,7 @@
1774
1809
  styles,
1775
1810
  });
1776
1811
  }
1812
+ this.disabled = disabled;
1777
1813
  this.addDisposables(this._onDidChange, this._onDidVisibilityChange, this.splitview.onDidSashEnd(() => {
1778
1814
  this._onDidChange.fire({});
1779
1815
  }));
@@ -1907,7 +1943,7 @@
1907
1943
  }
1908
1944
  function flipNode(node, size, orthogonalSize) {
1909
1945
  if (node instanceof BranchNode) {
1910
- const result = new BranchNode(orthogonal(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize);
1946
+ const result = new BranchNode(orthogonal(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled);
1911
1947
  let totalSize = 0;
1912
1948
  for (let i = node.children.length - 1; i >= 0; i--) {
1913
1949
  const child = node.children[i];
@@ -2043,31 +2079,57 @@
2043
2079
  get maximumHeight() {
2044
2080
  return this.root.maximumHeight;
2045
2081
  }
2082
+ get locked() {
2083
+ return this._locked;
2084
+ }
2085
+ set locked(value) {
2086
+ this._locked = value;
2087
+ const branch = [this.root];
2088
+ /**
2089
+ * simple depth-first-search to cover all nodes
2090
+ *
2091
+ * @see https://en.wikipedia.org/wiki/Depth-first_search
2092
+ */
2093
+ while (branch.length > 0) {
2094
+ const node = branch.pop();
2095
+ if (node instanceof BranchNode) {
2096
+ node.disabled = value;
2097
+ branch.push(...node.children);
2098
+ }
2099
+ }
2100
+ }
2046
2101
  maximizedView() {
2047
2102
  var _a;
2048
- return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.view;
2103
+ return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.leaf.view;
2049
2104
  }
2050
2105
  hasMaximizedView() {
2051
2106
  return this._maximizedNode !== undefined;
2052
2107
  }
2053
2108
  maximizeView(view) {
2109
+ var _a;
2054
2110
  const location = getGridLocation(view.element);
2055
2111
  const [_, node] = this.getNode(location);
2056
2112
  if (!(node instanceof LeafNode)) {
2057
2113
  return;
2058
2114
  }
2059
- if (this._maximizedNode === node) {
2115
+ if (((_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.leaf) === node) {
2060
2116
  return;
2061
2117
  }
2062
2118
  if (this.hasMaximizedView()) {
2063
2119
  this.exitMaximizedView();
2064
2120
  }
2121
+ const hiddenOnMaximize = [];
2065
2122
  function hideAllViewsBut(parent, exclude) {
2066
2123
  for (let i = 0; i < parent.children.length; i++) {
2067
2124
  const child = parent.children[i];
2068
2125
  if (child instanceof LeafNode) {
2069
2126
  if (child !== exclude) {
2070
- parent.setChildVisible(i, false);
2127
+ if (parent.isChildVisible(i)) {
2128
+ parent.setChildVisible(i, false);
2129
+ }
2130
+ else {
2131
+ hiddenOnMaximize.push(child);
2132
+ }
2071
2133
  }
2072
2134
  }
2073
2135
  else {
@@ -2076,18 +2138,21 @@
2076
2138
  }
2077
2139
  }
2078
2140
  hideAllViewsBut(this.root, node);
2079
- this._maximizedNode = node;
2080
- this._onDidMaxmizedNodeChange.fire();
2141
+ this._maximizedNode = { leaf: node, hiddenOnMaximize };
2142
+ this._onDidMaximizedNodeChange.fire();
2081
2143
  }
2082
2144
  exitMaximizedView() {
2083
2145
  if (!this._maximizedNode) {
2084
2146
  return;
2085
2147
  }
2148
+ const hiddenOnMaximize = this._maximizedNode.hiddenOnMaximize;
2086
2149
  function showViewsInReverseOrder(parent) {
2087
2150
  for (let index = parent.children.length - 1; index >= 0; index--) {
2088
2151
  const child = parent.children[index];
2089
2152
  if (child instanceof LeafNode) {
2090
- parent.setChildVisible(index, true);
2153
+ if (!hiddenOnMaximize.includes(child)) {
2154
+ parent.setChildVisible(index, true);
2155
+ }
2091
2156
  }
2092
2157
  else {
2093
2158
  showViewsInReverseOrder(child);
@@ -2096,13 +2161,13 @@
2096
2161
  }
2097
2162
  showViewsInReverseOrder(this.root);
2098
2163
  this._maximizedNode = undefined;
2099
- this._onDidMaxmizedNodeChange.fire();
2164
+ this._onDidMaximizedNodeChange.fire();
2100
2165
  }
2101
2166
  serialize() {
2102
2167
  if (this.hasMaximizedView()) {
2103
2168
  /**
2104
- * do not persist maximized view state but we must first exit any maximized views
2105
- * before serialization to ensure the correct dimensions are persisted
2169
+ * do not persist maximized view state
2170
+ * firstly exit any maximized views to ensure the correct dimensions are persisted
2106
2171
  */
2107
2172
  this.exitMaximizedView();
2108
2173
  }
@@ -2117,14 +2182,14 @@
2117
2182
  dispose() {
2118
2183
  this.disposable.dispose();
2119
2184
  this._onDidChange.dispose();
2120
- this._onDidMaxmizedNodeChange.dispose();
2185
+ this._onDidMaximizedNodeChange.dispose();
2121
2186
  this.root.dispose();
2122
2187
  this._maximizedNode = undefined;
2123
2188
  this.element.remove();
2124
2189
  }
2125
2190
  clear() {
2126
2191
  const orientation = this.root.orientation;
2127
- this.root = new BranchNode(orientation, this.proportionalLayout, this.styles, this.root.size, this.root.orthogonalSize);
2192
+ this.root = new BranchNode(orientation, this.proportionalLayout, this.styles, this.root.size, this.root.orthogonalSize, this._locked);
2128
2193
  }
2129
2194
  deserialize(json, deserializer) {
2130
2195
  const orientation = json.orientation;
@@ -2145,8 +2210,8 @@
2145
2210
  };
2146
2211
  });
2147
2212
  result = new BranchNode(orientation, this.proportionalLayout, this.styles, node.size, // <- orthogonal size - flips at each depth
2148
- orthogonalSize, // <- size - flips at each depth
2149
- children);
2213
+ orthogonalSize, // <- size - flips at each depth,
2214
+ this._locked, children);
2150
2215
  }
2151
2216
  else {
2152
2217
  result = new LeafNode(deserializer.fromJSON(node), orientation, orthogonalSize, node.size);
@@ -2179,7 +2244,7 @@
2179
2244
  }
2180
2245
  const oldRoot = this.root;
2181
2246
  oldRoot.element.remove();
2182
- this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size);
2247
+ this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size, this._locked);
2183
2248
  if (oldRoot.children.length === 0) ;
2184
2249
  else if (oldRoot.children.length === 1) {
2185
2250
  // can remove one level of redundant branching if there is only a single child
@@ -2247,15 +2312,16 @@
2247
2312
  constructor(proportionalLayout, styles, orientation) {
2248
2313
  this.proportionalLayout = proportionalLayout;
2249
2314
  this.styles = styles;
2315
+ this._locked = false;
2250
2316
  this._maximizedNode = undefined;
2251
2317
  this.disposable = new MutableDisposable();
2252
2318
  this._onDidChange = new Emitter();
2253
2319
  this.onDidChange = this._onDidChange.event;
2254
- this._onDidMaxmizedNodeChange = new Emitter();
2255
- this.onDidMaxmizedNodeChange = this._onDidMaxmizedNodeChange.event;
2320
+ this._onDidMaximizedNodeChange = new Emitter();
2321
+ this.onDidMaximizedNodeChange = this._onDidMaximizedNodeChange.event;
2256
2322
  this.element = document.createElement('div');
2257
2323
  this.element.className = 'grid-view';
2258
- this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0);
2324
+ this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0, this._locked);
2259
2325
  }
2260
2326
  isViewVisible(location) {
2261
2327
  const [rest, index] = tail(location);
@@ -2306,7 +2372,7 @@
2306
2372
  }
2307
2373
  const child = grandParent.removeChild(parentIndex);
2308
2374
  child.dispose();
2309
- const newParent = new BranchNode(parent.orientation, this.proportionalLayout, this.styles, parent.size, parent.orthogonalSize);
2375
+ const newParent = new BranchNode(parent.orientation, this.proportionalLayout, this.styles, parent.size, parent.orthogonalSize, this._locked);
2310
2376
  grandParent.addChild(newParent, parent.size, parentIndex);
2311
2377
  const newSibling = new LeafNode(parent.view, grandParent.orientation, parent.size);
2312
2378
  newParent.addChild(newSibling, newSiblingSize, 0);
@@ -2934,13 +3000,36 @@
2934
3000
  return this.component.onDidDrop;
2935
3001
  }
2936
3002
  /**
2937
- * Invoked before a group is dragged. Exposed for custom Drag'n'Drop functionality.
3003
+ * Invoked when a Drag'n'Drop event occurs but before dockview handles it giving the user an opportunity to intecept and
3004
+ * prevent the event from occuring using the standard `preventDefault()` syntax.
3005
+ *
3006
+ * Preventing certain events may causes unexpected behaviours, use carefully.
3007
+ */
3008
+ get onWillDrop() {
3009
+ return this.component.onWillDrop;
3010
+ }
3011
+ /**
3012
+ * Invoked before an overlay is shown indicating a drop target.
3013
+ *
3014
+ * Calling `event.preventDefault()` will prevent the overlay being shown and prevent
3015
+ * the any subsequent drop event.
3016
+ */
3017
+ get onWillShowOverlay() {
3018
+ return this.component.onWillShowOverlay;
3019
+ }
3020
+ /**
3021
+ * Invoked before a group is dragged.
3022
+ *
3023
+ * Calling `event.nativeEvent.preventDefault()` will prevent the group drag starting.
3024
+ *
2938
3025
  */
2939
3026
  get onWillDragGroup() {
2940
3027
  return this.component.onWillDragGroup;
2941
3028
  }
2942
3029
  /**
2943
- * Invoked before a panel is dragged. Exposed for custom Drag'n'Drop functionality.
3030
+ * Invoked before a panel is dragged.
3031
+ *
3032
+ * Calling `event.nativeEvent.preventDefault()` will prevent the panel drag starting.
2944
3033
  */
2945
3034
  get onWillDragPanel() {
2946
3035
  return this.component.onWillDragPanel;
@@ -3068,17 +3157,17 @@
3068
3157
  hasMaximizedGroup() {
3069
3158
  return this.component.hasMaximizedGroup();
3070
3159
  }
3071
- exitMaxmizedGroup() {
3160
+ exitMaximizedGroup() {
3072
3161
  this.component.exitMaximizedGroup();
3073
3162
  }
3074
- get onDidMaxmizedGroupChange() {
3075
- return this.component.onDidMaxmizedGroupChange;
3163
+ get onDidMaximizedGroupChange() {
3164
+ return this.component.onDidMaximizedGroupChange;
3076
3165
  }
3077
3166
  /**
3078
3167
  * Add a popout group in a new Window
3079
3168
  */
3080
3169
  addPopoutGroup(item, options) {
3081
- this.component.addPopoutGroup(item, options);
3170
+ return this.component.addPopoutGroup(item, options);
3082
3171
  }
3083
3172
  }
3084
3173
 
@@ -3132,6 +3221,18 @@
3132
3221
  }
3133
3222
  }
3134
3223
 
3224
+ class WillShowOverlayEvent extends DockviewEvent {
3225
+ get nativeEvent() {
3226
+ return this.options.nativeEvent;
3227
+ }
3228
+ get position() {
3229
+ return this.options.position;
3230
+ }
3231
+ constructor(options) {
3232
+ super();
3233
+ this.options = options;
3234
+ }
3235
+ }
3135
3236
  function directionToPosition(direction) {
3136
3237
  switch (direction) {
3137
3238
  case 'above':
@@ -3184,6 +3285,8 @@
3184
3285
  this.options = options;
3185
3286
  this._onDrop = new Emitter();
3186
3287
  this.onDrop = this._onDrop.event;
3288
+ this._onWillShowOverlay = new Emitter();
3289
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
3187
3290
  // use a set to take advantage of #<set>.has
3188
3291
  this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
3189
3292
  this.dnd = new DragAndDropObserver(this.element, {
@@ -3212,6 +3315,19 @@
3212
3315
  this.removeDropTarget();
3213
3316
  return;
3214
3317
  }
3318
+ const willShowOverlayEvent = new WillShowOverlayEvent({
3319
+ nativeEvent: e,
3320
+ position: quadrant,
3321
+ });
3322
+ /**
3323
+ * Provide an opportunity to prevent the overlay appearing and in turn
3324
+ * any dnd behaviours
3325
+ */
3326
+ this._onWillShowOverlay.fire(willShowOverlayEvent);
3327
+ if (willShowOverlayEvent.defaultPrevented) {
3328
+ this.removeDropTarget();
3329
+ return;
3330
+ }
3215
3331
  if (typeof this.options.canDisplayOverlay === 'boolean') {
3216
3332
  if (!this.options.canDisplayOverlay) {
3217
3333
  this.removeDropTarget();
@@ -3254,7 +3370,7 @@
3254
3370
  }
3255
3371
  },
3256
3372
  });
3257
- this.addDisposables(this._onDrop, this.dnd);
3373
+ this.addDisposables(this._onDrop, this._onWillShowOverlay, this.dnd);
3258
3374
  }
3259
3375
  setTargetZones(acceptedTargetZones) {
3260
3376
  this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
@@ -3307,25 +3423,44 @@
3307
3423
  size = clamp(0, sizeOptions.value, height) / height;
3308
3424
  }
3309
3425
  }
3310
- const translate = (1 - size) / 2;
3311
- const scale = size;
3312
- let transform;
3426
+ const box = { top: '0px', left: '0px', width: '100%', height: '100%' };
3427
+ /**
3428
+ * You can also achieve the overlay placement using the transform CSS property
3429
+ * to translate and scale the element however this has the undesired effect of
3430
+ * 'skewing' the element. Comment left here for anybody that ever revisits this.
3431
+ *
3432
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/transform
3433
+ *
3434
+ * right
3435
+ * translateX(${100 * (1 - size) / 2}%) scaleX(${scale})
3436
+ *
3437
+ * left
3438
+ * translateX(-${100 * (1 - size) / 2}%) scaleX(${scale})
3439
+ *
3440
+ * top
3441
+ * translateY(-${100 * (1 - size) / 2}%) scaleY(${scale})
3442
+ *
3443
+ * bottom
3444
+ * translateY(${100 * (1 - size) / 2}%) scaleY(${scale})
3445
+ */
3313
3446
  if (rightClass) {
3314
- transform = `translateX(${100 * translate}%) scaleX(${scale})`;
3447
+ box.left = `${100 * (1 - size)}%`;
3448
+ box.width = `${100 * size}%`;
3315
3449
  }
3316
3450
  else if (leftClass) {
3317
- transform = `translateX(-${100 * translate}%) scaleX(${scale})`;
3451
+ box.width = `${100 * size}%`;
3318
3452
  }
3319
3453
  else if (topClass) {
3320
- transform = `translateY(-${100 * translate}%) scaleY(${scale})`;
3454
+ box.height = `${100 * size}%`;
3321
3455
  }
3322
3456
  else if (bottomClass) {
3323
- transform = `translateY(${100 * translate}%) scaleY(${scale})`;
3324
- }
3325
- else {
3326
- transform = '';
3457
+ box.top = `${100 * (1 - size)}%`;
3458
+ box.height = `${100 * size}%`;
3327
3459
  }
3328
- this.overlayElement.style.transform = transform;
3460
+ this.overlayElement.style.top = box.top;
3461
+ this.overlayElement.style.left = box.left;
3462
+ this.overlayElement.style.width = box.width;
3463
+ this.overlayElement.style.height = box.height;
3329
3464
  toggleClass(this.overlayElement, 'dv-drop-target-small-vertical', isSmallY);
3330
3465
  toggleClass(this.overlayElement, 'dv-drop-target-small-horizontal', isSmallX);
3331
3466
  toggleClass(this.overlayElement, 'dv-drop-target-left', isLeft);
@@ -3393,14 +3528,6 @@
3393
3528
  return 'center';
3394
3529
  }
3395
3530
 
3396
- exports.DockviewDropTargets = void 0;
3397
- (function (DockviewDropTargets) {
3398
- DockviewDropTargets[DockviewDropTargets["Tab"] = 0] = "Tab";
3399
- DockviewDropTargets[DockviewDropTargets["Panel"] = 1] = "Panel";
3400
- DockviewDropTargets[DockviewDropTargets["TabContainer"] = 2] = "TabContainer";
3401
- DockviewDropTargets[DockviewDropTargets["Edge"] = 3] = "Edge";
3402
- })(exports.DockviewDropTargets || (exports.DockviewDropTargets = {}));
3403
-
3404
3531
  class ContentContainer extends CompositeDisposable {
3405
3532
  get element() {
3406
3533
  return this._element;
@@ -3428,7 +3555,7 @@
3428
3555
  const data = getPanelData();
3429
3556
  if (!data &&
3430
3557
  event.shiftKey &&
3431
- this.group.location !== 'floating') {
3558
+ this.group.location.type !== 'floating') {
3432
3559
  return false;
3433
3560
  }
3434
3561
  if (data && data.viewId === this.accessor.id) {
@@ -3446,7 +3573,7 @@
3446
3573
  data.groupId === this.group.id;
3447
3574
  return !groupHasOnePanelAndIsActiveDragElement;
3448
3575
  }
3449
- return this.group.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3576
+ return this.group.canDisplayOverlay(event, position, 'content');
3450
3577
  },
3451
3578
  });
3452
3579
  this.addDisposables(this.dropTarget);
@@ -3471,7 +3598,7 @@
3471
3598
  let container;
3472
3599
  switch (panel.api.renderer) {
3473
3600
  case 'onlyWhenVisibile':
3474
- this.accessor.overlayRenderContainer.detatch(panel);
3601
+ this.group.renderContainer.detatch(panel);
3475
3602
  if (this.panel) {
3476
3603
  if (doRender) {
3477
3604
  this._element.appendChild(this.panel.view.content.element);
@@ -3483,7 +3610,7 @@
3483
3610
  if (panel.view.content.element.parentElement === this._element) {
3484
3611
  this._element.removeChild(panel.view.content.element);
3485
3612
  }
3486
- container = this.accessor.overlayRenderContainer.attach({
3613
+ container = this.group.renderContainer.attach({
3487
3614
  panel,
3488
3615
  referenceContainer: this,
3489
3616
  });
@@ -3514,9 +3641,10 @@
3514
3641
  // noop
3515
3642
  }
3516
3643
  closePanel() {
3644
+ var _a;
3517
3645
  if (this.panel) {
3518
3646
  if (this.panel.api.renderer === 'onlyWhenVisibile') {
3519
- this._element.removeChild(this.panel.view.content.element);
3647
+ (_a = this.panel.view.content.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.panel.view.content.element);
3520
3648
  }
3521
3649
  }
3522
3650
  this.panel = undefined;
@@ -3627,7 +3755,7 @@
3627
3755
  this._element.draggable = true;
3628
3756
  toggleClass(this.element, 'inactive-tab', true);
3629
3757
  const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
3630
- this.droptarget = new Droptarget(this._element, {
3758
+ this.dropTarget = new Droptarget(this._element, {
3631
3759
  acceptedTargetZones: ['center'],
3632
3760
  canDisplayOverlay: (event, position) => {
3633
3761
  if (this.group.locked) {
@@ -3642,9 +3770,10 @@
3642
3770
  }
3643
3771
  return this.panel.id !== data.panelId;
3644
3772
  }
3645
- return this.group.model.canDisplayOverlay(event, position, exports.DockviewDropTargets.Tab);
3773
+ return this.group.model.canDisplayOverlay(event, position, 'tab');
3646
3774
  },
3647
3775
  });
3776
+ this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
3648
3777
  this.addDisposables(this._onChanged, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
3649
3778
  this._onDragStart.fire(event);
3650
3779
  }), dragHandler, addDisposableListener(this._element, 'mousedown', (event) => {
@@ -3652,9 +3781,9 @@
3652
3781
  return;
3653
3782
  }
3654
3783
  this._onChanged.fire(event);
3655
- }), this.droptarget.onDrop((event) => {
3784
+ }), this.dropTarget.onDrop((event) => {
3656
3785
  this._onDropped.fire(event);
3657
- }), this.droptarget);
3786
+ }), this.dropTarget);
3658
3787
  }
3659
3788
  setActive(isActive) {
3660
3789
  toggleClass(this.element, 'active-tab', isActive);
@@ -3701,7 +3830,7 @@
3701
3830
  }, true));
3702
3831
  }
3703
3832
  isCancelled(_event) {
3704
- if (this.group.api.location === 'floating' && !_event.shiftKey) {
3833
+ if (this.group.api.location.type === 'floating' && !_event.shiftKey) {
3705
3834
  return true;
3706
3835
  }
3707
3836
  return false;
@@ -3753,7 +3882,7 @@
3753
3882
  this.accessor.doSetGroupActive(this.group);
3754
3883
  }));
3755
3884
  const handler = new GroupDragHandler(this._element, accessor, group);
3756
- this.voidDropTarget = new Droptarget(this._element, {
3885
+ this.dropTraget = new Droptarget(this._element, {
3757
3886
  acceptedTargetZones: ['center'],
3758
3887
  canDisplayOverlay: (event, position) => {
3759
3888
  var _a;
@@ -3767,14 +3896,15 @@
3767
3896
  // don't show the overlay if the tab being dragged is the last panel of this group
3768
3897
  return ((_a = last(this.group.panels)) === null || _a === void 0 ? void 0 : _a.id) !== data.panelId;
3769
3898
  }
3770
- return group.model.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3899
+ return group.model.canDisplayOverlay(event, position, 'header_space');
3771
3900
  },
3772
3901
  });
3902
+ this.onWillShowOverlay = this.dropTraget.onWillShowOverlay;
3773
3903
  this.addDisposables(handler, handler.onDragStart((event) => {
3774
3904
  this._onDragStart.fire(event);
3775
- }), this.voidDropTarget.onDrop((event) => {
3905
+ }), this.dropTraget.onDrop((event) => {
3776
3906
  this._onDrop.fire(event);
3777
- }), this.voidDropTarget);
3907
+ }), this.dropTraget);
3778
3908
  }
3779
3909
  }
3780
3910
 
@@ -3862,19 +3992,11 @@
3862
3992
  this.onTabDragStart = this._onTabDragStart.event;
3863
3993
  this._onGroupDragStart = new Emitter();
3864
3994
  this.onGroupDragStart = this._onGroupDragStart.event;
3865
- this.addDisposables(this._onDrop, this._onTabDragStart, this._onGroupDragStart);
3995
+ this._onWillShowOverlay = new Emitter();
3996
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
3866
3997
  this._element = document.createElement('div');
3867
3998
  this._element.className = 'tabs-and-actions-container';
3868
3999
  toggleClass(this._element, 'dv-full-width-single-tab', this.accessor.options.singleTabMode === 'fullwidth');
3869
- this.addDisposables(this.accessor.onDidAddPanel((e) => {
3870
- if (e.api.group === this.group) {
3871
- toggleClass(this._element, 'dv-single-tab', this.size === 1);
3872
- }
3873
- }), this.accessor.onDidRemovePanel((e) => {
3874
- if (e.api.group === this.group) {
3875
- toggleClass(this._element, 'dv-single-tab', this.size === 1);
3876
- }
3877
- }));
3878
4000
  this.rightActionsContainer = document.createElement('div');
3879
4001
  this.rightActionsContainer.className = 'right-actions-container';
3880
4002
  this.leftActionsContainer = document.createElement('div');
@@ -3889,7 +4011,15 @@
3889
4011
  this._element.appendChild(this.leftActionsContainer);
3890
4012
  this._element.appendChild(this.voidContainer.element);
3891
4013
  this._element.appendChild(this.rightActionsContainer);
3892
- this.addDisposables(this.voidContainer, this.voidContainer.onDragStart((event) => {
4014
+ this.addDisposables(this.accessor.onDidAddPanel((e) => {
4015
+ if (e.api.group === this.group) {
4016
+ toggleClass(this._element, 'dv-single-tab', this.size === 1);
4017
+ }
4018
+ }), this.accessor.onDidRemovePanel((e) => {
4019
+ if (e.api.group === this.group) {
4020
+ toggleClass(this._element, 'dv-single-tab', this.size === 1);
4021
+ }
4022
+ }), this._onWillShowOverlay, this._onDrop, this._onTabDragStart, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
3893
4023
  this._onGroupDragStart.fire({
3894
4024
  nativeEvent: event,
3895
4025
  group: this.group,
@@ -3899,11 +4029,15 @@
3899
4029
  event: event.nativeEvent,
3900
4030
  index: this.tabs.length,
3901
4031
  });
4032
+ }), this.voidContainer.onWillShowOverlay((event) => {
4033
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
4034
+ kind: 'header_space',
4035
+ }));
3902
4036
  }), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => {
3903
4037
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3904
4038
  if (isFloatingGroupsEnabled &&
3905
4039
  event.shiftKey &&
3906
- this.group.api.location !== 'floating') {
4040
+ this.group.api.location.type !== 'floating') {
3907
4041
  event.preventDefault();
3908
4042
  const { top, left } = this.element.getBoundingClientRect();
3909
4043
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
@@ -3966,9 +4100,9 @@
3966
4100
  const disposable = new CompositeDisposable(tab.onDragStart((event) => {
3967
4101
  this._onTabDragStart.fire({ nativeEvent: event, panel });
3968
4102
  }), tab.onChanged((event) => {
3969
- var _a;
3970
4103
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3971
- const isFloatingWithOnePanel = this.group.api.location === 'floating' && this.size === 1;
4104
+ const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
4105
+ this.size === 1;
3972
4106
  if (isFloatingGroupsEnabled &&
3973
4107
  !isFloatingWithOnePanel &&
3974
4108
  event.shiftKey) {
@@ -3982,20 +4116,20 @@
3982
4116
  }, { inDragMode: true });
3983
4117
  return;
3984
4118
  }
3985
- const alreadyFocused = panel.id === ((_a = this.group.model.activePanel) === null || _a === void 0 ? void 0 : _a.id) &&
3986
- this.group.model.isContentFocused;
3987
4119
  const isLeftClick = event.button === 0;
3988
4120
  if (!isLeftClick || event.defaultPrevented) {
3989
4121
  return;
3990
4122
  }
3991
- this.group.model.openPanel(panel, {
3992
- skipFocus: alreadyFocused,
3993
- });
4123
+ if (this.group.activePanel !== panel) {
4124
+ this.group.model.openPanel(panel);
4125
+ }
3994
4126
  }), tab.onDrop((event) => {
3995
4127
  this._onDrop.fire({
3996
4128
  event: event.nativeEvent,
3997
4129
  index: this.tabs.findIndex((x) => x.value === tab),
3998
4130
  });
4131
+ }), tab.onWillShowOverlay((event) => {
4132
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, { kind: 'tab' }));
3999
4133
  }));
4000
4134
  const value = { value: tab, disposable };
4001
4135
  this.addTab(value, index);
@@ -4013,6 +4147,60 @@
4013
4147
  }
4014
4148
  }
4015
4149
 
4150
+ class DockviewDidDropEvent extends DockviewEvent {
4151
+ get nativeEvent() {
4152
+ return this.options.nativeEvent;
4153
+ }
4154
+ get position() {
4155
+ return this.options.position;
4156
+ }
4157
+ get panel() {
4158
+ return this.options.panel;
4159
+ }
4160
+ get group() {
4161
+ return this.options.group;
4162
+ }
4163
+ get api() {
4164
+ return this.options.api;
4165
+ }
4166
+ constructor(options) {
4167
+ super();
4168
+ this.options = options;
4169
+ }
4170
+ getData() {
4171
+ return this.options.getData();
4172
+ }
4173
+ }
4174
+ class DockviewWillDropEvent extends DockviewDidDropEvent {
4175
+ get kind() {
4176
+ return this._kind;
4177
+ }
4178
+ constructor(options) {
4179
+ super(options);
4180
+ this._kind = options.kind;
4181
+ }
4182
+ }
4183
+ class WillShowOverlayLocationEvent {
4184
+ get kind() {
4185
+ return this._kind;
4186
+ }
4187
+ get nativeEvent() {
4188
+ return this.event.nativeEvent;
4189
+ }
4190
+ get position() {
4191
+ return this.event.position;
4192
+ }
4193
+ get defaultPrevented() {
4194
+ return this.event.defaultPrevented;
4195
+ }
4196
+ preventDefault() {
4197
+ this.event.preventDefault();
4198
+ }
4199
+ constructor(event, options) {
4200
+ this.event = event;
4201
+ this._kind = options.kind;
4202
+ }
4203
+ }
4016
4204
  class DockviewGroupPanelModel extends CompositeDisposable {
4017
4205
  get element() {
4018
4206
  throw new Error('not supported');
@@ -4058,7 +4246,7 @@
4058
4246
  this._location = value;
4059
4247
  toggleClass(this.container, 'dv-groupview-floating', false);
4060
4248
  toggleClass(this.container, 'dv-groupview-popout', false);
4061
- switch (value) {
4249
+ switch (value.type) {
4062
4250
  case 'grid':
4063
4251
  this.contentContainer.dropTarget.setTargetZones([
4064
4252
  'top',
@@ -4094,7 +4282,7 @@
4094
4282
  this.groupPanel = groupPanel;
4095
4283
  this._isGroupActive = false;
4096
4284
  this._locked = false;
4097
- this._location = 'grid';
4285
+ this._location = { type: 'grid' };
4098
4286
  this.mostRecentlyUsed = [];
4099
4287
  this._onDidChange = new Emitter();
4100
4288
  this.onDidChange = this._onDidChange.event;
@@ -4105,6 +4293,10 @@
4105
4293
  this.onMove = this._onMove.event;
4106
4294
  this._onDidDrop = new Emitter();
4107
4295
  this.onDidDrop = this._onDidDrop.event;
4296
+ this._onWillDrop = new Emitter();
4297
+ this.onWillDrop = this._onWillDrop.event;
4298
+ this._onWillShowOverlay = new Emitter();
4299
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
4108
4300
  this._onTabDragStart = new Emitter();
4109
4301
  this.onTabDragStart = this._onTabDragStart.event;
4110
4302
  this._onGroupDragStart = new Emitter();
@@ -4115,46 +4307,69 @@
4115
4307
  this.onDidRemovePanel = this._onDidRemovePanel.event;
4116
4308
  this._onDidActivePanelChange = new Emitter();
4117
4309
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
4310
+ this._overwriteRenderContainer = null;
4118
4311
  toggleClass(this.container, 'groupview', true);
4312
+ this._api = new DockviewApi(this.accessor);
4119
4313
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
4120
4314
  this.contentContainer = new ContentContainer(this.accessor, this);
4121
4315
  container.append(this.tabsContainer.element, this.contentContainer.element);
4122
4316
  this.header.hidden = !!options.hideHeader;
4123
4317
  this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
4124
- this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this.tabsContainer.onTabDragStart((event) => {
4318
+ this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this._onWillShowOverlay, this.tabsContainer.onTabDragStart((event) => {
4125
4319
  this._onTabDragStart.fire(event);
4126
4320
  }), this.tabsContainer.onGroupDragStart((event) => {
4127
4321
  this._onGroupDragStart.fire(event);
4128
4322
  }), this.tabsContainer.onDrop((event) => {
4129
- this.handleDropEvent(event.event, 'center', event.index);
4323
+ this.handleDropEvent('header', event.event, 'center', event.index);
4130
4324
  }), this.contentContainer.onDidFocus(() => {
4131
- this.accessor.doSetGroupActive(this.groupPanel, true);
4325
+ this.accessor.doSetGroupActive(this.groupPanel);
4132
4326
  }), this.contentContainer.onDidBlur(() => {
4133
4327
  // noop
4134
4328
  }), this.contentContainer.dropTarget.onDrop((event) => {
4135
- this.handleDropEvent(event.nativeEvent, event.position);
4136
- }), this._onMove, this._onDidChange, this._onDidDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange);
4329
+ this.handleDropEvent('content', event.nativeEvent, event.position);
4330
+ }), this.tabsContainer.onWillShowOverlay((event) => {
4331
+ this._onWillShowOverlay.fire(event);
4332
+ }), this.contentContainer.dropTarget.onWillShowOverlay((event) => {
4333
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
4334
+ kind: 'content',
4335
+ }));
4336
+ }), this._onMove, this._onDidChange, this._onDidDrop, this._onWillDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange);
4337
+ }
4338
+ focusContent() {
4339
+ this.contentContainer.element.focus();
4340
+ }
4341
+ set renderContainer(value) {
4342
+ this.panels.forEach((panel) => {
4343
+ this.renderContainer.detatch(panel);
4344
+ });
4345
+ this._overwriteRenderContainer = value;
4346
+ this.panels.forEach((panel) => {
4347
+ this.rerender(panel);
4348
+ });
4349
+ }
4350
+ get renderContainer() {
4351
+ var _a;
4352
+ return ((_a = this._overwriteRenderContainer) !== null && _a !== void 0 ? _a : this.accessor.overlayRenderContainer);
4137
4353
  }
4138
4354
  initialize() {
4139
- var _a, _b;
4140
- if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.panels) {
4355
+ if (this.options.panels) {
4141
4356
  this.options.panels.forEach((panel) => {
4142
4357
  this.doAddPanel(panel);
4143
4358
  });
4144
4359
  }
4145
- if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.activePanel) {
4360
+ if (this.options.activePanel) {
4146
4361
  this.openPanel(this.options.activePanel);
4147
4362
  }
4148
4363
  // must be run after the constructor otherwise this.parent may not be
4149
4364
  // correctly initialized
4150
- this.setActive(this.isActive, true, true);
4365
+ this.setActive(this.isActive, true);
4151
4366
  this.updateContainer();
4152
4367
  if (this.accessor.options.createRightHeaderActionsElement) {
4153
4368
  this._rightHeaderActions =
4154
4369
  this.accessor.options.createRightHeaderActionsElement(this.groupPanel);
4155
4370
  this.addDisposables(this._rightHeaderActions);
4156
4371
  this._rightHeaderActions.init({
4157
- containerApi: new DockviewApi(this.accessor),
4372
+ containerApi: this._api,
4158
4373
  api: this.groupPanel.api,
4159
4374
  });
4160
4375
  this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
@@ -4164,7 +4379,7 @@
4164
4379
  this.accessor.options.createLeftHeaderActionsElement(this.groupPanel);
4165
4380
  this.addDisposables(this._leftHeaderActions);
4166
4381
  this._leftHeaderActions.init({
4167
- containerApi: new DockviewApi(this.accessor),
4382
+ containerApi: this._api,
4168
4383
  api: this.groupPanel.api,
4169
4384
  });
4170
4385
  this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
@@ -4174,7 +4389,7 @@
4174
4389
  this.accessor.options.createPrefixHeaderActionsElement(this.groupPanel);
4175
4390
  this.addDisposables(this._prefixHeaderActions);
4176
4391
  this._prefixHeaderActions.init({
4177
- containerApi: new DockviewApi(this.accessor),
4392
+ containerApi: this._api,
4178
4393
  api: this.groupPanel.api,
4179
4394
  });
4180
4395
  this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
@@ -4254,35 +4469,45 @@
4254
4469
  //noop
4255
4470
  }
4256
4471
  focus() {
4257
- var _a, _b;
4258
- (_b = (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a);
4472
+ var _a;
4473
+ (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.focus();
4259
4474
  }
4260
4475
  openPanel(panel, options = {}) {
4476
+ /**
4477
+ * set the panel group
4478
+ * add the panel
4479
+ * check if group active
4480
+ * check if panel active
4481
+ */
4261
4482
  if (typeof options.index !== 'number' ||
4262
4483
  options.index > this.panels.length) {
4263
4484
  options.index = this.panels.length;
4264
4485
  }
4265
- const skipSetPanelActive = !!options.skipSetPanelActive;
4266
- const skipSetGroupActive = !!options.skipSetGroupActive;
4486
+ const skipSetActive = !!options.skipSetActive;
4267
4487
  // ensure the group is updated before we fire any events
4268
- panel.updateParentGroup(this.groupPanel, true);
4488
+ panel.updateParentGroup(this.groupPanel, {
4489
+ skipSetActive: options.skipSetActive,
4490
+ });
4491
+ this.doAddPanel(panel, options.index, {
4492
+ skipSetActive: skipSetActive,
4493
+ });
4269
4494
  if (this._activePanel === panel) {
4270
- if (!skipSetGroupActive) {
4271
- this.accessor.doSetGroupActive(this.groupPanel);
4272
- }
4273
4495
  this.contentContainer.renderPanel(panel, { asActive: true });
4274
4496
  return;
4275
4497
  }
4276
- this.doAddPanel(panel, options.index, skipSetPanelActive);
4277
- if (!skipSetPanelActive) {
4498
+ if (!skipSetActive) {
4278
4499
  this.doSetActivePanel(panel);
4279
4500
  }
4280
- if (!skipSetGroupActive) {
4281
- this.accessor.doSetGroupActive(this.groupPanel, !!options.skipFocus);
4501
+ if (!options.skipSetGroupActive) {
4502
+ this.accessor.doSetGroupActive(this.groupPanel);
4503
+ }
4504
+ if (!options.skipSetActive) {
4505
+ this.updateContainer();
4282
4506
  }
4283
- this.updateContainer();
4284
4507
  }
4285
- removePanel(groupItemOrId) {
4508
+ removePanel(groupItemOrId, options = {
4509
+ skipSetActive: false,
4510
+ }) {
4286
4511
  const id = typeof groupItemOrId === 'string'
4287
4512
  ? groupItemOrId
4288
4513
  : groupItemOrId.id;
@@ -4290,7 +4515,7 @@
4290
4515
  if (!panelToRemove) {
4291
4516
  throw new Error('invalid operation');
4292
4517
  }
4293
- return this._removePanel(panelToRemove);
4518
+ return this._removePanel(panelToRemove, options);
4294
4519
  }
4295
4520
  closeAllPanels() {
4296
4521
  if (this.panels.length > 0) {
@@ -4316,12 +4541,8 @@
4316
4541
  updateActions(element) {
4317
4542
  this.tabsContainer.setRightActionsElement(element);
4318
4543
  }
4319
- setActive(isGroupActive, skipFocus = false, force = false) {
4320
- var _a, _b, _c, _d;
4544
+ setActive(isGroupActive, force = false) {
4321
4545
  if (!force && this.isActive === isGroupActive) {
4322
- if (!skipFocus) {
4323
- (_b = (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a);
4324
- }
4325
4546
  return;
4326
4547
  }
4327
4548
  this._isGroupActive = isGroupActive;
@@ -4332,11 +4553,6 @@
4332
4553
  this.doSetActivePanel(this.panels[0]);
4333
4554
  }
4334
4555
  this.updateContainer();
4335
- if (isGroupActive) {
4336
- if (!skipFocus) {
4337
- (_d = (_c = this._activePanel) === null || _c === void 0 ? void 0 : _c.focus) === null || _d === void 0 ? void 0 : _d.call(_c);
4338
- }
4339
- }
4340
4556
  }
4341
4557
  layout(width, height) {
4342
4558
  var _a;
@@ -4347,17 +4563,22 @@
4347
4563
  this._activePanel.layout(this._width, this._height);
4348
4564
  }
4349
4565
  }
4350
- _removePanel(panel) {
4566
+ _removePanel(panel, options) {
4351
4567
  const isActivePanel = this._activePanel === panel;
4352
4568
  this.doRemovePanel(panel);
4353
4569
  if (isActivePanel && this.panels.length > 0) {
4354
4570
  const nextPanel = this.mostRecentlyUsed[0];
4355
- this.openPanel(nextPanel);
4571
+ this.openPanel(nextPanel, {
4572
+ skipSetActive: options.skipSetActive,
4573
+ skipSetGroupActive: options.skipSetActiveGroup,
4574
+ });
4356
4575
  }
4357
4576
  if (this._activePanel && this.panels.length === 0) {
4358
4577
  this.doSetActivePanel(undefined);
4359
4578
  }
4360
- this.updateContainer();
4579
+ if (!options.skipSetActive) {
4580
+ this.updateContainer();
4581
+ }
4361
4582
  return panel;
4362
4583
  }
4363
4584
  doRemovePanel(panel) {
@@ -4372,13 +4593,13 @@
4372
4593
  }
4373
4594
  this._onDidRemovePanel.fire({ panel });
4374
4595
  }
4375
- doAddPanel(panel, index = this.panels.length, skipSetActive = false) {
4596
+ doAddPanel(panel, index = this.panels.length, options = { skipSetActive: false }) {
4376
4597
  const existingPanel = this._panels.indexOf(panel);
4377
4598
  const hasExistingPanel = existingPanel > -1;
4378
4599
  this.tabsContainer.show();
4379
4600
  this.contentContainer.show();
4380
4601
  this.tabsContainer.openPanel(panel, index);
4381
- if (!skipSetActive) {
4602
+ if (!options.skipSetActive) {
4382
4603
  this.contentContainer.openPanel(panel);
4383
4604
  }
4384
4605
  if (hasExistingPanel) {
@@ -4390,12 +4611,17 @@
4390
4611
  this._onDidAddPanel.fire({ panel });
4391
4612
  }
4392
4613
  doSetActivePanel(panel) {
4614
+ if (this._activePanel === panel) {
4615
+ return;
4616
+ }
4393
4617
  this._activePanel = panel;
4394
4618
  if (panel) {
4395
4619
  this.tabsContainer.setActivePanel(panel);
4396
4620
  panel.layout(this._width, this._height);
4397
4621
  this.updateMru(panel);
4398
- this._onDidActivePanelChange.fire({ panel });
4622
+ this._onDidActivePanelChange.fire({
4623
+ panel,
4624
+ });
4399
4625
  }
4400
4626
  }
4401
4627
  updateMru(panel) {
@@ -4407,11 +4633,11 @@
4407
4633
  updateContainer() {
4408
4634
  var _a, _b;
4409
4635
  toggleClass(this.container, 'empty', this.isEmpty);
4410
- this.panels.forEach((panel) => panel.updateParentGroup(this.groupPanel, this.isActive));
4636
+ this.panels.forEach((panel) => panel.runEvents());
4411
4637
  if (this.isEmpty && !this.watermark) {
4412
4638
  const watermark = this.accessor.createWatermarkComponent();
4413
4639
  watermark.init({
4414
- containerApi: new DockviewApi(this.accessor),
4640
+ containerApi: this._api,
4415
4641
  group: this.groupPanel,
4416
4642
  });
4417
4643
  this.watermark = watermark;
@@ -4444,10 +4670,32 @@
4444
4670
  }
4445
4671
  return false;
4446
4672
  }
4447
- handleDropEvent(event, position, index) {
4673
+ handleDropEvent(type, event, position, index) {
4448
4674
  if (this.locked === 'no-drop-target') {
4449
4675
  return;
4450
4676
  }
4677
+ function getKind() {
4678
+ switch (type) {
4679
+ case 'header':
4680
+ return typeof index === 'number' ? 'tab' : 'header_space';
4681
+ case 'content':
4682
+ return 'content';
4683
+ }
4684
+ }
4685
+ const panel = typeof index === 'number' ? this.panels[index] : undefined;
4686
+ const willDropEvent = new DockviewWillDropEvent({
4687
+ nativeEvent: event,
4688
+ position,
4689
+ panel,
4690
+ getData: () => getPanelData(),
4691
+ kind: getKind(),
4692
+ group: this.groupPanel,
4693
+ api: this._api,
4694
+ });
4695
+ this._onWillDrop.fire(willDropEvent);
4696
+ if (willDropEvent.defaultPrevented) {
4697
+ return;
4698
+ }
4451
4699
  const data = getPanelData();
4452
4700
  if (data && data.viewId === this.accessor.id) {
4453
4701
  if (data.panelId === null) {
@@ -4480,12 +4728,14 @@
4480
4728
  });
4481
4729
  }
4482
4730
  else {
4483
- this._onDidDrop.fire({
4731
+ this._onDidDrop.fire(new DockviewDidDropEvent({
4484
4732
  nativeEvent: event,
4485
4733
  position,
4486
- index,
4734
+ panel,
4487
4735
  getData: () => getPanelData(),
4488
- });
4736
+ group: this.groupPanel,
4737
+ api: this._api,
4738
+ }));
4489
4739
  }
4490
4740
  }
4491
4741
  dispose() {
@@ -4493,6 +4743,7 @@
4493
4743
  super.dispose();
4494
4744
  (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
4495
4745
  (_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
4746
+ this.watermark = undefined;
4496
4747
  for (const panel of this.panels) {
4497
4748
  panel.dispose();
4498
4749
  }
@@ -4514,15 +4765,7 @@
4514
4765
  constructor(parentElement, disableResizing = false) {
4515
4766
  super();
4516
4767
  this._disableResizing = disableResizing;
4517
- if (parentElement) {
4518
- this._element = parentElement;
4519
- }
4520
- else {
4521
- this._element = document.createElement('div');
4522
- this._element.style.height = '100%';
4523
- this._element.style.width = '100%';
4524
- this._element.className = 'dv-resizable-container';
4525
- }
4768
+ this._element = parentElement;
4526
4769
  this.addDisposables(watchElementResize(this._element, (entry) => {
4527
4770
  if (this.isDisposed) {
4528
4771
  /**
@@ -4610,25 +4853,38 @@
4610
4853
  get activeGroup() {
4611
4854
  return this._activeGroup;
4612
4855
  }
4856
+ get locked() {
4857
+ return this.gridview.locked;
4858
+ }
4859
+ set locked(value) {
4860
+ this.gridview.locked = value;
4861
+ }
4613
4862
  constructor(options) {
4614
- super(options.parentElement, options.disableAutoResizing);
4863
+ super(document.createElement('div'), options.disableAutoResizing);
4615
4864
  this._id = nextLayoutId$1.next();
4616
4865
  this._groups = new Map();
4617
4866
  this._onDidLayoutChange = new Emitter();
4618
4867
  this.onDidLayoutChange = this._onDidLayoutChange.event;
4619
- this._onDidRemoveGroup = new Emitter();
4620
- this.onDidRemoveGroup = this._onDidRemoveGroup.event;
4621
- this._onDidAddGroup = new Emitter();
4622
- this.onDidAddGroup = this._onDidAddGroup.event;
4623
- this._onDidActiveGroupChange = new Emitter();
4624
- this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
4868
+ this._onDidRemove = new Emitter();
4869
+ this.onDidRemove = this._onDidRemove.event;
4870
+ this._onDidAdd = new Emitter();
4871
+ this.onDidAdd = this._onDidAdd.event;
4872
+ this._onDidActiveChange = new Emitter();
4873
+ this.onDidActiveChange = this._onDidActiveChange.event;
4625
4874
  this._bufferOnDidLayoutChange = new TickDelayedEvent();
4875
+ this.element.style.height = '100%';
4876
+ this.element.style.width = '100%';
4877
+ options.parentElement.appendChild(this.element);
4626
4878
  this.gridview = new Gridview(!!options.proportionalLayout, options.styles, options.orientation);
4879
+ this.gridview.locked = !!options.locked;
4627
4880
  this.element.appendChild(this.gridview.element);
4628
4881
  this.layout(0, 0, true); // set some elements height/widths
4629
- this.addDisposables(this.gridview.onDidChange(() => {
4882
+ this.addDisposables(Disposable.from(() => {
4883
+ var _a;
4884
+ (_a = this.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.element);
4885
+ }), this.gridview.onDidChange(() => {
4630
4886
  this._bufferOnDidLayoutChange.fire();
4631
- }), exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup, this.onDidActiveGroupChange)(() => {
4887
+ }), exports.DockviewEvent.any(this.onDidAdd, this.onDidRemove, this.onDidActiveChange)(() => {
4632
4888
  this._bufferOnDidLayoutChange.fire();
4633
4889
  }), this._bufferOnDidLayoutChange.onEvent(() => {
4634
4890
  this._onDidLayoutChange.fire();
@@ -4643,6 +4899,7 @@
4643
4899
  }
4644
4900
  maximizeGroup(panel) {
4645
4901
  this.gridview.maximizeView(panel);
4902
+ this.doSetGroupActive(panel);
4646
4903
  }
4647
4904
  isMaximizedGroup(panel) {
4648
4905
  return this.gridview.maximizedView() === panel;
@@ -4653,13 +4910,12 @@
4653
4910
  hasMaximizedGroup() {
4654
4911
  return this.gridview.hasMaximizedView();
4655
4912
  }
4656
- get onDidMaxmizedGroupChange() {
4657
- return this.gridview.onDidMaxmizedNodeChange;
4913
+ get onDidMaximizedGroupChange() {
4914
+ return this.gridview.onDidMaximizedNodeChange;
4658
4915
  }
4659
4916
  doAddGroup(group, location = [0], size) {
4660
4917
  this.gridview.addView(group, size !== null && size !== void 0 ? size : exports.Sizing.Distribute, location);
4661
- this._onDidAddGroup.fire(group);
4662
- this.doSetGroupActive(group);
4918
+ this._onDidAdd.fire(group);
4663
4919
  }
4664
4920
  doRemoveGroup(group, options) {
4665
4921
  if (!this._groups.has(group.id)) {
@@ -4671,8 +4927,8 @@
4671
4927
  item.disposable.dispose();
4672
4928
  item.value.dispose();
4673
4929
  this._groups.delete(group.id);
4930
+ this._onDidRemove.fire(group);
4674
4931
  }
4675
- this._onDidRemoveGroup.fire(group);
4676
4932
  if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
4677
4933
  const groups = Array.from(this._groups.values());
4678
4934
  this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
@@ -4683,25 +4939,18 @@
4683
4939
  var _a;
4684
4940
  return (_a = this._groups.get(id)) === null || _a === void 0 ? void 0 : _a.value;
4685
4941
  }
4686
- doSetGroupActive(group, skipFocus) {
4687
- var _a, _b, _c;
4942
+ doSetGroupActive(group) {
4688
4943
  if (this._activeGroup === group) {
4689
4944
  return;
4690
4945
  }
4691
4946
  if (this._activeGroup) {
4692
4947
  this._activeGroup.setActive(false);
4693
- if (!skipFocus) {
4694
- (_b = (_a = this._activeGroup).focus) === null || _b === void 0 ? void 0 : _b.call(_a);
4695
- }
4696
4948
  }
4697
4949
  if (group) {
4698
4950
  group.setActive(true);
4699
- if (!skipFocus) {
4700
- (_c = group.focus) === null || _c === void 0 ? void 0 : _c.call(group);
4701
- }
4702
4951
  }
4703
4952
  this._activeGroup = group;
4704
- this._onDidActiveGroupChange.fire(group);
4953
+ this._onDidActiveChange.fire(group);
4705
4954
  }
4706
4955
  removeGroup(group) {
4707
4956
  this.doRemoveGroup(group);
@@ -4746,9 +4995,9 @@
4746
4995
  this.gridview.layout(width, height);
4747
4996
  }
4748
4997
  dispose() {
4749
- this._onDidActiveGroupChange.dispose();
4750
- this._onDidAddGroup.dispose();
4751
- this._onDidRemoveGroup.dispose();
4998
+ this._onDidActiveChange.dispose();
4999
+ this._onDidAdd.dispose();
5000
+ this._onDidRemove.dispose();
4752
5001
  this._onDidLayoutChange.dispose();
4753
5002
  for (const group of this.groups) {
4754
5003
  group.dispose();
@@ -4758,11 +5007,15 @@
4758
5007
  }
4759
5008
  }
4760
5009
 
5010
+ class WillFocusEvent extends DockviewEvent {
5011
+ constructor() {
5012
+ super();
5013
+ }
5014
+ }
4761
5015
  /**
4762
5016
  * A core api implementation that should be used across all panel-like objects
4763
5017
  */
4764
5018
  class PanelApiImpl extends CompositeDisposable {
4765
- //
4766
5019
  get isFocused() {
4767
5020
  return this._isFocused;
4768
5021
  }
@@ -4787,35 +5040,22 @@
4787
5040
  this._width = 0;
4788
5041
  this._height = 0;
4789
5042
  this.panelUpdatesDisposable = new MutableDisposable();
4790
- this._onDidDimensionChange = new Emitter({
4791
- replay: true,
4792
- });
5043
+ this._onDidDimensionChange = new Emitter();
4793
5044
  this.onDidDimensionsChange = this._onDidDimensionChange.event;
4794
- //
4795
- this._onDidChangeFocus = new Emitter({
4796
- replay: true,
4797
- });
5045
+ this._onDidChangeFocus = new Emitter();
4798
5046
  this.onDidFocusChange = this._onDidChangeFocus.event;
4799
5047
  //
4800
- this._onFocusEvent = new Emitter();
4801
- this.onFocusEvent = this._onFocusEvent.event;
5048
+ this._onWillFocus = new Emitter();
5049
+ this.onWillFocus = this._onWillFocus.event;
4802
5050
  //
4803
- this._onDidVisibilityChange = new Emitter({
4804
- replay: true,
4805
- });
5051
+ this._onDidVisibilityChange = new Emitter();
4806
5052
  this.onDidVisibilityChange = this._onDidVisibilityChange.event;
4807
- //
4808
- this._onVisibilityChange = new Emitter();
4809
- this.onVisibilityChange = this._onVisibilityChange.event;
4810
- //
4811
- this._onDidActiveChange = new Emitter({
4812
- replay: true,
4813
- });
5053
+ this._onWillVisibilityChange = new Emitter();
5054
+ this.onWillVisibilityChange = this._onWillVisibilityChange.event;
5055
+ this._onDidActiveChange = new Emitter();
4814
5056
  this.onDidActiveChange = this._onDidActiveChange.event;
4815
- //
4816
5057
  this._onActiveChange = new Emitter();
4817
5058
  this.onActiveChange = this._onActiveChange.event;
4818
- //
4819
5059
  this._onUpdateParameters = new Emitter();
4820
5060
  this.onUpdateParameters = this._onUpdateParameters.event;
4821
5061
  this.addDisposables(this.onDidFocusChange((event) => {
@@ -4827,7 +5067,7 @@
4827
5067
  }), this.onDidDimensionsChange((event) => {
4828
5068
  this._width = event.width;
4829
5069
  this._height = event.height;
4830
- }), this.panelUpdatesDisposable, this._onDidDimensionChange, this._onDidChangeFocus, this._onDidVisibilityChange, this._onDidActiveChange, this._onFocusEvent, this._onActiveChange, this._onVisibilityChange, this._onUpdateParameters);
5070
+ }), this.panelUpdatesDisposable, this._onDidDimensionChange, this._onDidChangeFocus, this._onDidVisibilityChange, this._onDidActiveChange, this._onWillFocus, this._onActiveChange, this._onUpdateParameters, this._onWillFocus, this._onWillVisibilityChange, this._onUpdateParameters);
4831
5071
  }
4832
5072
  initialize(panel) {
4833
5073
  this.panelUpdatesDisposable.value = this._onUpdateParameters.event((parameters) => {
@@ -4837,7 +5077,7 @@
4837
5077
  });
4838
5078
  }
4839
5079
  setVisible(isVisible) {
4840
- this._onVisibilityChange.fire({ isVisible });
5080
+ this._onWillVisibilityChange.fire({ isVisible });
4841
5081
  }
4842
5082
  setActive() {
4843
5083
  this._onActiveChange.fire();
@@ -4845,9 +5085,6 @@
4845
5085
  updateParameters(parameters) {
4846
5086
  this._onUpdateParameters.fire(parameters);
4847
5087
  }
4848
- dispose() {
4849
- super.dispose();
4850
- }
4851
5088
  }
4852
5089
 
4853
5090
  class SplitviewPanelApiImpl extends PanelApiImpl {
@@ -4935,7 +5172,12 @@
4935
5172
  }), focusTracker);
4936
5173
  }
4937
5174
  focus() {
4938
- this.api._onFocusEvent.fire();
5175
+ const event = new WillFocusEvent();
5176
+ this.api._onWillFocus.fire(event);
5177
+ if (event.defaultPrevented) {
5178
+ return;
5179
+ }
5180
+ this._element.focus();
4939
5181
  }
4940
5182
  layout(width, height) {
4941
5183
  this._width = width;
@@ -5053,7 +5295,11 @@
5053
5295
  this._onDidChangeExpansionState.fire(this.isExpanded()); // initialize value
5054
5296
  this._orientation = orientation;
5055
5297
  this.element.classList.add('pane');
5056
- this.addDisposables(this.api.onDidSizeChange((event) => {
5298
+ this.addDisposables(this.api.onWillVisibilityChange((event) => {
5299
+ const { isVisible } = event;
5300
+ const { accessor } = this._params;
5301
+ accessor.setVisible(this, isVisible);
5302
+ }), this.api.onDidSizeChange((event) => {
5057
5303
  this._onDidChange.fire({ size: event.size });
5058
5304
  }), addDisposableListener(this.element, 'mouseenter', (ev) => {
5059
5305
  this.api._onMouseEnter.fire(ev);
@@ -5264,9 +5510,7 @@
5264
5510
  super(id);
5265
5511
  this._onDidConstraintsChangeInternal = new Emitter();
5266
5512
  this.onDidConstraintsChangeInternal = this._onDidConstraintsChangeInternal.event;
5267
- this._onDidConstraintsChange = new Emitter({
5268
- replay: true,
5269
- });
5513
+ this._onDidConstraintsChange = new Emitter();
5270
5514
  this.onDidConstraintsChange = this._onDidConstraintsChange.event;
5271
5515
  this._onDidSizeChange = new Emitter();
5272
5516
  this.onDidSizeChange = this._onDidSizeChange.event;
@@ -5359,13 +5603,13 @@
5359
5603
  this._maximumHeight = options.maximumHeight;
5360
5604
  }
5361
5605
  this.api.initialize(this); // TODO: required to by-pass 'super before this' requirement
5362
- this.addDisposables(this.api.onVisibilityChange((event) => {
5606
+ this.addDisposables(this.api.onWillVisibilityChange((event) => {
5363
5607
  const { isVisible } = event;
5364
5608
  const { accessor } = this._params;
5365
5609
  accessor.setVisible(this, isVisible);
5366
5610
  }), this.api.onActiveChange(() => {
5367
5611
  const { accessor } = this._params;
5368
- accessor.setActive(this);
5612
+ accessor.doSetGroupActive(this);
5369
5613
  }), this.api.onDidConstraintsChangeInternal((event) => {
5370
5614
  if (typeof event.minimumWidth === 'number' ||
5371
5615
  typeof event.minimumWidth === 'function') {
@@ -5448,6 +5692,17 @@
5448
5692
  this.onDidLocationChange = this._onDidLocationChange.event;
5449
5693
  this.addDisposables(this._onDidLocationChange);
5450
5694
  }
5695
+ close() {
5696
+ if (!this._group) {
5697
+ return;
5698
+ }
5699
+ return this.accessor.removeGroup(this._group);
5700
+ }
5701
+ getWindow() {
5702
+ return this.location.type === 'popout'
5703
+ ? this.location.getWindow()
5704
+ : window;
5705
+ }
5451
5706
  moveTo(options) {
5452
5707
  var _a, _b, _c;
5453
5708
  if (!this._group) {
@@ -5455,14 +5710,23 @@
5455
5710
  }
5456
5711
  const group = (_a = options.group) !== null && _a !== void 0 ? _a : this.accessor.addGroup({
5457
5712
  direction: positionToDirection((_b = options.position) !== null && _b !== void 0 ? _b : 'right'),
5713
+ skipSetActive: true,
5714
+ });
5715
+ this.accessor.moveGroupOrPanel({
5716
+ from: { groupId: this._group.id },
5717
+ to: {
5718
+ group,
5719
+ position: options.group
5720
+ ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center'
5721
+ : 'center',
5722
+ },
5458
5723
  });
5459
- this.accessor.moveGroupOrPanel(group, this._group.id, undefined, options.group ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center' : 'center');
5460
5724
  }
5461
5725
  maximize() {
5462
5726
  if (!this._group) {
5463
5727
  throw new Error(NOT_INITIALIZED_MESSAGE);
5464
5728
  }
5465
- if (this.location !== 'grid') {
5729
+ if (this.location.type !== 'grid') {
5466
5730
  // only grid groups can be maximized
5467
5731
  return;
5468
5732
  }
@@ -5519,6 +5783,12 @@
5519
5783
  this.api.initialize(this); // cannot use 'this' after after 'super' call
5520
5784
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
5521
5785
  }
5786
+ focus() {
5787
+ if (!this.api.isActive) {
5788
+ this.api.setActive();
5789
+ }
5790
+ super.focus();
5791
+ }
5522
5792
  initialize() {
5523
5793
  this._model.initialize();
5524
5794
  }
@@ -5564,6 +5834,9 @@
5564
5834
  }
5565
5835
 
5566
5836
  class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5837
+ get location() {
5838
+ return this.group.api.location;
5839
+ }
5567
5840
  get title() {
5568
5841
  return this.panel.title;
5569
5842
  }
@@ -5574,16 +5847,14 @@
5574
5847
  return this.panel.renderer;
5575
5848
  }
5576
5849
  set group(value) {
5577
- const isOldGroupActive = this.isGroupActive;
5578
- this._group = value;
5579
- this._onDidGroupChange.fire();
5580
- if (this._group) {
5581
- this.disposable.value = this._group.api.onDidActiveChange(() => {
5582
- this._onDidActiveGroupChange.fire();
5850
+ const oldGroup = this._group;
5851
+ if (this._group !== value) {
5852
+ this._group = value;
5853
+ this._onDidGroupChange.fire({});
5854
+ this.setupGroupEventListeners(oldGroup);
5855
+ this._onDidLocationChange.fire({
5856
+ location: this.group.api.location,
5583
5857
  });
5584
- if (this.isGroupActive !== isOldGroupActive) {
5585
- this._onDidActiveGroupChange.fire();
5586
- }
5587
5858
  }
5588
5859
  }
5589
5860
  get group() {
@@ -5601,14 +5872,27 @@
5601
5872
  this.onDidGroupChange = this._onDidGroupChange.event;
5602
5873
  this._onDidRendererChange = new Emitter();
5603
5874
  this.onDidRendererChange = this._onDidRendererChange.event;
5604
- this.disposable = new MutableDisposable();
5875
+ this._onDidLocationChange = new Emitter();
5876
+ this.onDidLocationChange = this._onDidLocationChange.event;
5877
+ this.groupEventsDisposable = new MutableDisposable();
5605
5878
  this.initialize(panel);
5606
5879
  this._group = group;
5607
- this.addDisposables(this.disposable, this._onDidRendererChange, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5880
+ this.setupGroupEventListeners();
5881
+ this.addDisposables(this.groupEventsDisposable, this._onDidRendererChange, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange, this._onDidLocationChange);
5882
+ }
5883
+ getWindow() {
5884
+ return this.group.api.getWindow();
5608
5885
  }
5609
5886
  moveTo(options) {
5610
5887
  var _a;
5611
- this.accessor.moveGroupOrPanel(options.group, this._group.id, this.panel.id, (_a = options.position) !== null && _a !== void 0 ? _a : 'center', options.index);
5888
+ this.accessor.moveGroupOrPanel({
5889
+ from: { groupId: this._group.id, panelId: this.panel.id },
5890
+ to: {
5891
+ group: options.group,
5892
+ position: (_a = options.position) !== null && _a !== void 0 ? _a : 'center',
5893
+ index: options.index,
5894
+ },
5895
+ });
5612
5896
  }
5613
5897
  setTitle(title) {
5614
5898
  this.panel.setTitle(title);
@@ -5628,6 +5912,35 @@
5628
5912
  exitMaximized() {
5629
5913
  this.group.api.exitMaximized();
5630
5914
  }
5915
+ setupGroupEventListeners(previousGroup) {
5916
+ var _a;
5917
+ let _trackGroupActive = (_a = previousGroup === null || previousGroup === void 0 ? void 0 : previousGroup.isActive) !== null && _a !== void 0 ? _a : false; // prevent duplicate events with same state
5918
+ this.groupEventsDisposable.value = new CompositeDisposable(this.group.api.onDidVisibilityChange((event) => {
5919
+ if (!event.isVisible && this.isVisible) {
5920
+ this._onDidVisibilityChange.fire(event);
5921
+ }
5922
+ else if (event.isVisible &&
5923
+ !this.isVisible &&
5924
+ this.group.model.isPanelActive(this.panel)) {
5925
+ this._onDidVisibilityChange.fire(event);
5926
+ }
5927
+ }), this.group.api.onDidLocationChange((event) => {
5928
+ if (this.group !== this.panel.group) {
5929
+ return;
5930
+ }
5931
+ this._onDidLocationChange.fire(event);
5932
+ }), this.group.api.onDidActiveChange(() => {
5933
+ if (this.group !== this.panel.group) {
5934
+ return;
5935
+ }
5936
+ if (_trackGroupActive !== this.isGroupActive) {
5937
+ _trackGroupActive = this.isGroupActive;
5938
+ this._onDidActiveGroupChange.fire({
5939
+ isActive: this.isGroupActive,
5940
+ });
5941
+ }
5942
+ }));
5943
+ }
5631
5944
  }
5632
5945
 
5633
5946
  class DockviewPanel extends CompositeDisposable {
@@ -5669,7 +5982,14 @@
5669
5982
  this.setTitle(params.title);
5670
5983
  }
5671
5984
  focus() {
5672
- this.api._onFocusEvent.fire();
5985
+ const event = new WillFocusEvent();
5986
+ this.api._onWillFocus.fire(event);
5987
+ if (event.defaultPrevented) {
5988
+ return;
5989
+ }
5990
+ if (!this.api.isActive) {
5991
+ this.api.setActive();
5992
+ }
5673
5993
  }
5674
5994
  toJSON() {
5675
5995
  return {
@@ -5726,24 +6046,44 @@
5726
6046
  },
5727
6047
  });
5728
6048
  }
5729
- updateParentGroup(group, isGroupActive) {
6049
+ updateParentGroup(group, options) {
5730
6050
  this._group = group;
5731
- this.api.group = group;
6051
+ this.api.group = this._group;
5732
6052
  const isPanelVisible = this._group.model.isPanelActive(this);
5733
- this.api._onDidActiveChange.fire({
5734
- isActive: isGroupActive && isPanelVisible,
5735
- });
5736
- this.api._onDidVisibilityChange.fire({
5737
- isVisible: isPanelVisible,
5738
- });
5739
- this.view.updateParentGroup(this._group, this._group.model.isPanelActive(this));
6053
+ const isActive = this.group.api.isActive && isPanelVisible;
6054
+ if (!(options === null || options === void 0 ? void 0 : options.skipSetActive)) {
6055
+ if (this.api.isActive !== isActive) {
6056
+ this.api._onDidActiveChange.fire({
6057
+ isActive: this.group.api.isActive && isPanelVisible,
6058
+ });
6059
+ }
6060
+ }
6061
+ if (this.api.isVisible !== isPanelVisible) {
6062
+ this.api._onDidVisibilityChange.fire({
6063
+ isVisible: isPanelVisible,
6064
+ });
6065
+ }
5740
6066
  }
5741
- layout(width, height) {
5742
- // the obtain the correct dimensions of the content panel we must deduct the tab height
5743
- this.api._onDidDimensionChange.fire({
5744
- width,
5745
- height: height,
5746
- });
6067
+ runEvents() {
6068
+ const isPanelVisible = this._group.model.isPanelActive(this);
6069
+ const isActive = this.group.api.isActive && isPanelVisible;
6070
+ if (this.api.isActive !== isActive) {
6071
+ this.api._onDidActiveChange.fire({
6072
+ isActive: this.group.api.isActive && isPanelVisible,
6073
+ });
6074
+ }
6075
+ if (this.api.isVisible !== isPanelVisible) {
6076
+ this.api._onDidVisibilityChange.fire({
6077
+ isVisible: isPanelVisible,
6078
+ });
6079
+ }
6080
+ }
6081
+ layout(width, height) {
6082
+ // TODO: Can we somehow do height without header height or indicate what the header height is?
6083
+ this.api._onDidDimensionChange.fire({
6084
+ width,
6085
+ height: height,
6086
+ });
5747
6087
  this.view.layout(width, height);
5748
6088
  }
5749
6089
  dispose() {
@@ -5861,8 +6201,6 @@
5861
6201
  this.id = id;
5862
6202
  this.contentComponent = contentComponent;
5863
6203
  this.tabComponent = tabComponent;
5864
- this._group = null;
5865
- this._isPanelVisible = null;
5866
6204
  this._content = this.createContentComponent(this.id, contentComponent);
5867
6205
  this._tab = this.createTabComponent(this.id, tabComponent);
5868
6206
  }
@@ -5870,25 +6208,8 @@
5870
6208
  this.content.init(Object.assign(Object.assign({}, params), { tab: this.tab }));
5871
6209
  this.tab.init(params);
5872
6210
  }
5873
- updateParentGroup(group, isPanelVisible) {
5874
- if (group !== this._group) {
5875
- this._group = group;
5876
- if (this._content.onGroupChange) {
5877
- this._content.onGroupChange(group);
5878
- }
5879
- if (this._tab.onGroupChange) {
5880
- this._tab.onGroupChange(group);
5881
- }
5882
- }
5883
- if (isPanelVisible !== this._isPanelVisible) {
5884
- this._isPanelVisible = isPanelVisible;
5885
- if (this._content.onPanelVisibleChange) {
5886
- this._content.onPanelVisibleChange(isPanelVisible);
5887
- }
5888
- if (this._tab.onPanelVisibleChange) {
5889
- this._tab.onPanelVisibleChange(isPanelVisible);
5890
- }
5891
- }
6211
+ updateParentGroup(_group, _isPanelVisible) {
6212
+ // noop
5892
6213
  }
5893
6214
  layout(width, height) {
5894
6215
  var _a, _b;
@@ -6321,117 +6642,6 @@
6321
6642
  }
6322
6643
  }
6323
6644
 
6324
- class PopoutWindow extends CompositeDisposable {
6325
- constructor(id, className, options) {
6326
- super();
6327
- this.id = id;
6328
- this.className = className;
6329
- this.options = options;
6330
- this._onDidClose = new Emitter();
6331
- this.onDidClose = this._onDidClose.event;
6332
- this._window = null;
6333
- this.addDisposables(this._onDidClose, {
6334
- dispose: () => {
6335
- this.close();
6336
- },
6337
- });
6338
- }
6339
- dimensions() {
6340
- if (!this._window) {
6341
- return null;
6342
- }
6343
- const left = this._window.value.screenX;
6344
- const top = this._window.value.screenY;
6345
- const width = this._window.value.innerWidth;
6346
- const height = this._window.value.innerHeight;
6347
- return { top, left, width, height };
6348
- }
6349
- close() {
6350
- if (this._window) {
6351
- this._window.disposable.dispose();
6352
- this._window.value.close();
6353
- this._window = null;
6354
- }
6355
- }
6356
- open(content) {
6357
- if (this._window) {
6358
- throw new Error('instance of popout window is already open');
6359
- }
6360
- const url = `${this.options.url}`;
6361
- const features = Object.entries({
6362
- top: this.options.top,
6363
- left: this.options.left,
6364
- width: this.options.width,
6365
- height: this.options.height,
6366
- })
6367
- .map(([key, value]) => `${key}=${value}`)
6368
- .join(',');
6369
- // https://developer.mozilla.org/en-US/docs/Web/API/Window/open
6370
- const externalWindow = window.open(url, this.id, features);
6371
- if (!externalWindow) {
6372
- return;
6373
- }
6374
- const disposable = new CompositeDisposable();
6375
- this._window = { value: externalWindow, disposable };
6376
- const cleanUp = () => {
6377
- this._onDidClose.fire();
6378
- this._window = null;
6379
- };
6380
- // prevent any default content from loading
6381
- // externalWindow.document.body.replaceWith(document.createElement('div'));
6382
- disposable.addDisposables(addDisposableWindowListener(window, 'beforeunload', () => {
6383
- cleanUp();
6384
- this.close();
6385
- }));
6386
- externalWindow.addEventListener('load', () => {
6387
- const externalDocument = externalWindow.document;
6388
- externalDocument.title = document.title;
6389
- const div = document.createElement('div');
6390
- div.classList.add('dv-popout-window');
6391
- div.style.position = 'absolute';
6392
- div.style.width = '100%';
6393
- div.style.height = '100%';
6394
- div.style.top = '0px';
6395
- div.style.left = '0px';
6396
- div.classList.add(this.className);
6397
- div.appendChild(content);
6398
- externalDocument.body.replaceChildren(div);
6399
- externalDocument.body.classList.add(this.className);
6400
- addStyles(externalDocument, window.document.styleSheets);
6401
- externalWindow.addEventListener('beforeunload', () => {
6402
- // TODO: indicate external window is closing
6403
- cleanUp();
6404
- });
6405
- });
6406
- }
6407
- }
6408
-
6409
- class DockviewPopoutGroupPanel extends CompositeDisposable {
6410
- constructor(id, group, options) {
6411
- var _a;
6412
- super();
6413
- this.id = id;
6414
- this.group = group;
6415
- this.options = options;
6416
- this.window = new PopoutWindow(id, (_a = options.className) !== null && _a !== void 0 ? _a : '', {
6417
- url: this.options.popoutUrl,
6418
- left: this.options.box.left,
6419
- top: this.options.box.top,
6420
- width: this.options.box.width,
6421
- height: this.options.box.height,
6422
- });
6423
- group.model.location = 'popout';
6424
- this.addDisposables(this.window, {
6425
- dispose: () => {
6426
- group.model.location = 'grid';
6427
- },
6428
- }, this.window.onDidClose(() => {
6429
- this.dispose();
6430
- }));
6431
- this.window.open(group.element);
6432
- }
6433
- }
6434
-
6435
6645
  const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
6436
6646
  const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100 };
6437
6647
 
@@ -6445,11 +6655,13 @@
6445
6655
  super();
6446
6656
  this.element = element;
6447
6657
  this.map = {};
6658
+ this._disposed = false;
6448
6659
  this.addDisposables(Disposable.from(() => {
6449
6660
  for (const value of Object.values(this.map)) {
6450
6661
  value.disposable.dispose();
6451
6662
  value.destroy.dispose();
6452
6663
  }
6664
+ this._disposed = true;
6453
6665
  }));
6454
6666
  }
6455
6667
  detatch(panel) {
@@ -6489,7 +6701,7 @@
6489
6701
  focusContainer.style.top = `${box.top - box2.top}px`;
6490
6702
  focusContainer.style.width = `${box.width}px`;
6491
6703
  focusContainer.style.height = `${box.height}px`;
6492
- toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location === 'floating');
6704
+ toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location.type === 'floating');
6493
6705
  };
6494
6706
  const visibilityChanged = () => {
6495
6707
  if (panel.api.isVisible) {
@@ -6535,8 +6747,11 @@
6535
6747
  resize();
6536
6748
  }));
6537
6749
  this.map[panel.api.id].destroy = Disposable.from(() => {
6538
- focusContainer.removeChild(panel.view.content.element);
6539
- this.element.removeChild(focusContainer);
6750
+ var _a;
6751
+ if (panel.view.content.element.parentElement === focusContainer) {
6752
+ focusContainer.removeChild(panel.view.content.element);
6753
+ }
6754
+ (_a = focusContainer.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(focusContainer);
6540
6755
  });
6541
6756
  queueMicrotask(() => {
6542
6757
  if (this.isDisposed) {
@@ -6557,11 +6772,164 @@
6557
6772
  }
6558
6773
  }
6559
6774
 
6775
+ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
6776
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6777
+ return new (P || (P = Promise))(function (resolve, reject) {
6778
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6779
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6780
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
6781
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
6782
+ });
6783
+ };
6784
+ class PopoutWindow extends CompositeDisposable {
6785
+ get window() {
6786
+ var _a, _b;
6787
+ return (_b = (_a = this._window) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null;
6788
+ }
6789
+ constructor(target, className, options) {
6790
+ super();
6791
+ this.target = target;
6792
+ this.className = className;
6793
+ this.options = options;
6794
+ this._onWillClose = new Emitter();
6795
+ this.onWillClose = this._onWillClose.event;
6796
+ this._onDidClose = new Emitter();
6797
+ this.onDidClose = this._onDidClose.event;
6798
+ this._window = null;
6799
+ this.addDisposables(this._onWillClose, this._onDidClose, {
6800
+ dispose: () => {
6801
+ this.close();
6802
+ },
6803
+ });
6804
+ }
6805
+ dimensions() {
6806
+ if (!this._window) {
6807
+ return null;
6808
+ }
6809
+ const left = this._window.value.screenX;
6810
+ const top = this._window.value.screenY;
6811
+ const width = this._window.value.innerWidth;
6812
+ const height = this._window.value.innerHeight;
6813
+ return { top, left, width, height };
6814
+ }
6815
+ close() {
6816
+ var _a, _b;
6817
+ if (this._window) {
6818
+ this._onWillClose.fire();
6819
+ (_b = (_a = this.options).onWillClose) === null || _b === void 0 ? void 0 : _b.call(_a, {
6820
+ id: this.target,
6821
+ window: this._window.value,
6822
+ });
6823
+ this._window.disposable.dispose();
6824
+ this._window.value.close();
6825
+ this._window = null;
6826
+ this._onDidClose.fire();
6827
+ }
6828
+ }
6829
+ open() {
6830
+ var _a, _b;
6831
+ return __awaiter(this, void 0, void 0, function* () {
6832
+ if (this._window) {
6833
+ throw new Error('instance of popout window is already open');
6834
+ }
6835
+ const url = `${this.options.url}`;
6836
+ const features = Object.entries({
6837
+ top: this.options.top,
6838
+ left: this.options.left,
6839
+ width: this.options.width,
6840
+ height: this.options.height,
6841
+ })
6842
+ .map(([key, value]) => `${key}=${value}`)
6843
+ .join(',');
6844
+ /**
6845
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open
6846
+ */
6847
+ const externalWindow = window.open(url, this.target, features);
6848
+ if (!externalWindow) {
6849
+ /**
6850
+ * Popup blocked
6851
+ */
6852
+ return null;
6853
+ }
6854
+ const disposable = new CompositeDisposable();
6855
+ this._window = { value: externalWindow, disposable };
6856
+ disposable.addDisposables(addDisposableWindowListener(window, 'beforeunload', () => {
6857
+ /**
6858
+ * before the main window closes we should close this popup too
6859
+ * to be good citizens
6860
+ *
6861
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
6862
+ */
6863
+ this.close();
6864
+ }));
6865
+ const container = this.createPopoutWindowContainer();
6866
+ if (this.className) {
6867
+ container.classList.add(this.className);
6868
+ }
6869
+ (_b = (_a = this.options).onDidOpen) === null || _b === void 0 ? void 0 : _b.call(_a, {
6870
+ id: this.target,
6871
+ window: externalWindow,
6872
+ });
6873
+ return new Promise((resolve) => {
6874
+ externalWindow.addEventListener('unload', (e) => {
6875
+ // if page fails to load before unloading
6876
+ // this.close();
6877
+ });
6878
+ externalWindow.addEventListener('load', () => {
6879
+ /**
6880
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
6881
+ */
6882
+ const externalDocument = externalWindow.document;
6883
+ externalDocument.title = document.title;
6884
+ externalDocument.body.appendChild(container);
6885
+ addStyles(externalDocument, window.document.styleSheets);
6886
+ /**
6887
+ * beforeunload must be registered after load for reasons I could not determine
6888
+ * otherwise the beforeunload event will not fire when the window is closed
6889
+ */
6890
+ addDisposableWindowListener(externalWindow, 'beforeunload', () => {
6891
+ /**
6892
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
6893
+ */
6894
+ this.close();
6895
+ });
6896
+ resolve(container);
6897
+ });
6898
+ });
6899
+ });
6900
+ }
6901
+ createPopoutWindowContainer() {
6902
+ const el = document.createElement('div');
6903
+ el.classList.add('dv-popout-window');
6904
+ el.id = 'dv-popout-window';
6905
+ el.style.position = 'absolute';
6906
+ el.style.width = '100%';
6907
+ el.style.height = '100%';
6908
+ el.style.top = '0px';
6909
+ el.style.left = '0px';
6910
+ return el;
6911
+ }
6912
+ }
6913
+
6560
6914
  const DEFAULT_ROOT_OVERLAY_MODEL = {
6561
6915
  activationSize: { type: 'pixels', value: 10 },
6562
6916
  size: { type: 'pixels', value: 20 },
6563
6917
  };
6564
- function getTheme(element) {
6918
+ function moveGroupWithoutDestroying(options) {
6919
+ const activePanel = options.from.activePanel;
6920
+ const panels = [...options.from.panels].map((panel) => {
6921
+ const removedPanel = options.from.model.removePanel(panel);
6922
+ options.from.model.renderContainer.detatch(panel);
6923
+ return removedPanel;
6924
+ });
6925
+ panels.forEach((panel) => {
6926
+ options.to.model.openPanel(panel, {
6927
+ skipSetActive: activePanel !== panel,
6928
+ skipSetGroupActive: true,
6929
+ });
6930
+ });
6931
+ }
6932
+ function getDockviewTheme(element) {
6565
6933
  function toClassList(element) {
6566
6934
  const list = [];
6567
6935
  for (let i = 0; i < element.classList.length; i++) {
@@ -6612,6 +6980,7 @@
6612
6980
  styles: options.styles,
6613
6981
  parentElement: options.parentElement,
6614
6982
  disableAutoResizing: options.disableAutoResizing,
6983
+ locked: options.locked,
6615
6984
  });
6616
6985
  this.nextGroupId = sequentialNumberGenerator();
6617
6986
  this._deserializer = new DefaultDockviewDeserialzier(this);
@@ -6622,6 +6991,10 @@
6622
6991
  this.onWillDragGroup = this._onWillDragGroup.event;
6623
6992
  this._onDidDrop = new Emitter();
6624
6993
  this.onDidDrop = this._onDidDrop.event;
6994
+ this._onWillDrop = new Emitter();
6995
+ this.onWillDrop = this._onWillDrop.event;
6996
+ this._onWillShowOverlay = new Emitter();
6997
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
6625
6998
  this._onDidRemovePanel = new Emitter();
6626
6999
  this.onDidRemovePanel = this._onDidRemovePanel.event;
6627
7000
  this._onDidAddPanel = new Emitter();
@@ -6630,15 +7003,36 @@
6630
7003
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
6631
7004
  this._onDidActivePanelChange = new Emitter();
6632
7005
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
7006
+ this._onDidMovePanel = new Emitter();
6633
7007
  this._floatingGroups = [];
6634
7008
  this._popoutGroups = [];
7009
+ this._ignoreEvents = 0;
7010
+ this._onDidRemoveGroup = new Emitter();
7011
+ this.onDidRemoveGroup = this._onDidRemoveGroup.event;
7012
+ this._onDidAddGroup = new Emitter();
7013
+ this.onDidAddGroup = this._onDidAddGroup.event;
7014
+ this._onDidActiveGroupChange = new Emitter();
7015
+ this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
7016
+ this._moving = false;
6635
7017
  const gready = document.createElement('div');
6636
7018
  gready.className = 'dv-overlay-render-container';
6637
7019
  this.gridview.element.appendChild(gready);
6638
7020
  this.overlayRenderContainer = new OverlayRenderContainer(gready);
6639
7021
  toggleClass(this.gridview.element, 'dv-dockview', true);
6640
7022
  toggleClass(this.element, 'dv-debug', !!options.debug);
6641
- this.addDisposables(this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
7023
+ this.addDisposables(this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onWillShowOverlay, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, this._onWillDrop, this._onDidMovePanel, this._onDidAddGroup, this._onDidRemoveGroup, this._onDidActiveGroupChange, this.onDidAdd((event) => {
7024
+ if (!this._moving) {
7025
+ this._onDidAddGroup.fire(event);
7026
+ }
7027
+ }), this.onDidRemove((event) => {
7028
+ if (!this._moving) {
7029
+ this._onDidRemoveGroup.fire(event);
7030
+ }
7031
+ }), this.onDidActiveChange((event) => {
7032
+ if (!this._moving) {
7033
+ this._onDidActiveGroupChange.fire(event);
7034
+ }
7035
+ }), exports.DockviewEvent.any(this.onDidAdd, this.onDidRemove)(() => {
6642
7036
  this.updateWatermark();
6643
7037
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
6644
7038
  this._bufferOnDidLayoutChange.fire();
@@ -6649,7 +7043,7 @@
6649
7043
  }
6650
7044
  // iterate over a copy of the array since .dispose() mutates the original array
6651
7045
  for (const group of [...this._popoutGroups]) {
6652
- group.dispose();
7046
+ group.disposable.dispose();
6653
7047
  }
6654
7048
  }));
6655
7049
  this._options = options;
@@ -6695,7 +7089,7 @@
6695
7089
  return this.options.showDndOverlay({
6696
7090
  nativeEvent: event,
6697
7091
  position: position,
6698
- target: exports.DockviewDropTargets.Edge,
7092
+ target: 'edge',
6699
7093
  getData: getPanelData,
6700
7094
  });
6701
7095
  }
@@ -6704,88 +7098,259 @@
6704
7098
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
6705
7099
  overlayModel: (_b = this.options.rootOverlayModel) !== null && _b !== void 0 ? _b : DEFAULT_ROOT_OVERLAY_MODEL,
6706
7100
  });
6707
- this.addDisposables(this._rootDropTarget.onDrop((event) => {
7101
+ this.addDisposables(this._rootDropTarget, this._rootDropTarget.onWillShowOverlay((event) => {
7102
+ if (this.gridview.length > 0 && event.position === 'center') {
7103
+ // option only available when no panels in primary grid
7104
+ return;
7105
+ }
7106
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
7107
+ kind: 'edge',
7108
+ }));
7109
+ }), this._rootDropTarget.onDrop((event) => {
6708
7110
  var _a;
7111
+ const willDropEvent = new DockviewWillDropEvent({
7112
+ nativeEvent: event.nativeEvent,
7113
+ position: event.position,
7114
+ panel: undefined,
7115
+ api: this._api,
7116
+ group: undefined,
7117
+ getData: getPanelData,
7118
+ kind: 'edge',
7119
+ });
7120
+ this._onWillDrop.fire(willDropEvent);
7121
+ if (willDropEvent.defaultPrevented) {
7122
+ return;
7123
+ }
6709
7124
  const data = getPanelData();
6710
7125
  if (data) {
6711
- this.moveGroupOrPanel(this.orthogonalize(event.position), data.groupId, (_a = data.panelId) !== null && _a !== void 0 ? _a : undefined, 'center');
7126
+ this.moveGroupOrPanel({
7127
+ from: {
7128
+ groupId: data.groupId,
7129
+ panelId: (_a = data.panelId) !== null && _a !== void 0 ? _a : undefined,
7130
+ },
7131
+ to: {
7132
+ group: this.orthogonalize(event.position),
7133
+ position: 'center',
7134
+ },
7135
+ });
6712
7136
  }
6713
7137
  else {
6714
- this._onDidDrop.fire(Object.assign(Object.assign({}, event), { api: this._api, group: null, getData: getPanelData }));
7138
+ this._onDidDrop.fire(new DockviewDidDropEvent({
7139
+ nativeEvent: event.nativeEvent,
7140
+ position: event.position,
7141
+ panel: undefined,
7142
+ api: this._api,
7143
+ group: undefined,
7144
+ getData: getPanelData,
7145
+ }));
6715
7146
  }
6716
7147
  }), this._rootDropTarget);
6717
7148
  this._api = new DockviewApi(this);
6718
7149
  this.updateWatermark();
6719
7150
  }
6720
- addPopoutGroup(item, options) {
6721
- var _a;
6722
- let group;
6723
- let box = options === null || options === void 0 ? void 0 : options.position;
6724
- if (item instanceof DockviewPanel) {
6725
- group = this.createGroup();
6726
- this.removePanel(item, {
6727
- removeEmptyGroup: true,
6728
- skipDispose: true,
6729
- });
6730
- group.model.openPanel(item);
6731
- if (!box) {
6732
- box = this.element.getBoundingClientRect();
7151
+ addPopoutGroup(itemToPopout, options) {
7152
+ var _a, _b, _c;
7153
+ if (itemToPopout instanceof DockviewPanel &&
7154
+ itemToPopout.group.size === 1) {
7155
+ return this.addPopoutGroup(itemToPopout.group);
7156
+ }
7157
+ const theme = getDockviewTheme(this.gridview.element);
7158
+ const element = this.element;
7159
+ function getBox() {
7160
+ if (options === null || options === void 0 ? void 0 : options.position) {
7161
+ return options.position;
7162
+ }
7163
+ if (itemToPopout instanceof DockviewGroupPanel) {
7164
+ return itemToPopout.element.getBoundingClientRect();
7165
+ }
7166
+ if (itemToPopout.group) {
7167
+ return itemToPopout.group.element.getBoundingClientRect();
7168
+ }
7169
+ return element.getBoundingClientRect();
7170
+ }
7171
+ const box = getBox();
7172
+ const groupId = (_b = (_a = options === null || options === void 0 ? void 0 : options.overridePopoutGroup) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : this.getNextGroupId(); //item.id;
7173
+ if (itemToPopout.api.location.type === 'grid') {
7174
+ itemToPopout.api.setVisible(false);
7175
+ }
7176
+ const _window = new PopoutWindow(`${this.id}-${groupId}`, // unique id
7177
+ theme !== null && theme !== void 0 ? theme : '', {
7178
+ url: (_c = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _c !== void 0 ? _c : '/popout.html',
7179
+ left: window.screenX + box.left,
7180
+ top: window.screenY + box.top,
7181
+ width: box.width,
7182
+ height: box.height,
7183
+ onDidOpen: options === null || options === void 0 ? void 0 : options.onDidOpen,
7184
+ onWillClose: options === null || options === void 0 ? void 0 : options.onWillClose,
7185
+ });
7186
+ const popoutWindowDisposable = new CompositeDisposable(_window, _window.onDidClose(() => {
7187
+ popoutWindowDisposable.dispose();
7188
+ }));
7189
+ return _window
7190
+ .open()
7191
+ .then((popoutContainer) => {
7192
+ var _a;
7193
+ if (_window.isDisposed) {
7194
+ return;
6733
7195
  }
6734
- }
6735
- else {
6736
- group = item;
6737
- if (!box) {
6738
- box = group.element.getBoundingClientRect();
7196
+ if (popoutContainer === null) {
7197
+ popoutWindowDisposable.dispose();
7198
+ return;
6739
7199
  }
6740
- const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
6741
- options.skipRemoveGroup;
6742
- if (!skip) {
6743
- this.doRemoveGroup(item, { skipDispose: true });
6744
- }
6745
- }
6746
- const theme = getTheme(this.gridview.element);
6747
- const popoutWindow = new DockviewPopoutGroupPanel(`${this.id}-${group.id}`, // globally unique within dockview
6748
- group, {
6749
- className: theme !== null && theme !== void 0 ? theme : '',
6750
- popoutUrl: (_a = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _a !== void 0 ? _a : '/popout.html',
6751
- box: {
6752
- left: window.screenX + box.left,
6753
- top: window.screenY + box.top,
6754
- width: box.width,
6755
- height: box.height,
6756
- },
7200
+ const gready = document.createElement('div');
7201
+ gready.className = 'dv-overlay-render-container';
7202
+ const overlayRenderContainer = new OverlayRenderContainer(gready);
7203
+ const referenceGroup = itemToPopout instanceof DockviewPanel
7204
+ ? itemToPopout.group
7205
+ : itemToPopout;
7206
+ const referenceLocation = itemToPopout.api.location.type;
7207
+ const group = (_a = options === null || options === void 0 ? void 0 : options.overridePopoutGroup) !== null && _a !== void 0 ? _a : this.createGroup({ id: groupId });
7208
+ group.model.renderContainer = overlayRenderContainer;
7209
+ if (!(options === null || options === void 0 ? void 0 : options.overridePopoutGroup)) {
7210
+ this._onDidAddGroup.fire(group);
7211
+ }
7212
+ if (itemToPopout instanceof DockviewPanel) {
7213
+ this.movingLock(() => {
7214
+ const panel = referenceGroup.model.removePanel(itemToPopout);
7215
+ group.model.openPanel(panel);
7216
+ });
7217
+ }
7218
+ else {
7219
+ this.movingLock(() => moveGroupWithoutDestroying({
7220
+ from: referenceGroup,
7221
+ to: group,
7222
+ }));
7223
+ switch (referenceLocation) {
7224
+ case 'grid':
7225
+ referenceGroup.api.setVisible(false);
7226
+ break;
7227
+ case 'floating':
7228
+ case 'popout':
7229
+ this.removeGroup(referenceGroup);
7230
+ break;
7231
+ }
7232
+ }
7233
+ popoutContainer.classList.add('dv-dockview');
7234
+ popoutContainer.style.overflow = 'hidden';
7235
+ popoutContainer.appendChild(gready);
7236
+ popoutContainer.appendChild(group.element);
7237
+ group.model.location = {
7238
+ type: 'popout',
7239
+ getWindow: () => _window.window,
7240
+ };
7241
+ this.doSetGroupAndPanelActive(group);
7242
+ popoutWindowDisposable.addDisposables(group.api.onDidActiveChange((event) => {
7243
+ var _a;
7244
+ if (event.isActive) {
7245
+ (_a = _window.window) === null || _a === void 0 ? void 0 : _a.focus();
7246
+ }
7247
+ }), group.api.onWillFocus(() => {
7248
+ var _a;
7249
+ (_a = _window.window) === null || _a === void 0 ? void 0 : _a.focus();
7250
+ }));
7251
+ let returnedGroup;
7252
+ const value = {
7253
+ window: _window,
7254
+ popoutGroup: group,
7255
+ referenceGroup: this.getPanel(referenceGroup.id)
7256
+ ? referenceGroup.id
7257
+ : undefined,
7258
+ disposable: {
7259
+ dispose: () => {
7260
+ popoutWindowDisposable.dispose();
7261
+ return returnedGroup;
7262
+ },
7263
+ },
7264
+ };
7265
+ popoutWindowDisposable.addDisposables(
7266
+ /**
7267
+ * ResizeObserver seems slow here, I do not know why but we don't need it
7268
+ * since we can reply on the window resize event as we will occupy the full
7269
+ * window dimensions
7270
+ */
7271
+ addDisposableWindowListener(_window.window, 'resize', () => {
7272
+ group.layout(window.innerWidth, window.innerHeight);
7273
+ }), overlayRenderContainer, Disposable.from(() => {
7274
+ if (this.getPanel(referenceGroup.id)) {
7275
+ this.movingLock(() => moveGroupWithoutDestroying({
7276
+ from: group,
7277
+ to: referenceGroup,
7278
+ }));
7279
+ if (!referenceGroup.api.isVisible) {
7280
+ referenceGroup.api.setVisible(true);
7281
+ }
7282
+ if (this.getPanel(group.id)) {
7283
+ this.doRemoveGroup(group, {
7284
+ skipPopoutAssociated: true,
7285
+ });
7286
+ }
7287
+ }
7288
+ else {
7289
+ if (this.getPanel(group.id)) {
7290
+ const removedGroup = this.doRemoveGroup(group, {
7291
+ skipDispose: true,
7292
+ skipActive: true,
7293
+ });
7294
+ removedGroup.model.renderContainer =
7295
+ this.overlayRenderContainer;
7296
+ removedGroup.model.location = { type: 'grid' };
7297
+ returnedGroup = removedGroup;
7298
+ }
7299
+ }
7300
+ }));
7301
+ this._popoutGroups.push(value);
7302
+ this.updateWatermark();
7303
+ })
7304
+ .catch((err) => {
7305
+ console.error(err);
6757
7306
  });
6758
- popoutWindow.addDisposables({
6759
- dispose: () => {
6760
- remove(this._popoutGroups, popoutWindow);
6761
- this.updateWatermark();
6762
- },
6763
- }, popoutWindow.window.onDidClose(() => {
6764
- this.doAddGroup(group, [0]);
6765
- }));
6766
- this._popoutGroups.push(popoutWindow);
6767
- this.updateWatermark();
6768
7307
  }
6769
7308
  addFloatingGroup(item, coord, options) {
6770
- var _a, _b, _c, _d, _e, _f;
7309
+ var _a, _b, _c, _d, _e, _f, _g;
6771
7310
  let group;
6772
7311
  if (item instanceof DockviewPanel) {
6773
7312
  group = this.createGroup();
6774
- this.removePanel(item, {
7313
+ this._onDidAddGroup.fire(group);
7314
+ this.movingLock(() => this.removePanel(item, {
6775
7315
  removeEmptyGroup: true,
6776
7316
  skipDispose: true,
6777
- });
6778
- group.model.openPanel(item);
7317
+ skipSetActiveGroup: true,
7318
+ }));
7319
+ group.model.openPanel(item, { skipSetGroupActive: true });
6779
7320
  }
6780
7321
  else {
6781
7322
  group = item;
7323
+ const popoutReferenceGroupId = (_a = this._popoutGroups.find((_) => _.popoutGroup === group)) === null || _a === void 0 ? void 0 : _a.referenceGroup;
7324
+ const popoutReferenceGroup = popoutReferenceGroupId
7325
+ ? this.getPanel(popoutReferenceGroupId)
7326
+ : undefined;
6782
7327
  const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
6783
7328
  options.skipRemoveGroup;
6784
7329
  if (!skip) {
6785
- this.doRemoveGroup(item, { skipDispose: true });
7330
+ if (popoutReferenceGroup) {
7331
+ this.movingLock(() => moveGroupWithoutDestroying({
7332
+ from: item,
7333
+ to: popoutReferenceGroup,
7334
+ }));
7335
+ this.doRemoveGroup(item, {
7336
+ skipPopoutReturn: true,
7337
+ skipPopoutAssociated: true,
7338
+ });
7339
+ this.doRemoveGroup(popoutReferenceGroup, {
7340
+ skipDispose: true,
7341
+ });
7342
+ group = popoutReferenceGroup;
7343
+ }
7344
+ else {
7345
+ this.doRemoveGroup(item, {
7346
+ skipDispose: true,
7347
+ skipPopoutReturn: true,
7348
+ skipPopoutAssociated: !!popoutReferenceGroup,
7349
+ });
7350
+ }
6786
7351
  }
6787
7352
  }
6788
- group.model.location = 'floating';
7353
+ group.model.location = { type: 'floating' };
6789
7354
  const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number'
6790
7355
  ? Math.max(coord.x, 0)
6791
7356
  : DEFAULT_FLOATING_GROUP_POSITION.left;
@@ -6795,16 +7360,16 @@
6795
7360
  const overlay = new Overlay({
6796
7361
  container: this.gridview.element,
6797
7362
  content: group.element,
6798
- height: (_a = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _a !== void 0 ? _a : 300,
6799
- width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
7363
+ height: (_b = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _b !== void 0 ? _b : 300,
7364
+ width: (_c = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _c !== void 0 ? _c : 300,
6800
7365
  left: overlayLeft,
6801
7366
  top: overlayTop,
6802
7367
  minimumInViewportWidth: this.options.floatingGroupBounds === 'boundedWithinViewport'
6803
7368
  ? undefined
6804
- : (_d = (_c = this.options.floatingGroupBounds) === null || _c === void 0 ? void 0 : _c.minimumWidthWithinViewport) !== null && _d !== void 0 ? _d : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
7369
+ : (_e = (_d = this.options.floatingGroupBounds) === null || _d === void 0 ? void 0 : _d.minimumWidthWithinViewport) !== null && _e !== void 0 ? _e : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
6805
7370
  minimumInViewportHeight: this.options.floatingGroupBounds === 'boundedWithinViewport'
6806
7371
  ? undefined
6807
- : (_f = (_e = this.options.floatingGroupBounds) === null || _e === void 0 ? void 0 : _e.minimumHeightWithinViewport) !== null && _f !== void 0 ? _f : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
7372
+ : (_g = (_f = this.options.floatingGroupBounds) === null || _f === void 0 ? void 0 : _f.minimumHeightWithinViewport) !== null && _g !== void 0 ? _g : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
6808
7373
  });
6809
7374
  const el = group.element.querySelector('.void-container');
6810
7375
  if (!el) {
@@ -6835,12 +7400,15 @@
6835
7400
  }), {
6836
7401
  dispose: () => {
6837
7402
  disposable.dispose();
6838
- group.model.location = 'grid';
7403
+ group.model.location = { type: 'grid' };
6839
7404
  remove(this._floatingGroups, floatingGroupPanel);
6840
7405
  this.updateWatermark();
6841
7406
  },
6842
7407
  });
6843
7408
  this._floatingGroups.push(floatingGroupPanel);
7409
+ if (!(options === null || options === void 0 ? void 0 : options.skipActiveGroup)) {
7410
+ this.doSetGroupAndPanelActive(group);
7411
+ }
6844
7412
  this.updateWatermark();
6845
7413
  }
6846
7414
  orthogonalize(position) {
@@ -6930,8 +7498,8 @@
6930
7498
  return this.panels.find((panel) => panel.id === id);
6931
7499
  }
6932
7500
  setActivePanel(panel) {
6933
- this.doSetGroupActive(panel.group);
6934
7501
  panel.group.model.openPanel(panel);
7502
+ this.doSetGroupAndPanelActive(panel.group);
6935
7503
  }
6936
7504
  moveToNext(options = {}) {
6937
7505
  var _a;
@@ -6992,7 +7560,8 @@
6992
7560
  });
6993
7561
  const popoutGroups = this._popoutGroups.map((group) => {
6994
7562
  return {
6995
- data: group.group.toJSON(),
7563
+ data: group.popoutGroup.toJSON(),
7564
+ gridReferenceGroup: group.referenceGroup,
6996
7565
  position: group.window.dimensions(),
6997
7566
  };
6998
7567
  });
@@ -7010,7 +7579,7 @@
7010
7579
  return result;
7011
7580
  }
7012
7581
  fromJSON(data) {
7013
- var _a, _b;
7582
+ var _a, _b, _c;
7014
7583
  this.clear();
7015
7584
  if (typeof data !== 'object' || data === null) {
7016
7585
  throw new Error('serialized layout must be a non-null object');
@@ -7049,7 +7618,7 @@
7049
7618
  const isActive = typeof activeView === 'string' &&
7050
7619
  activeView === panel.id;
7051
7620
  group.model.openPanel(panel, {
7052
- skipSetPanelActive: !isActive,
7621
+ skipSetActive: !isActive,
7053
7622
  skipSetGroupActive: true,
7054
7623
  });
7055
7624
  }
@@ -7079,11 +7648,16 @@
7079
7648
  }
7080
7649
  const serializedPopoutGroups = (_b = data.popoutGroups) !== null && _b !== void 0 ? _b : [];
7081
7650
  for (const serializedPopoutGroup of serializedPopoutGroups) {
7082
- const { data, position } = serializedPopoutGroup;
7651
+ const { data, position, gridReferenceGroup } = serializedPopoutGroup;
7083
7652
  const group = createGroupFromSerializedState(data);
7084
- this.addPopoutGroup(group, {
7653
+ this.addPopoutGroup((_c = (gridReferenceGroup
7654
+ ? this.getPanel(gridReferenceGroup)
7655
+ : undefined)) !== null && _c !== void 0 ? _c : group, {
7085
7656
  skipRemoveGroup: true,
7086
7657
  position: position !== null && position !== void 0 ? position : undefined,
7658
+ overridePopoutGroup: gridReferenceGroup
7659
+ ? group
7660
+ : undefined,
7087
7661
  });
7088
7662
  }
7089
7663
  for (const floatingGroup of this._floatingGroups) {
@@ -7130,12 +7704,13 @@
7130
7704
  */
7131
7705
  throw err;
7132
7706
  }
7707
+ this.updateWatermark();
7133
7708
  this._onDidLayoutFromJSON.fire();
7134
7709
  }
7135
7710
  clear() {
7136
7711
  const groups = Array.from(this._groups.values()).map((_) => _.value);
7137
7712
  const hasActiveGroup = !!this.activeGroup;
7138
- const hasActivePanel = !!this.activePanel;
7713
+ !!this.activePanel;
7139
7714
  for (const group of groups) {
7140
7715
  // remove the group will automatically remove the panels
7141
7716
  this.removeGroup(group, { skipActive: true });
@@ -7143,9 +7718,6 @@
7143
7718
  if (hasActiveGroup) {
7144
7719
  this.doSetGroupAndPanelActive(undefined);
7145
7720
  }
7146
- if (hasActivePanel) {
7147
- this._onDidActivePanelChange.fire(undefined);
7148
- }
7149
7721
  this.gridview.clear();
7150
7722
  }
7151
7723
  closeAllGroups() {
@@ -7186,6 +7758,7 @@
7186
7758
  const group = this.orthogonalize(directionToPosition(options.position.direction));
7187
7759
  const panel = this.createPanel(options, group);
7188
7760
  group.model.openPanel(panel);
7761
+ this.doSetGroupAndPanelActive(group);
7189
7762
  return panel;
7190
7763
  }
7191
7764
  }
@@ -7197,6 +7770,7 @@
7197
7770
  const target = toTarget(((_b = options.position) === null || _b === void 0 ? void 0 : _b.direction) || 'within');
7198
7771
  if (options.floating) {
7199
7772
  const group = this.createGroup();
7773
+ this._onDidAddGroup.fire(group);
7200
7774
  const o = typeof options.floating === 'object' &&
7201
7775
  options.floating !== null
7202
7776
  ? options.floating
@@ -7204,16 +7778,16 @@
7204
7778
  this.addFloatingGroup(group, o, {
7205
7779
  inDragMode: false,
7206
7780
  skipRemoveGroup: true,
7781
+ skipActiveGroup: true,
7207
7782
  });
7208
- this._onDidAddGroup.fire(group);
7209
7783
  panel = this.createPanel(options, group);
7210
7784
  group.model.openPanel(panel);
7211
- this.doSetGroupAndPanelActive(group);
7212
7785
  }
7213
- else if (referenceGroup.api.location === 'floating' ||
7786
+ else if (referenceGroup.api.location.type === 'floating' ||
7214
7787
  target === 'center') {
7215
7788
  panel = this.createPanel(options, referenceGroup);
7216
7789
  referenceGroup.model.openPanel(panel);
7790
+ this.doSetGroupAndPanelActive(referenceGroup);
7217
7791
  }
7218
7792
  else {
7219
7793
  const location = getGridLocation(referenceGroup.element);
@@ -7221,10 +7795,12 @@
7221
7795
  const group = this.createGroupAtLocation(relativeLocation);
7222
7796
  panel = this.createPanel(options, group);
7223
7797
  group.model.openPanel(panel);
7798
+ this.doSetGroupAndPanelActive(group);
7224
7799
  }
7225
7800
  }
7226
7801
  else if (options.floating) {
7227
7802
  const group = this.createGroup();
7803
+ this._onDidAddGroup.fire(group);
7228
7804
  const o = typeof options.floating === 'object' &&
7229
7805
  options.floating !== null
7230
7806
  ? options.floating
@@ -7232,16 +7808,16 @@
7232
7808
  this.addFloatingGroup(group, o, {
7233
7809
  inDragMode: false,
7234
7810
  skipRemoveGroup: true,
7811
+ skipActiveGroup: true,
7235
7812
  });
7236
- this._onDidAddGroup.fire(group);
7237
7813
  panel = this.createPanel(options, group);
7238
7814
  group.model.openPanel(panel);
7239
- this.doSetGroupAndPanelActive(group);
7240
7815
  }
7241
7816
  else {
7242
7817
  const group = this.createGroupAtLocation();
7243
7818
  panel = this.createPanel(options, group);
7244
7819
  group.model.openPanel(panel);
7820
+ this.doSetGroupAndPanelActive(group);
7245
7821
  }
7246
7822
  return panel;
7247
7823
  }
@@ -7253,13 +7829,15 @@
7253
7829
  if (!group) {
7254
7830
  throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
7255
7831
  }
7256
- group.model.removePanel(panel);
7832
+ group.model.removePanel(panel, {
7833
+ skipSetActiveGroup: options.skipSetActiveGroup,
7834
+ });
7257
7835
  if (!options.skipDispose) {
7258
- this.overlayRenderContainer.detatch(panel);
7836
+ panel.group.model.renderContainer.detatch(panel);
7259
7837
  panel.dispose();
7260
7838
  }
7261
7839
  if (group.size === 0 && options.removeEmptyGroup) {
7262
- this.removeGroup(group);
7840
+ this.removeGroup(group, { skipActive: options.skipSetActiveGroup });
7263
7841
  }
7264
7842
  }
7265
7843
  createWatermarkComponent() {
@@ -7272,7 +7850,7 @@
7272
7850
  }
7273
7851
  updateWatermark() {
7274
7852
  var _a, _b;
7275
- if (this.groups.filter((x) => x.api.location === 'grid').length === 0) {
7853
+ if (this.groups.filter((x) => x.api.location.type === 'grid' && x.api.isVisible).length === 0) {
7276
7854
  if (!this.watermark) {
7277
7855
  this.watermark = this.createWatermarkComponent();
7278
7856
  this.watermark.init({
@@ -7318,36 +7896,42 @@
7318
7896
  }
7319
7897
  else {
7320
7898
  const group = this.orthogonalize(directionToPosition(options.direction));
7899
+ if (!options.skipSetActive) {
7900
+ this.doSetGroupAndPanelActive(group);
7901
+ }
7321
7902
  return group;
7322
7903
  }
7323
7904
  const target = toTarget(options.direction || 'within');
7324
7905
  const location = getGridLocation(referenceGroup.element);
7325
7906
  const relativeLocation = getRelativeLocation(this.gridview.orientation, location, target);
7326
7907
  this.doAddGroup(group, relativeLocation);
7908
+ if (!options.skipSetActive) {
7909
+ this.doSetGroupAndPanelActive(group);
7910
+ }
7327
7911
  return group;
7328
7912
  }
7329
7913
  else {
7330
7914
  this.doAddGroup(group);
7915
+ this.doSetGroupAndPanelActive(group);
7331
7916
  return group;
7332
7917
  }
7333
7918
  }
7334
7919
  removeGroup(group, options) {
7920
+ this.doRemoveGroup(group, options);
7921
+ }
7922
+ doRemoveGroup(group, options) {
7335
7923
  var _a;
7336
7924
  const panels = [...group.panels]; // reassign since group panels will mutate
7337
- for (const panel of panels) {
7338
- this.removePanel(panel, {
7339
- removeEmptyGroup: false,
7340
- skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
7341
- });
7925
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7926
+ for (const panel of panels) {
7927
+ this.removePanel(panel, {
7928
+ removeEmptyGroup: false,
7929
+ skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
7930
+ });
7931
+ }
7342
7932
  }
7343
7933
  const activePanel = this.activePanel;
7344
- this.doRemoveGroup(group, options);
7345
- if (this.activePanel !== activePanel) {
7346
- this._onDidActivePanelChange.fire(this.activePanel);
7347
- }
7348
- }
7349
- doRemoveGroup(group, options) {
7350
- if (group.api.location === 'floating') {
7934
+ if (group.api.location.type === 'floating') {
7351
7935
  const floatingGroup = this._floatingGroups.find((_) => _.group === group);
7352
7936
  if (floatingGroup) {
7353
7937
  if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
@@ -7359,60 +7943,124 @@
7359
7943
  floatingGroup.dispose();
7360
7944
  if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7361
7945
  const groups = Array.from(this._groups.values());
7362
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7946
+ this.doSetGroupAndPanelActive(groups.length > 0 ? groups[0].value : undefined);
7363
7947
  }
7364
7948
  return floatingGroup.group;
7365
7949
  }
7366
7950
  throw new Error('failed to find floating group');
7367
7951
  }
7368
- if (group.api.location === 'popout') {
7369
- const selectedGroup = this._popoutGroups.find((_) => _.group === group);
7952
+ if (group.api.location.type === 'popout') {
7953
+ const selectedGroup = this._popoutGroups.find((_) => _.popoutGroup === group);
7370
7954
  if (selectedGroup) {
7371
7955
  if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7372
- selectedGroup.group.dispose();
7956
+ if (!(options === null || options === void 0 ? void 0 : options.skipPopoutAssociated)) {
7957
+ const refGroup = selectedGroup.referenceGroup
7958
+ ? this.getPanel(selectedGroup.referenceGroup)
7959
+ : undefined;
7960
+ if (refGroup) {
7961
+ this.removeGroup(refGroup);
7962
+ }
7963
+ }
7964
+ selectedGroup.popoutGroup.dispose();
7373
7965
  this._groups.delete(group.id);
7374
7966
  this._onDidRemoveGroup.fire(group);
7375
7967
  }
7376
- selectedGroup.dispose();
7968
+ const removedGroup = selectedGroup.disposable.dispose();
7969
+ if (!(options === null || options === void 0 ? void 0 : options.skipPopoutReturn) && removedGroup) {
7970
+ this.doAddGroup(removedGroup, [0]);
7971
+ this.doSetGroupAndPanelActive(removedGroup);
7972
+ }
7377
7973
  if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7378
7974
  const groups = Array.from(this._groups.values());
7379
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7975
+ this.doSetGroupAndPanelActive(groups.length > 0 ? groups[0].value : undefined);
7380
7976
  }
7381
- return selectedGroup.group;
7977
+ this.updateWatermark();
7978
+ return selectedGroup.popoutGroup;
7382
7979
  }
7383
7980
  throw new Error('failed to find popout group');
7384
7981
  }
7385
- return super.doRemoveGroup(group, options);
7982
+ const re = super.doRemoveGroup(group, options);
7983
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive)) {
7984
+ if (this.activePanel !== activePanel) {
7985
+ this._onDidActivePanelChange.fire(this.activePanel);
7986
+ }
7987
+ }
7988
+ return re;
7386
7989
  }
7387
- moveGroupOrPanel(destinationGroup, sourceGroupId, sourceItemId, destinationTarget, destinationIndex) {
7388
- var _a, _b, _c;
7990
+ movingLock(func) {
7991
+ const isMoving = this._moving;
7992
+ try {
7993
+ this._moving = true;
7994
+ return func();
7995
+ }
7996
+ finally {
7997
+ this._moving = isMoving;
7998
+ }
7999
+ }
8000
+ moveGroupOrPanel(options) {
8001
+ var _a;
8002
+ const destinationGroup = options.to.group;
8003
+ const sourceGroupId = options.from.groupId;
8004
+ const sourceItemId = options.from.panelId;
8005
+ const destinationTarget = options.to.position;
8006
+ const destinationIndex = options.to.index;
7389
8007
  const sourceGroup = sourceGroupId
7390
8008
  ? (_a = this._groups.get(sourceGroupId)) === null || _a === void 0 ? void 0 : _a.value
7391
8009
  : undefined;
8010
+ if (!sourceGroup) {
8011
+ throw new Error(`Failed to find group id ${sourceGroupId}`);
8012
+ }
7392
8013
  if (sourceItemId === undefined) {
7393
- if (sourceGroup) {
7394
- this.moveGroup(sourceGroup, destinationGroup, destinationTarget);
7395
- }
8014
+ /**
8015
+ * Moving an entire group into another group
8016
+ */
8017
+ this.moveGroup({
8018
+ from: { group: sourceGroup },
8019
+ to: {
8020
+ group: destinationGroup,
8021
+ position: destinationTarget,
8022
+ },
8023
+ });
7396
8024
  return;
7397
8025
  }
7398
8026
  if (!destinationTarget || destinationTarget === 'center') {
7399
- const groupItem = (_b = sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.removePanel(sourceItemId)) !== null && _b !== void 0 ? _b : this.panels.find((panel) => panel.id === sourceItemId);
7400
- if (!groupItem) {
8027
+ /**
8028
+ * Dropping a panel within another group
8029
+ */
8030
+ const removedPanel = this.movingLock(() => sourceGroup.model.removePanel(sourceItemId, {
8031
+ skipSetActive: false,
8032
+ skipSetActiveGroup: true,
8033
+ }));
8034
+ if (!removedPanel) {
7401
8035
  throw new Error(`No panel with id ${sourceItemId}`);
7402
8036
  }
7403
- if ((sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.size) === 0) {
7404
- this.doRemoveGroup(sourceGroup);
8037
+ if (sourceGroup.model.size === 0) {
8038
+ // remove the group and do not set a new group as active
8039
+ this.doRemoveGroup(sourceGroup, { skipActive: true });
7405
8040
  }
7406
- destinationGroup.model.openPanel(groupItem, {
8041
+ this.movingLock(() => destinationGroup.model.openPanel(removedPanel, {
7407
8042
  index: destinationIndex,
8043
+ skipSetGroupActive: true,
8044
+ }));
8045
+ this.doSetGroupAndPanelActive(destinationGroup);
8046
+ this._onDidMovePanel.fire({
8047
+ panel: removedPanel,
7408
8048
  });
7409
8049
  }
7410
8050
  else {
8051
+ /**
8052
+ * Dropping a panel to the extremities of a group which will place that panel
8053
+ * into an adjacent group
8054
+ */
7411
8055
  const referenceLocation = getGridLocation(destinationGroup.element);
7412
8056
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
7413
- if (sourceGroup && sourceGroup.size < 2) {
8057
+ if (sourceGroup.size < 2) {
8058
+ /**
8059
+ * If we are moving from a group which only has one panel left we will consider
8060
+ * moving the group itself rather than moving the panel into a newly created group
8061
+ */
7414
8062
  const [targetParentLocation, to] = tail(targetLocation);
7415
- if (sourceGroup.api.location === 'grid') {
8063
+ if (sourceGroup.api.location.type === 'grid') {
7416
8064
  const sourceLocation = getGridLocation(sourceGroup.element);
7417
8065
  const [sourceParentLocation, from] = tail(sourceLocation);
7418
8066
  if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
@@ -7420,77 +8068,122 @@
7420
8068
  // if a group has one tab - we are essentially moving the 'group'
7421
8069
  // which is equivalent to swapping two views in this case
7422
8070
  this.gridview.moveView(sourceParentLocation, from, to);
8071
+ return;
7423
8072
  }
7424
8073
  }
7425
8074
  // source group will become empty so delete the group
7426
- const targetGroup = this.doRemoveGroup(sourceGroup, {
8075
+ const targetGroup = this.movingLock(() => this.doRemoveGroup(sourceGroup, {
7427
8076
  skipActive: true,
7428
8077
  skipDispose: true,
7429
- });
8078
+ }));
7430
8079
  // after deleting the group we need to re-evaulate the ref location
7431
8080
  const updatedReferenceLocation = getGridLocation(destinationGroup.element);
7432
8081
  const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
7433
- this.doAddGroup(targetGroup, location);
8082
+ this.movingLock(() => this.doAddGroup(targetGroup, location));
8083
+ this.doSetGroupAndPanelActive(targetGroup);
7434
8084
  }
7435
8085
  else {
7436
- const groupItem = (_c = sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.removePanel(sourceItemId)) !== null && _c !== void 0 ? _c : this.panels.find((panel) => panel.id === sourceItemId);
7437
- if (!groupItem) {
8086
+ /**
8087
+ * The group we are removing from has many panels, we need to remove the panels we are moving,
8088
+ * create a new group, add the panels to that new group and add the new group in an appropiate position
8089
+ */
8090
+ const removedPanel = this.movingLock(() => sourceGroup.model.removePanel(sourceItemId, {
8091
+ skipSetActive: false,
8092
+ skipSetActiveGroup: true,
8093
+ }));
8094
+ if (!removedPanel) {
7438
8095
  throw new Error(`No panel with id ${sourceItemId}`);
7439
8096
  }
7440
8097
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
7441
8098
  const group = this.createGroupAtLocation(dropLocation);
7442
- group.model.openPanel(groupItem);
8099
+ this.movingLock(() => group.model.openPanel(removedPanel, {
8100
+ skipSetGroupActive: true,
8101
+ }));
8102
+ this.doSetGroupAndPanelActive(group);
7443
8103
  }
7444
8104
  }
7445
8105
  }
7446
- moveGroup(sourceGroup, referenceGroup, target) {
7447
- if (sourceGroup) {
7448
- if (!target || target === 'center') {
7449
- const activePanel = sourceGroup.activePanel;
7450
- const panels = [...sourceGroup.panels].map((p) => sourceGroup.model.removePanel(p.id));
7451
- if ((sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.size) === 0) {
7452
- this.doRemoveGroup(sourceGroup);
7453
- }
8106
+ moveGroup(options) {
8107
+ const from = options.from.group;
8108
+ const to = options.to.group;
8109
+ const target = options.to.position;
8110
+ if (target === 'center') {
8111
+ const activePanel = from.activePanel;
8112
+ const panels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, {
8113
+ skipSetActive: true,
8114
+ })));
8115
+ if ((from === null || from === void 0 ? void 0 : from.model.size) === 0) {
8116
+ this.doRemoveGroup(from, { skipActive: true });
8117
+ }
8118
+ this.movingLock(() => {
7454
8119
  for (const panel of panels) {
7455
- referenceGroup.model.openPanel(panel, {
7456
- skipSetPanelActive: panel !== activePanel,
8120
+ to.model.openPanel(panel, {
8121
+ skipSetActive: panel !== activePanel,
8122
+ skipSetGroupActive: true,
7457
8123
  });
7458
8124
  }
7459
- }
7460
- else {
7461
- switch (sourceGroup.api.location) {
7462
- case 'grid':
7463
- this.gridview.removeView(getGridLocation(sourceGroup.element));
7464
- break;
7465
- case 'floating': {
7466
- const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === sourceGroup);
7467
- if (!selectedFloatingGroup) {
7468
- throw new Error('failed to find floating group');
7469
- }
7470
- selectedFloatingGroup.dispose();
7471
- break;
8125
+ });
8126
+ this.doSetGroupAndPanelActive(to);
8127
+ panels.forEach((panel) => {
8128
+ this._onDidMovePanel.fire({ panel });
8129
+ });
8130
+ }
8131
+ else {
8132
+ switch (from.api.location.type) {
8133
+ case 'grid':
8134
+ this.gridview.removeView(getGridLocation(from.element));
8135
+ break;
8136
+ case 'floating': {
8137
+ const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === from);
8138
+ if (!selectedFloatingGroup) {
8139
+ throw new Error('failed to find floating group');
7472
8140
  }
7473
- case 'popout': {
7474
- const selectedPopoutGroup = this._popoutGroups.find((x) => x.group === sourceGroup);
7475
- if (!selectedPopoutGroup) {
7476
- throw new Error('failed to find popout group');
7477
- }
7478
- selectedPopoutGroup.dispose();
8141
+ selectedFloatingGroup.dispose();
8142
+ break;
8143
+ }
8144
+ case 'popout': {
8145
+ const selectedPopoutGroup = this._popoutGroups.find((x) => x.popoutGroup === from);
8146
+ if (!selectedPopoutGroup) {
8147
+ throw new Error('failed to find popout group');
7479
8148
  }
8149
+ selectedPopoutGroup.disposable.dispose();
7480
8150
  }
7481
- const referenceLocation = getGridLocation(referenceGroup.element);
7482
- const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
7483
- this.gridview.addView(sourceGroup, exports.Sizing.Distribute, dropLocation);
7484
8151
  }
8152
+ const referenceLocation = getGridLocation(to.element);
8153
+ const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
8154
+ this.gridview.addView(from, exports.Sizing.Distribute, dropLocation);
8155
+ from.panels.forEach((panel) => {
8156
+ this._onDidMovePanel.fire({ panel });
8157
+ });
7485
8158
  }
7486
8159
  }
7487
- doSetGroupAndPanelActive(group, skipFocus) {
7488
- var _a, _b;
8160
+ doSetGroupActive(group) {
8161
+ super.doSetGroupActive(group);
8162
+ const activePanel = this.activePanel;
8163
+ if (!this._moving &&
8164
+ activePanel !== this._onDidActivePanelChange.value) {
8165
+ this._onDidActivePanelChange.fire(activePanel);
8166
+ }
8167
+ }
8168
+ doSetGroupAndPanelActive(group) {
8169
+ super.doSetGroupActive(group);
7489
8170
  const activePanel = this.activePanel;
7490
- super.doSetGroupActive(group, skipFocus);
7491
- if (((_a = this._activeGroup) === null || _a === void 0 ? void 0 : _a.activePanel) !== activePanel) {
7492
- this._onDidActivePanelChange.fire((_b = this._activeGroup) === null || _b === void 0 ? void 0 : _b.activePanel);
8171
+ if (group &&
8172
+ this.hasMaximizedGroup() &&
8173
+ !this.isMaximizedGroup(group)) {
8174
+ this.exitMaximizedGroup();
8175
+ }
8176
+ if (!this._moving &&
8177
+ activePanel !== this._onDidActivePanelChange.value) {
8178
+ this._onDidActivePanelChange.fire(activePanel);
8179
+ }
8180
+ }
8181
+ getNextGroupId() {
8182
+ let id = this.nextGroupId.next();
8183
+ while (this._groups.has(id)) {
8184
+ id = this.nextGroupId.next();
7493
8185
  }
8186
+ return id;
7494
8187
  }
7495
8188
  createGroup(options) {
7496
8189
  if (!options) {
@@ -7508,7 +8201,7 @@
7508
8201
  }
7509
8202
  }
7510
8203
  const view = new DockviewGroupPanel(this, id, options);
7511
- view.init({ params: {}, accessor: null }); // required to initialized .part and allow for correct disposal of group
8204
+ view.init({ params: {}, accessor: this });
7512
8205
  if (!this._groups.has(view.id)) {
7513
8206
  const disposable = new CompositeDisposable(view.model.onTabDragStart((event) => {
7514
8207
  this._onWillDragPanel.fire(event);
@@ -7516,20 +8209,48 @@
7516
8209
  this._onWillDragGroup.fire(event);
7517
8210
  }), view.model.onMove((event) => {
7518
8211
  const { groupId, itemId, target, index } = event;
7519
- this.moveGroupOrPanel(view, groupId, itemId, target, index);
8212
+ this.moveGroupOrPanel({
8213
+ from: { groupId: groupId, panelId: itemId },
8214
+ to: {
8215
+ group: view,
8216
+ position: target,
8217
+ index,
8218
+ },
8219
+ });
7520
8220
  }), view.model.onDidDrop((event) => {
7521
- this._onDidDrop.fire(Object.assign(Object.assign({}, event), { api: this._api, group: view }));
8221
+ this._onDidDrop.fire(event);
8222
+ }), view.model.onWillDrop((event) => {
8223
+ this._onWillDrop.fire(event);
8224
+ }), view.model.onWillShowOverlay((event) => {
8225
+ if (this.options.disableDnd) {
8226
+ event.preventDefault();
8227
+ return;
8228
+ }
8229
+ this._onWillShowOverlay.fire(event);
7522
8230
  }), view.model.onDidAddPanel((event) => {
8231
+ if (this._moving) {
8232
+ return;
8233
+ }
7523
8234
  this._onDidAddPanel.fire(event.panel);
7524
8235
  }), view.model.onDidRemovePanel((event) => {
8236
+ if (this._moving) {
8237
+ return;
8238
+ }
7525
8239
  this._onDidRemovePanel.fire(event.panel);
7526
8240
  }), view.model.onDidActivePanelChange((event) => {
7527
- this._onDidActivePanelChange.fire(event.panel);
8241
+ if (this._moving) {
8242
+ return;
8243
+ }
8244
+ if (event.panel !== this.activePanel) {
8245
+ return;
8246
+ }
8247
+ if (this._onDidActivePanelChange.value !== event.panel) {
8248
+ this._onDidActivePanelChange.fire(event.panel);
8249
+ }
7528
8250
  }));
7529
8251
  this._groups.set(view.id, { value: view, disposable });
7530
8252
  }
7531
- // TODO: must be called after the above listeners have been setup,
7532
- // not an ideal pattern
8253
+ // TODO: must be called after the above listeners have been setup, not an ideal pattern
7533
8254
  view.initialize();
7534
8255
  return view;
7535
8256
  }
@@ -7582,7 +8303,20 @@
7582
8303
  });
7583
8304
  this._onDidLayoutfromJSON = new Emitter();
7584
8305
  this.onDidLayoutFromJSON = this._onDidLayoutfromJSON.event;
8306
+ this._onDidRemoveGroup = new Emitter();
8307
+ this.onDidRemoveGroup = this._onDidRemoveGroup.event;
8308
+ this._onDidAddGroup = new Emitter();
8309
+ this.onDidAddGroup = this._onDidAddGroup.event;
8310
+ this._onDidActiveGroupChange = new Emitter();
8311
+ this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
7585
8312
  this._options = options;
8313
+ this.addDisposables(this._onDidAddGroup, this._onDidRemoveGroup, this._onDidActiveGroupChange, this.onDidAdd((event) => {
8314
+ this._onDidAddGroup.fire(event);
8315
+ }), this.onDidRemove((event) => {
8316
+ this._onDidRemoveGroup.fire(event);
8317
+ }), this.onDidActiveChange((event) => {
8318
+ this._onDidActiveGroupChange.fire(event);
8319
+ }));
7586
8320
  if (!this.options.components) {
7587
8321
  this.options.components = {};
7588
8322
  }
@@ -7757,6 +8491,7 @@
7757
8491
  });
7758
8492
  this.registerPanel(view);
7759
8493
  this.doAddGroup(view, relativeLocation, options.size);
8494
+ this.doSetGroupActive(view);
7760
8495
  return view;
7761
8496
  }
7762
8497
  registerPanel(panel) {
@@ -7898,19 +8633,19 @@
7898
8633
  const index = this.panels.indexOf(panel);
7899
8634
  this.splitview.setViewVisible(index, visible);
7900
8635
  }
7901
- setActive(view, skipFocus) {
7902
- this._activePanel = view;
8636
+ setActive(panel, skipFocus) {
8637
+ this._activePanel = panel;
7903
8638
  this.panels
7904
- .filter((v) => v !== view)
8639
+ .filter((v) => v !== panel)
7905
8640
  .forEach((v) => {
7906
8641
  v.api._onDidActiveChange.fire({ isActive: false });
7907
8642
  if (!skipFocus) {
7908
8643
  v.focus();
7909
8644
  }
7910
8645
  });
7911
- view.api._onDidActiveChange.fire({ isActive: true });
8646
+ panel.api._onDidActiveChange.fire({ isActive: true });
7912
8647
  if (!skipFocus) {
7913
- view.focus();
8648
+ panel.focus();
7914
8649
  }
7915
8650
  }
7916
8651
  removePanel(panel, sizing) {
@@ -8209,6 +8944,10 @@
8209
8944
  });
8210
8945
  this.addDisposables(this._disposable);
8211
8946
  }
8947
+ setVisible(panel, visible) {
8948
+ const index = this.panels.indexOf(panel);
8949
+ this.paneview.setViewVisible(index, visible);
8950
+ }
8212
8951
  focus() {
8213
8952
  //noop
8214
8953
  }
@@ -8255,6 +8994,7 @@
8255
8994
  isExpanded: options.isExpanded,
8256
8995
  title: options.title,
8257
8996
  containerApi: new PaneviewApi(this),
8997
+ accessor: this,
8258
8998
  });
8259
8999
  this.paneview.addPane(view, size, index);
8260
9000
  view.orientation = this.paneview.orientation;
@@ -8354,6 +9094,7 @@
8354
9094
  title: data.title,
8355
9095
  isExpanded: !!view.expanded,
8356
9096
  containerApi: new PaneviewApi(this),
9097
+ accessor: this,
8357
9098
  });
8358
9099
  panel.orientation = this.paneview.orientation;
8359
9100
  });
@@ -8442,7 +9183,7 @@
8442
9183
  this._onDidChange = new Emitter();
8443
9184
  this.onDidChange = this._onDidChange.event;
8444
9185
  this.api.initialize(this);
8445
- this.addDisposables(this._onDidChange, this.api.onVisibilityChange((event) => {
9186
+ this.addDisposables(this._onDidChange, this.api.onWillVisibilityChange((event) => {
8446
9187
  const { isVisible } = event;
8447
9188
  const { accessor } = this._params;
8448
9189
  accessor.setVisible(this, isVisible);
@@ -8567,13 +9308,13 @@
8567
9308
  if (this.disposed) {
8568
9309
  throw new Error('invalid operation: resource is already disposed');
8569
9310
  }
8570
- if (typeof this.component !== 'function') {
9311
+ if (!isReactComponent(this.component)) {
8571
9312
  /**
8572
9313
  * we know this isn't a React.FunctionComponent so throw an error here.
8573
- * if we do not intercept this the React library will throw a very obsure error
8574
- * for the same reason, at least at this point we will emit a sensible stacktrace.
9314
+ * if we do not intercept then React library will throw a very obsure error
9315
+ * for the same reason... at least at this point we will emit a sensible stacktrace.
8575
9316
  */
8576
- throw new Error('Invalid Operation. dockview only supports React Functional Components.');
9317
+ throw new Error('Dockview: Only React.memo(...), React.ForwardRef(...) and functional components are accepted as components');
8577
9318
  }
8578
9319
  const bridgeComponent = React__namespace.createElement(React__namespace.forwardRef(ReactComponentBridge), {
8579
9320
  component: this
@@ -8625,9 +9366,13 @@
8625
9366
  }, []);
8626
9367
  return [portals, addPortal];
8627
9368
  };
8628
- // it does the job...
8629
- function isReactElement(element) {
8630
- return !!(element === null || element === void 0 ? void 0 : element.type);
9369
+ function isReactComponent(component) {
9370
+ /**
9371
+ * Yes, we could use "react-is" but that would introduce an unwanted peer dependency
9372
+ * so for now we will check in a rather crude fashion...
9373
+ */
9374
+ return (typeof component === 'function' /** Functional Componnts */ ||
9375
+ !!(component === null || component === void 0 ? void 0 : component.$$typeof) /** React.memo(...) Components */);
8631
9376
  }
8632
9377
 
8633
9378
  class ReactPanelContentPart {
@@ -8887,6 +9632,8 @@
8887
9632
  defaultRenderer: props.defaultRenderer,
8888
9633
  debug: props.debug,
8889
9634
  rootOverlayModel: props.rootOverlayModel,
9635
+ locked: props.locked,
9636
+ disableDnd: props.disableDnd,
8890
9637
  });
8891
9638
  const { clientWidth, clientHeight } = domRef.current;
8892
9639
  dockview.layout(clientWidth, clientHeight);
@@ -8898,6 +9645,20 @@
8898
9645
  dockview.dispose();
8899
9646
  };
8900
9647
  }, []);
9648
+ React__namespace.useEffect(() => {
9649
+ if (!dockviewRef.current) {
9650
+ return;
9651
+ }
9652
+ dockviewRef.current.locked = !!props.locked;
9653
+ }, [props.locked]);
9654
+ React__namespace.useEffect(() => {
9655
+ if (!dockviewRef.current) {
9656
+ return;
9657
+ }
9658
+ dockviewRef.current.updateOptions({
9659
+ disableDnd: props.disableDnd,
9660
+ });
9661
+ }, [props.disableDnd]);
8901
9662
  React__namespace.useEffect(() => {
8902
9663
  if (!dockviewRef.current) {
8903
9664
  return () => {
@@ -8913,6 +9674,21 @@
8913
9674
  disposable.dispose();
8914
9675
  };
8915
9676
  }, [props.onDidDrop]);
9677
+ React__namespace.useEffect(() => {
9678
+ if (!dockviewRef.current) {
9679
+ return () => {
9680
+ // noop
9681
+ };
9682
+ }
9683
+ const disposable = dockviewRef.current.onWillDrop((event) => {
9684
+ if (props.onWillDrop) {
9685
+ props.onWillDrop(event);
9686
+ }
9687
+ });
9688
+ return () => {
9689
+ disposable.dispose();
9690
+ };
9691
+ }, [props.onWillDrop]);
8916
9692
  React__namespace.useEffect(() => {
8917
9693
  if (!dockviewRef.current) {
8918
9694
  return;
@@ -9155,7 +9931,9 @@
9155
9931
  return new ReactPart(this.element, this.reactPortalStore, this.reactComponent, {
9156
9932
  params: (_b = (_a = this._params) === null || _a === void 0 ? void 0 : _a.params) !== null && _b !== void 0 ? _b : {},
9157
9933
  api: this.api,
9158
- containerApi: new GridviewApi(this._params.accessor),
9934
+ // TODO: fix casting hack
9935
+ containerApi: new GridviewApi(this._params
9936
+ .accessor),
9159
9937
  });
9160
9938
  }
9161
9939
  }
@@ -9338,12 +10116,14 @@
9338
10116
  exports.DockviewComponent = DockviewComponent;
9339
10117
  exports.DockviewCompositeDisposable = CompositeDisposable;
9340
10118
  exports.DockviewDefaultTab = DockviewDefaultTab;
10119
+ exports.DockviewDidDropEvent = DockviewDidDropEvent;
9341
10120
  exports.DockviewEmitter = Emitter;
9342
10121
  exports.DockviewGroupPanel = DockviewGroupPanel;
9343
10122
  exports.DockviewGroupPanelModel = DockviewGroupPanelModel;
9344
10123
  exports.DockviewMutableDisposable = MutableDisposable;
9345
10124
  exports.DockviewPanel = DockviewPanel;
9346
10125
  exports.DockviewReact = DockviewReact;
10126
+ exports.DockviewWillDropEvent = DockviewWillDropEvent;
9347
10127
  exports.DraggablePaneviewPanel = DraggablePaneviewPanel;
9348
10128
  exports.Gridview = Gridview;
9349
10129
  exports.GridviewApi = GridviewApi;
@@ -9367,6 +10147,7 @@
9367
10147
  exports.SplitviewPanel = SplitviewPanel;
9368
10148
  exports.SplitviewReact = SplitviewReact;
9369
10149
  exports.Tab = Tab;
10150
+ exports.WillShowOverlayLocationEvent = WillShowOverlayLocationEvent;
9370
10151
  exports.createComponent = createComponent;
9371
10152
  exports.directionToPosition = directionToPosition;
9372
10153
  exports.getDirectionOrientation = getDirectionOrientation;
@@ -9381,7 +10162,7 @@
9381
10162
  exports.isGroupOptionsWithPanel = isGroupOptionsWithPanel;
9382
10163
  exports.isPanelOptionsWithGroup = isPanelOptionsWithGroup;
9383
10164
  exports.isPanelOptionsWithPanel = isPanelOptionsWithPanel;
9384
- exports.isReactElement = isReactElement;
10165
+ exports.isReactComponent = isReactComponent;
9385
10166
  exports.orthogonal = orthogonal;
9386
10167
  exports.positionToDirection = positionToDirection;
9387
10168
  exports.toTarget = toTarget;