dockview-core 1.8.5 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/README.md +18 -11
  2. package/dist/cjs/api/component.api.d.ts +12 -0
  3. package/dist/cjs/api/component.api.d.ts.map +1 -1
  4. package/dist/cjs/api/component.api.js +22 -0
  5. package/dist/cjs/api/component.api.js.map +1 -1
  6. package/dist/cjs/api/dockviewGroupPanelApi.d.ts +15 -8
  7. package/dist/cjs/api/dockviewGroupPanelApi.d.ts.map +1 -1
  8. package/dist/cjs/api/dockviewGroupPanelApi.js +39 -9
  9. package/dist/cjs/api/dockviewGroupPanelApi.js.map +1 -1
  10. package/dist/cjs/api/dockviewPanelApi.d.ts +19 -2
  11. package/dist/cjs/api/dockviewPanelApi.d.ts.map +1 -1
  12. package/dist/cjs/api/dockviewPanelApi.js +23 -3
  13. package/dist/cjs/api/dockviewPanelApi.js.map +1 -1
  14. package/dist/cjs/api/gridviewPanelApi.js.map +1 -1
  15. package/dist/cjs/api/panelApi.js.map +1 -1
  16. package/dist/cjs/api/paneviewPanelApi.js.map +1 -1
  17. package/dist/cjs/api/splitviewPanelApi.js.map +1 -1
  18. package/dist/cjs/array.js.map +1 -1
  19. package/dist/cjs/constants.d.ts +6 -0
  20. package/dist/cjs/constants.d.ts.map +1 -0
  21. package/dist/cjs/constants.js +6 -0
  22. package/dist/cjs/constants.js.map +1 -0
  23. package/dist/cjs/dnd/abstractDragHandler.js.map +1 -1
  24. package/dist/cjs/dnd/dataTransfer.js.map +1 -1
  25. package/dist/cjs/dnd/dnd.d.ts +5 -0
  26. package/dist/cjs/dnd/dnd.d.ts.map +1 -1
  27. package/dist/cjs/dnd/dnd.js +28 -13
  28. package/dist/cjs/dnd/dnd.js.map +1 -1
  29. package/dist/cjs/dnd/droptarget.d.ts +2 -0
  30. package/dist/cjs/dnd/droptarget.d.ts.map +1 -1
  31. package/dist/cjs/dnd/droptarget.js +3 -2
  32. package/dist/cjs/dnd/droptarget.js.map +1 -1
  33. package/dist/cjs/dnd/groupDragHandler.js +1 -1
  34. package/dist/cjs/dnd/groupDragHandler.js.map +1 -1
  35. package/dist/cjs/dnd/overlay.d.ts +4 -17
  36. package/dist/cjs/dnd/overlay.d.ts.map +1 -1
  37. package/dist/cjs/dnd/overlay.js.map +1 -1
  38. package/dist/cjs/dockview/components/panel/content.d.ts +14 -1
  39. package/dist/cjs/dockview/components/panel/content.d.ts.map +1 -1
  40. package/dist/cjs/dockview/components/panel/content.js +85 -26
  41. package/dist/cjs/dockview/components/panel/content.js.map +1 -1
  42. package/dist/cjs/dockview/components/tab/defaultTab.js.map +1 -1
  43. package/dist/cjs/dockview/components/tab/tab.js.map +1 -1
  44. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +2 -2
  45. package/dist/cjs/dockview/components/titlebar/tabsContainer.js.map +1 -1
  46. package/dist/cjs/dockview/components/titlebar/voidContainer.js.map +1 -1
  47. package/dist/cjs/dockview/components/watermark/watermark.js.map +1 -1
  48. package/dist/cjs/dockview/deserializer.d.ts +2 -2
  49. package/dist/cjs/dockview/deserializer.d.ts.map +1 -1
  50. package/dist/cjs/dockview/deserializer.js +6 -4
  51. package/dist/cjs/dockview/deserializer.js.map +1 -1
  52. package/dist/cjs/dockview/dockviewComponent.d.ts +21 -9
  53. package/dist/cjs/dockview/dockviewComponent.d.ts.map +1 -1
  54. package/dist/cjs/dockview/dockviewComponent.js +287 -103
  55. package/dist/cjs/dockview/dockviewComponent.js.map +1 -1
  56. package/dist/cjs/dockview/dockviewFloatingGroupPanel.js.map +1 -1
  57. package/dist/cjs/dockview/dockviewGroupPanel.d.ts.map +1 -1
  58. package/dist/cjs/dockview/dockviewGroupPanel.js +4 -2
  59. package/dist/cjs/dockview/dockviewGroupPanel.js.map +1 -1
  60. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +5 -4
  61. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts.map +1 -1
  62. package/dist/cjs/dockview/dockviewGroupPanelModel.js +37 -43
  63. package/dist/cjs/dockview/dockviewGroupPanelModel.js.map +1 -1
  64. package/dist/cjs/dockview/dockviewPanel.d.ts +8 -1
  65. package/dist/cjs/dockview/dockviewPanel.d.ts.map +1 -1
  66. package/dist/cjs/dockview/dockviewPanel.js +23 -1
  67. package/dist/cjs/dockview/dockviewPanel.js.map +1 -1
  68. package/dist/cjs/dockview/dockviewPanelModel.js.map +1 -1
  69. package/dist/cjs/dockview/dockviewPopoutGroupPanel.d.ts +16 -0
  70. package/dist/cjs/dockview/dockviewPopoutGroupPanel.d.ts.map +1 -0
  71. package/dist/cjs/dockview/dockviewPopoutGroupPanel.js +50 -0
  72. package/dist/cjs/dockview/dockviewPopoutGroupPanel.js.map +1 -0
  73. package/dist/cjs/dockview/options.d.ts +5 -0
  74. package/dist/cjs/dockview/options.d.ts.map +1 -1
  75. package/dist/cjs/dockview/options.js.map +1 -1
  76. package/dist/cjs/dockview/types.d.ts +2 -0
  77. package/dist/cjs/dockview/types.d.ts.map +1 -1
  78. package/dist/cjs/dockview/types.js.map +1 -1
  79. package/dist/cjs/dom.d.ts +12 -0
  80. package/dist/cjs/dom.d.ts.map +1 -1
  81. package/dist/cjs/dom.js +80 -1
  82. package/dist/cjs/dom.js.map +1 -1
  83. package/dist/cjs/events.js.map +1 -1
  84. package/dist/cjs/gridview/baseComponentGridview.d.ts +10 -0
  85. package/dist/cjs/gridview/baseComponentGridview.d.ts.map +1 -1
  86. package/dist/cjs/gridview/baseComponentGridview.js +19 -0
  87. package/dist/cjs/gridview/baseComponentGridview.js.map +1 -1
  88. package/dist/cjs/gridview/basePanelView.js.map +1 -1
  89. package/dist/cjs/gridview/branchNode.d.ts +2 -0
  90. package/dist/cjs/gridview/branchNode.d.ts.map +1 -1
  91. package/dist/cjs/gridview/branchNode.js +37 -10
  92. package/dist/cjs/gridview/branchNode.js.map +1 -1
  93. package/dist/cjs/gridview/gridview.d.ts +10 -3
  94. package/dist/cjs/gridview/gridview.d.ts.map +1 -1
  95. package/dist/cjs/gridview/gridview.js +80 -0
  96. package/dist/cjs/gridview/gridview.js.map +1 -1
  97. package/dist/cjs/gridview/gridviewComponent.js.map +1 -1
  98. package/dist/cjs/gridview/gridviewPanel.js.map +1 -1
  99. package/dist/cjs/gridview/leafNode.d.ts.map +1 -1
  100. package/dist/cjs/gridview/leafNode.js +1 -2
  101. package/dist/cjs/gridview/leafNode.js.map +1 -1
  102. package/dist/cjs/index.d.ts +2 -1
  103. package/dist/cjs/index.d.ts.map +1 -1
  104. package/dist/cjs/index.js.map +1 -1
  105. package/dist/cjs/lifecycle.d.ts +1 -0
  106. package/dist/cjs/lifecycle.d.ts.map +1 -1
  107. package/dist/cjs/lifecycle.js +8 -0
  108. package/dist/cjs/lifecycle.js.map +1 -1
  109. package/dist/cjs/math.js.map +1 -1
  110. package/dist/cjs/overlayRenderContainer.d.ts +19 -0
  111. package/dist/cjs/overlayRenderContainer.d.ts.map +1 -0
  112. package/dist/cjs/overlayRenderContainer.js +170 -0
  113. package/dist/cjs/overlayRenderContainer.js.map +1 -0
  114. package/dist/cjs/panel/componentFactory.js.map +1 -1
  115. package/dist/cjs/paneview/defaultPaneviewHeader.js.map +1 -1
  116. package/dist/cjs/paneview/draggablePaneviewPanel.js.map +1 -1
  117. package/dist/cjs/paneview/paneview.js.map +1 -1
  118. package/dist/cjs/paneview/paneviewComponent.js.map +1 -1
  119. package/dist/cjs/paneview/paneviewPanel.js.map +1 -1
  120. package/dist/cjs/popoutWindow.d.ts +18 -0
  121. package/dist/cjs/popoutWindow.d.ts.map +1 -0
  122. package/dist/cjs/popoutWindow.js +130 -0
  123. package/dist/cjs/popoutWindow.js.map +1 -0
  124. package/dist/cjs/resizable.js +1 -1
  125. package/dist/cjs/resizable.js.map +1 -1
  126. package/dist/cjs/splitview/splitview.d.ts +5 -4
  127. package/dist/cjs/splitview/splitview.d.ts.map +1 -1
  128. package/dist/cjs/splitview/splitview.js +31 -8
  129. package/dist/cjs/splitview/splitview.js.map +1 -1
  130. package/dist/cjs/splitview/splitviewComponent.js.map +1 -1
  131. package/dist/cjs/splitview/splitviewPanel.js.map +1 -1
  132. package/dist/cjs/splitview/viewItem.js.map +1 -1
  133. package/dist/cjs/types.d.ts +6 -0
  134. package/dist/cjs/types.d.ts.map +1 -1
  135. package/dist/dockview-core.amd.js +896 -170
  136. package/dist/dockview-core.amd.js.map +1 -1
  137. package/dist/dockview-core.amd.min.js +2 -2
  138. package/dist/dockview-core.amd.min.js.map +1 -1
  139. package/dist/dockview-core.amd.min.noStyle.js +2 -2
  140. package/dist/dockview-core.amd.min.noStyle.js.map +1 -1
  141. package/dist/dockview-core.amd.noStyle.js +895 -169
  142. package/dist/dockview-core.amd.noStyle.js.map +1 -1
  143. package/dist/dockview-core.cjs.js +896 -170
  144. package/dist/dockview-core.cjs.js.map +1 -1
  145. package/dist/dockview-core.esm.js +896 -170
  146. package/dist/dockview-core.esm.js.map +1 -1
  147. package/dist/dockview-core.esm.min.js +2 -2
  148. package/dist/dockview-core.esm.min.js.map +1 -1
  149. package/dist/dockview-core.js +896 -170
  150. package/dist/dockview-core.js.map +1 -1
  151. package/dist/dockview-core.min.js +2 -2
  152. package/dist/dockview-core.min.js.map +1 -1
  153. package/dist/dockview-core.min.noStyle.js +2 -2
  154. package/dist/dockview-core.min.noStyle.js.map +1 -1
  155. package/dist/dockview-core.noStyle.js +895 -169
  156. package/dist/dockview-core.noStyle.js.map +1 -1
  157. package/dist/esm/api/component.api.d.ts +12 -0
  158. package/dist/esm/api/component.api.d.ts.map +1 -1
  159. package/dist/esm/api/component.api.js +18 -0
  160. package/dist/esm/api/component.api.js.map +1 -1
  161. package/dist/esm/api/dockviewGroupPanelApi.d.ts +15 -8
  162. package/dist/esm/api/dockviewGroupPanelApi.d.ts.map +1 -1
  163. package/dist/esm/api/dockviewGroupPanelApi.js +39 -9
  164. package/dist/esm/api/dockviewGroupPanelApi.js.map +1 -1
  165. package/dist/esm/api/dockviewPanelApi.d.ts +19 -2
  166. package/dist/esm/api/dockviewPanelApi.d.ts.map +1 -1
  167. package/dist/esm/api/dockviewPanelApi.js +19 -3
  168. package/dist/esm/api/dockviewPanelApi.js.map +1 -1
  169. package/dist/esm/api/gridviewPanelApi.js.map +1 -1
  170. package/dist/esm/array.js.map +1 -1
  171. package/dist/esm/constants.d.ts +6 -0
  172. package/dist/esm/constants.d.ts.map +1 -0
  173. package/dist/esm/constants.js +3 -0
  174. package/dist/esm/constants.js.map +1 -0
  175. package/dist/esm/dnd/abstractDragHandler.js.map +1 -1
  176. package/dist/esm/dnd/dataTransfer.js.map +1 -1
  177. package/dist/esm/dnd/dnd.d.ts +5 -0
  178. package/dist/esm/dnd/dnd.d.ts.map +1 -1
  179. package/dist/esm/dnd/dnd.js +28 -13
  180. package/dist/esm/dnd/dnd.js.map +1 -1
  181. package/dist/esm/dnd/droptarget.d.ts +2 -0
  182. package/dist/esm/dnd/droptarget.d.ts.map +1 -1
  183. package/dist/esm/dnd/droptarget.js +3 -2
  184. package/dist/esm/dnd/droptarget.js.map +1 -1
  185. package/dist/esm/dnd/groupDragHandler.js +1 -1
  186. package/dist/esm/dnd/groupDragHandler.js.map +1 -1
  187. package/dist/esm/dnd/overlay.d.ts +4 -17
  188. package/dist/esm/dnd/overlay.d.ts.map +1 -1
  189. package/dist/esm/dnd/overlay.js.map +1 -1
  190. package/dist/esm/dockview/components/panel/content.d.ts +14 -1
  191. package/dist/esm/dockview/components/panel/content.d.ts.map +1 -1
  192. package/dist/esm/dockview/components/panel/content.js +84 -26
  193. package/dist/esm/dockview/components/panel/content.js.map +1 -1
  194. package/dist/esm/dockview/components/tab/defaultTab.js.map +1 -1
  195. package/dist/esm/dockview/components/tab/tab.js.map +1 -1
  196. package/dist/esm/dockview/components/titlebar/tabsContainer.js +2 -2
  197. package/dist/esm/dockview/components/titlebar/tabsContainer.js.map +1 -1
  198. package/dist/esm/dockview/components/titlebar/voidContainer.js.map +1 -1
  199. package/dist/esm/dockview/components/watermark/watermark.js.map +1 -1
  200. package/dist/esm/dockview/deserializer.d.ts +2 -2
  201. package/dist/esm/dockview/deserializer.d.ts.map +1 -1
  202. package/dist/esm/dockview/deserializer.js +6 -4
  203. package/dist/esm/dockview/deserializer.js.map +1 -1
  204. package/dist/esm/dockview/dockviewComponent.d.ts +21 -9
  205. package/dist/esm/dockview/dockviewComponent.d.ts.map +1 -1
  206. package/dist/esm/dockview/dockviewComponent.js +188 -42
  207. package/dist/esm/dockview/dockviewComponent.js.map +1 -1
  208. package/dist/esm/dockview/dockviewGroupPanel.d.ts.map +1 -1
  209. package/dist/esm/dockview/dockviewGroupPanel.js +4 -2
  210. package/dist/esm/dockview/dockviewGroupPanel.js.map +1 -1
  211. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +5 -4
  212. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts.map +1 -1
  213. package/dist/esm/dockview/dockviewGroupPanelModel.js +39 -45
  214. package/dist/esm/dockview/dockviewGroupPanelModel.js.map +1 -1
  215. package/dist/esm/dockview/dockviewPanel.d.ts +8 -1
  216. package/dist/esm/dockview/dockviewPanel.d.ts.map +1 -1
  217. package/dist/esm/dockview/dockviewPanel.js +19 -1
  218. package/dist/esm/dockview/dockviewPanel.js.map +1 -1
  219. package/dist/esm/dockview/dockviewPanelModel.js.map +1 -1
  220. package/dist/esm/dockview/dockviewPopoutGroupPanel.d.ts +16 -0
  221. package/dist/esm/dockview/dockviewPopoutGroupPanel.d.ts.map +1 -0
  222. package/dist/esm/dockview/dockviewPopoutGroupPanel.js +28 -0
  223. package/dist/esm/dockview/dockviewPopoutGroupPanel.js.map +1 -0
  224. package/dist/esm/dockview/options.d.ts +5 -0
  225. package/dist/esm/dockview/options.d.ts.map +1 -1
  226. package/dist/esm/dockview/options.js.map +1 -1
  227. package/dist/esm/dockview/types.d.ts +2 -0
  228. package/dist/esm/dockview/types.d.ts.map +1 -1
  229. package/dist/esm/dockview/types.js.map +1 -1
  230. package/dist/esm/dom.d.ts +12 -0
  231. package/dist/esm/dom.d.ts.map +1 -1
  232. package/dist/esm/dom.js +55 -0
  233. package/dist/esm/dom.js.map +1 -1
  234. package/dist/esm/events.js.map +1 -1
  235. package/dist/esm/gridview/baseComponentGridview.d.ts +10 -0
  236. package/dist/esm/gridview/baseComponentGridview.d.ts.map +1 -1
  237. package/dist/esm/gridview/baseComponentGridview.js +15 -0
  238. package/dist/esm/gridview/baseComponentGridview.js.map +1 -1
  239. package/dist/esm/gridview/basePanelView.js.map +1 -1
  240. package/dist/esm/gridview/branchNode.d.ts +2 -0
  241. package/dist/esm/gridview/branchNode.d.ts.map +1 -1
  242. package/dist/esm/gridview/branchNode.js +26 -5
  243. package/dist/esm/gridview/branchNode.js.map +1 -1
  244. package/dist/esm/gridview/gridview.d.ts +10 -3
  245. package/dist/esm/gridview/gridview.d.ts.map +1 -1
  246. package/dist/esm/gridview/gridview.js +80 -0
  247. package/dist/esm/gridview/gridview.js.map +1 -1
  248. package/dist/esm/gridview/gridviewComponent.js.map +1 -1
  249. package/dist/esm/gridview/gridviewPanel.js.map +1 -1
  250. package/dist/esm/gridview/leafNode.d.ts.map +1 -1
  251. package/dist/esm/gridview/leafNode.js +0 -1
  252. package/dist/esm/gridview/leafNode.js.map +1 -1
  253. package/dist/esm/index.d.ts +2 -1
  254. package/dist/esm/index.d.ts.map +1 -1
  255. package/dist/esm/index.js.map +1 -1
  256. package/dist/esm/lifecycle.d.ts +1 -0
  257. package/dist/esm/lifecycle.d.ts.map +1 -1
  258. package/dist/esm/lifecycle.js +8 -0
  259. package/dist/esm/lifecycle.js.map +1 -1
  260. package/dist/esm/math.js.map +1 -1
  261. package/dist/esm/overlayRenderContainer.d.ts +19 -0
  262. package/dist/esm/overlayRenderContainer.d.ts.map +1 -0
  263. package/dist/esm/overlayRenderContainer.js +125 -0
  264. package/dist/esm/overlayRenderContainer.js.map +1 -0
  265. package/dist/esm/panel/componentFactory.js.map +1 -1
  266. package/dist/esm/paneview/defaultPaneviewHeader.js.map +1 -1
  267. package/dist/esm/paneview/draggablePaneviewPanel.js.map +1 -1
  268. package/dist/esm/paneview/paneview.js.map +1 -1
  269. package/dist/esm/paneview/paneviewComponent.js.map +1 -1
  270. package/dist/esm/paneview/paneviewPanel.js.map +1 -1
  271. package/dist/esm/popoutWindow.d.ts +18 -0
  272. package/dist/esm/popoutWindow.d.ts.map +1 -0
  273. package/dist/esm/popoutWindow.js +88 -0
  274. package/dist/esm/popoutWindow.js.map +1 -0
  275. package/dist/esm/resizable.js +2 -2
  276. package/dist/esm/resizable.js.map +1 -1
  277. package/dist/esm/splitview/splitview.d.ts +5 -4
  278. package/dist/esm/splitview/splitview.d.ts.map +1 -1
  279. package/dist/esm/splitview/splitview.js +25 -8
  280. package/dist/esm/splitview/splitview.js.map +1 -1
  281. package/dist/esm/splitview/splitviewComponent.js.map +1 -1
  282. package/dist/esm/splitview/splitviewPanel.js.map +1 -1
  283. package/dist/esm/splitview/viewItem.js.map +1 -1
  284. package/dist/esm/types.d.ts +6 -0
  285. package/dist/esm/types.d.ts.map +1 -1
  286. package/dist/styles/dockview.css +33 -2
  287. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview-core
3
- * @version 1.8.5
3
+ * @version 1.9.0
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -236,6 +236,14 @@
236
236
  // noop
237
237
  },
238
238
  };
239
+ function from(func) {
240
+ return {
241
+ dispose: () => {
242
+ func();
243
+ },
244
+ };
245
+ }
246
+ Disposable.from = from;
239
247
  })(Disposable || (Disposable = {}));
240
248
  class CompositeDisposable {
241
249
  get isDisposed() {
@@ -420,6 +428,61 @@
420
428
  function quasiDefaultPrevented(event) {
421
429
  return event[QUASI_PREVENT_DEFAULT_KEY];
422
430
  }
431
+ function addStyles(document, styleSheetList) {
432
+ const styleSheets = Array.from(styleSheetList);
433
+ for (const styleSheet of styleSheets) {
434
+ if (styleSheet.href) {
435
+ const link = document.createElement('link');
436
+ link.href = styleSheet.href;
437
+ link.type = styleSheet.type;
438
+ link.rel = 'stylesheet';
439
+ document.head.appendChild(link);
440
+ }
441
+ let cssTexts = [];
442
+ try {
443
+ if (styleSheet.cssRules) {
444
+ cssTexts = Array.from(styleSheet.cssRules).map((rule) => rule.cssText);
445
+ }
446
+ }
447
+ catch (err) {
448
+ // security errors (lack of permissions), ignore
449
+ }
450
+ for (const rule of cssTexts) {
451
+ const style = document.createElement('style');
452
+ style.appendChild(document.createTextNode(rule));
453
+ document.head.appendChild(style);
454
+ }
455
+ }
456
+ }
457
+ function getDomNodePagePosition(domNode) {
458
+ const { left, top, width, height } = domNode.getBoundingClientRect();
459
+ return {
460
+ left: left + window.scrollX,
461
+ top: top + window.scrollY,
462
+ width: width,
463
+ height: height,
464
+ };
465
+ }
466
+ /**
467
+ * Check whether an element is in the DOM (including the Shadow DOM)
468
+ * @see https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/
469
+ */
470
+ function isInDocument(element) {
471
+ let currentElement = element;
472
+ while (currentElement === null || currentElement === void 0 ? void 0 : currentElement.parentNode) {
473
+ if (currentElement.parentNode === document) {
474
+ return true;
475
+ }
476
+ else if (currentElement.parentNode instanceof DocumentFragment) {
477
+ // handle shadow DOMs
478
+ currentElement = currentElement.parentNode.host;
479
+ }
480
+ else {
481
+ currentElement = currentElement.parentNode;
482
+ }
483
+ }
484
+ return false;
485
+ }
423
486
 
424
487
  function tail(arr) {
425
488
  if (arr.length === 0) {
@@ -617,6 +680,9 @@
617
680
  Sizing.Invisible = Invisible;
618
681
  })(exports.Sizing || (exports.Sizing = {}));
619
682
  class Splitview {
683
+ get contentSize() {
684
+ return this._contentSize;
685
+ }
620
686
  get size() {
621
687
  return this._size;
622
688
  }
@@ -682,7 +748,7 @@
682
748
  this.sashes = [];
683
749
  this._size = 0;
684
750
  this._orthogonalSize = 0;
685
- this.contentSize = 0;
751
+ this._contentSize = 0;
686
752
  this._proportions = undefined;
687
753
  this._startSnappingEnabled = true;
688
754
  this._endSnappingEnabled = true;
@@ -801,7 +867,7 @@
801
867
  );
802
868
  });
803
869
  // Initialize content size and proportions for first layout
804
- this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
870
+ this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
805
871
  this.saveProportions();
806
872
  }
807
873
  }
@@ -1075,7 +1141,7 @@
1075
1141
  this.addView(view, sizing, to);
1076
1142
  }
1077
1143
  layout(size, orthogonalSize) {
1078
- const previousSize = Math.max(this.size, this.contentSize);
1144
+ const previousSize = Math.max(this.size, this._contentSize);
1079
1145
  this.size = size;
1080
1146
  this.orthogonalSize = orthogonalSize;
1081
1147
  if (!this.proportions) {
@@ -1085,9 +1151,23 @@
1085
1151
  this.resize(this.viewItems.length - 1, size - previousSize, undefined, lowPriorityIndexes, highPriorityIndexes);
1086
1152
  }
1087
1153
  else {
1154
+ let total = 0;
1155
+ for (let i = 0; i < this.viewItems.length; i++) {
1156
+ const item = this.viewItems[i];
1157
+ const proportion = this.proportions[i];
1158
+ if (typeof proportion === 'number') {
1159
+ total += proportion;
1160
+ }
1161
+ else {
1162
+ size -= item.size;
1163
+ }
1164
+ }
1088
1165
  for (let i = 0; i < this.viewItems.length; i++) {
1089
1166
  const item = this.viewItems[i];
1090
- item.size = clamp(Math.round(this.proportions[i] * size), item.minimumSize, item.maximumSize);
1167
+ const proportion = this.proportions[i];
1168
+ if (typeof proportion === 'number' && total > 0) {
1169
+ item.size = clamp(Math.round((proportion * size) / total), item.minimumSize, item.maximumSize);
1170
+ }
1091
1171
  }
1092
1172
  }
1093
1173
  this.distributeEmptySpace();
@@ -1124,12 +1204,12 @@
1124
1204
  }
1125
1205
  }
1126
1206
  saveProportions() {
1127
- if (this.proportionalLayout && this.contentSize > 0) {
1128
- this._proportions = this.viewItems.map((i) => i.size / this.contentSize);
1207
+ if (this.proportionalLayout && this._contentSize > 0) {
1208
+ this._proportions = this.viewItems.map((i) => i.visible ? i.size / this._contentSize : undefined);
1129
1209
  }
1130
1210
  }
1131
1211
  layoutViews() {
1132
- this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
1212
+ this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
1133
1213
  let sum = 0;
1134
1214
  const x = [];
1135
1215
  this.updateSashEnablement();
@@ -1223,7 +1303,7 @@
1223
1303
  }
1224
1304
  else if (snappedAfter &&
1225
1305
  collapsesDown[index] &&
1226
- (position < this.contentSize || this.endSnappingEnabled)) {
1306
+ (position < this._contentSize || this.endSnappingEnabled)) {
1227
1307
  this.updateSash(sash, exports.SashState.MAXIMUM);
1228
1308
  }
1229
1309
  else {
@@ -1512,7 +1592,6 @@
1512
1592
  setVisible(visible) {
1513
1593
  if (this.view.setVisible) {
1514
1594
  this.view.setVisible(visible);
1515
- this._onDidChange.fire({});
1516
1595
  }
1517
1596
  }
1518
1597
  layout(size, orthogonalSize) {
@@ -1544,10 +1623,14 @@
1544
1623
  get minimumSize() {
1545
1624
  return this.children.length === 0
1546
1625
  ? 0
1547
- : Math.max(...this.children.map((c) => c.minimumOrthogonalSize));
1626
+ : Math.max(...this.children.map((c, index) => this.splitview.isViewVisible(index)
1627
+ ? c.minimumOrthogonalSize
1628
+ : 0));
1548
1629
  }
1549
1630
  get maximumSize() {
1550
- return Math.min(...this.children.map((c) => c.maximumOrthogonalSize));
1631
+ return Math.min(...this.children.map((c, index) => this.splitview.isViewVisible(index)
1632
+ ? c.maximumOrthogonalSize
1633
+ : Number.POSITIVE_INFINITY));
1551
1634
  }
1552
1635
  get minimumOrthogonalSize() {
1553
1636
  return this.splitview.minimumSize;
@@ -1605,6 +1688,8 @@
1605
1688
  this.children = [];
1606
1689
  this._onDidChange = new Emitter();
1607
1690
  this.onDidChange = this._onDidChange.event;
1691
+ this._onDidVisibilityChange = new Emitter();
1692
+ this.onDidVisibilityChange = this._onDidVisibilityChange.event;
1608
1693
  this._orthogonalSize = orthogonalSize;
1609
1694
  this._size = size;
1610
1695
  this.element = document.createElement('div');
@@ -1639,7 +1724,7 @@
1639
1724
  styles,
1640
1725
  });
1641
1726
  }
1642
- this.addDisposables(this._onDidChange, this.splitview.onDidSashEnd(() => {
1727
+ this.addDisposables(this._onDidChange, this._onDidVisibilityChange, this.splitview.onDidSashEnd(() => {
1643
1728
  this._onDidChange.fire({});
1644
1729
  }));
1645
1730
  this.setupChildrenEvents();
@@ -1662,7 +1747,15 @@
1662
1747
  if (this.splitview.isViewVisible(index) === visible) {
1663
1748
  return;
1664
1749
  }
1750
+ const wereAllChildrenHidden = this.splitview.contentSize === 0;
1665
1751
  this.splitview.setViewVisible(index, visible);
1752
+ const areAllChildrenHidden = this.splitview.contentSize === 0;
1753
+ // If all children are hidden then the parent should hide the entire splitview
1754
+ // If the entire splitview is hidden then the parent should show the splitview when a child is shown
1755
+ if ((visible && wereAllChildrenHidden) ||
1756
+ (!visible && areAllChildrenHidden)) {
1757
+ this._onDidVisibilityChange.fire(visible);
1758
+ }
1666
1759
  }
1667
1760
  moveChild(from, to) {
1668
1761
  if (from === to) {
@@ -1726,13 +1819,20 @@
1726
1819
  }
1727
1820
  setupChildrenEvents() {
1728
1821
  this._childrenDisposable.dispose();
1729
- this._childrenDisposable = exports.DockviewEvent.any(...this.children.map((c) => c.onDidChange))((e) => {
1822
+ this._childrenDisposable = new CompositeDisposable(exports.DockviewEvent.any(...this.children.map((c) => c.onDidChange))((e) => {
1730
1823
  /**
1731
1824
  * indicate a change has occured to allows any re-rendering but don't bubble
1732
1825
  * event because that was specific to this branch
1733
1826
  */
1734
1827
  this._onDidChange.fire({ size: e.orthogonalSize });
1735
- });
1828
+ }), ...this.children.map((c, i) => {
1829
+ if (c instanceof BranchNode) {
1830
+ return c.onDidVisibilityChange((visible) => {
1831
+ this.setChildVisible(i, visible);
1832
+ });
1833
+ }
1834
+ return Disposable.NONE;
1835
+ }));
1736
1836
  }
1737
1837
  dispose() {
1738
1838
  this._childrenDisposable.dispose();
@@ -1893,7 +1993,69 @@
1893
1993
  get maximumHeight() {
1894
1994
  return this.root.maximumHeight;
1895
1995
  }
1996
+ maximizedView() {
1997
+ var _a;
1998
+ return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.view;
1999
+ }
2000
+ hasMaximizedView() {
2001
+ return this._maximizedNode !== undefined;
2002
+ }
2003
+ maximizeView(view) {
2004
+ const location = getGridLocation(view.element);
2005
+ const [_, node] = this.getNode(location);
2006
+ if (!(node instanceof LeafNode)) {
2007
+ return;
2008
+ }
2009
+ if (this._maximizedNode === node) {
2010
+ return;
2011
+ }
2012
+ if (this.hasMaximizedView()) {
2013
+ this.exitMaximizedView();
2014
+ }
2015
+ function hideAllViewsBut(parent, exclude) {
2016
+ for (let i = 0; i < parent.children.length; i++) {
2017
+ const child = parent.children[i];
2018
+ if (child instanceof LeafNode) {
2019
+ if (child !== exclude) {
2020
+ parent.setChildVisible(i, false);
2021
+ }
2022
+ }
2023
+ else {
2024
+ hideAllViewsBut(child, exclude);
2025
+ }
2026
+ }
2027
+ }
2028
+ hideAllViewsBut(this.root, node);
2029
+ this._maximizedNode = node;
2030
+ this._onDidMaxmizedNodeChange.fire();
2031
+ }
2032
+ exitMaximizedView() {
2033
+ if (!this._maximizedNode) {
2034
+ return;
2035
+ }
2036
+ function showViewsInReverseOrder(parent) {
2037
+ for (let index = parent.children.length - 1; index >= 0; index--) {
2038
+ const child = parent.children[index];
2039
+ if (child instanceof LeafNode) {
2040
+ parent.setChildVisible(index, true);
2041
+ }
2042
+ else {
2043
+ showViewsInReverseOrder(child);
2044
+ }
2045
+ }
2046
+ }
2047
+ showViewsInReverseOrder(this.root);
2048
+ this._maximizedNode = undefined;
2049
+ this._onDidMaxmizedNodeChange.fire();
2050
+ }
1896
2051
  serialize() {
2052
+ if (this.hasMaximizedView()) {
2053
+ /**
2054
+ * do not persist maximized view state but we must first exit any maximized views
2055
+ * before serialization to ensure the correct dimensions are persisted
2056
+ */
2057
+ this.exitMaximizedView();
2058
+ }
1897
2059
  const root = serializeBranchNode(this.getView(), this.orientation);
1898
2060
  return {
1899
2061
  root,
@@ -1905,7 +2067,9 @@
1905
2067
  dispose() {
1906
2068
  this.disposable.dispose();
1907
2069
  this._onDidChange.dispose();
2070
+ this._onDidMaxmizedNodeChange.dispose();
1908
2071
  this.root.dispose();
2072
+ this._maximizedNode = undefined;
1909
2073
  this.element.remove();
1910
2074
  }
1911
2075
  clear() {
@@ -1946,6 +2110,7 @@
1946
2110
  const oldRoot = this._root;
1947
2111
  if (oldRoot) {
1948
2112
  oldRoot.dispose();
2113
+ this._maximizedNode = undefined;
1949
2114
  this.element.removeChild(oldRoot.element);
1950
2115
  }
1951
2116
  this._root = root;
@@ -2032,9 +2197,12 @@
2032
2197
  constructor(proportionalLayout, styles, orientation) {
2033
2198
  this.proportionalLayout = proportionalLayout;
2034
2199
  this.styles = styles;
2200
+ this._maximizedNode = undefined;
2035
2201
  this.disposable = new MutableDisposable();
2036
2202
  this._onDidChange = new Emitter();
2037
2203
  this.onDidChange = this._onDidChange.event;
2204
+ this._onDidMaxmizedNodeChange = new Emitter();
2205
+ this.onDidMaxmizedNodeChange = this._onDidMaxmizedNodeChange.event;
2038
2206
  this.element = document.createElement('div');
2039
2207
  this.element.className = 'grid-view';
2040
2208
  this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0);
@@ -2048,6 +2216,9 @@
2048
2216
  return parent.isChildVisible(index);
2049
2217
  }
2050
2218
  setViewVisible(location, visible) {
2219
+ if (this.hasMaximizedView()) {
2220
+ this.exitMaximizedView();
2221
+ }
2051
2222
  const [rest, index] = tail(location);
2052
2223
  const [, parent] = this.getNode(rest);
2053
2224
  if (!(parent instanceof BranchNode)) {
@@ -2056,6 +2227,9 @@
2056
2227
  parent.setChildVisible(index, visible);
2057
2228
  }
2058
2229
  moveView(parentLocation, from, to) {
2230
+ if (this.hasMaximizedView()) {
2231
+ this.exitMaximizedView();
2232
+ }
2059
2233
  const [, parent] = this.getNode(parentLocation);
2060
2234
  if (!(parent instanceof BranchNode)) {
2061
2235
  throw new Error('Invalid location');
@@ -2063,6 +2237,9 @@
2063
2237
  parent.moveChild(from, to);
2064
2238
  }
2065
2239
  addView(view, size, location) {
2240
+ if (this.hasMaximizedView()) {
2241
+ this.exitMaximizedView();
2242
+ }
2066
2243
  const [rest, index] = tail(location);
2067
2244
  const [pathToParent, parent] = this.getNode(rest);
2068
2245
  if (parent instanceof BranchNode) {
@@ -2095,6 +2272,9 @@
2095
2272
  return this.removeView(location, sizing);
2096
2273
  }
2097
2274
  removeView(location, sizing) {
2275
+ if (this.hasMaximizedView()) {
2276
+ this.exitMaximizedView();
2277
+ }
2098
2278
  const [rest, index] = tail(location);
2099
2279
  const [pathToParent, parent] = this.getNode(rest);
2100
2280
  if (!(parent instanceof BranchNode)) {
@@ -2832,6 +3012,24 @@
2832
3012
  moveToPrevious(options) {
2833
3013
  this.component.moveToPrevious(options);
2834
3014
  }
3015
+ maximizeGroup(panel) {
3016
+ this.component.maximizeGroup(panel.group);
3017
+ }
3018
+ hasMaximizedGroup() {
3019
+ return this.component.hasMaximizedGroup();
3020
+ }
3021
+ exitMaxmizedGroup() {
3022
+ this.component.exitMaximizedGroup();
3023
+ }
3024
+ get onDidMaxmizedGroupChange() {
3025
+ return this.component.onDidMaxmizedGroupChange;
3026
+ }
3027
+ /**
3028
+ * Add a popout group in a new Window
3029
+ */
3030
+ addPopoutGroup(item, options) {
3031
+ this.component.addPopoutGroup(item, options);
3032
+ }
2835
3033
  }
2836
3034
 
2837
3035
  class DragAndDropObserver extends CompositeDisposable {
@@ -2842,29 +3040,44 @@
2842
3040
  this.target = null;
2843
3041
  this.registerListeners();
2844
3042
  }
3043
+ onDragEnter(e) {
3044
+ this.target = e.target;
3045
+ this.callbacks.onDragEnter(e);
3046
+ }
3047
+ onDragOver(e) {
3048
+ e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)
3049
+ if (this.callbacks.onDragOver) {
3050
+ this.callbacks.onDragOver(e);
3051
+ }
3052
+ }
3053
+ onDragLeave(e) {
3054
+ if (this.target === e.target) {
3055
+ this.target = null;
3056
+ this.callbacks.onDragLeave(e);
3057
+ }
3058
+ }
3059
+ onDragEnd(e) {
3060
+ this.target = null;
3061
+ this.callbacks.onDragEnd(e);
3062
+ }
3063
+ onDrop(e) {
3064
+ this.callbacks.onDrop(e);
3065
+ }
2845
3066
  registerListeners() {
2846
3067
  this.addDisposables(addDisposableListener(this.element, 'dragenter', (e) => {
2847
- this.target = e.target;
2848
- this.callbacks.onDragEnter(e);
3068
+ this.onDragEnter(e);
2849
3069
  }, true));
2850
3070
  this.addDisposables(addDisposableListener(this.element, 'dragover', (e) => {
2851
- e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome)
2852
- if (this.callbacks.onDragOver) {
2853
- this.callbacks.onDragOver(e);
2854
- }
3071
+ this.onDragOver(e);
2855
3072
  }, true));
2856
3073
  this.addDisposables(addDisposableListener(this.element, 'dragleave', (e) => {
2857
- if (this.target === e.target) {
2858
- this.target = null;
2859
- this.callbacks.onDragLeave(e);
2860
- }
3074
+ this.onDragLeave(e);
2861
3075
  }));
2862
3076
  this.addDisposables(addDisposableListener(this.element, 'dragend', (e) => {
2863
- this.target = null;
2864
- this.callbacks.onDragEnd(e);
3077
+ this.onDragEnd(e);
2865
3078
  }));
2866
3079
  this.addDisposables(addDisposableListener(this.element, 'drop', (e) => {
2867
- this.callbacks.onDrop(e);
3080
+ this.onDrop(e);
2868
3081
  }));
2869
3082
  }
2870
3083
  }
@@ -2916,7 +3129,7 @@
2916
3129
  this.onDrop = this._onDrop.event;
2917
3130
  // use a set to take advantage of #<set>.has
2918
3131
  this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones);
2919
- this.addDisposables(this._onDrop, new DragAndDropObserver(this.element, {
3132
+ this.dnd = new DragAndDropObserver(this.element, {
2920
3133
  onDragEnter: () => undefined,
2921
3134
  onDragOver: (e) => {
2922
3135
  if (this._acceptedTargetZonesSet.size === 0) {
@@ -2983,7 +3196,8 @@
2983
3196
  this._onDrop.fire({ position: state, nativeEvent: e });
2984
3197
  }
2985
3198
  },
2986
- }));
3199
+ });
3200
+ this.addDisposables(this._onDrop, this.dnd);
2987
3201
  }
2988
3202
  setTargetZones(acceptedTargetZones) {
2989
3203
  this._acceptedTargetZonesSet = new Set(acceptedTargetZones);
@@ -3139,12 +3353,22 @@
3139
3353
  return 'center';
3140
3354
  }
3141
3355
 
3356
+ exports.DockviewDropTargets = void 0;
3357
+ (function (DockviewDropTargets) {
3358
+ DockviewDropTargets[DockviewDropTargets["Tab"] = 0] = "Tab";
3359
+ DockviewDropTargets[DockviewDropTargets["Panel"] = 1] = "Panel";
3360
+ DockviewDropTargets[DockviewDropTargets["TabContainer"] = 2] = "TabContainer";
3361
+ DockviewDropTargets[DockviewDropTargets["Edge"] = 3] = "Edge";
3362
+ })(exports.DockviewDropTargets || (exports.DockviewDropTargets = {}));
3363
+
3142
3364
  class ContentContainer extends CompositeDisposable {
3143
3365
  get element() {
3144
3366
  return this._element;
3145
3367
  }
3146
- constructor() {
3368
+ constructor(accessor, group) {
3147
3369
  super();
3370
+ this.accessor = accessor;
3371
+ this.group = group;
3148
3372
  this.disposable = new MutableDisposable();
3149
3373
  this._onDidFocus = new Emitter();
3150
3374
  this.onDidFocus = this._onDidFocus.event;
@@ -3154,11 +3378,38 @@
3154
3378
  this._element.className = 'content-container';
3155
3379
  this._element.tabIndex = -1;
3156
3380
  this.addDisposables(this._onDidFocus, this._onDidBlur);
3157
- // for hosted containers
3158
- // 1) register a drop target on the host
3159
- // 2) register window dragStart events to disable pointer events
3160
- // 3) register dragEnd events
3161
- // 4) register mouseMove events (if no buttons are present we take this as a dragEnd event)
3381
+ this.dropTarget = new Droptarget(this.element, {
3382
+ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3383
+ canDisplayOverlay: (event, position) => {
3384
+ if (this.group.locked === 'no-drop-target' ||
3385
+ (this.group.locked && position === 'center')) {
3386
+ return false;
3387
+ }
3388
+ const data = getPanelData();
3389
+ if (!data &&
3390
+ event.shiftKey &&
3391
+ this.group.location !== 'floating') {
3392
+ return false;
3393
+ }
3394
+ if (data && data.viewId === this.accessor.id) {
3395
+ if (data.groupId === this.group.id) {
3396
+ if (position === 'center') {
3397
+ // don't allow to drop on self for center position
3398
+ return false;
3399
+ }
3400
+ if (data.panelId === null) {
3401
+ // don't allow group move to drop anywhere on self
3402
+ return false;
3403
+ }
3404
+ }
3405
+ const groupHasOnePanelAndIsActiveDragElement = this.group.panels.length === 1 &&
3406
+ data.groupId === this.group.id;
3407
+ return !groupHasOnePanelAndIsActiveDragElement;
3408
+ }
3409
+ return this.group.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3410
+ },
3411
+ });
3412
+ this.addDisposables(this.dropTarget);
3162
3413
  }
3163
3414
  show() {
3164
3415
  this.element.style.display = '';
@@ -3166,23 +3417,43 @@
3166
3417
  hide() {
3167
3418
  this.element.style.display = 'none';
3168
3419
  }
3169
- openPanel(panel) {
3170
- var _a;
3171
- if (this.panel === panel) {
3172
- return;
3173
- }
3174
- if (this.panel) {
3175
- if ((_a = this.panel.view) === null || _a === void 0 ? void 0 : _a.content) {
3176
- this._element.removeChild(this.panel.view.content.element);
3177
- }
3178
- this.panel = undefined;
3420
+ renderPanel(panel, options = { asActive: true }) {
3421
+ const doRender = options.asActive ||
3422
+ (this.panel && this.group.isPanelActive(this.panel));
3423
+ if (this.panel &&
3424
+ this.panel.view.content.element.parentElement === this._element) {
3425
+ /**
3426
+ * If the currently attached panel is mounted directly to the content then remove it
3427
+ */
3428
+ this._element.removeChild(this.panel.view.content.element);
3179
3429
  }
3180
3430
  this.panel = panel;
3181
- const disposable = new CompositeDisposable();
3182
- if (this.panel.view) {
3183
- const _onDidFocus = this.panel.view.content.onDidFocus;
3184
- const _onDidBlur = this.panel.view.content.onDidBlur;
3185
- const focusTracker = trackFocus(this._element);
3431
+ let container;
3432
+ switch (panel.api.renderer) {
3433
+ case 'onlyWhenVisibile':
3434
+ this.accessor.overlayRenderContainer.detatch(panel);
3435
+ if (this.panel) {
3436
+ if (doRender) {
3437
+ this._element.appendChild(this.panel.view.content.element);
3438
+ }
3439
+ }
3440
+ container = this._element;
3441
+ break;
3442
+ case 'always':
3443
+ if (panel.view.content.element.parentElement === this._element) {
3444
+ this._element.removeChild(panel.view.content.element);
3445
+ }
3446
+ container = this.accessor.overlayRenderContainer.attach({
3447
+ panel,
3448
+ referenceContainer: this,
3449
+ });
3450
+ break;
3451
+ }
3452
+ if (doRender) {
3453
+ const _onDidFocus = panel.view.content.onDidFocus;
3454
+ const _onDidBlur = panel.view.content.onDidBlur;
3455
+ const focusTracker = trackFocus(container);
3456
+ const disposable = new CompositeDisposable();
3186
3457
  disposable.addDisposables(focusTracker, focusTracker.onDidFocus(() => this._onDidFocus.fire()), focusTracker.onDidBlur(() => this._onDidBlur.fire()));
3187
3458
  if (_onDidFocus) {
3188
3459
  disposable.addDisposables(_onDidFocus(() => this._onDidFocus.fire()));
@@ -3190,17 +3461,23 @@
3190
3461
  if (_onDidBlur) {
3191
3462
  disposable.addDisposables(_onDidBlur(() => this._onDidBlur.fire()));
3192
3463
  }
3193
- this._element.appendChild(this.panel.view.content.element);
3464
+ this.disposable.value = disposable;
3194
3465
  }
3195
- this.disposable.value = disposable;
3466
+ }
3467
+ openPanel(panel) {
3468
+ if (this.panel === panel) {
3469
+ return;
3470
+ }
3471
+ this.renderPanel(panel);
3196
3472
  }
3197
3473
  layout(_width, _height) {
3198
3474
  // noop
3199
3475
  }
3200
3476
  closePanel() {
3201
- var _a, _b, _c;
3202
- if ((_c = (_b = (_a = this.panel) === null || _a === void 0 ? void 0 : _a.view) === null || _b === void 0 ? void 0 : _b.content) === null || _c === void 0 ? void 0 : _c.element) {
3203
- this._element.removeChild(this.panel.view.content.element);
3477
+ if (this.panel) {
3478
+ if (this.accessor.options.defaultRenderer === 'onlyWhenVisibile') {
3479
+ this._element.removeChild(this.panel.view.content.element);
3480
+ }
3204
3481
  this.panel = undefined;
3205
3482
  }
3206
3483
  }
@@ -3210,14 +3487,6 @@
3210
3487
  }
3211
3488
  }
3212
3489
 
3213
- exports.DockviewDropTargets = void 0;
3214
- (function (DockviewDropTargets) {
3215
- DockviewDropTargets[DockviewDropTargets["Tab"] = 0] = "Tab";
3216
- DockviewDropTargets[DockviewDropTargets["Panel"] = 1] = "Panel";
3217
- DockviewDropTargets[DockviewDropTargets["TabContainer"] = 2] = "TabContainer";
3218
- DockviewDropTargets[DockviewDropTargets["Edge"] = 3] = "Edge";
3219
- })(exports.DockviewDropTargets || (exports.DockviewDropTargets = {}));
3220
-
3221
3490
  class DragHandler extends CompositeDisposable {
3222
3491
  constructor(el) {
3223
3492
  super();
@@ -3392,7 +3661,7 @@
3392
3661
  }, true));
3393
3662
  }
3394
3663
  isCancelled(_event) {
3395
- if (this.group.api.isFloating && !_event.shiftKey) {
3664
+ if (this.group.api.location === 'floating' && !_event.shiftKey) {
3396
3665
  return true;
3397
3666
  }
3398
3667
  return false;
@@ -3594,7 +3863,7 @@
3594
3863
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3595
3864
  if (isFloatingGroupsEnabled &&
3596
3865
  event.shiftKey &&
3597
- !this.group.api.isFloating) {
3866
+ this.group.api.location !== 'floating') {
3598
3867
  event.preventDefault();
3599
3868
  const { top, left } = this.element.getBoundingClientRect();
3600
3869
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
@@ -3659,7 +3928,7 @@
3659
3928
  }), tab.onChanged((event) => {
3660
3929
  var _a;
3661
3930
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3662
- const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
3931
+ const isFloatingWithOnePanel = this.group.api.location === 'floating' && this.size === 1;
3663
3932
  if (isFloatingGroupsEnabled &&
3664
3933
  !isFloatingWithOnePanel &&
3665
3934
  event.shiftKey) {
@@ -3742,15 +4011,37 @@
3742
4011
  }
3743
4012
  return isAncestor(document.activeElement, this.contentContainer.element);
3744
4013
  }
3745
- get isFloating() {
3746
- return this._isFloating;
3747
- }
3748
- set isFloating(value) {
3749
- this._isFloating = value;
3750
- this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']);
3751
- toggleClass(this.container, 'dv-groupview-floating', value);
3752
- this.groupPanel.api._onDidFloatingStateChange.fire({
3753
- isFloating: this.isFloating,
4014
+ get location() {
4015
+ return this._location;
4016
+ }
4017
+ set location(value) {
4018
+ this._location = value;
4019
+ toggleClass(this.container, 'dv-groupview-floating', false);
4020
+ toggleClass(this.container, 'dv-groupview-popout', false);
4021
+ switch (value) {
4022
+ case 'grid':
4023
+ this.contentContainer.dropTarget.setTargetZones([
4024
+ 'top',
4025
+ 'bottom',
4026
+ 'left',
4027
+ 'right',
4028
+ 'center',
4029
+ ]);
4030
+ break;
4031
+ case 'floating':
4032
+ this.contentContainer.dropTarget.setTargetZones(['center']);
4033
+ this.contentContainer.dropTarget.setTargetZones(value
4034
+ ? ['center']
4035
+ : ['top', 'bottom', 'left', 'right', 'center']);
4036
+ toggleClass(this.container, 'dv-groupview-floating', true);
4037
+ break;
4038
+ case 'popout':
4039
+ this.contentContainer.dropTarget.setTargetZones(['center']);
4040
+ toggleClass(this.container, 'dv-groupview-popout', true);
4041
+ break;
4042
+ }
4043
+ this.groupPanel.api._onDidLocationChange.fire({
4044
+ location: this.location,
3754
4045
  });
3755
4046
  }
3756
4047
  constructor(container, accessor, id, options, groupPanel) {
@@ -3763,7 +4054,7 @@
3763
4054
  this.groupPanel = groupPanel;
3764
4055
  this._isGroupActive = false;
3765
4056
  this._locked = false;
3766
- this._isFloating = false;
4057
+ this._location = 'grid';
3767
4058
  this.mostRecentlyUsed = [];
3768
4059
  this._onDidChange = new Emitter();
3769
4060
  this.onDidChange = this._onDidChange.event;
@@ -3786,35 +4077,7 @@
3786
4077
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
3787
4078
  toggleClass(this.container, 'groupview', true);
3788
4079
  this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
3789
- this.contentContainer = new ContentContainer();
3790
- this.dropTarget = new Droptarget(this.contentContainer.element, {
3791
- acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3792
- canDisplayOverlay: (event, position) => {
3793
- if (this.locked === 'no-drop-target' ||
3794
- (this.locked && position === 'center')) {
3795
- return false;
3796
- }
3797
- const data = getPanelData();
3798
- if (!data && event.shiftKey && !this.isFloating) {
3799
- return false;
3800
- }
3801
- if (data && data.viewId === this.accessor.id) {
3802
- if (data.groupId === this.id) {
3803
- if (position === 'center') {
3804
- // don't allow to drop on self for center position
3805
- return false;
3806
- }
3807
- if (data.panelId === null) {
3808
- // don't allow group move to drop anywhere on self
3809
- return false;
3810
- }
3811
- }
3812
- const groupHasOnePanelAndIsActiveDragElement = this._panels.length === 1 && data.groupId === this.id;
3813
- return !groupHasOnePanelAndIsActiveDragElement;
3814
- }
3815
- return this.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3816
- },
3817
- });
4080
+ this.contentContainer = new ContentContainer(this.accessor, this);
3818
4081
  container.append(this.tabsContainer.element, this.contentContainer.element);
3819
4082
  this.header.hidden = !!options.hideHeader;
3820
4083
  this.locked = (_a = options.locked) !== null && _a !== void 0 ? _a : false;
@@ -3828,7 +4091,7 @@
3828
4091
  this.accessor.doSetGroupActive(this.groupPanel, true);
3829
4092
  }), this.contentContainer.onDidBlur(() => {
3830
4093
  // noop
3831
- }), this.dropTarget.onDrop((event) => {
4094
+ }), this.contentContainer.dropTarget.onDrop((event) => {
3832
4095
  this.handleDropEvent(event.nativeEvent, event.position);
3833
4096
  }), this._onMove, this._onDidChange, this._onDidDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange);
3834
4097
  }
@@ -3877,6 +4140,9 @@
3877
4140
  this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
3878
4141
  }
3879
4142
  }
4143
+ rerender(panel) {
4144
+ this.contentContainer.renderPanel(panel, { asActive: false });
4145
+ }
3880
4146
  indexOf(panel) {
3881
4147
  return this.tabsContainer.indexOf(panel.id);
3882
4148
  }
@@ -4068,12 +4334,12 @@
4068
4334
  doAddPanel(panel, index = this.panels.length, skipSetActive = false) {
4069
4335
  const existingPanel = this._panels.indexOf(panel);
4070
4336
  const hasExistingPanel = existingPanel > -1;
4337
+ this.tabsContainer.show();
4338
+ this.contentContainer.show();
4071
4339
  this.tabsContainer.openPanel(panel, index);
4072
4340
  if (!skipSetActive) {
4073
4341
  this.contentContainer.openPanel(panel);
4074
4342
  }
4075
- this.tabsContainer.show();
4076
- this.contentContainer.show();
4077
4343
  if (hasExistingPanel) {
4078
4344
  // TODO - need to ensure ordering hasn't changed and if it has need to re-order this.panels
4079
4345
  return;
@@ -4189,7 +4455,6 @@
4189
4455
  for (const panel of this.panels) {
4190
4456
  panel.dispose();
4191
4457
  }
4192
- this.dropTarget.dispose();
4193
4458
  this.tabsContainer.dispose();
4194
4459
  this.contentContainer.dispose();
4195
4460
  }
@@ -4228,7 +4493,7 @@
4228
4493
  if (this.disableResizing) {
4229
4494
  return;
4230
4495
  }
4231
- if (!document.body.contains(this._element)) {
4496
+ if (!isInDocument(this._element)) {
4232
4497
  /**
4233
4498
  * since the event is dispatched through requestAnimationFrame there is a small chance
4234
4499
  * the component is no longer attached to the DOM, if that is the case the dimensions
@@ -4320,6 +4585,21 @@
4320
4585
  isVisible(panel) {
4321
4586
  return this.gridview.isViewVisible(getGridLocation(panel.element));
4322
4587
  }
4588
+ maximizeGroup(panel) {
4589
+ this.gridview.maximizeView(panel);
4590
+ }
4591
+ isMaximizedGroup(panel) {
4592
+ return this.gridview.maximizedView() === panel;
4593
+ }
4594
+ exitMaximizedGroup() {
4595
+ this.gridview.exitMaximizedView();
4596
+ }
4597
+ hasMaximizedGroup() {
4598
+ return this.gridview.hasMaximizedView();
4599
+ }
4600
+ get onDidMaxmizedGroupChange() {
4601
+ return this.gridview.onDidMaxmizedNodeChange;
4602
+ }
4323
4603
  doAddGroup(group, location = [0], size) {
4324
4604
  this.gridview.addView(group, size !== null && size !== void 0 ? size : exports.Sizing.Distribute, location);
4325
4605
  this._onDidAddGroup.fire(group);
@@ -5096,32 +5376,63 @@
5096
5376
  }
5097
5377
  }
5098
5378
 
5379
+ // TODO find a better way to initialize and avoid needing null checks
5380
+ const NOT_INITIALIZED_MESSAGE = 'DockviewGroupPanelApiImpl not initialized';
5099
5381
  class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
5100
- get isFloating() {
5382
+ get location() {
5101
5383
  if (!this._group) {
5102
- throw new Error(`DockviewGroupPanelApiImpl not initialized`);
5384
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5103
5385
  }
5104
- return this._group.model.isFloating;
5386
+ return this._group.model.location;
5105
5387
  }
5106
5388
  constructor(id, accessor) {
5107
5389
  super(id);
5108
5390
  this.accessor = accessor;
5109
- this._onDidFloatingStateChange = new Emitter();
5110
- this.onDidFloatingStateChange = this._onDidFloatingStateChange.event;
5111
- this.addDisposables(this._onDidFloatingStateChange);
5391
+ this._onDidLocationChange = new Emitter();
5392
+ this.onDidLocationChange = this._onDidLocationChange.event;
5393
+ this.addDisposables(this._onDidLocationChange);
5112
5394
  }
5113
5395
  moveTo(options) {
5114
- var _a;
5396
+ var _a, _b, _c;
5397
+ if (!this._group) {
5398
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5399
+ }
5400
+ const group = (_a = options.group) !== null && _a !== void 0 ? _a : this.accessor.addGroup({
5401
+ direction: positionToDirection((_b = options.position) !== null && _b !== void 0 ? _b : 'right'),
5402
+ });
5403
+ this.accessor.moveGroupOrPanel(group, this._group.id, undefined, options.group ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center' : 'center');
5404
+ }
5405
+ maximize() {
5406
+ if (!this._group) {
5407
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5408
+ }
5409
+ if (this.location !== 'grid') {
5410
+ // only grid groups can be maximized
5411
+ return;
5412
+ }
5413
+ this.accessor.maximizeGroup(this._group);
5414
+ }
5415
+ isMaximized() {
5115
5416
  if (!this._group) {
5116
- throw new Error(`DockviewGroupPanelApiImpl not initialized`);
5417
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5418
+ }
5419
+ return this.accessor.isMaximizedGroup(this._group);
5420
+ }
5421
+ exitMaximized() {
5422
+ if (!this._group) {
5423
+ throw new Error(NOT_INITIALIZED_MESSAGE);
5424
+ }
5425
+ if (this.isMaximized()) {
5426
+ this.accessor.exitMaximizedGroup();
5117
5427
  }
5118
- this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center');
5119
5428
  }
5120
5429
  initialize(group) {
5121
5430
  this._group = group;
5122
5431
  }
5123
5432
  }
5124
5433
 
5434
+ const MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH = 100;
5435
+ const MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT = 100;
5125
5436
  class DockviewGroupPanel extends GridviewPanel {
5126
5437
  get panels() {
5127
5438
  return this._model.panels;
@@ -5146,8 +5457,8 @@
5146
5457
  }
5147
5458
  constructor(accessor, id, options) {
5148
5459
  super(id, 'groupview_default', {
5149
- minimumHeight: 100,
5150
- minimumWidth: 100,
5460
+ minimumHeight: MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT,
5461
+ minimumWidth: MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH,
5151
5462
  }, new DockviewGroupPanelApiImpl(id, accessor));
5152
5463
  this.api.initialize(this); // cannot use 'this' after after 'super' call
5153
5464
  this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this);
@@ -5201,8 +5512,10 @@
5201
5512
  return this.panel.title;
5202
5513
  }
5203
5514
  get isGroupActive() {
5204
- var _a;
5205
- return !!((_a = this.group) === null || _a === void 0 ? void 0 : _a.isActive);
5515
+ return this.group.isActive;
5516
+ }
5517
+ get renderer() {
5518
+ return this.panel.renderer;
5206
5519
  }
5207
5520
  set group(value) {
5208
5521
  const isOldGroupActive = this.isGroupActive;
@@ -5230,10 +5543,12 @@
5230
5543
  this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
5231
5544
  this._onDidGroupChange = new Emitter();
5232
5545
  this.onDidGroupChange = this._onDidGroupChange.event;
5546
+ this._onDidRendererChange = new Emitter();
5547
+ this.onDidRendererChange = this._onDidRendererChange.event;
5233
5548
  this.disposable = new MutableDisposable();
5234
5549
  this.initialize(panel);
5235
5550
  this._group = group;
5236
- this.addDisposables(this.disposable, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5551
+ this.addDisposables(this.disposable, this._onDidRendererChange, this._onDidTitleChange, this._onDidGroupChange, this._onDidActiveGroupChange);
5237
5552
  }
5238
5553
  moveTo(options) {
5239
5554
  var _a;
@@ -5242,9 +5557,21 @@
5242
5557
  setTitle(title) {
5243
5558
  this.panel.setTitle(title);
5244
5559
  }
5560
+ setRenderer(renderer) {
5561
+ this.panel.setRenderer(renderer);
5562
+ }
5245
5563
  close() {
5246
5564
  this.group.model.closePanel(this.panel);
5247
5565
  }
5566
+ maximize() {
5567
+ this.group.api.maximize();
5568
+ }
5569
+ isMaximized() {
5570
+ return this.group.api.isMaximized();
5571
+ }
5572
+ exitMaximized() {
5573
+ this.group.api.exitMaximized();
5574
+ }
5248
5575
  }
5249
5576
 
5250
5577
  class DockviewPanel extends CompositeDisposable {
@@ -5257,11 +5584,17 @@
5257
5584
  get group() {
5258
5585
  return this._group;
5259
5586
  }
5260
- constructor(id, accessor, containerApi, group, view) {
5587
+ get renderer() {
5588
+ var _a;
5589
+ return (_a = this._renderer) !== null && _a !== void 0 ? _a : this.accessor.renderer;
5590
+ }
5591
+ constructor(id, accessor, containerApi, group, view, options) {
5261
5592
  super();
5262
5593
  this.id = id;
5594
+ this.accessor = accessor;
5263
5595
  this.containerApi = containerApi;
5264
5596
  this.view = view;
5597
+ this._renderer = options.renderer;
5265
5598
  this._group = group;
5266
5599
  this.api = new DockviewPanelApiImpl(this, this._group, accessor);
5267
5600
  this.addDisposables(this.api.onActiveChange(() => {
@@ -5270,6 +5603,8 @@
5270
5603
  // forward the resize event to the group since if you want to resize a panel
5271
5604
  // you are actually just resizing the panels parent which is the group
5272
5605
  this.group.api.setSize(event);
5606
+ }), this.api.onDidRendererChange((event) => {
5607
+ this.group.model.rerender(this);
5273
5608
  }));
5274
5609
  }
5275
5610
  init(params) {
@@ -5289,6 +5624,7 @@
5289
5624
  ? this._params
5290
5625
  : undefined,
5291
5626
  title: this.title,
5627
+ renderer: this._renderer,
5292
5628
  };
5293
5629
  }
5294
5630
  setTitle(title) {
@@ -5304,6 +5640,15 @@
5304
5640
  this.api._onDidTitleChange.fire({ title });
5305
5641
  }
5306
5642
  }
5643
+ setRenderer(renderer) {
5644
+ const didChange = renderer !== this.renderer;
5645
+ if (didChange) {
5646
+ this._renderer = renderer;
5647
+ this.api._onDidRendererChange.fire({
5648
+ renderer: renderer,
5649
+ });
5650
+ }
5651
+ }
5307
5652
  update(event) {
5308
5653
  var _a;
5309
5654
  // merge the new parameters with the existing parameters
@@ -5522,8 +5867,8 @@
5522
5867
  }
5523
5868
 
5524
5869
  class DefaultDockviewDeserialzier {
5525
- constructor(layout) {
5526
- this.layout = layout;
5870
+ constructor(accessor) {
5871
+ this.accessor = accessor;
5527
5872
  }
5528
5873
  fromJSON(panelData, group) {
5529
5874
  var _a, _b;
@@ -5537,8 +5882,10 @@
5537
5882
  const tabComponent = viewData
5538
5883
  ? (_b = viewData.tab) === null || _b === void 0 ? void 0 : _b.id
5539
5884
  : panelData.tabComponent;
5540
- const view = new DockviewPanelModel(this.layout, panelId, contentComponent, tabComponent);
5541
- const panel = new DockviewPanel(panelId, this.layout, new DockviewApi(this.layout), group, view);
5885
+ const view = new DockviewPanelModel(this.accessor, panelId, contentComponent, tabComponent);
5886
+ const panel = new DockviewPanel(panelId, this.accessor, new DockviewApi(this.accessor), group, view, {
5887
+ renderer: panelData.renderer,
5888
+ });
5542
5889
  panel.init({
5543
5890
  title: title !== null && title !== void 0 ? title : panelId,
5544
5891
  params: params !== null && params !== void 0 ? params : {},
@@ -5918,7 +6265,261 @@
5918
6265
  }
5919
6266
  }
5920
6267
 
6268
+ class PopoutWindow extends CompositeDisposable {
6269
+ constructor(id, className, options) {
6270
+ super();
6271
+ this.id = id;
6272
+ this.className = className;
6273
+ this.options = options;
6274
+ this._onDidClose = new Emitter();
6275
+ this.onDidClose = this._onDidClose.event;
6276
+ this._window = null;
6277
+ this.addDisposables(this._onDidClose, {
6278
+ dispose: () => {
6279
+ this.close();
6280
+ },
6281
+ });
6282
+ }
6283
+ dimensions() {
6284
+ if (!this._window) {
6285
+ return null;
6286
+ }
6287
+ const left = this._window.value.screenX;
6288
+ const top = this._window.value.screenY;
6289
+ const width = this._window.value.innerWidth;
6290
+ const height = this._window.value.innerHeight;
6291
+ return { top, left, width, height };
6292
+ }
6293
+ close() {
6294
+ if (this._window) {
6295
+ this._window.disposable.dispose();
6296
+ this._window.value.close();
6297
+ this._window = null;
6298
+ }
6299
+ }
6300
+ open(content) {
6301
+ if (this._window) {
6302
+ throw new Error('instance of popout window is already open');
6303
+ }
6304
+ const url = `${this.options.url}`;
6305
+ const features = Object.entries({
6306
+ top: this.options.top,
6307
+ left: this.options.left,
6308
+ width: this.options.width,
6309
+ height: this.options.height,
6310
+ })
6311
+ .map(([key, value]) => `${key}=${value}`)
6312
+ .join(',');
6313
+ // https://developer.mozilla.org/en-US/docs/Web/API/Window/open
6314
+ const externalWindow = window.open(url, this.id, features);
6315
+ if (!externalWindow) {
6316
+ return;
6317
+ }
6318
+ const disposable = new CompositeDisposable();
6319
+ this._window = { value: externalWindow, disposable };
6320
+ const cleanUp = () => {
6321
+ this._onDidClose.fire();
6322
+ this._window = null;
6323
+ };
6324
+ // prevent any default content from loading
6325
+ // externalWindow.document.body.replaceWith(document.createElement('div'));
6326
+ disposable.addDisposables(addDisposableWindowListener(window, 'beforeunload', () => {
6327
+ cleanUp();
6328
+ this.close();
6329
+ }));
6330
+ externalWindow.addEventListener('load', () => {
6331
+ const externalDocument = externalWindow.document;
6332
+ externalDocument.title = document.title;
6333
+ const div = document.createElement('div');
6334
+ div.classList.add('dv-popout-window');
6335
+ div.style.position = 'absolute';
6336
+ div.style.width = '100%';
6337
+ div.style.height = '100%';
6338
+ div.style.top = '0px';
6339
+ div.style.left = '0px';
6340
+ div.classList.add(this.className);
6341
+ div.appendChild(content);
6342
+ externalDocument.body.replaceChildren(div);
6343
+ externalDocument.body.classList.add(this.className);
6344
+ addStyles(externalDocument, window.document.styleSheets);
6345
+ externalWindow.addEventListener('beforeunload', () => {
6346
+ // TODO: indicate external window is closing
6347
+ cleanUp();
6348
+ });
6349
+ });
6350
+ }
6351
+ }
6352
+
6353
+ class DockviewPopoutGroupPanel extends CompositeDisposable {
6354
+ constructor(id, group, options) {
6355
+ var _a;
6356
+ super();
6357
+ this.id = id;
6358
+ this.group = group;
6359
+ this.options = options;
6360
+ this.window = new PopoutWindow(id, (_a = options.className) !== null && _a !== void 0 ? _a : '', {
6361
+ url: this.options.popoutUrl,
6362
+ left: this.options.box.left,
6363
+ top: this.options.box.top,
6364
+ width: this.options.box.width,
6365
+ height: this.options.box.height,
6366
+ });
6367
+ group.model.location = 'popout';
6368
+ this.addDisposables(this.window, {
6369
+ dispose: () => {
6370
+ group.model.location = 'grid';
6371
+ },
6372
+ }, this.window.onDidClose(() => {
6373
+ this.dispose();
6374
+ }));
6375
+ this.window.open(group.element);
6376
+ }
6377
+ }
6378
+
5921
6379
  const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
6380
+ const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100 };
6381
+
6382
+ function createFocusableElement() {
6383
+ const element = document.createElement('div');
6384
+ element.tabIndex = -1;
6385
+ return element;
6386
+ }
6387
+ class OverlayRenderContainer extends CompositeDisposable {
6388
+ constructor(element) {
6389
+ super();
6390
+ this.element = element;
6391
+ this.map = {};
6392
+ this.addDisposables(Disposable.from(() => {
6393
+ for (const value of Object.values(this.map)) {
6394
+ value.disposable.dispose();
6395
+ value.destroy.dispose();
6396
+ }
6397
+ }));
6398
+ }
6399
+ detatch(panel) {
6400
+ if (this.map[panel.api.id]) {
6401
+ const { disposable, destroy } = this.map[panel.api.id];
6402
+ disposable.dispose();
6403
+ destroy.dispose();
6404
+ delete this.map[panel.api.id];
6405
+ return true;
6406
+ }
6407
+ return false;
6408
+ }
6409
+ attach(options) {
6410
+ const { panel, referenceContainer } = options;
6411
+ if (!this.map[panel.api.id]) {
6412
+ const element = createFocusableElement();
6413
+ element.className = 'dv-render-overlay';
6414
+ this.map[panel.api.id] = {
6415
+ panel,
6416
+ disposable: Disposable.NONE,
6417
+ destroy: Disposable.NONE,
6418
+ element,
6419
+ };
6420
+ }
6421
+ const focusContainer = this.map[panel.api.id].element;
6422
+ if (panel.view.content.element.parentElement !== focusContainer) {
6423
+ focusContainer.appendChild(panel.view.content.element);
6424
+ }
6425
+ if (focusContainer.parentElement !== this.element) {
6426
+ this.element.appendChild(focusContainer);
6427
+ }
6428
+ const resize = () => {
6429
+ // TODO propagate position to avoid getDomNodePagePosition calls, possible performance bottleneck?
6430
+ const box = getDomNodePagePosition(referenceContainer.element);
6431
+ const box2 = getDomNodePagePosition(this.element);
6432
+ focusContainer.style.left = `${box.left - box2.left}px`;
6433
+ focusContainer.style.top = `${box.top - box2.top}px`;
6434
+ focusContainer.style.width = `${box.width}px`;
6435
+ focusContainer.style.height = `${box.height}px`;
6436
+ toggleClass(focusContainer, 'dv-render-overlay-float', panel.group.api.location === 'floating');
6437
+ };
6438
+ const visibilityChanged = () => {
6439
+ if (panel.api.isVisible) {
6440
+ resize();
6441
+ }
6442
+ focusContainer.style.display = panel.api.isVisible ? '' : 'none';
6443
+ };
6444
+ const disposable = new CompositeDisposable(
6445
+ /**
6446
+ * since container is positioned absoutely we must explicitly forward
6447
+ * the dnd events for the expect behaviours to continue to occur in terms of dnd
6448
+ *
6449
+ * the dnd observer does not need to be conditional on whether the panel is visible since
6450
+ * non-visible panels are 'display: none' and in such case the dnd observer will not fire.
6451
+ */
6452
+ new DragAndDropObserver(focusContainer, {
6453
+ onDragEnd: (e) => {
6454
+ referenceContainer.dropTarget.dnd.onDragEnd(e);
6455
+ },
6456
+ onDragEnter: (e) => {
6457
+ referenceContainer.dropTarget.dnd.onDragEnter(e);
6458
+ },
6459
+ onDragLeave: (e) => {
6460
+ referenceContainer.dropTarget.dnd.onDragLeave(e);
6461
+ },
6462
+ onDrop: (e) => {
6463
+ referenceContainer.dropTarget.dnd.onDrop(e);
6464
+ },
6465
+ onDragOver: (e) => {
6466
+ referenceContainer.dropTarget.dnd.onDragOver(e);
6467
+ },
6468
+ }), panel.api.onDidVisibilityChange((event) => {
6469
+ /**
6470
+ * Control the visibility of the content, however even when not visible (display: none)
6471
+ * the content is still maintained within the DOM hence DOM specific attributes
6472
+ * such as scroll position are maintained when next made visible.
6473
+ */
6474
+ visibilityChanged();
6475
+ }), panel.api.onDidDimensionsChange(() => {
6476
+ if (!panel.api.isVisible) {
6477
+ return;
6478
+ }
6479
+ resize();
6480
+ }));
6481
+ this.map[panel.api.id].destroy = Disposable.from(() => {
6482
+ focusContainer.removeChild(panel.view.content.element);
6483
+ this.element.removeChild(focusContainer);
6484
+ });
6485
+ queueMicrotask(() => {
6486
+ if (this.isDisposed) {
6487
+ return;
6488
+ }
6489
+ /**
6490
+ * wait until everything has finished in the current stack-frame call before
6491
+ * calling the first resize as other size-altering events may still occur before
6492
+ * the end of the stack-frame.
6493
+ */
6494
+ visibilityChanged();
6495
+ });
6496
+ // dispose of logic asoccciated with previous reference-container
6497
+ this.map[panel.api.id].disposable.dispose();
6498
+ // and reset the disposable to the active reference-container
6499
+ this.map[panel.api.id].disposable = disposable;
6500
+ return focusContainer;
6501
+ }
6502
+ }
6503
+
6504
+ function getTheme(element) {
6505
+ function toClassList(element) {
6506
+ const list = [];
6507
+ for (let i = 0; i < element.classList.length; i++) {
6508
+ list.push(element.classList.item(i));
6509
+ }
6510
+ return list;
6511
+ }
6512
+ let theme = undefined;
6513
+ let parent = element;
6514
+ while (parent !== null) {
6515
+ theme = toClassList(parent).find((cls) => cls.startsWith('dockview-theme-'));
6516
+ if (typeof theme === 'string') {
6517
+ break;
6518
+ }
6519
+ parent = parent.parentElement;
6520
+ }
6521
+ return theme;
6522
+ }
5922
6523
  class DockviewComponent extends BaseGrid {
5923
6524
  get orientation() {
5924
6525
  return this.gridview.orientation;
@@ -5939,6 +6540,10 @@
5939
6540
  }
5940
6541
  return activeGroup.activePanel;
5941
6542
  }
6543
+ get renderer() {
6544
+ var _a;
6545
+ return (_a = this.options.defaultRenderer) !== null && _a !== void 0 ? _a : 'onlyWhenVisibile';
6546
+ }
5942
6547
  constructor(options) {
5943
6548
  var _a;
5944
6549
  super({
@@ -5965,12 +6570,27 @@
5965
6570
  this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
5966
6571
  this._onDidActivePanelChange = new Emitter();
5967
6572
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5968
- this.floatingGroups = [];
6573
+ this._floatingGroups = [];
6574
+ this._popoutGroups = [];
6575
+ const gready = document.createElement('div');
6576
+ gready.className = 'dv-overlay-render-container';
6577
+ this.gridview.element.appendChild(gready);
6578
+ this.overlayRenderContainer = new OverlayRenderContainer(gready);
5969
6579
  toggleClass(this.gridview.element, 'dv-dockview', true);
5970
- this.addDisposables(this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
6580
+ toggleClass(this.element, 'dv-debug', !!options.debug);
6581
+ this.addDisposables(this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5971
6582
  this.updateWatermark();
5972
6583
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
5973
6584
  this._bufferOnDidLayoutChange.fire();
6585
+ }), Disposable.from(() => {
6586
+ // iterate over a copy of the array since .dispose() mutates the original array
6587
+ for (const group of [...this._floatingGroups]) {
6588
+ group.dispose();
6589
+ }
6590
+ // iterate over a copy of the array since .dispose() mutates the original array
6591
+ for (const group of [...this._popoutGroups]) {
6592
+ group.dispose();
6593
+ }
5974
6594
  }));
5975
6595
  this._options = options;
5976
6596
  if (!this.options.components) {
@@ -6040,6 +6660,55 @@
6040
6660
  this._api = new DockviewApi(this);
6041
6661
  this.updateWatermark();
6042
6662
  }
6663
+ addPopoutGroup(item, options) {
6664
+ var _a;
6665
+ let group;
6666
+ let box = options === null || options === void 0 ? void 0 : options.position;
6667
+ if (item instanceof DockviewPanel) {
6668
+ group = this.createGroup();
6669
+ this.removePanel(item, {
6670
+ removeEmptyGroup: true,
6671
+ skipDispose: true,
6672
+ });
6673
+ group.model.openPanel(item);
6674
+ if (!box) {
6675
+ box = this.element.getBoundingClientRect();
6676
+ }
6677
+ }
6678
+ else {
6679
+ group = item;
6680
+ if (!box) {
6681
+ box = group.element.getBoundingClientRect();
6682
+ }
6683
+ const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
6684
+ options.skipRemoveGroup;
6685
+ if (!skip) {
6686
+ this.doRemoveGroup(item, { skipDispose: true });
6687
+ }
6688
+ }
6689
+ const theme = getTheme(this.gridview.element);
6690
+ const popoutWindow = new DockviewPopoutGroupPanel(`${this.id}-${group.id}`, // globally unique within dockview
6691
+ group, {
6692
+ className: theme !== null && theme !== void 0 ? theme : '',
6693
+ popoutUrl: (_a = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _a !== void 0 ? _a : '/popout.html',
6694
+ box: {
6695
+ left: window.screenX + box.left,
6696
+ top: window.screenY + box.top,
6697
+ width: box.width,
6698
+ height: box.height,
6699
+ },
6700
+ });
6701
+ popoutWindow.addDisposables({
6702
+ dispose: () => {
6703
+ remove(this._popoutGroups, popoutWindow);
6704
+ this.updateWatermark();
6705
+ },
6706
+ }, popoutWindow.window.onDidClose(() => {
6707
+ this.doAddGroup(group, [0]);
6708
+ }));
6709
+ this._popoutGroups.push(popoutWindow);
6710
+ this.updateWatermark();
6711
+ }
6043
6712
  addFloatingGroup(item, coord, options) {
6044
6713
  var _a, _b, _c, _d, _e, _f;
6045
6714
  let group;
@@ -6059,9 +6728,13 @@
6059
6728
  this.doRemoveGroup(item, { skipDispose: true });
6060
6729
  }
6061
6730
  }
6062
- group.model.isFloating = true;
6063
- const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100;
6064
- const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100;
6731
+ group.model.location = 'floating';
6732
+ const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number'
6733
+ ? Math.max(coord.x, 0)
6734
+ : DEFAULT_FLOATING_GROUP_POSITION.left;
6735
+ const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number'
6736
+ ? Math.max(coord.y, 0)
6737
+ : DEFAULT_FLOATING_GROUP_POSITION.top;
6065
6738
  const overlay = new Overlay({
6066
6739
  container: this.gridview.element,
6067
6740
  content: group.element,
@@ -6105,12 +6778,12 @@
6105
6778
  }), {
6106
6779
  dispose: () => {
6107
6780
  disposable.dispose();
6108
- group.model.isFloating = false;
6109
- remove(this.floatingGroups, floatingGroupPanel);
6781
+ group.model.location = 'grid';
6782
+ remove(this._floatingGroups, floatingGroupPanel);
6110
6783
  this.updateWatermark();
6111
6784
  },
6112
6785
  });
6113
- this.floatingGroups.push(floatingGroupPanel);
6786
+ this._floatingGroups.push(floatingGroupPanel);
6114
6787
  this.updateWatermark();
6115
6788
  }
6116
6789
  orthogonalize(position) {
@@ -6155,7 +6828,7 @@
6155
6828
  this.gridview.orientation = options.orientation;
6156
6829
  }
6157
6830
  if (hasFloatingGroupOptionsChanged) {
6158
- for (const group of this.floatingGroups) {
6831
+ for (const group of this._floatingGroups) {
6159
6832
  switch (this.options.floatingGroupBounds) {
6160
6833
  case 'boundedWithinViewport':
6161
6834
  group.overlay.minimumInViewportHeight = undefined;
@@ -6180,8 +6853,8 @@
6180
6853
  }
6181
6854
  layout(width, height, forceResize) {
6182
6855
  super.layout(width, height, forceResize);
6183
- if (this.floatingGroups) {
6184
- for (const floating of this.floatingGroups) {
6856
+ if (this._floatingGroups) {
6857
+ for (const floating of this._floatingGroups) {
6185
6858
  // ensure floting groups stay within visible boundaries
6186
6859
  floating.overlay.setBounds();
6187
6860
  }
@@ -6249,10 +6922,16 @@
6249
6922
  collection[panel.id] = panel.toJSON();
6250
6923
  return collection;
6251
6924
  }, {});
6252
- const floats = this.floatingGroups.map((floatingGroup) => {
6925
+ const floats = this._floatingGroups.map((group) => {
6926
+ return {
6927
+ data: group.group.toJSON(),
6928
+ position: group.overlay.toJSON(),
6929
+ };
6930
+ });
6931
+ const popoutGroups = this._popoutGroups.map((group) => {
6253
6932
  return {
6254
- data: floatingGroup.group.toJSON(),
6255
- position: floatingGroup.overlay.toJSON(),
6933
+ data: group.group.toJSON(),
6934
+ position: group.window.dimensions(),
6256
6935
  };
6257
6936
  });
6258
6937
  const result = {
@@ -6263,10 +6942,13 @@
6263
6942
  if (floats.length > 0) {
6264
6943
  result.floatingGroups = floats;
6265
6944
  }
6945
+ if (popoutGroups.length > 0) {
6946
+ result.popoutGroups = popoutGroups;
6947
+ }
6266
6948
  return result;
6267
6949
  }
6268
6950
  fromJSON(data) {
6269
- var _a;
6951
+ var _a, _b;
6270
6952
  this.clear();
6271
6953
  if (typeof data !== 'object' || data === null) {
6272
6954
  throw new Error('serialized layout must be a non-null object');
@@ -6333,7 +7015,16 @@
6333
7015
  width: position.width,
6334
7016
  }, { skipRemoveGroup: true, inDragMode: false });
6335
7017
  }
6336
- for (const floatingGroup of this.floatingGroups) {
7018
+ const serializedPopoutGroups = (_b = data.popoutGroups) !== null && _b !== void 0 ? _b : [];
7019
+ for (const serializedPopoutGroup of serializedPopoutGroups) {
7020
+ const { data, position } = serializedPopoutGroup;
7021
+ const group = createGroupFromSerializedState(data);
7022
+ this.addPopoutGroup(group, {
7023
+ skipRemoveGroup: true,
7024
+ position: position !== null && position !== void 0 ? position : undefined,
7025
+ });
7026
+ }
7027
+ for (const floatingGroup of this._floatingGroups) {
6337
7028
  floatingGroup.overlay.setBounds();
6338
7029
  }
6339
7030
  if (typeof activeGroup === 'string') {
@@ -6365,7 +7056,7 @@
6365
7056
  this._onDidRemoveGroup.fire(group);
6366
7057
  }
6367
7058
  // iterate over a reassigned array since original array will be modified
6368
- for (const floatingGroup of [...this.floatingGroups]) {
7059
+ for (const floatingGroup of [...this._floatingGroups]) {
6369
7060
  floatingGroup.dispose();
6370
7061
  }
6371
7062
  // fires clean-up events and clears the underlying HTML gridview.
@@ -6457,7 +7148,8 @@
6457
7148
  group.model.openPanel(panel);
6458
7149
  this.doSetGroupAndPanelActive(group);
6459
7150
  }
6460
- else if (referenceGroup.api.isFloating || target === 'center') {
7151
+ else if (referenceGroup.api.location === 'floating' ||
7152
+ target === 'center') {
6461
7153
  panel = this.createPanel(options, referenceGroup);
6462
7154
  referenceGroup.model.openPanel(panel);
6463
7155
  }
@@ -6501,6 +7193,7 @@
6501
7193
  }
6502
7194
  group.model.removePanel(panel);
6503
7195
  if (!options.skipDispose) {
7196
+ this.overlayRenderContainer.detatch(panel);
6504
7197
  panel.dispose();
6505
7198
  }
6506
7199
  if (group.size === 0 && options.removeEmptyGroup) {
@@ -6517,7 +7210,7 @@
6517
7210
  }
6518
7211
  updateWatermark() {
6519
7212
  var _a, _b;
6520
- if (this.groups.filter((x) => !x.api.isFloating).length === 0) {
7213
+ if (this.groups.filter((x) => x.api.location === 'grid').length === 0) {
6521
7214
  if (!this.watermark) {
6522
7215
  this.watermark = this.createWatermarkComponent();
6523
7216
  this.watermark.init({
@@ -6592,19 +7285,40 @@
6592
7285
  }
6593
7286
  }
6594
7287
  doRemoveGroup(group, options) {
6595
- const floatingGroup = this.floatingGroups.find((_) => _.group === group);
6596
- if (floatingGroup) {
6597
- if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6598
- floatingGroup.group.dispose();
6599
- this._groups.delete(group.id);
6600
- this._onDidRemoveGroup.fire(group);
7288
+ if (group.api.location === 'floating') {
7289
+ const floatingGroup = this._floatingGroups.find((_) => _.group === group);
7290
+ if (floatingGroup) {
7291
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7292
+ floatingGroup.group.dispose();
7293
+ this._groups.delete(group.id);
7294
+ this._onDidRemoveGroup.fire(group);
7295
+ }
7296
+ remove(this._floatingGroups, floatingGroup);
7297
+ floatingGroup.dispose();
7298
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7299
+ const groups = Array.from(this._groups.values());
7300
+ this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7301
+ }
7302
+ return floatingGroup.group;
6601
7303
  }
6602
- floatingGroup.dispose();
6603
- if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
6604
- const groups = Array.from(this._groups.values());
6605
- this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7304
+ throw new Error('failed to find floating group');
7305
+ }
7306
+ if (group.api.location === 'popout') {
7307
+ const selectedGroup = this._popoutGroups.find((_) => _.group === group);
7308
+ if (selectedGroup) {
7309
+ if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
7310
+ selectedGroup.group.dispose();
7311
+ this._groups.delete(group.id);
7312
+ this._onDidRemoveGroup.fire(group);
7313
+ }
7314
+ selectedGroup.dispose();
7315
+ if (!(options === null || options === void 0 ? void 0 : options.skipActive) && this._activeGroup === group) {
7316
+ const groups = Array.from(this._groups.values());
7317
+ this.doSetGroupActive(groups.length > 0 ? groups[0].value : undefined);
7318
+ }
7319
+ return selectedGroup.group;
6606
7320
  }
6607
- return floatingGroup.group;
7321
+ throw new Error('failed to find popout group');
6608
7322
  }
6609
7323
  return super.doRemoveGroup(group, options);
6610
7324
  }
@@ -6636,8 +7350,7 @@
6636
7350
  const targetLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
6637
7351
  if (sourceGroup && sourceGroup.size < 2) {
6638
7352
  const [targetParentLocation, to] = tail(targetLocation);
6639
- const isFloating = this.floatingGroups.find((x) => x.group === sourceGroup);
6640
- if (!isFloating) {
7353
+ if (sourceGroup.api.location === 'grid') {
6641
7354
  const sourceLocation = getGridLocation(sourceGroup.element);
6642
7355
  const [sourceParentLocation, from] = tail(sourceLocation);
6643
7356
  if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
@@ -6683,12 +7396,25 @@
6683
7396
  }
6684
7397
  }
6685
7398
  else {
6686
- const floatingGroup = this.floatingGroups.find((x) => x.group === sourceGroup);
6687
- if (floatingGroup) {
6688
- floatingGroup.dispose();
6689
- }
6690
- else {
6691
- this.gridview.removeView(getGridLocation(sourceGroup.element));
7399
+ switch (sourceGroup.api.location) {
7400
+ case 'grid':
7401
+ this.gridview.removeView(getGridLocation(sourceGroup.element));
7402
+ break;
7403
+ case 'floating': {
7404
+ const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === sourceGroup);
7405
+ if (!selectedFloatingGroup) {
7406
+ throw new Error('failed to find floating group');
7407
+ }
7408
+ selectedFloatingGroup.dispose();
7409
+ break;
7410
+ }
7411
+ case 'popout': {
7412
+ const selectedPopoutGroup = this._popoutGroups.find((x) => x.group === sourceGroup);
7413
+ if (!selectedPopoutGroup) {
7414
+ throw new Error('failed to find popout group');
7415
+ }
7416
+ selectedPopoutGroup.dispose();
7417
+ }
6692
7418
  }
6693
7419
  const referenceLocation = getGridLocation(referenceGroup.element);
6694
7420
  const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target);
@@ -6750,7 +7476,7 @@
6750
7476
  const contentComponent = options.component;
6751
7477
  const tabComponent = (_a = options.tabComponent) !== null && _a !== void 0 ? _a : this.options.defaultTabComponent;
6752
7478
  const view = new DockviewPanelModel(this, options.id, contentComponent, tabComponent);
6753
- const panel = new DockviewPanel(options.id, this, this._api, group, view);
7479
+ const panel = new DockviewPanel(options.id, this, this._api, group, view, { renderer: options.renderer });
6754
7480
  panel.init({
6755
7481
  title: (_b = options.title) !== null && _b !== void 0 ? _b : options.id,
6756
7482
  params: (_c = options === null || options === void 0 ? void 0 : options.params) !== null && _c !== void 0 ? _c : {},