dockview-core 1.8.2 → 1.8.4

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 (187) hide show
  1. package/dist/cjs/api/component.api.d.ts +8 -4
  2. package/dist/cjs/api/component.api.d.ts.map +1 -1
  3. package/dist/cjs/api/component.api.js +14 -0
  4. package/dist/cjs/api/component.api.js.map +1 -1
  5. package/dist/cjs/dnd/abstractDragHandler.d.ts +2 -2
  6. package/dist/cjs/dnd/abstractDragHandler.d.ts.map +1 -1
  7. package/dist/cjs/dnd/abstractDragHandler.js +16 -12
  8. package/dist/cjs/dnd/abstractDragHandler.js.map +1 -1
  9. package/dist/cjs/dnd/groupDragHandler.d.ts +4 -3
  10. package/dist/cjs/dnd/groupDragHandler.d.ts.map +1 -1
  11. package/dist/cjs/dnd/groupDragHandler.js +5 -4
  12. package/dist/cjs/dnd/groupDragHandler.js.map +1 -1
  13. package/dist/cjs/dnd/overlay.d.ts +6 -2
  14. package/dist/cjs/dnd/overlay.d.ts.map +1 -1
  15. package/dist/cjs/dnd/overlay.js +54 -23
  16. package/dist/cjs/dnd/overlay.js.map +1 -1
  17. package/dist/cjs/dockview/components/tab/tab.d.ts +7 -4
  18. package/dist/cjs/dockview/components/tab/tab.d.ts.map +1 -1
  19. package/dist/cjs/dockview/components/tab/tab.js +36 -28
  20. package/dist/cjs/dockview/components/tab/tab.js.map +1 -1
  21. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +19 -1
  22. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts.map +1 -1
  23. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +42 -15
  24. package/dist/cjs/dockview/components/titlebar/tabsContainer.js.map +1 -1
  25. package/dist/cjs/dockview/components/titlebar/voidContainer.d.ts +2 -0
  26. package/dist/cjs/dockview/components/titlebar/voidContainer.d.ts.map +1 -1
  27. package/dist/cjs/dockview/components/titlebar/voidContainer.js +7 -3
  28. package/dist/cjs/dockview/components/titlebar/voidContainer.js.map +1 -1
  29. package/dist/cjs/dockview/dockviewComponent.d.ts +11 -4
  30. package/dist/cjs/dockview/dockviewComponent.d.ts.map +1 -1
  31. package/dist/cjs/dockview/dockviewComponent.js +288 -92
  32. package/dist/cjs/dockview/dockviewComponent.js.map +1 -1
  33. package/dist/cjs/dockview/dockviewGroupPanel.d.ts +4 -4
  34. package/dist/cjs/dockview/dockviewGroupPanel.d.ts.map +1 -1
  35. package/dist/cjs/dockview/dockviewGroupPanel.js.map +1 -1
  36. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +11 -4
  37. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts.map +1 -1
  38. package/dist/cjs/dockview/dockviewGroupPanelModel.js +28 -6
  39. package/dist/cjs/dockview/dockviewGroupPanelModel.js.map +1 -1
  40. package/dist/cjs/dockview/dockviewPanel.d.ts +1 -1
  41. package/dist/cjs/dockview/dockviewPanel.d.ts.map +1 -1
  42. package/dist/cjs/dockview/options.d.ts +9 -5
  43. package/dist/cjs/dockview/options.d.ts.map +1 -1
  44. package/dist/cjs/dockview/options.js.map +1 -1
  45. package/dist/cjs/gridview/baseComponentGridview.d.ts +1 -1
  46. package/dist/cjs/gridview/baseComponentGridview.d.ts.map +1 -1
  47. package/dist/cjs/gridview/baseComponentGridview.js.map +1 -1
  48. package/dist/cjs/gridview/basePanelView.d.ts +4 -4
  49. package/dist/cjs/gridview/basePanelView.d.ts.map +1 -1
  50. package/dist/cjs/gridview/basePanelView.js.map +1 -1
  51. package/dist/cjs/gridview/branchNode.d.ts.map +1 -1
  52. package/dist/cjs/gridview/branchNode.js +1 -0
  53. package/dist/cjs/gridview/branchNode.js.map +1 -1
  54. package/dist/cjs/gridview/gridview.d.ts.map +1 -1
  55. package/dist/cjs/gridview/gridview.js +8 -0
  56. package/dist/cjs/gridview/gridview.js.map +1 -1
  57. package/dist/cjs/gridview/gridviewComponent.d.ts +4 -4
  58. package/dist/cjs/gridview/gridviewComponent.d.ts.map +1 -1
  59. package/dist/cjs/gridview/gridviewComponent.js +71 -39
  60. package/dist/cjs/gridview/gridviewComponent.js.map +1 -1
  61. package/dist/cjs/index.d.ts +1 -0
  62. package/dist/cjs/index.d.ts.map +1 -1
  63. package/dist/cjs/index.js.map +1 -1
  64. package/dist/cjs/lifecycle.d.ts +0 -1
  65. package/dist/cjs/lifecycle.d.ts.map +1 -1
  66. package/dist/cjs/lifecycle.js +0 -32
  67. package/dist/cjs/lifecycle.js.map +1 -1
  68. package/dist/cjs/panel/types.d.ts +2 -2
  69. package/dist/cjs/panel/types.d.ts.map +1 -1
  70. package/dist/cjs/paneview/paneviewComponent.d.ts +5 -6
  71. package/dist/cjs/paneview/paneviewComponent.d.ts.map +1 -1
  72. package/dist/cjs/paneview/paneviewComponent.js.map +1 -1
  73. package/dist/cjs/resizable.d.ts.map +1 -1
  74. package/dist/cjs/resizable.js +8 -0
  75. package/dist/cjs/resizable.js.map +1 -1
  76. package/dist/cjs/splitview/splitview.d.ts.map +1 -1
  77. package/dist/cjs/splitview/splitview.js +11 -1
  78. package/dist/cjs/splitview/splitview.js.map +1 -1
  79. package/dist/cjs/splitview/splitviewComponent.d.ts +4 -4
  80. package/dist/cjs/splitview/splitviewComponent.d.ts.map +1 -1
  81. package/dist/cjs/splitview/splitviewComponent.js.map +1 -1
  82. package/dist/cjs/splitview/splitviewPanel.d.ts +1 -1
  83. package/dist/dockview-core.amd.js +411 -186
  84. package/dist/dockview-core.amd.js.map +1 -1
  85. package/dist/dockview-core.amd.min.js +2 -2
  86. package/dist/dockview-core.amd.min.js.map +1 -1
  87. package/dist/dockview-core.amd.min.noStyle.js +2 -2
  88. package/dist/dockview-core.amd.min.noStyle.js.map +1 -1
  89. package/dist/dockview-core.amd.noStyle.js +411 -186
  90. package/dist/dockview-core.amd.noStyle.js.map +1 -1
  91. package/dist/dockview-core.cjs.js +411 -186
  92. package/dist/dockview-core.cjs.js.map +1 -1
  93. package/dist/dockview-core.esm.js +411 -186
  94. package/dist/dockview-core.esm.js.map +1 -1
  95. package/dist/dockview-core.esm.min.js +2 -2
  96. package/dist/dockview-core.esm.min.js.map +1 -1
  97. package/dist/dockview-core.js +411 -186
  98. package/dist/dockview-core.js.map +1 -1
  99. package/dist/dockview-core.min.js +2 -2
  100. package/dist/dockview-core.min.js.map +1 -1
  101. package/dist/dockview-core.min.noStyle.js +2 -2
  102. package/dist/dockview-core.min.noStyle.js.map +1 -1
  103. package/dist/dockview-core.noStyle.js +411 -186
  104. package/dist/dockview-core.noStyle.js.map +1 -1
  105. package/dist/esm/api/component.api.d.ts +8 -4
  106. package/dist/esm/api/component.api.d.ts.map +1 -1
  107. package/dist/esm/api/component.api.js +6 -0
  108. package/dist/esm/api/component.api.js.map +1 -1
  109. package/dist/esm/dnd/abstractDragHandler.d.ts +2 -2
  110. package/dist/esm/dnd/abstractDragHandler.d.ts.map +1 -1
  111. package/dist/esm/dnd/abstractDragHandler.js +16 -12
  112. package/dist/esm/dnd/abstractDragHandler.js.map +1 -1
  113. package/dist/esm/dnd/groupDragHandler.d.ts +4 -3
  114. package/dist/esm/dnd/groupDragHandler.d.ts.map +1 -1
  115. package/dist/esm/dnd/groupDragHandler.js +5 -4
  116. package/dist/esm/dnd/groupDragHandler.js.map +1 -1
  117. package/dist/esm/dnd/overlay.d.ts +6 -2
  118. package/dist/esm/dnd/overlay.d.ts.map +1 -1
  119. package/dist/esm/dnd/overlay.js +46 -23
  120. package/dist/esm/dnd/overlay.js.map +1 -1
  121. package/dist/esm/dockview/components/tab/tab.d.ts +7 -4
  122. package/dist/esm/dockview/components/tab/tab.d.ts.map +1 -1
  123. package/dist/esm/dockview/components/tab/tab.js +32 -24
  124. package/dist/esm/dockview/components/tab/tab.js.map +1 -1
  125. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +19 -1
  126. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts.map +1 -1
  127. package/dist/esm/dockview/components/titlebar/tabsContainer.js +42 -15
  128. package/dist/esm/dockview/components/titlebar/tabsContainer.js.map +1 -1
  129. package/dist/esm/dockview/components/titlebar/voidContainer.d.ts +2 -0
  130. package/dist/esm/dockview/components/titlebar/voidContainer.d.ts.map +1 -1
  131. package/dist/esm/dockview/components/titlebar/voidContainer.js +7 -3
  132. package/dist/esm/dockview/components/titlebar/voidContainer.js.map +1 -1
  133. package/dist/esm/dockview/dockviewComponent.d.ts +11 -4
  134. package/dist/esm/dockview/dockviewComponent.d.ts.map +1 -1
  135. package/dist/esm/dockview/dockviewComponent.js +204 -59
  136. package/dist/esm/dockview/dockviewComponent.js.map +1 -1
  137. package/dist/esm/dockview/dockviewGroupPanel.d.ts +4 -4
  138. package/dist/esm/dockview/dockviewGroupPanel.d.ts.map +1 -1
  139. package/dist/esm/dockview/dockviewGroupPanel.js.map +1 -1
  140. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +11 -4
  141. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts.map +1 -1
  142. package/dist/esm/dockview/dockviewGroupPanelModel.js +28 -6
  143. package/dist/esm/dockview/dockviewGroupPanelModel.js.map +1 -1
  144. package/dist/esm/dockview/dockviewPanel.d.ts +1 -1
  145. package/dist/esm/dockview/dockviewPanel.d.ts.map +1 -1
  146. package/dist/esm/dockview/options.d.ts +9 -5
  147. package/dist/esm/dockview/options.d.ts.map +1 -1
  148. package/dist/esm/dockview/options.js.map +1 -1
  149. package/dist/esm/gridview/baseComponentGridview.d.ts +1 -1
  150. package/dist/esm/gridview/baseComponentGridview.d.ts.map +1 -1
  151. package/dist/esm/gridview/baseComponentGridview.js.map +1 -1
  152. package/dist/esm/gridview/basePanelView.d.ts +4 -4
  153. package/dist/esm/gridview/basePanelView.d.ts.map +1 -1
  154. package/dist/esm/gridview/basePanelView.js.map +1 -1
  155. package/dist/esm/gridview/branchNode.d.ts.map +1 -1
  156. package/dist/esm/gridview/branchNode.js +1 -0
  157. package/dist/esm/gridview/branchNode.js.map +1 -1
  158. package/dist/esm/gridview/gridview.d.ts.map +1 -1
  159. package/dist/esm/gridview/gridview.js +8 -0
  160. package/dist/esm/gridview/gridview.js.map +1 -1
  161. package/dist/esm/gridview/gridviewComponent.d.ts +4 -4
  162. package/dist/esm/gridview/gridviewComponent.d.ts.map +1 -1
  163. package/dist/esm/gridview/gridviewComponent.js +56 -35
  164. package/dist/esm/gridview/gridviewComponent.js.map +1 -1
  165. package/dist/esm/index.d.ts +1 -0
  166. package/dist/esm/index.d.ts.map +1 -1
  167. package/dist/esm/index.js.map +1 -1
  168. package/dist/esm/lifecycle.d.ts +0 -1
  169. package/dist/esm/lifecycle.d.ts.map +1 -1
  170. package/dist/esm/lifecycle.js +0 -3
  171. package/dist/esm/lifecycle.js.map +1 -1
  172. package/dist/esm/panel/types.d.ts +2 -2
  173. package/dist/esm/panel/types.d.ts.map +1 -1
  174. package/dist/esm/paneview/paneviewComponent.d.ts +5 -6
  175. package/dist/esm/paneview/paneviewComponent.d.ts.map +1 -1
  176. package/dist/esm/paneview/paneviewComponent.js.map +1 -1
  177. package/dist/esm/resizable.d.ts.map +1 -1
  178. package/dist/esm/resizable.js +8 -0
  179. package/dist/esm/resizable.js.map +1 -1
  180. package/dist/esm/splitview/splitview.d.ts.map +1 -1
  181. package/dist/esm/splitview/splitview.js +11 -1
  182. package/dist/esm/splitview/splitview.js.map +1 -1
  183. package/dist/esm/splitview/splitviewComponent.d.ts +4 -4
  184. package/dist/esm/splitview/splitviewComponent.d.ts.map +1 -1
  185. package/dist/esm/splitview/splitviewComponent.js.map +1 -1
  186. package/dist/esm/splitview/splitviewPanel.d.ts +1 -1
  187. package/package.json +3 -4
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * dockview-core
3
- * @version 1.8.2
3
+ * @version 1.8.4
4
4
  * @link https://github.com/mathuo/dockview
5
5
  * @license MIT
6
6
  */
@@ -274,9 +274,6 @@
274
274
  get isDisposed() {
275
275
  return this._isDisposed;
276
276
  }
277
- static from(...args) {
278
- return new CompositeDisposable(...args);
279
- }
280
277
  constructor(...args) {
281
278
  this._isDisposed = false;
282
279
  this._disposables = args;
@@ -905,7 +902,17 @@
905
902
  size = typeof size === 'number' ? size : item.size;
906
903
  size = clamp(size, item.minimumSize, item.maximumSize);
907
904
  item.size = size;
908
- this.relayout([index]);
905
+ const indexes = range(this.viewItems.length).filter((i) => i !== index);
906
+ const lowPriorityIndexes = [
907
+ ...indexes.filter((i) => this.viewItems[i].priority === exports.LayoutPriority.Low),
908
+ index,
909
+ ];
910
+ const highPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === exports.LayoutPriority.High);
911
+ /**
912
+ * add this view we are changing to the low-index list since we have determined the size
913
+ * here and don't want it changed
914
+ */
915
+ this.relayout([...lowPriorityIndexes, index], highPriorityIndexes);
909
916
  }
910
917
  addView(view, size = { type: 'distribute' }, index = this.viewItems.length, skipLayout) {
911
918
  const container = document.createElement('div');
@@ -1662,6 +1669,7 @@
1662
1669
  orientation: this.orientation,
1663
1670
  descriptor,
1664
1671
  proportionalLayout,
1672
+ styles,
1665
1673
  });
1666
1674
  }
1667
1675
  this.addDisposables(this._onDidChange, this.splitview.onDidSashEnd(() => {
@@ -2173,6 +2181,14 @@
2173
2181
  const child = sibling.children[i];
2174
2182
  grandParent.addChild(child, child.size, parentIndex + i);
2175
2183
  }
2184
+ /**
2185
+ * clean down the branch node since we need to dipose of it and
2186
+ * when .dispose() it called on a branch it will dispose of any
2187
+ * views it is holding onto.
2188
+ */
2189
+ while (sibling.children.length > 0) {
2190
+ sibling.removeChild(0);
2191
+ }
2176
2192
  }
2177
2193
  else {
2178
2194
  // otherwise create a new leaf node and add that to the grandparent
@@ -2480,6 +2496,12 @@
2480
2496
  get onDidDrop() {
2481
2497
  return this.component.onDidDrop;
2482
2498
  }
2499
+ get onWillDragGroup() {
2500
+ return this.component.onWillDragGroup;
2501
+ }
2502
+ get onWillDragPanel() {
2503
+ return this.component.onWillDragPanel;
2504
+ }
2483
2505
  get panels() {
2484
2506
  return this.component.panels;
2485
2507
  }
@@ -2942,7 +2964,7 @@
2942
2964
  }
2943
2965
  configure() {
2944
2966
  this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
2945
- if (this.isCancelled(event)) {
2967
+ if (event.defaultPrevented || this.isCancelled(event)) {
2946
2968
  event.preventDefault();
2947
2969
  return;
2948
2970
  }
@@ -2962,19 +2984,23 @@
2962
2984
  }
2963
2985
  this.el.classList.add('dv-dragged');
2964
2986
  setTimeout(() => this.el.classList.remove('dv-dragged'), 0);
2965
- this.dataDisposable.value = this.getData(event.dataTransfer);
2987
+ this.dataDisposable.value = this.getData(event);
2988
+ this._onDragStart.fire(event);
2966
2989
  if (event.dataTransfer) {
2967
2990
  event.dataTransfer.effectAllowed = 'move';
2968
- /**
2969
- * Although this is not used by dockview many third party dnd libraries will check
2970
- * dataTransfer.types to determine valid drag events.
2971
- *
2972
- * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
2973
- * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
2974
- * dnd logic. You can see the code at
2975
- * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
2976
- */
2977
- event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
2991
+ const hasData = event.dataTransfer.items.length > 0;
2992
+ if (!hasData) {
2993
+ /**
2994
+ * Although this is not used by dockview many third party dnd libraries will check
2995
+ * dataTransfer.types to determine valid drag events.
2996
+ *
2997
+ * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
2998
+ * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
2999
+ * dnd logic. You can see the code at
3000
+ * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
3001
+ */
3002
+ event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
3003
+ }
2978
3004
  }
2979
3005
  }), addDisposableListener(this.el, 'dragend', () => {
2980
3006
  this.pointerEventsDisposable.dispose();
@@ -2983,44 +3009,45 @@
2983
3009
  }
2984
3010
  }
2985
3011
 
3012
+ class TabDragHandler extends DragHandler {
3013
+ constructor(element, accessor, group, panel) {
3014
+ super(element);
3015
+ this.accessor = accessor;
3016
+ this.group = group;
3017
+ this.panel = panel;
3018
+ this.panelTransfer = LocalSelectionTransfer.getInstance();
3019
+ }
3020
+ getData(event) {
3021
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, this.panel.id)], PanelTransfer.prototype);
3022
+ return {
3023
+ dispose: () => {
3024
+ this.panelTransfer.clearData(PanelTransfer.prototype);
3025
+ },
3026
+ };
3027
+ }
3028
+ }
2986
3029
  class Tab extends CompositeDisposable {
2987
3030
  get element() {
2988
3031
  return this._element;
2989
3032
  }
2990
- constructor(panelId, accessor, group) {
3033
+ constructor(panel, accessor, group) {
2991
3034
  super();
2992
- this.panelId = panelId;
3035
+ this.panel = panel;
2993
3036
  this.accessor = accessor;
2994
3037
  this.group = group;
3038
+ this.content = undefined;
2995
3039
  this._onChanged = new Emitter();
2996
3040
  this.onChanged = this._onChanged.event;
2997
3041
  this._onDropped = new Emitter();
2998
3042
  this.onDrop = this._onDropped.event;
3043
+ this._onDragStart = new Emitter();
3044
+ this.onDragStart = this._onDragStart.event;
2999
3045
  this._element = document.createElement('div');
3000
3046
  this._element.className = 'tab';
3001
3047
  this._element.tabIndex = 0;
3002
3048
  this._element.draggable = true;
3003
3049
  toggleClass(this.element, 'inactive-tab', true);
3004
- this.addDisposables(this._onChanged, this._onDropped, new (class Handler extends DragHandler {
3005
- constructor() {
3006
- super(...arguments);
3007
- this.panelTransfer = LocalSelectionTransfer.getInstance();
3008
- }
3009
- getData() {
3010
- this.panelTransfer.setData([new PanelTransfer(accessor.id, group.id, panelId)], PanelTransfer.prototype);
3011
- return {
3012
- dispose: () => {
3013
- this.panelTransfer.clearData(PanelTransfer.prototype);
3014
- },
3015
- };
3016
- }
3017
- })(this._element));
3018
- this.addDisposables(addDisposableListener(this._element, 'mousedown', (event) => {
3019
- if (event.defaultPrevented) {
3020
- return;
3021
- }
3022
- this._onChanged.fire(event);
3023
- }));
3050
+ const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
3024
3051
  this.droptarget = new Droptarget(this._element, {
3025
3052
  acceptedTargetZones: ['center'],
3026
3053
  canDisplayOverlay: (event, position) => {
@@ -3034,12 +3061,19 @@
3034
3061
  // don't allow group move to drop on self
3035
3062
  return false;
3036
3063
  }
3037
- return this.panelId !== data.panelId;
3064
+ return this.panel.id !== data.panelId;
3038
3065
  }
3039
3066
  return this.group.model.canDisplayOverlay(event, position, exports.DockviewDropTargets.Tab);
3040
3067
  },
3041
3068
  });
3042
- this.addDisposables(this.droptarget.onDrop((event) => {
3069
+ this.addDisposables(this._onChanged, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
3070
+ this._onDragStart.fire(event);
3071
+ }), dragHandler, addDisposableListener(this._element, 'mousedown', (event) => {
3072
+ if (event.defaultPrevented) {
3073
+ return;
3074
+ }
3075
+ this._onChanged.fire(event);
3076
+ }), this.droptarget.onDrop((event) => {
3043
3077
  this._onDropped.fire(event);
3044
3078
  }), this.droptarget);
3045
3079
  }
@@ -3071,9 +3105,9 @@
3071
3105
  }
3072
3106
 
3073
3107
  class GroupDragHandler extends DragHandler {
3074
- constructor(element, accessorId, group) {
3108
+ constructor(element, accessor, group) {
3075
3109
  super(element);
3076
- this.accessorId = accessorId;
3110
+ this.accessor = accessor;
3077
3111
  this.group = group;
3078
3112
  this.panelTransfer = LocalSelectionTransfer.getInstance();
3079
3113
  this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
@@ -3093,8 +3127,9 @@
3093
3127
  }
3094
3128
  return false;
3095
3129
  }
3096
- getData(dataTransfer) {
3097
- this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype);
3130
+ getData(dragEvent) {
3131
+ const dataTransfer = dragEvent.dataTransfer;
3132
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, null)], PanelTransfer.prototype);
3098
3133
  const style = window.getComputedStyle(this.el);
3099
3134
  const bgColor = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-background-color');
3100
3135
  const color = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-color');
@@ -3129,14 +3164,16 @@
3129
3164
  this.group = group;
3130
3165
  this._onDrop = new Emitter();
3131
3166
  this.onDrop = this._onDrop.event;
3167
+ this._onDragStart = new Emitter();
3168
+ this.onDragStart = this._onDragStart.event;
3132
3169
  this._element = document.createElement('div');
3133
3170
  this._element.className = 'void-container';
3134
3171
  this._element.tabIndex = 0;
3135
3172
  this._element.draggable = true;
3136
- this.addDisposables(this._onDrop, addDisposableListener(this._element, 'click', () => {
3173
+ this.addDisposables(this._onDrop, this._onDragStart, addDisposableListener(this._element, 'click', () => {
3137
3174
  this.accessor.doSetGroupActive(this.group);
3138
3175
  }));
3139
- const handler = new GroupDragHandler(this._element, accessor.id, group);
3176
+ const handler = new GroupDragHandler(this._element, accessor, group);
3140
3177
  this.voidDropTarget = new Droptarget(this._element, {
3141
3178
  acceptedTargetZones: ['center'],
3142
3179
  canDisplayOverlay: (event, position) => {
@@ -3154,7 +3191,9 @@
3154
3191
  return group.model.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3155
3192
  },
3156
3193
  });
3157
- this.addDisposables(handler, this.voidDropTarget.onDrop((event) => {
3194
+ this.addDisposables(handler, handler.onDragStart((event) => {
3195
+ this._onDragStart.fire(event);
3196
+ }), this.voidDropTarget.onDrop((event) => {
3158
3197
  this._onDrop.fire(event);
3159
3198
  }), this.voidDropTarget);
3160
3199
  }
@@ -3162,7 +3201,7 @@
3162
3201
 
3163
3202
  class TabsContainer extends CompositeDisposable {
3164
3203
  get panels() {
3165
- return this.tabs.map((_) => _.value.panelId);
3204
+ return this.tabs.map((_) => _.value.panel.id);
3166
3205
  }
3167
3206
  get size() {
3168
3207
  return this.tabs.length;
@@ -3208,6 +3247,19 @@
3208
3247
  this.leftActions = element;
3209
3248
  }
3210
3249
  }
3250
+ setPrefixActionsElement(element) {
3251
+ if (this.preActions === element) {
3252
+ return;
3253
+ }
3254
+ if (this.preActions) {
3255
+ this.preActions.remove();
3256
+ this.preActions = undefined;
3257
+ }
3258
+ if (element) {
3259
+ this.preActionsContainer.appendChild(element);
3260
+ this.preActions = element;
3261
+ }
3262
+ }
3211
3263
  get element() {
3212
3264
  return this._element;
3213
3265
  }
@@ -3216,7 +3268,7 @@
3216
3268
  this.tabs[this.selectedIndex].value === tab);
3217
3269
  }
3218
3270
  indexOf(id) {
3219
- return this.tabs.findIndex((tab) => tab.value.panelId === id);
3271
+ return this.tabs.findIndex((tab) => tab.value.panel.id === id);
3220
3272
  }
3221
3273
  constructor(accessor, group) {
3222
3274
  super();
@@ -3227,7 +3279,11 @@
3227
3279
  this._hidden = false;
3228
3280
  this._onDrop = new Emitter();
3229
3281
  this.onDrop = this._onDrop.event;
3230
- this.addDisposables(this._onDrop);
3282
+ this._onTabDragStart = new Emitter();
3283
+ this.onTabDragStart = this._onTabDragStart.event;
3284
+ this._onGroupDragStart = new Emitter();
3285
+ this.onGroupDragStart = this._onGroupDragStart.event;
3286
+ this.addDisposables(this._onDrop, this._onTabDragStart, this._onGroupDragStart);
3231
3287
  this._element = document.createElement('div');
3232
3288
  this._element.className = 'tabs-and-actions-container';
3233
3289
  toggleClass(this._element, 'dv-full-width-single-tab', this.accessor.options.singleTabMode === 'fullwidth');
@@ -3244,14 +3300,22 @@
3244
3300
  this.rightActionsContainer.className = 'right-actions-container';
3245
3301
  this.leftActionsContainer = document.createElement('div');
3246
3302
  this.leftActionsContainer.className = 'left-actions-container';
3303
+ this.preActionsContainer = document.createElement('div');
3304
+ this.preActionsContainer.className = 'pre-actions-container';
3247
3305
  this.tabContainer = document.createElement('div');
3248
3306
  this.tabContainer.className = 'tabs-container';
3249
3307
  this.voidContainer = new VoidContainer(this.accessor, this.group);
3308
+ this._element.appendChild(this.preActionsContainer);
3250
3309
  this._element.appendChild(this.tabContainer);
3251
3310
  this._element.appendChild(this.leftActionsContainer);
3252
3311
  this._element.appendChild(this.voidContainer.element);
3253
3312
  this._element.appendChild(this.rightActionsContainer);
3254
- this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => {
3313
+ this.addDisposables(this.voidContainer, this.voidContainer.onDragStart((event) => {
3314
+ this._onGroupDragStart.fire({
3315
+ nativeEvent: event,
3316
+ group: this.group,
3317
+ });
3318
+ }), this.voidContainer.onDrop((event) => {
3255
3319
  this._onDrop.fire({
3256
3320
  event: event.nativeEvent,
3257
3321
  index: this.tabs.length,
@@ -3297,7 +3361,7 @@
3297
3361
  }
3298
3362
  }
3299
3363
  delete(id) {
3300
- const index = this.tabs.findIndex((tab) => tab.value.panelId === id);
3364
+ const index = this.tabs.findIndex((tab) => tab.value.panel.id === id);
3301
3365
  const tabToRemove = this.tabs.splice(index, 1)[0];
3302
3366
  const { value, disposable } = tabToRemove;
3303
3367
  disposable.dispose();
@@ -3306,21 +3370,23 @@
3306
3370
  }
3307
3371
  setActivePanel(panel) {
3308
3372
  this.tabs.forEach((tab) => {
3309
- const isActivePanel = panel.id === tab.value.panelId;
3373
+ const isActivePanel = panel.id === tab.value.panel.id;
3310
3374
  tab.value.setActive(isActivePanel);
3311
3375
  });
3312
3376
  }
3313
3377
  openPanel(panel, index = this.tabs.length) {
3314
3378
  var _a;
3315
- if (this.tabs.find((tab) => tab.value.panelId === panel.id)) {
3379
+ if (this.tabs.find((tab) => tab.value.panel.id === panel.id)) {
3316
3380
  return;
3317
3381
  }
3318
- const tabToAdd = new Tab(panel.id, this.accessor, this.group);
3382
+ const tab = new Tab(panel, this.accessor, this.group);
3319
3383
  if (!((_a = panel.view) === null || _a === void 0 ? void 0 : _a.tab)) {
3320
3384
  throw new Error('invalid header component');
3321
3385
  }
3322
- tabToAdd.setContent(panel.view.tab);
3323
- const disposable = CompositeDisposable.from(tabToAdd.onChanged((event) => {
3386
+ tab.setContent(panel.view.tab);
3387
+ const disposable = new CompositeDisposable(tab.onDragStart((event) => {
3388
+ this._onTabDragStart.fire({ nativeEvent: event, panel });
3389
+ }), tab.onChanged((event) => {
3324
3390
  var _a;
3325
3391
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3326
3392
  const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
@@ -3328,8 +3394,8 @@
3328
3394
  !isFloatingWithOnePanel &&
3329
3395
  event.shiftKey) {
3330
3396
  event.preventDefault();
3331
- const panel = this.accessor.getGroupPanel(tabToAdd.panelId);
3332
- const { top, left } = tabToAdd.element.getBoundingClientRect();
3397
+ const panel = this.accessor.getGroupPanel(tab.panel.id);
3398
+ const { top, left } = tab.element.getBoundingClientRect();
3333
3399
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3334
3400
  this.accessor.addFloatingGroup(panel, {
3335
3401
  x: left - rootLeft,
@@ -3346,13 +3412,13 @@
3346
3412
  this.group.model.openPanel(panel, {
3347
3413
  skipFocus: alreadyFocused,
3348
3414
  });
3349
- }), tabToAdd.onDrop((event) => {
3415
+ }), tab.onDrop((event) => {
3350
3416
  this._onDrop.fire({
3351
3417
  event: event.nativeEvent,
3352
- index: this.tabs.findIndex((x) => x.value === tabToAdd),
3418
+ index: this.tabs.findIndex((x) => x.value === tab),
3353
3419
  });
3354
3420
  }));
3355
- const value = { value: tabToAdd, disposable };
3421
+ const value = { value: tab, disposable };
3356
3422
  this.addTab(value, index);
3357
3423
  }
3358
3424
  closePanel(panel) {
@@ -3380,7 +3446,7 @@
3380
3446
  }
3381
3447
  set locked(value) {
3382
3448
  this._locked = value;
3383
- toggleClass(this.container, 'locked-groupview', value);
3449
+ toggleClass(this.container, 'locked-groupview', value === 'no-drop-target' || value);
3384
3450
  }
3385
3451
  get isActive() {
3386
3452
  return this._isGroupActive;
@@ -3437,6 +3503,10 @@
3437
3503
  this.onMove = this._onMove.event;
3438
3504
  this._onDidDrop = new Emitter();
3439
3505
  this.onDidDrop = this._onDidDrop.event;
3506
+ this._onTabDragStart = new Emitter();
3507
+ this.onTabDragStart = this._onTabDragStart.event;
3508
+ this._onGroupDragStart = new Emitter();
3509
+ this.onGroupDragStart = this._onGroupDragStart.event;
3440
3510
  this._onDidAddPanel = new Emitter();
3441
3511
  this.onDidAddPanel = this._onDidAddPanel.event;
3442
3512
  this._onDidRemovePanel = new Emitter();
@@ -3449,7 +3519,8 @@
3449
3519
  this.dropTarget = new Droptarget(this.contentContainer.element, {
3450
3520
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3451
3521
  canDisplayOverlay: (event, position) => {
3452
- if (this.locked && position === 'center') {
3522
+ if (this.locked === 'no-drop-target' ||
3523
+ (this.locked && position === 'center')) {
3453
3524
  return false;
3454
3525
  }
3455
3526
  const data = getPanelData();
@@ -3475,8 +3546,12 @@
3475
3546
  });
3476
3547
  container.append(this.tabsContainer.element, this.contentContainer.element);
3477
3548
  this.header.hidden = !!options.hideHeader;
3478
- this.locked = !!options.locked;
3479
- this.addDisposables(this.tabsContainer.onDrop((event) => {
3549
+ this.locked = options.locked || false;
3550
+ this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this.tabsContainer.onTabDragStart((event) => {
3551
+ this._onTabDragStart.fire(event);
3552
+ }), this.tabsContainer.onGroupDragStart((event) => {
3553
+ this._onGroupDragStart.fire(event);
3554
+ }), this.tabsContainer.onDrop((event) => {
3480
3555
  this.handleDropEvent(event.event, 'center', event.index);
3481
3556
  }), this.contentContainer.onDidFocus(() => {
3482
3557
  this.accessor.doSetGroupActive(this.groupPanel, true);
@@ -3520,6 +3595,16 @@
3520
3595
  });
3521
3596
  this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
3522
3597
  }
3598
+ if (this.accessor.options.createPrefixHeaderActionsElement) {
3599
+ this._prefixHeaderActions =
3600
+ this.accessor.options.createPrefixHeaderActionsElement(this.groupPanel);
3601
+ this.addDisposables(this._prefixHeaderActions);
3602
+ this._prefixHeaderActions.init({
3603
+ containerApi: new DockviewApi(this.accessor),
3604
+ api: this.groupPanel.api,
3605
+ });
3606
+ this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
3607
+ }
3523
3608
  }
3524
3609
  indexOf(panel) {
3525
3610
  return this.tabsContainer.indexOf(panel.id);
@@ -3531,8 +3616,8 @@
3531
3616
  activeView: (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.id,
3532
3617
  id: this.id,
3533
3618
  };
3534
- if (this.locked) {
3535
- result.locked = true;
3619
+ if (this.locked !== false) {
3620
+ result.locked = this.locked;
3536
3621
  }
3537
3622
  if (this.header.hidden) {
3538
3623
  result.hideHeader = true;
@@ -3782,6 +3867,9 @@
3782
3867
  return false;
3783
3868
  }
3784
3869
  handleDropEvent(event, position, index) {
3870
+ if (this.locked === 'no-drop-target') {
3871
+ return;
3872
+ }
3785
3873
  const data = getPanelData();
3786
3874
  if (data && data.viewId === this.accessor.id) {
3787
3875
  if (data.panelId === null) {
@@ -3859,6 +3947,14 @@
3859
3947
  */
3860
3948
  return;
3861
3949
  }
3950
+ if (!document.body.contains(this._element)) {
3951
+ /**
3952
+ * since the event is dispatched through requestAnimationFrame there is a small chance
3953
+ * the component is no longer attached to the DOM, if that is the case the dimensions
3954
+ * are mostly likely all zero and meaningless. we should skip this case.
3955
+ */
3956
+ return;
3957
+ }
3862
3958
  const { width, height } = entry.contentRect;
3863
3959
  this.layout(width, height);
3864
3960
  }));
@@ -5239,6 +5335,12 @@
5239
5335
  return pushToTop;
5240
5336
  })();
5241
5337
  class Overlay extends CompositeDisposable {
5338
+ set minimumInViewportWidth(value) {
5339
+ this.options.minimumInViewportWidth = value;
5340
+ }
5341
+ set minimumInViewportHeight(value) {
5342
+ this.options.minimumInViewportHeight = value;
5343
+ }
5242
5344
  constructor(options) {
5243
5345
  super();
5244
5346
  this.options = options;
@@ -5284,9 +5386,11 @@
5284
5386
  const overlayRect = this._element.getBoundingClientRect();
5285
5387
  // region: ensure bounds within allowable limits
5286
5388
  // a minimum width of minimumViewportWidth must be inside the viewport
5287
- const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5389
+ const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width));
5288
5390
  // a minimum height of minimumViewportHeight must be inside the viewport
5289
- const yOffset = Math.max(0, overlayRect.height - this.options.minimumInViewportHeight);
5391
+ const yOffset = typeof this.options.minimumInViewportHeight === 'number'
5392
+ ? Math.max(0, this.getMinimumHeight(overlayRect.height))
5393
+ : 0;
5290
5394
  const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5291
5395
  const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5292
5396
  this._element.style.left = `${left}px`;
@@ -5332,9 +5436,10 @@
5332
5436
  y: e.clientY - overlayRect.top,
5333
5437
  };
5334
5438
  }
5335
- const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5336
- const yOffset = Math.max(0, overlayRect.height -
5337
- this.options.minimumInViewportHeight);
5439
+ const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width));
5440
+ const yOffset = Math.max(0, this.options.minimumInViewportHeight
5441
+ ? this.getMinimumHeight(overlayRect.height)
5442
+ : 0);
5338
5443
  const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5339
5444
  const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5340
5445
  this.setBounds({ top, left });
@@ -5408,14 +5513,11 @@
5408
5513
  let height = undefined;
5409
5514
  let left = undefined;
5410
5515
  let width = undefined;
5411
- const minimumInViewportHeight = this.options.minimumInViewportHeight;
5412
- const minimumInViewportWidth = this.options.minimumInViewportWidth;
5413
- function moveTop() {
5516
+ const moveTop = () => {
5414
5517
  top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
5415
5518
  startPosition.originalHeight >
5416
5519
  containerRect.height
5417
- ? containerRect.height -
5418
- minimumInViewportHeight
5520
+ ? this.getMinimumHeight(containerRect.height)
5419
5521
  : Math.max(0, startPosition.originalY +
5420
5522
  startPosition.originalHeight -
5421
5523
  Overlay.MINIMUM_HEIGHT));
@@ -5423,21 +5525,23 @@
5423
5525
  startPosition.originalY +
5424
5526
  startPosition.originalHeight -
5425
5527
  top;
5426
- }
5427
- function moveBottom() {
5528
+ };
5529
+ const moveBottom = () => {
5428
5530
  top =
5429
5531
  startPosition.originalY -
5430
5532
  startPosition.originalHeight;
5431
- height = clamp(y - top, top < 0
5432
- ? -top + minimumInViewportHeight
5533
+ height = clamp(y - top, top < 0 &&
5534
+ typeof this.options
5535
+ .minimumInViewportHeight === 'number'
5536
+ ? -top +
5537
+ this.options.minimumInViewportHeight
5433
5538
  : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
5434
- }
5435
- function moveLeft() {
5539
+ };
5540
+ const moveLeft = () => {
5436
5541
  left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
5437
5542
  startPosition.originalWidth >
5438
5543
  containerRect.width
5439
- ? containerRect.width -
5440
- minimumInViewportWidth
5544
+ ? this.getMinimumWidth(containerRect.width)
5441
5545
  : Math.max(0, startPosition.originalX +
5442
5546
  startPosition.originalWidth -
5443
5547
  Overlay.MINIMUM_WIDTH));
@@ -5445,15 +5549,18 @@
5445
5549
  startPosition.originalX +
5446
5550
  startPosition.originalWidth -
5447
5551
  left;
5448
- }
5449
- function moveRight() {
5552
+ };
5553
+ const moveRight = () => {
5450
5554
  left =
5451
5555
  startPosition.originalX -
5452
5556
  startPosition.originalWidth;
5453
- width = clamp(x - left, left < 0
5454
- ? -left + minimumInViewportWidth
5557
+ width = clamp(x - left, left < 0 &&
5558
+ typeof this.options
5559
+ .minimumInViewportWidth === 'number'
5560
+ ? -left +
5561
+ this.options.minimumInViewportWidth
5455
5562
  : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
5456
- }
5563
+ };
5457
5564
  switch (direction) {
5458
5565
  case 'top':
5459
5566
  moveTop();
@@ -5497,6 +5604,18 @@
5497
5604
  }));
5498
5605
  }));
5499
5606
  }
5607
+ getMinimumWidth(width) {
5608
+ if (typeof this.options.minimumInViewportWidth === 'number') {
5609
+ return width - this.options.minimumInViewportWidth;
5610
+ }
5611
+ return 0;
5612
+ }
5613
+ getMinimumHeight(height) {
5614
+ if (typeof this.options.minimumInViewportHeight === 'number') {
5615
+ return height - this.options.minimumInViewportHeight;
5616
+ }
5617
+ return height;
5618
+ }
5500
5619
  dispose() {
5501
5620
  this._element.remove();
5502
5621
  super.dispose();
@@ -5517,6 +5636,7 @@
5517
5636
  }
5518
5637
  }
5519
5638
 
5639
+ const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
5520
5640
  class DockviewComponent extends BaseGrid {
5521
5641
  get orientation() {
5522
5642
  return this.gridview.orientation;
@@ -5547,6 +5667,10 @@
5547
5667
  this.nextGroupId = sequentialNumberGenerator();
5548
5668
  this._deserializer = new DefaultDockviewDeserialzier(this);
5549
5669
  this.watermark = null;
5670
+ this._onWillDragPanel = new Emitter();
5671
+ this.onWillDragPanel = this._onWillDragPanel.event;
5672
+ this._onWillDragGroup = new Emitter();
5673
+ this.onWillDragGroup = this._onWillDragGroup.event;
5550
5674
  this._onDidDrop = new Emitter();
5551
5675
  this.onDidDrop = this._onDidDrop.event;
5552
5676
  this._onDidRemovePanel = new Emitter();
@@ -5559,7 +5683,7 @@
5559
5683
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5560
5684
  this.floatingGroups = [];
5561
5685
  toggleClass(this.gridview.element, 'dv-dockview', true);
5562
- this.addDisposables(this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5686
+ this.addDisposables(this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5563
5687
  this.updateWatermark();
5564
5688
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
5565
5689
  this._bufferOnDidLayoutChange.fire();
@@ -5632,7 +5756,7 @@
5632
5756
  this.updateWatermark();
5633
5757
  }
5634
5758
  addFloatingGroup(item, coord, options) {
5635
- var _a, _b;
5759
+ var _a, _b, _c, _d, _e, _f;
5636
5760
  let group;
5637
5761
  if (item instanceof DockviewPanel) {
5638
5762
  group = this.createGroup();
@@ -5660,8 +5784,12 @@
5660
5784
  width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
5661
5785
  left: overlayLeft,
5662
5786
  top: overlayTop,
5663
- minimumInViewportWidth: 100,
5664
- minimumInViewportHeight: 100,
5787
+ minimumInViewportWidth: this.options.floatingGroupBounds === 'boundedWithinViewport'
5788
+ ? undefined
5789
+ : (_d = (_c = this.options.floatingGroupBounds) === null || _c === void 0 ? void 0 : _c.minimumWidthWithinViewport) !== null && _d !== void 0 ? _d : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
5790
+ minimumInViewportHeight: this.options.floatingGroupBounds === 'boundedWithinViewport'
5791
+ ? undefined
5792
+ : (_f = (_e = this.options.floatingGroupBounds) === null || _e === void 0 ? void 0 : _e.minimumHeightWithinViewport) !== null && _f !== void 0 ? _f : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
5665
5793
  });
5666
5794
  const el = group.element.querySelector('.void-container');
5667
5795
  if (!el) {
@@ -5732,12 +5860,37 @@
5732
5860
  }
5733
5861
  }
5734
5862
  updateOptions(options) {
5863
+ var _a, _b;
5735
5864
  const hasOrientationChanged = typeof options.orientation === 'string' &&
5736
5865
  this.gridview.orientation !== options.orientation;
5866
+ const hasFloatingGroupOptionsChanged = options.floatingGroupBounds !== undefined &&
5867
+ options.floatingGroupBounds !== this.options.floatingGroupBounds;
5737
5868
  this._options = Object.assign(Object.assign({}, this.options), options);
5738
5869
  if (hasOrientationChanged) {
5739
5870
  this.gridview.orientation = options.orientation;
5740
5871
  }
5872
+ if (hasFloatingGroupOptionsChanged) {
5873
+ for (const group of this.floatingGroups) {
5874
+ switch (this.options.floatingGroupBounds) {
5875
+ case 'boundedWithinViewport':
5876
+ group.overlay.minimumInViewportHeight = undefined;
5877
+ group.overlay.minimumInViewportWidth = undefined;
5878
+ break;
5879
+ case undefined:
5880
+ group.overlay.minimumInViewportHeight =
5881
+ DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE;
5882
+ group.overlay.minimumInViewportWidth =
5883
+ DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE;
5884
+ break;
5885
+ default:
5886
+ group.overlay.minimumInViewportHeight =
5887
+ (_a = this.options.floatingGroupBounds) === null || _a === void 0 ? void 0 : _a.minimumHeightWithinViewport;
5888
+ group.overlay.minimumInViewportWidth =
5889
+ (_b = this.options.floatingGroupBounds) === null || _b === void 0 ? void 0 : _b.minimumWidthWithinViewport;
5890
+ }
5891
+ group.overlay.setBounds({});
5892
+ }
5893
+ }
5741
5894
  this.layout(this.gridview.width, this.gridview.height, true);
5742
5895
  }
5743
5896
  layout(width, height, forceResize) {
@@ -5830,61 +5983,114 @@
5830
5983
  fromJSON(data) {
5831
5984
  var _a;
5832
5985
  this.clear();
5986
+ if (typeof data !== 'object' || data === null) {
5987
+ throw new Error('serialized layout must be a non-null object');
5988
+ }
5833
5989
  const { grid, panels, activeGroup } = data;
5834
5990
  if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
5835
5991
  throw new Error('root must be of type branch');
5836
5992
  }
5837
- // take note of the existing dimensions
5838
- const width = this.width;
5839
- const height = this.height;
5840
- const createGroupFromSerializedState = (data) => {
5841
- const { id, locked, hideHeader, views, activeView } = data;
5842
- const group = this.createGroup({
5843
- id,
5844
- locked: !!locked,
5845
- hideHeader: !!hideHeader,
5846
- });
5847
- this._onDidAddGroup.fire(group);
5848
- for (const child of views) {
5849
- const panel = this._deserializer.fromJSON(panels[child], group);
5850
- const isActive = typeof activeView === 'string' && activeView === panel.id;
5851
- group.model.openPanel(panel, {
5852
- skipSetPanelActive: !isActive,
5853
- skipSetGroupActive: true,
5993
+ try {
5994
+ // take note of the existing dimensions
5995
+ const width = this.width;
5996
+ const height = this.height;
5997
+ const createGroupFromSerializedState = (data) => {
5998
+ const { id, locked, hideHeader, views, activeView } = data;
5999
+ if (typeof id !== 'string') {
6000
+ throw new Error('group id must be of type string');
6001
+ }
6002
+ const group = this.createGroup({
6003
+ id,
6004
+ locked: !!locked,
6005
+ hideHeader: !!hideHeader,
5854
6006
  });
6007
+ const createdPanels = [];
6008
+ for (const child of views) {
6009
+ /**
6010
+ * Run the deserializer step seperately since this may fail to due corrupted external state.
6011
+ * In running this section first we avoid firing lots of 'add' events in the event of a failure
6012
+ * due to a corruption of input data.
6013
+ */
6014
+ const panel = this._deserializer.fromJSON(panels[child], group);
6015
+ createdPanels.push(panel);
6016
+ }
6017
+ this._onDidAddGroup.fire(group);
6018
+ for (let i = 0; i < views.length; i++) {
6019
+ const panel = createdPanels[i];
6020
+ const isActive = typeof activeView === 'string' &&
6021
+ activeView === panel.id;
6022
+ group.model.openPanel(panel, {
6023
+ skipSetPanelActive: !isActive,
6024
+ skipSetGroupActive: true,
6025
+ });
6026
+ }
6027
+ if (!group.activePanel && group.panels.length > 0) {
6028
+ group.model.openPanel(group.panels[group.panels.length - 1], {
6029
+ skipSetGroupActive: true,
6030
+ });
6031
+ }
6032
+ return group;
6033
+ };
6034
+ this.gridview.deserialize(grid, {
6035
+ fromJSON: (node) => {
6036
+ return createGroupFromSerializedState(node.data);
6037
+ },
6038
+ });
6039
+ this.layout(width, height, true);
6040
+ const serializedFloatingGroups = (_a = data.floatingGroups) !== null && _a !== void 0 ? _a : [];
6041
+ for (const serializedFloatingGroup of serializedFloatingGroups) {
6042
+ const { data, position } = serializedFloatingGroup;
6043
+ const group = createGroupFromSerializedState(data);
6044
+ this.addFloatingGroup(group, {
6045
+ x: position.left,
6046
+ y: position.top,
6047
+ height: position.height,
6048
+ width: position.width,
6049
+ }, { skipRemoveGroup: true, inDragMode: false });
6050
+ }
6051
+ for (const floatingGroup of this.floatingGroups) {
6052
+ floatingGroup.overlay.setBounds();
6053
+ }
6054
+ if (typeof activeGroup === 'string') {
6055
+ const panel = this.getPanel(activeGroup);
6056
+ if (panel) {
6057
+ this.doSetGroupActive(panel);
6058
+ }
5855
6059
  }
5856
- if (!group.activePanel && group.panels.length > 0) {
5857
- group.model.openPanel(group.panels[group.panels.length - 1], {
5858
- skipSetGroupActive: true,
5859
- });
6060
+ }
6061
+ catch (err) {
6062
+ /**
6063
+ * Takes all the successfully created groups and remove all of their panels.
6064
+ */
6065
+ for (const group of this.groups) {
6066
+ for (const panel of group.panels) {
6067
+ this.removePanel(panel, {
6068
+ removeEmptyGroup: false,
6069
+ skipDispose: false,
6070
+ });
6071
+ }
5860
6072
  }
5861
- return group;
5862
- };
5863
- this.gridview.deserialize(grid, {
5864
- fromJSON: (node) => {
5865
- return createGroupFromSerializedState(node.data);
5866
- },
5867
- });
5868
- this.layout(width, height, true);
5869
- const serializedFloatingGroups = (_a = data.floatingGroups) !== null && _a !== void 0 ? _a : [];
5870
- for (const serializedFloatingGroup of serializedFloatingGroups) {
5871
- const { data, position } = serializedFloatingGroup;
5872
- const group = createGroupFromSerializedState(data);
5873
- this.addFloatingGroup(group, {
5874
- x: position.left,
5875
- y: position.top,
5876
- height: position.height,
5877
- width: position.width,
5878
- }, { skipRemoveGroup: true, inDragMode: false });
5879
- }
5880
- for (const floatingGroup of this.floatingGroups) {
5881
- floatingGroup.overlay.setBounds();
5882
- }
5883
- if (typeof activeGroup === 'string') {
5884
- const panel = this.getPanel(activeGroup);
5885
- if (panel) {
5886
- this.doSetGroupActive(panel);
6073
+ /**
6074
+ * To remove a group we cannot call this.removeGroup(...) since this makes assumptions about
6075
+ * the underlying HTMLElement existing in the Gridview.
6076
+ */
6077
+ for (const group of this.groups) {
6078
+ group.dispose();
6079
+ this._groups.delete(group.id);
6080
+ this._onDidRemoveGroup.fire(group);
5887
6081
  }
6082
+ // iterate over a reassigned array since original array will be modified
6083
+ for (const floatingGroup of [...this.floatingGroups]) {
6084
+ floatingGroup.dispose();
6085
+ }
6086
+ // fires clean-up events and clears the underlying HTML gridview.
6087
+ this.clear();
6088
+ /**
6089
+ * even though we have cleaned-up we still want to inform the caller of their error
6090
+ * and we'll do this through re-throwing the original error since afterall you would
6091
+ * expect trying to load a corrupted layout to result in an error and not silently fail...
6092
+ */
6093
+ throw err;
5888
6094
  }
5889
6095
  this._onDidLayoutFromJSON.fire();
5890
6096
  }
@@ -6098,6 +6304,7 @@
6098
6304
  if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6099
6305
  floatingGroup.group.dispose();
6100
6306
  this._groups.delete(group.id);
6307
+ // TODO: fire group removed event?
6101
6308
  }
6102
6309
  floatingGroup.dispose();
6103
6310
  return floatingGroup.group;
@@ -6220,7 +6427,11 @@
6220
6427
  const view = new DockviewGroupPanel(this, id, options);
6221
6428
  view.init({ params: {}, accessor: null }); // required to initialized .part and allow for correct disposal of group
6222
6429
  if (!this._groups.has(view.id)) {
6223
- const disposable = new CompositeDisposable(view.model.onMove((event) => {
6430
+ const disposable = new CompositeDisposable(view.model.onTabDragStart((event) => {
6431
+ this._onWillDragPanel.fire(event);
6432
+ }), view.model.onGroupDragStart((event) => {
6433
+ this._onWillDragGroup.fire(event);
6434
+ }), view.model.onMove((event) => {
6224
6435
  const { groupId, itemId, target, index } = event;
6225
6436
  this.moveGroupOrPanel(view, groupId, itemId, target, index);
6226
6437
  }), view.model.onDidDrop((event) => {
@@ -6259,13 +6470,6 @@
6259
6470
  var _a;
6260
6471
  return (_a = Array.from(this._groups.values()).find((group) => group.value.model.containsPanel(panel))) === null || _a === void 0 ? void 0 : _a.value;
6261
6472
  }
6262
- dispose() {
6263
- this._onDidActivePanelChange.dispose();
6264
- this._onDidAddPanel.dispose();
6265
- this._onDidRemovePanel.dispose();
6266
- this._onDidLayoutFromJSON.dispose();
6267
- super.dispose();
6268
- }
6269
6473
  }
6270
6474
 
6271
6475
  class GridviewComponent extends BaseGrid {
@@ -6341,43 +6545,64 @@
6341
6545
  fromJSON(serializedGridview) {
6342
6546
  this.clear();
6343
6547
  const { grid, activePanel } = serializedGridview;
6344
- const queue = [];
6345
- // take note of the existing dimensions
6346
- const width = this.width;
6347
- const height = this.height;
6348
- this.gridview.deserialize(grid, {
6349
- fromJSON: (node) => {
6350
- const { data } = node;
6351
- const view = createComponent(data.id, data.component, this.options.components || {}, this.options.frameworkComponents || {}, this.options.frameworkComponentFactory
6352
- ? {
6353
- createComponent: this.options.frameworkComponentFactory
6354
- .createComponent,
6355
- }
6356
- : undefined);
6357
- queue.push(() => view.init({
6358
- params: data.params,
6359
- minimumWidth: data.minimumWidth,
6360
- maximumWidth: data.maximumWidth,
6361
- minimumHeight: data.minimumHeight,
6362
- maximumHeight: data.maximumHeight,
6363
- priority: data.priority,
6364
- snap: !!data.snap,
6365
- accessor: this,
6366
- isVisible: node.visible,
6367
- }));
6368
- this._onDidAddGroup.fire(view);
6369
- this.registerPanel(view);
6370
- return view;
6371
- },
6372
- });
6373
- this.layout(width, height, true);
6374
- queue.forEach((f) => f());
6375
- if (typeof activePanel === 'string') {
6376
- const panel = this.getPanel(activePanel);
6377
- if (panel) {
6378
- this.doSetGroupActive(panel);
6548
+ try {
6549
+ const queue = [];
6550
+ // take note of the existing dimensions
6551
+ const width = this.width;
6552
+ const height = this.height;
6553
+ this.gridview.deserialize(grid, {
6554
+ fromJSON: (node) => {
6555
+ const { data } = node;
6556
+ const view = createComponent(data.id, data.component, this.options.components || {}, this.options.frameworkComponents || {}, this.options.frameworkComponentFactory
6557
+ ? {
6558
+ createComponent: this.options.frameworkComponentFactory
6559
+ .createComponent,
6560
+ }
6561
+ : undefined);
6562
+ queue.push(() => view.init({
6563
+ params: data.params,
6564
+ minimumWidth: data.minimumWidth,
6565
+ maximumWidth: data.maximumWidth,
6566
+ minimumHeight: data.minimumHeight,
6567
+ maximumHeight: data.maximumHeight,
6568
+ priority: data.priority,
6569
+ snap: !!data.snap,
6570
+ accessor: this,
6571
+ isVisible: node.visible,
6572
+ }));
6573
+ this._onDidAddGroup.fire(view);
6574
+ this.registerPanel(view);
6575
+ return view;
6576
+ },
6577
+ });
6578
+ this.layout(width, height, true);
6579
+ queue.forEach((f) => f());
6580
+ if (typeof activePanel === 'string') {
6581
+ const panel = this.getPanel(activePanel);
6582
+ if (panel) {
6583
+ this.doSetGroupActive(panel);
6584
+ }
6379
6585
  }
6380
6586
  }
6587
+ catch (err) {
6588
+ /**
6589
+ * To remove a group we cannot call this.removeGroup(...) since this makes assumptions about
6590
+ * the underlying HTMLElement existing in the Gridview.
6591
+ */
6592
+ for (const group of this.groups) {
6593
+ group.dispose();
6594
+ this._groups.delete(group.id);
6595
+ this._onDidRemoveGroup.fire(group);
6596
+ }
6597
+ // fires clean-up events and clears the underlying HTML gridview.
6598
+ this.clear();
6599
+ /**
6600
+ * even though we have cleaned-up we still want to inform the caller of their error
6601
+ * and we'll do this through re-throwing the original error since afterall you would
6602
+ * expect trying to load a corrupted layout to result in an error and not silently fail...
6603
+ */
6604
+ throw err;
6605
+ }
6381
6606
  this._onDidLayoutfromJSON.fire();
6382
6607
  }
6383
6608
  clear() {