dockview-core 7.0.3 → 8.0.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 (374) hide show
  1. package/LICENCE.md +21 -0
  2. package/README.md +17 -86
  3. package/dist/cjs/api/component.api.d.ts +100 -9
  4. package/dist/cjs/api/dockviewGroupPanelApi.d.ts +45 -1
  5. package/dist/cjs/api/dockviewPanelApi.d.ts +21 -0
  6. package/dist/cjs/dismissableLayer.d.ts +57 -0
  7. package/dist/cjs/dnd/backend.d.ts +2 -2
  8. package/dist/cjs/dnd/dropTargetAnchorContainer.d.ts +12 -0
  9. package/dist/cjs/dnd/droptarget.d.ts +94 -0
  10. package/dist/cjs/dnd/ghost.d.ts +1 -0
  11. package/dist/cjs/dnd/pointer/longPress.d.ts +2 -2
  12. package/dist/cjs/dnd/pointer/pointerDragController.d.ts +5 -2
  13. package/dist/cjs/dnd/pointer/pointerDragSource.d.ts +1 -1
  14. package/dist/cjs/dnd/pointer/pointerDropTarget.d.ts +30 -1
  15. package/dist/cjs/dnd/pointer/pointerGhost.d.ts +1 -1
  16. package/dist/cjs/dockview/accessibilityMessages.d.ts +6 -0
  17. package/dist/cjs/dockview/advancedDnDService.d.ts +46 -0
  18. package/dist/cjs/dockview/components/panel/content.d.ts +1 -1
  19. package/dist/cjs/dockview/components/tab/defaultTab.d.ts +2 -0
  20. package/dist/cjs/dockview/components/tab/tab.d.ts +2 -0
  21. package/dist/cjs/dockview/components/titlebar/floatingTitleBar.d.ts +2 -2
  22. package/dist/cjs/dockview/components/titlebar/groupDragSource.d.ts +1 -1
  23. package/dist/cjs/dockview/components/titlebar/tabGroupChip.d.ts +1 -1
  24. package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.d.ts +73 -2
  25. package/dist/cjs/dockview/components/titlebar/tabGroups.d.ts +1 -1
  26. package/dist/cjs/dockview/components/titlebar/tabReorderController.d.ts +295 -0
  27. package/dist/cjs/dockview/components/titlebar/tabs.d.ts +120 -50
  28. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +48 -0
  29. package/dist/cjs/dockview/dndCapabilities.d.ts +1 -1
  30. package/dist/cjs/dockview/dockviewComponent.d.ts +303 -19
  31. package/dist/cjs/dockview/dockviewGroupPanel.d.ts +5 -0
  32. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +52 -2
  33. package/dist/cjs/dockview/dockviewPanel.d.ts +12 -0
  34. package/dist/cjs/dockview/dockviewShell.d.ts +48 -24
  35. package/dist/cjs/dockview/edgeGroupService.d.ts +20 -0
  36. package/dist/cjs/dockview/events.d.ts +6 -0
  37. package/dist/cjs/dockview/liveRegionService.d.ts +18 -5
  38. package/dist/cjs/dockview/moduleContracts.d.ts +480 -14
  39. package/dist/cjs/dockview/modules.d.ts +101 -22
  40. package/dist/cjs/dockview/options.d.ts +337 -30
  41. package/dist/cjs/dockview/optionsModules.d.ts +73 -0
  42. package/dist/cjs/dockview/popoutWindowService.d.ts +15 -10
  43. package/dist/cjs/dockview/rootDropTargetService.d.ts +11 -0
  44. package/dist/cjs/dockview/tabGroupAccent.d.ts +1 -1
  45. package/dist/cjs/dockview/tabGroupChipsService.d.ts +10 -0
  46. package/dist/cjs/dockview/theme.d.ts +2 -2
  47. package/dist/cjs/dockview/types.d.ts +3 -0
  48. package/dist/cjs/dom.d.ts +9 -1
  49. package/dist/cjs/gridview/baseComponentGridview.d.ts +2 -2
  50. package/dist/cjs/gridview/gridview.d.ts +2 -0
  51. package/dist/cjs/index.d.ts +35 -29
  52. package/dist/cjs/lifecycle.d.ts +1 -0
  53. package/dist/cjs/overlay/overlay.d.ts +4 -2
  54. package/dist/cjs/overlay/overlayRenderContainer.d.ts +8 -0
  55. package/dist/cjs/paneview/paneview.d.ts +2 -1
  56. package/dist/cjs/paneview/paneviewComponent.d.ts +3 -0
  57. package/dist/cjs/paneview/paneviewPanel.d.ts +5 -0
  58. package/dist/cjs/svg.d.ts +1 -0
  59. package/dist/cjs/types.d.ts +8 -0
  60. package/dist/dockview-core.js +18391 -19679
  61. package/dist/dockview-core.min.js +4138 -6
  62. package/dist/dockview-core.min.noStyle.js +6 -7
  63. package/dist/dockview-core.noStyle.js +18390 -19656
  64. package/dist/package/main.cjs.js +18002 -19268
  65. package/dist/package/main.cjs.min.js +6 -6
  66. package/dist/package/main.esm.min.mjs +6 -6
  67. package/dist/package/main.esm.mjs +17959 -19260
  68. package/package.json +81 -77
  69. package/dist/cjs/api/component.api.js +0 -1242
  70. package/dist/cjs/api/dockviewGroupPanelApi.js +0 -200
  71. package/dist/cjs/api/dockviewPanelApi.js +0 -172
  72. package/dist/cjs/api/entryPoints.js +0 -27
  73. package/dist/cjs/api/gridviewPanelApi.js +0 -45
  74. package/dist/cjs/api/panelApi.js +0 -133
  75. package/dist/cjs/api/paneviewPanelApi.js +0 -57
  76. package/dist/cjs/api/splitviewPanelApi.js +0 -47
  77. package/dist/cjs/array.js +0 -66
  78. package/dist/cjs/constants.js +0 -11
  79. package/dist/cjs/dnd/backend.js +0 -171
  80. package/dist/cjs/dnd/dataTransfer.js +0 -100
  81. package/dist/cjs/dnd/dnd.js +0 -74
  82. package/dist/cjs/dnd/dropOverlay.js +0 -197
  83. package/dist/cjs/dnd/dropTargetAnchorContainer.js +0 -104
  84. package/dist/cjs/dnd/droptarget.js +0 -362
  85. package/dist/cjs/dnd/ghost.js +0 -17
  86. package/dist/cjs/dnd/pointer/index.js +0 -13
  87. package/dist/cjs/dnd/pointer/longPress.js +0 -151
  88. package/dist/cjs/dnd/pointer/pointerDragController.js +0 -243
  89. package/dist/cjs/dnd/pointer/pointerDragSource.js +0 -197
  90. package/dist/cjs/dnd/pointer/pointerDropTarget.js +0 -198
  91. package/dist/cjs/dnd/pointer/pointerGhost.js +0 -44
  92. package/dist/cjs/dnd/pointer/types.js +0 -2
  93. package/dist/cjs/dockview/accessibilityMessages.js +0 -51
  94. package/dist/cjs/dockview/allModules.js +0 -25
  95. package/dist/cjs/dockview/components/panel/content.js +0 -213
  96. package/dist/cjs/dockview/components/popupService.js +0 -132
  97. package/dist/cjs/dockview/components/tab/defaultTab.js +0 -70
  98. package/dist/cjs/dockview/components/tab/tab.js +0 -281
  99. package/dist/cjs/dockview/components/titlebar/floatingTitleBar.js +0 -95
  100. package/dist/cjs/dockview/components/titlebar/groupDragSource.js +0 -218
  101. package/dist/cjs/dockview/components/titlebar/tabGroupChip.js +0 -104
  102. package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.js +0 -477
  103. package/dist/cjs/dockview/components/titlebar/tabGroups.js +0 -854
  104. package/dist/cjs/dockview/components/titlebar/tabOverflowControl.js +0 -19
  105. package/dist/cjs/dockview/components/titlebar/tabs.js +0 -2016
  106. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +0 -458
  107. package/dist/cjs/dockview/components/titlebar/voidContainer.js +0 -120
  108. package/dist/cjs/dockview/components/watermark/watermark.js +0 -40
  109. package/dist/cjs/dockview/deserializer.js +0 -39
  110. package/dist/cjs/dockview/dndCapabilities.js +0 -39
  111. package/dist/cjs/dockview/dockviewComponent.js +0 -3896
  112. package/dist/cjs/dockview/dockviewFloatingGroupPanel.js +0 -70
  113. package/dist/cjs/dockview/dockviewGroupPanel.js +0 -204
  114. package/dist/cjs/dockview/dockviewGroupPanelModel.js +0 -1514
  115. package/dist/cjs/dockview/dockviewPanel.js +0 -265
  116. package/dist/cjs/dockview/dockviewPanelModel.js +0 -105
  117. package/dist/cjs/dockview/dockviewShell.js +0 -744
  118. package/dist/cjs/dockview/edgeGroupService.js +0 -128
  119. package/dist/cjs/dockview/events.js +0 -67
  120. package/dist/cjs/dockview/floatingGroupService.js +0 -231
  121. package/dist/cjs/dockview/framework.js +0 -2
  122. package/dist/cjs/dockview/headerActionsService.js +0 -149
  123. package/dist/cjs/dockview/liveRegionService.js +0 -185
  124. package/dist/cjs/dockview/moduleContracts.js +0 -2
  125. package/dist/cjs/dockview/modules.js +0 -304
  126. package/dist/cjs/dockview/options.js +0 -103
  127. package/dist/cjs/dockview/popoutWindowService.js +0 -261
  128. package/dist/cjs/dockview/rootDropTargetService.js +0 -87
  129. package/dist/cjs/dockview/strictEventsSequencing.js +0 -63
  130. package/dist/cjs/dockview/tabGroup.js +0 -219
  131. package/dist/cjs/dockview/tabGroupAccent.js +0 -126
  132. package/dist/cjs/dockview/theme.js +0 -139
  133. package/dist/cjs/dockview/types.js +0 -2
  134. package/dist/cjs/dockview/validate.js +0 -76
  135. package/dist/cjs/dockview/watermarkService.js +0 -61
  136. package/dist/cjs/dom.js +0 -543
  137. package/dist/cjs/events.js +0 -296
  138. package/dist/cjs/framwork.js +0 -2
  139. package/dist/cjs/gridview/baseComponentGridview.js +0 -330
  140. package/dist/cjs/gridview/basePanelView.js +0 -162
  141. package/dist/cjs/gridview/branchNode.js +0 -372
  142. package/dist/cjs/gridview/gridview.js +0 -776
  143. package/dist/cjs/gridview/gridviewComponent.js +0 -363
  144. package/dist/cjs/gridview/gridviewPanel.js +0 -249
  145. package/dist/cjs/gridview/leafNode.js +0 -169
  146. package/dist/cjs/gridview/options.js +0 -17
  147. package/dist/cjs/gridview/types.js +0 -2
  148. package/dist/cjs/index.js +0 -105
  149. package/dist/cjs/lifecycle.js +0 -80
  150. package/dist/cjs/math.js +0 -38
  151. package/dist/cjs/overlay/overlay.js +0 -602
  152. package/dist/cjs/overlay/overlayRenderContainer.js +0 -309
  153. package/dist/cjs/panel/types.js +0 -2
  154. package/dist/cjs/paneview/defaultPaneviewHeader.js +0 -92
  155. package/dist/cjs/paneview/draggablePaneviewPanel.js +0 -141
  156. package/dist/cjs/paneview/options.js +0 -44
  157. package/dist/cjs/paneview/paneview.js +0 -203
  158. package/dist/cjs/paneview/paneviewComponent.js +0 -430
  159. package/dist/cjs/paneview/paneviewPanel.js +0 -275
  160. package/dist/cjs/popoutWindow.js +0 -244
  161. package/dist/cjs/resizable.js +0 -97
  162. package/dist/cjs/scrollbar.js +0 -169
  163. package/dist/cjs/splitview/options.js +0 -19
  164. package/dist/cjs/splitview/splitview.js +0 -999
  165. package/dist/cjs/splitview/splitviewComponent.js +0 -401
  166. package/dist/cjs/splitview/splitviewPanel.js +0 -179
  167. package/dist/cjs/splitview/viewItem.js +0 -119
  168. package/dist/cjs/svg.js +0 -43
  169. package/dist/cjs/types.js +0 -2
  170. package/dist/dockview-core.min.js.map +0 -1
  171. package/dist/dockview-core.min.noStyle.js.map +0 -1
  172. package/dist/esm/api/component.api.d.ts +0 -640
  173. package/dist/esm/api/component.api.js +0 -887
  174. package/dist/esm/api/dockviewGroupPanelApi.d.ts +0 -109
  175. package/dist/esm/api/dockviewGroupPanelApi.js +0 -155
  176. package/dist/esm/api/dockviewPanelApi.d.ts +0 -84
  177. package/dist/esm/api/dockviewPanelApi.js +0 -124
  178. package/dist/esm/api/entryPoints.d.ts +0 -9
  179. package/dist/esm/api/entryPoints.js +0 -21
  180. package/dist/esm/api/gridviewPanelApi.d.ts +0 -37
  181. package/dist/esm/api/gridviewPanelApi.js +0 -23
  182. package/dist/esm/api/panelApi.d.ts +0 -100
  183. package/dist/esm/api/panelApi.js +0 -87
  184. package/dist/esm/api/paneviewPanelApi.d.ts +0 -26
  185. package/dist/esm/api/paneviewPanelApi.js +0 -27
  186. package/dist/esm/api/splitviewPanelApi.d.ts +0 -32
  187. package/dist/esm/api/splitviewPanelApi.js +0 -25
  188. package/dist/esm/array.d.ts +0 -13
  189. package/dist/esm/array.js +0 -57
  190. package/dist/esm/constants.d.ts +0 -8
  191. package/dist/esm/constants.js +0 -8
  192. package/dist/esm/dnd/backend.d.ts +0 -70
  193. package/dist/esm/dnd/backend.js +0 -148
  194. package/dist/esm/dnd/dataTransfer.d.ts +0 -31
  195. package/dist/esm/dnd/dataTransfer.js +0 -67
  196. package/dist/esm/dnd/dnd.d.ts +0 -32
  197. package/dist/esm/dnd/dnd.js +0 -51
  198. package/dist/esm/dnd/dropOverlay.d.ts +0 -20
  199. package/dist/esm/dnd/dropOverlay.js +0 -192
  200. package/dist/esm/dnd/dropTargetAnchorContainer.d.ts +0 -16
  201. package/dist/esm/dnd/dropTargetAnchorContainer.js +0 -73
  202. package/dist/esm/dnd/droptarget.d.ts +0 -116
  203. package/dist/esm/dnd/droptarget.js +0 -316
  204. package/dist/esm/dnd/ghost.d.ts +0 -4
  205. package/dist/esm/dnd/ghost.js +0 -14
  206. package/dist/esm/dnd/pointer/index.d.ts +0 -11
  207. package/dist/esm/dnd/pointer/index.js +0 -5
  208. package/dist/esm/dnd/pointer/longPress.d.ts +0 -32
  209. package/dist/esm/dnd/pointer/longPress.js +0 -127
  210. package/dist/esm/dnd/pointer/pointerDragController.d.ts +0 -60
  211. package/dist/esm/dnd/pointer/pointerDragController.js +0 -193
  212. package/dist/esm/dnd/pointer/pointerDragSource.d.ts +0 -61
  213. package/dist/esm/dnd/pointer/pointerDragSource.js +0 -173
  214. package/dist/esm/dnd/pointer/pointerDropTarget.d.ts +0 -39
  215. package/dist/esm/dnd/pointer/pointerDropTarget.js +0 -168
  216. package/dist/esm/dnd/pointer/pointerGhost.d.ts +0 -30
  217. package/dist/esm/dnd/pointer/pointerGhost.js +0 -39
  218. package/dist/esm/dnd/pointer/types.d.ts +0 -16
  219. package/dist/esm/dnd/pointer/types.js +0 -1
  220. package/dist/esm/dockview/accessibilityMessages.d.ts +0 -32
  221. package/dist/esm/dockview/accessibilityMessages.js +0 -30
  222. package/dist/esm/dockview/allModules.d.ts +0 -8
  223. package/dist/esm/dockview/allModules.js +0 -22
  224. package/dist/esm/dockview/components/panel/content.d.ts +0 -54
  225. package/dist/esm/dockview/components/panel/content.js +0 -185
  226. package/dist/esm/dockview/components/popupService.d.ts +0 -21
  227. package/dist/esm/dockview/components/popupService.js +0 -108
  228. package/dist/esm/dockview/components/tab/defaultTab.d.ts +0 -12
  229. package/dist/esm/dockview/components/tab/defaultTab.js +0 -43
  230. package/dist/esm/dockview/components/tab/tab.d.ts +0 -44
  231. package/dist/esm/dockview/components/tab/tab.js +0 -242
  232. package/dist/esm/dockview/components/titlebar/floatingTitleBar.d.ts +0 -34
  233. package/dist/esm/dockview/components/titlebar/floatingTitleBar.js +0 -65
  234. package/dist/esm/dockview/components/titlebar/groupDragSource.d.ts +0 -51
  235. package/dist/esm/dockview/components/titlebar/groupDragSource.js +0 -178
  236. package/dist/esm/dockview/components/titlebar/tabGroupChip.d.ts +0 -37
  237. package/dist/esm/dockview/components/titlebar/tabGroupChip.js +0 -77
  238. package/dist/esm/dockview/components/titlebar/tabGroupIndicator.d.ts +0 -72
  239. package/dist/esm/dockview/components/titlebar/tabGroupIndicator.js +0 -360
  240. package/dist/esm/dockview/components/titlebar/tabGroups.d.ts +0 -107
  241. package/dist/esm/dockview/components/titlebar/tabGroups.js +0 -621
  242. package/dist/esm/dockview/components/titlebar/tabOverflowControl.d.ts +0 -8
  243. package/dist/esm/dockview/components/titlebar/tabOverflowControl.js +0 -16
  244. package/dist/esm/dockview/components/titlebar/tabs.d.ts +0 -167
  245. package/dist/esm/dockview/components/titlebar/tabs.js +0 -1653
  246. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +0 -104
  247. package/dist/esm/dockview/components/titlebar/tabsContainer.js +0 -359
  248. package/dist/esm/dockview/components/titlebar/voidContainer.d.ts +0 -21
  249. package/dist/esm/dockview/components/titlebar/voidContainer.js +0 -92
  250. package/dist/esm/dockview/components/watermark/watermark.d.ts +0 -8
  251. package/dist/esm/dockview/components/watermark/watermark.js +0 -14
  252. package/dist/esm/dockview/deserializer.d.ts +0 -12
  253. package/dist/esm/dockview/deserializer.js +0 -34
  254. package/dist/esm/dockview/dndCapabilities.d.ts +0 -19
  255. package/dist/esm/dockview/dndCapabilities.js +0 -36
  256. package/dist/esm/dockview/dockviewComponent.d.ts +0 -626
  257. package/dist/esm/dockview/dockviewComponent.js +0 -3214
  258. package/dist/esm/dockview/dockviewFloatingGroupPanel.d.ts +0 -45
  259. package/dist/esm/dockview/dockviewFloatingGroupPanel.js +0 -44
  260. package/dist/esm/dockview/dockviewGroupPanel.d.ts +0 -35
  261. package/dist/esm/dockview/dockviewGroupPanel.js +0 -142
  262. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +0 -358
  263. package/dist/esm/dockview/dockviewGroupPanelModel.js +0 -1180
  264. package/dist/esm/dockview/dockviewPanel.d.ts +0 -69
  265. package/dist/esm/dockview/dockviewPanel.js +0 -178
  266. package/dist/esm/dockview/dockviewPanelModel.d.ts +0 -37
  267. package/dist/esm/dockview/dockviewPanelModel.js +0 -81
  268. package/dist/esm/dockview/dockviewShell.d.ts +0 -150
  269. package/dist/esm/dockview/dockviewShell.js +0 -678
  270. package/dist/esm/dockview/edgeGroupService.d.ts +0 -38
  271. package/dist/esm/dockview/edgeGroupService.js +0 -63
  272. package/dist/esm/dockview/events.d.ts +0 -38
  273. package/dist/esm/dockview/events.js +0 -34
  274. package/dist/esm/dockview/floatingGroupService.d.ts +0 -37
  275. package/dist/esm/dockview/floatingGroupService.js +0 -150
  276. package/dist/esm/dockview/framework.d.ts +0 -65
  277. package/dist/esm/dockview/framework.js +0 -1
  278. package/dist/esm/dockview/headerActionsService.d.ts +0 -32
  279. package/dist/esm/dockview/headerActionsService.js +0 -86
  280. package/dist/esm/dockview/liveRegionService.d.ts +0 -53
  281. package/dist/esm/dockview/liveRegionService.js +0 -159
  282. package/dist/esm/dockview/moduleContracts.d.ts +0 -119
  283. package/dist/esm/dockview/moduleContracts.js +0 -1
  284. package/dist/esm/dockview/modules.d.ts +0 -110
  285. package/dist/esm/dockview/modules.js +0 -170
  286. package/dist/esm/dockview/options.d.ts +0 -474
  287. package/dist/esm/dockview/options.js +0 -77
  288. package/dist/esm/dockview/popoutWindowService.d.ts +0 -95
  289. package/dist/esm/dockview/popoutWindowService.js +0 -175
  290. package/dist/esm/dockview/rootDropTargetService.d.ts +0 -35
  291. package/dist/esm/dockview/rootDropTargetService.js +0 -82
  292. package/dist/esm/dockview/strictEventsSequencing.d.ts +0 -7
  293. package/dist/esm/dockview/strictEventsSequencing.js +0 -41
  294. package/dist/esm/dockview/tabGroup.d.ts +0 -99
  295. package/dist/esm/dockview/tabGroup.js +0 -144
  296. package/dist/esm/dockview/tabGroupAccent.d.ts +0 -65
  297. package/dist/esm/dockview/tabGroupAccent.js +0 -114
  298. package/dist/esm/dockview/theme.d.ts +0 -86
  299. package/dist/esm/dockview/theme.js +0 -136
  300. package/dist/esm/dockview/types.d.ts +0 -53
  301. package/dist/esm/dockview/types.js +0 -1
  302. package/dist/esm/dockview/validate.d.ts +0 -0
  303. package/dist/esm/dockview/validate.js +0 -76
  304. package/dist/esm/dockview/watermarkService.d.ts +0 -30
  305. package/dist/esm/dockview/watermarkService.js +0 -56
  306. package/dist/esm/dom.d.ts +0 -60
  307. package/dist/esm/dom.js +0 -375
  308. package/dist/esm/events.d.ts +0 -79
  309. package/dist/esm/events.js +0 -219
  310. package/dist/esm/framwork.d.ts +0 -4
  311. package/dist/esm/framwork.js +0 -1
  312. package/dist/esm/gridview/baseComponentGridview.d.ts +0 -111
  313. package/dist/esm/gridview/baseComponentGridview.js +0 -237
  314. package/dist/esm/gridview/basePanelView.d.ts +0 -40
  315. package/dist/esm/gridview/basePanelView.js +0 -91
  316. package/dist/esm/gridview/branchNode.d.ts +0 -57
  317. package/dist/esm/gridview/branchNode.js +0 -257
  318. package/dist/esm/gridview/gridview.d.ts +0 -158
  319. package/dist/esm/gridview/gridview.js +0 -681
  320. package/dist/esm/gridview/gridviewComponent.d.ts +0 -88
  321. package/dist/esm/gridview/gridviewComponent.js +0 -265
  322. package/dist/esm/gridview/gridviewPanel.d.ts +0 -77
  323. package/dist/esm/gridview/gridviewPanel.js +0 -182
  324. package/dist/esm/gridview/leafNode.d.ts +0 -34
  325. package/dist/esm/gridview/leafNode.js +0 -102
  326. package/dist/esm/gridview/options.d.ts +0 -15
  327. package/dist/esm/gridview/options.js +0 -14
  328. package/dist/esm/gridview/types.d.ts +0 -3
  329. package/dist/esm/gridview/types.js +0 -1
  330. package/dist/esm/index.d.ts +0 -58
  331. package/dist/esm/index.js +0 -44
  332. package/dist/esm/lifecycle.d.ts +0 -25
  333. package/dist/esm/lifecycle.js +0 -56
  334. package/dist/esm/math.d.ts +0 -5
  335. package/dist/esm/math.js +0 -32
  336. package/dist/esm/overlay/overlay.d.ts +0 -91
  337. package/dist/esm/overlay/overlay.js +0 -520
  338. package/dist/esm/overlay/overlayRenderContainer.d.ts +0 -24
  339. package/dist/esm/overlay/overlayRenderContainer.js +0 -249
  340. package/dist/esm/panel/types.d.ts +0 -33
  341. package/dist/esm/panel/types.js +0 -1
  342. package/dist/esm/paneview/defaultPaneviewHeader.d.ts +0 -21
  343. package/dist/esm/paneview/defaultPaneviewHeader.js +0 -65
  344. package/dist/esm/paneview/draggablePaneviewPanel.d.ts +0 -38
  345. package/dist/esm/paneview/draggablePaneviewPanel.js +0 -107
  346. package/dist/esm/paneview/options.d.ts +0 -30
  347. package/dist/esm/paneview/options.js +0 -22
  348. package/dist/esm/paneview/paneview.d.ts +0 -41
  349. package/dist/esm/paneview/paneview.js +0 -148
  350. package/dist/esm/paneview/paneviewComponent.d.ts +0 -133
  351. package/dist/esm/paneview/paneviewComponent.js +0 -306
  352. package/dist/esm/paneview/paneviewPanel.d.ts +0 -98
  353. package/dist/esm/paneview/paneviewPanel.js +0 -192
  354. package/dist/esm/popoutWindow.d.ts +0 -38
  355. package/dist/esm/popoutWindow.js +0 -170
  356. package/dist/esm/resizable.d.ts +0 -12
  357. package/dist/esm/resizable.js +0 -66
  358. package/dist/esm/scrollbar.d.ts +0 -15
  359. package/dist/esm/scrollbar.js +0 -139
  360. package/dist/esm/splitview/options.d.ts +0 -21
  361. package/dist/esm/splitview/options.js +0 -16
  362. package/dist/esm/splitview/splitview.d.ts +0 -145
  363. package/dist/esm/splitview/splitview.js +0 -770
  364. package/dist/esm/splitview/splitviewComponent.d.ts +0 -101
  365. package/dist/esm/splitview/splitviewComponent.js +0 -267
  366. package/dist/esm/splitview/splitviewPanel.d.ts +0 -45
  367. package/dist/esm/splitview/splitviewPanel.js +0 -108
  368. package/dist/esm/splitview/viewItem.d.ts +0 -25
  369. package/dist/esm/splitview/viewItem.js +0 -74
  370. package/dist/esm/svg.d.ts +0 -3
  371. package/dist/esm/svg.js +0 -31
  372. package/dist/esm/types.d.ts +0 -31
  373. package/dist/esm/types.js +0 -1
  374. package/dist/styles/dockview.css +0 -3436
@@ -1,3214 +0,0 @@
1
- import { getRelativeLocation, getGridLocation, orthogonal, Gridview, } from '../gridview/gridview';
2
- import { directionToPosition, } from '../dnd/droptarget';
3
- import { tail, sequenceEquals } from '../array';
4
- import { DockviewPanel } from './dockviewPanel';
5
- import { CompositeDisposable, Disposable } from '../lifecycle';
6
- import { Event, Emitter, addDisposableListener } from '../events';
7
- import { Watermark } from './components/watermark/watermark';
8
- import { sequentialNumberGenerator } from '../math';
9
- import { DefaultDockviewDeserialzier } from './deserializer';
10
- import { DockviewUnhandledDragOverEvent, isGroupOptionsWithGroup, isGroupOptionsWithPanel, isPanelOptionsWithGroup, isPanelOptionsWithPanel, } from './options';
11
- import { BaseGrid, toTarget, } from '../gridview/baseComponentGridview';
12
- import { DockviewApi } from '../api/component.api';
13
- import { Orientation, Sizing } from '../splitview/splitview';
14
- import { DockviewDidDropEvent, DockviewWillDropEvent, } from './dockviewGroupPanelModel';
15
- import { DockviewWillShowOverlayLocationEvent, } from './events';
16
- import { DockviewGroupPanel } from './dockviewGroupPanel';
17
- import { DockviewPanelModel } from './dockviewPanelModel';
18
- import { getPanelData } from '../dnd/dataTransfer';
19
- import { Overlay } from '../overlay/overlay';
20
- import { Classnames, getDockviewTheme, onDidWindowResizeEnd, onDidWindowMoveEnd, toggleClass, } from '../dom';
21
- import { FloatingTitleBar } from './components/titlebar/floatingTitleBar';
22
- import { assertModule, getRegisteredModules, isDockviewPackageLoaded, ModuleRegistry, } from './modules';
23
- import { AllModules } from './allModules';
24
- import { DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE, DEFAULT_FLOATING_GROUP_POSITION, DESERIALIZATION_POPOUT_DELAY_MS, } from '../constants';
25
- import { OverlayRenderContainer, } from '../overlay/overlayRenderContainer';
26
- import { PopoutWindow } from '../popoutWindow';
27
- import { StrictEventsSequencing } from './strictEventsSequencing';
28
- import { PopupService } from './components/popupService';
29
- import { DropTargetAnchorContainer } from '../dnd/dropTargetAnchorContainer';
30
- import { themeAbyss } from './theme';
31
- import { ShellManager, } from './dockviewShell';
32
- import { DEFAULT_TAB_GROUP_COLORS, TabGroupColorPalette, } from './tabGroupAccent';
33
- function buildTabGroupColorPalette(options) {
34
- var _a;
35
- const entries = (_a = options.tabGroupColors) !== null && _a !== void 0 ? _a : DEFAULT_TAB_GROUP_COLORS;
36
- const enabled = options.tabGroupAccent !== 'off';
37
- return new TabGroupColorPalette(entries, enabled);
38
- }
39
- function moveGroupWithoutDestroying(options) {
40
- const activePanel = options.from.activePanel;
41
- const panels = [...options.from.panels].map((panel) => {
42
- const removedPanel = options.from.model.removePanel(panel);
43
- options.from.model.renderContainer.detatch(panel);
44
- return removedPanel;
45
- });
46
- panels.forEach((panel) => {
47
- options.to.model.openPanel(panel, {
48
- skipSetActive: activePanel !== panel,
49
- skipSetGroupActive: true,
50
- });
51
- });
52
- }
53
- let _hasWarnedUsingCoreDirectly = false;
54
- /**
55
- * `dockview-core` is an internal package. The public `dockview` package calls
56
- * `markDockviewPackageLoaded()` on import; if that marker is absent the consumer
57
- * is using `dockview-core` directly, so emit a one-time console warning
58
- * steering them to `dockview`.
59
- *
60
- * Suppressed in production builds: it is a development-time nudge and most
61
- * bundlers inline `process.env.NODE_ENV` so the branch is dropped entirely. The
62
- * `typeof process` guard keeps this safe in plain browser/UMD contexts where
63
- * `process` is undefined.
64
- */
65
- function warnIfUsingCoreDirectly() {
66
- var _a;
67
- if (typeof process !== 'undefined' &&
68
- ((_a = process.env) === null || _a === void 0 ? void 0 : _a.NODE_ENV) === 'production') {
69
- return;
70
- }
71
- if (_hasWarnedUsingCoreDirectly || isDockviewPackageLoaded()) {
72
- return;
73
- }
74
- _hasWarnedUsingCoreDirectly = true;
75
- console.warn('dockview: do not use "dockview-core" directly — it is an internal ' +
76
- 'package. Use the "dockview" package, the JavaScript version of ' +
77
- 'dockview, instead. This notice is shown once.');
78
- }
79
- export class DockviewComponent extends BaseGrid {
80
- fireDidCreateTabGroup(event) {
81
- this._onDidCreateTabGroup.fire(event);
82
- }
83
- fireDidDestroyTabGroup(event) {
84
- this._onDidDestroyTabGroup.fire(event);
85
- }
86
- fireDidAddPanelToTabGroup(event) {
87
- this._onDidAddPanelToTabGroup.fire(event);
88
- }
89
- fireDidRemovePanelFromTabGroup(event) {
90
- this._onDidRemovePanelFromTabGroup.fire(event);
91
- }
92
- fireDidTabGroupChange(event) {
93
- this._onDidTabGroupChange.fire(event);
94
- }
95
- fireDidTabGroupCollapsedChange(event) {
96
- this._onDidTabGroupCollapsedChange.fire(event);
97
- }
98
- get orientation() {
99
- return this.gridview.orientation;
100
- }
101
- get totalPanels() {
102
- return this.panels.length;
103
- }
104
- get panels() {
105
- return this.groups.flatMap((group) => group.panels);
106
- }
107
- get options() {
108
- return this._options;
109
- }
110
- get tabGroupColorPalette() {
111
- return this._tabGroupColorPalette;
112
- }
113
- get activePanel() {
114
- const activeGroup = this.activeGroup;
115
- if (!activeGroup) {
116
- return undefined;
117
- }
118
- return activeGroup.activePanel;
119
- }
120
- get renderer() {
121
- var _a;
122
- return (_a = this.options.defaultRenderer) !== null && _a !== void 0 ? _a : 'onlyWhenVisible';
123
- }
124
- get defaultHeaderPosition() {
125
- var _a;
126
- return (_a = this.options.defaultHeaderPosition) !== null && _a !== void 0 ? _a : 'top';
127
- }
128
- get api() {
129
- return this._api;
130
- }
131
- get floatingGroups() {
132
- var _a, _b, _c;
133
- return ((_c = (_b = (_a = this._moduleRegistry) === null || _a === void 0 ? void 0 : _a.services.floatingGroupService) === null || _b === void 0 ? void 0 : _b.floatingGroups) !== null && _c !== void 0 ? _c : []);
134
- }
135
- /**
136
- * Boxes of the floating groups other than `exclude`, in coordinates
137
- * relative to the floating overlay container. Supplied to a
138
- * `transformFloatingGroupDrag` callback as `context.others` so it can
139
- * align the dragged float against its siblings.
140
- */
141
- _gatherFloatingGroupBoxes(exclude) {
142
- var _a;
143
- const container = (_a = this._floatingOverlayHost) !== null && _a !== void 0 ? _a : this.gridview.element;
144
- const containerRect = container.getBoundingClientRect();
145
- return this.floatingGroups
146
- .filter((floating) => floating.group !== exclude)
147
- .map((floating) => {
148
- const rect = floating.overlay.element.getBoundingClientRect();
149
- return {
150
- left: rect.left - containerRect.left,
151
- top: rect.top - containerRect.top,
152
- width: rect.width,
153
- height: rect.height,
154
- };
155
- });
156
- }
157
- get _floatingGroupService() {
158
- return this._moduleRegistry.services.floatingGroupService;
159
- }
160
- get _popoutWindowService() {
161
- return this._moduleRegistry.services.popoutWindowService;
162
- }
163
- get _watermarkService() {
164
- // Tier 1 module — optional. Callers must `?.`-guard so the module
165
- // can be removed from AllModules without crashing the component.
166
- return this._moduleRegistry.services.watermarkService;
167
- }
168
- get _edgeGroupService() {
169
- return this._moduleRegistry.services.edgeGroupService;
170
- }
171
- get _rootDropTargetService() {
172
- // Optional like every other module service — RootDropTargetModule can be
173
- // removed from the registered set without crashing the component.
174
- return this._moduleRegistry.services.rootDropTargetService;
175
- }
176
- get _advancedDnDService() {
177
- // Optional — callers `?.`-guard so the module can be removed from
178
- // AllModules. Absent ⇒ the onWill* hooks simply don't fire (≡ no
179
- // subscriber), which is invisible to apps not customising DnD.
180
- return this._moduleRegistry.services.advancedDnDService;
181
- }
182
- get headerActionsService() {
183
- return this._moduleRegistry.services.headerActionsService;
184
- }
185
- isGridEmpty() {
186
- return this.gridview.length === 0;
187
- }
188
- rootDropTargetOverrideTarget() {
189
- var _a;
190
- return (_a = this.rootDropTargetContainer) === null || _a === void 0 ? void 0 : _a.model;
191
- }
192
- dispatchUnhandledDragOver(nativeEvent, position) {
193
- const event = new DockviewUnhandledDragOverEvent(nativeEvent, 'edge', position, getPanelData);
194
- this._onUnhandledDragOver.fire(event);
195
- return event.isAccepted;
196
- }
197
- // IAdvancedDnDHost — the emitters stay here so the public onWill* event
198
- // shape is unchanged; AdvancedDnDService routes the per-group fires
199
- // through these. Engine guards (e.g. disableDnd) run on the component
200
- // ahead of the dispatch.
201
- fireWillDragPanel(event) {
202
- this._onWillDragPanel.fire(event);
203
- }
204
- fireWillDragGroup(event) {
205
- this._onWillDragGroup.fire(event);
206
- }
207
- fireWillDrop(event) {
208
- this._onWillDrop.fire(event);
209
- }
210
- fireWillShowOverlay(event) {
211
- this._onWillShowOverlay.fire(event);
212
- }
213
- /**
214
- * Resolve the custom group drag ghost (via the AdvancedDnD module), or
215
- * `undefined` to fall back to the default chip. Returns `undefined` when
216
- * the module is absent — the default ghost then renders.
217
- */
218
- buildGroupDragGhost(group) {
219
- var _a;
220
- return (_a = this._advancedDnDService) === null || _a === void 0 ? void 0 : _a.buildGroupDragGhost(group);
221
- }
222
- /**
223
- * Resolve the app-supplied drop overlay model (via the AdvancedDnD module)
224
- * for a group drop target, or `undefined` to keep the target's default.
225
- */
226
- resolveDropOverlayModel(location, group) {
227
- var _a;
228
- return (_a = this._advancedDnDService) === null || _a === void 0 ? void 0 : _a.resolveOverlayModel(location, group);
229
- }
230
- // IAccessibilityHost — keyboard docking reaches the AdvancedDnD preview +
231
- // LiveRegion announcer through these so the service stays decoupled.
232
- /** Outermost element — the shell (incl. edge groups) once built, else the gridview. */
233
- get rootElement() {
234
- var _a, _b;
235
- return (_b = (_a = this._shellManager) === null || _a === void 0 ? void 0 : _a.element) !== null && _b !== void 0 ? _b : this.element;
236
- }
237
- /**
238
- * The next / previous group in gridview (spatial) order, wrapping round.
239
- * The keyboard accessibility module's focus navigation is built on this
240
- * primitive — the only piece that needs the grid internals; the rest of
241
- * the navigation logic lives in the AccessibilityService.
242
- */
243
- adjacentGroup(group, reverse) {
244
- var _a;
245
- // gridview traversal only covers grid groups; a floating/popout group
246
- // isn't in the grid, so there's no adjacent grid group to step to.
247
- if (group.api.location.type !== 'grid') {
248
- return undefined;
249
- }
250
- const location = getGridLocation(group.element);
251
- return ((_a = (reverse
252
- ? this.gridview.previous(location)
253
- : this.gridview.next(location))) === null || _a === void 0 ? void 0 : _a.view);
254
- }
255
- /**
256
- * The nearest grid group in a spatial direction from `group`, by
257
- * comparing group centre points. Floating and popout groups sit outside
258
- * the grid's geometry and are ignored. Returns `undefined` when there is
259
- * no group in that direction.
260
- */
261
- adjacentGroupInDirection(group, direction) {
262
- if (group.api.location.type !== 'grid') {
263
- return undefined;
264
- }
265
- const from = group.element.getBoundingClientRect();
266
- const fromX = from.left + from.width / 2;
267
- const fromY = from.top + from.height / 2;
268
- let best;
269
- let bestDistance = Number.POSITIVE_INFINITY;
270
- for (const candidate of this.groups) {
271
- if (candidate === group || candidate.api.location.type !== 'grid') {
272
- continue;
273
- }
274
- const rect = candidate.element.getBoundingClientRect();
275
- const dx = rect.left + rect.width / 2 - fromX;
276
- const dy = rect.top + rect.height / 2 - fromY;
277
- // Require the candidate to sit predominantly in the asked-for
278
- // direction (dominant axis), so 'left' ignores a group that's
279
- // mostly above/below.
280
- const inDirection = direction === 'left'
281
- ? dx < 0 && Math.abs(dx) >= Math.abs(dy)
282
- : direction === 'right'
283
- ? dx > 0 && Math.abs(dx) >= Math.abs(dy)
284
- : direction === 'up'
285
- ? dy < 0 && Math.abs(dy) >= Math.abs(dx)
286
- : dy > 0 && Math.abs(dy) >= Math.abs(dx);
287
- if (!inDirection) {
288
- continue;
289
- }
290
- const distance = dx * dx + dy * dy;
291
- if (distance < bestDistance) {
292
- bestDistance = distance;
293
- best = candidate;
294
- }
295
- }
296
- return best;
297
- }
298
- showDropPreview(group, position) {
299
- var _a, _b;
300
- return ((_b = (_a = this._advancedDnDService) === null || _a === void 0 ? void 0 : _a.showPreviewOverlay(group, position)) !== null && _b !== void 0 ? _b : Disposable.NONE);
301
- }
302
- announce(message) {
303
- var _a;
304
- (_a = this._moduleRegistry.services.liveRegionService) === null || _a === void 0 ? void 0 : _a.announce(message);
305
- }
306
- dockPanel(panel, group, position) {
307
- this.moveGroupOrPanel({
308
- from: { groupId: panel.group.id, panelId: panel.id },
309
- to: { group, position },
310
- });
311
- }
312
- get contextMenuService() {
313
- // Owned by ContextMenuModule — undefined when the module is not
314
- // registered, so callers must `?.`-guard.
315
- return this._moduleRegistry.services.contextMenuService;
316
- }
317
- get mountElement() {
318
- return this.gridview.element;
319
- }
320
- hasVisibleGridGroup() {
321
- return this.groups.some((group) => group.api.location.type === 'grid' && group.api.isVisible);
322
- }
323
- fireLayoutChange() {
324
- this._bufferOnDidLayoutChange.fire();
325
- }
326
- /**
327
- * Promise that resolves when all popout groups from the last fromJSON call are restored.
328
- * Useful for tests that need to wait for delayed popout creation.
329
- */
330
- get popoutRestorationPromise() {
331
- var _a, _b;
332
- return ((_b = (_a = this._popoutWindowService) === null || _a === void 0 ? void 0 : _a.restorationPromise) !== null && _b !== void 0 ? _b : Promise.resolve());
333
- }
334
- constructor(container, options) {
335
- var _a, _b, _c, _d, _e;
336
- super(container, {
337
- proportionalLayout: true,
338
- orientation: Orientation.HORIZONTAL,
339
- styles: options.hideBorders
340
- ? { separatorBorder: 'transparent' }
341
- : undefined,
342
- disableAutoResizing: options.disableAutoResizing,
343
- locked: options.locked,
344
- margin: (_b = (_a = options.theme) === null || _a === void 0 ? void 0 : _a.gap) !== null && _b !== void 0 ? _b : 0,
345
- className: options.className,
346
- });
347
- this.nextGroupId = sequentialNumberGenerator();
348
- this._deserializer = new DefaultDockviewDeserialzier(this);
349
- this._moduleRegistry = new ModuleRegistry();
350
- this._onWillDragPanel = new Emitter();
351
- this.onWillDragPanel = this._onWillDragPanel.event;
352
- this._onWillDragGroup = new Emitter();
353
- this.onWillDragGroup = this._onWillDragGroup.event;
354
- this._onDidDrop = new Emitter();
355
- this.onDidDrop = this._onDidDrop.event;
356
- this._onWillDrop = new Emitter();
357
- this.onWillDrop = this._onWillDrop.event;
358
- // Transaction boundary bracketing each top-level structural mutation.
359
- // Compound operations (e.g. a drag that relocates a panel) nest via the
360
- // depth counter and bracket as a single transaction. See `mutation()`.
361
- this._mutationDepth = 0;
362
- // Current operation origin. Defaults to `'user'`; the DockviewApi boundary
363
- // flips it to `'api'` for the duration of a programmatic call via
364
- // `withOrigin`. Nested operations inherit the outermost origin (tracked by
365
- // `_originDepth`, independent of mutation bracketing so it also covers
366
- // active-panel changes that are not structural mutations).
367
- this._origin = 'user';
368
- this._originDepth = 0;
369
- this._onWillMutateLayout = new Emitter();
370
- this.onWillMutateLayout = this._onWillMutateLayout.event;
371
- this._onDidMutateLayout = new Emitter();
372
- this.onDidMutateLayout = this._onDidMutateLayout.event;
373
- this._onWillShowOverlay = new Emitter();
374
- this.onWillShowOverlay = this._onWillShowOverlay.event;
375
- this._onUnhandledDragOver = new Emitter();
376
- this.onUnhandledDragOver = this._onUnhandledDragOver.event;
377
- this._onDidRemovePanel = new Emitter();
378
- this.onDidRemovePanel = this._onDidRemovePanel.event;
379
- this._onDidAddPanel = new Emitter();
380
- this.onDidAddPanel = this._onDidAddPanel.event;
381
- this._onDidPopoutGroupSizeChange = new Emitter();
382
- this.onDidPopoutGroupSizeChange = this._onDidPopoutGroupSizeChange.event;
383
- this._onDidPopoutGroupPositionChange = new Emitter();
384
- this.onDidPopoutGroupPositionChange = this._onDidPopoutGroupPositionChange.event;
385
- this._onDidAddPopoutGroup = new Emitter();
386
- this.onDidAddPopoutGroup = this._onDidAddPopoutGroup.event;
387
- this._onDidRemovePopoutGroup = new Emitter();
388
- this.onDidRemovePopoutGroup = this._onDidRemovePopoutGroup.event;
389
- this._onDidOpenPopoutWindowFail = new Emitter();
390
- this.onDidOpenPopoutWindowFail = this._onDidOpenPopoutWindowFail.event;
391
- this._onDidLayoutFromJSON = new Emitter();
392
- this.onDidLayoutFromJSON = this._onDidLayoutFromJSON.event;
393
- this._onDidActivePanelChange = new Emitter({ replay: true });
394
- this.onDidActivePanelChange = this._onDidActivePanelChange.event;
395
- this._onDidMovePanel = new Emitter();
396
- this.onDidMovePanel = this._onDidMovePanel.event;
397
- this._onDidCreateTabGroup = new Emitter();
398
- this.onDidCreateTabGroup = this._onDidCreateTabGroup.event;
399
- this._onDidDestroyTabGroup = new Emitter();
400
- this.onDidDestroyTabGroup = this._onDidDestroyTabGroup.event;
401
- this._onDidAddPanelToTabGroup = new Emitter();
402
- this.onDidAddPanelToTabGroup = this._onDidAddPanelToTabGroup.event;
403
- this._onDidRemovePanelFromTabGroup = new Emitter();
404
- this.onDidRemovePanelFromTabGroup = this._onDidRemovePanelFromTabGroup.event;
405
- this._onDidTabGroupChange = new Emitter();
406
- this.onDidTabGroupChange = this._onDidTabGroupChange.event;
407
- this._onDidTabGroupCollapsedChange = new Emitter();
408
- this.onDidTabGroupCollapsedChange = this._onDidTabGroupCollapsedChange.event;
409
- this._onDidMaximizedGroupChange = new Emitter();
410
- this.onDidMaximizedGroupChange = this._onDidMaximizedGroupChange.event;
411
- this._inShellLayout = false;
412
- this._onDidRemoveGroup = new Emitter();
413
- this.onDidRemoveGroup = this._onDidRemoveGroup.event;
414
- this._onDidAddGroup = new Emitter();
415
- this.onDidAddGroup = this._onDidAddGroup.event;
416
- this._onDidOptionsChange = new Emitter();
417
- this.onDidOptionsChange = this._onDidOptionsChange.event;
418
- this._onDidActiveGroupChange = new Emitter();
419
- this.onDidActiveGroupChange = this._onDidActiveGroupChange.event;
420
- this._moving = false;
421
- this._options = options;
422
- this._tabGroupColorPalette = buildTabGroupColorPalette(options);
423
- // Internal seam: defaults to the full set, but tests can supply a
424
- // subset to assert every module is independently removable (and the
425
- // opt-in module API will build on this later). Not part of the public
426
- // options surface.
427
- const explicitModules = options
428
- .modules;
429
- const modules = explicitModules !== null && explicitModules !== void 0 ? explicitModules : [
430
- ...AllModules,
431
- ...getRegisteredModules(),
432
- ];
433
- for (const module of modules) {
434
- this._moduleRegistry.register(module);
435
- }
436
- this._moduleRegistry.initialize(this);
437
- // Surface popout removal symmetrically with `onDidAddPopoutGroup`. The
438
- // service is the single point every removal path funnels through — a
439
- // genuine window close and an explicit removal alike — and it suppresses
440
- // the event during component teardown.
441
- const popoutWindowService = this._popoutWindowService;
442
- if (popoutWindowService) {
443
- this.addDisposables(popoutWindowService.onDidRemove((entry) => {
444
- this._onDidRemovePopoutGroup.fire({
445
- id: entry.popoutGroup.id,
446
- group: entry.popoutGroup,
447
- window: entry.getWindow(),
448
- });
449
- }));
450
- }
451
- // Purely a developer warning (no functional effect): nudge anyone using
452
- // the internal `dockview-core` package directly towards `dockview`.
453
- warnIfUsingCoreDirectly();
454
- this.popupService = new PopupService(this.element);
455
- this._api = new DockviewApi(this);
456
- // The shell always wraps the dockview element so edge groups can be
457
- // added at any time via addEdgeGroup() without re-parenting the DOM.
458
- this.disableResizing = true;
459
- this.element.remove();
460
- this._shellManager = new ShellManager(container, this.element, (w, h) => this._layoutFromShell(w, h), (_d = (_c = options.theme) === null || _c === void 0 ? void 0 : _c.gap) !== null && _d !== void 0 ? _d : 0, (_e = options.theme) === null || _e === void 0 ? void 0 : _e.edgeGroupCollapsedSize);
461
- // The shell wraps the dockview element, so move the popup anchor
462
- // into the shell so overflow dropdowns in edge groups position correctly
463
- this.popupService.updateRoot(this._shellManager.element);
464
- this._shellThemeClassnames = new Classnames(this._shellManager.element);
465
- // Anchor the overlay container to the shell element so that edge groups
466
- // (which live outside this.element in the shell layout) are covered when
467
- // dndOverlayMounting is 'absolute'.
468
- this.rootDropTargetContainer = new DropTargetAnchorContainer(this._shellManager.element, { disabled: true });
469
- this.overlayRenderContainer = new OverlayRenderContainer(this._shellManager.element, this);
470
- // Hosted in the shell (not inside `.dv-dockview`) so floating overlays
471
- // share a stacking context with `dv-render-overlay` panels; sized to
472
- // mirror the gridview rect so saved positions remain valid.
473
- this._floatingOverlayHost = document.createElement('div');
474
- this._floatingOverlayHost.className = 'dv-floating-overlay-host';
475
- this._shellManager.element.appendChild(this._floatingOverlayHost);
476
- toggleClass(this.gridview.element, 'dv-dockview', true);
477
- toggleClass(this.element, 'dv-debug', !!options.debug);
478
- this.updateTheme();
479
- if (options.debug) {
480
- this.addDisposables(new StrictEventsSequencing(this));
481
- }
482
- this.addDisposables(this.rootDropTargetContainer, this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onWillShowOverlay, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, this._onWillDrop, this._onWillMutateLayout, this._onDidMutateLayout, this._onDidMovePanel, this._onDidMovePanel.event(() => {
483
- /**
484
- * Update overlay positions after DOM layout completes to prevent 0×0 dimensions.
485
- * With defaultRenderer="always" this results in panel content not showing after move operations.
486
- * Debounced to avoid multiple calls when moving groups with multiple panels.
487
- */
488
- this.debouncedUpdateAllPositions();
489
- }), this._onDidAddGroup, this._onDidRemoveGroup, this._onDidActiveGroupChange, this._onUnhandledDragOver, this._onDidMaximizedGroupChange, this._onDidPopoutGroupSizeChange, this._onDidPopoutGroupPositionChange, this._onDidAddPopoutGroup, this._onDidRemovePopoutGroup, this._onDidOpenPopoutWindowFail, this._onDidCreateTabGroup, this._onDidDestroyTabGroup, this._onDidAddPanelToTabGroup, this._onDidRemovePanelFromTabGroup, this._onDidTabGroupChange, this._onDidTabGroupCollapsedChange, Event.any(this.onDidPopoutGroupSizeChange, this.onDidPopoutGroupPositionChange, this.onDidCreateTabGroup, this.onDidDestroyTabGroup, this.onDidAddPanelToTabGroup, this.onDidRemovePanelFromTabGroup, this.onDidTabGroupChange, this.onDidTabGroupCollapsedChange)(() => {
490
- // Popout size/position and tab-group mutations persist as layout changes.
491
- this.fireLayoutChange();
492
- }), this._onDidOptionsChange, this.onDidAdd((event) => {
493
- if (!this._moving) {
494
- this._onDidAddGroup.fire(event);
495
- }
496
- }), this.onDidRemove((event) => {
497
- if (!this._moving) {
498
- this._onDidRemoveGroup.fire(event);
499
- }
500
- }), this.onDidActiveChange((event) => {
501
- if (!this._moving) {
502
- this._onDidActiveGroupChange.fire(event);
503
- }
504
- }), this.onDidMaximizedChange((event) => {
505
- this._onDidMaximizedGroupChange.fire({
506
- group: event.panel,
507
- isMaximized: event.isMaximized,
508
- });
509
- }), Event.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidAddGroup, this.onDidRemove, this.onDidRemoveGroup, this.onDidMovePanel, this.onDidActivePanelChange)(() => {
510
- this._bufferOnDidLayoutChange.fire();
511
- }), Disposable.from(() => {
512
- var _a;
513
- // Registry disposes init() subscriptions then every module
514
- // service that implements IDisposable. The order matters so
515
- // init handlers stop firing into services about to be torn
516
- // down. Includes popout-restoration timer cancellation that
517
- // resolves promises so awaiters of popoutRestorationPromise
518
- // don't hang. See issue #851.
519
- this._moduleRegistry.dispose();
520
- (_a = this._shellManager) === null || _a === void 0 ? void 0 : _a.dispose();
521
- }));
522
- // Root edge-drop wiring lives with its (optional) module — guard it so
523
- // the module is independently removable.
524
- const rootDropTarget = this._rootDropTargetService;
525
- if (rootDropTarget) {
526
- this.addDisposables(rootDropTarget.onWillShowOverlay((event) => {
527
- if (this.gridview.length > 0 &&
528
- event.position === 'center') {
529
- // option only available when no panels in primary grid
530
- return;
531
- }
532
- this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
533
- kind: 'edge',
534
- panel: undefined,
535
- api: this._api,
536
- group: undefined,
537
- getData: getPanelData,
538
- }));
539
- }), rootDropTarget.onDrop((event) => {
540
- var _a;
541
- const willDropEvent = new DockviewWillDropEvent({
542
- nativeEvent: event.nativeEvent,
543
- position: event.position,
544
- panel: undefined,
545
- api: this._api,
546
- group: undefined,
547
- getData: getPanelData,
548
- kind: 'edge',
549
- });
550
- this._onWillDrop.fire(willDropEvent);
551
- if (willDropEvent.defaultPrevented) {
552
- return;
553
- }
554
- const data = getPanelData();
555
- if (data) {
556
- this.moveGroupOrPanel({
557
- from: {
558
- groupId: data.groupId,
559
- panelId: (_a = data.panelId) !== null && _a !== void 0 ? _a : undefined,
560
- },
561
- to: {
562
- group: this.orthogonalize(event.position),
563
- position: 'center',
564
- },
565
- });
566
- }
567
- else {
568
- this._onDidDrop.fire(new DockviewDidDropEvent({
569
- nativeEvent: event.nativeEvent,
570
- position: event.position,
571
- panel: undefined,
572
- api: this._api,
573
- group: undefined,
574
- getData: getPanelData,
575
- }));
576
- }
577
- }));
578
- }
579
- // Final module wiring: runs after the host is fully constructed.
580
- // Modules subscribe to host events here so the component doesn't
581
- // need to manually invoke them at scattered call sites.
582
- this._moduleRegistry.postConstruct(this);
583
- }
584
- setVisible(panel, visible) {
585
- switch (panel.api.location.type) {
586
- case 'grid':
587
- super.setVisible(panel, visible);
588
- break;
589
- case 'floating': {
590
- const item = this.floatingGroups.find((floatingGroup) => floatingGroup.group === panel);
591
- if (item) {
592
- item.overlay.setVisible(visible);
593
- panel.api._onDidVisibilityChange.fire({
594
- isVisible: visible,
595
- });
596
- }
597
- break;
598
- }
599
- case 'popout':
600
- console.warn('dockview: You cannot hide a group that is in a popout window');
601
- break;
602
- case 'edge':
603
- // Edge group visibility is managed via setEdgeGroupVisible
604
- break;
605
- }
606
- }
607
- /**
608
- * Returns the {@link PopupService} that should host popovers (context
609
- * menus, tab overflow menus) for the given group. Popout groups have their
610
- * own service rooted in their popout window so the popover renders there
611
- * and dismisses on events from that window.
612
- */
613
- getPopupServiceForGroup(group) {
614
- var _a, _b;
615
- return ((_b = (_a = this._popoutWindowService) === null || _a === void 0 ? void 0 : _a.getPopupService(group.id)) !== null && _b !== void 0 ? _b : this.popupService);
616
- }
617
- addPopoutGroup(itemToPopout, options) {
618
- // The transaction brackets the synchronous structural change; the
619
- // popout window opens asynchronously after it resolves.
620
- return this.mutation('popout', () => this._doAddPopoutGroup(itemToPopout, options));
621
- }
622
- /** Enumerate the popout groups currently open in their own windows. */
623
- getPopouts() {
624
- var _a, _b;
625
- return ((_b = (_a = this._popoutWindowService) === null || _a === void 0 ? void 0 : _a.entries.map((entry) => ({
626
- id: entry.popoutGroup.id,
627
- group: entry.popoutGroup,
628
- window: entry.getWindow(),
629
- }))) !== null && _b !== void 0 ? _b : []);
630
- }
631
- _doAddPopoutGroup(itemToPopout, options) {
632
- var _a, _b, _c, _d, _e;
633
- const service = assertModule(this._popoutWindowService, 'PopoutWindow', 'api.addPopoutGroup');
634
- if (!service) {
635
- return Promise.resolve(false);
636
- }
637
- if (itemToPopout instanceof DockviewGroupPanel &&
638
- itemToPopout.model.location.type === 'edge') {
639
- // edge groups are permanent structural elements and cannot be popped out
640
- return Promise.resolve(false);
641
- }
642
- if (itemToPopout instanceof DockviewPanel &&
643
- itemToPopout.group.size === 1) {
644
- return this.addPopoutGroup(itemToPopout.group, options);
645
- }
646
- const theme = getDockviewTheme(this.gridview.element);
647
- const element = this.element;
648
- function getBox() {
649
- if (options === null || options === void 0 ? void 0 : options.position) {
650
- return options.position;
651
- }
652
- if (itemToPopout instanceof DockviewGroupPanel) {
653
- return itemToPopout.element.getBoundingClientRect();
654
- }
655
- if (itemToPopout.group) {
656
- return itemToPopout.group.element.getBoundingClientRect();
657
- }
658
- return element.getBoundingClientRect();
659
- }
660
- const box = getBox();
661
- 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();
662
- // Resolve the configured popout URL once (per-call override → global
663
- // option). Recorded on the entry / group locations so it survives
664
- // serialization; the '/popout.html' default is applied only when
665
- // actually opening the window, not baked into saved layouts.
666
- const resolvedPopoutUrl = (_c = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _c !== void 0 ? _c : (_d = this.options) === null || _d === void 0 ? void 0 : _d.popoutUrl;
667
- const _window = new PopoutWindow(`${this.id}-${groupId}`, // unique id
668
- theme !== null && theme !== void 0 ? theme : '', {
669
- url: resolvedPopoutUrl !== null && resolvedPopoutUrl !== void 0 ? resolvedPopoutUrl : '/popout.html',
670
- left: window.screenX + box.left,
671
- top: window.screenY + box.top,
672
- width: box.width,
673
- height: box.height,
674
- onDidOpen: options === null || options === void 0 ? void 0 : options.onDidOpen,
675
- onWillClose: options === null || options === void 0 ? void 0 : options.onWillClose,
676
- nonce: (_e = this.options) === null || _e === void 0 ? void 0 : _e.nonce,
677
- });
678
- const popoutWindowDisposable = new CompositeDisposable(_window, _window.onDidClose(() => {
679
- popoutWindowDisposable.dispose();
680
- }));
681
- return _window
682
- .open()
683
- .then((popoutContainer) => {
684
- var _a, _b, _c, _d;
685
- if (_window.isDisposed) {
686
- return false;
687
- }
688
- const referenceGroup = (_a = options === null || options === void 0 ? void 0 : options.referenceGroup) !== null && _a !== void 0 ? _a : (itemToPopout instanceof DockviewPanel
689
- ? itemToPopout.group
690
- : itemToPopout);
691
- const referenceLocation = itemToPopout.api.location.type;
692
- /**
693
- * The group that is being added doesn't already exist within the DOM, the most likely occurrence
694
- * of this case is when being called from the `fromJSON(...)` method
695
- */
696
- const isGroupAddedToDom = referenceGroup.element.parentElement !== null;
697
- let group;
698
- if (options === null || options === void 0 ? void 0 : options.overridePopoutGridview) {
699
- // Restoring a multi-group window: the anchor group is
700
- // already built inside the supplied gridview.
701
- group = (_b = options.overridePopoutGroup) !== null && _b !== void 0 ? _b : referenceGroup;
702
- }
703
- else if (!isGroupAddedToDom) {
704
- group = referenceGroup;
705
- }
706
- else if (options === null || options === void 0 ? void 0 : options.overridePopoutGroup) {
707
- group = options.overridePopoutGroup;
708
- }
709
- else {
710
- group = this.createGroup({ id: groupId });
711
- if (popoutContainer) {
712
- this._onDidAddGroup.fire(group);
713
- }
714
- }
715
- if (popoutContainer === null) {
716
- this.handleBlockedPopout({
717
- group,
718
- referenceGroup,
719
- options,
720
- popoutWindowDisposable,
721
- });
722
- return false;
723
- }
724
- const gready = document.createElement('div');
725
- gready.className = 'dv-overlay-render-container';
726
- const overlayRenderContainer = new OverlayRenderContainer(gready, this);
727
- group.model.renderContainer = overlayRenderContainer;
728
- // The popout window hosts its own gridview so it can grow into
729
- // a nested splitview layout. The window starts with the single
730
- // anchor group; further groups arrive via drag-and-drop. On
731
- // restore a pre-populated gridview is supplied instead.
732
- const popoutGridview = (_c = options === null || options === void 0 ? void 0 : options.overridePopoutGridview) !== null && _c !== void 0 ? _c : this.createNestedGridview();
733
- if (!(options === null || options === void 0 ? void 0 : options.overridePopoutGridview)) {
734
- popoutGridview.addView(group, Sizing.Distribute, [0]);
735
- }
736
- // Fill the popout window. Unlike the main grid (explicit px) and
737
- // floating windows (CSS inside .dv-resize-container), the popout
738
- // gridview has no sizing context, so without this it collapses
739
- // to 0 height and nothing renders.
740
- popoutGridview.element.style.width = '100%';
741
- popoutGridview.element.style.height = '100%';
742
- popoutGridview.layout(_window.window.innerWidth, _window.window.innerHeight);
743
- // Guarded so the teardown's re-entrant paths (window close
744
- // re-enters via the anchor's doRemoveGroup) never double-dispose.
745
- let popoutGridviewDisposed = false;
746
- const disposePopoutGridview = () => {
747
- if (!popoutGridviewDisposed) {
748
- popoutGridviewDisposed = true;
749
- popoutGridview.dispose();
750
- }
751
- };
752
- let floatingBox;
753
- if (!(options === null || options === void 0 ? void 0 : options.overridePopoutGroup) &&
754
- !(options === null || options === void 0 ? void 0 : options.overridePopoutGridview) &&
755
- isGroupAddedToDom) {
756
- if (itemToPopout instanceof DockviewPanel) {
757
- this.movingLock(() => {
758
- const panel = referenceGroup.model.removePanel(itemToPopout);
759
- group.model.openPanel(panel);
760
- });
761
- }
762
- else {
763
- this.movingLock(() => moveGroupWithoutDestroying({
764
- from: referenceGroup,
765
- to: group,
766
- }));
767
- switch (referenceLocation) {
768
- case 'grid':
769
- referenceGroup.api.setVisible(false);
770
- break;
771
- case 'floating':
772
- case 'popout':
773
- floatingBox = (_d = this.floatingGroups
774
- .find((value) => value.group.api.id ===
775
- itemToPopout.api.id)) === null || _d === void 0 ? void 0 : _d.overlay.toJSON();
776
- this.removeGroup(referenceGroup);
777
- break;
778
- }
779
- }
780
- }
781
- popoutContainer.classList.add('dv-dockview');
782
- popoutContainer.style.overflow = 'hidden';
783
- popoutContainer.appendChild(gready);
784
- popoutContainer.appendChild(popoutGridview.element);
785
- const anchor = document.createElement('div');
786
- const dropTargetContainer = new DropTargetAnchorContainer(anchor, { disabled: this.rootDropTargetContainer.disabled });
787
- popoutContainer.appendChild(anchor);
788
- group.model.dropTargetContainer = dropTargetContainer;
789
- // Each popout group needs its own popover service so that
790
- // tab context menus, chip menus, and tab overflow menus
791
- // render in the popout window (not the main window) and
792
- // their pointerdown/keydown listeners fire on the right
793
- // window for outside-click and Escape dismissal.
794
- const popoutPopupService = new PopupService(popoutContainer, _window.window);
795
- service.setPopupService(group.id, popoutPopupService);
796
- popoutWindowDisposable.addDisposables(popoutPopupService, Disposable.from(() => {
797
- service.deletePopupService(group.id);
798
- }));
799
- group.model.location = {
800
- type: 'popout',
801
- getWindow: () => _window.window,
802
- popoutUrl: resolvedPopoutUrl,
803
- };
804
- if (options === null || options === void 0 ? void 0 : options.overridePopoutGridview) {
805
- // Restored multi-group window. Wire every member (including
806
- // the anchor) to this window's containers and popout
807
- // location now that the gridview is attached and laid out —
808
- // re-setting renderContainer forces a re-render at the right
809
- // time so 'always'-rendered content positions in this
810
- // window rather than where it was first created.
811
- const members = this.groups.filter((candidate) => popoutGridview.element.contains(candidate.element));
812
- for (const member of members) {
813
- member.model.renderContainer = overlayRenderContainer;
814
- member.model.dropTargetContainer = dropTargetContainer;
815
- member.model.location = {
816
- type: 'popout',
817
- getWindow: () => _window.window,
818
- popoutUrl: resolvedPopoutUrl,
819
- };
820
- }
821
- }
822
- if (isGroupAddedToDom &&
823
- itemToPopout.api.location.type === 'grid') {
824
- itemToPopout.api.setVisible(false);
825
- }
826
- this.doSetGroupAndPanelActive(group);
827
- const resizeObserverDisposable = service.observeGridviewSize(_window, popoutGridview, overlayRenderContainer);
828
- if (resizeObserverDisposable) {
829
- popoutWindowDisposable.addDisposables(resizeObserverDisposable);
830
- }
831
- popoutWindowDisposable.addDisposables(group.api.onDidActiveChange((event) => {
832
- var _a;
833
- if (event.isActive) {
834
- (_a = _window.window) === null || _a === void 0 ? void 0 : _a.focus();
835
- }
836
- }), group.api.onWillFocus(() => {
837
- var _a;
838
- (_a = _window.window) === null || _a === void 0 ? void 0 : _a.focus();
839
- }));
840
- // Holder so the close teardown (extracted below) can publish
841
- // the group that was returned to the main grid back to the
842
- // entry's `dispose()` contract.
843
- const closeResult = {};
844
- const isValidReferenceGroup = isGroupAddedToDom &&
845
- referenceGroup &&
846
- this.getPanel(referenceGroup.id);
847
- const value = {
848
- window: _window,
849
- popoutGroup: group,
850
- gridview: popoutGridview,
851
- overlayRenderContainer,
852
- dropTargetContainer,
853
- getWindow: () => _window.window,
854
- popoutUrl: resolvedPopoutUrl,
855
- referenceGroup: isValidReferenceGroup
856
- ? referenceGroup.id
857
- : undefined,
858
- disposable: {
859
- dispose: () => {
860
- popoutWindowDisposable.dispose();
861
- return closeResult.returnedGroup;
862
- },
863
- },
864
- };
865
- const _onDidWindowPositionChange = onDidWindowMoveEnd(_window.window);
866
- popoutWindowDisposable.addDisposables(_onDidWindowPositionChange, onDidWindowResizeEnd(_window.window, () => {
867
- this._onDidPopoutGroupSizeChange.fire({
868
- width: _window.window.innerWidth,
869
- height: _window.window.innerHeight,
870
- group,
871
- });
872
- }), _onDidWindowPositionChange.event(() => {
873
- this._onDidPopoutGroupPositionChange.fire({
874
- screenX: _window.window.screenX,
875
- screenY: _window.window.screenX,
876
- group,
877
- });
878
- }), addDisposableListener(_window.window, 'resize', () => {
879
- popoutGridview.layout(_window.window.innerWidth, _window.window.innerHeight);
880
- }), overlayRenderContainer, Disposable.from(() => this.disposePopoutWindow({
881
- group,
882
- referenceGroup,
883
- popoutGridview,
884
- isGroupAddedToDom,
885
- floatingBox,
886
- disposePopoutGridview,
887
- closeResult,
888
- })));
889
- service.add(value);
890
- this._onDidAddPopoutGroup.fire({
891
- id: value.popoutGroup.id,
892
- group: value.popoutGroup,
893
- window: value.getWindow(),
894
- });
895
- return true;
896
- })
897
- .catch((err) => {
898
- console.error('dockview: failed to create popout.', err);
899
- return false;
900
- });
901
- }
902
- /**
903
- * The popout window was blocked (e.g. by the browser's popup blocker —
904
- * common when restoring popouts on load). Fall back gracefully so the
905
- * group(s) end up valid and visible in the main grid rather than as
906
- * orphans that later crash clear()/remove().
907
- */
908
- handleBlockedPopout(params) {
909
- const { group, referenceGroup, options, popoutWindowDisposable } = params;
910
- console.error('dockview: failed to create popout. perhaps you need to allow pop-ups for this website');
911
- popoutWindowDisposable.dispose();
912
- this._onDidOpenPopoutWindowFail.fire();
913
- if (options === null || options === void 0 ? void 0 : options.overridePopoutGridview) {
914
- // Restoring a multi-group popout window: its nested gridview was
915
- // built up-front but never attached to a window. Dock every member
916
- // into the main grid so no group is lost, then discard the
917
- // detached gridview.
918
- const blockedGridview = options.overridePopoutGridview;
919
- const members = this.groups.filter((candidate) => blockedGridview.element.contains(candidate.element));
920
- for (const member of members) {
921
- this.movingLock(() => {
922
- blockedGridview.remove(member);
923
- this.redockGroupToMainGrid(member);
924
- });
925
- }
926
- blockedGridview.dispose();
927
- if (referenceGroup && !referenceGroup.api.isVisible) {
928
- referenceGroup.api.setVisible(true);
929
- }
930
- return;
931
- }
932
- if (group === referenceGroup) {
933
- // No separate grid group to return to (e.g. restoring a popout
934
- // straight from JSON) — dock this group into the main grid.
935
- if (!this.gridview.element.contains(group.element)) {
936
- this.movingLock(() => this.doAddGroup(group, [0]));
937
- group.model.location = { type: 'grid' };
938
- }
939
- }
940
- else {
941
- // A fresh group was created for the popout — return its panels to
942
- // the reference group and discard the now-empty popout group so it
943
- // doesn't linger as an orphan.
944
- this.movingLock(() => moveGroupWithoutDestroying({
945
- from: group,
946
- to: referenceGroup,
947
- }));
948
- if (group.model.size === 0 && this._groups.has(group.id)) {
949
- group.dispose();
950
- this._groups.delete(group.id);
951
- this._onDidRemoveGroup.fire(group);
952
- }
953
- }
954
- if (!referenceGroup.api.isVisible) {
955
- referenceGroup.api.setVisible(true);
956
- }
957
- }
958
- /**
959
- * Wire a group that has been displaced from a floating / popout window back
960
- * to the main grid's render & drop-target containers and dock it at the
961
- * root. The caller is responsible for first detaching it from its old
962
- * gridview — the detach strategy differs between the window-teardown path
963
- * (`doRemoveGroup`) and the blocked-window path (`gridview.remove`).
964
- */
965
- redockGroupToMainGrid(group) {
966
- group.model.renderContainer = this.overlayRenderContainer;
967
- group.model.dropTargetContainer = this.rootDropTargetContainer;
968
- group.model.location = { type: 'grid' };
969
- this.doAddGroup(group, [0]);
970
- }
971
- /**
972
- * Teardown for a popout window's `popoutWindowDisposable`. Runs when the
973
- * window closes (by user, by `removeGroup`, or by component disposal):
974
- * relocates every member group back to the main grid (or to a floating
975
- * window when the anchor came from one), then disposes the nested gridview.
976
- * `closeResult.returnedGroup` is read by the entry's `dispose()` contract.
977
- */
978
- disposePopoutWindow(params) {
979
- var _a;
980
- const { group, referenceGroup, popoutGridview, isGroupAddedToDom, floatingBox, disposePopoutGridview, closeResult, } = params;
981
- if (this.isDisposed) {
982
- // cleanup may run after instance is disposed; just tear down the
983
- // nested gridview.
984
- disposePopoutGridview();
985
- return;
986
- }
987
- // Distinguish a genuine window close from an explicit `removeGroup`:
988
- // the explicit-removal paths remove the service entry *before* this
989
- // disposable runs. Key off the stable `popoutGridview` rather than the
990
- // captured `group`, which may no longer be the window's anchor (it can
991
- // have been dragged out, promoting another member to anchor).
992
- const genuineClose = !!((_a = this._popoutWindowService) === null || _a === void 0 ? void 0 : _a.entries.find((entry) => entry.gridview === popoutGridview));
993
- // The groups still living in this window, resolved from the gridview so
994
- // a reassigned anchor doesn't hide surviving members.
995
- const members = this.groups.filter((candidate) => popoutGridview.element.contains(candidate.element));
996
- const anchorPresent = members.includes(group);
997
- const anchorIsSoleMember = anchorPresent && members.length === 1;
998
- // On a genuine close, relocate every member that ISN'T the captured
999
- // anchor back to the main grid. The captured anchor (if still here) gets
1000
- // the reference-return / re-float treatment below. Explicit removal
1001
- // relocates via its own path, so the loop is skipped for it.
1002
- if (genuineClose) {
1003
- for (const member of members) {
1004
- if (member === group) {
1005
- continue;
1006
- }
1007
- this.movingLock(() => {
1008
- this.doRemoveGroup(member, {
1009
- skipDispose: true,
1010
- skipActive: true,
1011
- skipPopoutReturn: true,
1012
- });
1013
- this.redockGroupToMainGrid(member);
1014
- });
1015
- }
1016
- }
1017
- if (anchorPresent &&
1018
- isGroupAddedToDom &&
1019
- this.getPanel(referenceGroup.id)) {
1020
- this.movingLock(() => moveGroupWithoutDestroying({
1021
- from: group,
1022
- to: referenceGroup,
1023
- }));
1024
- if (!referenceGroup.api.isVisible) {
1025
- referenceGroup.api.setVisible(true);
1026
- }
1027
- if (this.getPanel(group.id)) {
1028
- this.doRemoveGroup(group, {
1029
- skipPopoutAssociated: true,
1030
- });
1031
- }
1032
- }
1033
- else if (anchorPresent && this.getPanel(group.id)) {
1034
- group.model.renderContainer = this.overlayRenderContainer;
1035
- group.model.dropTargetContainer = this.rootDropTargetContainer;
1036
- closeResult.returnedGroup = group;
1037
- if (!genuineClose) {
1038
- /**
1039
- * If this popout group was explicitly removed then we shouldn't run the additional
1040
- * steps. The explicit remover re-docks the returned group itself; here we only hand
1041
- * it back (above) and tear down the nested gridview.
1042
- */
1043
- disposePopoutGridview();
1044
- return;
1045
- }
1046
- // Re-float only restores the pre-popout state of a SINGLE popped-out
1047
- // group. A multi-group window must not be split (anchor re-floats
1048
- // while the rest dock to the grid), so dock the anchor to the grid
1049
- // alongside the other members once they're no longer alone.
1050
- if (floatingBox && anchorIsSoleMember) {
1051
- this.addFloatingGroup(group, {
1052
- height: floatingBox.height,
1053
- width: floatingBox.width,
1054
- position: floatingBox,
1055
- });
1056
- }
1057
- else {
1058
- this.doRemoveGroup(group, {
1059
- skipDispose: true,
1060
- skipActive: true,
1061
- skipPopoutReturn: true,
1062
- });
1063
- group.model.location = { type: 'grid' };
1064
- this.movingLock(() => {
1065
- // suppress group add events since the group already exists
1066
- this.doAddGroup(group, [0]);
1067
- });
1068
- }
1069
- this.doSetGroupAndPanelActive(group);
1070
- }
1071
- // All members have been relocated out; tear down the window's nested
1072
- // gridview (does not dispose the leaf views — their lifecycle stays
1073
- // with `_groups`).
1074
- disposePopoutGridview();
1075
- }
1076
- addFloatingGroup(item, options) {
1077
- this.mutation('float', () => this._doAddFloatingGroup(item, options));
1078
- }
1079
- _doAddFloatingGroup(item, options) {
1080
- var _a;
1081
- const service = assertModule(this._floatingGroupService, 'FloatingGroup', 'api.addFloatingGroup');
1082
- if (!service) {
1083
- return;
1084
- }
1085
- if (item instanceof DockviewGroupPanel &&
1086
- item.model.location.type === 'edge') {
1087
- // edge groups are permanent structural elements and cannot be floated
1088
- return;
1089
- }
1090
- let group;
1091
- if (item instanceof DockviewPanel) {
1092
- group = this.createGroup();
1093
- this._onDidAddGroup.fire(group);
1094
- this.movingLock(() => this.removePanel(item, {
1095
- removeEmptyGroup: true,
1096
- skipDispose: true,
1097
- skipSetActiveGroup: true,
1098
- }));
1099
- this.movingLock(() => group.model.openPanel(item, { skipSetGroupActive: true }));
1100
- }
1101
- else {
1102
- group = item;
1103
- const popoutReferenceGroupId = (_a = this._popoutWindowService) === null || _a === void 0 ? void 0 : _a.findReferenceGroupId(group);
1104
- const popoutReferenceGroup = popoutReferenceGroupId
1105
- ? this.getPanel(popoutReferenceGroupId)
1106
- : undefined;
1107
- const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' &&
1108
- options.skipRemoveGroup;
1109
- if (!skip) {
1110
- if (popoutReferenceGroup) {
1111
- this.movingLock(() => moveGroupWithoutDestroying({
1112
- from: item,
1113
- to: popoutReferenceGroup,
1114
- }));
1115
- this.doRemoveGroup(item, {
1116
- skipPopoutReturn: true,
1117
- skipPopoutAssociated: true,
1118
- });
1119
- this.doRemoveGroup(popoutReferenceGroup, {
1120
- skipDispose: true,
1121
- });
1122
- group = popoutReferenceGroup;
1123
- }
1124
- else {
1125
- this.doRemoveGroup(item, {
1126
- skipDispose: true,
1127
- skipPopoutReturn: true,
1128
- skipPopoutAssociated: false,
1129
- });
1130
- }
1131
- }
1132
- }
1133
- function getAnchoredBox() {
1134
- if (options === null || options === void 0 ? void 0 : options.position) {
1135
- const result = {};
1136
- if ('left' in options.position) {
1137
- result.left = Math.max(options.position.left, 0);
1138
- }
1139
- else if ('right' in options.position) {
1140
- result.right = Math.max(options.position.right, 0);
1141
- }
1142
- else {
1143
- result.left = DEFAULT_FLOATING_GROUP_POSITION.left;
1144
- }
1145
- if ('top' in options.position) {
1146
- result.top = Math.max(options.position.top, 0);
1147
- }
1148
- else if ('bottom' in options.position) {
1149
- result.bottom = Math.max(options.position.bottom, 0);
1150
- }
1151
- else {
1152
- result.top = DEFAULT_FLOATING_GROUP_POSITION.top;
1153
- }
1154
- if (typeof options.width === 'number') {
1155
- result.width = Math.max(options.width, 0);
1156
- }
1157
- else {
1158
- result.width = DEFAULT_FLOATING_GROUP_POSITION.width;
1159
- }
1160
- if (typeof options.height === 'number') {
1161
- result.height = Math.max(options.height, 0);
1162
- }
1163
- else {
1164
- result.height = DEFAULT_FLOATING_GROUP_POSITION.height;
1165
- }
1166
- return result;
1167
- }
1168
- return {
1169
- left: typeof (options === null || options === void 0 ? void 0 : options.x) === 'number'
1170
- ? Math.max(options.x, 0)
1171
- : DEFAULT_FLOATING_GROUP_POSITION.left,
1172
- top: typeof (options === null || options === void 0 ? void 0 : options.y) === 'number'
1173
- ? Math.max(options.y, 0)
1174
- : DEFAULT_FLOATING_GROUP_POSITION.top,
1175
- width: typeof (options === null || options === void 0 ? void 0 : options.width) === 'number'
1176
- ? Math.max(options.width, 0)
1177
- : DEFAULT_FLOATING_GROUP_POSITION.width,
1178
- height: typeof (options === null || options === void 0 ? void 0 : options.height) === 'number'
1179
- ? Math.max(options.height, 0)
1180
- : DEFAULT_FLOATING_GROUP_POSITION.height,
1181
- };
1182
- }
1183
- const anchoredBox = getAnchoredBox();
1184
- // The floating window hosts its own gridview so it can grow into a
1185
- // nested splitview layout. The window starts with the single anchor
1186
- // group; further groups are added via drag-and-drop.
1187
- const floatingGridview = this.createNestedGridview();
1188
- floatingGridview.addView(group, Sizing.Distribute, [0]);
1189
- this.mountFloatingWindow(floatingGridview, group, [group], anchoredBox, {
1190
- dragHandle: options === null || options === void 0 ? void 0 : options.dragHandle,
1191
- inDragMode: options === null || options === void 0 ? void 0 : options.inDragMode,
1192
- skipActiveGroup: options === null || options === void 0 ? void 0 : options.skipActiveGroup,
1193
- });
1194
- }
1195
- /**
1196
- * Build an empty gridview configured to match the main grid's styling, for
1197
- * hosting a nested layout inside a floating or popout window.
1198
- */
1199
- createNestedGridview(orientation = Orientation.HORIZONTAL) {
1200
- var _a, _b;
1201
- return new Gridview(true, this.options.hideBorders
1202
- ? { separatorBorder: 'transparent' }
1203
- : undefined, orientation, false, (_b = (_a = this.options.theme) === null || _a === void 0 ? void 0 : _a.gap) !== null && _b !== void 0 ? _b : 0);
1204
- }
1205
- /**
1206
- * Wrap a (populated) floating gridview in an overlay window: title bar /
1207
- * move handle, drag wiring, the floating-group service entry and the
1208
- * `floating` location tag for every member group.
1209
- */
1210
- mountFloatingWindow(floatingGridview, anchorGroup, members, anchoredBox, options) {
1211
- var _a, _b, _c, _d, _e, _f, _g, _h;
1212
- const service = assertModule(this._floatingGroupService, 'FloatingGroup', 'api.addFloatingGroup');
1213
- if (!service) {
1214
- return;
1215
- }
1216
- const dragHandleMode = (_b = (_a = options === null || options === void 0 ? void 0 : options.dragHandle) !== null && _a !== void 0 ? _a : this.options.floatingGroupDragHandle) !== null && _b !== void 0 ? _b : 'titlebar';
1217
- // `'titlebar'` renders a dedicated grab bar above the tab bar and uses
1218
- // it as the move handle; `'tabbar'` falls back to moving via the
1219
- // tab-bar void container.
1220
- const titleBar = dragHandleMode === 'titlebar'
1221
- ? new FloatingTitleBar(this, anchorGroup)
1222
- : undefined;
1223
- const overlay = new Overlay(Object.assign(Object.assign({ container: (_c = this._floatingOverlayHost) !== null && _c !== void 0 ? _c : this.gridview.element, content: floatingGridview.element, header: titleBar === null || titleBar === void 0 ? void 0 : titleBar.element }, anchoredBox), { minimumInViewportWidth: this.options.floatingGroupBounds === 'boundedWithinViewport'
1224
- ? undefined
1225
- : ((_e = (_d = this.options.floatingGroupBounds) === null || _d === void 0 ? void 0 : _d.minimumWidthWithinViewport) !== null && _e !== void 0 ? _e : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE), minimumInViewportHeight: this.options.floatingGroupBounds === 'boundedWithinViewport'
1226
- ? undefined
1227
- : ((_g = (_f = this.options.floatingGroupBounds) === null || _f === void 0 ? void 0 : _f.minimumHeightWithinViewport) !== null && _g !== void 0 ? _g : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE), transformDragPosition: this.options.transformFloatingGroupDrag
1228
- ? (context) => this.options.transformFloatingGroupDrag({
1229
- group: anchorGroup,
1230
- proposed: context.proposed,
1231
- container: context.container,
1232
- others: context.others,
1233
- })
1234
- : undefined, getSiblingBoxes: () => this._gatherFloatingGroupBoxes(anchorGroup) }));
1235
- const dragHandle = (_h = titleBar === null || titleBar === void 0 ? void 0 : titleBar.element) !== null && _h !== void 0 ? _h : anchorGroup.element.querySelector('.dv-void-container');
1236
- if (!dragHandle) {
1237
- throw new Error('dockview: failed to find drag handle');
1238
- }
1239
- overlay.setupDrag(dragHandle, {
1240
- inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean'
1241
- ? options.inDragMode
1242
- : false,
1243
- });
1244
- const floatingGroupPanel = service.add(anchorGroup, overlay, floatingGridview);
1245
- if (titleBar) {
1246
- // Tie the title bar's lifetime to the floating window and surface
1247
- // its redock drag through the same public `onWillDragGroup` event
1248
- // the tab-bar handle uses. Register it so anchor reassignment (when
1249
- // the original anchor leaves a multi-group window) retargets the
1250
- // bar at a group that still lives here.
1251
- floatingGroupPanel.setTitleBar(titleBar);
1252
- floatingGroupPanel.addDisposables(titleBar, Disposable.from(() => floatingGroupPanel.setTitleBar(undefined)), titleBar.onDragStart((event) => {
1253
- this._onWillDragGroup.fire({
1254
- nativeEvent: event,
1255
- group: floatingGroupPanel.group,
1256
- });
1257
- }));
1258
- }
1259
- for (const member of members) {
1260
- member.model.location = { type: 'floating' };
1261
- }
1262
- if (!(options === null || options === void 0 ? void 0 : options.skipActiveGroup)) {
1263
- this.doSetGroupAndPanelActive(anchorGroup);
1264
- }
1265
- }
1266
- orthogonalize(position, options) {
1267
- this.gridview.normalize();
1268
- switch (position) {
1269
- case 'top':
1270
- case 'bottom':
1271
- if (this.gridview.orientation === Orientation.HORIZONTAL) {
1272
- // we need to add to a vertical splitview but the current root is a horizontal splitview.
1273
- // insert a vertical splitview at the root level and add the existing view as a child
1274
- this.gridview.insertOrthogonalSplitviewAtRoot();
1275
- }
1276
- break;
1277
- case 'left':
1278
- case 'right':
1279
- if (this.gridview.orientation === Orientation.VERTICAL) {
1280
- // we need to add to a horizontal splitview but the current root is a vertical splitview.
1281
- // insert a horiziontal splitview at the root level and add the existing view as a child
1282
- this.gridview.insertOrthogonalSplitviewAtRoot();
1283
- }
1284
- break;
1285
- default:
1286
- break;
1287
- }
1288
- switch (position) {
1289
- case 'top':
1290
- case 'left':
1291
- case 'center':
1292
- return this.createGroupAtLocation([0], undefined, options); // insert into first position
1293
- case 'bottom':
1294
- case 'right':
1295
- return this.createGroupAtLocation([this.gridview.length], undefined, options); // insert into last position
1296
- default:
1297
- throw new Error(`dockview: unsupported position ${position}`);
1298
- }
1299
- }
1300
- updateOptions(options) {
1301
- var _a, _b, _c, _d, _e;
1302
- super.updateOptions(options);
1303
- (_a = this._floatingGroupService) === null || _a === void 0 ? void 0 : _a.updateBounds(options);
1304
- (_b = this._rootDropTargetService) === null || _b === void 0 ? void 0 : _b.setOptions(options);
1305
- const oldDisableDnd = this.options.disableDnd;
1306
- const oldDndStrategy = this.options.dndStrategy;
1307
- this._options = Object.assign(Object.assign({}, this.options), options);
1308
- const newDisableDnd = this.options.disableDnd;
1309
- const newDndStrategy = this.options.dndStrategy;
1310
- if (oldDisableDnd !== newDisableDnd ||
1311
- oldDndStrategy !== newDndStrategy) {
1312
- this.updateDragAndDropState();
1313
- }
1314
- if ('theme' in options) {
1315
- this.updateTheme();
1316
- }
1317
- if ('createRightHeaderActionComponent' in options ||
1318
- 'createLeftHeaderActionComponent' in options ||
1319
- 'createPrefixHeaderActionComponent' in options) {
1320
- (_c = this.headerActionsService) === null || _c === void 0 ? void 0 : _c.refreshAll();
1321
- }
1322
- if ('createWatermarkComponent' in options) {
1323
- (_d = this._watermarkService) === null || _d === void 0 ? void 0 : _d.refresh();
1324
- for (const group of this.groups) {
1325
- group.model.refreshWatermark();
1326
- }
1327
- }
1328
- if ('tabGroupColors' in options || 'tabGroupAccent' in options) {
1329
- this._tabGroupColorPalette.setEntries((_e = this._options.tabGroupColors) !== null && _e !== void 0 ? _e : DEFAULT_TAB_GROUP_COLORS);
1330
- this._tabGroupColorPalette.enabled =
1331
- this._options.tabGroupAccent !== 'off';
1332
- for (const group of this.groups) {
1333
- group.model.refreshTabGroupAccent();
1334
- }
1335
- }
1336
- this._onDidOptionsChange.fire();
1337
- this._layoutFromShell(this.gridview.width, this.gridview.height);
1338
- }
1339
- layout(width, height, forceResize) {
1340
- var _a, _b;
1341
- if (this._shellManager && !this._inShellLayout) {
1342
- this._shellManager.layout(width, height);
1343
- }
1344
- else {
1345
- super.layout(width, height, forceResize);
1346
- }
1347
- this._syncFloatingOverlayHost();
1348
- // floatingGroupService may be undefined during super() (BaseGrid calls
1349
- // layout(0, 0) before subclass field initialisers run).
1350
- (_b = (_a = this._moduleRegistry) === null || _a === void 0 ? void 0 : _a.services.floatingGroupService) === null || _b === void 0 ? void 0 : _b.constrainBounds();
1351
- }
1352
- _syncFloatingOverlayHost() {
1353
- if (!this._floatingOverlayHost || !this._shellManager) {
1354
- return;
1355
- }
1356
- const shellRect = this._shellManager.element.getBoundingClientRect();
1357
- const gridRect = this.element.getBoundingClientRect();
1358
- const host = this._floatingOverlayHost;
1359
- host.style.left = `${gridRect.left - shellRect.left}px`;
1360
- host.style.top = `${gridRect.top - shellRect.top}px`;
1361
- host.style.width = `${gridRect.width}px`;
1362
- host.style.height = `${gridRect.height}px`;
1363
- }
1364
- _layoutFromShell(width, height) {
1365
- this._inShellLayout = true;
1366
- this.layout(width, height, true);
1367
- this._inShellLayout = false;
1368
- }
1369
- forceRelayout() {
1370
- if (this._shellManager) {
1371
- this._layoutFromShell(this.width, this.height);
1372
- }
1373
- else {
1374
- super.forceRelayout();
1375
- }
1376
- }
1377
- addEdgeGroup(position, options) {
1378
- const service = assertModule(this._edgeGroupService, 'EdgeGroup', 'api.addEdgeGroup');
1379
- if (!service) {
1380
- throw new Error(`dockview: EdgeGroup module is not registered`);
1381
- }
1382
- if (service.has(position)) {
1383
- throw new Error(`dockview: edge group already exists at position '${position}'`);
1384
- }
1385
- return this.mutation('add', () => {
1386
- const group = this.createGroup({ id: options.id });
1387
- group.model.location = { type: 'edge', position };
1388
- group.model.headerPosition = position;
1389
- // Collapse when the group becomes empty
1390
- const autoCollapseDisposable = group.model.onDidRemovePanel(() => {
1391
- if (group.model.isEmpty) {
1392
- this.setEdgeGroupCollapsed(group, true);
1393
- }
1394
- });
1395
- service.add(position, group, autoCollapseDisposable);
1396
- this._onDidAddGroup.fire(group);
1397
- this._shellManager.addEdgeView(position, options, group);
1398
- return group.api;
1399
- });
1400
- }
1401
- getEdgeGroup(position) {
1402
- var _a, _b;
1403
- return (_b = (_a = this._edgeGroupService) === null || _a === void 0 ? void 0 : _a.get(position)) === null || _b === void 0 ? void 0 : _b.api;
1404
- }
1405
- setEdgeGroupVisible(position, visible) {
1406
- this._shellManager.setEdgeGroupVisible(position, visible);
1407
- }
1408
- isEdgeGroupVisible(position) {
1409
- return this._shellManager.isEdgeGroupVisible(position);
1410
- }
1411
- removeEdgeGroup(position) {
1412
- const service = assertModule(this._edgeGroupService, 'EdgeGroup', 'api.removeEdgeGroup');
1413
- if (!service) {
1414
- return;
1415
- }
1416
- const group = service.get(position);
1417
- if (!group) {
1418
- throw new Error(`dockview: no edge group exists at position '${position}'`);
1419
- }
1420
- // One transaction — the per-panel removals below nest via the depth
1421
- // counter, so consumers see a single edge-group removal.
1422
- this.mutation('remove', () => {
1423
- // Remove panels inside the group first
1424
- for (const panel of [...group.panels]) {
1425
- this.removePanel(panel, {
1426
- removeEmptyGroup: false,
1427
- skipDispose: false,
1428
- });
1429
- }
1430
- // Remove from the shell splitview
1431
- this._shellManager.removeEdgeView(position);
1432
- // Clean up service-tracked state + group itself
1433
- service.remove(position);
1434
- group.dispose();
1435
- this._groups.delete(group.id);
1436
- this._onDidRemoveGroup.fire(group);
1437
- });
1438
- }
1439
- setEdgeGroupCollapsed(group, collapsed) {
1440
- var _a;
1441
- const position = (_a = this._edgeGroupService) === null || _a === void 0 ? void 0 : _a.findPositionOf(group);
1442
- if (!position) {
1443
- return;
1444
- }
1445
- if (this._shellManager.isEdgeGroupCollapsed(position) === collapsed) {
1446
- // Skip the splitview resize on a no-op: with non-zero theme gap,
1447
- // redundant resizeView calls accumulate rounding drift that
1448
- // gradually shrinks the group.
1449
- return;
1450
- }
1451
- this._shellManager.setEdgeGroupCollapsed(position, collapsed);
1452
- group.api._onDidCollapsedChange.fire({ isCollapsed: collapsed });
1453
- }
1454
- isEdgeGroupCollapsed(group) {
1455
- var _a;
1456
- const position = (_a = this._edgeGroupService) === null || _a === void 0 ? void 0 : _a.findPositionOf(group);
1457
- return position
1458
- ? this._shellManager.isEdgeGroupCollapsed(position)
1459
- : false;
1460
- }
1461
- updateDragAndDropState() {
1462
- // Update draggable state for all tabs and void containers
1463
- for (const group of this.groups) {
1464
- group.model.updateDragAndDropState();
1465
- }
1466
- }
1467
- focus() {
1468
- var _a;
1469
- (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.focus();
1470
- }
1471
- getGroupPanel(id) {
1472
- return this.panels.find((panel) => panel.id === id);
1473
- }
1474
- setActivePanel(panel) {
1475
- panel.group.model.openPanel(panel);
1476
- this.doSetGroupAndPanelActive(panel.group);
1477
- }
1478
- moveToNext(options = {}) {
1479
- var _a;
1480
- if (!options.group) {
1481
- if (!this.activeGroup) {
1482
- return;
1483
- }
1484
- options.group = this.activeGroup;
1485
- }
1486
- if (options.includePanel && options.group) {
1487
- if (options.group.activePanel !==
1488
- options.group.panels[options.group.panels.length - 1]) {
1489
- options.group.model.moveToNext({ suppressRoll: true });
1490
- return;
1491
- }
1492
- }
1493
- const location = getGridLocation(options.group.element);
1494
- const next = (_a = this.gridview.next(location)) === null || _a === void 0 ? void 0 : _a.view;
1495
- this.doSetGroupAndPanelActive(next);
1496
- }
1497
- moveToPrevious(options = {}) {
1498
- var _a;
1499
- if (!options.group) {
1500
- if (!this.activeGroup) {
1501
- return;
1502
- }
1503
- options.group = this.activeGroup;
1504
- }
1505
- if (options.includePanel && options.group) {
1506
- if (options.group.activePanel !== options.group.panels[0]) {
1507
- options.group.model.moveToPrevious({ suppressRoll: true });
1508
- return;
1509
- }
1510
- }
1511
- const location = getGridLocation(options.group.element);
1512
- const next = (_a = this.gridview.previous(location)) === null || _a === void 0 ? void 0 : _a.view;
1513
- if (next) {
1514
- this.doSetGroupAndPanelActive(next);
1515
- }
1516
- }
1517
- /**
1518
- * Serialize the current state of the layout
1519
- *
1520
- * @returns A JSON respresentation of the layout
1521
- */
1522
- toJSON() {
1523
- var _a, _b, _c, _d, _e, _f, _g, _h;
1524
- const data = this.gridview.serialize();
1525
- const panels = this.panels.reduce((collection, panel) => {
1526
- collection[panel.id] = panel.toJSON();
1527
- return collection;
1528
- }, {});
1529
- const floats = (_b = (_a = this._floatingGroupService) === null || _a === void 0 ? void 0 : _a.serialize()) !== null && _b !== void 0 ? _b : [];
1530
- const popoutGroups = (_d = (_c = this._popoutWindowService) === null || _c === void 0 ? void 0 : _c.serialize()) !== null && _d !== void 0 ? _d : [];
1531
- const result = {
1532
- grid: data,
1533
- panels,
1534
- activeGroup: (_e = this.activeGroup) === null || _e === void 0 ? void 0 : _e.id,
1535
- };
1536
- if (floats.length > 0) {
1537
- result.floatingGroups = floats;
1538
- }
1539
- if (popoutGroups.length > 0) {
1540
- result.popoutGroups = popoutGroups;
1541
- }
1542
- const edgeEntries = (_g = (_f = this._edgeGroupService) === null || _f === void 0 ? void 0 : _f.entries()) !== null && _g !== void 0 ? _g : [];
1543
- if ((_h = this._edgeGroupService) === null || _h === void 0 ? void 0 : _h.hasAny()) {
1544
- const shellSerialized = this._shellManager.toJSON();
1545
- // Augment each entry with the serialized group state
1546
- for (const [position, group] of edgeEntries) {
1547
- const entry = shellSerialized[position];
1548
- if (entry) {
1549
- entry.group = group.toJSON();
1550
- }
1551
- }
1552
- result.edgeGroups = shellSerialized;
1553
- }
1554
- return result;
1555
- }
1556
- fromJSON(data, options) {
1557
- // One 'load' transaction for the whole deserialization — the many
1558
- // nested add/remove mutations join it via the depth counter.
1559
- this.mutation('load', () => this._doFromJSON(data, options));
1560
- }
1561
- _doFromJSON(data, options) {
1562
- var _a, _b, _c, _d, _e, _f, _g;
1563
- // Cancel any popout-restoration timers queued by a previous fromJSON
1564
- // that haven't fired yet. The cancel path also disposes orphan groups
1565
- // registered in _groups synchronously but never parented into a popout
1566
- // window — otherwise the upcoming clear() would call gridview.remove()
1567
- // on an unparented element and throw "Invalid grid element". See
1568
- // issue #1304.
1569
- (_a = this._popoutWindowService) === null || _a === void 0 ? void 0 : _a.cancelPendingRestorations();
1570
- const existingPanels = new Map();
1571
- let tempGroup;
1572
- if (options === null || options === void 0 ? void 0 : options.reuseExistingPanels) {
1573
- /**
1574
- * What are we doing here?
1575
- *
1576
- * 1. Create a temporary group to hold any panels that currently exist and that also exist in the new layout
1577
- * 2. Remove that temporary group from the group mapping so that it doesn't get cleared when we clear the layout
1578
- */
1579
- tempGroup = this.createGroup();
1580
- this._groups.delete(tempGroup.api.id);
1581
- const newPanels = Object.keys(data.panels);
1582
- for (const panel of this.panels) {
1583
- if (newPanels.includes(panel.api.id)) {
1584
- existingPanels.set(panel.api.id, panel);
1585
- }
1586
- }
1587
- this.movingLock(() => {
1588
- Array.from(existingPanels.values()).forEach((panel) => {
1589
- this.moveGroupOrPanel({
1590
- from: {
1591
- groupId: panel.api.group.api.id,
1592
- panelId: panel.api.id,
1593
- },
1594
- to: {
1595
- group: tempGroup,
1596
- position: 'center',
1597
- },
1598
- keepEmptyGroups: true,
1599
- });
1600
- });
1601
- });
1602
- }
1603
- this.clear();
1604
- if (typeof data !== 'object' || data === null) {
1605
- throw new Error('dockview: serialized layout must be a non-null object');
1606
- }
1607
- const { grid, panels, activeGroup } = data;
1608
- if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
1609
- throw new Error('dockview: root must be of type branch');
1610
- }
1611
- try {
1612
- // take note of the existing dimensions
1613
- const width = this.width;
1614
- const height = this.height;
1615
- const createGroupFromSerializedState = (data) => {
1616
- const { id, locked, hideHeader, headerPosition, views, activeView, } = data;
1617
- if (typeof id !== 'string') {
1618
- throw new TypeError('dockview: group id must be of type string');
1619
- }
1620
- const group = this.createGroup({
1621
- id,
1622
- locked: !!locked,
1623
- hideHeader: !!hideHeader,
1624
- headerPosition,
1625
- });
1626
- this._onDidAddGroup.fire(group);
1627
- const createdPanels = [];
1628
- for (const child of views) {
1629
- /**
1630
- * Run the deserializer step seperately since this may fail to due corrupted external state.
1631
- * In running this section first we avoid firing lots of 'add' events in the event of a failure
1632
- * due to a corruption of input data.
1633
- */
1634
- const existingPanel = existingPanels.get(child);
1635
- if (tempGroup && existingPanel) {
1636
- this.movingLock(() => {
1637
- tempGroup.model.removePanel(existingPanel);
1638
- });
1639
- createdPanels.push(existingPanel);
1640
- existingPanel.updateFromStateModel(panels[child]);
1641
- }
1642
- else {
1643
- const panel = this._deserializer.fromJSON(panels[child], group);
1644
- createdPanels.push(panel);
1645
- }
1646
- }
1647
- for (let i = 0; i < views.length; i++) {
1648
- const panel = createdPanels[i];
1649
- const isActive = typeof activeView === 'string' &&
1650
- activeView === panel.id;
1651
- const hasExisting = existingPanels.has(panel.api.id);
1652
- if (hasExisting) {
1653
- this.movingLock(() => {
1654
- group.model.openPanel(panel, {
1655
- skipSetActive: !isActive,
1656
- skipSetGroupActive: true,
1657
- });
1658
- });
1659
- }
1660
- else {
1661
- group.model.openPanel(panel, {
1662
- skipSetActive: !isActive,
1663
- skipSetGroupActive: true,
1664
- });
1665
- }
1666
- }
1667
- // Restore tab groups before activating a fallback panel so
1668
- // that collapsed groups can clear the active panel correctly.
1669
- if (data.tabGroups && data.tabGroups.length > 0) {
1670
- group.model.restoreTabGroups(data.tabGroups);
1671
- }
1672
- if (!group.activePanel && group.panels.length > 0) {
1673
- group.model.openPanel(group.panels[group.panels.length - 1], {
1674
- skipSetGroupActive: true,
1675
- });
1676
- }
1677
- return group;
1678
- };
1679
- this.gridview.deserialize(grid, {
1680
- fromJSON: (node) => {
1681
- return createGroupFromSerializedState(node.data);
1682
- },
1683
- });
1684
- this._layoutFromShell(width, height);
1685
- if (data.edgeGroups) {
1686
- this.deserializeEdgeGroups(data.edgeGroups, panels);
1687
- }
1688
- this.deserializeFloatingWindows((_b = data.floatingGroups) !== null && _b !== void 0 ? _b : [], createGroupFromSerializedState);
1689
- const popoutPromises = this.deserializePopoutWindows((_c = data.popoutGroups) !== null && _c !== void 0 ? _c : [], createGroupFromSerializedState);
1690
- (_d = this._popoutWindowService) === null || _d === void 0 ? void 0 : _d.finishRestoration(popoutPromises);
1691
- (_e = this._floatingGroupService) === null || _e === void 0 ? void 0 : _e.constrainBounds();
1692
- if (typeof activeGroup === 'string') {
1693
- const panel = this.getPanel(activeGroup);
1694
- if (panel) {
1695
- this.doSetGroupAndPanelActive(panel);
1696
- }
1697
- }
1698
- // `gridview.deserialize()` rebuilds the grid without firing the
1699
- // BaseGrid add events the watermark module reacts to, so the
1700
- // watermark mounted during `clear()` would otherwise persist over
1701
- // the restored layout. Re-evaluate now the layout is in place.
1702
- (_f = this._watermarkService) === null || _f === void 0 ? void 0 : _f.update();
1703
- }
1704
- catch (err) {
1705
- console.error('dockview: failed to deserialize layout. Reverting changes', err);
1706
- /**
1707
- * Takes all the successfully created groups and remove all of their panels.
1708
- */
1709
- for (const group of this.groups) {
1710
- for (const panel of group.panels) {
1711
- this.removePanel(panel, {
1712
- removeEmptyGroup: false,
1713
- skipDispose: false,
1714
- });
1715
- }
1716
- }
1717
- /**
1718
- * To remove a group we cannot call this.removeGroup(...) since this makes assumptions about
1719
- * the underlying HTMLElement existing in the Gridview.
1720
- */
1721
- for (const group of this.groups) {
1722
- group.dispose();
1723
- this._groups.delete(group.id);
1724
- this._onDidRemoveGroup.fire(group);
1725
- }
1726
- (_g = this._floatingGroupService) === null || _g === void 0 ? void 0 : _g.disposeAll();
1727
- // fires clean-up events and clears the underlying HTML gridview.
1728
- this.clear();
1729
- /**
1730
- * even though we have cleaned-up we still want to inform the caller of their error
1731
- * and we'll do this through re-throwing the original error since afterall you would
1732
- * expect trying to load a corrupted layout to result in an error and not silently fail...
1733
- */
1734
- throw err;
1735
- }
1736
- // Force position updates for always visible panels after DOM layout is complete
1737
- this.debouncedUpdateAllPositions();
1738
- this._onDidLayoutFromJSON.fire();
1739
- }
1740
- /**
1741
- * Rebuild a floating / popout window's nested gridview from its serialized
1742
- * tree, collecting the member groups (in deserialization order) so the
1743
- * caller can mount or restore the window.
1744
- */
1745
- deserializeNestedGridview(grid, createGroup) {
1746
- const gridview = this.createNestedGridview(grid.orientation);
1747
- const members = [];
1748
- gridview.deserialize(grid, {
1749
- fromJSON: (node) => {
1750
- const group = createGroup(node.data);
1751
- members.push(group);
1752
- return group;
1753
- },
1754
- });
1755
- return { gridview, members };
1756
- }
1757
- deserializeEdgeGroups(edgeGroups, panels) {
1758
- var _a;
1759
- const edgeService = assertModule(this._edgeGroupService, 'EdgeGroup', 'fromJSON edge restoration');
1760
- if (!edgeService) {
1761
- return;
1762
- }
1763
- // Auto-create edge groups for positions in the serialized state that
1764
- // don't already have a group registered (e.g. when fromJSON is called
1765
- // before the user has called addEdgeGroup).
1766
- for (const _position of [
1767
- 'top',
1768
- 'bottom',
1769
- 'left',
1770
- 'right',
1771
- ]) {
1772
- const fixedData = edgeGroups[_position];
1773
- if (fixedData && !edgeService.has(_position)) {
1774
- const groupState = fixedData.group;
1775
- const id = (_a = groupState === null || groupState === void 0 ? void 0 : groupState.id) !== null && _a !== void 0 ? _a : `${_position}-group`;
1776
- this.addEdgeGroup(_position, { id });
1777
- }
1778
- }
1779
- // Restore panel contents of edge groups
1780
- for (const [position, edgeGroup] of edgeService.entries()) {
1781
- const edgeData = edgeGroups[position];
1782
- const groupState = edgeData === null || edgeData === void 0 ? void 0 : edgeData.group;
1783
- if (groupState) {
1784
- const { views, activeView } = groupState;
1785
- const createdPanels = [];
1786
- for (const panelId of views) {
1787
- if (panels[panelId]) {
1788
- const panel = this._deserializer.fromJSON(panels[panelId], edgeGroup);
1789
- createdPanels.push(panel);
1790
- }
1791
- }
1792
- for (const panel of createdPanels) {
1793
- const isActive = activeView === panel.id;
1794
- edgeGroup.model.openPanel(panel, {
1795
- skipSetActive: !isActive,
1796
- skipSetGroupActive: true,
1797
- });
1798
- }
1799
- // Restore tab groups before activating a fallback panel
1800
- if (groupState.tabGroups && groupState.tabGroups.length > 0) {
1801
- edgeGroup.model.restoreTabGroups(groupState.tabGroups);
1802
- }
1803
- if (!edgeGroup.activePanel && edgeGroup.panels.length > 0) {
1804
- edgeGroup.model.openPanel(edgeGroup.panels[edgeGroup.panels.length - 1], { skipSetGroupActive: true });
1805
- }
1806
- }
1807
- }
1808
- this._shellManager.fromJSON(edgeGroups);
1809
- }
1810
- deserializeFloatingWindows(serialized, createGroup) {
1811
- for (const serializedFloatingGroup of serialized) {
1812
- const { data, grid, position } = serializedFloatingGroup;
1813
- if (grid) {
1814
- // Multi-group window: rebuild the window's nested gridview from
1815
- // its serialized tree.
1816
- const { gridview: floatingGridview, members } = this.deserializeNestedGridview(grid, createGroup);
1817
- if (members.length === 0) {
1818
- continue;
1819
- }
1820
- this.mountFloatingWindow(floatingGridview, members[0], members, position, { inDragMode: false });
1821
- }
1822
- else if (data) {
1823
- const group = createGroup(data);
1824
- this.addFloatingGroup(group, {
1825
- position: position,
1826
- width: position.width,
1827
- height: position.height,
1828
- skipRemoveGroup: true,
1829
- inDragMode: false,
1830
- });
1831
- }
1832
- }
1833
- }
1834
- deserializePopoutWindows(serialized, createGroup) {
1835
- const popoutService = serialized.length > 0
1836
- ? assertModule(this._popoutWindowService, 'PopoutWindow', 'fromJSON popout restoration')
1837
- : this._popoutWindowService;
1838
- if (!popoutService) {
1839
- return [];
1840
- }
1841
- // Queue popup group creation with delays to avoid browser blocking
1842
- return serialized.flatMap((serializedPopoutGroup, index) => {
1843
- const { data, grid, position, gridReferenceGroup, url } = serializedPopoutGroup;
1844
- // Multi-group popout windows rebuild their nested gridview from the
1845
- // serialized tree; single-group windows use the legacy single-group
1846
- // path.
1847
- let overridePopoutGridview;
1848
- let members = [];
1849
- if (grid) {
1850
- const built = this.deserializeNestedGridview(grid, createGroup);
1851
- overridePopoutGridview = built.gridview;
1852
- members = built.members;
1853
- if (members.length === 0) {
1854
- // A serialized window with no groups: nothing to restore.
1855
- // Mirror the floating path's guard and discard the empty
1856
- // gridview rather than passing an undefined anchor to
1857
- // addPopoutGroup.
1858
- overridePopoutGridview.dispose();
1859
- return [];
1860
- }
1861
- }
1862
- const group = grid ? members[0] : createGroup(data);
1863
- return popoutService.scheduleRestoration(index * DESERIALIZATION_POPOUT_DELAY_MS, () => {
1864
- this.addPopoutGroup(group, {
1865
- position: position !== null && position !== void 0 ? position : undefined,
1866
- overridePopoutGroup: gridReferenceGroup
1867
- ? group
1868
- : undefined,
1869
- overridePopoutGridview,
1870
- referenceGroup: gridReferenceGroup
1871
- ? this.getPanel(gridReferenceGroup)
1872
- : undefined,
1873
- popoutUrl: url,
1874
- });
1875
- }, () => {
1876
- // The group was registered in _groups synchronously but the
1877
- // timer that would parent it into the popout window never
1878
- // ran. Dispose the orphan here so the next clear() doesn't
1879
- // trip over an unparented element. See issue #1304.
1880
- for (const orphan of members.length > 0
1881
- ? members
1882
- : [group]) {
1883
- if (!this.isDisposed &&
1884
- this._groups.has(orphan.id) &&
1885
- orphan.element.parentElement === null) {
1886
- for (const panel of [...orphan.panels]) {
1887
- this.removePanel(panel, {
1888
- removeEmptyGroup: false,
1889
- });
1890
- }
1891
- orphan.dispose();
1892
- this._groups.delete(orphan.id);
1893
- this._onDidRemoveGroup.fire(orphan);
1894
- }
1895
- }
1896
- });
1897
- });
1898
- }
1899
- clear() {
1900
- this.mutation('clear', () => this._doClear());
1901
- }
1902
- _doClear() {
1903
- var _a;
1904
- const groups = Array.from(this._groups.values()).map((_) => _.value);
1905
- const hasActiveGroup = !!this.activeGroup;
1906
- for (const group of groups) {
1907
- if ((_a = this._edgeGroupService) === null || _a === void 0 ? void 0 : _a.includes(group)) {
1908
- // Edge groups are structural - only clear their panels, not the group itself
1909
- const panels = [...group.panels];
1910
- for (const panel of panels) {
1911
- this.removePanel(panel, { removeEmptyGroup: false });
1912
- }
1913
- continue;
1914
- }
1915
- // remove the group will automatically remove the panels
1916
- this.removeGroup(group, { skipActive: true });
1917
- }
1918
- if (hasActiveGroup) {
1919
- this.doSetGroupAndPanelActive(undefined);
1920
- }
1921
- this.gridview.clear();
1922
- }
1923
- closeAllGroups() {
1924
- // One transaction — the per-panel removals inside nest via the depth
1925
- // counter, so consumers (undo, announcements) see a single mutation.
1926
- this.mutation('remove', () => {
1927
- for (const entry of this._groups.entries()) {
1928
- const [_, group] = entry;
1929
- group.value.model.closeAllPanels();
1930
- }
1931
- });
1932
- }
1933
- addPanel(options) {
1934
- return this.mutation('add', () => this._doAddPanel(options));
1935
- }
1936
- _doAddPanel(options) {
1937
- var _a, _b, _c, _d;
1938
- if (this.panels.some((_) => _.id === options.id)) {
1939
- throw new Error(`dockview: panel with id ${options.id} already exists`);
1940
- }
1941
- let referenceGroup;
1942
- if (options.position && options.floating) {
1943
- throw new Error('dockview: you can only provide one of: position, floating as arguments to .addPanel(...)');
1944
- }
1945
- const initial = {
1946
- width: options.initialWidth,
1947
- height: options.initialHeight,
1948
- };
1949
- let index;
1950
- if (options.position) {
1951
- if (isPanelOptionsWithPanel(options.position)) {
1952
- const referencePanel = typeof options.position.referencePanel === 'string'
1953
- ? this.getGroupPanel(options.position.referencePanel)
1954
- : options.position.referencePanel;
1955
- index = options.position.index;
1956
- if (!referencePanel) {
1957
- const referenceId = typeof options.position.referencePanel === 'string'
1958
- ? options.position.referencePanel
1959
- : (_a = options.position.referencePanel) === null || _a === void 0 ? void 0 : _a.id;
1960
- throw new Error(`dockview: referencePanel '${referenceId}' does not exist`);
1961
- }
1962
- referenceGroup = this.findGroup(referencePanel);
1963
- }
1964
- else if (isPanelOptionsWithGroup(options.position)) {
1965
- referenceGroup =
1966
- typeof options.position.referenceGroup === 'string'
1967
- ? (_b = this._groups.get(options.position.referenceGroup)) === null || _b === void 0 ? void 0 : _b.value
1968
- : options.position.referenceGroup;
1969
- index = options.position.index;
1970
- if (!referenceGroup) {
1971
- const referenceId = typeof options.position.referenceGroup === 'string'
1972
- ? options.position.referenceGroup
1973
- : (_c = options.position.referenceGroup) === null || _c === void 0 ? void 0 : _c.id;
1974
- throw new Error(`dockview: referenceGroup '${referenceId}' does not exist`);
1975
- }
1976
- }
1977
- else {
1978
- const group = this.orthogonalize(directionToPosition(options.position.direction));
1979
- const panel = this.createPanel(options, group);
1980
- group.model.openPanel(panel, {
1981
- skipSetActive: options.inactive,
1982
- skipSetGroupActive: options.inactive,
1983
- index,
1984
- });
1985
- if (!options.inactive) {
1986
- this.doSetGroupAndPanelActive(group);
1987
- }
1988
- group.api.setSize({
1989
- height: initial === null || initial === void 0 ? void 0 : initial.height,
1990
- width: initial === null || initial === void 0 ? void 0 : initial.width,
1991
- });
1992
- return panel;
1993
- }
1994
- }
1995
- else {
1996
- referenceGroup = this.activeGroup;
1997
- }
1998
- let panel;
1999
- if (referenceGroup) {
2000
- const target = toTarget(((_d = options.position) === null || _d === void 0 ? void 0 : _d.direction) || 'within');
2001
- if (options.floating) {
2002
- const group = this.createGroup();
2003
- this._onDidAddGroup.fire(group);
2004
- const floatingGroupOptions = typeof options.floating === 'object' &&
2005
- options.floating !== null
2006
- ? options.floating
2007
- : {};
2008
- this.addFloatingGroup(group, Object.assign(Object.assign({}, floatingGroupOptions), { inDragMode: false, skipRemoveGroup: true, skipActiveGroup: true }));
2009
- panel = this.createPanel(options, group);
2010
- group.model.openPanel(panel, {
2011
- skipSetActive: options.inactive,
2012
- skipSetGroupActive: options.inactive,
2013
- index,
2014
- });
2015
- }
2016
- else if (referenceGroup.api.location.type === 'floating' ||
2017
- referenceGroup.api.location.type === 'edge' ||
2018
- target === 'center') {
2019
- panel = this.createPanel(options, referenceGroup);
2020
- referenceGroup.model.openPanel(panel, {
2021
- skipSetActive: options.inactive,
2022
- skipSetGroupActive: options.inactive,
2023
- index,
2024
- });
2025
- referenceGroup.api.setSize({
2026
- width: initial === null || initial === void 0 ? void 0 : initial.width,
2027
- height: initial === null || initial === void 0 ? void 0 : initial.height,
2028
- });
2029
- if (!options.inactive) {
2030
- this.doSetGroupAndPanelActive(referenceGroup);
2031
- }
2032
- }
2033
- else {
2034
- const location = getGridLocation(referenceGroup.element);
2035
- const relativeLocation = getRelativeLocation(this.gridview.orientation, location, target);
2036
- const group = this.createGroupAtLocation(relativeLocation, this.orientationAtLocation(relativeLocation) ===
2037
- Orientation.VERTICAL
2038
- ? initial === null || initial === void 0 ? void 0 : initial.height
2039
- : initial === null || initial === void 0 ? void 0 : initial.width);
2040
- panel = this.createPanel(options, group);
2041
- group.model.openPanel(panel, {
2042
- skipSetActive: options.inactive,
2043
- skipSetGroupActive: options.inactive,
2044
- index,
2045
- });
2046
- if (!options.inactive) {
2047
- this.doSetGroupAndPanelActive(group);
2048
- }
2049
- }
2050
- }
2051
- else if (options.floating) {
2052
- const group = this.createGroup();
2053
- this._onDidAddGroup.fire(group);
2054
- const coordinates = typeof options.floating === 'object' &&
2055
- options.floating !== null
2056
- ? options.floating
2057
- : {};
2058
- this.addFloatingGroup(group, Object.assign(Object.assign({}, coordinates), { inDragMode: false, skipRemoveGroup: true, skipActiveGroup: true }));
2059
- panel = this.createPanel(options, group);
2060
- group.model.openPanel(panel, {
2061
- skipSetActive: options.inactive,
2062
- skipSetGroupActive: options.inactive,
2063
- index,
2064
- });
2065
- }
2066
- else {
2067
- const group = this.createGroupAtLocation([0], this.gridview.orientation === Orientation.VERTICAL
2068
- ? initial === null || initial === void 0 ? void 0 : initial.height
2069
- : initial === null || initial === void 0 ? void 0 : initial.width);
2070
- panel = this.createPanel(options, group);
2071
- group.model.openPanel(panel, {
2072
- skipSetActive: options.inactive,
2073
- skipSetGroupActive: options.inactive,
2074
- index,
2075
- });
2076
- if (!options.inactive) {
2077
- this.doSetGroupAndPanelActive(group);
2078
- }
2079
- }
2080
- return panel;
2081
- }
2082
- removePanel(panel, options) {
2083
- this.mutation('remove', () => {
2084
- var _a;
2085
- return this._doRemovePanel(panel, {
2086
- removeEmptyGroup: (_a = options === null || options === void 0 ? void 0 : options.removeEmptyGroup) !== null && _a !== void 0 ? _a : true,
2087
- skipDispose: options === null || options === void 0 ? void 0 : options.skipDispose,
2088
- skipSetActiveGroup: options === null || options === void 0 ? void 0 : options.skipSetActiveGroup,
2089
- });
2090
- });
2091
- }
2092
- _doRemovePanel(panel, options) {
2093
- const group = panel.group;
2094
- if (!group) {
2095
- throw new Error(`dockview: cannot remove panel ${panel.id}. it's missing a group.`);
2096
- }
2097
- group.model.removePanel(panel, {
2098
- skipSetActiveGroup: options.skipSetActiveGroup,
2099
- });
2100
- if (!options.skipDispose) {
2101
- panel.group.model.renderContainer.detatch(panel);
2102
- panel.dispose();
2103
- }
2104
- if (group.size === 0 && options.removeEmptyGroup) {
2105
- this.removeGroup(group, { skipActive: options.skipSetActiveGroup });
2106
- }
2107
- }
2108
- createWatermarkComponent() {
2109
- if (this.options.createWatermarkComponent) {
2110
- return this.options.createWatermarkComponent();
2111
- }
2112
- return new Watermark();
2113
- }
2114
- addGroup(options) {
2115
- return this.mutation('add', () => this._doAddGroup(options));
2116
- }
2117
- _doAddGroup(options) {
2118
- var _a, _b, _c;
2119
- if (options) {
2120
- let referenceGroup;
2121
- if (isGroupOptionsWithPanel(options)) {
2122
- const referencePanel = typeof options.referencePanel === 'string'
2123
- ? this.panels.find((panel) => panel.id === options.referencePanel)
2124
- : options.referencePanel;
2125
- const referencePanelId = typeof options.referencePanel === 'string'
2126
- ? options.referencePanel
2127
- : (_a = options.referencePanel) === null || _a === void 0 ? void 0 : _a.id;
2128
- if (!referencePanel) {
2129
- throw new Error(`dockview: reference panel ${referencePanelId} does not exist`);
2130
- }
2131
- referenceGroup = this.findGroup(referencePanel);
2132
- if (!referenceGroup) {
2133
- throw new Error(`dockview: reference group for reference panel ${referencePanelId} does not exist`);
2134
- }
2135
- }
2136
- else if (isGroupOptionsWithGroup(options)) {
2137
- referenceGroup =
2138
- typeof options.referenceGroup === 'string'
2139
- ? (_b = this._groups.get(options.referenceGroup)) === null || _b === void 0 ? void 0 : _b.value
2140
- : options.referenceGroup;
2141
- if (!referenceGroup) {
2142
- const referenceId = typeof options.referenceGroup === 'string'
2143
- ? options.referenceGroup
2144
- : (_c = options.referenceGroup) === null || _c === void 0 ? void 0 : _c.id;
2145
- throw new Error(`dockview: reference group ${referenceId} does not exist`);
2146
- }
2147
- }
2148
- else {
2149
- const group = this.orthogonalize(directionToPosition(options.direction), options);
2150
- if (!options.skipSetActive) {
2151
- this.doSetGroupAndPanelActive(group);
2152
- }
2153
- return group;
2154
- }
2155
- const target = toTarget(options.direction || 'within');
2156
- const location = getGridLocation(referenceGroup.element);
2157
- const relativeLocation = getRelativeLocation(this.gridview.orientation, location, target);
2158
- const group = this.createGroup(options);
2159
- const size = this.getLocationOrientation(relativeLocation) ===
2160
- Orientation.VERTICAL
2161
- ? options.initialHeight
2162
- : options.initialWidth;
2163
- this.doAddGroup(group, relativeLocation, size);
2164
- if (!options.skipSetActive) {
2165
- this.doSetGroupAndPanelActive(group);
2166
- }
2167
- return group;
2168
- }
2169
- else {
2170
- const group = this.createGroup(options);
2171
- this.doAddGroup(group);
2172
- this.doSetGroupAndPanelActive(group);
2173
- return group;
2174
- }
2175
- }
2176
- getLocationOrientation(location) {
2177
- return location.length % 2 == 0 &&
2178
- this.gridview.orientation === Orientation.HORIZONTAL
2179
- ? Orientation.HORIZONTAL
2180
- : Orientation.VERTICAL;
2181
- }
2182
- removeGroup(group, options) {
2183
- this.mutation('remove', () => this.doRemoveGroup(group, options));
2184
- }
2185
- /**
2186
- * Detach a single group from the nested gridview of its floating / popout
2187
- * window, keeping the window and its remaining members alive, and reassign
2188
- * the window's anchor if the detached group was it.
2189
- *
2190
- * @returns `true` if the group was detached from a multi-member window;
2191
- * `false` if `group` is not in a nested window, or is the window's only
2192
- * member — in which case the caller is responsible for disposing the whole
2193
- * window.
2194
- */
2195
- detachFromNestedWindow(group) {
2196
- var _a, _b;
2197
- const floating = (_a = this._floatingGroupService) === null || _a === void 0 ? void 0 : _a.findByGroup(group);
2198
- if (floating) {
2199
- const members = this.nestedWindowMembers(group);
2200
- if (members.length <= 1) {
2201
- return false;
2202
- }
2203
- floating.gridview.remove(group);
2204
- if (floating.group === group) {
2205
- // The anchor left; promote a remaining member.
2206
- floating.setAnchorGroup(members.find((m) => m !== group));
2207
- }
2208
- return true;
2209
- }
2210
- const popout = (_b = this._popoutWindowService) === null || _b === void 0 ? void 0 : _b.findByGroup(group);
2211
- if (popout) {
2212
- const members = this.nestedWindowMembers(group);
2213
- if (members.length <= 1) {
2214
- return false;
2215
- }
2216
- popout.gridview.remove(group);
2217
- if (popout.popoutGroup === group) {
2218
- // The anchor left; promote a remaining member.
2219
- popout.popoutGroup = members.find((m) => m !== group);
2220
- }
2221
- return true;
2222
- }
2223
- return false;
2224
- }
2225
- /**
2226
- * Dispose a group and forget it: remove it from `_groups` and fire the
2227
- * removed event.
2228
- */
2229
- disposeGroupRecord(group) {
2230
- group.dispose();
2231
- this._groups.delete(group.id);
2232
- this._onDidRemoveGroup.fire(group);
2233
- }
2234
- /**
2235
- * When `removed` was the active group, fall the active selection back to
2236
- * the first remaining group (or clear it when none remain).
2237
- */
2238
- activateFallbackGroupIfRemoved(removed, skipActive) {
2239
- if (!skipActive && this._activeGroup === removed) {
2240
- const groups = Array.from(this._groups.values());
2241
- this.doSetGroupAndPanelActive(groups.length > 0 ? groups[0].value : undefined);
2242
- }
2243
- }
2244
- doRemoveGroup(group, options) {
2245
- var _a, _b, _c, _d, _e;
2246
- // Edge groups are permanent structural elements - never remove them from the layout
2247
- if ((_a = this._edgeGroupService) === null || _a === void 0 ? void 0 : _a.includes(group)) {
2248
- return group;
2249
- }
2250
- const panels = [...group.panels]; // reassign since group panels will mutate
2251
- if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
2252
- for (const panel of panels) {
2253
- this.removePanel(panel, {
2254
- removeEmptyGroup: false,
2255
- skipDispose: (_b = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _b !== void 0 ? _b : false,
2256
- });
2257
- }
2258
- }
2259
- const activePanel = this.activePanel;
2260
- if (group.api.location.type === 'floating') {
2261
- const floatingGroup = (_c = this._floatingGroupService) === null || _c === void 0 ? void 0 : _c.findByGroup(group);
2262
- if (!floatingGroup) {
2263
- throw new Error('dockview: failed to find floating group');
2264
- }
2265
- if (this.detachFromNestedWindow(group)) {
2266
- // The floating window hosts other groups and stays alive —
2267
- // finalize just this group.
2268
- if (options === null || options === void 0 ? void 0 : options.skipDispose) {
2269
- // Relocation: reset location so the destination root can
2270
- // re-tag it.
2271
- group.model.location = { type: 'grid' };
2272
- }
2273
- else {
2274
- this.disposeGroupRecord(group);
2275
- }
2276
- this.activateFallbackGroupIfRemoved(group, options === null || options === void 0 ? void 0 : options.skipActive);
2277
- return group;
2278
- }
2279
- // Last group leaving — dispose the whole floating window.
2280
- if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
2281
- this.disposeGroupRecord(group);
2282
- }
2283
- // floatingGroup.dispose() removes itself from the service array
2284
- floatingGroup.dispose();
2285
- this.activateFallbackGroupIfRemoved(group, options === null || options === void 0 ? void 0 : options.skipActive);
2286
- return group;
2287
- }
2288
- if (group.api.location.type === 'popout') {
2289
- const selectedGroup = (_d = this._popoutWindowService) === null || _d === void 0 ? void 0 : _d.findByGroup(group);
2290
- if (!selectedGroup) {
2291
- throw new Error('dockview: failed to find popout group');
2292
- }
2293
- if (this.detachFromNestedWindow(group)) {
2294
- // The popout window hosts other groups and stays alive —
2295
- // finalize just this group.
2296
- if (options === null || options === void 0 ? void 0 : options.skipDispose) {
2297
- // Relocation: reset location so the destination root can
2298
- // re-tag it.
2299
- group.model.location = { type: 'grid' };
2300
- }
2301
- else {
2302
- this.disposeGroupRecord(group);
2303
- }
2304
- this.activateFallbackGroupIfRemoved(group, options === null || options === void 0 ? void 0 : options.skipActive);
2305
- return group;
2306
- }
2307
- // Last group leaving — tear the whole popout window down.
2308
- if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
2309
- if (!(options === null || options === void 0 ? void 0 : options.skipPopoutAssociated)) {
2310
- const refGroup = selectedGroup.referenceGroup
2311
- ? this.getPanel(selectedGroup.referenceGroup)
2312
- : undefined;
2313
- if ((refGroup === null || refGroup === void 0 ? void 0 : refGroup.panels.length) === 0) {
2314
- this.removeGroup(refGroup);
2315
- }
2316
- }
2317
- selectedGroup.popoutGroup.dispose();
2318
- this._groups.delete(group.id);
2319
- this._onDidRemoveGroup.fire(group);
2320
- }
2321
- (_e = this._popoutWindowService) === null || _e === void 0 ? void 0 : _e.remove(selectedGroup);
2322
- const removedGroup = selectedGroup.disposable.dispose();
2323
- if (!(options === null || options === void 0 ? void 0 : options.skipPopoutReturn) && removedGroup) {
2324
- this.doAddGroup(removedGroup, [0]);
2325
- this.doSetGroupAndPanelActive(removedGroup);
2326
- }
2327
- this.activateFallbackGroupIfRemoved(group, options === null || options === void 0 ? void 0 : options.skipActive);
2328
- return selectedGroup.popoutGroup;
2329
- }
2330
- // A `grid`-location group whose element isn't actually in the gridview
2331
- // is an orphan — e.g. a popout-destined group created during fromJSON
2332
- // whose window hasn't opened yet, swept up by clear()/a re-entrant
2333
- // fromJSON. `gridview.remove()` would throw "Invalid grid element", so
2334
- // dispose it directly.
2335
- if (!this.gridview.element.contains(group.element)) {
2336
- if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
2337
- const item = this._groups.get(group.id);
2338
- item === null || item === void 0 ? void 0 : item.disposable.dispose();
2339
- this.disposeGroupRecord(group);
2340
- }
2341
- this.activateFallbackGroupIfRemoved(group, options === null || options === void 0 ? void 0 : options.skipActive);
2342
- return group;
2343
- }
2344
- const re = super.doRemoveGroup(group, options);
2345
- if (!(options === null || options === void 0 ? void 0 : options.skipActive)) {
2346
- if (this.activePanel !== activePanel) {
2347
- this.fireActivePanelChange(this.activePanel);
2348
- }
2349
- }
2350
- return re;
2351
- }
2352
- debouncedUpdateAllPositions() {
2353
- if (this._updatePositionsFrameId !== undefined) {
2354
- cancelAnimationFrame(this._updatePositionsFrameId);
2355
- }
2356
- this._updatePositionsFrameId = requestAnimationFrame(() => {
2357
- var _a, _b;
2358
- this._updatePositionsFrameId = undefined;
2359
- this.overlayRenderContainer.updateAllPositions();
2360
- // Popout windows have their own render containers; reposition those
2361
- // too so panels moved/split within a popout are laid out (the main
2362
- // container only covers grid + floating, which share it).
2363
- for (const entry of (_b = (_a = this._popoutWindowService) === null || _a === void 0 ? void 0 : _a.entries) !== null && _b !== void 0 ? _b : []) {
2364
- entry.overlayRenderContainer.updateAllPositions();
2365
- }
2366
- });
2367
- }
2368
- movingLock(func) {
2369
- const isMoving = this._moving;
2370
- try {
2371
- this._moving = true;
2372
- return func();
2373
- }
2374
- finally {
2375
- this._moving = isMoving;
2376
- }
2377
- }
2378
- /**
2379
- * Bracket a structural mutation with `onWillMutateLayout` /
2380
- * `onDidMutateLayout`. Re-entrant: nested calls (a compound operation such
2381
- * as a drag that relocates a panel) join the outermost transaction, so the
2382
- * events fire exactly once around the whole operation. `kind` reflects the
2383
- * outermost mutation.
2384
- */
2385
- mutation(kind, func) {
2386
- const outer = this._mutationDepth === 0;
2387
- const origin = this._origin;
2388
- if (outer) {
2389
- this._onWillMutateLayout.fire({ kind, origin });
2390
- }
2391
- this._mutationDepth++;
2392
- try {
2393
- return func();
2394
- }
2395
- finally {
2396
- this._mutationDepth--;
2397
- if (outer) {
2398
- this._onDidMutateLayout.fire({ kind, origin });
2399
- }
2400
- }
2401
- }
2402
- /**
2403
- * The origin of the operation currently in progress (`'user'` by default).
2404
- * Read inside a `mutation()` or active-panel change to learn whether the
2405
- * change was driven by application code (via the {@link DockviewApi}) or a
2406
- * user gesture.
2407
- */
2408
- currentOrigin() {
2409
- return this._origin;
2410
- }
2411
- /**
2412
- * Run `func` with the operation origin set to `origin`, restoring the
2413
- * previous value afterwards. Used by the DockviewApi boundary to tag
2414
- * programmatic operations as `'api'`, and by user-gesture handlers to tag
2415
- * `'user'`. Only the outermost caller sets the origin — a nested call (or a
2416
- * call made while a mutation is already in flight) keeps whatever the
2417
- * enclosing operation established, so the trigger always wins.
2418
- */
2419
- withOrigin(origin, func) {
2420
- if (this._originDepth > 0 || this._mutationDepth > 0) {
2421
- return func();
2422
- }
2423
- const previous = this._origin;
2424
- this._origin = origin;
2425
- this._originDepth++;
2426
- try {
2427
- return func();
2428
- }
2429
- finally {
2430
- this._originDepth--;
2431
- this._origin = previous;
2432
- }
2433
- }
2434
- /**
2435
- * Fire `onDidActivePanelChange` with the panel and the current operation
2436
- * {@link DockviewOrigin}. Callers keep their own dedupe guards.
2437
- */
2438
- fireActivePanelChange(panel) {
2439
- this._onDidActivePanelChange.fire({ panel, origin: this._origin });
2440
- }
2441
- moveGroupOrPanel(options) {
2442
- this.mutation('move', () => this._doMoveGroupOrPanel(options));
2443
- }
2444
- _doMoveGroupOrPanel(options) {
2445
- var _a, _b;
2446
- const destinationGroup = options.to.group;
2447
- const sourceGroupId = options.from.groupId;
2448
- const sourceItemId = options.from.panelId;
2449
- const destinationTarget = options.to.position;
2450
- const destinationIndex = options.to.index;
2451
- const sourceGroup = sourceGroupId
2452
- ? (_a = this._groups.get(sourceGroupId)) === null || _a === void 0 ? void 0 : _a.value
2453
- : undefined;
2454
- if (!sourceGroup) {
2455
- throw new Error(`dockview: Failed to find group id ${sourceGroupId}`);
2456
- }
2457
- if (sourceItemId === undefined) {
2458
- if (options.from.tabGroupId) {
2459
- /**
2460
- * Moving a tab group (subset of panels) into another group
2461
- */
2462
- this.moveTabGroupToGroup({
2463
- sourceGroup,
2464
- tabGroupId: options.from.tabGroupId,
2465
- destinationGroup,
2466
- destinationTarget,
2467
- destinationIndex,
2468
- skipSetActive: options.skipSetActive,
2469
- keepEmptyGroups: options.keepEmptyGroups,
2470
- });
2471
- }
2472
- else {
2473
- /**
2474
- * Moving an entire group into another group
2475
- */
2476
- this.moveGroup({
2477
- from: { group: sourceGroup },
2478
- to: {
2479
- group: destinationGroup,
2480
- position: destinationTarget,
2481
- },
2482
- skipSetActive: options.skipSetActive,
2483
- });
2484
- }
2485
- return;
2486
- }
2487
- if (!destinationTarget || destinationTarget === 'center') {
2488
- /**
2489
- * Dropping a panel within another group
2490
- */
2491
- const removedPanel = this.movingLock(() => sourceGroup.model.removePanel(sourceItemId, {
2492
- skipSetActive: false,
2493
- skipSetActiveGroup: true,
2494
- }));
2495
- if (!removedPanel) {
2496
- throw new Error(`dockview: No panel with id ${sourceItemId}`);
2497
- }
2498
- if (!options.keepEmptyGroups && sourceGroup.model.size === 0) {
2499
- // remove the group and do not set a new group as active
2500
- this.doRemoveGroup(sourceGroup, { skipActive: true });
2501
- }
2502
- // Check if destination group is empty - if so, force render the component
2503
- const isDestinationGroupEmpty = destinationGroup.model.size === 0;
2504
- this.movingLock(() => {
2505
- var _a;
2506
- return destinationGroup.model.openPanel(removedPanel, {
2507
- index: destinationIndex,
2508
- skipSetActive: ((_a = options.skipSetActive) !== null && _a !== void 0 ? _a : false) &&
2509
- !isDestinationGroupEmpty,
2510
- skipSetGroupActive: true,
2511
- });
2512
- });
2513
- if (!options.skipSetActive) {
2514
- this.doSetGroupAndPanelActive(destinationGroup);
2515
- }
2516
- this._onDidMovePanel.fire({
2517
- panel: removedPanel,
2518
- from: sourceGroup,
2519
- });
2520
- }
2521
- else {
2522
- /**
2523
- * Dropping a panel to the extremities of a group which will place that panel
2524
- * into an adjacent group
2525
- */
2526
- // The destination group may live in the main grid or in a floating
2527
- // window's nested gridview — resolve which root we are dropping
2528
- // into so locations/orientation are computed against it.
2529
- const destinationGridview = this.getGridviewForGroup(destinationGroup);
2530
- const referenceLocation = getGridLocation(destinationGroup.element);
2531
- const targetLocation = getRelativeLocation(destinationGridview.orientation, referenceLocation, destinationTarget);
2532
- if (sourceGroup.size < 2) {
2533
- /**
2534
- * If we are moving from a group which only has one panel left we will consider
2535
- * moving the group itself rather than moving the panel into a newly created group
2536
- */
2537
- const [targetParentLocation, to] = tail(targetLocation);
2538
- if (sourceGroup.api.location.type === 'grid' &&
2539
- destinationGridview === this.gridview) {
2540
- const sourceLocation = getGridLocation(sourceGroup.element);
2541
- const [sourceParentLocation, from] = tail(sourceLocation);
2542
- if (sequenceEquals(sourceParentLocation, targetParentLocation)) {
2543
- // special case when 'swapping' two views within same grid location
2544
- // if a group has one tab - we are essentially moving the 'group'
2545
- // which is equivalent to swapping two views in this case
2546
- this.gridview.moveView(sourceParentLocation, from, to);
2547
- this._onDidMovePanel.fire({
2548
- panel: this.getGroupPanel(sourceItemId),
2549
- from: sourceGroup,
2550
- });
2551
- return;
2552
- }
2553
- }
2554
- if (sourceGroup.api.location.type === 'popout' &&
2555
- this.nestedWindowMembers(sourceGroup).length <= 1) {
2556
- /**
2557
- * the source group is the only group in a popout window and
2558
- * has a single panel
2559
- *
2560
- * 1. remove the panel from the group without triggering any events
2561
- * 2. remove the popout group — this may cascade-remove the empty
2562
- * reference group it left behind in the main grid (see
2563
- * doRemoveGroup for popout groups), which can shift grid indices
2564
- * 3. recompute the target location now that the grid is stable
2565
- * 4. create a new group at the recomputed location and add that panel
2566
- *
2567
- * Multi-group popout windows fall through to the generic
2568
- * detach-and-re-add path so the window stays alive.
2569
- */
2570
- const popoutGroup = (_b = this._popoutWindowService) === null || _b === void 0 ? void 0 : _b.findByGroup(sourceGroup);
2571
- if (!popoutGroup) {
2572
- return;
2573
- }
2574
- const removedPanel = this.movingLock(() => popoutGroup.popoutGroup.model.removePanel(popoutGroup.popoutGroup.panels[0], {
2575
- skipSetActive: true,
2576
- skipSetActiveGroup: true,
2577
- }));
2578
- this.doRemoveGroup(sourceGroup, { skipActive: true });
2579
- const updatedTargetLocation = getRelativeLocation(destinationGridview.orientation, getGridLocation(destinationGroup.element), destinationTarget);
2580
- const newGroup = this.createGroupAtLocation(updatedTargetLocation, undefined, undefined, destinationGridview);
2581
- this.movingLock(() => newGroup.model.openPanel(removedPanel, {
2582
- skipSetActive: true,
2583
- }));
2584
- this.doSetGroupAndPanelActive(newGroup);
2585
- this._onDidMovePanel.fire({
2586
- panel: this.getGroupPanel(sourceItemId),
2587
- from: sourceGroup,
2588
- });
2589
- return;
2590
- }
2591
- if (sourceGroup.api.location.type === 'edge') {
2592
- /**
2593
- * Edge groups are permanent structural elements — never move the
2594
- * group itself. Instead extract the panel and create a new grid group,
2595
- * leaving the edge slot intact (same behaviour as the size >= 2 path).
2596
- */
2597
- const removedPanel = this.movingLock(() => sourceGroup.model.removePanel(sourceItemId, {
2598
- skipSetActive: false,
2599
- skipSetActiveGroup: true,
2600
- }));
2601
- if (!removedPanel) {
2602
- throw new Error(`dockview: No panel with id ${sourceItemId}`);
2603
- }
2604
- const newGroup = this.createGroupAtLocation(targetLocation, undefined, undefined, destinationGridview);
2605
- this.movingLock(() => newGroup.model.openPanel(removedPanel, {
2606
- skipSetGroupActive: true,
2607
- }));
2608
- this.doSetGroupAndPanelActive(newGroup);
2609
- this._onDidMovePanel.fire({
2610
- panel: removedPanel,
2611
- from: sourceGroup,
2612
- });
2613
- return;
2614
- }
2615
- // source group will become empty so delete the group
2616
- const targetGroup = this.movingLock(() => this.doRemoveGroup(sourceGroup, {
2617
- skipActive: true,
2618
- skipDispose: true,
2619
- }));
2620
- // after deleting the group we need to re-evaulate the ref location
2621
- const updatedReferenceLocation = getGridLocation(destinationGroup.element);
2622
- const location = getRelativeLocation(destinationGridview.orientation, updatedReferenceLocation, destinationTarget);
2623
- this.movingLock(() => this.doAddGroup(targetGroup, location, undefined, destinationGridview));
2624
- this.setGroupLocationForRoot(targetGroup, destinationGridview);
2625
- this.doSetGroupAndPanelActive(targetGroup);
2626
- this._onDidMovePanel.fire({
2627
- panel: this.getGroupPanel(sourceItemId),
2628
- from: sourceGroup,
2629
- });
2630
- }
2631
- else {
2632
- /**
2633
- * The group we are removing from has many panels, we need to remove the panels we are moving,
2634
- * create a new group, add the panels to that new group and add the new group in an appropiate position
2635
- */
2636
- const removedPanel = this.movingLock(() => sourceGroup.model.removePanel(sourceItemId, {
2637
- skipSetActive: false,
2638
- skipSetActiveGroup: true,
2639
- }));
2640
- if (!removedPanel) {
2641
- throw new Error(`dockview: No panel with id ${sourceItemId}`);
2642
- }
2643
- const dropLocation = getRelativeLocation(destinationGridview.orientation, referenceLocation, destinationTarget);
2644
- const group = this.createGroupAtLocation(dropLocation, undefined, undefined, destinationGridview);
2645
- this.movingLock(() => group.model.openPanel(removedPanel, {
2646
- skipSetGroupActive: true,
2647
- }));
2648
- this.doSetGroupAndPanelActive(group);
2649
- this._onDidMovePanel.fire({
2650
- panel: removedPanel,
2651
- from: sourceGroup,
2652
- });
2653
- }
2654
- }
2655
- }
2656
- moveTabGroupToGroup(options) {
2657
- const { sourceGroup, tabGroupId, destinationGroup, destinationTarget, destinationIndex, } = options;
2658
- const tabGroup = sourceGroup.model
2659
- .getTabGroups()
2660
- .find((tg) => tg.id === tabGroupId);
2661
- if (!tabGroup || tabGroup.panelIds.length === 0) {
2662
- return;
2663
- }
2664
- // Snapshot tab group metadata before removing panels
2665
- const label = tabGroup.label;
2666
- const color = tabGroup.color;
2667
- const collapsed = tabGroup.collapsed;
2668
- const componentParams = tabGroup.componentParams;
2669
- const panelIds = [...tabGroup.panelIds];
2670
- // Capture the destination's grid location BEFORE potentially
2671
- // removing the source group, in case source === destination and
2672
- // the source becomes empty after panel removal.
2673
- const referenceLocation = destinationTarget && destinationTarget !== 'center'
2674
- ? getGridLocation(destinationGroup.element)
2675
- : undefined;
2676
- // Remove panels from the source group
2677
- const removedPanels = this.movingLock(() => panelIds
2678
- .map((pid) => sourceGroup.model.removePanel(pid, {
2679
- skipSetActive: false,
2680
- skipSetActiveGroup: true,
2681
- }))
2682
- .filter((p) => p !== undefined));
2683
- if (removedPanels.length === 0) {
2684
- return;
2685
- }
2686
- const addPanelsToGroup = (targetGroup) => {
2687
- this.movingLock(() => {
2688
- for (const panel of removedPanels) {
2689
- targetGroup.model.openPanel(panel, {
2690
- index: destinationIndex,
2691
- skipSetActive: true,
2692
- skipSetGroupActive: true,
2693
- });
2694
- }
2695
- });
2696
- // Recreate the tab group in the destination
2697
- const newTabGroup = targetGroup.model.createTabGroup({
2698
- label,
2699
- color,
2700
- collapsed,
2701
- componentParams,
2702
- });
2703
- for (const panel of removedPanels) {
2704
- targetGroup.model.addPanelToTabGroup(newTabGroup.id, panel.id);
2705
- }
2706
- if (!options.skipSetActive) {
2707
- this.doSetGroupAndPanelActive(targetGroup);
2708
- }
2709
- for (const panel of removedPanels) {
2710
- this._onDidMovePanel.fire({
2711
- panel,
2712
- from: sourceGroup,
2713
- });
2714
- }
2715
- };
2716
- let targetGroup;
2717
- if (!destinationTarget ||
2718
- destinationTarget === 'center' ||
2719
- !referenceLocation) {
2720
- targetGroup = destinationGroup;
2721
- }
2722
- else {
2723
- const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, destinationTarget);
2724
- targetGroup = this.createGroupAtLocation(dropLocation);
2725
- }
2726
- // Remove the source group if it became empty. We compare against
2727
- // the actual targetGroup (which is a freshly-created group for
2728
- // edge drops) rather than the originally-passed destinationGroup,
2729
- // so a tab-group drag onto its own group's edge still cleans up
2730
- // the now-empty source.
2731
- if (!options.keepEmptyGroups &&
2732
- sourceGroup.model.size === 0 &&
2733
- sourceGroup !== targetGroup) {
2734
- this.doRemoveGroup(sourceGroup, { skipActive: true });
2735
- }
2736
- addPanelsToGroup(targetGroup);
2737
- }
2738
- moveGroup(options) {
2739
- this.mutation('move', () => this._doMoveGroup(options));
2740
- }
2741
- // Bracket maximize/restore as a 'maximize' transaction. The maximized node
2742
- // is serialized by the gridview (`SerializedGridview.maximizedNode`), so
2743
- // the state round-trips through toJSON/fromJSON and is restorable on undo.
2744
- // When the exit is a side-effect of another bracketed operation (e.g. a
2745
- // move that activates a different group) the depth counter folds it in.
2746
- maximizeGroup(panel) {
2747
- this.mutation('maximize', () => super.maximizeGroup(panel));
2748
- }
2749
- exitMaximizedGroup() {
2750
- this.mutation('maximize', () => super.exitMaximizedGroup());
2751
- }
2752
- _doMoveGroup(options) {
2753
- var _a, _b, _c;
2754
- const from = options.from.group;
2755
- const to = options.to.group;
2756
- const target = options.to.position;
2757
- // The group whose panels end up at the target. For non-edge moves
2758
- // we relocate `from` itself; for edge moves we move panels into a
2759
- // freshly created group so the edge slot stays anchored.
2760
- let source = from;
2761
- if (target === 'center') {
2762
- const activePanel = from.activePanel;
2763
- // Snapshot tab group metadata before removing panels so we
2764
- // can recreate the tab groups in the destination after the
2765
- // panels are merged in.
2766
- const tabGroupSnapshots = from.model.getTabGroups().map((tg) => ({
2767
- label: tg.label,
2768
- color: tg.color,
2769
- collapsed: tg.collapsed,
2770
- componentParams: tg.componentParams,
2771
- panelIds: [...tg.panelIds],
2772
- }));
2773
- const panels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, {
2774
- skipSetActive: true,
2775
- })));
2776
- if ((from === null || from === void 0 ? void 0 : from.model.size) === 0) {
2777
- this.doRemoveGroup(from, { skipActive: true });
2778
- }
2779
- this.movingLock(() => {
2780
- for (const panel of panels) {
2781
- to.model.openPanel(panel, {
2782
- skipSetActive: panel !== activePanel,
2783
- skipSetGroupActive: true,
2784
- });
2785
- }
2786
- });
2787
- for (const snapshot of tabGroupSnapshots) {
2788
- const newTabGroup = to.model.createTabGroup({
2789
- label: snapshot.label,
2790
- color: snapshot.color,
2791
- collapsed: snapshot.collapsed,
2792
- componentParams: snapshot.componentParams,
2793
- });
2794
- for (const panelId of snapshot.panelIds) {
2795
- to.model.addPanelToTabGroup(newTabGroup.id, panelId);
2796
- }
2797
- }
2798
- // Ensure group becomes active after move
2799
- if (options.skipSetActive !== true) {
2800
- // For center moves (merges), we need to ensure the target group is active
2801
- // unless explicitly told not to (skipSetActive: true)
2802
- this.doSetGroupAndPanelActive(to);
2803
- }
2804
- else if (!this.activePanel) {
2805
- // Even with skipSetActive: true, ensure there's an active panel if none exists
2806
- // This maintains basic functionality while respecting skipSetActive
2807
- this.doSetGroupAndPanelActive(to);
2808
- }
2809
- }
2810
- else {
2811
- if (from.api.location.type === 'edge') {
2812
- /**
2813
- * Edge groups are permanent structural elements and must
2814
- * stay anchored in their edge slot. Move the panels into a
2815
- * new group; the auto-collapse listener registered in
2816
- * addEdgeGroup will collapse the now-empty edge slot once
2817
- * the last panel leaves. The placement code below then
2818
- * positions `source` like any other moved group.
2819
- */
2820
- const activePanel = from.activePanel;
2821
- // Snapshot tab group metadata so the new group inherits
2822
- // the tab grouping from the edge slot.
2823
- const tabGroupSnapshots = from.model
2824
- .getTabGroups()
2825
- .map((tg) => ({
2826
- label: tg.label,
2827
- color: tg.color,
2828
- collapsed: tg.collapsed,
2829
- componentParams: tg.componentParams,
2830
- panelIds: [...tg.panelIds],
2831
- }));
2832
- const movedPanels = this.movingLock(() => [...from.panels].map((p) => from.model.removePanel(p.id, { skipSetActive: true })));
2833
- source = this.createGroup();
2834
- // The new source group enters the layout via gridview.addView
2835
- // below, which bypasses doAddGroup and so doesn't fire
2836
- // BaseGrid._onDidAdd. Modules (TabGroupChips, etc.) drive
2837
- // per-group attachment off _onDidAddGroup, so we fire it
2838
- // explicitly here — matches the pattern in addFloatingGroup
2839
- // and addEdgeGroup.
2840
- this._onDidAddGroup.fire(source);
2841
- this.movingLock(() => {
2842
- for (const panel of movedPanels) {
2843
- source.model.openPanel(panel, {
2844
- skipSetActive: panel !== activePanel,
2845
- skipSetGroupActive: true,
2846
- });
2847
- }
2848
- });
2849
- for (const snapshot of tabGroupSnapshots) {
2850
- const newTabGroup = source.model.createTabGroup({
2851
- label: snapshot.label,
2852
- color: snapshot.color,
2853
- collapsed: snapshot.collapsed,
2854
- componentParams: snapshot.componentParams,
2855
- });
2856
- for (const panelId of snapshot.panelIds) {
2857
- source.model.addPanelToTabGroup(newTabGroup.id, panelId);
2858
- }
2859
- }
2860
- }
2861
- else {
2862
- switch (from.api.location.type) {
2863
- case 'grid':
2864
- this.gridview.removeView(getGridLocation(from.element));
2865
- break;
2866
- case 'floating': {
2867
- const selectedFloatingGroup = (_a = this._floatingGroupService) === null || _a === void 0 ? void 0 : _a.findByGroup(from);
2868
- if (!selectedFloatingGroup) {
2869
- throw new Error('dockview: failed to find floating group');
2870
- }
2871
- // Detach just this group from the floating window's
2872
- // nested gridview, keeping the window (and its other
2873
- // groups) alive. If it was the only member, dispose the
2874
- // whole window.
2875
- if (!this.detachFromNestedWindow(from)) {
2876
- selectedFloatingGroup.dispose();
2877
- }
2878
- break;
2879
- }
2880
- case 'popout': {
2881
- const selectedPopoutGroup = (_b = this._popoutWindowService) === null || _b === void 0 ? void 0 : _b.findByGroup(from);
2882
- if (!selectedPopoutGroup) {
2883
- throw new Error('dockview: failed to find popout group');
2884
- }
2885
- // Detach just this group from the popout window's
2886
- // nested gridview, keeping the window + its other groups
2887
- // alive. Destination containers/location are applied by
2888
- // the placement block below.
2889
- if (this.detachFromNestedWindow(from)) {
2890
- break;
2891
- }
2892
- // Last group leaving — tear the window down. Remove from
2893
- // the service first to prevent automatic restoration.
2894
- (_c = this._popoutWindowService) === null || _c === void 0 ? void 0 : _c.remove(selectedPopoutGroup);
2895
- // Clean up the reference group (ghost) if it exists and is hidden
2896
- if (selectedPopoutGroup.referenceGroup) {
2897
- const referenceGroup = this.getPanel(selectedPopoutGroup.referenceGroup);
2898
- if (referenceGroup &&
2899
- !referenceGroup.api.isVisible) {
2900
- this.doRemoveGroup(referenceGroup, {
2901
- skipActive: true,
2902
- });
2903
- }
2904
- }
2905
- // Dispose the window without triggering restoration. The
2906
- // placement block below applies the destination
2907
- // location and containers to `from`.
2908
- selectedPopoutGroup.window.dispose();
2909
- break;
2910
- }
2911
- }
2912
- }
2913
- // Place `source` next to `to`, in whichever gridview root `to`
2914
- // lives in. When `to` is inside a floating / popout window this
2915
- // splits that window's nested layout rather than spawning a new one.
2916
- if (to.api.location.type === 'grid' ||
2917
- to.api.location.type === 'floating' ||
2918
- to.api.location.type === 'popout') {
2919
- const destGridview = this.getGridviewForGroup(to);
2920
- const referenceLocation = getGridLocation(to.element);
2921
- const dropLocation = getRelativeLocation(destGridview.orientation, referenceLocation, target);
2922
- let size;
2923
- switch (destGridview.orientation) {
2924
- case Orientation.VERTICAL:
2925
- size =
2926
- referenceLocation.length % 2 == 0
2927
- ? from.api.width
2928
- : from.api.height;
2929
- break;
2930
- case Orientation.HORIZONTAL:
2931
- size =
2932
- referenceLocation.length % 2 == 0
2933
- ? from.api.height
2934
- : from.api.width;
2935
- break;
2936
- }
2937
- destGridview.addView(source, size, dropLocation);
2938
- this.setGroupLocationForRoot(source, destGridview);
2939
- }
2940
- }
2941
- source.panels.forEach((panel) => {
2942
- this._onDidMovePanel.fire({ panel, from });
2943
- });
2944
- this.debouncedUpdateAllPositions();
2945
- // Ensure group becomes active after move
2946
- if (options.skipSetActive === false) {
2947
- // Only activate when explicitly requested (skipSetActive: false)
2948
- // Use 'to' group for non-center moves since 'from' may have been destroyed
2949
- const targetGroup = to !== null && to !== void 0 ? to : from;
2950
- this.doSetGroupAndPanelActive(targetGroup);
2951
- }
2952
- else if (source !== from && options.skipSetActive !== true) {
2953
- // Edge group moves create a fresh `source` group; activate it
2954
- // by default so the moved panels receive focus.
2955
- this.doSetGroupAndPanelActive(source);
2956
- }
2957
- }
2958
- doSetGroupActive(group) {
2959
- var _a;
2960
- super.doSetGroupActive(group);
2961
- const activePanel = this.activePanel;
2962
- if (!this._moving &&
2963
- activePanel !== ((_a = this._onDidActivePanelChange.value) === null || _a === void 0 ? void 0 : _a.panel)) {
2964
- this.fireActivePanelChange(activePanel);
2965
- }
2966
- }
2967
- doSetGroupAndPanelActive(group) {
2968
- var _a;
2969
- super.doSetGroupActive(group);
2970
- const activePanel = this.activePanel;
2971
- if (group &&
2972
- this.hasMaximizedGroup() &&
2973
- !this.isMaximizedGroup(group)) {
2974
- this.exitMaximizedGroup();
2975
- }
2976
- if (!this._moving &&
2977
- activePanel !== ((_a = this._onDidActivePanelChange.value) === null || _a === void 0 ? void 0 : _a.panel)) {
2978
- this.fireActivePanelChange(activePanel);
2979
- }
2980
- }
2981
- getNextGroupId() {
2982
- let id = this.nextGroupId.next();
2983
- while (this._groups.has(id)) {
2984
- id = this.nextGroupId.next();
2985
- }
2986
- return id;
2987
- }
2988
- createGroup(options) {
2989
- options !== null && options !== void 0 ? options : (options = {});
2990
- let id = options === null || options === void 0 ? void 0 : options.id;
2991
- if (id && this._groups.has(options.id)) {
2992
- console.warn(`dockview: Duplicate group id ${options === null || options === void 0 ? void 0 : options.id}. reassigning group id to avoid errors`);
2993
- id = undefined;
2994
- }
2995
- if (!id) {
2996
- id = this.nextGroupId.next();
2997
- while (this._groups.has(id)) {
2998
- id = this.nextGroupId.next();
2999
- }
3000
- }
3001
- const view = new DockviewGroupPanel(this, id, options);
3002
- view.init({ params: {}, accessor: this });
3003
- if (!this._groups.has(view.id)) {
3004
- const disposable = new CompositeDisposable(view.model.onTabDragStart((event) => {
3005
- var _a;
3006
- (_a = this._advancedDnDService) === null || _a === void 0 ? void 0 : _a.dispatchWillDragPanel(event);
3007
- }), view.model.onGroupDragStart((event) => {
3008
- var _a;
3009
- (_a = this._advancedDnDService) === null || _a === void 0 ? void 0 : _a.dispatchWillDragGroup(event);
3010
- }), view.model.onMove((event) => {
3011
- const { groupId, itemId, target, index, tabGroupId } = event;
3012
- this.moveGroupOrPanel({
3013
- from: {
3014
- groupId: groupId,
3015
- panelId: itemId,
3016
- tabGroupId,
3017
- },
3018
- to: {
3019
- group: view,
3020
- position: target,
3021
- index,
3022
- },
3023
- });
3024
- }), view.model.onDidDrop((event) => {
3025
- this._onDidDrop.fire(event);
3026
- }), view.model.onWillDrop((event) => {
3027
- var _a;
3028
- (_a = this._advancedDnDService) === null || _a === void 0 ? void 0 : _a.dispatchWillDrop(event);
3029
- }), view.model.onWillShowOverlay((event) => {
3030
- var _a;
3031
- if (this.options.disableDnd) {
3032
- // Engine policy — stays in core, ahead of any
3033
- // customisation dispatch.
3034
- event.preventDefault();
3035
- return;
3036
- }
3037
- (_a = this._advancedDnDService) === null || _a === void 0 ? void 0 : _a.dispatchWillShowOverlay(event);
3038
- }), view.model.onUnhandledDragOver((event) => {
3039
- this._onUnhandledDragOver.fire(event);
3040
- }), view.model.onDidAddPanel((event) => {
3041
- if (this._moving) {
3042
- return;
3043
- }
3044
- this._onDidAddPanel.fire(event.panel);
3045
- }), view.model.onDidRemovePanel((event) => {
3046
- if (this._moving) {
3047
- return;
3048
- }
3049
- this._onDidRemovePanel.fire(event.panel);
3050
- }), view.model.onDidActivePanelChange((event) => {
3051
- var _a;
3052
- if (this._moving) {
3053
- return;
3054
- }
3055
- if (event.panel !== this.activePanel) {
3056
- return;
3057
- }
3058
- if (((_a = this._onDidActivePanelChange.value) === null || _a === void 0 ? void 0 : _a.panel) !==
3059
- event.panel) {
3060
- this.fireActivePanelChange(event.panel);
3061
- }
3062
- }), Event.any(view.model.onDidPanelTitleChange, view.model.onDidPanelParametersChange)(() => {
3063
- this._bufferOnDidLayoutChange.fire();
3064
- }));
3065
- this._groups.set(view.id, { value: view, disposable });
3066
- }
3067
- // TODO: must be called after the above listeners have been setup, not an ideal pattern
3068
- view.initialize();
3069
- return view;
3070
- }
3071
- createPanel(options, group) {
3072
- var _a, _b, _c;
3073
- const contentComponent = options.component;
3074
- const tabComponent = (_a = options.tabComponent) !== null && _a !== void 0 ? _a : this.options.defaultTabComponent;
3075
- const view = new DockviewPanelModel(this, options.id, contentComponent, tabComponent);
3076
- const panel = new DockviewPanel(options.id, contentComponent, tabComponent, this, this._api, group, view, {
3077
- renderer: options.renderer,
3078
- minimumWidth: options.minimumWidth,
3079
- minimumHeight: options.minimumHeight,
3080
- maximumWidth: options.maximumWidth,
3081
- maximumHeight: options.maximumHeight,
3082
- });
3083
- panel.init({
3084
- title: (_b = options.title) !== null && _b !== void 0 ? _b : options.id,
3085
- params: (_c = options === null || options === void 0 ? void 0 : options.params) !== null && _c !== void 0 ? _c : {},
3086
- });
3087
- return panel;
3088
- }
3089
- createGroupAtLocation(location, size, options, gridview = this.gridview) {
3090
- const group = this.createGroup(options);
3091
- this.doAddGroup(group, location, size, gridview);
3092
- this.setGroupLocationForRoot(group, gridview);
3093
- return group;
3094
- }
3095
- /**
3096
- * Tag a group with the location and render / drop-target containers
3097
- * matching the gridview root it now lives in: the main grid, a floating
3098
- * window (shares the main containers), or a popout window (uses its own
3099
- * window-local containers).
3100
- */
3101
- setGroupLocationForRoot(group, gridview) {
3102
- var _a;
3103
- const popout = (_a = this._popoutWindowService) === null || _a === void 0 ? void 0 : _a.entries.find((entry) => entry.gridview === gridview);
3104
- if (popout) {
3105
- if (group.model.renderContainer !== popout.overlayRenderContainer) {
3106
- group.model.renderContainer = popout.overlayRenderContainer;
3107
- }
3108
- group.model.dropTargetContainer = popout.dropTargetContainer;
3109
- group.model.location = {
3110
- type: 'popout',
3111
- getWindow: popout.getWindow,
3112
- popoutUrl: popout.popoutUrl,
3113
- };
3114
- return;
3115
- }
3116
- // grid / floating both render through the main containers
3117
- if (group.model.renderContainer !== this.overlayRenderContainer) {
3118
- group.model.renderContainer = this.overlayRenderContainer;
3119
- }
3120
- group.model.dropTargetContainer = this.rootDropTargetContainer;
3121
- group.model.location =
3122
- gridview === this.gridview
3123
- ? { type: 'grid' }
3124
- : { type: 'floating' };
3125
- }
3126
- /**
3127
- * Resolve which gridview root currently owns a group: the main grid, or
3128
- * the nested gridview of the floating / popout window it lives in.
3129
- */
3130
- getGridviewForGroup(group) {
3131
- var _a, _b;
3132
- const floating = (_a = this._floatingGroupService) === null || _a === void 0 ? void 0 : _a.findByGroup(group);
3133
- if (floating) {
3134
- return floating.gridview;
3135
- }
3136
- // Use findByGroup (anchor-identity OR containment) for symmetry with
3137
- // the floating branch — it also resolves an anchor whose element is
3138
- // briefly detached from the gridview during a move/restore.
3139
- const popout = (_b = this._popoutWindowService) === null || _b === void 0 ? void 0 : _b.findByGroup(group);
3140
- if (popout) {
3141
- return popout.gridview;
3142
- }
3143
- return this.gridview;
3144
- }
3145
- /**
3146
- * The groups that live within the same floating / popout window as `group`
3147
- * (including `group` itself). Empty when `group` is in the main grid.
3148
- */
3149
- nestedWindowMembers(group) {
3150
- const gridview = this.getGridviewForGroup(group);
3151
- if (gridview === this.gridview) {
3152
- return [];
3153
- }
3154
- return this.groups.filter((candidate) => gridview.element.contains(candidate.element));
3155
- }
3156
- findGroup(panel) {
3157
- var _a;
3158
- return (_a = Array.from(this._groups.values()).find((group) => group.value.model.containsPanel(panel))) === null || _a === void 0 ? void 0 : _a.value;
3159
- }
3160
- orientationAtLocation(location) {
3161
- const rootOrientation = this.gridview.orientation;
3162
- return location.length % 2 == 1
3163
- ? rootOrientation
3164
- : orthogonal(rootOrientation);
3165
- }
3166
- updateTheme() {
3167
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
3168
- const theme = (_a = this._options.theme) !== null && _a !== void 0 ? _a : themeAbyss;
3169
- // Apply the theme class only to the shell so edge groups and the
3170
- // main grid both inherit its CSS custom properties via the cascade.
3171
- // Re-declaring it on `.dv-dockview` would block consumer overrides
3172
- // set on the shell from reaching the dockview subtree.
3173
- (_b = this._shellThemeClassnames) === null || _b === void 0 ? void 0 : _b.setClassNames(theme.className);
3174
- const gap = (_c = theme.gap) !== null && _c !== void 0 ? _c : 0;
3175
- this.gridview.margin = gap;
3176
- // Floating / popout windows host their own nested gridviews; keep their
3177
- // gap in sync with the main grid when the theme changes at runtime.
3178
- for (const floating of this.floatingGroups) {
3179
- floating.gridview.margin = gap;
3180
- }
3181
- for (const entry of (_e = (_d = this._popoutWindowService) === null || _d === void 0 ? void 0 : _d.entries) !== null && _e !== void 0 ? _e : []) {
3182
- entry.gridview.margin = gap;
3183
- }
3184
- (_f = this._shellManager) === null || _f === void 0 ? void 0 : _f.updateTheme(gap, (_g = theme.edgeGroupCollapsedSize) !== null && _g !== void 0 ? _g : 35);
3185
- if (theme.dndOverlayBorder === undefined) {
3186
- this.element.style.removeProperty('--dv-drag-over-border');
3187
- (_h = this._shellManager) === null || _h === void 0 ? void 0 : _h.element.style.removeProperty('--dv-drag-over-border');
3188
- }
3189
- else {
3190
- this.element.style.setProperty('--dv-drag-over-border', theme.dndOverlayBorder);
3191
- (_j = this._shellManager) === null || _j === void 0 ? void 0 : _j.element.style.setProperty('--dv-drag-over-border', theme.dndOverlayBorder);
3192
- }
3193
- switch (theme.dndOverlayMounting) {
3194
- case 'absolute':
3195
- this.rootDropTargetContainer.disabled = false;
3196
- break;
3197
- case 'relative':
3198
- default:
3199
- this.rootDropTargetContainer.disabled = true;
3200
- break;
3201
- }
3202
- // Toggle a CSS class so theme stylesheets can scope pure-CSS
3203
- // tab group indicator rules to the 'none' mode only.
3204
- const indicatorNone = ((_k = theme.tabGroupIndicator) !== null && _k !== void 0 ? _k : 'wrap') === 'none';
3205
- toggleClass(this.element, 'dv-tab-group-indicator-none', indicatorNone);
3206
- if (this._shellManager) {
3207
- toggleClass(this._shellManager.element, 'dv-tab-group-indicator-none', indicatorNone);
3208
- }
3209
- // Re-render tab group indicators so the new tabGroupIndicator mode takes effect
3210
- for (const group of this.groups) {
3211
- group.model.updateTabGroups();
3212
- }
3213
- }
3214
- }