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
  */
@@ -244,9 +244,6 @@
244
244
  get isDisposed() {
245
245
  return this._isDisposed;
246
246
  }
247
- static from(...args) {
248
- return new CompositeDisposable(...args);
249
- }
250
247
  constructor(...args) {
251
248
  this._isDisposed = false;
252
249
  this._disposables = args;
@@ -875,7 +872,17 @@
875
872
  size = typeof size === 'number' ? size : item.size;
876
873
  size = clamp(size, item.minimumSize, item.maximumSize);
877
874
  item.size = size;
878
- this.relayout([index]);
875
+ const indexes = range(this.viewItems.length).filter((i) => i !== index);
876
+ const lowPriorityIndexes = [
877
+ ...indexes.filter((i) => this.viewItems[i].priority === exports.LayoutPriority.Low),
878
+ index,
879
+ ];
880
+ const highPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === exports.LayoutPriority.High);
881
+ /**
882
+ * add this view we are changing to the low-index list since we have determined the size
883
+ * here and don't want it changed
884
+ */
885
+ this.relayout([...lowPriorityIndexes, index], highPriorityIndexes);
879
886
  }
880
887
  addView(view, size = { type: 'distribute' }, index = this.viewItems.length, skipLayout) {
881
888
  const container = document.createElement('div');
@@ -1632,6 +1639,7 @@
1632
1639
  orientation: this.orientation,
1633
1640
  descriptor,
1634
1641
  proportionalLayout,
1642
+ styles,
1635
1643
  });
1636
1644
  }
1637
1645
  this.addDisposables(this._onDidChange, this.splitview.onDidSashEnd(() => {
@@ -2143,6 +2151,14 @@
2143
2151
  const child = sibling.children[i];
2144
2152
  grandParent.addChild(child, child.size, parentIndex + i);
2145
2153
  }
2154
+ /**
2155
+ * clean down the branch node since we need to dipose of it and
2156
+ * when .dispose() it called on a branch it will dispose of any
2157
+ * views it is holding onto.
2158
+ */
2159
+ while (sibling.children.length > 0) {
2160
+ sibling.removeChild(0);
2161
+ }
2146
2162
  }
2147
2163
  else {
2148
2164
  // otherwise create a new leaf node and add that to the grandparent
@@ -2450,6 +2466,12 @@
2450
2466
  get onDidDrop() {
2451
2467
  return this.component.onDidDrop;
2452
2468
  }
2469
+ get onWillDragGroup() {
2470
+ return this.component.onWillDragGroup;
2471
+ }
2472
+ get onWillDragPanel() {
2473
+ return this.component.onWillDragPanel;
2474
+ }
2453
2475
  get panels() {
2454
2476
  return this.component.panels;
2455
2477
  }
@@ -2912,7 +2934,7 @@
2912
2934
  }
2913
2935
  configure() {
2914
2936
  this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => {
2915
- if (this.isCancelled(event)) {
2937
+ if (event.defaultPrevented || this.isCancelled(event)) {
2916
2938
  event.preventDefault();
2917
2939
  return;
2918
2940
  }
@@ -2932,19 +2954,23 @@
2932
2954
  }
2933
2955
  this.el.classList.add('dv-dragged');
2934
2956
  setTimeout(() => this.el.classList.remove('dv-dragged'), 0);
2935
- this.dataDisposable.value = this.getData(event.dataTransfer);
2957
+ this.dataDisposable.value = this.getData(event);
2958
+ this._onDragStart.fire(event);
2936
2959
  if (event.dataTransfer) {
2937
2960
  event.dataTransfer.effectAllowed = 'move';
2938
- /**
2939
- * Although this is not used by dockview many third party dnd libraries will check
2940
- * dataTransfer.types to determine valid drag events.
2941
- *
2942
- * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
2943
- * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
2944
- * dnd logic. You can see the code at
2945
- * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
2946
- */
2947
- event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
2961
+ const hasData = event.dataTransfer.items.length > 0;
2962
+ if (!hasData) {
2963
+ /**
2964
+ * Although this is not used by dockview many third party dnd libraries will check
2965
+ * dataTransfer.types to determine valid drag events.
2966
+ *
2967
+ * For example: in react-dnd if dataTransfer.types is not set then the dragStart event will be cancelled
2968
+ * through .preventDefault(). Since this is applied globally to all drag events this would break dockviews
2969
+ * dnd logic. You can see the code at
2970
+ * https://github.com/react-dnd/react-dnd/blob/main/packages/backend-html5/src/HTML5BackendImpl.ts#L542
2971
+ */
2972
+ event.dataTransfer.setData('text/plain', '__dockview_internal_drag_event__');
2973
+ }
2948
2974
  }
2949
2975
  }), addDisposableListener(this.el, 'dragend', () => {
2950
2976
  this.pointerEventsDisposable.dispose();
@@ -2953,44 +2979,45 @@
2953
2979
  }
2954
2980
  }
2955
2981
 
2982
+ class TabDragHandler extends DragHandler {
2983
+ constructor(element, accessor, group, panel) {
2984
+ super(element);
2985
+ this.accessor = accessor;
2986
+ this.group = group;
2987
+ this.panel = panel;
2988
+ this.panelTransfer = LocalSelectionTransfer.getInstance();
2989
+ }
2990
+ getData(event) {
2991
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, this.panel.id)], PanelTransfer.prototype);
2992
+ return {
2993
+ dispose: () => {
2994
+ this.panelTransfer.clearData(PanelTransfer.prototype);
2995
+ },
2996
+ };
2997
+ }
2998
+ }
2956
2999
  class Tab extends CompositeDisposable {
2957
3000
  get element() {
2958
3001
  return this._element;
2959
3002
  }
2960
- constructor(panelId, accessor, group) {
3003
+ constructor(panel, accessor, group) {
2961
3004
  super();
2962
- this.panelId = panelId;
3005
+ this.panel = panel;
2963
3006
  this.accessor = accessor;
2964
3007
  this.group = group;
3008
+ this.content = undefined;
2965
3009
  this._onChanged = new Emitter();
2966
3010
  this.onChanged = this._onChanged.event;
2967
3011
  this._onDropped = new Emitter();
2968
3012
  this.onDrop = this._onDropped.event;
3013
+ this._onDragStart = new Emitter();
3014
+ this.onDragStart = this._onDragStart.event;
2969
3015
  this._element = document.createElement('div');
2970
3016
  this._element.className = 'tab';
2971
3017
  this._element.tabIndex = 0;
2972
3018
  this._element.draggable = true;
2973
3019
  toggleClass(this.element, 'inactive-tab', true);
2974
- this.addDisposables(this._onChanged, this._onDropped, new (class Handler extends DragHandler {
2975
- constructor() {
2976
- super(...arguments);
2977
- this.panelTransfer = LocalSelectionTransfer.getInstance();
2978
- }
2979
- getData() {
2980
- this.panelTransfer.setData([new PanelTransfer(accessor.id, group.id, panelId)], PanelTransfer.prototype);
2981
- return {
2982
- dispose: () => {
2983
- this.panelTransfer.clearData(PanelTransfer.prototype);
2984
- },
2985
- };
2986
- }
2987
- })(this._element));
2988
- this.addDisposables(addDisposableListener(this._element, 'mousedown', (event) => {
2989
- if (event.defaultPrevented) {
2990
- return;
2991
- }
2992
- this._onChanged.fire(event);
2993
- }));
3020
+ const dragHandler = new TabDragHandler(this._element, this.accessor, this.group, this.panel);
2994
3021
  this.droptarget = new Droptarget(this._element, {
2995
3022
  acceptedTargetZones: ['center'],
2996
3023
  canDisplayOverlay: (event, position) => {
@@ -3004,12 +3031,19 @@
3004
3031
  // don't allow group move to drop on self
3005
3032
  return false;
3006
3033
  }
3007
- return this.panelId !== data.panelId;
3034
+ return this.panel.id !== data.panelId;
3008
3035
  }
3009
3036
  return this.group.model.canDisplayOverlay(event, position, exports.DockviewDropTargets.Tab);
3010
3037
  },
3011
3038
  });
3012
- this.addDisposables(this.droptarget.onDrop((event) => {
3039
+ this.addDisposables(this._onChanged, this._onDropped, this._onDragStart, dragHandler.onDragStart((event) => {
3040
+ this._onDragStart.fire(event);
3041
+ }), dragHandler, addDisposableListener(this._element, 'mousedown', (event) => {
3042
+ if (event.defaultPrevented) {
3043
+ return;
3044
+ }
3045
+ this._onChanged.fire(event);
3046
+ }), this.droptarget.onDrop((event) => {
3013
3047
  this._onDropped.fire(event);
3014
3048
  }), this.droptarget);
3015
3049
  }
@@ -3041,9 +3075,9 @@
3041
3075
  }
3042
3076
 
3043
3077
  class GroupDragHandler extends DragHandler {
3044
- constructor(element, accessorId, group) {
3078
+ constructor(element, accessor, group) {
3045
3079
  super(element);
3046
- this.accessorId = accessorId;
3080
+ this.accessor = accessor;
3047
3081
  this.group = group;
3048
3082
  this.panelTransfer = LocalSelectionTransfer.getInstance();
3049
3083
  this.addDisposables(addDisposableListener(element, 'mousedown', (e) => {
@@ -3063,8 +3097,9 @@
3063
3097
  }
3064
3098
  return false;
3065
3099
  }
3066
- getData(dataTransfer) {
3067
- this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype);
3100
+ getData(dragEvent) {
3101
+ const dataTransfer = dragEvent.dataTransfer;
3102
+ this.panelTransfer.setData([new PanelTransfer(this.accessor.id, this.group.id, null)], PanelTransfer.prototype);
3068
3103
  const style = window.getComputedStyle(this.el);
3069
3104
  const bgColor = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-background-color');
3070
3105
  const color = style.getPropertyValue('--dv-activegroup-visiblepanel-tab-color');
@@ -3099,14 +3134,16 @@
3099
3134
  this.group = group;
3100
3135
  this._onDrop = new Emitter();
3101
3136
  this.onDrop = this._onDrop.event;
3137
+ this._onDragStart = new Emitter();
3138
+ this.onDragStart = this._onDragStart.event;
3102
3139
  this._element = document.createElement('div');
3103
3140
  this._element.className = 'void-container';
3104
3141
  this._element.tabIndex = 0;
3105
3142
  this._element.draggable = true;
3106
- this.addDisposables(this._onDrop, addDisposableListener(this._element, 'click', () => {
3143
+ this.addDisposables(this._onDrop, this._onDragStart, addDisposableListener(this._element, 'click', () => {
3107
3144
  this.accessor.doSetGroupActive(this.group);
3108
3145
  }));
3109
- const handler = new GroupDragHandler(this._element, accessor.id, group);
3146
+ const handler = new GroupDragHandler(this._element, accessor, group);
3110
3147
  this.voidDropTarget = new Droptarget(this._element, {
3111
3148
  acceptedTargetZones: ['center'],
3112
3149
  canDisplayOverlay: (event, position) => {
@@ -3124,7 +3161,9 @@
3124
3161
  return group.model.canDisplayOverlay(event, position, exports.DockviewDropTargets.Panel);
3125
3162
  },
3126
3163
  });
3127
- this.addDisposables(handler, this.voidDropTarget.onDrop((event) => {
3164
+ this.addDisposables(handler, handler.onDragStart((event) => {
3165
+ this._onDragStart.fire(event);
3166
+ }), this.voidDropTarget.onDrop((event) => {
3128
3167
  this._onDrop.fire(event);
3129
3168
  }), this.voidDropTarget);
3130
3169
  }
@@ -3132,7 +3171,7 @@
3132
3171
 
3133
3172
  class TabsContainer extends CompositeDisposable {
3134
3173
  get panels() {
3135
- return this.tabs.map((_) => _.value.panelId);
3174
+ return this.tabs.map((_) => _.value.panel.id);
3136
3175
  }
3137
3176
  get size() {
3138
3177
  return this.tabs.length;
@@ -3178,6 +3217,19 @@
3178
3217
  this.leftActions = element;
3179
3218
  }
3180
3219
  }
3220
+ setPrefixActionsElement(element) {
3221
+ if (this.preActions === element) {
3222
+ return;
3223
+ }
3224
+ if (this.preActions) {
3225
+ this.preActions.remove();
3226
+ this.preActions = undefined;
3227
+ }
3228
+ if (element) {
3229
+ this.preActionsContainer.appendChild(element);
3230
+ this.preActions = element;
3231
+ }
3232
+ }
3181
3233
  get element() {
3182
3234
  return this._element;
3183
3235
  }
@@ -3186,7 +3238,7 @@
3186
3238
  this.tabs[this.selectedIndex].value === tab);
3187
3239
  }
3188
3240
  indexOf(id) {
3189
- return this.tabs.findIndex((tab) => tab.value.panelId === id);
3241
+ return this.tabs.findIndex((tab) => tab.value.panel.id === id);
3190
3242
  }
3191
3243
  constructor(accessor, group) {
3192
3244
  super();
@@ -3197,7 +3249,11 @@
3197
3249
  this._hidden = false;
3198
3250
  this._onDrop = new Emitter();
3199
3251
  this.onDrop = this._onDrop.event;
3200
- this.addDisposables(this._onDrop);
3252
+ this._onTabDragStart = new Emitter();
3253
+ this.onTabDragStart = this._onTabDragStart.event;
3254
+ this._onGroupDragStart = new Emitter();
3255
+ this.onGroupDragStart = this._onGroupDragStart.event;
3256
+ this.addDisposables(this._onDrop, this._onTabDragStart, this._onGroupDragStart);
3201
3257
  this._element = document.createElement('div');
3202
3258
  this._element.className = 'tabs-and-actions-container';
3203
3259
  toggleClass(this._element, 'dv-full-width-single-tab', this.accessor.options.singleTabMode === 'fullwidth');
@@ -3214,14 +3270,22 @@
3214
3270
  this.rightActionsContainer.className = 'right-actions-container';
3215
3271
  this.leftActionsContainer = document.createElement('div');
3216
3272
  this.leftActionsContainer.className = 'left-actions-container';
3273
+ this.preActionsContainer = document.createElement('div');
3274
+ this.preActionsContainer.className = 'pre-actions-container';
3217
3275
  this.tabContainer = document.createElement('div');
3218
3276
  this.tabContainer.className = 'tabs-container';
3219
3277
  this.voidContainer = new VoidContainer(this.accessor, this.group);
3278
+ this._element.appendChild(this.preActionsContainer);
3220
3279
  this._element.appendChild(this.tabContainer);
3221
3280
  this._element.appendChild(this.leftActionsContainer);
3222
3281
  this._element.appendChild(this.voidContainer.element);
3223
3282
  this._element.appendChild(this.rightActionsContainer);
3224
- this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => {
3283
+ this.addDisposables(this.voidContainer, this.voidContainer.onDragStart((event) => {
3284
+ this._onGroupDragStart.fire({
3285
+ nativeEvent: event,
3286
+ group: this.group,
3287
+ });
3288
+ }), this.voidContainer.onDrop((event) => {
3225
3289
  this._onDrop.fire({
3226
3290
  event: event.nativeEvent,
3227
3291
  index: this.tabs.length,
@@ -3267,7 +3331,7 @@
3267
3331
  }
3268
3332
  }
3269
3333
  delete(id) {
3270
- const index = this.tabs.findIndex((tab) => tab.value.panelId === id);
3334
+ const index = this.tabs.findIndex((tab) => tab.value.panel.id === id);
3271
3335
  const tabToRemove = this.tabs.splice(index, 1)[0];
3272
3336
  const { value, disposable } = tabToRemove;
3273
3337
  disposable.dispose();
@@ -3276,21 +3340,23 @@
3276
3340
  }
3277
3341
  setActivePanel(panel) {
3278
3342
  this.tabs.forEach((tab) => {
3279
- const isActivePanel = panel.id === tab.value.panelId;
3343
+ const isActivePanel = panel.id === tab.value.panel.id;
3280
3344
  tab.value.setActive(isActivePanel);
3281
3345
  });
3282
3346
  }
3283
3347
  openPanel(panel, index = this.tabs.length) {
3284
3348
  var _a;
3285
- if (this.tabs.find((tab) => tab.value.panelId === panel.id)) {
3349
+ if (this.tabs.find((tab) => tab.value.panel.id === panel.id)) {
3286
3350
  return;
3287
3351
  }
3288
- const tabToAdd = new Tab(panel.id, this.accessor, this.group);
3352
+ const tab = new Tab(panel, this.accessor, this.group);
3289
3353
  if (!((_a = panel.view) === null || _a === void 0 ? void 0 : _a.tab)) {
3290
3354
  throw new Error('invalid header component');
3291
3355
  }
3292
- tabToAdd.setContent(panel.view.tab);
3293
- const disposable = CompositeDisposable.from(tabToAdd.onChanged((event) => {
3356
+ tab.setContent(panel.view.tab);
3357
+ const disposable = new CompositeDisposable(tab.onDragStart((event) => {
3358
+ this._onTabDragStart.fire({ nativeEvent: event, panel });
3359
+ }), tab.onChanged((event) => {
3294
3360
  var _a;
3295
3361
  const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
3296
3362
  const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1;
@@ -3298,8 +3364,8 @@
3298
3364
  !isFloatingWithOnePanel &&
3299
3365
  event.shiftKey) {
3300
3366
  event.preventDefault();
3301
- const panel = this.accessor.getGroupPanel(tabToAdd.panelId);
3302
- const { top, left } = tabToAdd.element.getBoundingClientRect();
3367
+ const panel = this.accessor.getGroupPanel(tab.panel.id);
3368
+ const { top, left } = tab.element.getBoundingClientRect();
3303
3369
  const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
3304
3370
  this.accessor.addFloatingGroup(panel, {
3305
3371
  x: left - rootLeft,
@@ -3316,13 +3382,13 @@
3316
3382
  this.group.model.openPanel(panel, {
3317
3383
  skipFocus: alreadyFocused,
3318
3384
  });
3319
- }), tabToAdd.onDrop((event) => {
3385
+ }), tab.onDrop((event) => {
3320
3386
  this._onDrop.fire({
3321
3387
  event: event.nativeEvent,
3322
- index: this.tabs.findIndex((x) => x.value === tabToAdd),
3388
+ index: this.tabs.findIndex((x) => x.value === tab),
3323
3389
  });
3324
3390
  }));
3325
- const value = { value: tabToAdd, disposable };
3391
+ const value = { value: tab, disposable };
3326
3392
  this.addTab(value, index);
3327
3393
  }
3328
3394
  closePanel(panel) {
@@ -3350,7 +3416,7 @@
3350
3416
  }
3351
3417
  set locked(value) {
3352
3418
  this._locked = value;
3353
- toggleClass(this.container, 'locked-groupview', value);
3419
+ toggleClass(this.container, 'locked-groupview', value === 'no-drop-target' || value);
3354
3420
  }
3355
3421
  get isActive() {
3356
3422
  return this._isGroupActive;
@@ -3407,6 +3473,10 @@
3407
3473
  this.onMove = this._onMove.event;
3408
3474
  this._onDidDrop = new Emitter();
3409
3475
  this.onDidDrop = this._onDidDrop.event;
3476
+ this._onTabDragStart = new Emitter();
3477
+ this.onTabDragStart = this._onTabDragStart.event;
3478
+ this._onGroupDragStart = new Emitter();
3479
+ this.onGroupDragStart = this._onGroupDragStart.event;
3410
3480
  this._onDidAddPanel = new Emitter();
3411
3481
  this.onDidAddPanel = this._onDidAddPanel.event;
3412
3482
  this._onDidRemovePanel = new Emitter();
@@ -3419,7 +3489,8 @@
3419
3489
  this.dropTarget = new Droptarget(this.contentContainer.element, {
3420
3490
  acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'],
3421
3491
  canDisplayOverlay: (event, position) => {
3422
- if (this.locked && position === 'center') {
3492
+ if (this.locked === 'no-drop-target' ||
3493
+ (this.locked && position === 'center')) {
3423
3494
  return false;
3424
3495
  }
3425
3496
  const data = getPanelData();
@@ -3445,8 +3516,12 @@
3445
3516
  });
3446
3517
  container.append(this.tabsContainer.element, this.contentContainer.element);
3447
3518
  this.header.hidden = !!options.hideHeader;
3448
- this.locked = !!options.locked;
3449
- this.addDisposables(this.tabsContainer.onDrop((event) => {
3519
+ this.locked = options.locked || false;
3520
+ this.addDisposables(this._onTabDragStart, this._onGroupDragStart, this.tabsContainer.onTabDragStart((event) => {
3521
+ this._onTabDragStart.fire(event);
3522
+ }), this.tabsContainer.onGroupDragStart((event) => {
3523
+ this._onGroupDragStart.fire(event);
3524
+ }), this.tabsContainer.onDrop((event) => {
3450
3525
  this.handleDropEvent(event.event, 'center', event.index);
3451
3526
  }), this.contentContainer.onDidFocus(() => {
3452
3527
  this.accessor.doSetGroupActive(this.groupPanel, true);
@@ -3490,6 +3565,16 @@
3490
3565
  });
3491
3566
  this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element);
3492
3567
  }
3568
+ if (this.accessor.options.createPrefixHeaderActionsElement) {
3569
+ this._prefixHeaderActions =
3570
+ this.accessor.options.createPrefixHeaderActionsElement(this.groupPanel);
3571
+ this.addDisposables(this._prefixHeaderActions);
3572
+ this._prefixHeaderActions.init({
3573
+ containerApi: new DockviewApi(this.accessor),
3574
+ api: this.groupPanel.api,
3575
+ });
3576
+ this.tabsContainer.setPrefixActionsElement(this._prefixHeaderActions.element);
3577
+ }
3493
3578
  }
3494
3579
  indexOf(panel) {
3495
3580
  return this.tabsContainer.indexOf(panel.id);
@@ -3501,8 +3586,8 @@
3501
3586
  activeView: (_a = this._activePanel) === null || _a === void 0 ? void 0 : _a.id,
3502
3587
  id: this.id,
3503
3588
  };
3504
- if (this.locked) {
3505
- result.locked = true;
3589
+ if (this.locked !== false) {
3590
+ result.locked = this.locked;
3506
3591
  }
3507
3592
  if (this.header.hidden) {
3508
3593
  result.hideHeader = true;
@@ -3752,6 +3837,9 @@
3752
3837
  return false;
3753
3838
  }
3754
3839
  handleDropEvent(event, position, index) {
3840
+ if (this.locked === 'no-drop-target') {
3841
+ return;
3842
+ }
3755
3843
  const data = getPanelData();
3756
3844
  if (data && data.viewId === this.accessor.id) {
3757
3845
  if (data.panelId === null) {
@@ -3829,6 +3917,14 @@
3829
3917
  */
3830
3918
  return;
3831
3919
  }
3920
+ if (!document.body.contains(this._element)) {
3921
+ /**
3922
+ * since the event is dispatched through requestAnimationFrame there is a small chance
3923
+ * the component is no longer attached to the DOM, if that is the case the dimensions
3924
+ * are mostly likely all zero and meaningless. we should skip this case.
3925
+ */
3926
+ return;
3927
+ }
3832
3928
  const { width, height } = entry.contentRect;
3833
3929
  this.layout(width, height);
3834
3930
  }));
@@ -5209,6 +5305,12 @@
5209
5305
  return pushToTop;
5210
5306
  })();
5211
5307
  class Overlay extends CompositeDisposable {
5308
+ set minimumInViewportWidth(value) {
5309
+ this.options.minimumInViewportWidth = value;
5310
+ }
5311
+ set minimumInViewportHeight(value) {
5312
+ this.options.minimumInViewportHeight = value;
5313
+ }
5212
5314
  constructor(options) {
5213
5315
  super();
5214
5316
  this.options = options;
@@ -5254,9 +5356,11 @@
5254
5356
  const overlayRect = this._element.getBoundingClientRect();
5255
5357
  // region: ensure bounds within allowable limits
5256
5358
  // a minimum width of minimumViewportWidth must be inside the viewport
5257
- const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5359
+ const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width));
5258
5360
  // a minimum height of minimumViewportHeight must be inside the viewport
5259
- const yOffset = Math.max(0, overlayRect.height - this.options.minimumInViewportHeight);
5361
+ const yOffset = typeof this.options.minimumInViewportHeight === 'number'
5362
+ ? Math.max(0, this.getMinimumHeight(overlayRect.height))
5363
+ : 0;
5260
5364
  const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5261
5365
  const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5262
5366
  this._element.style.left = `${left}px`;
@@ -5302,9 +5406,10 @@
5302
5406
  y: e.clientY - overlayRect.top,
5303
5407
  };
5304
5408
  }
5305
- const xOffset = Math.max(0, overlayRect.width - this.options.minimumInViewportWidth);
5306
- const yOffset = Math.max(0, overlayRect.height -
5307
- this.options.minimumInViewportHeight);
5409
+ const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width));
5410
+ const yOffset = Math.max(0, this.options.minimumInViewportHeight
5411
+ ? this.getMinimumHeight(overlayRect.height)
5412
+ : 0);
5308
5413
  const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset));
5309
5414
  const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset));
5310
5415
  this.setBounds({ top, left });
@@ -5378,14 +5483,11 @@
5378
5483
  let height = undefined;
5379
5484
  let left = undefined;
5380
5485
  let width = undefined;
5381
- const minimumInViewportHeight = this.options.minimumInViewportHeight;
5382
- const minimumInViewportWidth = this.options.minimumInViewportWidth;
5383
- function moveTop() {
5486
+ const moveTop = () => {
5384
5487
  top = clamp(y, -Number.MAX_VALUE, startPosition.originalY +
5385
5488
  startPosition.originalHeight >
5386
5489
  containerRect.height
5387
- ? containerRect.height -
5388
- minimumInViewportHeight
5490
+ ? this.getMinimumHeight(containerRect.height)
5389
5491
  : Math.max(0, startPosition.originalY +
5390
5492
  startPosition.originalHeight -
5391
5493
  Overlay.MINIMUM_HEIGHT));
@@ -5393,21 +5495,23 @@
5393
5495
  startPosition.originalY +
5394
5496
  startPosition.originalHeight -
5395
5497
  top;
5396
- }
5397
- function moveBottom() {
5498
+ };
5499
+ const moveBottom = () => {
5398
5500
  top =
5399
5501
  startPosition.originalY -
5400
5502
  startPosition.originalHeight;
5401
- height = clamp(y - top, top < 0
5402
- ? -top + minimumInViewportHeight
5503
+ height = clamp(y - top, top < 0 &&
5504
+ typeof this.options
5505
+ .minimumInViewportHeight === 'number'
5506
+ ? -top +
5507
+ this.options.minimumInViewportHeight
5403
5508
  : Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE);
5404
- }
5405
- function moveLeft() {
5509
+ };
5510
+ const moveLeft = () => {
5406
5511
  left = clamp(x, -Number.MAX_VALUE, startPosition.originalX +
5407
5512
  startPosition.originalWidth >
5408
5513
  containerRect.width
5409
- ? containerRect.width -
5410
- minimumInViewportWidth
5514
+ ? this.getMinimumWidth(containerRect.width)
5411
5515
  : Math.max(0, startPosition.originalX +
5412
5516
  startPosition.originalWidth -
5413
5517
  Overlay.MINIMUM_WIDTH));
@@ -5415,15 +5519,18 @@
5415
5519
  startPosition.originalX +
5416
5520
  startPosition.originalWidth -
5417
5521
  left;
5418
- }
5419
- function moveRight() {
5522
+ };
5523
+ const moveRight = () => {
5420
5524
  left =
5421
5525
  startPosition.originalX -
5422
5526
  startPosition.originalWidth;
5423
- width = clamp(x - left, left < 0
5424
- ? -left + minimumInViewportWidth
5527
+ width = clamp(x - left, left < 0 &&
5528
+ typeof this.options
5529
+ .minimumInViewportWidth === 'number'
5530
+ ? -left +
5531
+ this.options.minimumInViewportWidth
5425
5532
  : Overlay.MINIMUM_WIDTH, Number.MAX_VALUE);
5426
- }
5533
+ };
5427
5534
  switch (direction) {
5428
5535
  case 'top':
5429
5536
  moveTop();
@@ -5467,6 +5574,18 @@
5467
5574
  }));
5468
5575
  }));
5469
5576
  }
5577
+ getMinimumWidth(width) {
5578
+ if (typeof this.options.minimumInViewportWidth === 'number') {
5579
+ return width - this.options.minimumInViewportWidth;
5580
+ }
5581
+ return 0;
5582
+ }
5583
+ getMinimumHeight(height) {
5584
+ if (typeof this.options.minimumInViewportHeight === 'number') {
5585
+ return height - this.options.minimumInViewportHeight;
5586
+ }
5587
+ return height;
5588
+ }
5470
5589
  dispose() {
5471
5590
  this._element.remove();
5472
5591
  super.dispose();
@@ -5487,6 +5606,7 @@
5487
5606
  }
5488
5607
  }
5489
5608
 
5609
+ const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100;
5490
5610
  class DockviewComponent extends BaseGrid {
5491
5611
  get orientation() {
5492
5612
  return this.gridview.orientation;
@@ -5517,6 +5637,10 @@
5517
5637
  this.nextGroupId = sequentialNumberGenerator();
5518
5638
  this._deserializer = new DefaultDockviewDeserialzier(this);
5519
5639
  this.watermark = null;
5640
+ this._onWillDragPanel = new Emitter();
5641
+ this.onWillDragPanel = this._onWillDragPanel.event;
5642
+ this._onWillDragGroup = new Emitter();
5643
+ this.onWillDragGroup = this._onWillDragGroup.event;
5520
5644
  this._onDidDrop = new Emitter();
5521
5645
  this.onDidDrop = this._onDidDrop.event;
5522
5646
  this._onDidRemovePanel = new Emitter();
@@ -5529,7 +5653,7 @@
5529
5653
  this.onDidActivePanelChange = this._onDidActivePanelChange.event;
5530
5654
  this.floatingGroups = [];
5531
5655
  toggleClass(this.gridview.element, 'dv-dockview', true);
5532
- this.addDisposables(this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5656
+ this.addDisposables(this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, exports.DockviewEvent.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => {
5533
5657
  this.updateWatermark();
5534
5658
  }), exports.DockviewEvent.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => {
5535
5659
  this._bufferOnDidLayoutChange.fire();
@@ -5602,7 +5726,7 @@
5602
5726
  this.updateWatermark();
5603
5727
  }
5604
5728
  addFloatingGroup(item, coord, options) {
5605
- var _a, _b;
5729
+ var _a, _b, _c, _d, _e, _f;
5606
5730
  let group;
5607
5731
  if (item instanceof DockviewPanel) {
5608
5732
  group = this.createGroup();
@@ -5630,8 +5754,12 @@
5630
5754
  width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300,
5631
5755
  left: overlayLeft,
5632
5756
  top: overlayTop,
5633
- minimumInViewportWidth: 100,
5634
- minimumInViewportHeight: 100,
5757
+ minimumInViewportWidth: this.options.floatingGroupBounds === 'boundedWithinViewport'
5758
+ ? undefined
5759
+ : (_d = (_c = this.options.floatingGroupBounds) === null || _c === void 0 ? void 0 : _c.minimumWidthWithinViewport) !== null && _d !== void 0 ? _d : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
5760
+ minimumInViewportHeight: this.options.floatingGroupBounds === 'boundedWithinViewport'
5761
+ ? undefined
5762
+ : (_f = (_e = this.options.floatingGroupBounds) === null || _e === void 0 ? void 0 : _e.minimumHeightWithinViewport) !== null && _f !== void 0 ? _f : DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
5635
5763
  });
5636
5764
  const el = group.element.querySelector('.void-container');
5637
5765
  if (!el) {
@@ -5702,12 +5830,37 @@
5702
5830
  }
5703
5831
  }
5704
5832
  updateOptions(options) {
5833
+ var _a, _b;
5705
5834
  const hasOrientationChanged = typeof options.orientation === 'string' &&
5706
5835
  this.gridview.orientation !== options.orientation;
5836
+ const hasFloatingGroupOptionsChanged = options.floatingGroupBounds !== undefined &&
5837
+ options.floatingGroupBounds !== this.options.floatingGroupBounds;
5707
5838
  this._options = Object.assign(Object.assign({}, this.options), options);
5708
5839
  if (hasOrientationChanged) {
5709
5840
  this.gridview.orientation = options.orientation;
5710
5841
  }
5842
+ if (hasFloatingGroupOptionsChanged) {
5843
+ for (const group of this.floatingGroups) {
5844
+ switch (this.options.floatingGroupBounds) {
5845
+ case 'boundedWithinViewport':
5846
+ group.overlay.minimumInViewportHeight = undefined;
5847
+ group.overlay.minimumInViewportWidth = undefined;
5848
+ break;
5849
+ case undefined:
5850
+ group.overlay.minimumInViewportHeight =
5851
+ DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE;
5852
+ group.overlay.minimumInViewportWidth =
5853
+ DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE;
5854
+ break;
5855
+ default:
5856
+ group.overlay.minimumInViewportHeight =
5857
+ (_a = this.options.floatingGroupBounds) === null || _a === void 0 ? void 0 : _a.minimumHeightWithinViewport;
5858
+ group.overlay.minimumInViewportWidth =
5859
+ (_b = this.options.floatingGroupBounds) === null || _b === void 0 ? void 0 : _b.minimumWidthWithinViewport;
5860
+ }
5861
+ group.overlay.setBounds({});
5862
+ }
5863
+ }
5711
5864
  this.layout(this.gridview.width, this.gridview.height, true);
5712
5865
  }
5713
5866
  layout(width, height, forceResize) {
@@ -5800,61 +5953,114 @@
5800
5953
  fromJSON(data) {
5801
5954
  var _a;
5802
5955
  this.clear();
5956
+ if (typeof data !== 'object' || data === null) {
5957
+ throw new Error('serialized layout must be a non-null object');
5958
+ }
5803
5959
  const { grid, panels, activeGroup } = data;
5804
5960
  if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
5805
5961
  throw new Error('root must be of type branch');
5806
5962
  }
5807
- // take note of the existing dimensions
5808
- const width = this.width;
5809
- const height = this.height;
5810
- const createGroupFromSerializedState = (data) => {
5811
- const { id, locked, hideHeader, views, activeView } = data;
5812
- const group = this.createGroup({
5813
- id,
5814
- locked: !!locked,
5815
- hideHeader: !!hideHeader,
5816
- });
5817
- this._onDidAddGroup.fire(group);
5818
- for (const child of views) {
5819
- const panel = this._deserializer.fromJSON(panels[child], group);
5820
- const isActive = typeof activeView === 'string' && activeView === panel.id;
5821
- group.model.openPanel(panel, {
5822
- skipSetPanelActive: !isActive,
5823
- skipSetGroupActive: true,
5963
+ try {
5964
+ // take note of the existing dimensions
5965
+ const width = this.width;
5966
+ const height = this.height;
5967
+ const createGroupFromSerializedState = (data) => {
5968
+ const { id, locked, hideHeader, views, activeView } = data;
5969
+ if (typeof id !== 'string') {
5970
+ throw new Error('group id must be of type string');
5971
+ }
5972
+ const group = this.createGroup({
5973
+ id,
5974
+ locked: !!locked,
5975
+ hideHeader: !!hideHeader,
5824
5976
  });
5977
+ const createdPanels = [];
5978
+ for (const child of views) {
5979
+ /**
5980
+ * Run the deserializer step seperately since this may fail to due corrupted external state.
5981
+ * In running this section first we avoid firing lots of 'add' events in the event of a failure
5982
+ * due to a corruption of input data.
5983
+ */
5984
+ const panel = this._deserializer.fromJSON(panels[child], group);
5985
+ createdPanels.push(panel);
5986
+ }
5987
+ this._onDidAddGroup.fire(group);
5988
+ for (let i = 0; i < views.length; i++) {
5989
+ const panel = createdPanels[i];
5990
+ const isActive = typeof activeView === 'string' &&
5991
+ activeView === panel.id;
5992
+ group.model.openPanel(panel, {
5993
+ skipSetPanelActive: !isActive,
5994
+ skipSetGroupActive: true,
5995
+ });
5996
+ }
5997
+ if (!group.activePanel && group.panels.length > 0) {
5998
+ group.model.openPanel(group.panels[group.panels.length - 1], {
5999
+ skipSetGroupActive: true,
6000
+ });
6001
+ }
6002
+ return group;
6003
+ };
6004
+ this.gridview.deserialize(grid, {
6005
+ fromJSON: (node) => {
6006
+ return createGroupFromSerializedState(node.data);
6007
+ },
6008
+ });
6009
+ this.layout(width, height, true);
6010
+ const serializedFloatingGroups = (_a = data.floatingGroups) !== null && _a !== void 0 ? _a : [];
6011
+ for (const serializedFloatingGroup of serializedFloatingGroups) {
6012
+ const { data, position } = serializedFloatingGroup;
6013
+ const group = createGroupFromSerializedState(data);
6014
+ this.addFloatingGroup(group, {
6015
+ x: position.left,
6016
+ y: position.top,
6017
+ height: position.height,
6018
+ width: position.width,
6019
+ }, { skipRemoveGroup: true, inDragMode: false });
6020
+ }
6021
+ for (const floatingGroup of this.floatingGroups) {
6022
+ floatingGroup.overlay.setBounds();
6023
+ }
6024
+ if (typeof activeGroup === 'string') {
6025
+ const panel = this.getPanel(activeGroup);
6026
+ if (panel) {
6027
+ this.doSetGroupActive(panel);
6028
+ }
5825
6029
  }
5826
- if (!group.activePanel && group.panels.length > 0) {
5827
- group.model.openPanel(group.panels[group.panels.length - 1], {
5828
- skipSetGroupActive: true,
5829
- });
6030
+ }
6031
+ catch (err) {
6032
+ /**
6033
+ * Takes all the successfully created groups and remove all of their panels.
6034
+ */
6035
+ for (const group of this.groups) {
6036
+ for (const panel of group.panels) {
6037
+ this.removePanel(panel, {
6038
+ removeEmptyGroup: false,
6039
+ skipDispose: false,
6040
+ });
6041
+ }
5830
6042
  }
5831
- return group;
5832
- };
5833
- this.gridview.deserialize(grid, {
5834
- fromJSON: (node) => {
5835
- return createGroupFromSerializedState(node.data);
5836
- },
5837
- });
5838
- this.layout(width, height, true);
5839
- const serializedFloatingGroups = (_a = data.floatingGroups) !== null && _a !== void 0 ? _a : [];
5840
- for (const serializedFloatingGroup of serializedFloatingGroups) {
5841
- const { data, position } = serializedFloatingGroup;
5842
- const group = createGroupFromSerializedState(data);
5843
- this.addFloatingGroup(group, {
5844
- x: position.left,
5845
- y: position.top,
5846
- height: position.height,
5847
- width: position.width,
5848
- }, { skipRemoveGroup: true, inDragMode: false });
5849
- }
5850
- for (const floatingGroup of this.floatingGroups) {
5851
- floatingGroup.overlay.setBounds();
5852
- }
5853
- if (typeof activeGroup === 'string') {
5854
- const panel = this.getPanel(activeGroup);
5855
- if (panel) {
5856
- this.doSetGroupActive(panel);
6043
+ /**
6044
+ * To remove a group we cannot call this.removeGroup(...) since this makes assumptions about
6045
+ * the underlying HTMLElement existing in the Gridview.
6046
+ */
6047
+ for (const group of this.groups) {
6048
+ group.dispose();
6049
+ this._groups.delete(group.id);
6050
+ this._onDidRemoveGroup.fire(group);
5857
6051
  }
6052
+ // iterate over a reassigned array since original array will be modified
6053
+ for (const floatingGroup of [...this.floatingGroups]) {
6054
+ floatingGroup.dispose();
6055
+ }
6056
+ // fires clean-up events and clears the underlying HTML gridview.
6057
+ this.clear();
6058
+ /**
6059
+ * even though we have cleaned-up we still want to inform the caller of their error
6060
+ * and we'll do this through re-throwing the original error since afterall you would
6061
+ * expect trying to load a corrupted layout to result in an error and not silently fail...
6062
+ */
6063
+ throw err;
5858
6064
  }
5859
6065
  this._onDidLayoutFromJSON.fire();
5860
6066
  }
@@ -6068,6 +6274,7 @@
6068
6274
  if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) {
6069
6275
  floatingGroup.group.dispose();
6070
6276
  this._groups.delete(group.id);
6277
+ // TODO: fire group removed event?
6071
6278
  }
6072
6279
  floatingGroup.dispose();
6073
6280
  return floatingGroup.group;
@@ -6190,7 +6397,11 @@
6190
6397
  const view = new DockviewGroupPanel(this, id, options);
6191
6398
  view.init({ params: {}, accessor: null }); // required to initialized .part and allow for correct disposal of group
6192
6399
  if (!this._groups.has(view.id)) {
6193
- const disposable = new CompositeDisposable(view.model.onMove((event) => {
6400
+ const disposable = new CompositeDisposable(view.model.onTabDragStart((event) => {
6401
+ this._onWillDragPanel.fire(event);
6402
+ }), view.model.onGroupDragStart((event) => {
6403
+ this._onWillDragGroup.fire(event);
6404
+ }), view.model.onMove((event) => {
6194
6405
  const { groupId, itemId, target, index } = event;
6195
6406
  this.moveGroupOrPanel(view, groupId, itemId, target, index);
6196
6407
  }), view.model.onDidDrop((event) => {
@@ -6229,13 +6440,6 @@
6229
6440
  var _a;
6230
6441
  return (_a = Array.from(this._groups.values()).find((group) => group.value.model.containsPanel(panel))) === null || _a === void 0 ? void 0 : _a.value;
6231
6442
  }
6232
- dispose() {
6233
- this._onDidActivePanelChange.dispose();
6234
- this._onDidAddPanel.dispose();
6235
- this._onDidRemovePanel.dispose();
6236
- this._onDidLayoutFromJSON.dispose();
6237
- super.dispose();
6238
- }
6239
6443
  }
6240
6444
 
6241
6445
  class GridviewComponent extends BaseGrid {
@@ -6311,43 +6515,64 @@
6311
6515
  fromJSON(serializedGridview) {
6312
6516
  this.clear();
6313
6517
  const { grid, activePanel } = serializedGridview;
6314
- const queue = [];
6315
- // take note of the existing dimensions
6316
- const width = this.width;
6317
- const height = this.height;
6318
- this.gridview.deserialize(grid, {
6319
- fromJSON: (node) => {
6320
- const { data } = node;
6321
- const view = createComponent(data.id, data.component, this.options.components || {}, this.options.frameworkComponents || {}, this.options.frameworkComponentFactory
6322
- ? {
6323
- createComponent: this.options.frameworkComponentFactory
6324
- .createComponent,
6325
- }
6326
- : undefined);
6327
- queue.push(() => view.init({
6328
- params: data.params,
6329
- minimumWidth: data.minimumWidth,
6330
- maximumWidth: data.maximumWidth,
6331
- minimumHeight: data.minimumHeight,
6332
- maximumHeight: data.maximumHeight,
6333
- priority: data.priority,
6334
- snap: !!data.snap,
6335
- accessor: this,
6336
- isVisible: node.visible,
6337
- }));
6338
- this._onDidAddGroup.fire(view);
6339
- this.registerPanel(view);
6340
- return view;
6341
- },
6342
- });
6343
- this.layout(width, height, true);
6344
- queue.forEach((f) => f());
6345
- if (typeof activePanel === 'string') {
6346
- const panel = this.getPanel(activePanel);
6347
- if (panel) {
6348
- this.doSetGroupActive(panel);
6518
+ try {
6519
+ const queue = [];
6520
+ // take note of the existing dimensions
6521
+ const width = this.width;
6522
+ const height = this.height;
6523
+ this.gridview.deserialize(grid, {
6524
+ fromJSON: (node) => {
6525
+ const { data } = node;
6526
+ const view = createComponent(data.id, data.component, this.options.components || {}, this.options.frameworkComponents || {}, this.options.frameworkComponentFactory
6527
+ ? {
6528
+ createComponent: this.options.frameworkComponentFactory
6529
+ .createComponent,
6530
+ }
6531
+ : undefined);
6532
+ queue.push(() => view.init({
6533
+ params: data.params,
6534
+ minimumWidth: data.minimumWidth,
6535
+ maximumWidth: data.maximumWidth,
6536
+ minimumHeight: data.minimumHeight,
6537
+ maximumHeight: data.maximumHeight,
6538
+ priority: data.priority,
6539
+ snap: !!data.snap,
6540
+ accessor: this,
6541
+ isVisible: node.visible,
6542
+ }));
6543
+ this._onDidAddGroup.fire(view);
6544
+ this.registerPanel(view);
6545
+ return view;
6546
+ },
6547
+ });
6548
+ this.layout(width, height, true);
6549
+ queue.forEach((f) => f());
6550
+ if (typeof activePanel === 'string') {
6551
+ const panel = this.getPanel(activePanel);
6552
+ if (panel) {
6553
+ this.doSetGroupActive(panel);
6554
+ }
6349
6555
  }
6350
6556
  }
6557
+ catch (err) {
6558
+ /**
6559
+ * To remove a group we cannot call this.removeGroup(...) since this makes assumptions about
6560
+ * the underlying HTMLElement existing in the Gridview.
6561
+ */
6562
+ for (const group of this.groups) {
6563
+ group.dispose();
6564
+ this._groups.delete(group.id);
6565
+ this._onDidRemoveGroup.fire(group);
6566
+ }
6567
+ // fires clean-up events and clears the underlying HTML gridview.
6568
+ this.clear();
6569
+ /**
6570
+ * even though we have cleaned-up we still want to inform the caller of their error
6571
+ * and we'll do this through re-throwing the original error since afterall you would
6572
+ * expect trying to load a corrupted layout to result in an error and not silently fail...
6573
+ */
6574
+ throw err;
6575
+ }
6351
6576
  this._onDidLayoutfromJSON.fire();
6352
6577
  }
6353
6578
  clear() {