dockview 1.9.1 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +1287 -537
  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 +1287 -537
  40. package/dist/dockview.amd.noStyle.js.map +1 -1
  41. package/dist/dockview.cjs.js +1287 -537
  42. package/dist/dockview.cjs.js.map +1 -1
  43. package/dist/dockview.esm.js +1284 -537
  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 +1287 -537
  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 +1287 -537
  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
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview
3
- * @version 1.9.1
3
+ * @version 1.10.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -119,6 +119,17 @@ var Event;
119
119
  };
120
120
  };
121
121
  })(Event || (Event = {}));
122
+ class DockviewEvent {
123
+ constructor() {
124
+ this._defaultPrevented = false;
125
+ }
126
+ get defaultPrevented() {
127
+ return this._defaultPrevented;
128
+ }
129
+ preventDefault() {
130
+ this._defaultPrevented = true;
131
+ }
132
+ }
122
133
  class LeakageMonitor {
123
134
  constructor() {
124
135
  this.events = new Map();
@@ -162,6 +173,9 @@ class Emitter {
162
173
  }
163
174
  Emitter.ENABLE_TRACKING = isEnabled;
164
175
  }
176
+ get value() {
177
+ return this._last;
178
+ }
165
179
  constructor(options) {
166
180
  this.options = options;
167
181
  this._listeners = [];
@@ -284,8 +298,12 @@ class CompositeDisposable {
284
298
  args.forEach((arg) => this._disposables.push(arg));
285
299
  }
286
300
  dispose() {
287
- this._disposables.forEach((arg) => arg.dispose());
301
+ if (this._isDisposed) {
302
+ return;
303
+ }
288
304
  this._isDisposed = true;
305
+ this._disposables.forEach((arg) => arg.dispose());
306
+ this._disposables = [];
289
307
  }
290
308
  }
291
309
  class MutableDisposable {
@@ -769,6 +787,13 @@ class Splitview {
769
787
  this._endSnappingEnabled = endSnappingEnabled;
770
788
  this.updateSashEnablement();
771
789
  }
790
+ get disabled() {
791
+ return this._disabled;
792
+ }
793
+ set disabled(value) {
794
+ this._disabled = value;
795
+ toggleClass(this.element, 'dv-splitview-disabled', value);
796
+ }
772
797
  constructor(container, options) {
773
798
  this.container = container;
774
799
  this.viewItems = [];
@@ -779,6 +804,7 @@ class Splitview {
779
804
  this._proportions = undefined;
780
805
  this._startSnappingEnabled = true;
781
806
  this._endSnappingEnabled = true;
807
+ this._disabled = false;
782
808
  this._onDidSashEnd = new Emitter();
783
809
  this.onDidSashEnd = this._onDidSashEnd.event;
784
810
  this._onDidAddView = new Emitter();
@@ -1706,7 +1732,13 @@ class BranchNode extends CompositeDisposable {
1706
1732
  }
1707
1733
  return LayoutPriority.Normal;
1708
1734
  }
1709
- constructor(orientation, proportionalLayout, styles, size, orthogonalSize, childDescriptors) {
1735
+ get disabled() {
1736
+ return this.splitview.disabled;
1737
+ }
1738
+ set disabled(value) {
1739
+ this.splitview.disabled = value;
1740
+ }
1741
+ constructor(orientation, proportionalLayout, styles, size, orthogonalSize, disabled, childDescriptors) {
1710
1742
  super();
1711
1743
  this.orientation = orientation;
1712
1744
  this.proportionalLayout = proportionalLayout;
@@ -1751,6 +1783,7 @@ class BranchNode extends CompositeDisposable {
1751
1783
  styles,
1752
1784
  });
1753
1785
  }
1786
+ this.disabled = disabled;
1754
1787
  this.addDisposables(this._onDidChange, this._onDidVisibilityChange, this.splitview.onDidSashEnd(() => {
1755
1788
  this._onDidChange.fire({});
1756
1789
  }));
@@ -1884,7 +1917,7 @@ function findLeaf(candiateNode, last) {
1884
1917
  }
1885
1918
  function flipNode(node, size, orthogonalSize) {
1886
1919
  if (node instanceof BranchNode) {
1887
- const result = new BranchNode(orthogonal(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize);
1920
+ const result = new BranchNode(orthogonal(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled);
1888
1921
  let totalSize = 0;
1889
1922
  for (let i = node.children.length - 1; i >= 0; i--) {
1890
1923
  const child = node.children[i];
@@ -2020,31 +2053,57 @@ class Gridview {
2020
2053
  get maximumHeight() {
2021
2054
  return this.root.maximumHeight;
2022
2055
  }
2056
+ get locked() {
2057
+ return this._locked;
2058
+ }
2059
+ set locked(value) {
2060
+ this._locked = value;
2061
+ const branch = [this.root];
2062
+ /**
2063
+ * simple depth-first-search to cover all nodes
2064
+ *
2065
+ * @see https://en.wikipedia.org/wiki/Depth-first_search
2066
+ */
2067
+ while (branch.length > 0) {
2068
+ const node = branch.pop();
2069
+ if (node instanceof BranchNode) {
2070
+ node.disabled = value;
2071
+ branch.push(...node.children);
2072
+ }
2073
+ }
2074
+ }
2023
2075
  maximizedView() {
2024
2076
  var _a;
2025
- return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.view;
2077
+ return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.leaf.view;
2026
2078
  }
2027
2079
  hasMaximizedView() {
2028
2080
  return this._maximizedNode !== undefined;
2029
2081
  }
2030
2082
  maximizeView(view) {
2083
+ var _a;
2031
2084
  const location = getGridLocation(view.element);
2032
2085
  const [_, node] = this.getNode(location);
2033
2086
  if (!(node instanceof LeafNode)) {
2034
2087
  return;
2035
2088
  }
2036
- if (this._maximizedNode === node) {
2089
+ if (((_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.leaf) === node) {
2037
2090
  return;
2038
2091
  }
2039
2092
  if (this.hasMaximizedView()) {
2040
2093
  this.exitMaximizedView();
2041
2094
  }
2095
+ const hiddenOnMaximize = [];
2042
2096
  function hideAllViewsBut(parent, exclude) {
2043
2097
  for (let i = 0; i < parent.children.length; i++) {
2044
2098
  const child = parent.children[i];
2045
2099
  if (child instanceof LeafNode) {
2046
2100
  if (child !== exclude) {
2047
- parent.setChildVisible(i, false);
2101
+ if (parent.isChildVisible(i)) {
2102
+ parent.setChildVisible(i, false);
2103
+ }
2104
+ else {
2105
+ hiddenOnMaximize.push(child);
2106
+ }
2048
2107
  }
2049
2108
  }
2050
2109
  else {
@@ -2053,18 +2112,21 @@ class Gridview {
2053
2112
  }
2054
2113
  }
2055
2114
  hideAllViewsBut(this.root, node);
2056
- this._maximizedNode = node;
2057
- this._onDidMaxmizedNodeChange.fire();
2115
+ this._maximizedNode = { leaf: node, hiddenOnMaximize };
2116
+ this._onDidMaximizedNodeChange.fire();
2058
2117
  }
2059
2118
  exitMaximizedView() {
2060
2119
  if (!this._maximizedNode) {
2061
2120
  return;
2062
2121
  }
2122
+ const hiddenOnMaximize = this._maximizedNode.hiddenOnMaximize;
2063
2123
  function showViewsInReverseOrder(parent) {
2064
2124
  for (let index = parent.children.length - 1; index >= 0; index--) {
2065
2125
  const child = parent.children[index];
2066
2126
  if (child instanceof LeafNode) {
2067
- parent.setChildVisible(index, true);
2127
+ if (!hiddenOnMaximize.includes(child)) {
2128
+ parent.setChildVisible(index, true);
2129
+ }
2068
2130
  }
2069
2131
  else {
2070
2132
  showViewsInReverseOrder(child);
@@ -2073,13 +2135,13 @@ class Gridview {
2073
2135
  }
2074
2136
  showViewsInReverseOrder(this.root);
2075
2137
  this._maximizedNode = undefined;
2076
- this._onDidMaxmizedNodeChange.fire();
2138
+ this._onDidMaximizedNodeChange.fire();
2077
2139
  }
2078
2140
  serialize() {
2079
2141
  if (this.hasMaximizedView()) {
2080
2142
  /**
2081
- * do not persist maximized view state but we must first exit any maximized views
2082
- * before serialization to ensure the correct dimensions are persisted
2143
+ * do not persist maximized view state
2144
+ * firstly exit any maximized views to ensure the correct dimensions are persisted
2083
2145
  */
2084
2146
  this.exitMaximizedView();
2085
2147
  }
@@ -2094,14 +2156,14 @@ class Gridview {
2094
2156
  dispose() {
2095
2157
  this.disposable.dispose();
2096
2158
  this._onDidChange.dispose();
2097
- this._onDidMaxmizedNodeChange.dispose();
2159
+ this._onDidMaximizedNodeChange.dispose();
2098
2160
  this.root.dispose();
2099
2161
  this._maximizedNode = undefined;
2100
2162
  this.element.remove();
2101
2163
  }
2102
2164
  clear() {
2103
2165
  const orientation = this.root.orientation;
2104
- this.root = new BranchNode(orientation, this.proportionalLayout, this.styles, this.root.size, this.root.orthogonalSize);
2166
+ this.root = new BranchNode(orientation, this.proportionalLayout, this.styles, this.root.size, this.root.orthogonalSize, this._locked);
2105
2167
  }
2106
2168
  deserialize(json, deserializer) {
2107
2169
  const orientation = json.orientation;
@@ -2122,8 +2184,8 @@ class Gridview {
2122
2184
  };
2123
2185
  });
2124
2186
  result = new BranchNode(orientation, this.proportionalLayout, this.styles, node.size, // <- orthogonal size - flips at each depth
2125
- orthogonalSize, // <- size - flips at each depth
2126
- children);
2187
+ orthogonalSize, // <- size - flips at each depth,
2188
+ this._locked, children);
2127
2189
  }
2128
2190
  else {
2129
2191
  result = new LeafNode(deserializer.fromJSON(node), orientation, orthogonalSize, node.size);
@@ -2156,7 +2218,7 @@ class Gridview {
2156
2218
  }
2157
2219
  const oldRoot = this.root;
2158
2220
  oldRoot.element.remove();
2159
- this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size);
2221
+ this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size, this._locked);
2160
2222
  if (oldRoot.children.length === 0) ;
2161
2223
  else if (oldRoot.children.length === 1) {
2162
2224
  // can remove one level of redundant branching if there is only a single child
@@ -2224,15 +2286,16 @@ class Gridview {
2224
2286
  constructor(proportionalLayout, styles, orientation) {
2225
2287
  this.proportionalLayout = proportionalLayout;
2226
2288
  this.styles = styles;
2289
+ this._locked = false;
2227
2290
  this._maximizedNode = undefined;
2228
2291
  this.disposable = new MutableDisposable();
2229
2292
  this._onDidChange = new Emitter();
2230
2293
  this.onDidChange = this._onDidChange.event;
2231
- this._onDidMaxmizedNodeChange = new Emitter();
2232
- this.onDidMaxmizedNodeChange = this._onDidMaxmizedNodeChange.event;
2294
+ this._onDidMaximizedNodeChange = new Emitter();
2295
+ this.onDidMaximizedNodeChange = this._onDidMaximizedNodeChange.event;
2233
2296
  this.element = document.createElement('div');
2234
2297
  this.element.className = 'grid-view';
2235
- this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0);
2298
+ this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0, this._locked);
2236
2299
  }
2237
2300
  isViewVisible(location) {
2238
2301
  const [rest, index] = tail(location);
@@ -2283,7 +2346,7 @@ class Gridview {
2283
2346
  }
2284
2347
  const child = grandParent.removeChild(parentIndex);
2285
2348
  child.dispose();
2286
- const newParent = new BranchNode(parent.orientation, this.proportionalLayout, this.styles, parent.size, parent.orthogonalSize);
2349
+ const newParent = new BranchNode(parent.orientation, this.proportionalLayout, this.styles, parent.size, parent.orthogonalSize, this._locked);
2287
2350
  grandParent.addChild(newParent, parent.size, parentIndex);
2288
2351
  const newSibling = new LeafNode(parent.view, grandParent.orientation, parent.size);
2289
2352
  newParent.addChild(newSibling, newSiblingSize, 0);
@@ -2910,6 +2973,21 @@ class DockviewApi {
2910
2973
  get onDidDrop() {
2911
2974
  return this.component.onDidDrop;
2912
2975
  }
2976
+ /**
2977
+ * Invoked when a Drag'n'Drop event occurs but before dockview handles it giving the user an opportunity to intecept and
2978
+ * prevent the event from occuring using the standard `preventDefault()` syntax.
2979
+ *
2980
+ * Preventing certain events may causes unexpected behaviours, use carefully.
2981
+ */
2982
+ get onWillDrop() {
2983
+ return this.component.onWillDrop;
2984
+ }
2985
+ /**
2986
+ *
2987
+ */
2988
+ get onWillShowOverlay() {
2989
+ return this.component.onWillShowOverlay;
2990
+ }
2913
2991
  /**
2914
2992
  * Invoked before a group is dragged. Exposed for custom Drag'n'Drop functionality.
2915
2993
  */
@@ -3045,17 +3123,17 @@ class DockviewApi {
3045
3123
  hasMaximizedGroup() {
3046
3124
  return this.component.hasMaximizedGroup();
3047
3125
  }
3048
- exitMaxmizedGroup() {
3126
+ exitMaximizedGroup() {
3049
3127
  this.component.exitMaximizedGroup();
3050
3128
  }
3051
- get onDidMaxmizedGroupChange() {
3052
- return this.component.onDidMaxmizedGroupChange;
3129
+ get onDidMaximizedGroupChange() {
3130
+ return this.component.onDidMaximizedGroupChange;
3053
3131
  }
3054
3132
  /**
3055
3133
  * Add a popout group in a new Window
3056
3134
  */
3057
3135
  addPopoutGroup(item, options) {
3058
- this.component.addPopoutGroup(item, options);
3136
+ return this.component.addPopoutGroup(item, options);
3059
3137
  }
3060
3138
  }
3061
3139
 
@@ -3109,6 +3187,18 @@ class DragAndDropObserver extends CompositeDisposable {
3109
3187
  }
3110
3188
  }
3111
3189
 
3190
+ class WillShowOverlayEvent extends DockviewEvent {
3191
+ get nativeEvent() {
3192
+ return this.options.nativeEvent;
3193
+ }
3194
+ get position() {
3195
+ return this.options.position;
3196
+ }
3197
+ constructor(options) {
3198
+ super();
3199
+ this.options = options;
3200
+ }
3201
+ }
3112
3202
  function directionToPosition(direction) {
3113
3203
  switch (direction) {
3114
3204
  case 'above':
@@ -3161,6 +3251,8 @@ class Droptarget extends CompositeDisposable {
3161
3251
  this.options = options;
3162
3252
  this._onDrop = new Emitter();
3163
3253
  this.onDrop = this._onDrop.event;
3254
+ this._onWillShowOverlay = new Emitter();
3255
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
3164
3256
  // use a set to take advantage of #<set>.has
3165
3257
  this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
3166
3258
  this.dnd = new DragAndDropObserver(this.element, {
@@ -3189,6 +3281,19 @@ class Droptarget extends CompositeDisposable {
3189
3281
  this.removeDropTarget();
3190
3282
  return;
3191
3283
  }
3284
+ const willShowOverlayEvent = new WillShowOverlayEvent({
3285
+ nativeEvent: e,
3286
+ position: quadrant,
3287
+ });
3288
+ /**
3289
+ * Provide an opportunity to prevent the overlay appearing and in turn
3290
+ * any dnd behaviours
3291
+ */
3292
+ this._onWillShowOverlay.fire(willShowOverlayEvent);
3293
+ if (willShowOverlayEvent.defaultPrevented) {
3294
+ this.removeDropTarget();
3295
+ return;
3296
+ }
3192
3297
  if (typeof this.options.canDisplayOverlay === 'boolean') {
3193
3298
  if (!this.options.canDisplayOverlay) {
3194
3299
  this.removeDropTarget();
@@ -3231,7 +3336,7 @@ class Droptarget extends CompositeDisposable {
3231
3336
  }
3232
3337
  },
3233
3338
  });
3234
- this.addDisposables(this._onDrop, this.dnd);
3339
+ this.addDisposables(this._onDrop, this._onWillShowOverlay, this.dnd);
3235
3340
  }
3236
3341
  setTargetZones(acceptedTargetZones) {
3237
3342
  this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
@@ -3284,25 +3389,44 @@ class Droptarget extends CompositeDisposable {
3284
3389
  size = clamp(0, sizeOptions.value, height) / height;
3285
3390
  }
3286
3391
  }
3287
- const translate = (1 - size) / 2;
3288
- const scale = size;
3289
- let transform;
3392
+ const box = { top: '0px', left: '0px', width: '100%', height: '100%' };
3393
+ /**
3394
+ * You can also achieve the overlay placement using the transform CSS property
3395
+ * to translate and scale the element however this has the undesired effect of
3396
+ * 'skewing' the element. Comment left here for anybody that ever revisits this.
3397
+ *
3398
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/transform
3399
+ *
3400
+ * right
3401
+ * translateX(${100 * (1 - size) / 2}%) scaleX(${scale})
3402
+ *
3403
+ * left
3404
+ * translateX(-${100 * (1 - size) / 2}%) scaleX(${scale})
3405
+ *
3406
+ * top
3407
+ * translateY(-${100 * (1 - size) / 2}%) scaleY(${scale})
3408
+ *
3409
+ * bottom
3410
+ * translateY(${100 * (1 - size) / 2}%) scaleY(${scale})
3411
+ */
3290
3412
  if (rightClass) {
3291
- transform = `translateX(${100 * translate}%) scaleX(${scale})`;
3413
+ box.left = `${100 * (1 - size)}%`;
3414
+ box.width = `${100 * size}%`;
3292
3415
  }
3293
3416
  else if (leftClass) {
3294
- transform = `translateX(-${100 * translate}%) scaleX(${scale})`;
3417
+ box.width = `${100 * size}%`;
3295
3418
  }
3296
3419
  else if (topClass) {
3297
- transform = `translateY(-${100 * translate}%) scaleY(${scale})`;
3420
+ box.height = `${100 * size}%`;
3298
3421
  }
3299
3422
  else if (bottomClass) {
3300
- transform = `translateY(${100 * translate}%) scaleY(${scale})`;
3301
- }
3302
- else {
3303
- transform = '';
3423
+ box.top = `${100 * (1 - size)}%`;
3424
+ box.height = `${100 * size}%`;
3304
3425
  }
3305
- this.overlayElement.style.transform = transform;
3426
+ this.overlayElement.style.top = box.top;
3427
+ this.overlayElement.style.left = box.left;
3428
+ this.overlayElement.style.width = box.width;
3429
+ this.overlayElement.style.height = box.height;
3306
3430
  toggleClass(this.overlayElement, 'dv-drop-target-small-vertical', isSmallY);
3307
3431
  toggleClass(this.overlayElement, 'dv-drop-target-small-horizontal', isSmallX);
3308
3432
  toggleClass(this.overlayElement, 'dv-drop-target-left', isLeft);
@@ -3370,14 +3494,6 @@ function calculateQuadrantAsPixels(overlayType, x, y, width, height, threshold)
3370
3494
  return 'center';
3371
3495
  }
3372
3496
 
3373
- var DockviewDropTargets;
3374
- (function (DockviewDropTargets) {
3375
- DockviewDropTargets[DockviewDropTargets["Tab"] = 0] = "Tab";
3376
- DockviewDropTargets[DockviewDropTargets["Panel"] = 1] = "Panel";
3377
- DockviewDropTargets[DockviewDropTargets["TabContainer"] = 2] = "TabContainer";
3378
- DockviewDropTargets[DockviewDropTargets["Edge"] = 3] = "Edge";
3379
- })(DockviewDropTargets || (DockviewDropTargets = {}));
3380
-
3381
3497
  class ContentContainer extends CompositeDisposable {
3382
3498
  get element() {
3383
3499
  return this._element;
@@ -3405,7 +3521,7 @@ class ContentContainer extends CompositeDisposable {
3405
3521
  const data = getPanelData();
3406
3522
  if (!data &&
3407
3523
  event.shiftKey &&
3408
- this.group.location !== 'floating') {
3524
+ this.group.location.type !== 'floating') {
3409
3525
  return false;
3410
3526
  }
3411
3527
  if (data && data.viewId === this.accessor.id) {
@@ -3423,7 +3539,7 @@ class ContentContainer extends CompositeDisposable {
3423
3539
  data.groupId === this.group.id;
3424
3540
  return !groupHasOnePanelAndIsActiveDragElement;
3425
3541
  }
3426
- return this.group.canDisplayOverlay(event, position, DockviewDropTargets.Panel);
3542
+ return this.group.canDisplayOverlay(event, position, 'panel');
3427
3543
  },
3428
3544
  });
3429
3545
  this.addDisposables(this.dropTarget);
@@ -3448,7 +3564,7 @@ class ContentContainer extends CompositeDisposable {
3448
3564
  let container;
3449
3565
  switch (panel.api.renderer) {
3450
3566
  case 'onlyWhenVisibile':
3451
- this.accessor.overlayRenderContainer.detatch(panel);
3567
+ this.group.renderContainer.detatch(panel);
3452
3568
  if (this.panel) {
3453
3569
  if (doRender) {
3454
3570
  this._element.appendChild(this.panel.view.content.element);
@@ -3460,7 +3576,7 @@ class ContentContainer extends CompositeDisposable {
3460
3576
  if (panel.view.content.element.parentElement === this._element) {
3461
3577
  this._element.removeChild(panel.view.content.element);
3462
3578
  }
3463
- container = this.accessor.overlayRenderContainer.attach({
3579
+ container = this.group.renderContainer.attach({
3464
3580
  panel,
3465
3581
  referenceContainer: this,
3466
3582
  });
@@ -3491,12 +3607,13 @@ class ContentContainer extends CompositeDisposable {
3491
3607
  // noop
3492
3608
  }
3493
3609
  closePanel() {
3610
+ var _a;
3494
3611
  if (this.panel) {
3495
- if (this.accessor.options.defaultRenderer === 'onlyWhenVisibile') {
3496
- this._element.removeChild(this.panel.view.content.element);
3612
+ if (this.panel.api.renderer === 'onlyWhenVisibile') {
3613
+ (_a = this.panel.view.content.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.panel.view.content.element);
3497
3614
  }
3498
- this.panel = undefined;
3499
3615
  }
3616
+ this.panel = undefined;
3500
3617
  }
3501
3618
  dispose() {
3502
3619
  this.disposable.dispose();
@@ -3604,7 +3721,7 @@ class Tab extends CompositeDisposable {
3604
3721
  this._element.draggable = true;
3605
3722
  toggleClass(this.element, 'inactive-tab', true);
3606
3723
  const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
3607
- this.droptarget = new Droptarget(this._element, {
3724
+ this.dropTarget = new Droptarget(this._element, {
3608
3725
  acceptedTargetZones: ['center'],
3609
3726
  canDisplayOverlay: (event, position) => {
3610
3727
  if (this.group.locked) {
@@ -3619,9 +3736,10 @@ class Tab extends CompositeDisposable {
3619
3736
  }
3620
3737
  return this.panel.id !== data.panelId;
3621
3738
  }
3622
- return this.group.model.canDisplayOverlay(event, position, DockviewDropTargets.Tab);
3739
+ return this.group.model.canDisplayOverlay(event, position, 'tab');
3623
3740
  },
3624
3741
  });
3742
+ this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
3625
3743
  this.addDisposables(this._onChanged, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
3626
3744
  this._onDragStart.fire(event);
3627
3745
  }), dragHandler, addDisposableListener(this._element, 'mousedown', (event) => {
@@ -3629,9 +3747,9 @@ class Tab extends CompositeDisposable {
3629
3747
  return;
3630
3748
  }
3631
3749
  this._onChanged.fire(event);
3632
- }), this.droptarget.onDrop((event) => {
3750
+ }), this.dropTarget.onDrop((event) => {
3633
3751
  this._onDropped.fire(event);
3634
- }), this.droptarget);
3752
+ }), this.dropTarget);
3635
3753
  }
3636
3754
  setActive(isActive) {
3637
3755
  toggleClass(this.element, 'active-tab', isActive);
@@ -3678,7 +3796,7 @@ class GroupDragHandler extends DragHandler {
3678
3796
  }, true));
3679
3797
  }
3680
3798
  isCancelled(_event) {
3681
- if (this.group.api.location === 'floating' && !_event.shiftKey) {
3799
+ if (this.group.api.location.type === 'floating' && !_event.shiftKey) {
3682
3800
  return true;
3683
3801
  }
3684
3802
  return false;
@@ -3730,7 +3848,7 @@ class VoidContainer extends CompositeDisposable {
3730
3848
  this.accessor.doSetGroupActive(this.group);
3731
3849
  }));
3732
3850
  const handler = new GroupDragHandler(this._element, accessor, group);
3733
- this.voidDropTarget = new Droptarget(this._element, {
3851
+ this.dropTraget = new Droptarget(this._element, {
3734
3852
  acceptedTargetZones: ['center'],
3735
3853
  canDisplayOverlay: (event, position) => {
3736
3854
  var _a;
@@ -3744,14 +3862,15 @@ class VoidContainer extends CompositeDisposable {
3744
3862
  // don't show the overlay if the tab being dragged is the last panel of this group
3745
3863
  return ((_a = last(this.group.panels)) === null || _a === void 0 ? void 0 : _a.id) !== data.panelId;
3746
3864
  }
3747
- return group.model.canDisplayOverlay(event, position, DockviewDropTargets.Panel);
3865
+ return group.model.canDisplayOverlay(event, position, 'panel');
3748
3866
  },
3749
3867
  });
3868
+ this.onWillShowOverlay = this.dropTraget.onWillShowOverlay;
3750
3869
  this.addDisposables(handler, handler.onDragStart((event) => {
3751
3870
  this._onDragStart.fire(event);
3752
- }), this.voidDropTarget.onDrop((event) => {
3871
+ }), this.dropTraget.onDrop((event) => {
3753
3872
  this._onDrop.fire(event);
3754
- }), this.voidDropTarget);
3873
+ }), this.dropTraget);
3755
3874
  }
3756
3875
  }
3757
3876
 
@@ -3839,19 +3958,11 @@ class TabsContainer extends CompositeDisposable {
3839
3958
  this.onTabDragStart = this._onTabDragStart.event;
3840
3959
  this._onGroupDragStart = new Emitter();
3841
3960
  this.onGroupDragStart = this._onGroupDragStart.event;
3842
- this.addDisposables(this._onDrop, this._onTabDragStart, this._onGroupDragStart);
3961
+ this._onWillShowOverlay = new Emitter();
3962
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
3843
3963
  this._element = document.createElement('div');
3844
3964
  this._element.className = 'tabs-and-actions-container';
3845
3965
  toggleClass(this._element, 'dv-full-width-single-tab', this.accessor.options.singleTabMode === 'fullwidth');
3846
- this.addDisposables(this.accessor.onDidAddPanel((e) => {
3847
- if (e.api.group === this.group) {
3848
- toggleClass(this._element, 'dv-single-tab', this.size === 1);
3849
- }
3850
- }), this.accessor.onDidRemovePanel((e) => {
3851
- if (e.api.group === this.group) {
3852
- toggleClass(this._element, 'dv-single-tab', this.size === 1);
3853
- }
3854
- }));
3855
3966
  this.rightActionsContainer = document.createElement('div');
3856
3967
  this.rightActionsContainer.className = 'right-actions-container';
3857
3968
  this.leftActionsContainer = document.createElement('div');
@@ -3866,7 +3977,15 @@ class TabsContainer extends CompositeDisposable {
3866
3977
  this._element.appendChild(this.leftActionsContainer);
3867
3978
  this._element.appendChild(this.voidContainer.element);
3868
3979
  this._element.appendChild(this.rightActionsContainer);
3869
- this.addDisposables(this.voidContainer, this.voidContainer.onDragStart((event) => {
3980
+ this.addDisposables(this.accessor.onDidAddPanel((e) => {
3981
+ if (e.api.group === this.group) {
3982
+ toggleClass(this._element, 'dv-single-tab', this.size === 1);
3983
+ }
3984
+ }), this.accessor.onDidRemovePanel((e) => {
3985
+ if (e.api.group === this.group) {
3986
+ toggleClass(this._element, 'dv-single-tab', this.size === 1);
3987
+ }
3988
+ }), this._onWillShowOverlay, this._onDrop, this._onTabDragStart, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
3870
3989
  this._onGroupDragStart.fire({
3871
3990
  nativeEvent: event,
3872
3991
  group: this.group,
@@ -3876,11 +3995,15 @@ class TabsContainer extends CompositeDisposable {
3876
3995
  event: event.nativeEvent,
3877
3996
  index: this.tabs.length,
3878
3997
  });
3998
+ }), this.voidContainer.onWillShowOverlay((event) => {
3999
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
4000
+ kind: 'header_space',
4001
+ }));
3879
4002
  }), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => {
3880
4003
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3881
4004
  if (isFloatingGroupsEnabled &&
3882
4005
  event.shiftKey &&
3883
- this.group.api.location !== 'floating') {
4006
+ this.group.api.location.type !== 'floating') {
3884
4007
  event.preventDefault();
3885
4008
  const { top, left } = this.element.getBoundingClientRect();
3886
4009
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
@@ -3943,9 +4066,9 @@ class TabsContainer extends CompositeDisposable {
3943
4066
  const disposable = new CompositeDisposable(tab.onDragStart((event) => {
3944
4067
  this._onTabDragStart.fire({ nativeEvent: event, panel });
3945
4068
  }), tab.onChanged((event) => {
3946
- var _a;
3947
4069
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3948
- const isFloatingWithOnePanel = this.group.api.location === 'floating' && this.size === 1;
4070
+ const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
4071
+ this.size === 1;
3949
4072
  if (isFloatingGroupsEnabled &&
3950
4073
  !isFloatingWithOnePanel &&
3951
4074
  event.shiftKey) {
@@ -3959,20 +4082,20 @@ class TabsContainer extends CompositeDisposable {
3959
4082
  }, { inDragMode: true });
3960
4083
  return;
3961
4084
  }
3962
- const alreadyFocused = panel.id === ((_a = this.group.model.activePanel) === null || _a === void 0 ? void 0 : _a.id) &&
3963
- this.group.model.isContentFocused;
3964
4085
  const isLeftClick = event.button === 0;
3965
4086
  if (!isLeftClick || event.defaultPrevented) {
3966
4087
  return;
3967
4088
  }
3968
- this.group.model.openPanel(panel, {
3969
- skipFocus: alreadyFocused,
3970
- });
4089
+ if (this.group.activePanel !== panel) {
4090
+ this.group.model.openPanel(panel);
4091
+ }
3971
4092
  }), tab.onDrop((event) => {
3972
4093
  this._onDrop.fire({
3973
4094
  event: event.nativeEvent,
3974
4095
  index: this.tabs.findIndex((x) => x.value === tab),
3975
4096
  });
4097
+ }), tab.onWillShowOverlay((event) => {
4098
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, { kind: 'tab' }));
3976
4099
  }));
3977
4100
  const value = { value: tab, disposable };
3978
4101
  this.addTab(value, index);
@@ -3990,6 +4113,60 @@ class TabsContainer extends CompositeDisposable {
3990
4113
  }
3991
4114
  }
3992
4115
 
4116
+ class DockviewDidDropEvent extends DockviewEvent {
4117
+ get nativeEvent() {
4118
+ return this.options.nativeEvent;
4119
+ }
4120
+ get position() {
4121
+ return this.options.position;
4122
+ }
4123
+ get panel() {
4124
+ return this.options.panel;
4125
+ }
4126
+ get group() {
4127
+ return this.options.group;
4128
+ }
4129
+ get api() {
4130
+ return this.options.api;
4131
+ }
4132
+ constructor(options) {
4133
+ super();
4134
+ this.options = options;
4135
+ }
4136
+ getData() {
4137
+ return this.options.getData();
4138
+ }
4139
+ }
4140
+ class DockviewWillDropEvent extends DockviewDidDropEvent {
4141
+ get kind() {
4142
+ return this._kind;
4143
+ }
4144
+ constructor(options) {
4145
+ super(options);
4146
+ this._kind = options.kind;
4147
+ }
4148
+ }
4149
+ class WillShowOverlayLocationEvent {
4150
+ get kind() {
4151
+ return this._kind;
4152
+ }
4153
+ get nativeEvent() {
4154
+ return this.event.nativeEvent;
4155
+ }
4156
+ get position() {
4157
+ return this.event.position;
4158
+ }
4159
+ get defaultPrevented() {
4160
+ return this.event.defaultPrevented;
4161
+ }
4162
+ preventDefault() {
4163
+ this.event.preventDefault();
4164
+ }
4165
+ constructor(event, options) {
4166
+ this.event = event;
4167
+ this._kind = options.kind;
4168
+ }
4169
+ }
3993
4170
  class DockviewGroupPanelModel extends CompositeDisposable {
3994
4171
  get element() {
3995
4172
  throw new Error('not supported');
@@ -4035,7 +4212,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4035
4212
  this._location = value;
4036
4213
  toggleClass(this.container, 'dv-groupview-floating', false);
4037
4214
  toggleClass(this.container, 'dv-groupview-popout', false);
4038
- switch (value) {
4215
+ switch (value.type) {
4039
4216
  case 'grid':
4040
4217
  this.contentContainer.dropTarget.setTargetZones([
4041
4218
  'top',
@@ -4071,7 +4248,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4071
4248
  this.groupPanel = groupPanel;
4072
4249
  this._isGroupActive = false;
4073
4250
  this._locked = false;
4074
- this._location = 'grid';
4251
+ this._location = { type: 'grid' };
4075
4252
  this.mostRecentlyUsed = [];
4076
4253
  this._onDidChange = new Emitter();
4077
4254
  this.onDidChange = this._onDidChange.event;
@@ -4082,6 +4259,10 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4082
4259
  this.onMove = this._onMove.event;
4083
4260
  this._onDidDrop = new Emitter();
4084
4261
  this.onDidDrop = this._onDidDrop.event;
4262
+ this._onWillDrop = new Emitter();
4263
+ this.onWillDrop = this._onWillDrop.event;
4264
+ this._onWillShowOverlay = new Emitter();
4265
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
4085
4266
  this._onTabDragStart = new Emitter();
4086
4267
  this.onTabDragStart = this._onTabDragStart.event;
4087
4268
  this._onGroupDragStart = new Emitter();
@@ -4092,46 +4273,69 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4092
4273
  this.onDidRemovePanel = this._onDidRemovePanel.event;
4093
4274
  this._onDidActivePanelChange = new Emitter();
4094
4275
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
4276
+ this._overwriteRenderContainer = null;
4095
4277
  toggleClass(this.container, 'groupview', true);
4278
+ this._api = new DockviewApi(this.accessor);
4096
4279
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
4097
4280
  this.contentContainer = new ContentContainer(this.accessor, this);
4098
4281
  container.append(this.tabsContainer.element, this.contentContainer.element);
4099
4282
  this.header.hidden = !!options.hideHeader;
4100
4283
  this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
4101
- this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this.tabsContainer.onTabDragStart((event) => {
4284
+ this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this._onWillShowOverlay, this.tabsContainer.onTabDragStart((event) => {
4102
4285
  this._onTabDragStart.fire(event);
4103
4286
  }), this.tabsContainer.onGroupDragStart((event) => {
4104
4287
  this._onGroupDragStart.fire(event);
4105
4288
  }), this.tabsContainer.onDrop((event) => {
4106
- this.handleDropEvent(event.event, 'center', event.index);
4289
+ this.handleDropEvent('header', event.event, 'center', event.index);
4107
4290
  }), this.contentContainer.onDidFocus(() => {
4108
- this.accessor.doSetGroupActive(this.groupPanel, true);
4291
+ this.accessor.doSetGroupActive(this.groupPanel);
4109
4292
  }), this.contentContainer.onDidBlur(() => {
4110
4293
  // noop
4111
4294
  }), this.contentContainer.dropTarget.onDrop((event) => {
4112
- this.handleDropEvent(event.nativeEvent, event.position);
4113
- }), this._onMove, this._onDidChange, this._onDidDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange);
4295
+ this.handleDropEvent('content', event.nativeEvent, event.position);
4296
+ }), this.tabsContainer.onWillShowOverlay((event) => {
4297
+ this._onWillShowOverlay.fire(event);
4298
+ }), this.contentContainer.dropTarget.onWillShowOverlay((event) => {
4299
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
4300
+ kind: 'content',
4301
+ }));
4302
+ }), this._onMove, this._onDidChange, this._onDidDrop, this._onWillDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange);
4303
+ }
4304
+ focusContent() {
4305
+ this.contentContainer.element.focus();
4306
+ }
4307
+ set renderContainer(value) {
4308
+ this.panels.forEach((panel) => {
4309
+ this.renderContainer.detatch(panel);
4310
+ });
4311
+ this._overwriteRenderContainer = value;
4312
+ this.panels.forEach((panel) => {
4313
+ this.rerender(panel);
4314
+ });
4315
+ }
4316
+ get renderContainer() {
4317
+ var _a;
4318
+ return ((_a = this._overwriteRenderContainer) !== null && _a !== void 0 ? _a : this.accessor.overlayRenderContainer);
4114
4319
  }
4115
4320
  initialize() {
4116
- var _a, _b;
4117
- if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.panels) {
4321
+ if (this.options.panels) {
4118
4322
  this.options.panels.forEach((panel) => {
4119
4323
  this.doAddPanel(panel);
4120
4324
  });
4121
4325
  }
4122
- if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.activePanel) {
4326
+ if (this.options.activePanel) {
4123
4327
  this.openPanel(this.options.activePanel);
4124
4328
  }
4125
4329
  // must be run after the constructor otherwise this.parent may not be
4126
4330
  // correctly initialized
4127
- this.setActive(this.isActive, true, true);
4331
+ this.setActive(this.isActive, true);
4128
4332
  this.updateContainer();
4129
4333
  if (this.accessor.options.createRightHeaderActionsElement) {
4130
4334
  this._rightHeaderActions =
4131
4335
  this.accessor.options.createRightHeaderActionsElement(this.groupPanel);
4132
4336
  this.addDisposables(this._rightHeaderActions);
4133
4337
  this._rightHeaderActions.init({
4134
- containerApi: new DockviewApi(this.accessor),
4338
+ containerApi: this._api,
4135
4339
  api: this.groupPanel.api,
4136
4340
  });
4137
4341
  this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
@@ -4141,7 +4345,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4141
4345
  this.accessor.options.createLeftHeaderActionsElement(this.groupPanel);
4142
4346
  this.addDisposables(this._leftHeaderActions);
4143
4347
  this._leftHeaderActions.init({
4144
- containerApi: new DockviewApi(this.accessor),
4348
+ containerApi: this._api,
4145
4349
  api: this.groupPanel.api,
4146
4350
  });
4147
4351
  this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
@@ -4151,7 +4355,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4151
4355
  this.accessor.options.createPrefixHeaderActionsElement(this.groupPanel);
4152
4356
  this.addDisposables(this._prefixHeaderActions);
4153
4357
  this._prefixHeaderActions.init({
4154
- containerApi: new DockviewApi(this.accessor),
4358
+ containerApi: this._api,
4155
4359
  api: this.groupPanel.api,
4156
4360
  });
4157
4361
  this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
@@ -4231,34 +4435,45 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4231
4435
  //noop
4232
4436
  }
4233
4437
  focus() {
4234
- var _a, _b;
4235
- (_b = (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a);
4438
+ var _a;
4439
+ (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.focus();
4236
4440
  }
4237
4441
  openPanel(panel, options = {}) {
4442
+ /**
4443
+ * set the panel group
4444
+ * add the panel
4445
+ * check if group active
4446
+ * check if panel active
4447
+ */
4238
4448
  if (typeof options.index !== 'number' ||
4239
4449
  options.index > this.panels.length) {
4240
4450
  options.index = this.panels.length;
4241
4451
  }
4242
- const skipSetPanelActive = !!options.skipSetPanelActive;
4243
- const skipSetGroupActive = !!options.skipSetGroupActive;
4452
+ const skipSetActive = !!options.skipSetActive;
4244
4453
  // ensure the group is updated before we fire any events
4245
- panel.updateParentGroup(this.groupPanel, true);
4454
+ panel.updateParentGroup(this.groupPanel, {
4455
+ skipSetActive: options.skipSetActive,
4456
+ });
4457
+ this.doAddPanel(panel, options.index, {
4458
+ skipSetActive: skipSetActive,
4459
+ });
4246
4460
  if (this._activePanel === panel) {
4247
- if (!skipSetGroupActive) {
4248
- this.accessor.doSetGroupActive(this.groupPanel);
4249
- }
4461
+ this.contentContainer.renderPanel(panel, { asActive: true });
4250
4462
  return;
4251
4463
  }
4252
- this.doAddPanel(panel, options.index, skipSetPanelActive);
4253
- if (!skipSetPanelActive) {
4464
+ if (!skipSetActive) {
4254
4465
  this.doSetActivePanel(panel);
4255
4466
  }
4256
- if (!skipSetGroupActive) {
4257
- this.accessor.doSetGroupActive(this.groupPanel, !!options.skipFocus);
4467
+ if (!options.skipSetGroupActive) {
4468
+ this.accessor.doSetGroupActive(this.groupPanel);
4469
+ }
4470
+ if (!options.skipSetActive) {
4471
+ this.updateContainer();
4258
4472
  }
4259
- this.updateContainer();
4260
4473
  }
4261
- removePanel(groupItemOrId) {
4474
+ removePanel(groupItemOrId, options = {
4475
+ skipSetActive: false,
4476
+ }) {
4262
4477
  const id = typeof groupItemOrId === 'string'
4263
4478
  ? groupItemOrId
4264
4479
  : groupItemOrId.id;
@@ -4266,7 +4481,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4266
4481
  if (!panelToRemove) {
4267
4482
  throw new Error('invalid operation');
4268
4483
  }
4269
- return this._removePanel(panelToRemove);
4484
+ return this._removePanel(panelToRemove, options);
4270
4485
  }
4271
4486
  closeAllPanels() {
4272
4487
  if (this.panels.length > 0) {
@@ -4292,12 +4507,8 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4292
4507
  updateActions(element) {
4293
4508
  this.tabsContainer.setRightActionsElement(element);
4294
4509
  }
4295
- setActive(isGroupActive, skipFocus = false, force = false) {
4296
- var _a, _b, _c, _d;
4510
+ setActive(isGroupActive, force = false) {
4297
4511
  if (!force && this.isActive === isGroupActive) {
4298
- if (!skipFocus) {
4299
- (_b = (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a);
4300
- }
4301
4512
  return;
4302
4513
  }
4303
4514
  this._isGroupActive = isGroupActive;
@@ -4308,11 +4519,6 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4308
4519
  this.doSetActivePanel(this.panels[0]);
4309
4520
  }
4310
4521
  this.updateContainer();
4311
- if (isGroupActive) {
4312
- if (!skipFocus) {
4313
- (_d = (_c = this._activePanel) === null || _c === void 0 ? void 0 : _c.focus) === null || _d === void 0 ? void 0 : _d.call(_c);
4314
- }
4315
- }
4316
4522
  }
4317
4523
  layout(width, height) {
4318
4524
  var _a;
@@ -4323,17 +4529,22 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4323
4529
  this._activePanel.layout(this._width, this._height);
4324
4530
  }
4325
4531
  }
4326
- _removePanel(panel) {
4532
+ _removePanel(panel, options) {
4327
4533
  const isActivePanel = this._activePanel === panel;
4328
4534
  this.doRemovePanel(panel);
4329
4535
  if (isActivePanel && this.panels.length > 0) {
4330
4536
  const nextPanel = this.mostRecentlyUsed[0];
4331
- this.openPanel(nextPanel);
4537
+ this.openPanel(nextPanel, {
4538
+ skipSetActive: options.skipSetActive,
4539
+ skipSetGroupActive: options.skipSetActiveGroup,
4540
+ });
4332
4541
  }
4333
4542
  if (this._activePanel && this.panels.length === 0) {
4334
4543
  this.doSetActivePanel(undefined);
4335
4544
  }
4336
- this.updateContainer();
4545
+ if (!options.skipSetActive) {
4546
+ this.updateContainer();
4547
+ }
4337
4548
  return panel;
4338
4549
  }
4339
4550
  doRemovePanel(panel) {
@@ -4348,13 +4559,13 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4348
4559
  }
4349
4560
  this._onDidRemovePanel.fire({ panel });
4350
4561
  }
4351
- doAddPanel(panel, index = this.panels.length, skipSetActive = false) {
4562
+ doAddPanel(panel, index = this.panels.length, options = { skipSetActive: false }) {
4352
4563
  const existingPanel = this._panels.indexOf(panel);
4353
4564
  const hasExistingPanel = existingPanel > -1;
4354
4565
  this.tabsContainer.show();
4355
4566
  this.contentContainer.show();
4356
4567
  this.tabsContainer.openPanel(panel, index);
4357
- if (!skipSetActive) {
4568
+ if (!options.skipSetActive) {
4358
4569
  this.contentContainer.openPanel(panel);
4359
4570
  }
4360
4571
  if (hasExistingPanel) {
@@ -4366,12 +4577,17 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4366
4577
  this._onDidAddPanel.fire({ panel });
4367
4578
  }
4368
4579
  doSetActivePanel(panel) {
4580
+ if (this._activePanel === panel) {
4581
+ return;
4582
+ }
4369
4583
  this._activePanel = panel;
4370
4584
  if (panel) {
4371
4585
  this.tabsContainer.setActivePanel(panel);
4372
4586
  panel.layout(this._width, this._height);
4373
4587
  this.updateMru(panel);
4374
- this._onDidActivePanelChange.fire({ panel });
4588
+ this._onDidActivePanelChange.fire({
4589
+ panel,
4590
+ });
4375
4591
  }
4376
4592
  }
4377
4593
  updateMru(panel) {
@@ -4383,11 +4599,11 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4383
4599
  updateContainer() {
4384
4600
  var _a, _b;
4385
4601
  toggleClass(this.container, 'empty', this.isEmpty);
4386
- this.panels.forEach((panel) => panel.updateParentGroup(this.groupPanel, this.isActive));
4602
+ this.panels.forEach((panel) => panel.runEvents());
4387
4603
  if (this.isEmpty && !this.watermark) {
4388
4604
  const watermark = this.accessor.createWatermarkComponent();
4389
4605
  watermark.init({
4390
- containerApi: new DockviewApi(this.accessor),
4606
+ containerApi: this._api,
4391
4607
  group: this.groupPanel,
4392
4608
  });
4393
4609
  this.watermark = watermark;
@@ -4420,10 +4636,32 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4420
4636
  }
4421
4637
  return false;
4422
4638
  }
4423
- handleDropEvent(event, position, index) {
4639
+ handleDropEvent(type, event, position, index) {
4424
4640
  if (this.locked === 'no-drop-target') {
4425
4641
  return;
4426
4642
  }
4643
+ function getKind() {
4644
+ switch (type) {
4645
+ case 'header':
4646
+ return typeof index === 'number' ? 'tab' : 'header_space';
4647
+ case 'content':
4648
+ return 'content';
4649
+ }
4650
+ }
4651
+ const panel = typeof index === 'number' ? this.panels[index] : undefined;
4652
+ const willDropEvent = new DockviewWillDropEvent({
4653
+ nativeEvent: event,
4654
+ position,
4655
+ panel,
4656
+ getData: () => getPanelData(),
4657
+ kind: getKind(),
4658
+ group: this.groupPanel,
4659
+ api: this._api,
4660
+ });
4661
+ this._onWillDrop.fire(willDropEvent);
4662
+ if (willDropEvent.defaultPrevented) {
4663
+ return;
4664
+ }
4427
4665
  const data = getPanelData();
4428
4666
  if (data && data.viewId === this.accessor.id) {
4429
4667
  if (data.panelId === null) {
@@ -4456,12 +4694,14 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4456
4694
  });
4457
4695
  }
4458
4696
  else {
4459
- this._onDidDrop.fire({
4697
+ this._onDidDrop.fire(new DockviewDidDropEvent({
4460
4698
  nativeEvent: event,
4461
4699
  position,
4462
- index,
4700
+ panel,
4463
4701
  getData: () => getPanelData(),
4464
- });
4702
+ group: this.groupPanel,
4703
+ api: this._api,
4704
+ }));
4465
4705
  }
4466
4706
  }
4467
4707
  dispose() {
@@ -4469,6 +4709,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4469
4709
  super.dispose();
4470
4710
  (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
4471
4711
  (_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
4712
+ this.watermark = undefined;
4472
4713
  for (const panel of this.panels) {
4473
4714
  panel.dispose();
4474
4715
  }
@@ -4490,15 +4731,7 @@ class Resizable extends CompositeDisposable {
4490
4731
  constructor(parentElement, disableResizing = false) {
4491
4732
  super();
4492
4733
  this._disableResizing = disableResizing;
4493
- if (parentElement) {
4494
- this._element = parentElement;
4495
- }
4496
- else {
4497
- this._element = document.createElement('div');
4498
- this._element.style.height = '100%';
4499
- this._element.style.width = '100%';
4500
- this._element.className = 'dv-resizable-container';
4501
- }
4734
+ this._element = parentElement;
4502
4735
  this.addDisposables(watchElementResize(this._element, (entry) => {
4503
4736
  if (this.isDisposed) {
4504
4737
  /**
@@ -4586,25 +4819,38 @@ class BaseGrid extends Resizable {
4586
4819
  get activeGroup() {
4587
4820
  return this._activeGroup;
4588
4821
  }
4822
+ get locked() {
4823
+ return this.gridview.locked;
4824
+ }
4825
+ set locked(value) {
4826
+ this.gridview.locked = value;
4827
+ }
4589
4828
  constructor(options) {
4590
- super(options.parentElement, options.disableAutoResizing);
4829
+ super(document.createElement('div'), options.disableAutoResizing);
4591
4830
  this._id = nextLayoutId$1.next();
4592
4831
  this._groups = new Map();
4593
4832
  this._onDidLayoutChange = new Emitter();
4594
4833
  this.onDidLayoutChange = this._onDidLayoutChange.event;
4595
- this._onDidRemoveGroup = new Emitter();
4596
- this.onDidRemoveGroup = this._onDidRemoveGroup.event;
4597
- this._onDidAddGroup = new Emitter();
4598
- this.onDidAddGroup = this._onDidAddGroup.event;
4599
- this._onDidActiveGroupChange = new Emitter();
4600
- this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
4834
+ this._onDidRemove = new Emitter();
4835
+ this.onDidRemove = this._onDidRemove.event;
4836
+ this._onDidAdd = new Emitter();
4837
+ this.onDidAdd = this._onDidAdd.event;
4838
+ this._onDidActiveChange = new Emitter();
4839
+ this.onDidActiveChange = this._onDidActiveChange.event;
4601
4840
  this._bufferOnDidLayoutChange = new TickDelayedEvent();
4841
+ this.element.style.height = '100%';
4842
+ this.element.style.width = '100%';
4843
+ options.parentElement.appendChild(this.element);
4602
4844
  this.gridview = new Gridview(!!options.proportionalLayout, options.styles, options.orientation);
4845
+ this.gridview.locked = !!options.locked;
4603
4846
  this.element.appendChild(this.gridview.element);
4604
4847
  this.layout(0, 0, true); // set some elements height/widths
4605
- this.addDisposables(this.gridview.onDidChange(() => {
4848
+ this.addDisposables(Disposable.from(() => {
4849
+ var _a;
4850
+ (_a = this.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.element);
4851
+ }), this.gridview.onDidChange(() => {
4606
4852
  this._bufferOnDidLayoutChange.fire();
4607
- }), Event.any(this.onDidAddGroup, this.onDidRemoveGroup, this.onDidActiveGroupChange)(() => {
4853
+ }), Event.any(this.onDidAdd, this.onDidRemove, this.onDidActiveChange)(() => {
4608
4854
  this._bufferOnDidLayoutChange.fire();
4609
4855
  }), this._bufferOnDidLayoutChange.onEvent(() => {
4610
4856
  this._onDidLayoutChange.fire();
@@ -4619,6 +4865,7 @@ class BaseGrid extends Resizable {
4619
4865
  }
4620
4866
  maximizeGroup(panel) {
4621
4867
  this.gridview.maximizeView(panel);
4868
+ this.doSetGroupActive(panel);
4622
4869
  }
4623
4870
  isMaximizedGroup(panel) {
4624
4871
  return this.gridview.maximizedView() === panel;
@@ -4629,13 +4876,12 @@ class BaseGrid extends Resizable {
4629
4876
  hasMaximizedGroup() {
4630
4877
  return this.gridview.hasMaximizedView();
4631
4878
  }
4632
- get onDidMaxmizedGroupChange() {
4633
- return this.gridview.onDidMaxmizedNodeChange;
4879
+ get onDidMaximizedGroupChange() {
4880
+ return this.gridview.onDidMaximizedNodeChange;
4634
4881
  }
4635
4882
  doAddGroup(group, location = [0], size) {
4636
4883
  this.gridview.addView(group, size !== null && size !== void 0 ? size : Sizing.Distribute, location);
4637
- this._onDidAddGroup.fire(group);
4638
- this.doSetGroupActive(group);
4884
+ this._onDidAdd.fire(group);
4639
4885
  }
4640
4886
  doRemoveGroup(group, options) {
4641
4887
  if (!this._groups.has(group.id)) {
@@ -4647,8 +4893,8 @@ class BaseGrid extends Resizable {
4647
4893
  item.disposable.dispose();
4648
4894
  item.value.dispose();
4649
4895
  this._groups.delete(group.id);
4896
+ this._onDidRemove.fire(group);
4650
4897
  }
4651
- this._onDidRemoveGroup.fire(group);
4652
4898
  if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
4653
4899
  const groups = Array.from(this._groups.values());
4654
4900
  this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
@@ -4659,25 +4905,18 @@ class BaseGrid extends Resizable {
4659
4905
  var _a;
4660
4906
  return (_a = this._groups.get(id)) === null || _a === void 0 ? void 0 : _a.value;
4661
4907
  }
4662
- doSetGroupActive(group, skipFocus) {
4663
- var _a, _b, _c;
4908
+ doSetGroupActive(group) {
4664
4909
  if (this._activeGroup === group) {
4665
4910
  return;
4666
4911
  }
4667
4912
  if (this._activeGroup) {
4668
4913
  this._activeGroup.setActive(false);
4669
- if (!skipFocus) {
4670
- (_b = (_a = this._activeGroup).focus) === null || _b === void 0 ? void 0 : _b.call(_a);
4671
- }
4672
4914
  }
4673
4915
  if (group) {
4674
4916
  group.setActive(true);
4675
- if (!skipFocus) {
4676
- (_c = group.focus) === null || _c === void 0 ? void 0 : _c.call(group);
4677
- }
4678
4917
  }
4679
4918
  this._activeGroup = group;
4680
- this._onDidActiveGroupChange.fire(group);
4919
+ this._onDidActiveChange.fire(group);
4681
4920
  }
4682
4921
  removeGroup(group) {
4683
4922
  this.doRemoveGroup(group);
@@ -4722,9 +4961,9 @@ class BaseGrid extends Resizable {
4722
4961
  this.gridview.layout(width, height);
4723
4962
  }
4724
4963
  dispose() {
4725
- this._onDidActiveGroupChange.dispose();
4726
- this._onDidAddGroup.dispose();
4727
- this._onDidRemoveGroup.dispose();
4964
+ this._onDidActiveChange.dispose();
4965
+ this._onDidAdd.dispose();
4966
+ this._onDidRemove.dispose();
4728
4967
  this._onDidLayoutChange.dispose();
4729
4968
  for (const group of this.groups) {
4730
4969
  group.dispose();
@@ -4734,11 +4973,15 @@ class BaseGrid extends Resizable {
4734
4973
  }
4735
4974
  }
4736
4975
 
4976
+ class WillFocusEvent extends DockviewEvent {
4977
+ constructor() {
4978
+ super();
4979
+ }
4980
+ }
4737
4981
  /**
4738
4982
  * A core api implementation that should be used across all panel-like objects
4739
4983
  */
4740
4984
  class PanelApiImpl extends CompositeDisposable {
4741
- //
4742
4985
  get isFocused() {
4743
4986
  return this._isFocused;
4744
4987
  }
@@ -4748,6 +4991,9 @@ class PanelApiImpl extends CompositeDisposable {
4748
4991
  get isVisible() {
4749
4992
  return this._isVisible;
4750
4993
  }
4994
+ get isHidden() {
4995
+ return this._isHidden;
4996
+ }
4751
4997
  get width() {
4752
4998
  return this._width;
4753
4999
  }
@@ -4760,38 +5006,26 @@ class PanelApiImpl extends CompositeDisposable {
4760
5006
  this._isFocused = false;
4761
5007
  this._isActive = false;
4762
5008
  this._isVisible = true;
5009
+ this._isHidden = false;
4763
5010
  this._width = 0;
4764
5011
  this._height = 0;
4765
5012
  this.panelUpdatesDisposable = new MutableDisposable();
4766
- this._onDidDimensionChange = new Emitter({
4767
- replay: true,
4768
- });
5013
+ this._onDidDimensionChange = new Emitter();
4769
5014
  this.onDidDimensionsChange = this._onDidDimensionChange.event;
4770
- //
4771
- this._onDidChangeFocus = new Emitter({
4772
- replay: true,
4773
- });
5015
+ this._onDidChangeFocus = new Emitter();
4774
5016
  this.onDidFocusChange = this._onDidChangeFocus.event;
4775
5017
  //
4776
- this._onFocusEvent = new Emitter();
4777
- this.onFocusEvent = this._onFocusEvent.event;
5018
+ this._onWillFocus = new Emitter();
5019
+ this.onWillFocus = this._onWillFocus.event;
4778
5020
  //
4779
- this._onDidVisibilityChange = new Emitter({
4780
- replay: true,
4781
- });
5021
+ this._onDidVisibilityChange = new Emitter();
4782
5022
  this.onDidVisibilityChange = this._onDidVisibilityChange.event;
4783
- //
4784
- this._onVisibilityChange = new Emitter();
4785
- this.onVisibilityChange = this._onVisibilityChange.event;
4786
- //
4787
- this._onDidActiveChange = new Emitter({
4788
- replay: true,
4789
- });
5023
+ this._onDidHiddenChange = new Emitter();
5024
+ this.onDidHiddenChange = this._onDidHiddenChange.event;
5025
+ this._onDidActiveChange = new Emitter();
4790
5026
  this.onDidActiveChange = this._onDidActiveChange.event;
4791
- //
4792
5027
  this._onActiveChange = new Emitter();
4793
5028
  this.onActiveChange = this._onActiveChange.event;
4794
- //
4795
5029
  this._onUpdateParameters = new Emitter();
4796
5030
  this.onUpdateParameters = this._onUpdateParameters.event;
4797
5031
  this.addDisposables(this.onDidFocusChange((event) => {
@@ -4800,10 +5034,12 @@ class PanelApiImpl extends CompositeDisposable {
4800
5034
  this._isActive = event.isActive;
4801
5035
  }), this.onDidVisibilityChange((event) => {
4802
5036
  this._isVisible = event.isVisible;
5037
+ }), this.onDidHiddenChange((event) => {
5038
+ this._isHidden = event.isHidden;
4803
5039
  }), this.onDidDimensionsChange((event) => {
4804
5040
  this._width = event.width;
4805
5041
  this._height = event.height;
4806
- }), this.panelUpdatesDisposable, this._onDidDimensionChange, this._onDidChangeFocus, this._onDidVisibilityChange, this._onDidActiveChange, this._onFocusEvent, this._onActiveChange, this._onVisibilityChange, this._onUpdateParameters);
5042
+ }), this.panelUpdatesDisposable, this._onDidDimensionChange, this._onDidChangeFocus, this._onDidVisibilityChange, this._onDidActiveChange, this._onWillFocus, this._onActiveChange, this._onUpdateParameters, this._onWillFocus, this._onDidHiddenChange, this._onUpdateParameters);
4807
5043
  }
4808
5044
  initialize(panel) {
4809
5045
  this.panelUpdatesDisposable.value = this._onUpdateParameters.event((parameters) => {
@@ -4812,8 +5048,8 @@ class PanelApiImpl extends CompositeDisposable {
4812
5048
  });
4813
5049
  });
4814
5050
  }
4815
- setVisible(isVisible) {
4816
- this._onVisibilityChange.fire({ isVisible });
5051
+ setHidden(isHidden) {
5052
+ this._onDidHiddenChange.fire({ isHidden });
4817
5053
  }
4818
5054
  setActive() {
4819
5055
  this._onActiveChange.fire();
@@ -4821,9 +5057,6 @@ class PanelApiImpl extends CompositeDisposable {
4821
5057
  updateParameters(parameters) {
4822
5058
  this._onUpdateParameters.fire(parameters);
4823
5059
  }
4824
- dispose() {
4825
- super.dispose();
4826
- }
4827
5060
  }
4828
5061
 
4829
5062
  class SplitviewPanelApiImpl extends PanelApiImpl {
@@ -4911,7 +5144,12 @@ class BasePanelView extends CompositeDisposable {
4911
5144
  }), focusTracker);
4912
5145
  }
4913
5146
  focus() {
4914
- this.api._onFocusEvent.fire();
5147
+ const event = new WillFocusEvent();
5148
+ this.api._onWillFocus.fire(event);
5149
+ if (event.defaultPrevented) {
5150
+ return;
5151
+ }
5152
+ this._element.focus();
4915
5153
  }
4916
5154
  layout(width, height) {
4917
5155
  this._width = width;
@@ -5240,9 +5478,7 @@ class GridviewPanelApiImpl extends PanelApiImpl {
5240
5478
  super(id);
5241
5479
  this._onDidConstraintsChangeInternal = new Emitter();
5242
5480
  this.onDidConstraintsChangeInternal = this._onDidConstraintsChangeInternal.event;
5243
- this._onDidConstraintsChange = new Emitter({
5244
- replay: true,
5245
- });
5481
+ this._onDidConstraintsChange = new Emitter();
5246
5482
  this.onDidConstraintsChange = this._onDidConstraintsChange.event;
5247
5483
  this._onDidSizeChange = new Emitter();
5248
5484
  this.onDidSizeChange = this._onDidSizeChange.event;
@@ -5335,13 +5571,13 @@ class GridviewPanel extends BasePanelView {
5335
5571
  this._maximumHeight = options.maximumHeight;
5336
5572
  }
5337
5573
  this.api.initialize(this); // TODO: required to by-pass 'super before this' requirement
5338
- this.addDisposables(this.api.onVisibilityChange((event) => {
5339
- const { isVisible } = event;
5574
+ this.addDisposables(this.api.onDidHiddenChange((event) => {
5575
+ const { isHidden } = event;
5340
5576
  const { accessor } = this._params;
5341
- accessor.setVisible(this, isVisible);
5577
+ accessor.setVisible(this, !isHidden);
5342
5578
  }), this.api.onActiveChange(() => {
5343
5579
  const { accessor } = this._params;
5344
- accessor.setActive(this);
5580
+ accessor.doSetGroupActive(this);
5345
5581
  }), this.api.onDidConstraintsChangeInternal((event) => {
5346
5582
  if (typeof event.minimumWidth === 'number' ||
5347
5583
  typeof event.minimumWidth === 'function') {
@@ -5424,6 +5660,17 @@ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
5424
5660
  this.onDidLocationChange = this._onDidLocationChange.event;
5425
5661
  this.addDisposables(this._onDidLocationChange);
5426
5662
  }
5663
+ close() {
5664
+ if (!this._group) {
5665
+ return;
5666
+ }
5667
+ return this.accessor.removeGroup(this._group);
5668
+ }
5669
+ getWindow() {
5670
+ return this.location.type === 'popout'
5671
+ ? this.location.getWindow()
5672
+ : window;
5673
+ }
5427
5674
  moveTo(options) {
5428
5675
  var _a, _b, _c;
5429
5676
  if (!this._group) {
@@ -5431,14 +5678,23 @@ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
5431
5678
  }
5432
5679
  const group = (_a = options.group) !== null && _a !== void 0 ? _a : this.accessor.addGroup({
5433
5680
  direction: positionToDirection((_b = options.position) !== null && _b !== void 0 ? _b : 'right'),
5681
+ skipSetActive: true,
5682
+ });
5683
+ this.accessor.moveGroupOrPanel({
5684
+ from: { groupId: this._group.id },
5685
+ to: {
5686
+ group,
5687
+ position: options.group
5688
+ ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center'
5689
+ : 'center',
5690
+ },
5434
5691
  });
5435
- this.accessor.moveGroupOrPanel(group, this._group.id, undefined, options.group ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center' : 'center');
5436
5692
  }
5437
5693
  maximize() {
5438
5694
  if (!this._group) {
5439
5695
  throw new Error(NOT_INITIALIZED_MESSAGE);
5440
5696
  }
5441
- if (this.location !== 'grid') {
5697
+ if (this.location.type !== 'grid') {
5442
5698
  // only grid groups can be maximized
5443
5699
  return;
5444
5700
  }
@@ -5495,6 +5751,12 @@ class DockviewGroupPanel extends GridviewPanel {
5495
5751
  this.api.initialize(this); // cannot use 'this' after after 'super' call
5496
5752
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
5497
5753
  }
5754
+ focus() {
5755
+ if (!this.api.isActive) {
5756
+ this.api.setActive();
5757
+ }
5758
+ super.focus();
5759
+ }
5498
5760
  initialize() {
5499
5761
  this._model.initialize();
5500
5762
  }
@@ -5540,6 +5802,9 @@ function isGroupOptionsWithGroup(data) {
5540
5802
  }
5541
5803
 
5542
5804
  class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5805
+ get location() {
5806
+ return this.group.api.location;
5807
+ }
5543
5808
  get title() {
5544
5809
  return this.panel.title;
5545
5810
  }
@@ -5551,15 +5816,34 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5551
5816
  }
5552
5817
  set group(value) {
5553
5818
  const isOldGroupActive = this.isGroupActive;
5554
- this._group = value;
5555
- this._onDidGroupChange.fire();
5556
- if (this._group) {
5557
- this.disposable.value = this._group.api.onDidActiveChange(() => {
5558
- this._onDidActiveGroupChange.fire();
5819
+ if (this._group !== value) {
5820
+ this._group = value;
5821
+ this._onDidGroupChange.fire({});
5822
+ let _trackGroupActive = isOldGroupActive; // prevent duplicate events with same state
5823
+ this.groupEventsDisposable.value = new CompositeDisposable(this.group.api.onDidLocationChange((event) => {
5824
+ if (this.group !== this.panel.group) {
5825
+ return;
5826
+ }
5827
+ this._onDidLocationChange.fire(event);
5828
+ }), this.group.api.onDidActiveChange(() => {
5829
+ if (this.group !== this.panel.group) {
5830
+ return;
5831
+ }
5832
+ if (_trackGroupActive !== this.isGroupActive) {
5833
+ _trackGroupActive = this.isGroupActive;
5834
+ this._onDidActiveGroupChange.fire({
5835
+ isActive: this.isGroupActive,
5836
+ });
5837
+ }
5838
+ }));
5839
+ // if (this.isGroupActive !== isOldGroupActive) {
5840
+ // this._onDidActiveGroupChange.fire({
5841
+ // isActive: this.isGroupActive,
5842
+ // });
5843
+ // }
5844
+ this._onDidLocationChange.fire({
5845
+ location: this.group.api.location,
5559
5846
  });
5560
- if (this.isGroupActive !== isOldGroupActive) {
5561
- this._onDidActiveGroupChange.fire();
5562
- }
5563
5847
  }
5564
5848
  }
5565
5849
  get group() {
@@ -5577,14 +5861,26 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5577
5861
  this.onDidGroupChange = this._onDidGroupChange.event;
5578
5862
  this._onDidRendererChange = new Emitter();
5579
5863
  this.onDidRendererChange = this._onDidRendererChange.event;
5580
- this.disposable = new MutableDisposable();
5864
+ this._onDidLocationChange = new Emitter();
5865
+ this.onDidLocationChange = this._onDidLocationChange.event;
5866
+ this.groupEventsDisposable = new MutableDisposable();
5581
5867
  this.initialize(panel);
5582
5868
  this._group = group;
5583
- this.addDisposables(this.disposable, this._onDidRendererChange, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5869
+ this.addDisposables(this.groupEventsDisposable, this._onDidRendererChange, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange, this._onDidLocationChange);
5870
+ }
5871
+ getWindow() {
5872
+ return this.group.api.getWindow();
5584
5873
  }
5585
5874
  moveTo(options) {
5586
5875
  var _a;
5587
- this.accessor.moveGroupOrPanel(options.group, this._group.id, this.panel.id, (_a = options.position) !== null && _a !== void 0 ? _a : 'center', options.index);
5876
+ this.accessor.moveGroupOrPanel({
5877
+ from: { groupId: this._group.id, panelId: this.panel.id },
5878
+ to: {
5879
+ group: options.group,
5880
+ position: (_a = options.position) !== null && _a !== void 0 ? _a : 'center',
5881
+ index: options.index,
5882
+ },
5883
+ });
5588
5884
  }
5589
5885
  setTitle(title) {
5590
5886
  this.panel.setTitle(title);
@@ -5645,7 +5941,14 @@ class DockviewPanel extends CompositeDisposable {
5645
5941
  this.setTitle(params.title);
5646
5942
  }
5647
5943
  focus() {
5648
- this.api._onFocusEvent.fire();
5944
+ const event = new WillFocusEvent();
5945
+ this.api._onWillFocus.fire(event);
5946
+ if (event.defaultPrevented) {
5947
+ return;
5948
+ }
5949
+ if (!this.api.isActive) {
5950
+ this.api.setActive();
5951
+ }
5649
5952
  }
5650
5953
  toJSON() {
5651
5954
  return {
@@ -5702,20 +6005,40 @@ class DockviewPanel extends CompositeDisposable {
5702
6005
  },
5703
6006
  });
5704
6007
  }
5705
- updateParentGroup(group, isGroupActive) {
6008
+ updateParentGroup(group, options) {
5706
6009
  this._group = group;
5707
- this.api.group = group;
6010
+ this.api.group = this._group;
5708
6011
  const isPanelVisible = this._group.model.isPanelActive(this);
5709
- this.api._onDidActiveChange.fire({
5710
- isActive: isGroupActive && isPanelVisible,
5711
- });
5712
- this.api._onDidVisibilityChange.fire({
5713
- isVisible: isPanelVisible,
5714
- });
5715
- this.view.updateParentGroup(this._group, this._group.model.isPanelActive(this));
6012
+ const isActive = this.group.api.isActive && isPanelVisible;
6013
+ if (!(options === null || options === void 0 ? void 0 : options.skipSetActive)) {
6014
+ if (this.api.isActive !== isActive) {
6015
+ this.api._onDidActiveChange.fire({
6016
+ isActive: this.group.api.isActive && isPanelVisible,
6017
+ });
6018
+ }
6019
+ }
6020
+ if (this.api.isVisible !== isPanelVisible) {
6021
+ this.api._onDidVisibilityChange.fire({
6022
+ isVisible: isPanelVisible,
6023
+ });
6024
+ }
6025
+ }
6026
+ runEvents() {
6027
+ const isPanelVisible = this._group.model.isPanelActive(this);
6028
+ const isActive = this.group.api.isActive && isPanelVisible;
6029
+ if (this.api.isActive !== isActive) {
6030
+ this.api._onDidActiveChange.fire({
6031
+ isActive: this.group.api.isActive && isPanelVisible,
6032
+ });
6033
+ }
6034
+ if (this.api.isVisible !== isPanelVisible) {
6035
+ this.api._onDidVisibilityChange.fire({
6036
+ isVisible: isPanelVisible,
6037
+ });
6038
+ }
5716
6039
  }
5717
6040
  layout(width, height) {
5718
- // the obtain the correct dimensions of the content panel we must deduct the tab height
6041
+ // TODO: Can we somehow do height without header height or indicate what the header height is?
5719
6042
  this.api._onDidDimensionChange.fire({
5720
6043
  width,
5721
6044
  height: height,
@@ -5837,8 +6160,6 @@ class DockviewPanelModel {
5837
6160
  this.id = id;
5838
6161
  this.contentComponent = contentComponent;
5839
6162
  this.tabComponent = tabComponent;
5840
- this._group = null;
5841
- this._isPanelVisible = null;
5842
6163
  this._content = this.createContentComponent(this.id, contentComponent);
5843
6164
  this._tab = this.createTabComponent(this.id, tabComponent);
5844
6165
  }
@@ -5846,25 +6167,8 @@ class DockviewPanelModel {
5846
6167
  this.content.init(Object.assign(Object.assign({}, params), { tab: this.tab }));
5847
6168
  this.tab.init(params);
5848
6169
  }
5849
- updateParentGroup(group, isPanelVisible) {
5850
- if (group !== this._group) {
5851
- this._group = group;
5852
- if (this._content.onGroupChange) {
5853
- this._content.onGroupChange(group);
5854
- }
5855
- if (this._tab.onGroupChange) {
5856
- this._tab.onGroupChange(group);
5857
- }
5858
- }
5859
- if (isPanelVisible !== this._isPanelVisible) {
5860
- this._isPanelVisible = isPanelVisible;
5861
- if (this._content.onPanelVisibleChange) {
5862
- this._content.onPanelVisibleChange(isPanelVisible);
5863
- }
5864
- if (this._tab.onPanelVisibleChange) {
5865
- this._tab.onPanelVisibleChange(isPanelVisible);
5866
- }
5867
- }
6170
+ updateParentGroup(_group, _isPanelVisible) {
6171
+ // noop
5868
6172
  }
5869
6173
  layout(width, height) {
5870
6174
  var _a, _b;
@@ -6297,117 +6601,6 @@ class DockviewFloatingGroupPanel extends CompositeDisposable {
6297
6601
  }
6298
6602
  }
6299
6603
 
6300
- class PopoutWindow extends CompositeDisposable {
6301
- constructor(id, className, options) {
6302
- super();
6303
- this.id = id;
6304
- this.className = className;
6305
- this.options = options;
6306
- this._onDidClose = new Emitter();
6307
- this.onDidClose = this._onDidClose.event;
6308
- this._window = null;
6309
- this.addDisposables(this._onDidClose, {
6310
- dispose: () => {
6311
- this.close();
6312
- },
6313
- });
6314
- }
6315
- dimensions() {
6316
- if (!this._window) {
6317
- return null;
6318
- }
6319
- const left = this._window.value.screenX;
6320
- const top = this._window.value.screenY;
6321
- const width = this._window.value.innerWidth;
6322
- const height = this._window.value.innerHeight;
6323
- return { top, left, width, height };
6324
- }
6325
- close() {
6326
- if (this._window) {
6327
- this._window.disposable.dispose();
6328
- this._window.value.close();
6329
- this._window = null;
6330
- }
6331
- }
6332
- open(content) {
6333
- if (this._window) {
6334
- throw new Error('instance of popout window is already open');
6335
- }
6336
- const url = `${this.options.url}`;
6337
- const features = Object.entries({
6338
- top: this.options.top,
6339
- left: this.options.left,
6340
- width: this.options.width,
6341
- height: this.options.height,
6342
- })
6343
- .map(([key, value]) => `${key}=${value}`)
6344
- .join(',');
6345
- // https://developer.mozilla.org/en-US/docs/Web/API/Window/open
6346
- const externalWindow = window.open(url, this.id, features);
6347
- if (!externalWindow) {
6348
- return;
6349
- }
6350
- const disposable = new CompositeDisposable();
6351
- this._window = { value: externalWindow, disposable };
6352
- const cleanUp = () => {
6353
- this._onDidClose.fire();
6354
- this._window = null;
6355
- };
6356
- // prevent any default content from loading
6357
- // externalWindow.document.body.replaceWith(document.createElement('div'));
6358
- disposable.addDisposables(addDisposableWindowListener(window, 'beforeunload', () => {
6359
- cleanUp();
6360
- this.close();
6361
- }));
6362
- externalWindow.addEventListener('load', () => {
6363
- const externalDocument = externalWindow.document;
6364
- externalDocument.title = document.title;
6365
- const div = document.createElement('div');
6366
- div.classList.add('dv-popout-window');
6367
- div.style.position = 'absolute';
6368
- div.style.width = '100%';
6369
- div.style.height = '100%';
6370
- div.style.top = '0px';
6371
- div.style.left = '0px';
6372
- div.classList.add(this.className);
6373
- div.appendChild(content);
6374
- externalDocument.body.replaceChildren(div);
6375
- externalDocument.body.classList.add(this.className);
6376
- addStyles(externalDocument, window.document.styleSheets);
6377
- externalWindow.addEventListener('beforeunload', () => {
6378
- // TODO: indicate external window is closing
6379
- cleanUp();
6380
- });
6381
- });
6382
- }
6383
- }
6384
-
6385
- class DockviewPopoutGroupPanel extends CompositeDisposable {
6386
- constructor(id, group, options) {
6387
- var _a;
6388
- super();
6389
- this.id = id;
6390
- this.group = group;
6391
- this.options = options;
6392
- this.window = new PopoutWindow(id, (_a = options.className) !== null && _a !== void 0 ? _a : '', {
6393
- url: this.options.popoutUrl,
6394
- left: this.options.box.left,
6395
- top: this.options.box.top,
6396
- width: this.options.box.width,
6397
- height: this.options.box.height,
6398
- });
6399
- group.model.location = 'popout';
6400
- this.addDisposables(this.window, {
6401
- dispose: () => {
6402
- group.model.location = 'grid';
6403
- },
6404
- }, this.window.onDidClose(() => {
6405
- this.dispose();
6406
- }));
6407
- this.window.open(group.element);
6408
- }
6409
- }
6410
-
6411
6604
  const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
6412
6605
  const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100 };
6413
6606
 
@@ -6421,11 +6614,13 @@ class OverlayRenderContainer extends CompositeDisposable {
6421
6614
  super();
6422
6615
  this.element = element;
6423
6616
  this.map = {};
6617
+ this._disposed = false;
6424
6618
  this.addDisposables(Disposable.from(() => {
6425
6619
  for (const value of Object.values(this.map)) {
6426
6620
  value.disposable.dispose();
6427
6621
  value.destroy.dispose();
6428
6622
  }
6623
+ this._disposed = true;
6429
6624
  }));
6430
6625
  }
6431
6626
  detatch(panel) {
@@ -6465,7 +6660,7 @@ class OverlayRenderContainer extends CompositeDisposable {
6465
6660
  focusContainer.style.top = `${box.top - box2.top}px`;
6466
6661
  focusContainer.style.width = `${box.width}px`;
6467
6662
  focusContainer.style.height = `${box.height}px`;
6468
- toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location === 'floating');
6663
+ toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location.type === 'floating');
6469
6664
  };
6470
6665
  const visibilityChanged = () => {
6471
6666
  if (panel.api.isVisible) {
@@ -6511,8 +6706,11 @@ class OverlayRenderContainer extends CompositeDisposable {
6511
6706
  resize();
6512
6707
  }));
6513
6708
  this.map[panel.api.id].destroy = Disposable.from(() => {
6514
- focusContainer.removeChild(panel.view.content.element);
6515
- this.element.removeChild(focusContainer);
6709
+ var _a;
6710
+ if (panel.view.content.element.parentElement === focusContainer) {
6711
+ focusContainer.removeChild(panel.view.content.element);
6712
+ }
6713
+ (_a = focusContainer.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(focusContainer);
6516
6714
  });
6517
6715
  queueMicrotask(() => {
6518
6716
  if (this.isDisposed) {
@@ -6533,11 +6731,164 @@ class OverlayRenderContainer extends CompositeDisposable {
6533
6731
  }
6534
6732
  }
6535
6733
 
6734
+ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
6735
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6736
+ return new (P || (P = Promise))(function (resolve, reject) {
6737
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6738
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6739
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
6740
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
6741
+ });
6742
+ };
6743
+ class PopoutWindow extends CompositeDisposable {
6744
+ get window() {
6745
+ var _a, _b;
6746
+ return (_b = (_a = this._window) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null;
6747
+ }
6748
+ constructor(target, className, options) {
6749
+ super();
6750
+ this.target = target;
6751
+ this.className = className;
6752
+ this.options = options;
6753
+ this._onWillClose = new Emitter();
6754
+ this.onWillClose = this._onWillClose.event;
6755
+ this._onDidClose = new Emitter();
6756
+ this.onDidClose = this._onDidClose.event;
6757
+ this._window = null;
6758
+ this.addDisposables(this._onWillClose, this._onDidClose, {
6759
+ dispose: () => {
6760
+ this.close();
6761
+ },
6762
+ });
6763
+ }
6764
+ dimensions() {
6765
+ if (!this._window) {
6766
+ return null;
6767
+ }
6768
+ const left = this._window.value.screenX;
6769
+ const top = this._window.value.screenY;
6770
+ const width = this._window.value.innerWidth;
6771
+ const height = this._window.value.innerHeight;
6772
+ return { top, left, width, height };
6773
+ }
6774
+ close() {
6775
+ var _a, _b;
6776
+ if (this._window) {
6777
+ this._onWillClose.fire();
6778
+ (_b = (_a = this.options).onWillClose) === null || _b === void 0 ? void 0 : _b.call(_a, {
6779
+ id: this.target,
6780
+ window: this._window.value,
6781
+ });
6782
+ this._window.disposable.dispose();
6783
+ this._window.value.close();
6784
+ this._window = null;
6785
+ this._onDidClose.fire();
6786
+ }
6787
+ }
6788
+ open() {
6789
+ var _a, _b;
6790
+ return __awaiter(this, void 0, void 0, function* () {
6791
+ if (this._window) {
6792
+ throw new Error('instance of popout window is already open');
6793
+ }
6794
+ const url = `${this.options.url}`;
6795
+ const features = Object.entries({
6796
+ top: this.options.top,
6797
+ left: this.options.left,
6798
+ width: this.options.width,
6799
+ height: this.options.height,
6800
+ })
6801
+ .map(([key, value]) => `${key}=${value}`)
6802
+ .join(',');
6803
+ /**
6804
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open
6805
+ */
6806
+ const externalWindow = window.open(url, this.target, features);
6807
+ if (!externalWindow) {
6808
+ /**
6809
+ * Popup blocked
6810
+ */
6811
+ return null;
6812
+ }
6813
+ const disposable = new CompositeDisposable();
6814
+ this._window = { value: externalWindow, disposable };
6815
+ disposable.addDisposables(addDisposableWindowListener(window, 'beforeunload', () => {
6816
+ /**
6817
+ * before the main window closes we should close this popup too
6818
+ * to be good citizens
6819
+ *
6820
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
6821
+ */
6822
+ this.close();
6823
+ }));
6824
+ const container = this.createPopoutWindowContainer();
6825
+ if (this.className) {
6826
+ container.classList.add(this.className);
6827
+ }
6828
+ (_b = (_a = this.options).onDidOpen) === null || _b === void 0 ? void 0 : _b.call(_a, {
6829
+ id: this.target,
6830
+ window: externalWindow,
6831
+ });
6832
+ return new Promise((resolve) => {
6833
+ externalWindow.addEventListener('unload', (e) => {
6834
+ // if page fails to load before unloading
6835
+ // this.close();
6836
+ });
6837
+ externalWindow.addEventListener('load', () => {
6838
+ /**
6839
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
6840
+ */
6841
+ const externalDocument = externalWindow.document;
6842
+ externalDocument.title = document.title;
6843
+ externalDocument.body.appendChild(container);
6844
+ addStyles(externalDocument, window.document.styleSheets);
6845
+ /**
6846
+ * beforeunload must be registered after load for reasons I could not determine
6847
+ * otherwise the beforeunload event will not fire when the window is closed
6848
+ */
6849
+ addDisposableWindowListener(externalWindow, 'beforeunload', () => {
6850
+ /**
6851
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
6852
+ */
6853
+ this.close();
6854
+ });
6855
+ resolve(container);
6856
+ });
6857
+ });
6858
+ });
6859
+ }
6860
+ createPopoutWindowContainer() {
6861
+ const el = document.createElement('div');
6862
+ el.classList.add('dv-popout-window');
6863
+ el.id = 'dv-popout-window';
6864
+ el.style.position = 'absolute';
6865
+ el.style.width = '100%';
6866
+ el.style.height = '100%';
6867
+ el.style.top = '0px';
6868
+ el.style.left = '0px';
6869
+ return el;
6870
+ }
6871
+ }
6872
+
6536
6873
  const DEFAULT_ROOT_OVERLAY_MODEL = {
6537
6874
  activationSize: { type: 'pixels', value: 10 },
6538
6875
  size: { type: 'pixels', value: 20 },
6539
6876
  };
6540
- function getTheme(element) {
6877
+ function moveGroupWithoutDestroying(options) {
6878
+ const activePanel = options.from.activePanel;
6879
+ const panels = [...options.from.panels].map((panel) => {
6880
+ const removedPanel = options.from.model.removePanel(panel);
6881
+ options.from.model.renderContainer.detatch(panel);
6882
+ return removedPanel;
6883
+ });
6884
+ panels.forEach((panel) => {
6885
+ options.to.model.openPanel(panel, {
6886
+ skipSetActive: activePanel !== panel,
6887
+ skipSetGroupActive: true,
6888
+ });
6889
+ });
6890
+ }
6891
+ function getDockviewTheme(element) {
6541
6892
  function toClassList(element) {
6542
6893
  const list = [];
6543
6894
  for (let i = 0; i < element.classList.length; i++) {
@@ -6588,6 +6939,7 @@ class DockviewComponent extends BaseGrid {
6588
6939
  styles: options.styles,
6589
6940
  parentElement: options.parentElement,
6590
6941
  disableAutoResizing: options.disableAutoResizing,
6942
+ locked: options.locked,
6591
6943
  });
6592
6944
  this.nextGroupId = sequentialNumberGenerator();
6593
6945
  this._deserializer = new DefaultDockviewDeserialzier(this);
@@ -6598,6 +6950,10 @@ class DockviewComponent extends BaseGrid {
6598
6950
  this.onWillDragGroup = this._onWillDragGroup.event;
6599
6951
  this._onDidDrop = new Emitter();
6600
6952
  this.onDidDrop = this._onDidDrop.event;
6953
+ this._onWillDrop = new Emitter();
6954
+ this.onWillDrop = this._onWillDrop.event;
6955
+ this._onWillShowOverlay = new Emitter();
6956
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
6601
6957
  this._onDidRemovePanel = new Emitter();
6602
6958
  this.onDidRemovePanel = this._onDidRemovePanel.event;
6603
6959
  this._onDidAddPanel = new Emitter();
@@ -6606,15 +6962,36 @@ class DockviewComponent extends BaseGrid {
6606
6962
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
6607
6963
  this._onDidActivePanelChange = new Emitter();
6608
6964
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
6965
+ this._onDidMovePanel = new Emitter();
6609
6966
  this._floatingGroups = [];
6610
6967
  this._popoutGroups = [];
6968
+ this._ignoreEvents = 0;
6969
+ this._onDidRemoveGroup = new Emitter();
6970
+ this.onDidRemoveGroup = this._onDidRemoveGroup.event;
6971
+ this._onDidAddGroup = new Emitter();
6972
+ this.onDidAddGroup = this._onDidAddGroup.event;
6973
+ this._onDidActiveGroupChange = new Emitter();
6974
+ this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
6975
+ this._moving = false;
6611
6976
  const gready = document.createElement('div');
6612
6977
  gready.className = 'dv-overlay-render-container';
6613
6978
  this.gridview.element.appendChild(gready);
6614
6979
  this.overlayRenderContainer = new OverlayRenderContainer(gready);
6615
6980
  toggleClass(this.gridview.element, 'dv-dockview', true);
6616
6981
  toggleClass(this.element, 'dv-debug', !!options.debug);
6617
- this.addDisposables(this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, Event.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
6982
+ 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) => {
6983
+ if (!this._moving) {
6984
+ this._onDidAddGroup.fire(event);
6985
+ }
6986
+ }), this.onDidRemove((event) => {
6987
+ if (!this._moving) {
6988
+ this._onDidRemoveGroup.fire(event);
6989
+ }
6990
+ }), this.onDidActiveChange((event) => {
6991
+ if (!this._moving) {
6992
+ this._onDidActiveGroupChange.fire(event);
6993
+ }
6994
+ }), Event.any(this.onDidAdd, this.onDidRemove)(() => {
6618
6995
  this.updateWatermark();
6619
6996
  }), Event.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
6620
6997
  this._bufferOnDidLayoutChange.fire();
@@ -6625,7 +7002,7 @@ class DockviewComponent extends BaseGrid {
6625
7002
  }
6626
7003
  // iterate over a copy of the array since .dispose() mutates the original array
6627
7004
  for (const group of [...this._popoutGroups]) {
6628
- group.dispose();
7005
+ group.disposable.dispose();
6629
7006
  }
6630
7007
  }));
6631
7008
  this._options = options;
@@ -6671,7 +7048,7 @@ class DockviewComponent extends BaseGrid {
6671
7048
  return this.options.showDndOverlay({
6672
7049
  nativeEvent: event,
6673
7050
  position: position,
6674
- target: DockviewDropTargets.Edge,
7051
+ target: 'edge',
6675
7052
  getData: getPanelData,
6676
7053
  });
6677
7054
  }
@@ -6682,86 +7059,249 @@ class DockviewComponent extends BaseGrid {
6682
7059
  });
6683
7060
  this.addDisposables(this._rootDropTarget.onDrop((event) => {
6684
7061
  var _a;
7062
+ const willDropEvent = new DockviewWillDropEvent({
7063
+ nativeEvent: event.nativeEvent,
7064
+ position: event.position,
7065
+ panel: undefined,
7066
+ api: this._api,
7067
+ group: undefined,
7068
+ getData: getPanelData,
7069
+ kind: 'content',
7070
+ });
7071
+ this._onWillDrop.fire(willDropEvent);
7072
+ if (willDropEvent.defaultPrevented) {
7073
+ return;
7074
+ }
6685
7075
  const data = getPanelData();
6686
7076
  if (data) {
6687
- this.moveGroupOrPanel(this.orthogonalize(event.position), data.groupId, (_a = data.panelId) !== null && _a !== void 0 ? _a : undefined, 'center');
7077
+ this.moveGroupOrPanel({
7078
+ from: {
7079
+ groupId: data.groupId,
7080
+ panelId: (_a = data.panelId) !== null && _a !== void 0 ? _a : undefined,
7081
+ },
7082
+ to: {
7083
+ group: this.orthogonalize(event.position),
7084
+ position: 'center',
7085
+ },
7086
+ });
6688
7087
  }
6689
7088
  else {
6690
- this._onDidDrop.fire(Object.assign(Object.assign({}, event), { api: this._api, group: null, getData: getPanelData }));
7089
+ this._onDidDrop.fire(new DockviewDidDropEvent({
7090
+ nativeEvent: event.nativeEvent,
7091
+ position: event.position,
7092
+ panel: undefined,
7093
+ api: this._api,
7094
+ group: undefined,
7095
+ getData: getPanelData,
7096
+ }));
6691
7097
  }
6692
7098
  }), this._rootDropTarget);
6693
7099
  this._api = new DockviewApi(this);
6694
7100
  this.updateWatermark();
6695
7101
  }
6696
- addPopoutGroup(item, options) {
6697
- var _a;
6698
- let group;
6699
- let box = options === null || options === void 0 ? void 0 : options.position;
6700
- if (item instanceof DockviewPanel) {
6701
- group = this.createGroup();
6702
- this.removePanel(item, {
6703
- removeEmptyGroup: true,
6704
- skipDispose: true,
6705
- });
6706
- group.model.openPanel(item);
6707
- if (!box) {
6708
- box = this.element.getBoundingClientRect();
7102
+ addPopoutGroup(itemToPopout, options) {
7103
+ var _a, _b, _c;
7104
+ if (itemToPopout instanceof DockviewPanel &&
7105
+ itemToPopout.group.size === 1) {
7106
+ return this.addPopoutGroup(itemToPopout.group);
7107
+ }
7108
+ const theme = getDockviewTheme(this.gridview.element);
7109
+ const element = this.element;
7110
+ function getBox() {
7111
+ if (options === null || options === void 0 ? void 0 : options.position) {
7112
+ return options.position;
7113
+ }
7114
+ if (itemToPopout instanceof DockviewGroupPanel) {
7115
+ return itemToPopout.element.getBoundingClientRect();
7116
+ }
7117
+ if (itemToPopout.group) {
7118
+ return itemToPopout.group.element.getBoundingClientRect();
7119
+ }
7120
+ return element.getBoundingClientRect();
7121
+ }
7122
+ const box = getBox();
7123
+ 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;
7124
+ if (itemToPopout.api.location.type === 'grid') {
7125
+ itemToPopout.api.setHidden(true);
7126
+ }
7127
+ const _window = new PopoutWindow(`${this.id}-${groupId}`, // unique id
7128
+ theme !== null && theme !== void 0 ? theme : '', {
7129
+ url: (_c = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _c !== void 0 ? _c : '/popout.html',
7130
+ left: window.screenX + box.left,
7131
+ top: window.screenY + box.top,
7132
+ width: box.width,
7133
+ height: box.height,
7134
+ onDidOpen: options === null || options === void 0 ? void 0 : options.onDidOpen,
7135
+ onWillClose: options === null || options === void 0 ? void 0 : options.onWillClose,
7136
+ });
7137
+ const popoutWindowDisposable = new CompositeDisposable(_window, _window.onDidClose(() => {
7138
+ popoutWindowDisposable.dispose();
7139
+ }));
7140
+ return _window
7141
+ .open()
7142
+ .then((popoutContainer) => {
7143
+ var _a;
7144
+ if (_window.isDisposed) {
7145
+ return;
6709
7146
  }
6710
- }
6711
- else {
6712
- group = item;
6713
- if (!box) {
6714
- box = group.element.getBoundingClientRect();
7147
+ if (popoutContainer === null) {
7148
+ popoutWindowDisposable.dispose();
7149
+ return;
6715
7150
  }
6716
- const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
6717
- options.skipRemoveGroup;
6718
- if (!skip) {
6719
- this.doRemoveGroup(item, { skipDispose: true });
6720
- }
6721
- }
6722
- const theme = getTheme(this.gridview.element);
6723
- const popoutWindow = new DockviewPopoutGroupPanel(`${this.id}-${group.id}`, // globally unique within dockview
6724
- group, {
6725
- className: theme !== null && theme !== void 0 ? theme : '',
6726
- popoutUrl: (_a = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _a !== void 0 ? _a : '/popout.html',
6727
- box: {
6728
- left: window.screenX + box.left,
6729
- top: window.screenY + box.top,
6730
- width: box.width,
6731
- height: box.height,
6732
- },
7151
+ const gready = document.createElement('div');
7152
+ gready.className = 'dv-overlay-render-container';
7153
+ const overlayRenderContainer = new OverlayRenderContainer(gready);
7154
+ const referenceGroup = itemToPopout instanceof DockviewPanel
7155
+ ? itemToPopout.group
7156
+ : itemToPopout;
7157
+ const referenceLocation = itemToPopout.api.location.type;
7158
+ const group = (_a = options === null || options === void 0 ? void 0 : options.overridePopoutGroup) !== null && _a !== void 0 ? _a : this.createGroup({ id: groupId });
7159
+ group.model.renderContainer = overlayRenderContainer;
7160
+ if (!(options === null || options === void 0 ? void 0 : options.overridePopoutGroup)) {
7161
+ this._onDidAddGroup.fire(group);
7162
+ }
7163
+ if (itemToPopout instanceof DockviewPanel) {
7164
+ this.movingLock(() => {
7165
+ const panel = referenceGroup.model.removePanel(itemToPopout);
7166
+ group.model.openPanel(panel);
7167
+ });
7168
+ }
7169
+ else {
7170
+ this.movingLock(() => moveGroupWithoutDestroying({
7171
+ from: referenceGroup,
7172
+ to: group,
7173
+ }));
7174
+ switch (referenceLocation) {
7175
+ case 'grid':
7176
+ referenceGroup.api.setHidden(true);
7177
+ break;
7178
+ case 'floating':
7179
+ case 'popout':
7180
+ this.removeGroup(referenceGroup);
7181
+ break;
7182
+ }
7183
+ }
7184
+ popoutContainer.classList.add('dv-dockview');
7185
+ popoutContainer.style.overflow = 'hidden';
7186
+ popoutContainer.appendChild(gready);
7187
+ popoutContainer.appendChild(group.element);
7188
+ group.model.location = {
7189
+ type: 'popout',
7190
+ getWindow: () => _window.window,
7191
+ };
7192
+ this.doSetGroupAndPanelActive(group);
7193
+ popoutWindowDisposable.addDisposables(group.api.onDidActiveChange((event) => {
7194
+ var _a;
7195
+ if (event.isActive) {
7196
+ (_a = _window.window) === null || _a === void 0 ? void 0 : _a.focus();
7197
+ }
7198
+ }), group.api.onWillFocus(() => {
7199
+ var _a;
7200
+ (_a = _window.window) === null || _a === void 0 ? void 0 : _a.focus();
7201
+ }));
7202
+ let returnedGroup;
7203
+ const value = {
7204
+ window: _window,
7205
+ popoutGroup: group,
7206
+ referenceGroup: this.getPanel(referenceGroup.id)
7207
+ ? referenceGroup.id
7208
+ : undefined,
7209
+ disposable: {
7210
+ dispose: () => {
7211
+ popoutWindowDisposable.dispose();
7212
+ return returnedGroup;
7213
+ },
7214
+ },
7215
+ };
7216
+ popoutWindowDisposable.addDisposables(
7217
+ /**
7218
+ * ResizeObserver seems slow here, I do not know why but we don't need it
7219
+ * since we can reply on the window resize event as we will occupy the full
7220
+ * window dimensions
7221
+ */
7222
+ addDisposableWindowListener(_window.window, 'resize', () => {
7223
+ group.layout(window.innerWidth, window.innerHeight);
7224
+ }), overlayRenderContainer, Disposable.from(() => {
7225
+ if (this.getPanel(referenceGroup.id)) {
7226
+ this.movingLock(() => moveGroupWithoutDestroying({
7227
+ from: group,
7228
+ to: referenceGroup,
7229
+ }));
7230
+ if (referenceGroup.api.isHidden) {
7231
+ referenceGroup.api.setHidden(false);
7232
+ }
7233
+ if (this.getPanel(group.id)) {
7234
+ this.doRemoveGroup(group, {
7235
+ skipPopoutAssociated: true,
7236
+ });
7237
+ }
7238
+ }
7239
+ else {
7240
+ if (this.getPanel(group.id)) {
7241
+ const removedGroup = this.doRemoveGroup(group, {
7242
+ skipDispose: true,
7243
+ skipActive: true,
7244
+ });
7245
+ removedGroup.model.renderContainer =
7246
+ this.overlayRenderContainer;
7247
+ removedGroup.model.location = { type: 'grid' };
7248
+ returnedGroup = removedGroup;
7249
+ }
7250
+ }
7251
+ }));
7252
+ this._popoutGroups.push(value);
7253
+ this.updateWatermark();
7254
+ })
7255
+ .catch((err) => {
7256
+ console.error(err);
6733
7257
  });
6734
- popoutWindow.addDisposables({
6735
- dispose: () => {
6736
- remove(this._popoutGroups, popoutWindow);
6737
- this.updateWatermark();
6738
- },
6739
- }, popoutWindow.window.onDidClose(() => {
6740
- this.doAddGroup(group, [0]);
6741
- }));
6742
- this._popoutGroups.push(popoutWindow);
6743
- this.updateWatermark();
6744
7258
  }
6745
7259
  addFloatingGroup(item, coord, options) {
6746
- var _a, _b, _c, _d, _e, _f;
7260
+ var _a, _b, _c, _d, _e, _f, _g;
6747
7261
  let group;
6748
7262
  if (item instanceof DockviewPanel) {
6749
7263
  group = this.createGroup();
6750
- this.removePanel(item, {
7264
+ this._onDidAddGroup.fire(group);
7265
+ this.movingLock(() => this.removePanel(item, {
6751
7266
  removeEmptyGroup: true,
6752
7267
  skipDispose: true,
6753
- });
6754
- group.model.openPanel(item);
7268
+ skipSetActiveGroup: true,
7269
+ }));
7270
+ group.model.openPanel(item, { skipSetGroupActive: true });
6755
7271
  }
6756
7272
  else {
6757
7273
  group = item;
7274
+ const popoutReferenceGroupId = (_a = this._popoutGroups.find((_) => _.popoutGroup === group)) === null || _a === void 0 ? void 0 : _a.referenceGroup;
7275
+ const popoutReferenceGroup = popoutReferenceGroupId
7276
+ ? this.getPanel(popoutReferenceGroupId)
7277
+ : undefined;
6758
7278
  const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
6759
7279
  options.skipRemoveGroup;
6760
7280
  if (!skip) {
6761
- this.doRemoveGroup(item, { skipDispose: true });
7281
+ if (popoutReferenceGroup) {
7282
+ this.movingLock(() => moveGroupWithoutDestroying({
7283
+ from: item,
7284
+ to: popoutReferenceGroup,
7285
+ }));
7286
+ this.doRemoveGroup(item, {
7287
+ skipPopoutReturn: true,
7288
+ skipPopoutAssociated: true,
7289
+ });
7290
+ this.doRemoveGroup(popoutReferenceGroup, {
7291
+ skipDispose: true,
7292
+ });
7293
+ group = popoutReferenceGroup;
7294
+ }
7295
+ else {
7296
+ this.doRemoveGroup(item, {
7297
+ skipDispose: true,
7298
+ skipPopoutReturn: true,
7299
+ skipPopoutAssociated: !!popoutReferenceGroup,
7300
+ });
7301
+ }
6762
7302
  }
6763
7303
  }
6764
- group.model.location = 'floating';
7304
+ group.model.location = { type: 'floating' };
6765
7305
  const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number'
6766
7306
  ? Math.max(coord.x, 0)
6767
7307
  : DEFAULT_FLOATING_GROUP_POSITION.left;
@@ -6771,16 +7311,16 @@ class DockviewComponent extends BaseGrid {
6771
7311
  const overlay = new Overlay({
6772
7312
  container: this.gridview.element,
6773
7313
  content: group.element,
6774
- height: (_a = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _a !== void 0 ? _a : 300,
6775
- width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
7314
+ height: (_b = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _b !== void 0 ? _b : 300,
7315
+ width: (_c = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _c !== void 0 ? _c : 300,
6776
7316
  left: overlayLeft,
6777
7317
  top: overlayTop,
6778
7318
  minimumInViewportWidth: this.options.floatingGroupBounds === 'boundedWithinViewport'
6779
7319
  ? undefined
6780
- : (_d = (_c = this.options.floatingGroupBounds) === null || _c === void 0 ? void 0 : _c.minimumWidthWithinViewport) !== null && _d !== void 0 ? _d : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
7320
+ : (_e = (_d = this.options.floatingGroupBounds) === null || _d === void 0 ? void 0 : _d.minimumWidthWithinViewport) !== null && _e !== void 0 ? _e : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
6781
7321
  minimumInViewportHeight: this.options.floatingGroupBounds === 'boundedWithinViewport'
6782
7322
  ? undefined
6783
- : (_f = (_e = this.options.floatingGroupBounds) === null || _e === void 0 ? void 0 : _e.minimumHeightWithinViewport) !== null && _f !== void 0 ? _f : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
7323
+ : (_g = (_f = this.options.floatingGroupBounds) === null || _f === void 0 ? void 0 : _f.minimumHeightWithinViewport) !== null && _g !== void 0 ? _g : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
6784
7324
  });
6785
7325
  const el = group.element.querySelector('.void-container');
6786
7326
  if (!el) {
@@ -6811,12 +7351,15 @@ class DockviewComponent extends BaseGrid {
6811
7351
  }), {
6812
7352
  dispose: () => {
6813
7353
  disposable.dispose();
6814
- group.model.location = 'grid';
7354
+ group.model.location = { type: 'grid' };
6815
7355
  remove(this._floatingGroups, floatingGroupPanel);
6816
7356
  this.updateWatermark();
6817
7357
  },
6818
7358
  });
6819
7359
  this._floatingGroups.push(floatingGroupPanel);
7360
+ if (!(options === null || options === void 0 ? void 0 : options.skipActiveGroup)) {
7361
+ this.doSetGroupAndPanelActive(group);
7362
+ }
6820
7363
  this.updateWatermark();
6821
7364
  }
6822
7365
  orthogonalize(position) {
@@ -6906,8 +7449,8 @@ class DockviewComponent extends BaseGrid {
6906
7449
  return this.panels.find((panel) => panel.id === id);
6907
7450
  }
6908
7451
  setActivePanel(panel) {
6909
- this.doSetGroupActive(panel.group);
6910
7452
  panel.group.model.openPanel(panel);
7453
+ this.doSetGroupAndPanelActive(panel.group);
6911
7454
  }
6912
7455
  moveToNext(options = {}) {
6913
7456
  var _a;
@@ -6968,7 +7511,8 @@ class DockviewComponent extends BaseGrid {
6968
7511
  });
6969
7512
  const popoutGroups = this._popoutGroups.map((group) => {
6970
7513
  return {
6971
- data: group.group.toJSON(),
7514
+ data: group.popoutGroup.toJSON(),
7515
+ gridReferenceGroup: group.referenceGroup,
6972
7516
  position: group.window.dimensions(),
6973
7517
  };
6974
7518
  });
@@ -6986,7 +7530,7 @@ class DockviewComponent extends BaseGrid {
6986
7530
  return result;
6987
7531
  }
6988
7532
  fromJSON(data) {
6989
- var _a, _b;
7533
+ var _a, _b, _c;
6990
7534
  this.clear();
6991
7535
  if (typeof data !== 'object' || data === null) {
6992
7536
  throw new Error('serialized layout must be a non-null object');
@@ -7025,7 +7569,7 @@ class DockviewComponent extends BaseGrid {
7025
7569
  const isActive = typeof activeView === 'string' &&
7026
7570
  activeView === panel.id;
7027
7571
  group.model.openPanel(panel, {
7028
- skipSetPanelActive: !isActive,
7572
+ skipSetActive: !isActive,
7029
7573
  skipSetGroupActive: true,
7030
7574
  });
7031
7575
  }
@@ -7055,11 +7599,16 @@ class DockviewComponent extends BaseGrid {
7055
7599
  }
7056
7600
  const serializedPopoutGroups = (_b = data.popoutGroups) !== null && _b !== void 0 ? _b : [];
7057
7601
  for (const serializedPopoutGroup of serializedPopoutGroups) {
7058
- const { data, position } = serializedPopoutGroup;
7602
+ const { data, position, gridReferenceGroup } = serializedPopoutGroup;
7059
7603
  const group = createGroupFromSerializedState(data);
7060
- this.addPopoutGroup(group, {
7604
+ this.addPopoutGroup((_c = (gridReferenceGroup
7605
+ ? this.getPanel(gridReferenceGroup)
7606
+ : undefined)) !== null && _c !== void 0 ? _c : group, {
7061
7607
  skipRemoveGroup: true,
7062
7608
  position: position !== null && position !== void 0 ? position : undefined,
7609
+ overridePopoutGroup: gridReferenceGroup
7610
+ ? group
7611
+ : undefined,
7063
7612
  });
7064
7613
  }
7065
7614
  for (const floatingGroup of this._floatingGroups) {
@@ -7106,12 +7655,13 @@ class DockviewComponent extends BaseGrid {
7106
7655
  */
7107
7656
  throw err;
7108
7657
  }
7658
+ this.updateWatermark();
7109
7659
  this._onDidLayoutFromJSON.fire();
7110
7660
  }
7111
7661
  clear() {
7112
7662
  const groups = Array.from(this._groups.values()).map((_) => _.value);
7113
7663
  const hasActiveGroup = !!this.activeGroup;
7114
- const hasActivePanel = !!this.activePanel;
7664
+ !!this.activePanel;
7115
7665
  for (const group of groups) {
7116
7666
  // remove the group will automatically remove the panels
7117
7667
  this.removeGroup(group, { skipActive: true });
@@ -7119,9 +7669,6 @@ class DockviewComponent extends BaseGrid {
7119
7669
  if (hasActiveGroup) {
7120
7670
  this.doSetGroupAndPanelActive(undefined);
7121
7671
  }
7122
- if (hasActivePanel) {
7123
- this._onDidActivePanelChange.fire(undefined);
7124
- }
7125
7672
  this.gridview.clear();
7126
7673
  }
7127
7674
  closeAllGroups() {
@@ -7162,6 +7709,7 @@ class DockviewComponent extends BaseGrid {
7162
7709
  const group = this.orthogonalize(directionToPosition(options.position.direction));
7163
7710
  const panel = this.createPanel(options, group);
7164
7711
  group.model.openPanel(panel);
7712
+ this.doSetGroupAndPanelActive(group);
7165
7713
  return panel;
7166
7714
  }
7167
7715
  }
@@ -7173,6 +7721,7 @@ class DockviewComponent extends BaseGrid {
7173
7721
  const target = toTarget(((_b = options.position) === null || _b === void 0 ? void 0 : _b.direction) || 'within');
7174
7722
  if (options.floating) {
7175
7723
  const group = this.createGroup();
7724
+ this._onDidAddGroup.fire(group);
7176
7725
  const o = typeof options.floating === 'object' &&
7177
7726
  options.floating !== null
7178
7727
  ? options.floating
@@ -7180,16 +7729,16 @@ class DockviewComponent extends BaseGrid {
7180
7729
  this.addFloatingGroup(group, o, {
7181
7730
  inDragMode: false,
7182
7731
  skipRemoveGroup: true,
7732
+ skipActiveGroup: true,
7183
7733
  });
7184
- this._onDidAddGroup.fire(group);
7185
7734
  panel = this.createPanel(options, group);
7186
7735
  group.model.openPanel(panel);
7187
- this.doSetGroupAndPanelActive(group);
7188
7736
  }
7189
- else if (referenceGroup.api.location === 'floating' ||
7737
+ else if (referenceGroup.api.location.type === 'floating' ||
7190
7738
  target === 'center') {
7191
7739
  panel = this.createPanel(options, referenceGroup);
7192
7740
  referenceGroup.model.openPanel(panel);
7741
+ this.doSetGroupAndPanelActive(referenceGroup);
7193
7742
  }
7194
7743
  else {
7195
7744
  const location = getGridLocation(referenceGroup.element);
@@ -7197,10 +7746,12 @@ class DockviewComponent extends BaseGrid {
7197
7746
  const group = this.createGroupAtLocation(relativeLocation);
7198
7747
  panel = this.createPanel(options, group);
7199
7748
  group.model.openPanel(panel);
7749
+ this.doSetGroupAndPanelActive(group);
7200
7750
  }
7201
7751
  }
7202
7752
  else if (options.floating) {
7203
7753
  const group = this.createGroup();
7754
+ this._onDidAddGroup.fire(group);
7204
7755
  const o = typeof options.floating === 'object' &&
7205
7756
  options.floating !== null
7206
7757
  ? options.floating
@@ -7208,16 +7759,16 @@ class DockviewComponent extends BaseGrid {
7208
7759
  this.addFloatingGroup(group, o, {
7209
7760
  inDragMode: false,
7210
7761
  skipRemoveGroup: true,
7762
+ skipActiveGroup: true,
7211
7763
  });
7212
- this._onDidAddGroup.fire(group);
7213
7764
  panel = this.createPanel(options, group);
7214
7765
  group.model.openPanel(panel);
7215
- this.doSetGroupAndPanelActive(group);
7216
7766
  }
7217
7767
  else {
7218
7768
  const group = this.createGroupAtLocation();
7219
7769
  panel = this.createPanel(options, group);
7220
7770
  group.model.openPanel(panel);
7771
+ this.doSetGroupAndPanelActive(group);
7221
7772
  }
7222
7773
  return panel;
7223
7774
  }
@@ -7229,13 +7780,15 @@ class DockviewComponent extends BaseGrid {
7229
7780
  if (!group) {
7230
7781
  throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
7231
7782
  }
7232
- group.model.removePanel(panel);
7783
+ group.model.removePanel(panel, {
7784
+ skipSetActiveGroup: options.skipSetActiveGroup,
7785
+ });
7233
7786
  if (!options.skipDispose) {
7234
- this.overlayRenderContainer.detatch(panel);
7787
+ panel.group.model.renderContainer.detatch(panel);
7235
7788
  panel.dispose();
7236
7789
  }
7237
7790
  if (group.size === 0 && options.removeEmptyGroup) {
7238
- this.removeGroup(group);
7791
+ this.removeGroup(group, { skipActive: options.skipSetActiveGroup });
7239
7792
  }
7240
7793
  }
7241
7794
  createWatermarkComponent() {
@@ -7248,7 +7801,7 @@ class DockviewComponent extends BaseGrid {
7248
7801
  }
7249
7802
  updateWatermark() {
7250
7803
  var _a, _b;
7251
- if (this.groups.filter((x) => x.api.location === 'grid').length === 0) {
7804
+ if (this.groups.filter((x) => x.api.location.type === 'grid' && !x.api.isHidden).length === 0) {
7252
7805
  if (!this.watermark) {
7253
7806
  this.watermark = this.createWatermarkComponent();
7254
7807
  this.watermark.init({
@@ -7268,7 +7821,7 @@ class DockviewComponent extends BaseGrid {
7268
7821
  }
7269
7822
  addGroup(options) {
7270
7823
  var _a;
7271
- const group = this.createGroup();
7824
+ const group = this.createGroup(options);
7272
7825
  if (options) {
7273
7826
  let referenceGroup;
7274
7827
  if (isGroupOptionsWithPanel(options)) {
@@ -7294,36 +7847,42 @@ class DockviewComponent extends BaseGrid {
7294
7847
  }
7295
7848
  else {
7296
7849
  const group = this.orthogonalize(directionToPosition(options.direction));
7850
+ if (!options.skipSetActive) {
7851
+ this.doSetGroupAndPanelActive(group);
7852
+ }
7297
7853
  return group;
7298
7854
  }
7299
7855
  const target = toTarget(options.direction || 'within');
7300
7856
  const location = getGridLocation(referenceGroup.element);
7301
7857
  const relativeLocation = getRelativeLocation(this.gridview.orientation, location, target);
7302
7858
  this.doAddGroup(group, relativeLocation);
7859
+ if (!options.skipSetActive) {
7860
+ this.doSetGroupAndPanelActive(group);
7861
+ }
7303
7862
  return group;
7304
7863
  }
7305
7864
  else {
7306
7865
  this.doAddGroup(group);
7866
+ this.doSetGroupAndPanelActive(group);
7307
7867
  return group;
7308
7868
  }
7309
7869
  }
7310
7870
  removeGroup(group, options) {
7871
+ this.doRemoveGroup(group, options);
7872
+ }
7873
+ doRemoveGroup(group, options) {
7311
7874
  var _a;
7312
7875
  const panels = [...group.panels]; // reassign since group panels will mutate
7313
- for (const panel of panels) {
7314
- this.removePanel(panel, {
7315
- removeEmptyGroup: false,
7316
- skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
7317
- });
7876
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7877
+ for (const panel of panels) {
7878
+ this.removePanel(panel, {
7879
+ removeEmptyGroup: false,
7880
+ skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
7881
+ });
7882
+ }
7318
7883
  }
7319
7884
  const activePanel = this.activePanel;
7320
- this.doRemoveGroup(group, options);
7321
- if (this.activePanel !== activePanel) {
7322
- this._onDidActivePanelChange.fire(this.activePanel);
7323
- }
7324
- }
7325
- doRemoveGroup(group, options) {
7326
- if (group.api.location === 'floating') {
7885
+ if (group.api.location.type === 'floating') {
7327
7886
  const floatingGroup = this._floatingGroups.find((_) => _.group === group);
7328
7887
  if (floatingGroup) {
7329
7888
  if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
@@ -7335,60 +7894,124 @@ class DockviewComponent extends BaseGrid {
7335
7894
  floatingGroup.dispose();
7336
7895
  if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7337
7896
  const groups = Array.from(this._groups.values());
7338
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7897
+ this.doSetGroupAndPanelActive(groups.length > 0 ? groups[0].value : undefined);
7339
7898
  }
7340
7899
  return floatingGroup.group;
7341
7900
  }
7342
7901
  throw new Error('failed to find floating group');
7343
7902
  }
7344
- if (group.api.location === 'popout') {
7345
- const selectedGroup = this._popoutGroups.find((_) => _.group === group);
7903
+ if (group.api.location.type === 'popout') {
7904
+ const selectedGroup = this._popoutGroups.find((_) => _.popoutGroup === group);
7346
7905
  if (selectedGroup) {
7347
7906
  if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7348
- selectedGroup.group.dispose();
7907
+ if (!(options === null || options === void 0 ? void 0 : options.skipPopoutAssociated)) {
7908
+ const refGroup = selectedGroup.referenceGroup
7909
+ ? this.getPanel(selectedGroup.referenceGroup)
7910
+ : undefined;
7911
+ if (refGroup) {
7912
+ this.removeGroup(refGroup);
7913
+ }
7914
+ }
7915
+ selectedGroup.popoutGroup.dispose();
7349
7916
  this._groups.delete(group.id);
7350
7917
  this._onDidRemoveGroup.fire(group);
7351
7918
  }
7352
- selectedGroup.dispose();
7919
+ const removedGroup = selectedGroup.disposable.dispose();
7920
+ if (!(options === null || options === void 0 ? void 0 : options.skipPopoutReturn) && removedGroup) {
7921
+ this.doAddGroup(removedGroup, [0]);
7922
+ this.doSetGroupAndPanelActive(removedGroup);
7923
+ }
7353
7924
  if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7354
7925
  const groups = Array.from(this._groups.values());
7355
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7926
+ this.doSetGroupAndPanelActive(groups.length > 0 ? groups[0].value : undefined);
7356
7927
  }
7357
- return selectedGroup.group;
7928
+ this.updateWatermark();
7929
+ return selectedGroup.popoutGroup;
7358
7930
  }
7359
7931
  throw new Error('failed to find popout group');
7360
7932
  }
7361
- return super.doRemoveGroup(group, options);
7933
+ const re = super.doRemoveGroup(group, options);
7934
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive)) {
7935
+ if (this.activePanel !== activePanel) {
7936
+ this._onDidActivePanelChange.fire(this.activePanel);
7937
+ }
7938
+ }
7939
+ return re;
7362
7940
  }
7363
- moveGroupOrPanel(destinationGroup, sourceGroupId, sourceItemId, destinationTarget, destinationIndex) {
7364
- var _a, _b, _c;
7941
+ movingLock(func) {
7942
+ const isMoving = this._moving;
7943
+ try {
7944
+ this._moving = true;
7945
+ return func();
7946
+ }
7947
+ finally {
7948
+ this._moving = isMoving;
7949
+ }
7950
+ }
7951
+ moveGroupOrPanel(options) {
7952
+ var _a;
7953
+ const destinationGroup = options.to.group;
7954
+ const sourceGroupId = options.from.groupId;
7955
+ const sourceItemId = options.from.panelId;
7956
+ const destinationTarget = options.to.position;
7957
+ const destinationIndex = options.to.index;
7365
7958
  const sourceGroup = sourceGroupId
7366
7959
  ? (_a = this._groups.get(sourceGroupId)) === null || _a === void 0 ? void 0 : _a.value
7367
7960
  : undefined;
7961
+ if (!sourceGroup) {
7962
+ throw new Error(`Failed to find group id ${sourceGroupId}`);
7963
+ }
7368
7964
  if (sourceItemId === undefined) {
7369
- if (sourceGroup) {
7370
- this.moveGroup(sourceGroup, destinationGroup, destinationTarget);
7371
- }
7965
+ /**
7966
+ * Moving an entire group into another group
7967
+ */
7968
+ this.moveGroup({
7969
+ from: { group: sourceGroup },
7970
+ to: {
7971
+ group: destinationGroup,
7972
+ position: destinationTarget,
7973
+ },
7974
+ });
7372
7975
  return;
7373
7976
  }
7374
7977
  if (!destinationTarget || destinationTarget === 'center') {
7375
- 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);
7376
- if (!groupItem) {
7978
+ /**
7979
+ * Dropping a panel within another group
7980
+ */
7981
+ const removedPanel = this.movingLock(() => sourceGroup.model.removePanel(sourceItemId, {
7982
+ skipSetActive: false,
7983
+ skipSetActiveGroup: true,
7984
+ }));
7985
+ if (!removedPanel) {
7377
7986
  throw new Error(`No panel with id ${sourceItemId}`);
7378
7987
  }
7379
- if ((sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.size) === 0) {
7380
- this.doRemoveGroup(sourceGroup);
7988
+ if (sourceGroup.model.size === 0) {
7989
+ // remove the group and do not set a new group as active
7990
+ this.doRemoveGroup(sourceGroup, { skipActive: true });
7381
7991
  }
7382
- destinationGroup.model.openPanel(groupItem, {
7992
+ this.movingLock(() => destinationGroup.model.openPanel(removedPanel, {
7383
7993
  index: destinationIndex,
7994
+ skipSetGroupActive: true,
7995
+ }));
7996
+ this.doSetGroupAndPanelActive(destinationGroup);
7997
+ this._onDidMovePanel.fire({
7998
+ panel: removedPanel,
7384
7999
  });
7385
8000
  }
7386
8001
  else {
8002
+ /**
8003
+ * Dropping a panel to the extremities of a group which will place that panel
8004
+ * into an adjacent group
8005
+ */
7387
8006
  const referenceLocation = getGridLocation(destinationGroup.element);
7388
8007
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
7389
- if (sourceGroup && sourceGroup.size < 2) {
8008
+ if (sourceGroup.size < 2) {
8009
+ /**
8010
+ * If we are moving from a group which only has one panel left we will consider
8011
+ * moving the group itself rather than moving the panel into a newly created group
8012
+ */
7390
8013
  const [targetParentLocation, to] = tail(targetLocation);
7391
- if (sourceGroup.api.location === 'grid') {
8014
+ if (sourceGroup.api.location.type === 'grid') {
7392
8015
  const sourceLocation = getGridLocation(sourceGroup.element);
7393
8016
  const [sourceParentLocation, from] = tail(sourceLocation);
7394
8017
  if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
@@ -7396,78 +8019,123 @@ class DockviewComponent extends BaseGrid {
7396
8019
  // if a group has one tab - we are essentially moving the 'group'
7397
8020
  // which is equivalent to swapping two views in this case
7398
8021
  this.gridview.moveView(sourceParentLocation, from, to);
8022
+ return;
7399
8023
  }
7400
8024
  }
7401
8025
  // source group will become empty so delete the group
7402
- const targetGroup = this.doRemoveGroup(sourceGroup, {
8026
+ const targetGroup = this.movingLock(() => this.doRemoveGroup(sourceGroup, {
7403
8027
  skipActive: true,
7404
8028
  skipDispose: true,
7405
- });
8029
+ }));
7406
8030
  // after deleting the group we need to re-evaulate the ref location
7407
8031
  const updatedReferenceLocation = getGridLocation(destinationGroup.element);
7408
8032
  const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
7409
- this.doAddGroup(targetGroup, location);
8033
+ this.movingLock(() => this.doAddGroup(targetGroup, location));
8034
+ this.doSetGroupAndPanelActive(targetGroup);
7410
8035
  }
7411
8036
  else {
7412
- 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);
7413
- if (!groupItem) {
8037
+ /**
8038
+ * The group we are removing from has many panels, we need to remove the panels we are moving,
8039
+ * create a new group, add the panels to that new group and add the new group in an appropiate position
8040
+ */
8041
+ const removedPanel = this.movingLock(() => sourceGroup.model.removePanel(sourceItemId, {
8042
+ skipSetActive: false,
8043
+ skipSetActiveGroup: true,
8044
+ }));
8045
+ if (!removedPanel) {
7414
8046
  throw new Error(`No panel with id ${sourceItemId}`);
7415
8047
  }
7416
8048
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
7417
8049
  const group = this.createGroupAtLocation(dropLocation);
7418
- group.model.openPanel(groupItem);
8050
+ this.movingLock(() => group.model.openPanel(removedPanel, {
8051
+ skipSetGroupActive: true,
8052
+ }));
8053
+ this.doSetGroupAndPanelActive(group);
7419
8054
  }
7420
8055
  }
7421
8056
  }
7422
- moveGroup(sourceGroup, referenceGroup, target) {
7423
- if (sourceGroup) {
7424
- if (!target || target === 'center') {
7425
- const activePanel = sourceGroup.activePanel;
7426
- const panels = [...sourceGroup.panels].map((p) => sourceGroup.model.removePanel(p.id));
7427
- if ((sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.size) === 0) {
7428
- this.doRemoveGroup(sourceGroup);
7429
- }
8057
+ moveGroup(options) {
8058
+ const from = options.from.group;
8059
+ const to = options.to.group;
8060
+ const target = options.to.position;
8061
+ if (target === 'center') {
8062
+ const activePanel = from.activePanel;
8063
+ const panels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, {
8064
+ skipSetActive: true,
8065
+ })));
8066
+ if ((from === null || from === void 0 ? void 0 : from.model.size) === 0) {
8067
+ this.doRemoveGroup(from, { skipActive: true });
8068
+ }
8069
+ this.movingLock(() => {
7430
8070
  for (const panel of panels) {
7431
- referenceGroup.model.openPanel(panel, {
7432
- skipSetPanelActive: panel !== activePanel,
8071
+ to.model.openPanel(panel, {
8072
+ skipSetActive: panel !== activePanel,
8073
+ skipSetGroupActive: true,
7433
8074
  });
7434
8075
  }
7435
- }
7436
- else {
7437
- switch (sourceGroup.api.location) {
7438
- case 'grid':
7439
- this.gridview.removeView(getGridLocation(sourceGroup.element));
7440
- break;
7441
- case 'floating': {
7442
- const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === sourceGroup);
7443
- if (!selectedFloatingGroup) {
7444
- throw new Error('failed to find floating group');
7445
- }
7446
- selectedFloatingGroup.dispose();
7447
- break;
8076
+ });
8077
+ this.doSetGroupAndPanelActive(to);
8078
+ panels.forEach((panel) => {
8079
+ this._onDidMovePanel.fire({ panel });
8080
+ });
8081
+ }
8082
+ else {
8083
+ switch (from.api.location.type) {
8084
+ case 'grid':
8085
+ this.gridview.removeView(getGridLocation(from.element));
8086
+ break;
8087
+ case 'floating': {
8088
+ const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === from);
8089
+ if (!selectedFloatingGroup) {
8090
+ throw new Error('failed to find floating group');
7448
8091
  }
7449
- case 'popout': {
7450
- const selectedPopoutGroup = this._popoutGroups.find((x) => x.group === sourceGroup);
7451
- if (!selectedPopoutGroup) {
7452
- throw new Error('failed to find popout group');
7453
- }
7454
- selectedPopoutGroup.dispose();
8092
+ selectedFloatingGroup.dispose();
8093
+ break;
8094
+ }
8095
+ case 'popout': {
8096
+ const selectedPopoutGroup = this._popoutGroups.find((x) => x.popoutGroup === from);
8097
+ if (!selectedPopoutGroup) {
8098
+ throw new Error('failed to find popout group');
7455
8099
  }
8100
+ selectedPopoutGroup.disposable.dispose();
7456
8101
  }
7457
- const referenceLocation = getGridLocation(referenceGroup.element);
7458
- const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
7459
- this.gridview.addView(sourceGroup, Sizing.Distribute, dropLocation);
7460
8102
  }
8103
+ const referenceLocation = getGridLocation(to.element);
8104
+ const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
8105
+ this.gridview.addView(from, Sizing.Distribute, dropLocation);
8106
+ from.panels.forEach((panel) => {
8107
+ this._onDidMovePanel.fire({ panel });
8108
+ });
7461
8109
  }
7462
8110
  }
7463
- doSetGroupAndPanelActive(group, skipFocus) {
7464
- var _a, _b;
8111
+ doSetGroupActive(group) {
8112
+ super.doSetGroupActive(group);
8113
+ const activePanel = this.activePanel;
8114
+ if (!this._moving &&
8115
+ activePanel !== this._onDidActivePanelChange.value) {
8116
+ this._onDidActivePanelChange.fire(activePanel);
8117
+ }
8118
+ }
8119
+ doSetGroupAndPanelActive(group) {
8120
+ super.doSetGroupActive(group);
7465
8121
  const activePanel = this.activePanel;
7466
- super.doSetGroupActive(group, skipFocus);
7467
- if (((_a = this._activeGroup) === null || _a === void 0 ? void 0 : _a.activePanel) !== activePanel) {
7468
- this._onDidActivePanelChange.fire((_b = this._activeGroup) === null || _b === void 0 ? void 0 : _b.activePanel);
8122
+ if (group &&
8123
+ this.hasMaximizedGroup() &&
8124
+ !this.isMaximizedGroup(group)) {
8125
+ this.exitMaximizedGroup();
8126
+ }
8127
+ if (!this._moving &&
8128
+ activePanel !== this._onDidActivePanelChange.value) {
8129
+ this._onDidActivePanelChange.fire(activePanel);
7469
8130
  }
7470
8131
  }
8132
+ getNextGroupId() {
8133
+ let id = this.nextGroupId.next();
8134
+ while (this._groups.has(id)) {
8135
+ id = this.nextGroupId.next();
8136
+ }
8137
+ return id;
8138
+ }
7471
8139
  createGroup(options) {
7472
8140
  if (!options) {
7473
8141
  options = {};
@@ -7484,7 +8152,7 @@ class DockviewComponent extends BaseGrid {
7484
8152
  }
7485
8153
  }
7486
8154
  const view = new DockviewGroupPanel(this, id, options);
7487
- view.init({ params: {}, accessor: null }); // required to initialized .part and allow for correct disposal of group
8155
+ view.init({ params: {}, accessor: this });
7488
8156
  if (!this._groups.has(view.id)) {
7489
8157
  const disposable = new CompositeDisposable(view.model.onTabDragStart((event) => {
7490
8158
  this._onWillDragPanel.fire(event);
@@ -7492,20 +8160,48 @@ class DockviewComponent extends BaseGrid {
7492
8160
  this._onWillDragGroup.fire(event);
7493
8161
  }), view.model.onMove((event) => {
7494
8162
  const { groupId, itemId, target, index } = event;
7495
- this.moveGroupOrPanel(view, groupId, itemId, target, index);
8163
+ this.moveGroupOrPanel({
8164
+ from: { groupId: groupId, panelId: itemId },
8165
+ to: {
8166
+ group: view,
8167
+ position: target,
8168
+ index,
8169
+ },
8170
+ });
7496
8171
  }), view.model.onDidDrop((event) => {
7497
- this._onDidDrop.fire(Object.assign(Object.assign({}, event), { api: this._api, group: view }));
8172
+ this._onDidDrop.fire(event);
8173
+ }), view.model.onWillDrop((event) => {
8174
+ this._onWillDrop.fire(event);
8175
+ }), view.model.onWillShowOverlay((event) => {
8176
+ if (this.options.disableDnd) {
8177
+ event.preventDefault();
8178
+ return;
8179
+ }
8180
+ this._onWillShowOverlay.fire(event);
7498
8181
  }), view.model.onDidAddPanel((event) => {
8182
+ if (this._moving) {
8183
+ return;
8184
+ }
7499
8185
  this._onDidAddPanel.fire(event.panel);
7500
8186
  }), view.model.onDidRemovePanel((event) => {
8187
+ if (this._moving) {
8188
+ return;
8189
+ }
7501
8190
  this._onDidRemovePanel.fire(event.panel);
7502
8191
  }), view.model.onDidActivePanelChange((event) => {
7503
- this._onDidActivePanelChange.fire(event.panel);
8192
+ if (this._moving) {
8193
+ return;
8194
+ }
8195
+ if (event.panel !== this.activePanel) {
8196
+ return;
8197
+ }
8198
+ if (this._onDidActivePanelChange.value !== event.panel) {
8199
+ this._onDidActivePanelChange.fire(event.panel);
8200
+ }
7504
8201
  }));
7505
8202
  this._groups.set(view.id, { value: view, disposable });
7506
8203
  }
7507
- // TODO: must be called after the above listeners have been setup,
7508
- // not an ideal pattern
8204
+ // TODO: must be called after the above listeners have been setup, not an ideal pattern
7509
8205
  view.initialize();
7510
8206
  return view;
7511
8207
  }
@@ -7558,7 +8254,20 @@ class GridviewComponent extends BaseGrid {
7558
8254
  });
7559
8255
  this._onDidLayoutfromJSON = new Emitter();
7560
8256
  this.onDidLayoutFromJSON = this._onDidLayoutfromJSON.event;
8257
+ this._onDidRemoveGroup = new Emitter();
8258
+ this.onDidRemoveGroup = this._onDidRemoveGroup.event;
8259
+ this._onDidAddGroup = new Emitter();
8260
+ this.onDidAddGroup = this._onDidAddGroup.event;
8261
+ this._onDidActiveGroupChange = new Emitter();
8262
+ this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
7561
8263
  this._options = options;
8264
+ this.addDisposables(this._onDidAddGroup, this._onDidRemoveGroup, this._onDidActiveGroupChange, this.onDidAdd((event) => {
8265
+ this._onDidAddGroup.fire(event);
8266
+ }), this.onDidRemove((event) => {
8267
+ this._onDidRemoveGroup.fire(event);
8268
+ }), this.onDidActiveChange((event) => {
8269
+ this._onDidActiveGroupChange.fire(event);
8270
+ }));
7562
8271
  if (!this.options.components) {
7563
8272
  this.options.components = {};
7564
8273
  }
@@ -7733,6 +8442,7 @@ class GridviewComponent extends BaseGrid {
7733
8442
  });
7734
8443
  this.registerPanel(view);
7735
8444
  this.doAddGroup(view, relativeLocation, options.size);
8445
+ this.doSetGroupActive(view);
7736
8446
  return view;
7737
8447
  }
7738
8448
  registerPanel(panel) {
@@ -8418,10 +9128,10 @@ class SplitviewPanel extends BasePanelView {
8418
9128
  this._onDidChange = new Emitter();
8419
9129
  this.onDidChange = this._onDidChange.event;
8420
9130
  this.api.initialize(this);
8421
- this.addDisposables(this._onDidChange, this.api.onVisibilityChange((event) => {
8422
- const { isVisible } = event;
9131
+ this.addDisposables(this._onDidChange, this.api.onDidHiddenChange((event) => {
9132
+ const { isHidden } = event;
8423
9133
  const { accessor } = this._params;
8424
- accessor.setVisible(this, isVisible);
9134
+ accessor.setVisible(this, !isHidden);
8425
9135
  }), this.api.onActiveChange(() => {
8426
9136
  const { accessor } = this._params;
8427
9137
  accessor.setActive(this);
@@ -8543,13 +9253,13 @@ class ReactPart {
8543
9253
  if (this.disposed) {
8544
9254
  throw new Error('invalid operation: resource is already disposed');
8545
9255
  }
8546
- if (typeof this.component !== 'function') {
9256
+ if (!isReactComponent(this.component)) {
8547
9257
  /**
8548
9258
  * we know this isn't a React.FunctionComponent so throw an error here.
8549
- * if we do not intercept this the React library will throw a very obsure error
8550
- * for the same reason, at least at this point we will emit a sensible stacktrace.
9259
+ * if we do not intercept then React library will throw a very obsure error
9260
+ * for the same reason... at least at this point we will emit a sensible stacktrace.
8551
9261
  */
8552
- throw new Error('Invalid Operation. dockview only supports React Functional Components.');
9262
+ throw new Error('Dockview: Only React.memo(...), React.ForwardRef(...) and functional components are accepted as components');
8553
9263
  }
8554
9264
  const bridgeComponent = React.createElement(React.forwardRef(ReactComponentBridge), {
8555
9265
  component: this
@@ -8601,9 +9311,13 @@ const usePortalsLifecycle = () => {
8601
9311
  }, []);
8602
9312
  return [portals, addPortal];
8603
9313
  };
8604
- // it does the job...
8605
- function isReactElement(element) {
8606
- return !!(element === null || element === void 0 ? void 0 : element.type);
9314
+ function isReactComponent(component) {
9315
+ /**
9316
+ * Yes, we could use "react-is" but that would introduce an unwanted peer dependency
9317
+ * so for now we will check in a rather crude fashion...
9318
+ */
9319
+ return (typeof component === 'function' /** Functional Componnts */ ||
9320
+ !!(component === null || component === void 0 ? void 0 : component.$$typeof) /** React.memo(...) Components */);
8607
9321
  }
8608
9322
 
8609
9323
  class ReactPanelContentPart {
@@ -8863,6 +9577,8 @@ const DockviewReact = React.forwardRef((props, ref) => {
8863
9577
  defaultRenderer: props.defaultRenderer,
8864
9578
  debug: props.debug,
8865
9579
  rootOverlayModel: props.rootOverlayModel,
9580
+ locked: props.locked,
9581
+ disableDnd: props.disableDnd,
8866
9582
  });
8867
9583
  const { clientWidth, clientHeight } = domRef.current;
8868
9584
  dockview.layout(clientWidth, clientHeight);
@@ -8874,6 +9590,20 @@ const DockviewReact = React.forwardRef((props, ref) => {
8874
9590
  dockview.dispose();
8875
9591
  };
8876
9592
  }, []);
9593
+ React.useEffect(() => {
9594
+ if (!dockviewRef.current) {
9595
+ return;
9596
+ }
9597
+ dockviewRef.current.locked = !!props.locked;
9598
+ }, [props.locked]);
9599
+ React.useEffect(() => {
9600
+ if (!dockviewRef.current) {
9601
+ return;
9602
+ }
9603
+ dockviewRef.current.updateOptions({
9604
+ disableDnd: props.disableDnd,
9605
+ });
9606
+ }, [props.disableDnd]);
8877
9607
  React.useEffect(() => {
8878
9608
  if (!dockviewRef.current) {
8879
9609
  return () => {
@@ -8889,6 +9619,21 @@ const DockviewReact = React.forwardRef((props, ref) => {
8889
9619
  disposable.dispose();
8890
9620
  };
8891
9621
  }, [props.onDidDrop]);
9622
+ React.useEffect(() => {
9623
+ if (!dockviewRef.current) {
9624
+ return () => {
9625
+ // noop
9626
+ };
9627
+ }
9628
+ const disposable = dockviewRef.current.onWillDrop((event) => {
9629
+ if (props.onWillDrop) {
9630
+ props.onWillDrop(event);
9631
+ }
9632
+ });
9633
+ return () => {
9634
+ disposable.dispose();
9635
+ };
9636
+ }, [props.onWillDrop]);
8892
9637
  React.useEffect(() => {
8893
9638
  if (!dockviewRef.current) {
8894
9639
  return;
@@ -9131,7 +9876,9 @@ class ReactGridPanelView extends GridviewPanel {
9131
9876
  return new ReactPart(this.element, this.reactPortalStore, this.reactComponent, {
9132
9877
  params: (_b = (_a = this._params) === null || _a === void 0 ? void 0 : _a.params) !== null && _b !== void 0 ? _b : {},
9133
9878
  api: this.api,
9134
- containerApi: new GridviewApi(this._params.accessor),
9879
+ // TODO: fix casting hack
9880
+ containerApi: new GridviewApi(this._params
9881
+ .accessor),
9135
9882
  });
9136
9883
  }
9137
9884
  }
@@ -9306,5 +10053,5 @@ const PaneviewReact = React.forwardRef((props, ref) => {
9306
10053
  });
9307
10054
  PaneviewReact.displayName = 'PaneviewComponent';
9308
10055
 
9309
- export { BaseGrid, ContentContainer, DefaultDockviewDeserialzier, DefaultTab, DockviewApi, DockviewComponent, CompositeDisposable as DockviewCompositeDisposable, DockviewDefaultTab, DockviewDropTargets, Emitter as DockviewEmitter, Event as DockviewEvent, DockviewGroupPanel, DockviewGroupPanelModel, MutableDisposable as DockviewMutableDisposable, DockviewPanel, DockviewReact, DraggablePaneviewPanel, Gridview, GridviewApi, GridviewComponent, GridviewPanel, GridviewReact, LayoutPriority, LocalSelectionTransfer, Orientation, PaneFramework, PaneTransfer, PanelTransfer, Paneview, PaneviewApi, PaneviewComponent, PaneviewPanel, PaneviewReact, ReactPart, ReactPartContext, SashState, Sizing, Splitview, SplitviewApi, SplitviewComponent, SplitviewPanel, SplitviewReact, Tab, createComponent, directionToPosition, getDirectionOrientation, getGridLocation, getLocationOrientation, getPaneData, getPanelData, getRelativeLocation, indexInParent, isGridBranchNode, isGroupOptionsWithGroup, isGroupOptionsWithPanel, isPanelOptionsWithGroup, isPanelOptionsWithPanel, isReactElement, orthogonal, positionToDirection, toTarget, usePortalsLifecycle };
10056
+ export { BaseGrid, ContentContainer, DefaultDockviewDeserialzier, DefaultTab, DockviewApi, DockviewComponent, CompositeDisposable as DockviewCompositeDisposable, DockviewDefaultTab, DockviewDidDropEvent, Emitter as DockviewEmitter, Event as DockviewEvent, DockviewGroupPanel, DockviewGroupPanelModel, MutableDisposable as DockviewMutableDisposable, DockviewPanel, DockviewReact, DockviewWillDropEvent, DraggablePaneviewPanel, Gridview, GridviewApi, GridviewComponent, GridviewPanel, GridviewReact, LayoutPriority, LocalSelectionTransfer, Orientation, PaneFramework, PaneTransfer, PanelTransfer, Paneview, PaneviewApi, PaneviewComponent, PaneviewPanel, PaneviewReact, ReactPart, ReactPartContext, SashState, Sizing, Splitview, SplitviewApi, SplitviewComponent, SplitviewPanel, SplitviewReact, Tab, WillShowOverlayLocationEvent, createComponent, directionToPosition, getDirectionOrientation, getGridLocation, getLocationOrientation, getPaneData, getPanelData, getRelativeLocation, indexInParent, isGridBranchNode, isGroupOptionsWithGroup, isGroupOptionsWithPanel, isPanelOptionsWithGroup, isPanelOptionsWithPanel, isReactComponent, orthogonal, positionToDirection, toTarget, usePortalsLifecycle };
9310
10057
  //# sourceMappingURL=dockview.esm.js.map