dockview 1.9.2 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/dist/cjs/dockview/defaultTab.d.ts +0 -1
  2. package/dist/cjs/dockview/defaultTab.js +0 -1
  3. package/dist/cjs/dockview/dockview.d.ts +5 -3
  4. package/dist/cjs/dockview/dockview.js +31 -1
  5. package/dist/cjs/dockview/headerActionsRenderer.d.ts +0 -1
  6. package/dist/cjs/dockview/headerActionsRenderer.js +0 -1
  7. package/dist/cjs/dockview/reactContentPart.d.ts +0 -1
  8. package/dist/cjs/dockview/reactContentPart.js +0 -1
  9. package/dist/cjs/dockview/reactHeaderPart.d.ts +0 -1
  10. package/dist/cjs/dockview/reactHeaderPart.js +0 -1
  11. package/dist/cjs/dockview/reactWatermarkPart.d.ts +0 -1
  12. package/dist/cjs/dockview/reactWatermarkPart.js +0 -1
  13. package/dist/cjs/gridview/gridview.d.ts +0 -1
  14. package/dist/cjs/gridview/gridview.js +0 -1
  15. package/dist/cjs/gridview/view.d.ts +0 -1
  16. package/dist/cjs/gridview/view.js +3 -2
  17. package/dist/cjs/index.d.ts +0 -1
  18. package/dist/cjs/index.js +0 -1
  19. package/dist/cjs/paneview/paneview.d.ts +0 -1
  20. package/dist/cjs/paneview/paneview.js +0 -1
  21. package/dist/cjs/paneview/view.d.ts +0 -1
  22. package/dist/cjs/paneview/view.js +0 -1
  23. package/dist/cjs/react.d.ts +1 -2
  24. package/dist/cjs/react.js +13 -10
  25. package/dist/cjs/splitview/splitview.d.ts +0 -1
  26. package/dist/cjs/splitview/splitview.js +0 -1
  27. package/dist/cjs/splitview/view.d.ts +0 -1
  28. package/dist/cjs/splitview/view.js +0 -1
  29. package/dist/cjs/svg.d.ts +0 -1
  30. package/dist/cjs/svg.js +0 -1
  31. package/dist/cjs/types.d.ts +0 -1
  32. package/dist/cjs/types.js +0 -1
  33. package/dist/dockview.amd.js +1325 -544
  34. package/dist/dockview.amd.js.map +1 -1
  35. package/dist/dockview.amd.min.js +2 -2
  36. package/dist/dockview.amd.min.js.map +1 -1
  37. package/dist/dockview.amd.min.noStyle.js +2 -2
  38. package/dist/dockview.amd.min.noStyle.js.map +1 -1
  39. package/dist/dockview.amd.noStyle.js +1325 -544
  40. package/dist/dockview.amd.noStyle.js.map +1 -1
  41. package/dist/dockview.cjs.js +1325 -544
  42. package/dist/dockview.cjs.js.map +1 -1
  43. package/dist/dockview.esm.js +1322 -544
  44. package/dist/dockview.esm.js.map +1 -1
  45. package/dist/dockview.esm.min.js +2 -2
  46. package/dist/dockview.esm.min.js.map +1 -1
  47. package/dist/dockview.js +1325 -544
  48. package/dist/dockview.js.map +1 -1
  49. package/dist/dockview.min.js +2 -2
  50. package/dist/dockview.min.js.map +1 -1
  51. package/dist/dockview.min.noStyle.js +2 -2
  52. package/dist/dockview.min.noStyle.js.map +1 -1
  53. package/dist/dockview.noStyle.js +1325 -544
  54. package/dist/dockview.noStyle.js.map +1 -1
  55. package/dist/esm/dockview/defaultTab.d.ts +0 -1
  56. package/dist/esm/dockview/defaultTab.js +0 -1
  57. package/dist/esm/dockview/dockview.d.ts +5 -3
  58. package/dist/esm/dockview/dockview.js +31 -1
  59. package/dist/esm/dockview/headerActionsRenderer.d.ts +0 -1
  60. package/dist/esm/dockview/headerActionsRenderer.js +0 -1
  61. package/dist/esm/dockview/reactContentPart.d.ts +0 -1
  62. package/dist/esm/dockview/reactContentPart.js +0 -1
  63. package/dist/esm/dockview/reactHeaderPart.d.ts +0 -1
  64. package/dist/esm/dockview/reactHeaderPart.js +0 -1
  65. package/dist/esm/dockview/reactWatermarkPart.d.ts +0 -1
  66. package/dist/esm/dockview/reactWatermarkPart.js +0 -1
  67. package/dist/esm/gridview/gridview.d.ts +0 -1
  68. package/dist/esm/gridview/gridview.js +0 -1
  69. package/dist/esm/gridview/view.d.ts +0 -1
  70. package/dist/esm/gridview/view.js +3 -2
  71. package/dist/esm/index.d.ts +0 -1
  72. package/dist/esm/index.js +0 -1
  73. package/dist/esm/paneview/paneview.d.ts +0 -1
  74. package/dist/esm/paneview/paneview.js +0 -1
  75. package/dist/esm/paneview/view.d.ts +0 -1
  76. package/dist/esm/paneview/view.js +0 -1
  77. package/dist/esm/react.d.ts +1 -2
  78. package/dist/esm/react.js +11 -8
  79. package/dist/esm/splitview/splitview.d.ts +0 -1
  80. package/dist/esm/splitview/splitview.js +0 -1
  81. package/dist/esm/splitview/view.d.ts +0 -1
  82. package/dist/esm/splitview/view.js +0 -1
  83. package/dist/esm/svg.d.ts +0 -1
  84. package/dist/esm/svg.js +0 -1
  85. package/dist/esm/types.d.ts +0 -1
  86. package/dist/esm/types.js +0 -1
  87. package/package.json +4 -4
  88. package/dist/cjs/dockview/defaultTab.d.ts.map +0 -1
  89. package/dist/cjs/dockview/defaultTab.js.map +0 -1
  90. package/dist/cjs/dockview/dockview.d.ts.map +0 -1
  91. package/dist/cjs/dockview/dockview.js.map +0 -1
  92. package/dist/cjs/dockview/headerActionsRenderer.d.ts.map +0 -1
  93. package/dist/cjs/dockview/headerActionsRenderer.js.map +0 -1
  94. package/dist/cjs/dockview/reactContentPart.d.ts.map +0 -1
  95. package/dist/cjs/dockview/reactContentPart.js.map +0 -1
  96. package/dist/cjs/dockview/reactHeaderPart.d.ts.map +0 -1
  97. package/dist/cjs/dockview/reactHeaderPart.js.map +0 -1
  98. package/dist/cjs/dockview/reactWatermarkPart.d.ts.map +0 -1
  99. package/dist/cjs/dockview/reactWatermarkPart.js.map +0 -1
  100. package/dist/cjs/gridview/gridview.d.ts.map +0 -1
  101. package/dist/cjs/gridview/gridview.js.map +0 -1
  102. package/dist/cjs/gridview/view.d.ts.map +0 -1
  103. package/dist/cjs/gridview/view.js.map +0 -1
  104. package/dist/cjs/index.d.ts.map +0 -1
  105. package/dist/cjs/index.js.map +0 -1
  106. package/dist/cjs/paneview/paneview.d.ts.map +0 -1
  107. package/dist/cjs/paneview/paneview.js.map +0 -1
  108. package/dist/cjs/paneview/view.d.ts.map +0 -1
  109. package/dist/cjs/paneview/view.js.map +0 -1
  110. package/dist/cjs/react.d.ts.map +0 -1
  111. package/dist/cjs/react.js.map +0 -1
  112. package/dist/cjs/splitview/splitview.d.ts.map +0 -1
  113. package/dist/cjs/splitview/splitview.js.map +0 -1
  114. package/dist/cjs/splitview/view.d.ts.map +0 -1
  115. package/dist/cjs/splitview/view.js.map +0 -1
  116. package/dist/cjs/svg.d.ts.map +0 -1
  117. package/dist/cjs/svg.js.map +0 -1
  118. package/dist/cjs/types.d.ts.map +0 -1
  119. package/dist/cjs/types.js.map +0 -1
  120. package/dist/esm/dockview/defaultTab.d.ts.map +0 -1
  121. package/dist/esm/dockview/defaultTab.js.map +0 -1
  122. package/dist/esm/dockview/dockview.d.ts.map +0 -1
  123. package/dist/esm/dockview/dockview.js.map +0 -1
  124. package/dist/esm/dockview/headerActionsRenderer.d.ts.map +0 -1
  125. package/dist/esm/dockview/headerActionsRenderer.js.map +0 -1
  126. package/dist/esm/dockview/reactContentPart.d.ts.map +0 -1
  127. package/dist/esm/dockview/reactContentPart.js.map +0 -1
  128. package/dist/esm/dockview/reactHeaderPart.d.ts.map +0 -1
  129. package/dist/esm/dockview/reactHeaderPart.js.map +0 -1
  130. package/dist/esm/dockview/reactWatermarkPart.d.ts.map +0 -1
  131. package/dist/esm/dockview/reactWatermarkPart.js.map +0 -1
  132. package/dist/esm/gridview/gridview.d.ts.map +0 -1
  133. package/dist/esm/gridview/gridview.js.map +0 -1
  134. package/dist/esm/gridview/view.d.ts.map +0 -1
  135. package/dist/esm/gridview/view.js.map +0 -1
  136. package/dist/esm/index.d.ts.map +0 -1
  137. package/dist/esm/index.js.map +0 -1
  138. package/dist/esm/paneview/paneview.d.ts.map +0 -1
  139. package/dist/esm/paneview/paneview.js.map +0 -1
  140. package/dist/esm/paneview/view.d.ts.map +0 -1
  141. package/dist/esm/paneview/view.js.map +0 -1
  142. package/dist/esm/react.d.ts.map +0 -1
  143. package/dist/esm/react.js.map +0 -1
  144. package/dist/esm/splitview/splitview.d.ts.map +0 -1
  145. package/dist/esm/splitview/splitview.js.map +0 -1
  146. package/dist/esm/splitview/view.d.ts.map +0 -1
  147. package/dist/esm/splitview/view.js.map +0 -1
  148. package/dist/esm/svg.d.ts.map +0 -1
  149. package/dist/esm/svg.js.map +0 -1
  150. package/dist/esm/types.d.ts.map +0 -1
  151. package/dist/esm/types.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview
3
- * @version 1.9.2
3
+ * @version 1.10.1
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -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();
@@ -1453,6 +1479,9 @@ class Paneview extends CompositeDisposable {
1453
1479
  this._onDidChange.fire();
1454
1480
  }));
1455
1481
  }
1482
+ setViewVisible(index, visible) {
1483
+ this.splitview.setViewVisible(index, visible);
1484
+ }
1456
1485
  addPane(pane, size, index = this.splitview.length, skipLayout = false) {
1457
1486
  const disposable = pane.onDidChangeExpansionState(() => {
1458
1487
  this.setupAnimation();
@@ -1706,7 +1735,13 @@ class BranchNode extends CompositeDisposable {
1706
1735
  }
1707
1736
  return LayoutPriority.Normal;
1708
1737
  }
1709
- constructor(orientation, proportionalLayout, styles, size, orthogonalSize, childDescriptors) {
1738
+ get disabled() {
1739
+ return this.splitview.disabled;
1740
+ }
1741
+ set disabled(value) {
1742
+ this.splitview.disabled = value;
1743
+ }
1744
+ constructor(orientation, proportionalLayout, styles, size, orthogonalSize, disabled, childDescriptors) {
1710
1745
  super();
1711
1746
  this.orientation = orientation;
1712
1747
  this.proportionalLayout = proportionalLayout;
@@ -1751,6 +1786,7 @@ class BranchNode extends CompositeDisposable {
1751
1786
  styles,
1752
1787
  });
1753
1788
  }
1789
+ this.disabled = disabled;
1754
1790
  this.addDisposables(this._onDidChange, this._onDidVisibilityChange, this.splitview.onDidSashEnd(() => {
1755
1791
  this._onDidChange.fire({});
1756
1792
  }));
@@ -1884,7 +1920,7 @@ function findLeaf(candiateNode, last) {
1884
1920
  }
1885
1921
  function flipNode(node, size, orthogonalSize) {
1886
1922
  if (node instanceof BranchNode) {
1887
- const result = new BranchNode(orthogonal(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize);
1923
+ const result = new BranchNode(orthogonal(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled);
1888
1924
  let totalSize = 0;
1889
1925
  for (let i = node.children.length - 1; i >= 0; i--) {
1890
1926
  const child = node.children[i];
@@ -2020,31 +2056,57 @@ class Gridview {
2020
2056
  get maximumHeight() {
2021
2057
  return this.root.maximumHeight;
2022
2058
  }
2059
+ get locked() {
2060
+ return this._locked;
2061
+ }
2062
+ set locked(value) {
2063
+ this._locked = value;
2064
+ const branch = [this.root];
2065
+ /**
2066
+ * simple depth-first-search to cover all nodes
2067
+ *
2068
+ * @see https://en.wikipedia.org/wiki/Depth-first_search
2069
+ */
2070
+ while (branch.length > 0) {
2071
+ const node = branch.pop();
2072
+ if (node instanceof BranchNode) {
2073
+ node.disabled = value;
2074
+ branch.push(...node.children);
2075
+ }
2076
+ }
2077
+ }
2023
2078
  maximizedView() {
2024
2079
  var _a;
2025
- return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.view;
2080
+ return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.leaf.view;
2026
2081
  }
2027
2082
  hasMaximizedView() {
2028
2083
  return this._maximizedNode !== undefined;
2029
2084
  }
2030
2085
  maximizeView(view) {
2086
+ var _a;
2031
2087
  const location = getGridLocation(view.element);
2032
2088
  const [_, node] = this.getNode(location);
2033
2089
  if (!(node instanceof LeafNode)) {
2034
2090
  return;
2035
2091
  }
2036
- if (this._maximizedNode === node) {
2092
+ if (((_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.leaf) === node) {
2037
2093
  return;
2038
2094
  }
2039
2095
  if (this.hasMaximizedView()) {
2040
2096
  this.exitMaximizedView();
2041
2097
  }
2098
+ const hiddenOnMaximize = [];
2042
2099
  function hideAllViewsBut(parent, exclude) {
2043
2100
  for (let i = 0; i < parent.children.length; i++) {
2044
2101
  const child = parent.children[i];
2045
2102
  if (child instanceof LeafNode) {
2046
2103
  if (child !== exclude) {
2047
- parent.setChildVisible(i, false);
2104
+ if (parent.isChildVisible(i)) {
2105
+ parent.setChildVisible(i, false);
2106
+ }
2107
+ else {
2108
+ hiddenOnMaximize.push(child);
2109
+ }
2048
2110
  }
2049
2111
  }
2050
2112
  else {
@@ -2053,18 +2115,21 @@ class Gridview {
2053
2115
  }
2054
2116
  }
2055
2117
  hideAllViewsBut(this.root, node);
2056
- this._maximizedNode = node;
2057
- this._onDidMaxmizedNodeChange.fire();
2118
+ this._maximizedNode = { leaf: node, hiddenOnMaximize };
2119
+ this._onDidMaximizedNodeChange.fire();
2058
2120
  }
2059
2121
  exitMaximizedView() {
2060
2122
  if (!this._maximizedNode) {
2061
2123
  return;
2062
2124
  }
2125
+ const hiddenOnMaximize = this._maximizedNode.hiddenOnMaximize;
2063
2126
  function showViewsInReverseOrder(parent) {
2064
2127
  for (let index = parent.children.length - 1; index >= 0; index--) {
2065
2128
  const child = parent.children[index];
2066
2129
  if (child instanceof LeafNode) {
2067
- parent.setChildVisible(index, true);
2130
+ if (!hiddenOnMaximize.includes(child)) {
2131
+ parent.setChildVisible(index, true);
2132
+ }
2068
2133
  }
2069
2134
  else {
2070
2135
  showViewsInReverseOrder(child);
@@ -2073,13 +2138,13 @@ class Gridview {
2073
2138
  }
2074
2139
  showViewsInReverseOrder(this.root);
2075
2140
  this._maximizedNode = undefined;
2076
- this._onDidMaxmizedNodeChange.fire();
2141
+ this._onDidMaximizedNodeChange.fire();
2077
2142
  }
2078
2143
  serialize() {
2079
2144
  if (this.hasMaximizedView()) {
2080
2145
  /**
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
2146
+ * do not persist maximized view state
2147
+ * firstly exit any maximized views to ensure the correct dimensions are persisted
2083
2148
  */
2084
2149
  this.exitMaximizedView();
2085
2150
  }
@@ -2094,14 +2159,14 @@ class Gridview {
2094
2159
  dispose() {
2095
2160
  this.disposable.dispose();
2096
2161
  this._onDidChange.dispose();
2097
- this._onDidMaxmizedNodeChange.dispose();
2162
+ this._onDidMaximizedNodeChange.dispose();
2098
2163
  this.root.dispose();
2099
2164
  this._maximizedNode = undefined;
2100
2165
  this.element.remove();
2101
2166
  }
2102
2167
  clear() {
2103
2168
  const orientation = this.root.orientation;
2104
- this.root = new BranchNode(orientation, this.proportionalLayout, this.styles, this.root.size, this.root.orthogonalSize);
2169
+ this.root = new BranchNode(orientation, this.proportionalLayout, this.styles, this.root.size, this.root.orthogonalSize, this._locked);
2105
2170
  }
2106
2171
  deserialize(json, deserializer) {
2107
2172
  const orientation = json.orientation;
@@ -2122,8 +2187,8 @@ class Gridview {
2122
2187
  };
2123
2188
  });
2124
2189
  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);
2190
+ orthogonalSize, // <- size - flips at each depth,
2191
+ this._locked, children);
2127
2192
  }
2128
2193
  else {
2129
2194
  result = new LeafNode(deserializer.fromJSON(node), orientation, orthogonalSize, node.size);
@@ -2156,7 +2221,7 @@ class Gridview {
2156
2221
  }
2157
2222
  const oldRoot = this.root;
2158
2223
  oldRoot.element.remove();
2159
- this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size);
2224
+ this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size, this._locked);
2160
2225
  if (oldRoot.children.length === 0) ;
2161
2226
  else if (oldRoot.children.length === 1) {
2162
2227
  // can remove one level of redundant branching if there is only a single child
@@ -2224,15 +2289,16 @@ class Gridview {
2224
2289
  constructor(proportionalLayout, styles, orientation) {
2225
2290
  this.proportionalLayout = proportionalLayout;
2226
2291
  this.styles = styles;
2292
+ this._locked = false;
2227
2293
  this._maximizedNode = undefined;
2228
2294
  this.disposable = new MutableDisposable();
2229
2295
  this._onDidChange = new Emitter();
2230
2296
  this.onDidChange = this._onDidChange.event;
2231
- this._onDidMaxmizedNodeChange = new Emitter();
2232
- this.onDidMaxmizedNodeChange = this._onDidMaxmizedNodeChange.event;
2297
+ this._onDidMaximizedNodeChange = new Emitter();
2298
+ this.onDidMaximizedNodeChange = this._onDidMaximizedNodeChange.event;
2233
2299
  this.element = document.createElement('div');
2234
2300
  this.element.className = 'grid-view';
2235
- this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0);
2301
+ this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0, this._locked);
2236
2302
  }
2237
2303
  isViewVisible(location) {
2238
2304
  const [rest, index] = tail(location);
@@ -2283,7 +2349,7 @@ class Gridview {
2283
2349
  }
2284
2350
  const child = grandParent.removeChild(parentIndex);
2285
2351
  child.dispose();
2286
- const newParent = new BranchNode(parent.orientation, this.proportionalLayout, this.styles, parent.size, parent.orthogonalSize);
2352
+ const newParent = new BranchNode(parent.orientation, this.proportionalLayout, this.styles, parent.size, parent.orthogonalSize, this._locked);
2287
2353
  grandParent.addChild(newParent, parent.size, parentIndex);
2288
2354
  const newSibling = new LeafNode(parent.view, grandParent.orientation, parent.size);
2289
2355
  newParent.addChild(newSibling, newSiblingSize, 0);
@@ -2911,13 +2977,36 @@ class DockviewApi {
2911
2977
  return this.component.onDidDrop;
2912
2978
  }
2913
2979
  /**
2914
- * Invoked before a group is dragged. Exposed for custom Drag'n'Drop functionality.
2980
+ * Invoked when a Drag'n'Drop event occurs but before dockview handles it giving the user an opportunity to intecept and
2981
+ * prevent the event from occuring using the standard `preventDefault()` syntax.
2982
+ *
2983
+ * Preventing certain events may causes unexpected behaviours, use carefully.
2984
+ */
2985
+ get onWillDrop() {
2986
+ return this.component.onWillDrop;
2987
+ }
2988
+ /**
2989
+ * Invoked before an overlay is shown indicating a drop target.
2990
+ *
2991
+ * Calling `event.preventDefault()` will prevent the overlay being shown and prevent
2992
+ * the any subsequent drop event.
2993
+ */
2994
+ get onWillShowOverlay() {
2995
+ return this.component.onWillShowOverlay;
2996
+ }
2997
+ /**
2998
+ * Invoked before a group is dragged.
2999
+ *
3000
+ * Calling `event.nativeEvent.preventDefault()` will prevent the group drag starting.
3001
+ *
2915
3002
  */
2916
3003
  get onWillDragGroup() {
2917
3004
  return this.component.onWillDragGroup;
2918
3005
  }
2919
3006
  /**
2920
- * Invoked before a panel is dragged. Exposed for custom Drag'n'Drop functionality.
3007
+ * Invoked before a panel is dragged.
3008
+ *
3009
+ * Calling `event.nativeEvent.preventDefault()` will prevent the panel drag starting.
2921
3010
  */
2922
3011
  get onWillDragPanel() {
2923
3012
  return this.component.onWillDragPanel;
@@ -3045,17 +3134,17 @@ class DockviewApi {
3045
3134
  hasMaximizedGroup() {
3046
3135
  return this.component.hasMaximizedGroup();
3047
3136
  }
3048
- exitMaxmizedGroup() {
3137
+ exitMaximizedGroup() {
3049
3138
  this.component.exitMaximizedGroup();
3050
3139
  }
3051
- get onDidMaxmizedGroupChange() {
3052
- return this.component.onDidMaxmizedGroupChange;
3140
+ get onDidMaximizedGroupChange() {
3141
+ return this.component.onDidMaximizedGroupChange;
3053
3142
  }
3054
3143
  /**
3055
3144
  * Add a popout group in a new Window
3056
3145
  */
3057
3146
  addPopoutGroup(item, options) {
3058
- this.component.addPopoutGroup(item, options);
3147
+ return this.component.addPopoutGroup(item, options);
3059
3148
  }
3060
3149
  }
3061
3150
 
@@ -3109,6 +3198,18 @@ class DragAndDropObserver extends CompositeDisposable {
3109
3198
  }
3110
3199
  }
3111
3200
 
3201
+ class WillShowOverlayEvent extends DockviewEvent {
3202
+ get nativeEvent() {
3203
+ return this.options.nativeEvent;
3204
+ }
3205
+ get position() {
3206
+ return this.options.position;
3207
+ }
3208
+ constructor(options) {
3209
+ super();
3210
+ this.options = options;
3211
+ }
3212
+ }
3112
3213
  function directionToPosition(direction) {
3113
3214
  switch (direction) {
3114
3215
  case 'above':
@@ -3161,6 +3262,8 @@ class Droptarget extends CompositeDisposable {
3161
3262
  this.options = options;
3162
3263
  this._onDrop = new Emitter();
3163
3264
  this.onDrop = this._onDrop.event;
3265
+ this._onWillShowOverlay = new Emitter();
3266
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
3164
3267
  // use a set to take advantage of #<set>.has
3165
3268
  this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
3166
3269
  this.dnd = new DragAndDropObserver(this.element, {
@@ -3189,6 +3292,19 @@ class Droptarget extends CompositeDisposable {
3189
3292
  this.removeDropTarget();
3190
3293
  return;
3191
3294
  }
3295
+ const willShowOverlayEvent = new WillShowOverlayEvent({
3296
+ nativeEvent: e,
3297
+ position: quadrant,
3298
+ });
3299
+ /**
3300
+ * Provide an opportunity to prevent the overlay appearing and in turn
3301
+ * any dnd behaviours
3302
+ */
3303
+ this._onWillShowOverlay.fire(willShowOverlayEvent);
3304
+ if (willShowOverlayEvent.defaultPrevented) {
3305
+ this.removeDropTarget();
3306
+ return;
3307
+ }
3192
3308
  if (typeof this.options.canDisplayOverlay === 'boolean') {
3193
3309
  if (!this.options.canDisplayOverlay) {
3194
3310
  this.removeDropTarget();
@@ -3231,7 +3347,7 @@ class Droptarget extends CompositeDisposable {
3231
3347
  }
3232
3348
  },
3233
3349
  });
3234
- this.addDisposables(this._onDrop, this.dnd);
3350
+ this.addDisposables(this._onDrop, this._onWillShowOverlay, this.dnd);
3235
3351
  }
3236
3352
  setTargetZones(acceptedTargetZones) {
3237
3353
  this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
@@ -3284,25 +3400,44 @@ class Droptarget extends CompositeDisposable {
3284
3400
  size = clamp(0, sizeOptions.value, height) / height;
3285
3401
  }
3286
3402
  }
3287
- const translate = (1 - size) / 2;
3288
- const scale = size;
3289
- let transform;
3403
+ const box = { top: '0px', left: '0px', width: '100%', height: '100%' };
3404
+ /**
3405
+ * You can also achieve the overlay placement using the transform CSS property
3406
+ * to translate and scale the element however this has the undesired effect of
3407
+ * 'skewing' the element. Comment left here for anybody that ever revisits this.
3408
+ *
3409
+ * @see https://developer.mozilla.org/en-US/docs/Web/CSS/transform
3410
+ *
3411
+ * right
3412
+ * translateX(${100 * (1 - size) / 2}%) scaleX(${scale})
3413
+ *
3414
+ * left
3415
+ * translateX(-${100 * (1 - size) / 2}%) scaleX(${scale})
3416
+ *
3417
+ * top
3418
+ * translateY(-${100 * (1 - size) / 2}%) scaleY(${scale})
3419
+ *
3420
+ * bottom
3421
+ * translateY(${100 * (1 - size) / 2}%) scaleY(${scale})
3422
+ */
3290
3423
  if (rightClass) {
3291
- transform = `translateX(${100 * translate}%) scaleX(${scale})`;
3424
+ box.left = `${100 * (1 - size)}%`;
3425
+ box.width = `${100 * size}%`;
3292
3426
  }
3293
3427
  else if (leftClass) {
3294
- transform = `translateX(-${100 * translate}%) scaleX(${scale})`;
3428
+ box.width = `${100 * size}%`;
3295
3429
  }
3296
3430
  else if (topClass) {
3297
- transform = `translateY(-${100 * translate}%) scaleY(${scale})`;
3431
+ box.height = `${100 * size}%`;
3298
3432
  }
3299
3433
  else if (bottomClass) {
3300
- transform = `translateY(${100 * translate}%) scaleY(${scale})`;
3301
- }
3302
- else {
3303
- transform = '';
3434
+ box.top = `${100 * (1 - size)}%`;
3435
+ box.height = `${100 * size}%`;
3304
3436
  }
3305
- this.overlayElement.style.transform = transform;
3437
+ this.overlayElement.style.top = box.top;
3438
+ this.overlayElement.style.left = box.left;
3439
+ this.overlayElement.style.width = box.width;
3440
+ this.overlayElement.style.height = box.height;
3306
3441
  toggleClass(this.overlayElement, 'dv-drop-target-small-vertical', isSmallY);
3307
3442
  toggleClass(this.overlayElement, 'dv-drop-target-small-horizontal', isSmallX);
3308
3443
  toggleClass(this.overlayElement, 'dv-drop-target-left', isLeft);
@@ -3370,14 +3505,6 @@ function calculateQuadrantAsPixels(overlayType, x, y, width, height, threshold)
3370
3505
  return 'center';
3371
3506
  }
3372
3507
 
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
3508
  class ContentContainer extends CompositeDisposable {
3382
3509
  get element() {
3383
3510
  return this._element;
@@ -3405,7 +3532,7 @@ class ContentContainer extends CompositeDisposable {
3405
3532
  const data = getPanelData();
3406
3533
  if (!data &&
3407
3534
  event.shiftKey &&
3408
- this.group.location !== 'floating') {
3535
+ this.group.location.type !== 'floating') {
3409
3536
  return false;
3410
3537
  }
3411
3538
  if (data && data.viewId === this.accessor.id) {
@@ -3423,7 +3550,7 @@ class ContentContainer extends CompositeDisposable {
3423
3550
  data.groupId === this.group.id;
3424
3551
  return !groupHasOnePanelAndIsActiveDragElement;
3425
3552
  }
3426
- return this.group.canDisplayOverlay(event, position, DockviewDropTargets.Panel);
3553
+ return this.group.canDisplayOverlay(event, position, 'content');
3427
3554
  },
3428
3555
  });
3429
3556
  this.addDisposables(this.dropTarget);
@@ -3448,7 +3575,7 @@ class ContentContainer extends CompositeDisposable {
3448
3575
  let container;
3449
3576
  switch (panel.api.renderer) {
3450
3577
  case 'onlyWhenVisibile':
3451
- this.accessor.overlayRenderContainer.detatch(panel);
3578
+ this.group.renderContainer.detatch(panel);
3452
3579
  if (this.panel) {
3453
3580
  if (doRender) {
3454
3581
  this._element.appendChild(this.panel.view.content.element);
@@ -3460,7 +3587,7 @@ class ContentContainer extends CompositeDisposable {
3460
3587
  if (panel.view.content.element.parentElement === this._element) {
3461
3588
  this._element.removeChild(panel.view.content.element);
3462
3589
  }
3463
- container = this.accessor.overlayRenderContainer.attach({
3590
+ container = this.group.renderContainer.attach({
3464
3591
  panel,
3465
3592
  referenceContainer: this,
3466
3593
  });
@@ -3491,9 +3618,10 @@ class ContentContainer extends CompositeDisposable {
3491
3618
  // noop
3492
3619
  }
3493
3620
  closePanel() {
3621
+ var _a;
3494
3622
  if (this.panel) {
3495
3623
  if (this.panel.api.renderer === 'onlyWhenVisibile') {
3496
- this._element.removeChild(this.panel.view.content.element);
3624
+ (_a = this.panel.view.content.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.panel.view.content.element);
3497
3625
  }
3498
3626
  }
3499
3627
  this.panel = undefined;
@@ -3604,7 +3732,7 @@ class Tab extends CompositeDisposable {
3604
3732
  this._element.draggable = true;
3605
3733
  toggleClass(this.element, 'inactive-tab', true);
3606
3734
  const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
3607
- this.droptarget = new Droptarget(this._element, {
3735
+ this.dropTarget = new Droptarget(this._element, {
3608
3736
  acceptedTargetZones: ['center'],
3609
3737
  canDisplayOverlay: (event, position) => {
3610
3738
  if (this.group.locked) {
@@ -3619,9 +3747,10 @@ class Tab extends CompositeDisposable {
3619
3747
  }
3620
3748
  return this.panel.id !== data.panelId;
3621
3749
  }
3622
- return this.group.model.canDisplayOverlay(event, position, DockviewDropTargets.Tab);
3750
+ return this.group.model.canDisplayOverlay(event, position, 'tab');
3623
3751
  },
3624
3752
  });
3753
+ this.onWillShowOverlay = this.dropTarget.onWillShowOverlay;
3625
3754
  this.addDisposables(this._onChanged, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
3626
3755
  this._onDragStart.fire(event);
3627
3756
  }), dragHandler, addDisposableListener(this._element, 'mousedown', (event) => {
@@ -3629,9 +3758,9 @@ class Tab extends CompositeDisposable {
3629
3758
  return;
3630
3759
  }
3631
3760
  this._onChanged.fire(event);
3632
- }), this.droptarget.onDrop((event) => {
3761
+ }), this.dropTarget.onDrop((event) => {
3633
3762
  this._onDropped.fire(event);
3634
- }), this.droptarget);
3763
+ }), this.dropTarget);
3635
3764
  }
3636
3765
  setActive(isActive) {
3637
3766
  toggleClass(this.element, 'active-tab', isActive);
@@ -3678,7 +3807,7 @@ class GroupDragHandler extends DragHandler {
3678
3807
  }, true));
3679
3808
  }
3680
3809
  isCancelled(_event) {
3681
- if (this.group.api.location === 'floating' && !_event.shiftKey) {
3810
+ if (this.group.api.location.type === 'floating' && !_event.shiftKey) {
3682
3811
  return true;
3683
3812
  }
3684
3813
  return false;
@@ -3730,7 +3859,7 @@ class VoidContainer extends CompositeDisposable {
3730
3859
  this.accessor.doSetGroupActive(this.group);
3731
3860
  }));
3732
3861
  const handler = new GroupDragHandler(this._element, accessor, group);
3733
- this.voidDropTarget = new Droptarget(this._element, {
3862
+ this.dropTraget = new Droptarget(this._element, {
3734
3863
  acceptedTargetZones: ['center'],
3735
3864
  canDisplayOverlay: (event, position) => {
3736
3865
  var _a;
@@ -3744,14 +3873,15 @@ class VoidContainer extends CompositeDisposable {
3744
3873
  // don't show the overlay if the tab being dragged is the last panel of this group
3745
3874
  return ((_a = last(this.group.panels)) === null || _a === void 0 ? void 0 : _a.id) !== data.panelId;
3746
3875
  }
3747
- return group.model.canDisplayOverlay(event, position, DockviewDropTargets.Panel);
3876
+ return group.model.canDisplayOverlay(event, position, 'header_space');
3748
3877
  },
3749
3878
  });
3879
+ this.onWillShowOverlay = this.dropTraget.onWillShowOverlay;
3750
3880
  this.addDisposables(handler, handler.onDragStart((event) => {
3751
3881
  this._onDragStart.fire(event);
3752
- }), this.voidDropTarget.onDrop((event) => {
3882
+ }), this.dropTraget.onDrop((event) => {
3753
3883
  this._onDrop.fire(event);
3754
- }), this.voidDropTarget);
3884
+ }), this.dropTraget);
3755
3885
  }
3756
3886
  }
3757
3887
 
@@ -3839,19 +3969,11 @@ class TabsContainer extends CompositeDisposable {
3839
3969
  this.onTabDragStart = this._onTabDragStart.event;
3840
3970
  this._onGroupDragStart = new Emitter();
3841
3971
  this.onGroupDragStart = this._onGroupDragStart.event;
3842
- this.addDisposables(this._onDrop, this._onTabDragStart, this._onGroupDragStart);
3972
+ this._onWillShowOverlay = new Emitter();
3973
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
3843
3974
  this._element = document.createElement('div');
3844
3975
  this._element.className = 'tabs-and-actions-container';
3845
3976
  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
3977
  this.rightActionsContainer = document.createElement('div');
3856
3978
  this.rightActionsContainer.className = 'right-actions-container';
3857
3979
  this.leftActionsContainer = document.createElement('div');
@@ -3866,7 +3988,15 @@ class TabsContainer extends CompositeDisposable {
3866
3988
  this._element.appendChild(this.leftActionsContainer);
3867
3989
  this._element.appendChild(this.voidContainer.element);
3868
3990
  this._element.appendChild(this.rightActionsContainer);
3869
- this.addDisposables(this.voidContainer, this.voidContainer.onDragStart((event) => {
3991
+ this.addDisposables(this.accessor.onDidAddPanel((e) => {
3992
+ if (e.api.group === this.group) {
3993
+ toggleClass(this._element, 'dv-single-tab', this.size === 1);
3994
+ }
3995
+ }), this.accessor.onDidRemovePanel((e) => {
3996
+ if (e.api.group === this.group) {
3997
+ toggleClass(this._element, 'dv-single-tab', this.size === 1);
3998
+ }
3999
+ }), this._onWillShowOverlay, this._onDrop, this._onTabDragStart, this._onGroupDragStart, this.voidContainer, this.voidContainer.onDragStart((event) => {
3870
4000
  this._onGroupDragStart.fire({
3871
4001
  nativeEvent: event,
3872
4002
  group: this.group,
@@ -3876,11 +4006,15 @@ class TabsContainer extends CompositeDisposable {
3876
4006
  event: event.nativeEvent,
3877
4007
  index: this.tabs.length,
3878
4008
  });
4009
+ }), this.voidContainer.onWillShowOverlay((event) => {
4010
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
4011
+ kind: 'header_space',
4012
+ }));
3879
4013
  }), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => {
3880
4014
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3881
4015
  if (isFloatingGroupsEnabled &&
3882
4016
  event.shiftKey &&
3883
- this.group.api.location !== 'floating') {
4017
+ this.group.api.location.type !== 'floating') {
3884
4018
  event.preventDefault();
3885
4019
  const { top, left } = this.element.getBoundingClientRect();
3886
4020
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
@@ -3943,9 +4077,9 @@ class TabsContainer extends CompositeDisposable {
3943
4077
  const disposable = new CompositeDisposable(tab.onDragStart((event) => {
3944
4078
  this._onTabDragStart.fire({ nativeEvent: event, panel });
3945
4079
  }), tab.onChanged((event) => {
3946
- var _a;
3947
4080
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3948
- const isFloatingWithOnePanel = this.group.api.location === 'floating' && this.size === 1;
4081
+ const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
4082
+ this.size === 1;
3949
4083
  if (isFloatingGroupsEnabled &&
3950
4084
  !isFloatingWithOnePanel &&
3951
4085
  event.shiftKey) {
@@ -3959,20 +4093,20 @@ class TabsContainer extends CompositeDisposable {
3959
4093
  }, { inDragMode: true });
3960
4094
  return;
3961
4095
  }
3962
- const alreadyFocused = panel.id === ((_a = this.group.model.activePanel) === null || _a === void 0 ? void 0 : _a.id) &&
3963
- this.group.model.isContentFocused;
3964
4096
  const isLeftClick = event.button === 0;
3965
4097
  if (!isLeftClick || event.defaultPrevented) {
3966
4098
  return;
3967
4099
  }
3968
- this.group.model.openPanel(panel, {
3969
- skipFocus: alreadyFocused,
3970
- });
4100
+ if (this.group.activePanel !== panel) {
4101
+ this.group.model.openPanel(panel);
4102
+ }
3971
4103
  }), tab.onDrop((event) => {
3972
4104
  this._onDrop.fire({
3973
4105
  event: event.nativeEvent,
3974
4106
  index: this.tabs.findIndex((x) => x.value === tab),
3975
4107
  });
4108
+ }), tab.onWillShowOverlay((event) => {
4109
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, { kind: 'tab' }));
3976
4110
  }));
3977
4111
  const value = { value: tab, disposable };
3978
4112
  this.addTab(value, index);
@@ -3990,6 +4124,60 @@ class TabsContainer extends CompositeDisposable {
3990
4124
  }
3991
4125
  }
3992
4126
 
4127
+ class DockviewDidDropEvent extends DockviewEvent {
4128
+ get nativeEvent() {
4129
+ return this.options.nativeEvent;
4130
+ }
4131
+ get position() {
4132
+ return this.options.position;
4133
+ }
4134
+ get panel() {
4135
+ return this.options.panel;
4136
+ }
4137
+ get group() {
4138
+ return this.options.group;
4139
+ }
4140
+ get api() {
4141
+ return this.options.api;
4142
+ }
4143
+ constructor(options) {
4144
+ super();
4145
+ this.options = options;
4146
+ }
4147
+ getData() {
4148
+ return this.options.getData();
4149
+ }
4150
+ }
4151
+ class DockviewWillDropEvent extends DockviewDidDropEvent {
4152
+ get kind() {
4153
+ return this._kind;
4154
+ }
4155
+ constructor(options) {
4156
+ super(options);
4157
+ this._kind = options.kind;
4158
+ }
4159
+ }
4160
+ class WillShowOverlayLocationEvent {
4161
+ get kind() {
4162
+ return this._kind;
4163
+ }
4164
+ get nativeEvent() {
4165
+ return this.event.nativeEvent;
4166
+ }
4167
+ get position() {
4168
+ return this.event.position;
4169
+ }
4170
+ get defaultPrevented() {
4171
+ return this.event.defaultPrevented;
4172
+ }
4173
+ preventDefault() {
4174
+ this.event.preventDefault();
4175
+ }
4176
+ constructor(event, options) {
4177
+ this.event = event;
4178
+ this._kind = options.kind;
4179
+ }
4180
+ }
3993
4181
  class DockviewGroupPanelModel extends CompositeDisposable {
3994
4182
  get element() {
3995
4183
  throw new Error('not supported');
@@ -4035,7 +4223,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4035
4223
  this._location = value;
4036
4224
  toggleClass(this.container, 'dv-groupview-floating', false);
4037
4225
  toggleClass(this.container, 'dv-groupview-popout', false);
4038
- switch (value) {
4226
+ switch (value.type) {
4039
4227
  case 'grid':
4040
4228
  this.contentContainer.dropTarget.setTargetZones([
4041
4229
  'top',
@@ -4071,7 +4259,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4071
4259
  this.groupPanel = groupPanel;
4072
4260
  this._isGroupActive = false;
4073
4261
  this._locked = false;
4074
- this._location = 'grid';
4262
+ this._location = { type: 'grid' };
4075
4263
  this.mostRecentlyUsed = [];
4076
4264
  this._onDidChange = new Emitter();
4077
4265
  this.onDidChange = this._onDidChange.event;
@@ -4082,6 +4270,10 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4082
4270
  this.onMove = this._onMove.event;
4083
4271
  this._onDidDrop = new Emitter();
4084
4272
  this.onDidDrop = this._onDidDrop.event;
4273
+ this._onWillDrop = new Emitter();
4274
+ this.onWillDrop = this._onWillDrop.event;
4275
+ this._onWillShowOverlay = new Emitter();
4276
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
4085
4277
  this._onTabDragStart = new Emitter();
4086
4278
  this.onTabDragStart = this._onTabDragStart.event;
4087
4279
  this._onGroupDragStart = new Emitter();
@@ -4092,46 +4284,69 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4092
4284
  this.onDidRemovePanel = this._onDidRemovePanel.event;
4093
4285
  this._onDidActivePanelChange = new Emitter();
4094
4286
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
4287
+ this._overwriteRenderContainer = null;
4095
4288
  toggleClass(this.container, 'groupview', true);
4289
+ this._api = new DockviewApi(this.accessor);
4096
4290
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
4097
4291
  this.contentContainer = new ContentContainer(this.accessor, this);
4098
4292
  container.append(this.tabsContainer.element, this.contentContainer.element);
4099
4293
  this.header.hidden = !!options.hideHeader;
4100
4294
  this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
4101
- this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this.tabsContainer.onTabDragStart((event) => {
4295
+ this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this._onWillShowOverlay, this.tabsContainer.onTabDragStart((event) => {
4102
4296
  this._onTabDragStart.fire(event);
4103
4297
  }), this.tabsContainer.onGroupDragStart((event) => {
4104
4298
  this._onGroupDragStart.fire(event);
4105
4299
  }), this.tabsContainer.onDrop((event) => {
4106
- this.handleDropEvent(event.event, 'center', event.index);
4300
+ this.handleDropEvent('header', event.event, 'center', event.index);
4107
4301
  }), this.contentContainer.onDidFocus(() => {
4108
- this.accessor.doSetGroupActive(this.groupPanel, true);
4302
+ this.accessor.doSetGroupActive(this.groupPanel);
4109
4303
  }), this.contentContainer.onDidBlur(() => {
4110
4304
  // noop
4111
4305
  }), 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);
4306
+ this.handleDropEvent('content', event.nativeEvent, event.position);
4307
+ }), this.tabsContainer.onWillShowOverlay((event) => {
4308
+ this._onWillShowOverlay.fire(event);
4309
+ }), this.contentContainer.dropTarget.onWillShowOverlay((event) => {
4310
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
4311
+ kind: 'content',
4312
+ }));
4313
+ }), this._onMove, this._onDidChange, this._onDidDrop, this._onWillDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange);
4314
+ }
4315
+ focusContent() {
4316
+ this.contentContainer.element.focus();
4317
+ }
4318
+ set renderContainer(value) {
4319
+ this.panels.forEach((panel) => {
4320
+ this.renderContainer.detatch(panel);
4321
+ });
4322
+ this._overwriteRenderContainer = value;
4323
+ this.panels.forEach((panel) => {
4324
+ this.rerender(panel);
4325
+ });
4326
+ }
4327
+ get renderContainer() {
4328
+ var _a;
4329
+ return ((_a = this._overwriteRenderContainer) !== null && _a !== void 0 ? _a : this.accessor.overlayRenderContainer);
4114
4330
  }
4115
4331
  initialize() {
4116
- var _a, _b;
4117
- if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.panels) {
4332
+ if (this.options.panels) {
4118
4333
  this.options.panels.forEach((panel) => {
4119
4334
  this.doAddPanel(panel);
4120
4335
  });
4121
4336
  }
4122
- if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.activePanel) {
4337
+ if (this.options.activePanel) {
4123
4338
  this.openPanel(this.options.activePanel);
4124
4339
  }
4125
4340
  // must be run after the constructor otherwise this.parent may not be
4126
4341
  // correctly initialized
4127
- this.setActive(this.isActive, true, true);
4342
+ this.setActive(this.isActive, true);
4128
4343
  this.updateContainer();
4129
4344
  if (this.accessor.options.createRightHeaderActionsElement) {
4130
4345
  this._rightHeaderActions =
4131
4346
  this.accessor.options.createRightHeaderActionsElement(this.groupPanel);
4132
4347
  this.addDisposables(this._rightHeaderActions);
4133
4348
  this._rightHeaderActions.init({
4134
- containerApi: new DockviewApi(this.accessor),
4349
+ containerApi: this._api,
4135
4350
  api: this.groupPanel.api,
4136
4351
  });
4137
4352
  this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element);
@@ -4141,7 +4356,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4141
4356
  this.accessor.options.createLeftHeaderActionsElement(this.groupPanel);
4142
4357
  this.addDisposables(this._leftHeaderActions);
4143
4358
  this._leftHeaderActions.init({
4144
- containerApi: new DockviewApi(this.accessor),
4359
+ containerApi: this._api,
4145
4360
  api: this.groupPanel.api,
4146
4361
  });
4147
4362
  this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
@@ -4151,7 +4366,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4151
4366
  this.accessor.options.createPrefixHeaderActionsElement(this.groupPanel);
4152
4367
  this.addDisposables(this._prefixHeaderActions);
4153
4368
  this._prefixHeaderActions.init({
4154
- containerApi: new DockviewApi(this.accessor),
4369
+ containerApi: this._api,
4155
4370
  api: this.groupPanel.api,
4156
4371
  });
4157
4372
  this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
@@ -4231,35 +4446,45 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4231
4446
  //noop
4232
4447
  }
4233
4448
  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);
4449
+ var _a;
4450
+ (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.focus();
4236
4451
  }
4237
4452
  openPanel(panel, options = {}) {
4453
+ /**
4454
+ * set the panel group
4455
+ * add the panel
4456
+ * check if group active
4457
+ * check if panel active
4458
+ */
4238
4459
  if (typeof options.index !== 'number' ||
4239
4460
  options.index > this.panels.length) {
4240
4461
  options.index = this.panels.length;
4241
4462
  }
4242
- const skipSetPanelActive = !!options.skipSetPanelActive;
4243
- const skipSetGroupActive = !!options.skipSetGroupActive;
4463
+ const skipSetActive = !!options.skipSetActive;
4244
4464
  // ensure the group is updated before we fire any events
4245
- panel.updateParentGroup(this.groupPanel, true);
4465
+ panel.updateParentGroup(this.groupPanel, {
4466
+ skipSetActive: options.skipSetActive,
4467
+ });
4468
+ this.doAddPanel(panel, options.index, {
4469
+ skipSetActive: skipSetActive,
4470
+ });
4246
4471
  if (this._activePanel === panel) {
4247
- if (!skipSetGroupActive) {
4248
- this.accessor.doSetGroupActive(this.groupPanel);
4249
- }
4250
4472
  this.contentContainer.renderPanel(panel, { asActive: true });
4251
4473
  return;
4252
4474
  }
4253
- this.doAddPanel(panel, options.index, skipSetPanelActive);
4254
- if (!skipSetPanelActive) {
4475
+ if (!skipSetActive) {
4255
4476
  this.doSetActivePanel(panel);
4256
4477
  }
4257
- if (!skipSetGroupActive) {
4258
- this.accessor.doSetGroupActive(this.groupPanel, !!options.skipFocus);
4478
+ if (!options.skipSetGroupActive) {
4479
+ this.accessor.doSetGroupActive(this.groupPanel);
4480
+ }
4481
+ if (!options.skipSetActive) {
4482
+ this.updateContainer();
4259
4483
  }
4260
- this.updateContainer();
4261
4484
  }
4262
- removePanel(groupItemOrId) {
4485
+ removePanel(groupItemOrId, options = {
4486
+ skipSetActive: false,
4487
+ }) {
4263
4488
  const id = typeof groupItemOrId === 'string'
4264
4489
  ? groupItemOrId
4265
4490
  : groupItemOrId.id;
@@ -4267,7 +4492,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4267
4492
  if (!panelToRemove) {
4268
4493
  throw new Error('invalid operation');
4269
4494
  }
4270
- return this._removePanel(panelToRemove);
4495
+ return this._removePanel(panelToRemove, options);
4271
4496
  }
4272
4497
  closeAllPanels() {
4273
4498
  if (this.panels.length > 0) {
@@ -4293,12 +4518,8 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4293
4518
  updateActions(element) {
4294
4519
  this.tabsContainer.setRightActionsElement(element);
4295
4520
  }
4296
- setActive(isGroupActive, skipFocus = false, force = false) {
4297
- var _a, _b, _c, _d;
4521
+ setActive(isGroupActive, force = false) {
4298
4522
  if (!force && this.isActive === isGroupActive) {
4299
- if (!skipFocus) {
4300
- (_b = (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a);
4301
- }
4302
4523
  return;
4303
4524
  }
4304
4525
  this._isGroupActive = isGroupActive;
@@ -4309,11 +4530,6 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4309
4530
  this.doSetActivePanel(this.panels[0]);
4310
4531
  }
4311
4532
  this.updateContainer();
4312
- if (isGroupActive) {
4313
- if (!skipFocus) {
4314
- (_d = (_c = this._activePanel) === null || _c === void 0 ? void 0 : _c.focus) === null || _d === void 0 ? void 0 : _d.call(_c);
4315
- }
4316
- }
4317
4533
  }
4318
4534
  layout(width, height) {
4319
4535
  var _a;
@@ -4324,17 +4540,22 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4324
4540
  this._activePanel.layout(this._width, this._height);
4325
4541
  }
4326
4542
  }
4327
- _removePanel(panel) {
4543
+ _removePanel(panel, options) {
4328
4544
  const isActivePanel = this._activePanel === panel;
4329
4545
  this.doRemovePanel(panel);
4330
4546
  if (isActivePanel && this.panels.length > 0) {
4331
4547
  const nextPanel = this.mostRecentlyUsed[0];
4332
- this.openPanel(nextPanel);
4548
+ this.openPanel(nextPanel, {
4549
+ skipSetActive: options.skipSetActive,
4550
+ skipSetGroupActive: options.skipSetActiveGroup,
4551
+ });
4333
4552
  }
4334
4553
  if (this._activePanel && this.panels.length === 0) {
4335
4554
  this.doSetActivePanel(undefined);
4336
4555
  }
4337
- this.updateContainer();
4556
+ if (!options.skipSetActive) {
4557
+ this.updateContainer();
4558
+ }
4338
4559
  return panel;
4339
4560
  }
4340
4561
  doRemovePanel(panel) {
@@ -4349,13 +4570,13 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4349
4570
  }
4350
4571
  this._onDidRemovePanel.fire({ panel });
4351
4572
  }
4352
- doAddPanel(panel, index = this.panels.length, skipSetActive = false) {
4573
+ doAddPanel(panel, index = this.panels.length, options = { skipSetActive: false }) {
4353
4574
  const existingPanel = this._panels.indexOf(panel);
4354
4575
  const hasExistingPanel = existingPanel > -1;
4355
4576
  this.tabsContainer.show();
4356
4577
  this.contentContainer.show();
4357
4578
  this.tabsContainer.openPanel(panel, index);
4358
- if (!skipSetActive) {
4579
+ if (!options.skipSetActive) {
4359
4580
  this.contentContainer.openPanel(panel);
4360
4581
  }
4361
4582
  if (hasExistingPanel) {
@@ -4367,12 +4588,17 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4367
4588
  this._onDidAddPanel.fire({ panel });
4368
4589
  }
4369
4590
  doSetActivePanel(panel) {
4591
+ if (this._activePanel === panel) {
4592
+ return;
4593
+ }
4370
4594
  this._activePanel = panel;
4371
4595
  if (panel) {
4372
4596
  this.tabsContainer.setActivePanel(panel);
4373
4597
  panel.layout(this._width, this._height);
4374
4598
  this.updateMru(panel);
4375
- this._onDidActivePanelChange.fire({ panel });
4599
+ this._onDidActivePanelChange.fire({
4600
+ panel,
4601
+ });
4376
4602
  }
4377
4603
  }
4378
4604
  updateMru(panel) {
@@ -4384,11 +4610,11 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4384
4610
  updateContainer() {
4385
4611
  var _a, _b;
4386
4612
  toggleClass(this.container, 'empty', this.isEmpty);
4387
- this.panels.forEach((panel) => panel.updateParentGroup(this.groupPanel, this.isActive));
4613
+ this.panels.forEach((panel) => panel.runEvents());
4388
4614
  if (this.isEmpty && !this.watermark) {
4389
4615
  const watermark = this.accessor.createWatermarkComponent();
4390
4616
  watermark.init({
4391
- containerApi: new DockviewApi(this.accessor),
4617
+ containerApi: this._api,
4392
4618
  group: this.groupPanel,
4393
4619
  });
4394
4620
  this.watermark = watermark;
@@ -4421,10 +4647,32 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4421
4647
  }
4422
4648
  return false;
4423
4649
  }
4424
- handleDropEvent(event, position, index) {
4650
+ handleDropEvent(type, event, position, index) {
4425
4651
  if (this.locked === 'no-drop-target') {
4426
4652
  return;
4427
4653
  }
4654
+ function getKind() {
4655
+ switch (type) {
4656
+ case 'header':
4657
+ return typeof index === 'number' ? 'tab' : 'header_space';
4658
+ case 'content':
4659
+ return 'content';
4660
+ }
4661
+ }
4662
+ const panel = typeof index === 'number' ? this.panels[index] : undefined;
4663
+ const willDropEvent = new DockviewWillDropEvent({
4664
+ nativeEvent: event,
4665
+ position,
4666
+ panel,
4667
+ getData: () => getPanelData(),
4668
+ kind: getKind(),
4669
+ group: this.groupPanel,
4670
+ api: this._api,
4671
+ });
4672
+ this._onWillDrop.fire(willDropEvent);
4673
+ if (willDropEvent.defaultPrevented) {
4674
+ return;
4675
+ }
4428
4676
  const data = getPanelData();
4429
4677
  if (data && data.viewId === this.accessor.id) {
4430
4678
  if (data.panelId === null) {
@@ -4457,12 +4705,14 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4457
4705
  });
4458
4706
  }
4459
4707
  else {
4460
- this._onDidDrop.fire({
4708
+ this._onDidDrop.fire(new DockviewDidDropEvent({
4461
4709
  nativeEvent: event,
4462
4710
  position,
4463
- index,
4711
+ panel,
4464
4712
  getData: () => getPanelData(),
4465
- });
4713
+ group: this.groupPanel,
4714
+ api: this._api,
4715
+ }));
4466
4716
  }
4467
4717
  }
4468
4718
  dispose() {
@@ -4470,6 +4720,7 @@ class DockviewGroupPanelModel extends CompositeDisposable {
4470
4720
  super.dispose();
4471
4721
  (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
4472
4722
  (_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
4723
+ this.watermark = undefined;
4473
4724
  for (const panel of this.panels) {
4474
4725
  panel.dispose();
4475
4726
  }
@@ -4491,15 +4742,7 @@ class Resizable extends CompositeDisposable {
4491
4742
  constructor(parentElement, disableResizing = false) {
4492
4743
  super();
4493
4744
  this._disableResizing = disableResizing;
4494
- if (parentElement) {
4495
- this._element = parentElement;
4496
- }
4497
- else {
4498
- this._element = document.createElement('div');
4499
- this._element.style.height = '100%';
4500
- this._element.style.width = '100%';
4501
- this._element.className = 'dv-resizable-container';
4502
- }
4745
+ this._element = parentElement;
4503
4746
  this.addDisposables(watchElementResize(this._element, (entry) => {
4504
4747
  if (this.isDisposed) {
4505
4748
  /**
@@ -4587,25 +4830,38 @@ class BaseGrid extends Resizable {
4587
4830
  get activeGroup() {
4588
4831
  return this._activeGroup;
4589
4832
  }
4833
+ get locked() {
4834
+ return this.gridview.locked;
4835
+ }
4836
+ set locked(value) {
4837
+ this.gridview.locked = value;
4838
+ }
4590
4839
  constructor(options) {
4591
- super(options.parentElement, options.disableAutoResizing);
4840
+ super(document.createElement('div'), options.disableAutoResizing);
4592
4841
  this._id = nextLayoutId$1.next();
4593
4842
  this._groups = new Map();
4594
4843
  this._onDidLayoutChange = new Emitter();
4595
4844
  this.onDidLayoutChange = this._onDidLayoutChange.event;
4596
- this._onDidRemoveGroup = new Emitter();
4597
- this.onDidRemoveGroup = this._onDidRemoveGroup.event;
4598
- this._onDidAddGroup = new Emitter();
4599
- this.onDidAddGroup = this._onDidAddGroup.event;
4600
- this._onDidActiveGroupChange = new Emitter();
4601
- this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
4845
+ this._onDidRemove = new Emitter();
4846
+ this.onDidRemove = this._onDidRemove.event;
4847
+ this._onDidAdd = new Emitter();
4848
+ this.onDidAdd = this._onDidAdd.event;
4849
+ this._onDidActiveChange = new Emitter();
4850
+ this.onDidActiveChange = this._onDidActiveChange.event;
4602
4851
  this._bufferOnDidLayoutChange = new TickDelayedEvent();
4852
+ this.element.style.height = '100%';
4853
+ this.element.style.width = '100%';
4854
+ options.parentElement.appendChild(this.element);
4603
4855
  this.gridview = new Gridview(!!options.proportionalLayout, options.styles, options.orientation);
4856
+ this.gridview.locked = !!options.locked;
4604
4857
  this.element.appendChild(this.gridview.element);
4605
4858
  this.layout(0, 0, true); // set some elements height/widths
4606
- this.addDisposables(this.gridview.onDidChange(() => {
4859
+ this.addDisposables(Disposable.from(() => {
4860
+ var _a;
4861
+ (_a = this.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.element);
4862
+ }), this.gridview.onDidChange(() => {
4607
4863
  this._bufferOnDidLayoutChange.fire();
4608
- }), Event.any(this.onDidAddGroup, this.onDidRemoveGroup, this.onDidActiveGroupChange)(() => {
4864
+ }), Event.any(this.onDidAdd, this.onDidRemove, this.onDidActiveChange)(() => {
4609
4865
  this._bufferOnDidLayoutChange.fire();
4610
4866
  }), this._bufferOnDidLayoutChange.onEvent(() => {
4611
4867
  this._onDidLayoutChange.fire();
@@ -4620,6 +4876,7 @@ class BaseGrid extends Resizable {
4620
4876
  }
4621
4877
  maximizeGroup(panel) {
4622
4878
  this.gridview.maximizeView(panel);
4879
+ this.doSetGroupActive(panel);
4623
4880
  }
4624
4881
  isMaximizedGroup(panel) {
4625
4882
  return this.gridview.maximizedView() === panel;
@@ -4630,13 +4887,12 @@ class BaseGrid extends Resizable {
4630
4887
  hasMaximizedGroup() {
4631
4888
  return this.gridview.hasMaximizedView();
4632
4889
  }
4633
- get onDidMaxmizedGroupChange() {
4634
- return this.gridview.onDidMaxmizedNodeChange;
4890
+ get onDidMaximizedGroupChange() {
4891
+ return this.gridview.onDidMaximizedNodeChange;
4635
4892
  }
4636
4893
  doAddGroup(group, location = [0], size) {
4637
4894
  this.gridview.addView(group, size !== null && size !== void 0 ? size : Sizing.Distribute, location);
4638
- this._onDidAddGroup.fire(group);
4639
- this.doSetGroupActive(group);
4895
+ this._onDidAdd.fire(group);
4640
4896
  }
4641
4897
  doRemoveGroup(group, options) {
4642
4898
  if (!this._groups.has(group.id)) {
@@ -4648,8 +4904,8 @@ class BaseGrid extends Resizable {
4648
4904
  item.disposable.dispose();
4649
4905
  item.value.dispose();
4650
4906
  this._groups.delete(group.id);
4907
+ this._onDidRemove.fire(group);
4651
4908
  }
4652
- this._onDidRemoveGroup.fire(group);
4653
4909
  if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
4654
4910
  const groups = Array.from(this._groups.values());
4655
4911
  this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
@@ -4660,25 +4916,18 @@ class BaseGrid extends Resizable {
4660
4916
  var _a;
4661
4917
  return (_a = this._groups.get(id)) === null || _a === void 0 ? void 0 : _a.value;
4662
4918
  }
4663
- doSetGroupActive(group, skipFocus) {
4664
- var _a, _b, _c;
4919
+ doSetGroupActive(group) {
4665
4920
  if (this._activeGroup === group) {
4666
4921
  return;
4667
4922
  }
4668
4923
  if (this._activeGroup) {
4669
4924
  this._activeGroup.setActive(false);
4670
- if (!skipFocus) {
4671
- (_b = (_a = this._activeGroup).focus) === null || _b === void 0 ? void 0 : _b.call(_a);
4672
- }
4673
4925
  }
4674
4926
  if (group) {
4675
4927
  group.setActive(true);
4676
- if (!skipFocus) {
4677
- (_c = group.focus) === null || _c === void 0 ? void 0 : _c.call(group);
4678
- }
4679
4928
  }
4680
4929
  this._activeGroup = group;
4681
- this._onDidActiveGroupChange.fire(group);
4930
+ this._onDidActiveChange.fire(group);
4682
4931
  }
4683
4932
  removeGroup(group) {
4684
4933
  this.doRemoveGroup(group);
@@ -4723,9 +4972,9 @@ class BaseGrid extends Resizable {
4723
4972
  this.gridview.layout(width, height);
4724
4973
  }
4725
4974
  dispose() {
4726
- this._onDidActiveGroupChange.dispose();
4727
- this._onDidAddGroup.dispose();
4728
- this._onDidRemoveGroup.dispose();
4975
+ this._onDidActiveChange.dispose();
4976
+ this._onDidAdd.dispose();
4977
+ this._onDidRemove.dispose();
4729
4978
  this._onDidLayoutChange.dispose();
4730
4979
  for (const group of this.groups) {
4731
4980
  group.dispose();
@@ -4735,11 +4984,15 @@ class BaseGrid extends Resizable {
4735
4984
  }
4736
4985
  }
4737
4986
 
4987
+ class WillFocusEvent extends DockviewEvent {
4988
+ constructor() {
4989
+ super();
4990
+ }
4991
+ }
4738
4992
  /**
4739
4993
  * A core api implementation that should be used across all panel-like objects
4740
4994
  */
4741
4995
  class PanelApiImpl extends CompositeDisposable {
4742
- //
4743
4996
  get isFocused() {
4744
4997
  return this._isFocused;
4745
4998
  }
@@ -4764,35 +5017,22 @@ class PanelApiImpl extends CompositeDisposable {
4764
5017
  this._width = 0;
4765
5018
  this._height = 0;
4766
5019
  this.panelUpdatesDisposable = new MutableDisposable();
4767
- this._onDidDimensionChange = new Emitter({
4768
- replay: true,
4769
- });
5020
+ this._onDidDimensionChange = new Emitter();
4770
5021
  this.onDidDimensionsChange = this._onDidDimensionChange.event;
4771
- //
4772
- this._onDidChangeFocus = new Emitter({
4773
- replay: true,
4774
- });
5022
+ this._onDidChangeFocus = new Emitter();
4775
5023
  this.onDidFocusChange = this._onDidChangeFocus.event;
4776
5024
  //
4777
- this._onFocusEvent = new Emitter();
4778
- this.onFocusEvent = this._onFocusEvent.event;
5025
+ this._onWillFocus = new Emitter();
5026
+ this.onWillFocus = this._onWillFocus.event;
4779
5027
  //
4780
- this._onDidVisibilityChange = new Emitter({
4781
- replay: true,
4782
- });
5028
+ this._onDidVisibilityChange = new Emitter();
4783
5029
  this.onDidVisibilityChange = this._onDidVisibilityChange.event;
4784
- //
4785
- this._onVisibilityChange = new Emitter();
4786
- this.onVisibilityChange = this._onVisibilityChange.event;
4787
- //
4788
- this._onDidActiveChange = new Emitter({
4789
- replay: true,
4790
- });
5030
+ this._onWillVisibilityChange = new Emitter();
5031
+ this.onWillVisibilityChange = this._onWillVisibilityChange.event;
5032
+ this._onDidActiveChange = new Emitter();
4791
5033
  this.onDidActiveChange = this._onDidActiveChange.event;
4792
- //
4793
5034
  this._onActiveChange = new Emitter();
4794
5035
  this.onActiveChange = this._onActiveChange.event;
4795
- //
4796
5036
  this._onUpdateParameters = new Emitter();
4797
5037
  this.onUpdateParameters = this._onUpdateParameters.event;
4798
5038
  this.addDisposables(this.onDidFocusChange((event) => {
@@ -4804,7 +5044,7 @@ class PanelApiImpl extends CompositeDisposable {
4804
5044
  }), this.onDidDimensionsChange((event) => {
4805
5045
  this._width = event.width;
4806
5046
  this._height = event.height;
4807
- }), this.panelUpdatesDisposable, this._onDidDimensionChange, this._onDidChangeFocus, this._onDidVisibilityChange, this._onDidActiveChange, this._onFocusEvent, this._onActiveChange, this._onVisibilityChange, this._onUpdateParameters);
5047
+ }), this.panelUpdatesDisposable, this._onDidDimensionChange, this._onDidChangeFocus, this._onDidVisibilityChange, this._onDidActiveChange, this._onWillFocus, this._onActiveChange, this._onUpdateParameters, this._onWillFocus, this._onWillVisibilityChange, this._onUpdateParameters);
4808
5048
  }
4809
5049
  initialize(panel) {
4810
5050
  this.panelUpdatesDisposable.value = this._onUpdateParameters.event((parameters) => {
@@ -4814,7 +5054,7 @@ class PanelApiImpl extends CompositeDisposable {
4814
5054
  });
4815
5055
  }
4816
5056
  setVisible(isVisible) {
4817
- this._onVisibilityChange.fire({ isVisible });
5057
+ this._onWillVisibilityChange.fire({ isVisible });
4818
5058
  }
4819
5059
  setActive() {
4820
5060
  this._onActiveChange.fire();
@@ -4822,9 +5062,6 @@ class PanelApiImpl extends CompositeDisposable {
4822
5062
  updateParameters(parameters) {
4823
5063
  this._onUpdateParameters.fire(parameters);
4824
5064
  }
4825
- dispose() {
4826
- super.dispose();
4827
- }
4828
5065
  }
4829
5066
 
4830
5067
  class SplitviewPanelApiImpl extends PanelApiImpl {
@@ -4912,7 +5149,12 @@ class BasePanelView extends CompositeDisposable {
4912
5149
  }), focusTracker);
4913
5150
  }
4914
5151
  focus() {
4915
- this.api._onFocusEvent.fire();
5152
+ const event = new WillFocusEvent();
5153
+ this.api._onWillFocus.fire(event);
5154
+ if (event.defaultPrevented) {
5155
+ return;
5156
+ }
5157
+ this._element.focus();
4916
5158
  }
4917
5159
  layout(width, height) {
4918
5160
  this._width = width;
@@ -5030,7 +5272,11 @@ class PaneviewPanel extends BasePanelView {
5030
5272
  this._onDidChangeExpansionState.fire(this.isExpanded()); // initialize value
5031
5273
  this._orientation = orientation;
5032
5274
  this.element.classList.add('pane');
5033
- this.addDisposables(this.api.onDidSizeChange((event) => {
5275
+ this.addDisposables(this.api.onWillVisibilityChange((event) => {
5276
+ const { isVisible } = event;
5277
+ const { accessor } = this._params;
5278
+ accessor.setVisible(this, isVisible);
5279
+ }), this.api.onDidSizeChange((event) => {
5034
5280
  this._onDidChange.fire({ size: event.size });
5035
5281
  }), addDisposableListener(this.element, 'mouseenter', (ev) => {
5036
5282
  this.api._onMouseEnter.fire(ev);
@@ -5241,9 +5487,7 @@ class GridviewPanelApiImpl extends PanelApiImpl {
5241
5487
  super(id);
5242
5488
  this._onDidConstraintsChangeInternal = new Emitter();
5243
5489
  this.onDidConstraintsChangeInternal = this._onDidConstraintsChangeInternal.event;
5244
- this._onDidConstraintsChange = new Emitter({
5245
- replay: true,
5246
- });
5490
+ this._onDidConstraintsChange = new Emitter();
5247
5491
  this.onDidConstraintsChange = this._onDidConstraintsChange.event;
5248
5492
  this._onDidSizeChange = new Emitter();
5249
5493
  this.onDidSizeChange = this._onDidSizeChange.event;
@@ -5336,13 +5580,13 @@ class GridviewPanel extends BasePanelView {
5336
5580
  this._maximumHeight = options.maximumHeight;
5337
5581
  }
5338
5582
  this.api.initialize(this); // TODO: required to by-pass 'super before this' requirement
5339
- this.addDisposables(this.api.onVisibilityChange((event) => {
5583
+ this.addDisposables(this.api.onWillVisibilityChange((event) => {
5340
5584
  const { isVisible } = event;
5341
5585
  const { accessor } = this._params;
5342
5586
  accessor.setVisible(this, isVisible);
5343
5587
  }), this.api.onActiveChange(() => {
5344
5588
  const { accessor } = this._params;
5345
- accessor.setActive(this);
5589
+ accessor.doSetGroupActive(this);
5346
5590
  }), this.api.onDidConstraintsChangeInternal((event) => {
5347
5591
  if (typeof event.minimumWidth === 'number' ||
5348
5592
  typeof event.minimumWidth === 'function') {
@@ -5425,6 +5669,17 @@ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
5425
5669
  this.onDidLocationChange = this._onDidLocationChange.event;
5426
5670
  this.addDisposables(this._onDidLocationChange);
5427
5671
  }
5672
+ close() {
5673
+ if (!this._group) {
5674
+ return;
5675
+ }
5676
+ return this.accessor.removeGroup(this._group);
5677
+ }
5678
+ getWindow() {
5679
+ return this.location.type === 'popout'
5680
+ ? this.location.getWindow()
5681
+ : window;
5682
+ }
5428
5683
  moveTo(options) {
5429
5684
  var _a, _b, _c;
5430
5685
  if (!this._group) {
@@ -5432,14 +5687,23 @@ class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
5432
5687
  }
5433
5688
  const group = (_a = options.group) !== null && _a !== void 0 ? _a : this.accessor.addGroup({
5434
5689
  direction: positionToDirection((_b = options.position) !== null && _b !== void 0 ? _b : 'right'),
5690
+ skipSetActive: true,
5691
+ });
5692
+ this.accessor.moveGroupOrPanel({
5693
+ from: { groupId: this._group.id },
5694
+ to: {
5695
+ group,
5696
+ position: options.group
5697
+ ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center'
5698
+ : 'center',
5699
+ },
5435
5700
  });
5436
- this.accessor.moveGroupOrPanel(group, this._group.id, undefined, options.group ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center' : 'center');
5437
5701
  }
5438
5702
  maximize() {
5439
5703
  if (!this._group) {
5440
5704
  throw new Error(NOT_INITIALIZED_MESSAGE);
5441
5705
  }
5442
- if (this.location !== 'grid') {
5706
+ if (this.location.type !== 'grid') {
5443
5707
  // only grid groups can be maximized
5444
5708
  return;
5445
5709
  }
@@ -5496,6 +5760,12 @@ class DockviewGroupPanel extends GridviewPanel {
5496
5760
  this.api.initialize(this); // cannot use 'this' after after 'super' call
5497
5761
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
5498
5762
  }
5763
+ focus() {
5764
+ if (!this.api.isActive) {
5765
+ this.api.setActive();
5766
+ }
5767
+ super.focus();
5768
+ }
5499
5769
  initialize() {
5500
5770
  this._model.initialize();
5501
5771
  }
@@ -5541,6 +5811,9 @@ function isGroupOptionsWithGroup(data) {
5541
5811
  }
5542
5812
 
5543
5813
  class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5814
+ get location() {
5815
+ return this.group.api.location;
5816
+ }
5544
5817
  get title() {
5545
5818
  return this.panel.title;
5546
5819
  }
@@ -5551,16 +5824,14 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5551
5824
  return this.panel.renderer;
5552
5825
  }
5553
5826
  set group(value) {
5554
- const isOldGroupActive = this.isGroupActive;
5555
- this._group = value;
5556
- this._onDidGroupChange.fire();
5557
- if (this._group) {
5558
- this.disposable.value = this._group.api.onDidActiveChange(() => {
5559
- this._onDidActiveGroupChange.fire();
5827
+ const oldGroup = this._group;
5828
+ if (this._group !== value) {
5829
+ this._group = value;
5830
+ this._onDidGroupChange.fire({});
5831
+ this.setupGroupEventListeners(oldGroup);
5832
+ this._onDidLocationChange.fire({
5833
+ location: this.group.api.location,
5560
5834
  });
5561
- if (this.isGroupActive !== isOldGroupActive) {
5562
- this._onDidActiveGroupChange.fire();
5563
- }
5564
5835
  }
5565
5836
  }
5566
5837
  get group() {
@@ -5578,14 +5849,27 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5578
5849
  this.onDidGroupChange = this._onDidGroupChange.event;
5579
5850
  this._onDidRendererChange = new Emitter();
5580
5851
  this.onDidRendererChange = this._onDidRendererChange.event;
5581
- this.disposable = new MutableDisposable();
5852
+ this._onDidLocationChange = new Emitter();
5853
+ this.onDidLocationChange = this._onDidLocationChange.event;
5854
+ this.groupEventsDisposable = new MutableDisposable();
5582
5855
  this.initialize(panel);
5583
5856
  this._group = group;
5584
- this.addDisposables(this.disposable, this._onDidRendererChange, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5857
+ this.setupGroupEventListeners();
5858
+ this.addDisposables(this.groupEventsDisposable, this._onDidRendererChange, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange, this._onDidLocationChange);
5859
+ }
5860
+ getWindow() {
5861
+ return this.group.api.getWindow();
5585
5862
  }
5586
5863
  moveTo(options) {
5587
5864
  var _a;
5588
- this.accessor.moveGroupOrPanel(options.group, this._group.id, this.panel.id, (_a = options.position) !== null && _a !== void 0 ? _a : 'center', options.index);
5865
+ this.accessor.moveGroupOrPanel({
5866
+ from: { groupId: this._group.id, panelId: this.panel.id },
5867
+ to: {
5868
+ group: options.group,
5869
+ position: (_a = options.position) !== null && _a !== void 0 ? _a : 'center',
5870
+ index: options.index,
5871
+ },
5872
+ });
5589
5873
  }
5590
5874
  setTitle(title) {
5591
5875
  this.panel.setTitle(title);
@@ -5605,6 +5889,35 @@ class DockviewPanelApiImpl extends GridviewPanelApiImpl {
5605
5889
  exitMaximized() {
5606
5890
  this.group.api.exitMaximized();
5607
5891
  }
5892
+ setupGroupEventListeners(previousGroup) {
5893
+ var _a;
5894
+ let _trackGroupActive = (_a = previousGroup === null || previousGroup === void 0 ? void 0 : previousGroup.isActive) !== null && _a !== void 0 ? _a : false; // prevent duplicate events with same state
5895
+ this.groupEventsDisposable.value = new CompositeDisposable(this.group.api.onDidVisibilityChange((event) => {
5896
+ if (!event.isVisible && this.isVisible) {
5897
+ this._onDidVisibilityChange.fire(event);
5898
+ }
5899
+ else if (event.isVisible &&
5900
+ !this.isVisible &&
5901
+ this.group.model.isPanelActive(this.panel)) {
5902
+ this._onDidVisibilityChange.fire(event);
5903
+ }
5904
+ }), this.group.api.onDidLocationChange((event) => {
5905
+ if (this.group !== this.panel.group) {
5906
+ return;
5907
+ }
5908
+ this._onDidLocationChange.fire(event);
5909
+ }), this.group.api.onDidActiveChange(() => {
5910
+ if (this.group !== this.panel.group) {
5911
+ return;
5912
+ }
5913
+ if (_trackGroupActive !== this.isGroupActive) {
5914
+ _trackGroupActive = this.isGroupActive;
5915
+ this._onDidActiveGroupChange.fire({
5916
+ isActive: this.isGroupActive,
5917
+ });
5918
+ }
5919
+ }));
5920
+ }
5608
5921
  }
5609
5922
 
5610
5923
  class DockviewPanel extends CompositeDisposable {
@@ -5646,7 +5959,14 @@ class DockviewPanel extends CompositeDisposable {
5646
5959
  this.setTitle(params.title);
5647
5960
  }
5648
5961
  focus() {
5649
- this.api._onFocusEvent.fire();
5962
+ const event = new WillFocusEvent();
5963
+ this.api._onWillFocus.fire(event);
5964
+ if (event.defaultPrevented) {
5965
+ return;
5966
+ }
5967
+ if (!this.api.isActive) {
5968
+ this.api.setActive();
5969
+ }
5650
5970
  }
5651
5971
  toJSON() {
5652
5972
  return {
@@ -5703,24 +6023,44 @@ class DockviewPanel extends CompositeDisposable {
5703
6023
  },
5704
6024
  });
5705
6025
  }
5706
- updateParentGroup(group, isGroupActive) {
6026
+ updateParentGroup(group, options) {
5707
6027
  this._group = group;
5708
- this.api.group = group;
6028
+ this.api.group = this._group;
5709
6029
  const isPanelVisible = this._group.model.isPanelActive(this);
5710
- this.api._onDidActiveChange.fire({
5711
- isActive: isGroupActive && isPanelVisible,
5712
- });
5713
- this.api._onDidVisibilityChange.fire({
5714
- isVisible: isPanelVisible,
5715
- });
5716
- this.view.updateParentGroup(this._group, this._group.model.isPanelActive(this));
6030
+ const isActive = this.group.api.isActive && isPanelVisible;
6031
+ if (!(options === null || options === void 0 ? void 0 : options.skipSetActive)) {
6032
+ if (this.api.isActive !== isActive) {
6033
+ this.api._onDidActiveChange.fire({
6034
+ isActive: this.group.api.isActive && isPanelVisible,
6035
+ });
6036
+ }
6037
+ }
6038
+ if (this.api.isVisible !== isPanelVisible) {
6039
+ this.api._onDidVisibilityChange.fire({
6040
+ isVisible: isPanelVisible,
6041
+ });
6042
+ }
5717
6043
  }
5718
- layout(width, height) {
5719
- // the obtain the correct dimensions of the content panel we must deduct the tab height
5720
- this.api._onDidDimensionChange.fire({
5721
- width,
5722
- height: height,
5723
- });
6044
+ runEvents() {
6045
+ const isPanelVisible = this._group.model.isPanelActive(this);
6046
+ const isActive = this.group.api.isActive && isPanelVisible;
6047
+ if (this.api.isActive !== isActive) {
6048
+ this.api._onDidActiveChange.fire({
6049
+ isActive: this.group.api.isActive && isPanelVisible,
6050
+ });
6051
+ }
6052
+ if (this.api.isVisible !== isPanelVisible) {
6053
+ this.api._onDidVisibilityChange.fire({
6054
+ isVisible: isPanelVisible,
6055
+ });
6056
+ }
6057
+ }
6058
+ layout(width, height) {
6059
+ // TODO: Can we somehow do height without header height or indicate what the header height is?
6060
+ this.api._onDidDimensionChange.fire({
6061
+ width,
6062
+ height: height,
6063
+ });
5724
6064
  this.view.layout(width, height);
5725
6065
  }
5726
6066
  dispose() {
@@ -5838,8 +6178,6 @@ class DockviewPanelModel {
5838
6178
  this.id = id;
5839
6179
  this.contentComponent = contentComponent;
5840
6180
  this.tabComponent = tabComponent;
5841
- this._group = null;
5842
- this._isPanelVisible = null;
5843
6181
  this._content = this.createContentComponent(this.id, contentComponent);
5844
6182
  this._tab = this.createTabComponent(this.id, tabComponent);
5845
6183
  }
@@ -5847,25 +6185,8 @@ class DockviewPanelModel {
5847
6185
  this.content.init(Object.assign(Object.assign({}, params), { tab: this.tab }));
5848
6186
  this.tab.init(params);
5849
6187
  }
5850
- updateParentGroup(group, isPanelVisible) {
5851
- if (group !== this._group) {
5852
- this._group = group;
5853
- if (this._content.onGroupChange) {
5854
- this._content.onGroupChange(group);
5855
- }
5856
- if (this._tab.onGroupChange) {
5857
- this._tab.onGroupChange(group);
5858
- }
5859
- }
5860
- if (isPanelVisible !== this._isPanelVisible) {
5861
- this._isPanelVisible = isPanelVisible;
5862
- if (this._content.onPanelVisibleChange) {
5863
- this._content.onPanelVisibleChange(isPanelVisible);
5864
- }
5865
- if (this._tab.onPanelVisibleChange) {
5866
- this._tab.onPanelVisibleChange(isPanelVisible);
5867
- }
5868
- }
6188
+ updateParentGroup(_group, _isPanelVisible) {
6189
+ // noop
5869
6190
  }
5870
6191
  layout(width, height) {
5871
6192
  var _a, _b;
@@ -6298,117 +6619,6 @@ class DockviewFloatingGroupPanel extends CompositeDisposable {
6298
6619
  }
6299
6620
  }
6300
6621
 
6301
- class PopoutWindow extends CompositeDisposable {
6302
- constructor(id, className, options) {
6303
- super();
6304
- this.id = id;
6305
- this.className = className;
6306
- this.options = options;
6307
- this._onDidClose = new Emitter();
6308
- this.onDidClose = this._onDidClose.event;
6309
- this._window = null;
6310
- this.addDisposables(this._onDidClose, {
6311
- dispose: () => {
6312
- this.close();
6313
- },
6314
- });
6315
- }
6316
- dimensions() {
6317
- if (!this._window) {
6318
- return null;
6319
- }
6320
- const left = this._window.value.screenX;
6321
- const top = this._window.value.screenY;
6322
- const width = this._window.value.innerWidth;
6323
- const height = this._window.value.innerHeight;
6324
- return { top, left, width, height };
6325
- }
6326
- close() {
6327
- if (this._window) {
6328
- this._window.disposable.dispose();
6329
- this._window.value.close();
6330
- this._window = null;
6331
- }
6332
- }
6333
- open(content) {
6334
- if (this._window) {
6335
- throw new Error('instance of popout window is already open');
6336
- }
6337
- const url = `${this.options.url}`;
6338
- const features = Object.entries({
6339
- top: this.options.top,
6340
- left: this.options.left,
6341
- width: this.options.width,
6342
- height: this.options.height,
6343
- })
6344
- .map(([key, value]) => `${key}=${value}`)
6345
- .join(',');
6346
- // https://developer.mozilla.org/en-US/docs/Web/API/Window/open
6347
- const externalWindow = window.open(url, this.id, features);
6348
- if (!externalWindow) {
6349
- return;
6350
- }
6351
- const disposable = new CompositeDisposable();
6352
- this._window = { value: externalWindow, disposable };
6353
- const cleanUp = () => {
6354
- this._onDidClose.fire();
6355
- this._window = null;
6356
- };
6357
- // prevent any default content from loading
6358
- // externalWindow.document.body.replaceWith(document.createElement('div'));
6359
- disposable.addDisposables(addDisposableWindowListener(window, 'beforeunload', () => {
6360
- cleanUp();
6361
- this.close();
6362
- }));
6363
- externalWindow.addEventListener('load', () => {
6364
- const externalDocument = externalWindow.document;
6365
- externalDocument.title = document.title;
6366
- const div = document.createElement('div');
6367
- div.classList.add('dv-popout-window');
6368
- div.style.position = 'absolute';
6369
- div.style.width = '100%';
6370
- div.style.height = '100%';
6371
- div.style.top = '0px';
6372
- div.style.left = '0px';
6373
- div.classList.add(this.className);
6374
- div.appendChild(content);
6375
- externalDocument.body.replaceChildren(div);
6376
- externalDocument.body.classList.add(this.className);
6377
- addStyles(externalDocument, window.document.styleSheets);
6378
- externalWindow.addEventListener('beforeunload', () => {
6379
- // TODO: indicate external window is closing
6380
- cleanUp();
6381
- });
6382
- });
6383
- }
6384
- }
6385
-
6386
- class DockviewPopoutGroupPanel extends CompositeDisposable {
6387
- constructor(id, group, options) {
6388
- var _a;
6389
- super();
6390
- this.id = id;
6391
- this.group = group;
6392
- this.options = options;
6393
- this.window = new PopoutWindow(id, (_a = options.className) !== null && _a !== void 0 ? _a : '', {
6394
- url: this.options.popoutUrl,
6395
- left: this.options.box.left,
6396
- top: this.options.box.top,
6397
- width: this.options.box.width,
6398
- height: this.options.box.height,
6399
- });
6400
- group.model.location = 'popout';
6401
- this.addDisposables(this.window, {
6402
- dispose: () => {
6403
- group.model.location = 'grid';
6404
- },
6405
- }, this.window.onDidClose(() => {
6406
- this.dispose();
6407
- }));
6408
- this.window.open(group.element);
6409
- }
6410
- }
6411
-
6412
6622
  const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
6413
6623
  const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100 };
6414
6624
 
@@ -6422,11 +6632,13 @@ class OverlayRenderContainer extends CompositeDisposable {
6422
6632
  super();
6423
6633
  this.element = element;
6424
6634
  this.map = {};
6635
+ this._disposed = false;
6425
6636
  this.addDisposables(Disposable.from(() => {
6426
6637
  for (const value of Object.values(this.map)) {
6427
6638
  value.disposable.dispose();
6428
6639
  value.destroy.dispose();
6429
6640
  }
6641
+ this._disposed = true;
6430
6642
  }));
6431
6643
  }
6432
6644
  detatch(panel) {
@@ -6466,7 +6678,7 @@ class OverlayRenderContainer extends CompositeDisposable {
6466
6678
  focusContainer.style.top = `${box.top - box2.top}px`;
6467
6679
  focusContainer.style.width = `${box.width}px`;
6468
6680
  focusContainer.style.height = `${box.height}px`;
6469
- toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location === 'floating');
6681
+ toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location.type === 'floating');
6470
6682
  };
6471
6683
  const visibilityChanged = () => {
6472
6684
  if (panel.api.isVisible) {
@@ -6512,8 +6724,11 @@ class OverlayRenderContainer extends CompositeDisposable {
6512
6724
  resize();
6513
6725
  }));
6514
6726
  this.map[panel.api.id].destroy = Disposable.from(() => {
6515
- focusContainer.removeChild(panel.view.content.element);
6516
- this.element.removeChild(focusContainer);
6727
+ var _a;
6728
+ if (panel.view.content.element.parentElement === focusContainer) {
6729
+ focusContainer.removeChild(panel.view.content.element);
6730
+ }
6731
+ (_a = focusContainer.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(focusContainer);
6517
6732
  });
6518
6733
  queueMicrotask(() => {
6519
6734
  if (this.isDisposed) {
@@ -6534,11 +6749,164 @@ class OverlayRenderContainer extends CompositeDisposable {
6534
6749
  }
6535
6750
  }
6536
6751
 
6752
+ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
6753
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6754
+ return new (P || (P = Promise))(function (resolve, reject) {
6755
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6756
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6757
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
6758
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
6759
+ });
6760
+ };
6761
+ class PopoutWindow extends CompositeDisposable {
6762
+ get window() {
6763
+ var _a, _b;
6764
+ return (_b = (_a = this._window) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null;
6765
+ }
6766
+ constructor(target, className, options) {
6767
+ super();
6768
+ this.target = target;
6769
+ this.className = className;
6770
+ this.options = options;
6771
+ this._onWillClose = new Emitter();
6772
+ this.onWillClose = this._onWillClose.event;
6773
+ this._onDidClose = new Emitter();
6774
+ this.onDidClose = this._onDidClose.event;
6775
+ this._window = null;
6776
+ this.addDisposables(this._onWillClose, this._onDidClose, {
6777
+ dispose: () => {
6778
+ this.close();
6779
+ },
6780
+ });
6781
+ }
6782
+ dimensions() {
6783
+ if (!this._window) {
6784
+ return null;
6785
+ }
6786
+ const left = this._window.value.screenX;
6787
+ const top = this._window.value.screenY;
6788
+ const width = this._window.value.innerWidth;
6789
+ const height = this._window.value.innerHeight;
6790
+ return { top, left, width, height };
6791
+ }
6792
+ close() {
6793
+ var _a, _b;
6794
+ if (this._window) {
6795
+ this._onWillClose.fire();
6796
+ (_b = (_a = this.options).onWillClose) === null || _b === void 0 ? void 0 : _b.call(_a, {
6797
+ id: this.target,
6798
+ window: this._window.value,
6799
+ });
6800
+ this._window.disposable.dispose();
6801
+ this._window.value.close();
6802
+ this._window = null;
6803
+ this._onDidClose.fire();
6804
+ }
6805
+ }
6806
+ open() {
6807
+ var _a, _b;
6808
+ return __awaiter(this, void 0, void 0, function* () {
6809
+ if (this._window) {
6810
+ throw new Error('instance of popout window is already open');
6811
+ }
6812
+ const url = `${this.options.url}`;
6813
+ const features = Object.entries({
6814
+ top: this.options.top,
6815
+ left: this.options.left,
6816
+ width: this.options.width,
6817
+ height: this.options.height,
6818
+ })
6819
+ .map(([key, value]) => `${key}=${value}`)
6820
+ .join(',');
6821
+ /**
6822
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/open
6823
+ */
6824
+ const externalWindow = window.open(url, this.target, features);
6825
+ if (!externalWindow) {
6826
+ /**
6827
+ * Popup blocked
6828
+ */
6829
+ return null;
6830
+ }
6831
+ const disposable = new CompositeDisposable();
6832
+ this._window = { value: externalWindow, disposable };
6833
+ disposable.addDisposables(addDisposableWindowListener(window, 'beforeunload', () => {
6834
+ /**
6835
+ * before the main window closes we should close this popup too
6836
+ * to be good citizens
6837
+ *
6838
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
6839
+ */
6840
+ this.close();
6841
+ }));
6842
+ const container = this.createPopoutWindowContainer();
6843
+ if (this.className) {
6844
+ container.classList.add(this.className);
6845
+ }
6846
+ (_b = (_a = this.options).onDidOpen) === null || _b === void 0 ? void 0 : _b.call(_a, {
6847
+ id: this.target,
6848
+ window: externalWindow,
6849
+ });
6850
+ return new Promise((resolve) => {
6851
+ externalWindow.addEventListener('unload', (e) => {
6852
+ // if page fails to load before unloading
6853
+ // this.close();
6854
+ });
6855
+ externalWindow.addEventListener('load', () => {
6856
+ /**
6857
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
6858
+ */
6859
+ const externalDocument = externalWindow.document;
6860
+ externalDocument.title = document.title;
6861
+ externalDocument.body.appendChild(container);
6862
+ addStyles(externalDocument, window.document.styleSheets);
6863
+ /**
6864
+ * beforeunload must be registered after load for reasons I could not determine
6865
+ * otherwise the beforeunload event will not fire when the window is closed
6866
+ */
6867
+ addDisposableWindowListener(externalWindow, 'beforeunload', () => {
6868
+ /**
6869
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event
6870
+ */
6871
+ this.close();
6872
+ });
6873
+ resolve(container);
6874
+ });
6875
+ });
6876
+ });
6877
+ }
6878
+ createPopoutWindowContainer() {
6879
+ const el = document.createElement('div');
6880
+ el.classList.add('dv-popout-window');
6881
+ el.id = 'dv-popout-window';
6882
+ el.style.position = 'absolute';
6883
+ el.style.width = '100%';
6884
+ el.style.height = '100%';
6885
+ el.style.top = '0px';
6886
+ el.style.left = '0px';
6887
+ return el;
6888
+ }
6889
+ }
6890
+
6537
6891
  const DEFAULT_ROOT_OVERLAY_MODEL = {
6538
6892
  activationSize: { type: 'pixels', value: 10 },
6539
6893
  size: { type: 'pixels', value: 20 },
6540
6894
  };
6541
- function getTheme(element) {
6895
+ function moveGroupWithoutDestroying(options) {
6896
+ const activePanel = options.from.activePanel;
6897
+ const panels = [...options.from.panels].map((panel) => {
6898
+ const removedPanel = options.from.model.removePanel(panel);
6899
+ options.from.model.renderContainer.detatch(panel);
6900
+ return removedPanel;
6901
+ });
6902
+ panels.forEach((panel) => {
6903
+ options.to.model.openPanel(panel, {
6904
+ skipSetActive: activePanel !== panel,
6905
+ skipSetGroupActive: true,
6906
+ });
6907
+ });
6908
+ }
6909
+ function getDockviewTheme(element) {
6542
6910
  function toClassList(element) {
6543
6911
  const list = [];
6544
6912
  for (let i = 0; i < element.classList.length; i++) {
@@ -6589,6 +6957,7 @@ class DockviewComponent extends BaseGrid {
6589
6957
  styles: options.styles,
6590
6958
  parentElement: options.parentElement,
6591
6959
  disableAutoResizing: options.disableAutoResizing,
6960
+ locked: options.locked,
6592
6961
  });
6593
6962
  this.nextGroupId = sequentialNumberGenerator();
6594
6963
  this._deserializer = new DefaultDockviewDeserialzier(this);
@@ -6599,6 +6968,10 @@ class DockviewComponent extends BaseGrid {
6599
6968
  this.onWillDragGroup = this._onWillDragGroup.event;
6600
6969
  this._onDidDrop = new Emitter();
6601
6970
  this.onDidDrop = this._onDidDrop.event;
6971
+ this._onWillDrop = new Emitter();
6972
+ this.onWillDrop = this._onWillDrop.event;
6973
+ this._onWillShowOverlay = new Emitter();
6974
+ this.onWillShowOverlay = this._onWillShowOverlay.event;
6602
6975
  this._onDidRemovePanel = new Emitter();
6603
6976
  this.onDidRemovePanel = this._onDidRemovePanel.event;
6604
6977
  this._onDidAddPanel = new Emitter();
@@ -6607,15 +6980,36 @@ class DockviewComponent extends BaseGrid {
6607
6980
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
6608
6981
  this._onDidActivePanelChange = new Emitter();
6609
6982
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
6983
+ this._onDidMovePanel = new Emitter();
6610
6984
  this._floatingGroups = [];
6611
6985
  this._popoutGroups = [];
6986
+ this._ignoreEvents = 0;
6987
+ this._onDidRemoveGroup = new Emitter();
6988
+ this.onDidRemoveGroup = this._onDidRemoveGroup.event;
6989
+ this._onDidAddGroup = new Emitter();
6990
+ this.onDidAddGroup = this._onDidAddGroup.event;
6991
+ this._onDidActiveGroupChange = new Emitter();
6992
+ this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
6993
+ this._moving = false;
6612
6994
  const gready = document.createElement('div');
6613
6995
  gready.className = 'dv-overlay-render-container';
6614
6996
  this.gridview.element.appendChild(gready);
6615
6997
  this.overlayRenderContainer = new OverlayRenderContainer(gready);
6616
6998
  toggleClass(this.gridview.element, 'dv-dockview', true);
6617
6999
  toggleClass(this.element, 'dv-debug', !!options.debug);
6618
- this.addDisposables(this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, Event.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
7000
+ 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) => {
7001
+ if (!this._moving) {
7002
+ this._onDidAddGroup.fire(event);
7003
+ }
7004
+ }), this.onDidRemove((event) => {
7005
+ if (!this._moving) {
7006
+ this._onDidRemoveGroup.fire(event);
7007
+ }
7008
+ }), this.onDidActiveChange((event) => {
7009
+ if (!this._moving) {
7010
+ this._onDidActiveGroupChange.fire(event);
7011
+ }
7012
+ }), Event.any(this.onDidAdd, this.onDidRemove)(() => {
6619
7013
  this.updateWatermark();
6620
7014
  }), Event.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
6621
7015
  this._bufferOnDidLayoutChange.fire();
@@ -6626,7 +7020,7 @@ class DockviewComponent extends BaseGrid {
6626
7020
  }
6627
7021
  // iterate over a copy of the array since .dispose() mutates the original array
6628
7022
  for (const group of [...this._popoutGroups]) {
6629
- group.dispose();
7023
+ group.disposable.dispose();
6630
7024
  }
6631
7025
  }));
6632
7026
  this._options = options;
@@ -6672,7 +7066,7 @@ class DockviewComponent extends BaseGrid {
6672
7066
  return this.options.showDndOverlay({
6673
7067
  nativeEvent: event,
6674
7068
  position: position,
6675
- target: DockviewDropTargets.Edge,
7069
+ target: 'edge',
6676
7070
  getData: getPanelData,
6677
7071
  });
6678
7072
  }
@@ -6681,88 +7075,259 @@ class DockviewComponent extends BaseGrid {
6681
7075
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
6682
7076
  overlayModel: (_b = this.options.rootOverlayModel) !== null && _b !== void 0 ? _b : DEFAULT_ROOT_OVERLAY_MODEL,
6683
7077
  });
6684
- this.addDisposables(this._rootDropTarget.onDrop((event) => {
7078
+ this.addDisposables(this._rootDropTarget, this._rootDropTarget.onWillShowOverlay((event) => {
7079
+ if (this.gridview.length > 0 && event.position === 'center') {
7080
+ // option only available when no panels in primary grid
7081
+ return;
7082
+ }
7083
+ this._onWillShowOverlay.fire(new WillShowOverlayLocationEvent(event, {
7084
+ kind: 'edge',
7085
+ }));
7086
+ }), this._rootDropTarget.onDrop((event) => {
6685
7087
  var _a;
7088
+ const willDropEvent = new DockviewWillDropEvent({
7089
+ nativeEvent: event.nativeEvent,
7090
+ position: event.position,
7091
+ panel: undefined,
7092
+ api: this._api,
7093
+ group: undefined,
7094
+ getData: getPanelData,
7095
+ kind: 'edge',
7096
+ });
7097
+ this._onWillDrop.fire(willDropEvent);
7098
+ if (willDropEvent.defaultPrevented) {
7099
+ return;
7100
+ }
6686
7101
  const data = getPanelData();
6687
7102
  if (data) {
6688
- this.moveGroupOrPanel(this.orthogonalize(event.position), data.groupId, (_a = data.panelId) !== null && _a !== void 0 ? _a : undefined, 'center');
7103
+ this.moveGroupOrPanel({
7104
+ from: {
7105
+ groupId: data.groupId,
7106
+ panelId: (_a = data.panelId) !== null && _a !== void 0 ? _a : undefined,
7107
+ },
7108
+ to: {
7109
+ group: this.orthogonalize(event.position),
7110
+ position: 'center',
7111
+ },
7112
+ });
6689
7113
  }
6690
7114
  else {
6691
- this._onDidDrop.fire(Object.assign(Object.assign({}, event), { api: this._api, group: null, getData: getPanelData }));
7115
+ this._onDidDrop.fire(new DockviewDidDropEvent({
7116
+ nativeEvent: event.nativeEvent,
7117
+ position: event.position,
7118
+ panel: undefined,
7119
+ api: this._api,
7120
+ group: undefined,
7121
+ getData: getPanelData,
7122
+ }));
6692
7123
  }
6693
7124
  }), this._rootDropTarget);
6694
7125
  this._api = new DockviewApi(this);
6695
7126
  this.updateWatermark();
6696
7127
  }
6697
- addPopoutGroup(item, options) {
6698
- var _a;
6699
- let group;
6700
- let box = options === null || options === void 0 ? void 0 : options.position;
6701
- if (item instanceof DockviewPanel) {
6702
- group = this.createGroup();
6703
- this.removePanel(item, {
6704
- removeEmptyGroup: true,
6705
- skipDispose: true,
6706
- });
6707
- group.model.openPanel(item);
6708
- if (!box) {
6709
- box = this.element.getBoundingClientRect();
7128
+ addPopoutGroup(itemToPopout, options) {
7129
+ var _a, _b, _c;
7130
+ if (itemToPopout instanceof DockviewPanel &&
7131
+ itemToPopout.group.size === 1) {
7132
+ return this.addPopoutGroup(itemToPopout.group);
7133
+ }
7134
+ const theme = getDockviewTheme(this.gridview.element);
7135
+ const element = this.element;
7136
+ function getBox() {
7137
+ if (options === null || options === void 0 ? void 0 : options.position) {
7138
+ return options.position;
7139
+ }
7140
+ if (itemToPopout instanceof DockviewGroupPanel) {
7141
+ return itemToPopout.element.getBoundingClientRect();
7142
+ }
7143
+ if (itemToPopout.group) {
7144
+ return itemToPopout.group.element.getBoundingClientRect();
7145
+ }
7146
+ return element.getBoundingClientRect();
7147
+ }
7148
+ const box = getBox();
7149
+ 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;
7150
+ if (itemToPopout.api.location.type === 'grid') {
7151
+ itemToPopout.api.setVisible(false);
7152
+ }
7153
+ const _window = new PopoutWindow(`${this.id}-${groupId}`, // unique id
7154
+ theme !== null && theme !== void 0 ? theme : '', {
7155
+ url: (_c = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _c !== void 0 ? _c : '/popout.html',
7156
+ left: window.screenX + box.left,
7157
+ top: window.screenY + box.top,
7158
+ width: box.width,
7159
+ height: box.height,
7160
+ onDidOpen: options === null || options === void 0 ? void 0 : options.onDidOpen,
7161
+ onWillClose: options === null || options === void 0 ? void 0 : options.onWillClose,
7162
+ });
7163
+ const popoutWindowDisposable = new CompositeDisposable(_window, _window.onDidClose(() => {
7164
+ popoutWindowDisposable.dispose();
7165
+ }));
7166
+ return _window
7167
+ .open()
7168
+ .then((popoutContainer) => {
7169
+ var _a;
7170
+ if (_window.isDisposed) {
7171
+ return;
6710
7172
  }
6711
- }
6712
- else {
6713
- group = item;
6714
- if (!box) {
6715
- box = group.element.getBoundingClientRect();
7173
+ if (popoutContainer === null) {
7174
+ popoutWindowDisposable.dispose();
7175
+ return;
6716
7176
  }
6717
- const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
6718
- options.skipRemoveGroup;
6719
- if (!skip) {
6720
- this.doRemoveGroup(item, { skipDispose: true });
6721
- }
6722
- }
6723
- const theme = getTheme(this.gridview.element);
6724
- const popoutWindow = new DockviewPopoutGroupPanel(`${this.id}-${group.id}`, // globally unique within dockview
6725
- group, {
6726
- className: theme !== null && theme !== void 0 ? theme : '',
6727
- popoutUrl: (_a = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _a !== void 0 ? _a : '/popout.html',
6728
- box: {
6729
- left: window.screenX + box.left,
6730
- top: window.screenY + box.top,
6731
- width: box.width,
6732
- height: box.height,
6733
- },
7177
+ const gready = document.createElement('div');
7178
+ gready.className = 'dv-overlay-render-container';
7179
+ const overlayRenderContainer = new OverlayRenderContainer(gready);
7180
+ const referenceGroup = itemToPopout instanceof DockviewPanel
7181
+ ? itemToPopout.group
7182
+ : itemToPopout;
7183
+ const referenceLocation = itemToPopout.api.location.type;
7184
+ const group = (_a = options === null || options === void 0 ? void 0 : options.overridePopoutGroup) !== null && _a !== void 0 ? _a : this.createGroup({ id: groupId });
7185
+ group.model.renderContainer = overlayRenderContainer;
7186
+ if (!(options === null || options === void 0 ? void 0 : options.overridePopoutGroup)) {
7187
+ this._onDidAddGroup.fire(group);
7188
+ }
7189
+ if (itemToPopout instanceof DockviewPanel) {
7190
+ this.movingLock(() => {
7191
+ const panel = referenceGroup.model.removePanel(itemToPopout);
7192
+ group.model.openPanel(panel);
7193
+ });
7194
+ }
7195
+ else {
7196
+ this.movingLock(() => moveGroupWithoutDestroying({
7197
+ from: referenceGroup,
7198
+ to: group,
7199
+ }));
7200
+ switch (referenceLocation) {
7201
+ case 'grid':
7202
+ referenceGroup.api.setVisible(false);
7203
+ break;
7204
+ case 'floating':
7205
+ case 'popout':
7206
+ this.removeGroup(referenceGroup);
7207
+ break;
7208
+ }
7209
+ }
7210
+ popoutContainer.classList.add('dv-dockview');
7211
+ popoutContainer.style.overflow = 'hidden';
7212
+ popoutContainer.appendChild(gready);
7213
+ popoutContainer.appendChild(group.element);
7214
+ group.model.location = {
7215
+ type: 'popout',
7216
+ getWindow: () => _window.window,
7217
+ };
7218
+ this.doSetGroupAndPanelActive(group);
7219
+ popoutWindowDisposable.addDisposables(group.api.onDidActiveChange((event) => {
7220
+ var _a;
7221
+ if (event.isActive) {
7222
+ (_a = _window.window) === null || _a === void 0 ? void 0 : _a.focus();
7223
+ }
7224
+ }), group.api.onWillFocus(() => {
7225
+ var _a;
7226
+ (_a = _window.window) === null || _a === void 0 ? void 0 : _a.focus();
7227
+ }));
7228
+ let returnedGroup;
7229
+ const value = {
7230
+ window: _window,
7231
+ popoutGroup: group,
7232
+ referenceGroup: this.getPanel(referenceGroup.id)
7233
+ ? referenceGroup.id
7234
+ : undefined,
7235
+ disposable: {
7236
+ dispose: () => {
7237
+ popoutWindowDisposable.dispose();
7238
+ return returnedGroup;
7239
+ },
7240
+ },
7241
+ };
7242
+ popoutWindowDisposable.addDisposables(
7243
+ /**
7244
+ * ResizeObserver seems slow here, I do not know why but we don't need it
7245
+ * since we can reply on the window resize event as we will occupy the full
7246
+ * window dimensions
7247
+ */
7248
+ addDisposableWindowListener(_window.window, 'resize', () => {
7249
+ group.layout(window.innerWidth, window.innerHeight);
7250
+ }), overlayRenderContainer, Disposable.from(() => {
7251
+ if (this.getPanel(referenceGroup.id)) {
7252
+ this.movingLock(() => moveGroupWithoutDestroying({
7253
+ from: group,
7254
+ to: referenceGroup,
7255
+ }));
7256
+ if (!referenceGroup.api.isVisible) {
7257
+ referenceGroup.api.setVisible(true);
7258
+ }
7259
+ if (this.getPanel(group.id)) {
7260
+ this.doRemoveGroup(group, {
7261
+ skipPopoutAssociated: true,
7262
+ });
7263
+ }
7264
+ }
7265
+ else {
7266
+ if (this.getPanel(group.id)) {
7267
+ const removedGroup = this.doRemoveGroup(group, {
7268
+ skipDispose: true,
7269
+ skipActive: true,
7270
+ });
7271
+ removedGroup.model.renderContainer =
7272
+ this.overlayRenderContainer;
7273
+ removedGroup.model.location = { type: 'grid' };
7274
+ returnedGroup = removedGroup;
7275
+ }
7276
+ }
7277
+ }));
7278
+ this._popoutGroups.push(value);
7279
+ this.updateWatermark();
7280
+ })
7281
+ .catch((err) => {
7282
+ console.error(err);
6734
7283
  });
6735
- popoutWindow.addDisposables({
6736
- dispose: () => {
6737
- remove(this._popoutGroups, popoutWindow);
6738
- this.updateWatermark();
6739
- },
6740
- }, popoutWindow.window.onDidClose(() => {
6741
- this.doAddGroup(group, [0]);
6742
- }));
6743
- this._popoutGroups.push(popoutWindow);
6744
- this.updateWatermark();
6745
7284
  }
6746
7285
  addFloatingGroup(item, coord, options) {
6747
- var _a, _b, _c, _d, _e, _f;
7286
+ var _a, _b, _c, _d, _e, _f, _g;
6748
7287
  let group;
6749
7288
  if (item instanceof DockviewPanel) {
6750
7289
  group = this.createGroup();
6751
- this.removePanel(item, {
7290
+ this._onDidAddGroup.fire(group);
7291
+ this.movingLock(() => this.removePanel(item, {
6752
7292
  removeEmptyGroup: true,
6753
7293
  skipDispose: true,
6754
- });
6755
- group.model.openPanel(item);
7294
+ skipSetActiveGroup: true,
7295
+ }));
7296
+ group.model.openPanel(item, { skipSetGroupActive: true });
6756
7297
  }
6757
7298
  else {
6758
7299
  group = item;
7300
+ const popoutReferenceGroupId = (_a = this._popoutGroups.find((_) => _.popoutGroup === group)) === null || _a === void 0 ? void 0 : _a.referenceGroup;
7301
+ const popoutReferenceGroup = popoutReferenceGroupId
7302
+ ? this.getPanel(popoutReferenceGroupId)
7303
+ : undefined;
6759
7304
  const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
6760
7305
  options.skipRemoveGroup;
6761
7306
  if (!skip) {
6762
- this.doRemoveGroup(item, { skipDispose: true });
7307
+ if (popoutReferenceGroup) {
7308
+ this.movingLock(() => moveGroupWithoutDestroying({
7309
+ from: item,
7310
+ to: popoutReferenceGroup,
7311
+ }));
7312
+ this.doRemoveGroup(item, {
7313
+ skipPopoutReturn: true,
7314
+ skipPopoutAssociated: true,
7315
+ });
7316
+ this.doRemoveGroup(popoutReferenceGroup, {
7317
+ skipDispose: true,
7318
+ });
7319
+ group = popoutReferenceGroup;
7320
+ }
7321
+ else {
7322
+ this.doRemoveGroup(item, {
7323
+ skipDispose: true,
7324
+ skipPopoutReturn: true,
7325
+ skipPopoutAssociated: !!popoutReferenceGroup,
7326
+ });
7327
+ }
6763
7328
  }
6764
7329
  }
6765
- group.model.location = 'floating';
7330
+ group.model.location = { type: 'floating' };
6766
7331
  const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number'
6767
7332
  ? Math.max(coord.x, 0)
6768
7333
  : DEFAULT_FLOATING_GROUP_POSITION.left;
@@ -6772,16 +7337,16 @@ class DockviewComponent extends BaseGrid {
6772
7337
  const overlay = new Overlay({
6773
7338
  container: this.gridview.element,
6774
7339
  content: group.element,
6775
- height: (_a = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _a !== void 0 ? _a : 300,
6776
- width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
7340
+ height: (_b = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _b !== void 0 ? _b : 300,
7341
+ width: (_c = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _c !== void 0 ? _c : 300,
6777
7342
  left: overlayLeft,
6778
7343
  top: overlayTop,
6779
7344
  minimumInViewportWidth: this.options.floatingGroupBounds === 'boundedWithinViewport'
6780
7345
  ? undefined
6781
- : (_d = (_c = this.options.floatingGroupBounds) === null || _c === void 0 ? void 0 : _c.minimumWidthWithinViewport) !== null && _d !== void 0 ? _d : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
7346
+ : (_e = (_d = this.options.floatingGroupBounds) === null || _d === void 0 ? void 0 : _d.minimumWidthWithinViewport) !== null && _e !== void 0 ? _e : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
6782
7347
  minimumInViewportHeight: this.options.floatingGroupBounds === 'boundedWithinViewport'
6783
7348
  ? undefined
6784
- : (_f = (_e = this.options.floatingGroupBounds) === null || _e === void 0 ? void 0 : _e.minimumHeightWithinViewport) !== null && _f !== void 0 ? _f : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
7349
+ : (_g = (_f = this.options.floatingGroupBounds) === null || _f === void 0 ? void 0 : _f.minimumHeightWithinViewport) !== null && _g !== void 0 ? _g : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
6785
7350
  });
6786
7351
  const el = group.element.querySelector('.void-container');
6787
7352
  if (!el) {
@@ -6812,12 +7377,15 @@ class DockviewComponent extends BaseGrid {
6812
7377
  }), {
6813
7378
  dispose: () => {
6814
7379
  disposable.dispose();
6815
- group.model.location = 'grid';
7380
+ group.model.location = { type: 'grid' };
6816
7381
  remove(this._floatingGroups, floatingGroupPanel);
6817
7382
  this.updateWatermark();
6818
7383
  },
6819
7384
  });
6820
7385
  this._floatingGroups.push(floatingGroupPanel);
7386
+ if (!(options === null || options === void 0 ? void 0 : options.skipActiveGroup)) {
7387
+ this.doSetGroupAndPanelActive(group);
7388
+ }
6821
7389
  this.updateWatermark();
6822
7390
  }
6823
7391
  orthogonalize(position) {
@@ -6907,8 +7475,8 @@ class DockviewComponent extends BaseGrid {
6907
7475
  return this.panels.find((panel) => panel.id === id);
6908
7476
  }
6909
7477
  setActivePanel(panel) {
6910
- this.doSetGroupActive(panel.group);
6911
7478
  panel.group.model.openPanel(panel);
7479
+ this.doSetGroupAndPanelActive(panel.group);
6912
7480
  }
6913
7481
  moveToNext(options = {}) {
6914
7482
  var _a;
@@ -6969,7 +7537,8 @@ class DockviewComponent extends BaseGrid {
6969
7537
  });
6970
7538
  const popoutGroups = this._popoutGroups.map((group) => {
6971
7539
  return {
6972
- data: group.group.toJSON(),
7540
+ data: group.popoutGroup.toJSON(),
7541
+ gridReferenceGroup: group.referenceGroup,
6973
7542
  position: group.window.dimensions(),
6974
7543
  };
6975
7544
  });
@@ -6987,7 +7556,7 @@ class DockviewComponent extends BaseGrid {
6987
7556
  return result;
6988
7557
  }
6989
7558
  fromJSON(data) {
6990
- var _a, _b;
7559
+ var _a, _b, _c;
6991
7560
  this.clear();
6992
7561
  if (typeof data !== 'object' || data === null) {
6993
7562
  throw new Error('serialized layout must be a non-null object');
@@ -7026,7 +7595,7 @@ class DockviewComponent extends BaseGrid {
7026
7595
  const isActive = typeof activeView === 'string' &&
7027
7596
  activeView === panel.id;
7028
7597
  group.model.openPanel(panel, {
7029
- skipSetPanelActive: !isActive,
7598
+ skipSetActive: !isActive,
7030
7599
  skipSetGroupActive: true,
7031
7600
  });
7032
7601
  }
@@ -7056,11 +7625,16 @@ class DockviewComponent extends BaseGrid {
7056
7625
  }
7057
7626
  const serializedPopoutGroups = (_b = data.popoutGroups) !== null && _b !== void 0 ? _b : [];
7058
7627
  for (const serializedPopoutGroup of serializedPopoutGroups) {
7059
- const { data, position } = serializedPopoutGroup;
7628
+ const { data, position, gridReferenceGroup } = serializedPopoutGroup;
7060
7629
  const group = createGroupFromSerializedState(data);
7061
- this.addPopoutGroup(group, {
7630
+ this.addPopoutGroup((_c = (gridReferenceGroup
7631
+ ? this.getPanel(gridReferenceGroup)
7632
+ : undefined)) !== null && _c !== void 0 ? _c : group, {
7062
7633
  skipRemoveGroup: true,
7063
7634
  position: position !== null && position !== void 0 ? position : undefined,
7635
+ overridePopoutGroup: gridReferenceGroup
7636
+ ? group
7637
+ : undefined,
7064
7638
  });
7065
7639
  }
7066
7640
  for (const floatingGroup of this._floatingGroups) {
@@ -7107,12 +7681,13 @@ class DockviewComponent extends BaseGrid {
7107
7681
  */
7108
7682
  throw err;
7109
7683
  }
7684
+ this.updateWatermark();
7110
7685
  this._onDidLayoutFromJSON.fire();
7111
7686
  }
7112
7687
  clear() {
7113
7688
  const groups = Array.from(this._groups.values()).map((_) => _.value);
7114
7689
  const hasActiveGroup = !!this.activeGroup;
7115
- const hasActivePanel = !!this.activePanel;
7690
+ !!this.activePanel;
7116
7691
  for (const group of groups) {
7117
7692
  // remove the group will automatically remove the panels
7118
7693
  this.removeGroup(group, { skipActive: true });
@@ -7120,9 +7695,6 @@ class DockviewComponent extends BaseGrid {
7120
7695
  if (hasActiveGroup) {
7121
7696
  this.doSetGroupAndPanelActive(undefined);
7122
7697
  }
7123
- if (hasActivePanel) {
7124
- this._onDidActivePanelChange.fire(undefined);
7125
- }
7126
7698
  this.gridview.clear();
7127
7699
  }
7128
7700
  closeAllGroups() {
@@ -7163,6 +7735,7 @@ class DockviewComponent extends BaseGrid {
7163
7735
  const group = this.orthogonalize(directionToPosition(options.position.direction));
7164
7736
  const panel = this.createPanel(options, group);
7165
7737
  group.model.openPanel(panel);
7738
+ this.doSetGroupAndPanelActive(group);
7166
7739
  return panel;
7167
7740
  }
7168
7741
  }
@@ -7174,6 +7747,7 @@ class DockviewComponent extends BaseGrid {
7174
7747
  const target = toTarget(((_b = options.position) === null || _b === void 0 ? void 0 : _b.direction) || 'within');
7175
7748
  if (options.floating) {
7176
7749
  const group = this.createGroup();
7750
+ this._onDidAddGroup.fire(group);
7177
7751
  const o = typeof options.floating === 'object' &&
7178
7752
  options.floating !== null
7179
7753
  ? options.floating
@@ -7181,16 +7755,16 @@ class DockviewComponent extends BaseGrid {
7181
7755
  this.addFloatingGroup(group, o, {
7182
7756
  inDragMode: false,
7183
7757
  skipRemoveGroup: true,
7758
+ skipActiveGroup: true,
7184
7759
  });
7185
- this._onDidAddGroup.fire(group);
7186
7760
  panel = this.createPanel(options, group);
7187
7761
  group.model.openPanel(panel);
7188
- this.doSetGroupAndPanelActive(group);
7189
7762
  }
7190
- else if (referenceGroup.api.location === 'floating' ||
7763
+ else if (referenceGroup.api.location.type === 'floating' ||
7191
7764
  target === 'center') {
7192
7765
  panel = this.createPanel(options, referenceGroup);
7193
7766
  referenceGroup.model.openPanel(panel);
7767
+ this.doSetGroupAndPanelActive(referenceGroup);
7194
7768
  }
7195
7769
  else {
7196
7770
  const location = getGridLocation(referenceGroup.element);
@@ -7198,10 +7772,12 @@ class DockviewComponent extends BaseGrid {
7198
7772
  const group = this.createGroupAtLocation(relativeLocation);
7199
7773
  panel = this.createPanel(options, group);
7200
7774
  group.model.openPanel(panel);
7775
+ this.doSetGroupAndPanelActive(group);
7201
7776
  }
7202
7777
  }
7203
7778
  else if (options.floating) {
7204
7779
  const group = this.createGroup();
7780
+ this._onDidAddGroup.fire(group);
7205
7781
  const o = typeof options.floating === 'object' &&
7206
7782
  options.floating !== null
7207
7783
  ? options.floating
@@ -7209,16 +7785,16 @@ class DockviewComponent extends BaseGrid {
7209
7785
  this.addFloatingGroup(group, o, {
7210
7786
  inDragMode: false,
7211
7787
  skipRemoveGroup: true,
7788
+ skipActiveGroup: true,
7212
7789
  });
7213
- this._onDidAddGroup.fire(group);
7214
7790
  panel = this.createPanel(options, group);
7215
7791
  group.model.openPanel(panel);
7216
- this.doSetGroupAndPanelActive(group);
7217
7792
  }
7218
7793
  else {
7219
7794
  const group = this.createGroupAtLocation();
7220
7795
  panel = this.createPanel(options, group);
7221
7796
  group.model.openPanel(panel);
7797
+ this.doSetGroupAndPanelActive(group);
7222
7798
  }
7223
7799
  return panel;
7224
7800
  }
@@ -7230,13 +7806,15 @@ class DockviewComponent extends BaseGrid {
7230
7806
  if (!group) {
7231
7807
  throw new Error(`cannot remove panel ${panel.id}. it's missing a group.`);
7232
7808
  }
7233
- group.model.removePanel(panel);
7809
+ group.model.removePanel(panel, {
7810
+ skipSetActiveGroup: options.skipSetActiveGroup,
7811
+ });
7234
7812
  if (!options.skipDispose) {
7235
- this.overlayRenderContainer.detatch(panel);
7813
+ panel.group.model.renderContainer.detatch(panel);
7236
7814
  panel.dispose();
7237
7815
  }
7238
7816
  if (group.size === 0 && options.removeEmptyGroup) {
7239
- this.removeGroup(group);
7817
+ this.removeGroup(group, { skipActive: options.skipSetActiveGroup });
7240
7818
  }
7241
7819
  }
7242
7820
  createWatermarkComponent() {
@@ -7249,7 +7827,7 @@ class DockviewComponent extends BaseGrid {
7249
7827
  }
7250
7828
  updateWatermark() {
7251
7829
  var _a, _b;
7252
- if (this.groups.filter((x) => x.api.location === 'grid').length === 0) {
7830
+ if (this.groups.filter((x) => x.api.location.type === 'grid' && x.api.isVisible).length === 0) {
7253
7831
  if (!this.watermark) {
7254
7832
  this.watermark = this.createWatermarkComponent();
7255
7833
  this.watermark.init({
@@ -7295,36 +7873,42 @@ class DockviewComponent extends BaseGrid {
7295
7873
  }
7296
7874
  else {
7297
7875
  const group = this.orthogonalize(directionToPosition(options.direction));
7876
+ if (!options.skipSetActive) {
7877
+ this.doSetGroupAndPanelActive(group);
7878
+ }
7298
7879
  return group;
7299
7880
  }
7300
7881
  const target = toTarget(options.direction || 'within');
7301
7882
  const location = getGridLocation(referenceGroup.element);
7302
7883
  const relativeLocation = getRelativeLocation(this.gridview.orientation, location, target);
7303
7884
  this.doAddGroup(group, relativeLocation);
7885
+ if (!options.skipSetActive) {
7886
+ this.doSetGroupAndPanelActive(group);
7887
+ }
7304
7888
  return group;
7305
7889
  }
7306
7890
  else {
7307
7891
  this.doAddGroup(group);
7892
+ this.doSetGroupAndPanelActive(group);
7308
7893
  return group;
7309
7894
  }
7310
7895
  }
7311
7896
  removeGroup(group, options) {
7897
+ this.doRemoveGroup(group, options);
7898
+ }
7899
+ doRemoveGroup(group, options) {
7312
7900
  var _a;
7313
7901
  const panels = [...group.panels]; // reassign since group panels will mutate
7314
- for (const panel of panels) {
7315
- this.removePanel(panel, {
7316
- removeEmptyGroup: false,
7317
- skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
7318
- });
7902
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7903
+ for (const panel of panels) {
7904
+ this.removePanel(panel, {
7905
+ removeEmptyGroup: false,
7906
+ skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false,
7907
+ });
7908
+ }
7319
7909
  }
7320
7910
  const activePanel = this.activePanel;
7321
- this.doRemoveGroup(group, options);
7322
- if (this.activePanel !== activePanel) {
7323
- this._onDidActivePanelChange.fire(this.activePanel);
7324
- }
7325
- }
7326
- doRemoveGroup(group, options) {
7327
- if (group.api.location === 'floating') {
7911
+ if (group.api.location.type === 'floating') {
7328
7912
  const floatingGroup = this._floatingGroups.find((_) => _.group === group);
7329
7913
  if (floatingGroup) {
7330
7914
  if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
@@ -7336,60 +7920,124 @@ class DockviewComponent extends BaseGrid {
7336
7920
  floatingGroup.dispose();
7337
7921
  if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7338
7922
  const groups = Array.from(this._groups.values());
7339
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7923
+ this.doSetGroupAndPanelActive(groups.length > 0 ? groups[0].value : undefined);
7340
7924
  }
7341
7925
  return floatingGroup.group;
7342
7926
  }
7343
7927
  throw new Error('failed to find floating group');
7344
7928
  }
7345
- if (group.api.location === 'popout') {
7346
- const selectedGroup = this._popoutGroups.find((_) => _.group === group);
7929
+ if (group.api.location.type === 'popout') {
7930
+ const selectedGroup = this._popoutGroups.find((_) => _.popoutGroup === group);
7347
7931
  if (selectedGroup) {
7348
7932
  if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7349
- selectedGroup.group.dispose();
7933
+ if (!(options === null || options === void 0 ? void 0 : options.skipPopoutAssociated)) {
7934
+ const refGroup = selectedGroup.referenceGroup
7935
+ ? this.getPanel(selectedGroup.referenceGroup)
7936
+ : undefined;
7937
+ if (refGroup) {
7938
+ this.removeGroup(refGroup);
7939
+ }
7940
+ }
7941
+ selectedGroup.popoutGroup.dispose();
7350
7942
  this._groups.delete(group.id);
7351
7943
  this._onDidRemoveGroup.fire(group);
7352
7944
  }
7353
- selectedGroup.dispose();
7945
+ const removedGroup = selectedGroup.disposable.dispose();
7946
+ if (!(options === null || options === void 0 ? void 0 : options.skipPopoutReturn) && removedGroup) {
7947
+ this.doAddGroup(removedGroup, [0]);
7948
+ this.doSetGroupAndPanelActive(removedGroup);
7949
+ }
7354
7950
  if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7355
7951
  const groups = Array.from(this._groups.values());
7356
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7952
+ this.doSetGroupAndPanelActive(groups.length > 0 ? groups[0].value : undefined);
7357
7953
  }
7358
- return selectedGroup.group;
7954
+ this.updateWatermark();
7955
+ return selectedGroup.popoutGroup;
7359
7956
  }
7360
7957
  throw new Error('failed to find popout group');
7361
7958
  }
7362
- return super.doRemoveGroup(group, options);
7959
+ const re = super.doRemoveGroup(group, options);
7960
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive)) {
7961
+ if (this.activePanel !== activePanel) {
7962
+ this._onDidActivePanelChange.fire(this.activePanel);
7963
+ }
7964
+ }
7965
+ return re;
7363
7966
  }
7364
- moveGroupOrPanel(destinationGroup, sourceGroupId, sourceItemId, destinationTarget, destinationIndex) {
7365
- var _a, _b, _c;
7967
+ movingLock(func) {
7968
+ const isMoving = this._moving;
7969
+ try {
7970
+ this._moving = true;
7971
+ return func();
7972
+ }
7973
+ finally {
7974
+ this._moving = isMoving;
7975
+ }
7976
+ }
7977
+ moveGroupOrPanel(options) {
7978
+ var _a;
7979
+ const destinationGroup = options.to.group;
7980
+ const sourceGroupId = options.from.groupId;
7981
+ const sourceItemId = options.from.panelId;
7982
+ const destinationTarget = options.to.position;
7983
+ const destinationIndex = options.to.index;
7366
7984
  const sourceGroup = sourceGroupId
7367
7985
  ? (_a = this._groups.get(sourceGroupId)) === null || _a === void 0 ? void 0 : _a.value
7368
7986
  : undefined;
7987
+ if (!sourceGroup) {
7988
+ throw new Error(`Failed to find group id ${sourceGroupId}`);
7989
+ }
7369
7990
  if (sourceItemId === undefined) {
7370
- if (sourceGroup) {
7371
- this.moveGroup(sourceGroup, destinationGroup, destinationTarget);
7372
- }
7991
+ /**
7992
+ * Moving an entire group into another group
7993
+ */
7994
+ this.moveGroup({
7995
+ from: { group: sourceGroup },
7996
+ to: {
7997
+ group: destinationGroup,
7998
+ position: destinationTarget,
7999
+ },
8000
+ });
7373
8001
  return;
7374
8002
  }
7375
8003
  if (!destinationTarget || destinationTarget === 'center') {
7376
- 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);
7377
- if (!groupItem) {
8004
+ /**
8005
+ * Dropping a panel within another group
8006
+ */
8007
+ const removedPanel = this.movingLock(() => sourceGroup.model.removePanel(sourceItemId, {
8008
+ skipSetActive: false,
8009
+ skipSetActiveGroup: true,
8010
+ }));
8011
+ if (!removedPanel) {
7378
8012
  throw new Error(`No panel with id ${sourceItemId}`);
7379
8013
  }
7380
- if ((sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.size) === 0) {
7381
- this.doRemoveGroup(sourceGroup);
8014
+ if (sourceGroup.model.size === 0) {
8015
+ // remove the group and do not set a new group as active
8016
+ this.doRemoveGroup(sourceGroup, { skipActive: true });
7382
8017
  }
7383
- destinationGroup.model.openPanel(groupItem, {
8018
+ this.movingLock(() => destinationGroup.model.openPanel(removedPanel, {
7384
8019
  index: destinationIndex,
8020
+ skipSetGroupActive: true,
8021
+ }));
8022
+ this.doSetGroupAndPanelActive(destinationGroup);
8023
+ this._onDidMovePanel.fire({
8024
+ panel: removedPanel,
7385
8025
  });
7386
8026
  }
7387
8027
  else {
8028
+ /**
8029
+ * Dropping a panel to the extremities of a group which will place that panel
8030
+ * into an adjacent group
8031
+ */
7388
8032
  const referenceLocation = getGridLocation(destinationGroup.element);
7389
8033
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
7390
- if (sourceGroup && sourceGroup.size < 2) {
8034
+ if (sourceGroup.size < 2) {
8035
+ /**
8036
+ * If we are moving from a group which only has one panel left we will consider
8037
+ * moving the group itself rather than moving the panel into a newly created group
8038
+ */
7391
8039
  const [targetParentLocation, to] = tail(targetLocation);
7392
- if (sourceGroup.api.location === 'grid') {
8040
+ if (sourceGroup.api.location.type === 'grid') {
7393
8041
  const sourceLocation = getGridLocation(sourceGroup.element);
7394
8042
  const [sourceParentLocation, from] = tail(sourceLocation);
7395
8043
  if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
@@ -7397,77 +8045,122 @@ class DockviewComponent extends BaseGrid {
7397
8045
  // if a group has one tab - we are essentially moving the 'group'
7398
8046
  // which is equivalent to swapping two views in this case
7399
8047
  this.gridview.moveView(sourceParentLocation, from, to);
8048
+ return;
7400
8049
  }
7401
8050
  }
7402
8051
  // source group will become empty so delete the group
7403
- const targetGroup = this.doRemoveGroup(sourceGroup, {
8052
+ const targetGroup = this.movingLock(() => this.doRemoveGroup(sourceGroup, {
7404
8053
  skipActive: true,
7405
8054
  skipDispose: true,
7406
- });
8055
+ }));
7407
8056
  // after deleting the group we need to re-evaulate the ref location
7408
8057
  const updatedReferenceLocation = getGridLocation(destinationGroup.element);
7409
8058
  const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget);
7410
- this.doAddGroup(targetGroup, location);
8059
+ this.movingLock(() => this.doAddGroup(targetGroup, location));
8060
+ this.doSetGroupAndPanelActive(targetGroup);
7411
8061
  }
7412
8062
  else {
7413
- 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);
7414
- if (!groupItem) {
8063
+ /**
8064
+ * The group we are removing from has many panels, we need to remove the panels we are moving,
8065
+ * create a new group, add the panels to that new group and add the new group in an appropiate position
8066
+ */
8067
+ const removedPanel = this.movingLock(() => sourceGroup.model.removePanel(sourceItemId, {
8068
+ skipSetActive: false,
8069
+ skipSetActiveGroup: true,
8070
+ }));
8071
+ if (!removedPanel) {
7415
8072
  throw new Error(`No panel with id ${sourceItemId}`);
7416
8073
  }
7417
8074
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
7418
8075
  const group = this.createGroupAtLocation(dropLocation);
7419
- group.model.openPanel(groupItem);
8076
+ this.movingLock(() => group.model.openPanel(removedPanel, {
8077
+ skipSetGroupActive: true,
8078
+ }));
8079
+ this.doSetGroupAndPanelActive(group);
7420
8080
  }
7421
8081
  }
7422
8082
  }
7423
- moveGroup(sourceGroup, referenceGroup, target) {
7424
- if (sourceGroup) {
7425
- if (!target || target === 'center') {
7426
- const activePanel = sourceGroup.activePanel;
7427
- const panels = [...sourceGroup.panels].map((p) => sourceGroup.model.removePanel(p.id));
7428
- if ((sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.size) === 0) {
7429
- this.doRemoveGroup(sourceGroup);
7430
- }
8083
+ moveGroup(options) {
8084
+ const from = options.from.group;
8085
+ const to = options.to.group;
8086
+ const target = options.to.position;
8087
+ if (target === 'center') {
8088
+ const activePanel = from.activePanel;
8089
+ const panels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, {
8090
+ skipSetActive: true,
8091
+ })));
8092
+ if ((from === null || from === void 0 ? void 0 : from.model.size) === 0) {
8093
+ this.doRemoveGroup(from, { skipActive: true });
8094
+ }
8095
+ this.movingLock(() => {
7431
8096
  for (const panel of panels) {
7432
- referenceGroup.model.openPanel(panel, {
7433
- skipSetPanelActive: panel !== activePanel,
8097
+ to.model.openPanel(panel, {
8098
+ skipSetActive: panel !== activePanel,
8099
+ skipSetGroupActive: true,
7434
8100
  });
7435
8101
  }
7436
- }
7437
- else {
7438
- switch (sourceGroup.api.location) {
7439
- case 'grid':
7440
- this.gridview.removeView(getGridLocation(sourceGroup.element));
7441
- break;
7442
- case 'floating': {
7443
- const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === sourceGroup);
7444
- if (!selectedFloatingGroup) {
7445
- throw new Error('failed to find floating group');
7446
- }
7447
- selectedFloatingGroup.dispose();
7448
- break;
8102
+ });
8103
+ this.doSetGroupAndPanelActive(to);
8104
+ panels.forEach((panel) => {
8105
+ this._onDidMovePanel.fire({ panel });
8106
+ });
8107
+ }
8108
+ else {
8109
+ switch (from.api.location.type) {
8110
+ case 'grid':
8111
+ this.gridview.removeView(getGridLocation(from.element));
8112
+ break;
8113
+ case 'floating': {
8114
+ const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === from);
8115
+ if (!selectedFloatingGroup) {
8116
+ throw new Error('failed to find floating group');
7449
8117
  }
7450
- case 'popout': {
7451
- const selectedPopoutGroup = this._popoutGroups.find((x) => x.group === sourceGroup);
7452
- if (!selectedPopoutGroup) {
7453
- throw new Error('failed to find popout group');
7454
- }
7455
- selectedPopoutGroup.dispose();
8118
+ selectedFloatingGroup.dispose();
8119
+ break;
8120
+ }
8121
+ case 'popout': {
8122
+ const selectedPopoutGroup = this._popoutGroups.find((x) => x.popoutGroup === from);
8123
+ if (!selectedPopoutGroup) {
8124
+ throw new Error('failed to find popout group');
7456
8125
  }
8126
+ selectedPopoutGroup.disposable.dispose();
7457
8127
  }
7458
- const referenceLocation = getGridLocation(referenceGroup.element);
7459
- const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
7460
- this.gridview.addView(sourceGroup, Sizing.Distribute, dropLocation);
7461
8128
  }
8129
+ const referenceLocation = getGridLocation(to.element);
8130
+ const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
8131
+ this.gridview.addView(from, Sizing.Distribute, dropLocation);
8132
+ from.panels.forEach((panel) => {
8133
+ this._onDidMovePanel.fire({ panel });
8134
+ });
7462
8135
  }
7463
8136
  }
7464
- doSetGroupAndPanelActive(group, skipFocus) {
7465
- var _a, _b;
8137
+ doSetGroupActive(group) {
8138
+ super.doSetGroupActive(group);
8139
+ const activePanel = this.activePanel;
8140
+ if (!this._moving &&
8141
+ activePanel !== this._onDidActivePanelChange.value) {
8142
+ this._onDidActivePanelChange.fire(activePanel);
8143
+ }
8144
+ }
8145
+ doSetGroupAndPanelActive(group) {
8146
+ super.doSetGroupActive(group);
7466
8147
  const activePanel = this.activePanel;
7467
- super.doSetGroupActive(group, skipFocus);
7468
- if (((_a = this._activeGroup) === null || _a === void 0 ? void 0 : _a.activePanel) !== activePanel) {
7469
- this._onDidActivePanelChange.fire((_b = this._activeGroup) === null || _b === void 0 ? void 0 : _b.activePanel);
8148
+ if (group &&
8149
+ this.hasMaximizedGroup() &&
8150
+ !this.isMaximizedGroup(group)) {
8151
+ this.exitMaximizedGroup();
8152
+ }
8153
+ if (!this._moving &&
8154
+ activePanel !== this._onDidActivePanelChange.value) {
8155
+ this._onDidActivePanelChange.fire(activePanel);
8156
+ }
8157
+ }
8158
+ getNextGroupId() {
8159
+ let id = this.nextGroupId.next();
8160
+ while (this._groups.has(id)) {
8161
+ id = this.nextGroupId.next();
7470
8162
  }
8163
+ return id;
7471
8164
  }
7472
8165
  createGroup(options) {
7473
8166
  if (!options) {
@@ -7485,7 +8178,7 @@ class DockviewComponent extends BaseGrid {
7485
8178
  }
7486
8179
  }
7487
8180
  const view = new DockviewGroupPanel(this, id, options);
7488
- view.init({ params: {}, accessor: null }); // required to initialized .part and allow for correct disposal of group
8181
+ view.init({ params: {}, accessor: this });
7489
8182
  if (!this._groups.has(view.id)) {
7490
8183
  const disposable = new CompositeDisposable(view.model.onTabDragStart((event) => {
7491
8184
  this._onWillDragPanel.fire(event);
@@ -7493,20 +8186,48 @@ class DockviewComponent extends BaseGrid {
7493
8186
  this._onWillDragGroup.fire(event);
7494
8187
  }), view.model.onMove((event) => {
7495
8188
  const { groupId, itemId, target, index } = event;
7496
- this.moveGroupOrPanel(view, groupId, itemId, target, index);
8189
+ this.moveGroupOrPanel({
8190
+ from: { groupId: groupId, panelId: itemId },
8191
+ to: {
8192
+ group: view,
8193
+ position: target,
8194
+ index,
8195
+ },
8196
+ });
7497
8197
  }), view.model.onDidDrop((event) => {
7498
- this._onDidDrop.fire(Object.assign(Object.assign({}, event), { api: this._api, group: view }));
8198
+ this._onDidDrop.fire(event);
8199
+ }), view.model.onWillDrop((event) => {
8200
+ this._onWillDrop.fire(event);
8201
+ }), view.model.onWillShowOverlay((event) => {
8202
+ if (this.options.disableDnd) {
8203
+ event.preventDefault();
8204
+ return;
8205
+ }
8206
+ this._onWillShowOverlay.fire(event);
7499
8207
  }), view.model.onDidAddPanel((event) => {
8208
+ if (this._moving) {
8209
+ return;
8210
+ }
7500
8211
  this._onDidAddPanel.fire(event.panel);
7501
8212
  }), view.model.onDidRemovePanel((event) => {
8213
+ if (this._moving) {
8214
+ return;
8215
+ }
7502
8216
  this._onDidRemovePanel.fire(event.panel);
7503
8217
  }), view.model.onDidActivePanelChange((event) => {
7504
- this._onDidActivePanelChange.fire(event.panel);
8218
+ if (this._moving) {
8219
+ return;
8220
+ }
8221
+ if (event.panel !== this.activePanel) {
8222
+ return;
8223
+ }
8224
+ if (this._onDidActivePanelChange.value !== event.panel) {
8225
+ this._onDidActivePanelChange.fire(event.panel);
8226
+ }
7505
8227
  }));
7506
8228
  this._groups.set(view.id, { value: view, disposable });
7507
8229
  }
7508
- // TODO: must be called after the above listeners have been setup,
7509
- // not an ideal pattern
8230
+ // TODO: must be called after the above listeners have been setup, not an ideal pattern
7510
8231
  view.initialize();
7511
8232
  return view;
7512
8233
  }
@@ -7559,7 +8280,20 @@ class GridviewComponent extends BaseGrid {
7559
8280
  });
7560
8281
  this._onDidLayoutfromJSON = new Emitter();
7561
8282
  this.onDidLayoutFromJSON = this._onDidLayoutfromJSON.event;
8283
+ this._onDidRemoveGroup = new Emitter();
8284
+ this.onDidRemoveGroup = this._onDidRemoveGroup.event;
8285
+ this._onDidAddGroup = new Emitter();
8286
+ this.onDidAddGroup = this._onDidAddGroup.event;
8287
+ this._onDidActiveGroupChange = new Emitter();
8288
+ this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
7562
8289
  this._options = options;
8290
+ this.addDisposables(this._onDidAddGroup, this._onDidRemoveGroup, this._onDidActiveGroupChange, this.onDidAdd((event) => {
8291
+ this._onDidAddGroup.fire(event);
8292
+ }), this.onDidRemove((event) => {
8293
+ this._onDidRemoveGroup.fire(event);
8294
+ }), this.onDidActiveChange((event) => {
8295
+ this._onDidActiveGroupChange.fire(event);
8296
+ }));
7563
8297
  if (!this.options.components) {
7564
8298
  this.options.components = {};
7565
8299
  }
@@ -7734,6 +8468,7 @@ class GridviewComponent extends BaseGrid {
7734
8468
  });
7735
8469
  this.registerPanel(view);
7736
8470
  this.doAddGroup(view, relativeLocation, options.size);
8471
+ this.doSetGroupActive(view);
7737
8472
  return view;
7738
8473
  }
7739
8474
  registerPanel(panel) {
@@ -7875,19 +8610,19 @@ class SplitviewComponent extends Resizable {
7875
8610
  const index = this.panels.indexOf(panel);
7876
8611
  this.splitview.setViewVisible(index, visible);
7877
8612
  }
7878
- setActive(view, skipFocus) {
7879
- this._activePanel = view;
8613
+ setActive(panel, skipFocus) {
8614
+ this._activePanel = panel;
7880
8615
  this.panels
7881
- .filter((v) => v !== view)
8616
+ .filter((v) => v !== panel)
7882
8617
  .forEach((v) => {
7883
8618
  v.api._onDidActiveChange.fire({ isActive: false });
7884
8619
  if (!skipFocus) {
7885
8620
  v.focus();
7886
8621
  }
7887
8622
  });
7888
- view.api._onDidActiveChange.fire({ isActive: true });
8623
+ panel.api._onDidActiveChange.fire({ isActive: true });
7889
8624
  if (!skipFocus) {
7890
- view.focus();
8625
+ panel.focus();
7891
8626
  }
7892
8627
  }
7893
8628
  removePanel(panel, sizing) {
@@ -8186,6 +8921,10 @@ class PaneviewComponent extends Resizable {
8186
8921
  });
8187
8922
  this.addDisposables(this._disposable);
8188
8923
  }
8924
+ setVisible(panel, visible) {
8925
+ const index = this.panels.indexOf(panel);
8926
+ this.paneview.setViewVisible(index, visible);
8927
+ }
8189
8928
  focus() {
8190
8929
  //noop
8191
8930
  }
@@ -8232,6 +8971,7 @@ class PaneviewComponent extends Resizable {
8232
8971
  isExpanded: options.isExpanded,
8233
8972
  title: options.title,
8234
8973
  containerApi: new PaneviewApi(this),
8974
+ accessor: this,
8235
8975
  });
8236
8976
  this.paneview.addPane(view, size, index);
8237
8977
  view.orientation = this.paneview.orientation;
@@ -8331,6 +9071,7 @@ class PaneviewComponent extends Resizable {
8331
9071
  title: data.title,
8332
9072
  isExpanded: !!view.expanded,
8333
9073
  containerApi: new PaneviewApi(this),
9074
+ accessor: this,
8334
9075
  });
8335
9076
  panel.orientation = this.paneview.orientation;
8336
9077
  });
@@ -8419,7 +9160,7 @@ class SplitviewPanel extends BasePanelView {
8419
9160
  this._onDidChange = new Emitter();
8420
9161
  this.onDidChange = this._onDidChange.event;
8421
9162
  this.api.initialize(this);
8422
- this.addDisposables(this._onDidChange, this.api.onVisibilityChange((event) => {
9163
+ this.addDisposables(this._onDidChange, this.api.onWillVisibilityChange((event) => {
8423
9164
  const { isVisible } = event;
8424
9165
  const { accessor } = this._params;
8425
9166
  accessor.setVisible(this, isVisible);
@@ -8544,13 +9285,13 @@ class ReactPart {
8544
9285
  if (this.disposed) {
8545
9286
  throw new Error('invalid operation: resource is already disposed');
8546
9287
  }
8547
- if (typeof this.component !== 'function') {
9288
+ if (!isReactComponent(this.component)) {
8548
9289
  /**
8549
9290
  * we know this isn't a React.FunctionComponent so throw an error here.
8550
- * if we do not intercept this the React library will throw a very obsure error
8551
- * for the same reason, at least at this point we will emit a sensible stacktrace.
9291
+ * if we do not intercept then React library will throw a very obsure error
9292
+ * for the same reason... at least at this point we will emit a sensible stacktrace.
8552
9293
  */
8553
- throw new Error('Invalid Operation. dockview only supports React Functional Components.');
9294
+ throw new Error('Dockview: Only React.memo(...), React.ForwardRef(...) and functional components are accepted as components');
8554
9295
  }
8555
9296
  const bridgeComponent = React.createElement(React.forwardRef(ReactComponentBridge), {
8556
9297
  component: this
@@ -8602,9 +9343,13 @@ const usePortalsLifecycle = () => {
8602
9343
  }, []);
8603
9344
  return [portals, addPortal];
8604
9345
  };
8605
- // it does the job...
8606
- function isReactElement(element) {
8607
- return !!(element === null || element === void 0 ? void 0 : element.type);
9346
+ function isReactComponent(component) {
9347
+ /**
9348
+ * Yes, we could use "react-is" but that would introduce an unwanted peer dependency
9349
+ * so for now we will check in a rather crude fashion...
9350
+ */
9351
+ return (typeof component === 'function' /** Functional Componnts */ ||
9352
+ !!(component === null || component === void 0 ? void 0 : component.$$typeof) /** React.memo(...) Components */);
8608
9353
  }
8609
9354
 
8610
9355
  class ReactPanelContentPart {
@@ -8864,6 +9609,8 @@ const DockviewReact = React.forwardRef((props, ref) => {
8864
9609
  defaultRenderer: props.defaultRenderer,
8865
9610
  debug: props.debug,
8866
9611
  rootOverlayModel: props.rootOverlayModel,
9612
+ locked: props.locked,
9613
+ disableDnd: props.disableDnd,
8867
9614
  });
8868
9615
  const { clientWidth, clientHeight } = domRef.current;
8869
9616
  dockview.layout(clientWidth, clientHeight);
@@ -8875,6 +9622,20 @@ const DockviewReact = React.forwardRef((props, ref) => {
8875
9622
  dockview.dispose();
8876
9623
  };
8877
9624
  }, []);
9625
+ React.useEffect(() => {
9626
+ if (!dockviewRef.current) {
9627
+ return;
9628
+ }
9629
+ dockviewRef.current.locked = !!props.locked;
9630
+ }, [props.locked]);
9631
+ React.useEffect(() => {
9632
+ if (!dockviewRef.current) {
9633
+ return;
9634
+ }
9635
+ dockviewRef.current.updateOptions({
9636
+ disableDnd: props.disableDnd,
9637
+ });
9638
+ }, [props.disableDnd]);
8878
9639
  React.useEffect(() => {
8879
9640
  if (!dockviewRef.current) {
8880
9641
  return () => {
@@ -8890,6 +9651,21 @@ const DockviewReact = React.forwardRef((props, ref) => {
8890
9651
  disposable.dispose();
8891
9652
  };
8892
9653
  }, [props.onDidDrop]);
9654
+ React.useEffect(() => {
9655
+ if (!dockviewRef.current) {
9656
+ return () => {
9657
+ // noop
9658
+ };
9659
+ }
9660
+ const disposable = dockviewRef.current.onWillDrop((event) => {
9661
+ if (props.onWillDrop) {
9662
+ props.onWillDrop(event);
9663
+ }
9664
+ });
9665
+ return () => {
9666
+ disposable.dispose();
9667
+ };
9668
+ }, [props.onWillDrop]);
8893
9669
  React.useEffect(() => {
8894
9670
  if (!dockviewRef.current) {
8895
9671
  return;
@@ -9132,7 +9908,9 @@ class ReactGridPanelView extends GridviewPanel {
9132
9908
  return new ReactPart(this.element, this.reactPortalStore, this.reactComponent, {
9133
9909
  params: (_b = (_a = this._params) === null || _a === void 0 ? void 0 : _a.params) !== null && _b !== void 0 ? _b : {},
9134
9910
  api: this.api,
9135
- containerApi: new GridviewApi(this._params.accessor),
9911
+ // TODO: fix casting hack
9912
+ containerApi: new GridviewApi(this._params
9913
+ .accessor),
9136
9914
  });
9137
9915
  }
9138
9916
  }
@@ -9307,5 +10085,5 @@ const PaneviewReact = React.forwardRef((props, ref) => {
9307
10085
  });
9308
10086
  PaneviewReact.displayName = 'PaneviewComponent';
9309
10087
 
9310
- 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 };
10088
+ 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 };
9311
10089
  //# sourceMappingURL=dockview.esm.js.map