dockview-core 6.3.0 → 6.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +1 -0
  2. package/dist/cjs/dnd/backend.d.ts +70 -0
  3. package/dist/cjs/dnd/backend.js +171 -0
  4. package/dist/cjs/dnd/dropOverlay.d.ts +20 -0
  5. package/dist/cjs/dnd/dropOverlay.js +197 -0
  6. package/dist/cjs/dnd/droptarget.d.ts +20 -6
  7. package/dist/cjs/dnd/droptarget.js +14 -208
  8. package/dist/cjs/dnd/pointer/index.d.ts +11 -0
  9. package/dist/cjs/dnd/pointer/index.js +13 -0
  10. package/dist/cjs/dnd/pointer/longPress.d.ts +32 -0
  11. package/dist/cjs/dnd/pointer/longPress.js +151 -0
  12. package/dist/cjs/dnd/pointer/pointerDragController.d.ts +60 -0
  13. package/dist/cjs/dnd/pointer/pointerDragController.js +241 -0
  14. package/dist/cjs/dnd/pointer/pointerDragSource.d.ts +61 -0
  15. package/dist/cjs/dnd/pointer/pointerDragSource.js +195 -0
  16. package/dist/cjs/dnd/pointer/pointerDropTarget.d.ts +39 -0
  17. package/dist/cjs/dnd/pointer/pointerDropTarget.js +198 -0
  18. package/dist/cjs/dnd/pointer/pointerGhost.d.ts +30 -0
  19. package/dist/cjs/dnd/pointer/pointerGhost.js +44 -0
  20. package/dist/cjs/dnd/pointer/types.d.ts +16 -0
  21. package/dist/cjs/dnd/pointer/types.js +2 -0
  22. package/dist/cjs/dockview/components/panel/content.d.ts +3 -1
  23. package/dist/cjs/dockview/components/panel/content.js +33 -16
  24. package/dist/cjs/dockview/components/popupService.js +34 -0
  25. package/dist/cjs/dockview/components/tab/tab.d.ts +11 -3
  26. package/dist/cjs/dockview/components/tab/tab.js +151 -117
  27. package/dist/cjs/dockview/components/titlebar/tabGroupChip.d.ts +9 -2
  28. package/dist/cjs/dockview/components/titlebar/tabGroupChip.js +15 -6
  29. package/dist/cjs/dockview/components/titlebar/tabGroups.d.ts +33 -5
  30. package/dist/cjs/dockview/components/titlebar/tabGroups.js +231 -40
  31. package/dist/cjs/dockview/components/titlebar/tabs.d.ts +38 -1
  32. package/dist/cjs/dockview/components/titlebar/tabs.js +372 -251
  33. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +5 -3
  34. package/dist/cjs/dockview/components/titlebar/voidContainer.d.ts +6 -2
  35. package/dist/cjs/dockview/components/titlebar/voidContainer.js +189 -27
  36. package/dist/cjs/dockview/contextMenu.js +19 -4
  37. package/dist/cjs/dockview/dndCapabilities.d.ts +19 -0
  38. package/dist/cjs/dockview/dndCapabilities.js +39 -0
  39. package/dist/cjs/dockview/dockviewComponent.d.ts +1 -0
  40. package/dist/cjs/dockview/dockviewComponent.js +54 -33
  41. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +9 -5
  42. package/dist/cjs/dockview/dockviewGroupPanelModel.js +25 -11
  43. package/dist/cjs/dockview/events.d.ts +2 -1
  44. package/dist/cjs/dockview/events.js +1 -0
  45. package/dist/cjs/dockview/options.d.ts +18 -3
  46. package/dist/cjs/dockview/options.js +1 -0
  47. package/dist/cjs/dom.js +7 -3
  48. package/dist/cjs/overlay/overlay.d.ts +12 -0
  49. package/dist/cjs/overlay/overlay.js +84 -16
  50. package/dist/cjs/paneview/draggablePaneviewPanel.d.ts +3 -1
  51. package/dist/cjs/paneview/draggablePaneviewPanel.js +27 -26
  52. package/dist/cjs/paneview/options.d.ts +4 -3
  53. package/dist/dockview-core.js +2199 -834
  54. package/dist/dockview-core.min.js +2 -2
  55. package/dist/dockview-core.min.js.map +1 -1
  56. package/dist/dockview-core.min.noStyle.js +2 -2
  57. package/dist/dockview-core.min.noStyle.js.map +1 -1
  58. package/dist/dockview-core.noStyle.js +2202 -837
  59. package/dist/esm/dnd/backend.d.ts +70 -0
  60. package/dist/esm/dnd/backend.js +148 -0
  61. package/dist/esm/dnd/dropOverlay.d.ts +20 -0
  62. package/dist/esm/dnd/dropOverlay.js +192 -0
  63. package/dist/esm/dnd/droptarget.d.ts +20 -6
  64. package/dist/esm/dnd/droptarget.js +16 -210
  65. package/dist/esm/dnd/pointer/index.d.ts +11 -0
  66. package/dist/esm/dnd/pointer/index.js +5 -0
  67. package/dist/esm/dnd/pointer/longPress.d.ts +32 -0
  68. package/dist/esm/dnd/pointer/longPress.js +127 -0
  69. package/dist/esm/dnd/pointer/pointerDragController.d.ts +60 -0
  70. package/dist/esm/dnd/pointer/pointerDragController.js +191 -0
  71. package/dist/esm/dnd/pointer/pointerDragSource.d.ts +61 -0
  72. package/dist/esm/dnd/pointer/pointerDragSource.js +171 -0
  73. package/dist/esm/dnd/pointer/pointerDropTarget.d.ts +39 -0
  74. package/dist/esm/dnd/pointer/pointerDropTarget.js +168 -0
  75. package/dist/esm/dnd/pointer/pointerGhost.d.ts +30 -0
  76. package/dist/esm/dnd/pointer/pointerGhost.js +39 -0
  77. package/dist/esm/dnd/pointer/types.d.ts +16 -0
  78. package/dist/esm/dnd/pointer/types.js +1 -0
  79. package/dist/esm/dockview/components/panel/content.d.ts +3 -1
  80. package/dist/esm/dockview/components/panel/content.js +33 -16
  81. package/dist/esm/dockview/components/popupService.js +34 -0
  82. package/dist/esm/dockview/components/tab/tab.d.ts +11 -3
  83. package/dist/esm/dockview/components/tab/tab.js +139 -114
  84. package/dist/esm/dockview/components/titlebar/tabGroupChip.d.ts +9 -2
  85. package/dist/esm/dockview/components/titlebar/tabGroupChip.js +15 -6
  86. package/dist/esm/dockview/components/titlebar/tabGroups.d.ts +33 -5
  87. package/dist/esm/dockview/components/titlebar/tabGroups.js +177 -12
  88. package/dist/esm/dockview/components/titlebar/tabs.d.ts +38 -1
  89. package/dist/esm/dockview/components/titlebar/tabs.js +348 -227
  90. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +5 -3
  91. package/dist/esm/dockview/components/titlebar/voidContainer.d.ts +6 -2
  92. package/dist/esm/dockview/components/titlebar/voidContainer.js +179 -31
  93. package/dist/esm/dockview/contextMenu.js +19 -4
  94. package/dist/esm/dockview/dndCapabilities.d.ts +19 -0
  95. package/dist/esm/dockview/dndCapabilities.js +36 -0
  96. package/dist/esm/dockview/dockviewComponent.d.ts +1 -0
  97. package/dist/esm/dockview/dockviewComponent.js +55 -34
  98. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +9 -5
  99. package/dist/esm/dockview/dockviewGroupPanelModel.js +24 -11
  100. package/dist/esm/dockview/events.d.ts +2 -1
  101. package/dist/esm/dockview/events.js +1 -0
  102. package/dist/esm/dockview/options.d.ts +18 -3
  103. package/dist/esm/dockview/options.js +1 -0
  104. package/dist/esm/dom.js +7 -3
  105. package/dist/esm/overlay/overlay.d.ts +12 -0
  106. package/dist/esm/overlay/overlay.js +85 -17
  107. package/dist/esm/paneview/draggablePaneviewPanel.d.ts +3 -1
  108. package/dist/esm/paneview/draggablePaneviewPanel.js +26 -20
  109. package/dist/esm/paneview/options.d.ts +4 -3
  110. package/dist/package/main.cjs.js +2202 -837
  111. package/dist/package/main.cjs.min.js +2 -2
  112. package/dist/package/main.esm.min.mjs +2 -2
  113. package/dist/package/main.esm.mjs +2202 -837
  114. package/dist/styles/dockview.css +117 -1
  115. package/package.json +3 -1
  116. package/dist/cjs/dnd/abstractDragHandler.d.ts +0 -14
  117. package/dist/cjs/dnd/abstractDragHandler.js +0 -86
  118. package/dist/cjs/dnd/groupDragHandler.d.ts +0 -12
  119. package/dist/cjs/dnd/groupDragHandler.js +0 -104
  120. package/dist/esm/dnd/abstractDragHandler.d.ts +0 -14
  121. package/dist/esm/dnd/abstractDragHandler.js +0 -63
  122. package/dist/esm/dnd/groupDragHandler.d.ts +0 -12
  123. package/dist/esm/dnd/groupDragHandler.js +0 -81
@@ -9,6 +9,10 @@ import { TabsContainer, } from './components/titlebar/tabsContainer';
9
9
  import { DockviewUnhandledDragOverEvent, } from './options';
10
10
  import { TabGroup, } from './tabGroup';
11
11
  export class DockviewDidDropEvent extends DockviewEvent {
12
+ /**
13
+ * `PointerEvent` for touch drags has no `dataTransfer`; use
14
+ * `getData()` for the dockview payload regardless of input method.
15
+ */
12
16
  get nativeEvent() {
13
17
  return this.options.nativeEvent;
14
18
  }
@@ -113,29 +117,28 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
113
117
  toggleClass(this.container, 'dv-groupview-floating', false);
114
118
  toggleClass(this.container, 'dv-groupview-popout', false);
115
119
  toggleClass(this.container, 'dv-groupview-edge', false);
120
+ // Mouse and touch drop targets must agree on accepted zones.
121
+ const applyZones = (zones) => {
122
+ this.contentContainer.dropTarget.setTargetZones(zones);
123
+ this.contentContainer.pointerDropTarget.setTargetZones(zones);
124
+ };
116
125
  switch (value.type) {
117
126
  case 'grid':
118
- this.contentContainer.dropTarget.setTargetZones([
119
- 'top',
120
- 'bottom',
121
- 'left',
122
- 'right',
123
- 'center',
124
- ]);
127
+ applyZones(['top', 'bottom', 'left', 'right', 'center']);
125
128
  break;
126
129
  case 'floating':
127
- this.contentContainer.dropTarget.setTargetZones(['center']);
128
- this.contentContainer.dropTarget.setTargetZones(value
130
+ applyZones(['center']);
131
+ applyZones(value
129
132
  ? ['center']
130
133
  : ['top', 'bottom', 'left', 'right', 'center']);
131
134
  toggleClass(this.container, 'dv-groupview-floating', true);
132
135
  break;
133
136
  case 'popout':
134
- this.contentContainer.dropTarget.setTargetZones(['center']);
137
+ applyZones(['center']);
135
138
  toggleClass(this.container, 'dv-groupview-popout', true);
136
139
  break;
137
140
  case 'edge':
138
- this.contentContainer.dropTarget.setTargetZones(['center']);
141
+ applyZones(['center']);
139
142
  toggleClass(this.container, 'dv-groupview-edge', true);
140
143
  break;
141
144
  }
@@ -261,6 +264,8 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
261
264
  // noop
262
265
  }), this.contentContainer.dropTarget.onDrop((event) => {
263
266
  this.handleDropEvent('content', event.nativeEvent, event.position);
267
+ }), this.contentContainer.pointerDropTarget.onDrop((event) => {
268
+ this.handleDropEvent('content', event.nativeEvent, event.position);
264
269
  }), this.tabsContainer.onWillShowOverlay((event) => {
265
270
  this._onWillShowOverlay.fire(event);
266
271
  }), this.contentContainer.dropTarget.onWillShowOverlay((event) => {
@@ -271,6 +276,14 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
271
276
  group: this.groupPanel,
272
277
  getData: getPanelData,
273
278
  }));
279
+ }), this.contentContainer.pointerDropTarget.onWillShowOverlay((event) => {
280
+ this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
281
+ kind: 'content',
282
+ panel: this.activePanel,
283
+ api: this._api,
284
+ group: this.groupPanel,
285
+ getData: getPanelData,
286
+ }));
274
287
  }), this._onMove, this._onDidChange, this._onDidDrop, this._onWillDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange, this._onUnhandledDragOverEvent, this._onDidPanelTitleChange, this._onDidPanelParametersChange, this._onDidCreateTabGroup, this._onDidDestroyTabGroup, this._onDidAddPanelToTabGroup, this._onDidRemovePanelFromTabGroup, this._onDidTabGroupChange, this._onDidTabGroupCollapsedChange, this._onDidCreateTabGroup.event(() => {
275
288
  this._scheduleTabGroupUpdate();
276
289
  }), this._onDidDestroyTabGroup.event(() => {
@@ -25,7 +25,8 @@ export declare class DockviewWillShowOverlayLocationEvent implements IDockviewEv
25
25
  private readonly event;
26
26
  readonly options: DockviewWillShowOverlayLocationEventOptions;
27
27
  get kind(): DockviewGroupDropLocation;
28
- get nativeEvent(): DragEvent;
28
+ /** Narrow with `instanceof DragEvent` before reading `dataTransfer`. */
29
+ get nativeEvent(): DragEvent | PointerEvent;
29
30
  get position(): Position;
30
31
  get defaultPrevented(): boolean;
31
32
  get panel(): IDockviewPanel | undefined;
@@ -2,6 +2,7 @@ export class DockviewWillShowOverlayLocationEvent {
2
2
  get kind() {
3
3
  return this.options.kind;
4
4
  }
5
+ /** Narrow with `instanceof DragEvent` before reading `dataTransfer`. */
5
6
  get nativeEvent() {
6
7
  return this.event.nativeEvent;
7
8
  }
@@ -77,6 +77,7 @@ export interface ViewFactoryData {
77
77
  }
78
78
  export type DockviewHeaderPosition = 'top' | 'bottom' | 'left' | 'right';
79
79
  export type DockviewHeaderDirection = 'horizontal' | 'vertical';
80
+ export type DockviewDndStrategy = 'auto' | 'pointer' | 'html5';
80
81
  export interface DockviewOptions {
81
82
  /**
82
83
  * Disable the auto-resizing which is controlled through a `ResizeObserver`.
@@ -101,6 +102,19 @@ export interface DockviewOptions {
101
102
  * */
102
103
  rootOverlayModel?: DroptargetOverlayModel;
103
104
  disableDnd?: boolean;
105
+ /**
106
+ * Selects which drag-and-drop implementation is active.
107
+ *
108
+ * - `'auto'` (default): HTML5 drag-and-drop drives mouse drags; pointer
109
+ * events drive touch and pen drags. Matches the historical behaviour.
110
+ * - `'pointer'`: pointer events drive every input type. Useful in
111
+ * environments where HTML5 drag-and-drop is unreliable (some Linux
112
+ * browsers, certain Safari versions, embedded webviews). Cross-window
113
+ * HTML5 drag and the HTML5 native drag image are not available in this
114
+ * mode.
115
+ * - `'html5'`: HTML5 drag-and-drop only — disables touch / pen drag.
116
+ */
117
+ dndStrategy?: DockviewDndStrategy;
104
118
  locked?: boolean;
105
119
  className?: string;
106
120
  /**
@@ -177,19 +191,20 @@ export interface DockviewOptions {
177
191
  }
178
192
  export type TabAnimation = 'smooth' | 'default';
179
193
  export interface DockviewDndOverlayEvent extends IAcceptableEvent {
180
- nativeEvent: DragEvent;
194
+ /** Narrow with `instanceof DragEvent` before reading `dataTransfer`. */
195
+ nativeEvent: DragEvent | PointerEvent;
181
196
  target: DockviewGroupDropLocation;
182
197
  position: Position;
183
198
  group?: DockviewGroupPanel;
184
199
  getData: () => PanelTransfer | undefined;
185
200
  }
186
201
  export declare class DockviewUnhandledDragOverEvent extends AcceptableEvent implements DockviewDndOverlayEvent {
187
- readonly nativeEvent: DragEvent;
202
+ readonly nativeEvent: DragEvent | PointerEvent;
188
203
  readonly target: DockviewGroupDropLocation;
189
204
  readonly position: Position;
190
205
  readonly getData: () => PanelTransfer | undefined;
191
206
  readonly group?: DockviewGroupPanel | undefined;
192
- constructor(nativeEvent: DragEvent, target: DockviewGroupDropLocation, position: Position, getData: () => PanelTransfer | undefined, group?: DockviewGroupPanel | undefined);
207
+ constructor(nativeEvent: DragEvent | PointerEvent, target: DockviewGroupDropLocation, position: Position, getData: () => PanelTransfer | undefined, group?: DockviewGroupPanel | undefined);
193
208
  }
194
209
  export declare const PROPERTY_KEYS_DOCKVIEW: (keyof DockviewOptions)[];
195
210
  export interface CreateComponentOptions {
@@ -28,6 +28,7 @@ export const PROPERTY_KEYS_DOCKVIEW = (() => {
28
28
  rootOverlayModel: undefined,
29
29
  locked: undefined,
30
30
  disableDnd: undefined,
31
+ dndStrategy: undefined,
31
32
  className: undefined,
32
33
  noPanelsOverlay: undefined,
33
34
  dndEdges: undefined,
package/dist/esm/dom.js CHANGED
@@ -205,7 +205,7 @@ export function addTestId(element, id) {
205
205
  * Should be more efficient than element.querySelectorAll("*") since there
206
206
  * is no need to store every element in-memory using this approach
207
207
  */
208
- function allTagsNamesInclusiveOfShadowDoms(tagNames) {
208
+ function allTagsNamesInclusiveOfShadowDoms(tagNames, rootNode) {
209
209
  const iframes = [];
210
210
  function findIframesInNode(node) {
211
211
  if (node.nodeType === Node.ELEMENT_NODE) {
@@ -220,11 +220,15 @@ function allTagsNamesInclusiveOfShadowDoms(tagNames) {
220
220
  }
221
221
  }
222
222
  }
223
- findIframesInNode(document.documentElement);
223
+ // Document → walk from its root element. Element → walk from itself.
224
+ const startEl = rootNode instanceof Document
225
+ ? rootNode.documentElement
226
+ : rootNode;
227
+ findIframesInNode(startEl);
224
228
  return iframes;
225
229
  }
226
230
  export function disableIframePointEvents(rootNode = document) {
227
- const iframes = allTagsNamesInclusiveOfShadowDoms(['IFRAME', 'WEBVIEW']);
231
+ const iframes = allTagsNamesInclusiveOfShadowDoms(['IFRAME', 'WEBVIEW'], rootNode);
228
232
  const original = new WeakMap(); // don't hold onto HTMLElement references longer than required
229
233
  for (const iframe of iframes) {
230
234
  original.set(iframe, iframe.style.pointerEvents);
@@ -8,6 +8,11 @@ export declare class Overlay extends CompositeDisposable {
8
8
  readonly onDidChange: Event<void>;
9
9
  private readonly _onDidChangeEnd;
10
10
  readonly onDidChangeEnd: Event<void>;
11
+ private readonly _onDidStartMoving;
12
+ /** Fires once per drag, the first time the float actually moves. */
13
+ readonly onDidStartMoving: Event<void>;
14
+ private readonly _dragMove;
15
+ private _dragCancelled;
11
16
  private static readonly MINIMUM_HEIGHT;
12
17
  private static readonly MINIMUM_WIDTH;
13
18
  private verticalAlignment;
@@ -27,6 +32,13 @@ export declare class Overlay extends CompositeDisposable {
27
32
  bringToFront(): void;
28
33
  setBounds(bounds?: Partial<AnchoredBox>): void;
29
34
  toJSON(): AnchoredBox;
35
+ /**
36
+ * Abort an in-flight move-the-float drag. Used by the void container
37
+ * when a redock long-press fires after the move started, so the ghost
38
+ * gesture wins without the float continuing to follow the finger.
39
+ * Does not emit `onDidChangeEnd` because no change is being committed.
40
+ */
41
+ cancelPendingDrag(): void;
30
42
  setupDrag(dragTarget: HTMLElement, options?: {
31
43
  inDragMode: boolean;
32
44
  }): void;
@@ -1,6 +1,6 @@
1
1
  import { disableIframePointEvents, quasiDefaultPrevented, toggleClass, } from '../dom';
2
2
  import { Emitter, addDisposableListener } from '../events';
3
- import { CompositeDisposable, MutableDisposable } from '../lifecycle';
3
+ import { CompositeDisposable, Disposable, MutableDisposable, } from '../lifecycle';
4
4
  import { clamp } from '../math';
5
5
  class AriaLevelTracker {
6
6
  constructor() {
@@ -47,7 +47,12 @@ export class Overlay extends CompositeDisposable {
47
47
  this.onDidChange = this._onDidChange.event;
48
48
  this._onDidChangeEnd = new Emitter();
49
49
  this.onDidChangeEnd = this._onDidChangeEnd.event;
50
- this.addDisposables(this._onDidChange, this._onDidChangeEnd);
50
+ this._onDidStartMoving = new Emitter();
51
+ /** Fires once per drag, the first time the float actually moves. */
52
+ this.onDidStartMoving = this._onDidStartMoving.event;
53
+ this._dragMove = new MutableDisposable();
54
+ this._dragCancelled = false;
55
+ this.addDisposables(this._onDidChange, this._onDidChangeEnd, this._onDidStartMoving, this._dragMove);
51
56
  this._element.className = 'dv-resize-container';
52
57
  this._isVisible = true;
53
58
  this.setupResize('top');
@@ -156,16 +161,60 @@ export class Overlay extends CompositeDisposable {
156
161
  result.height = element.height;
157
162
  return result;
158
163
  }
164
+ /**
165
+ * Abort an in-flight move-the-float drag. Used by the void container
166
+ * when a redock long-press fires after the move started, so the ghost
167
+ * gesture wins without the float continuing to follow the finger.
168
+ * Does not emit `onDidChangeEnd` because no change is being committed.
169
+ */
170
+ cancelPendingDrag() {
171
+ if (!this._dragMove.value) {
172
+ return;
173
+ }
174
+ this._dragCancelled = true;
175
+ toggleClass(this._element, 'dv-resize-container-dragging', false);
176
+ this._dragMove.value = Disposable.NONE;
177
+ }
159
178
  setupDrag(dragTarget, options = { inDragMode: false }) {
160
- const move = new MutableDisposable();
161
- const track = () => {
179
+ const track = (captureTarget, pointerId) => {
162
180
  let offset = null;
181
+ let hasMoved = false;
182
+ this._dragCancelled = false;
163
183
  const iframes = disableIframePointEvents();
164
- move.value = new CompositeDisposable({
184
+ if (captureTarget &&
185
+ typeof pointerId === 'number' &&
186
+ typeof captureTarget.setPointerCapture === 'function') {
187
+ try {
188
+ captureTarget.setPointerCapture(pointerId);
189
+ }
190
+ catch (_a) {
191
+ // ignore – non-fatal if the browser refuses capture
192
+ }
193
+ }
194
+ const end = () => {
195
+ toggleClass(this._element, 'dv-resize-container-dragging', false);
196
+ this._dragMove.value = Disposable.NONE;
197
+ this._onDidChangeEnd.fire();
198
+ };
199
+ this._dragMove.value = new CompositeDisposable({
165
200
  dispose: () => {
166
201
  iframes.release();
202
+ if (captureTarget &&
203
+ typeof pointerId === 'number' &&
204
+ typeof captureTarget.releasePointerCapture ===
205
+ 'function') {
206
+ try {
207
+ captureTarget.releasePointerCapture(pointerId);
208
+ }
209
+ catch (_a) {
210
+ // ignore – pointer may already be released
211
+ }
212
+ }
167
213
  },
168
214
  }, addDisposableListener(window, 'pointermove', (e) => {
215
+ if (this._dragCancelled) {
216
+ return;
217
+ }
169
218
  const containerRect = this.options.container.getBoundingClientRect();
170
219
  const x = e.clientX - containerRect.left;
171
220
  const y = e.clientY - containerRect.top;
@@ -202,13 +251,13 @@ export class Overlay extends CompositeDisposable {
202
251
  bounds.right = right;
203
252
  }
204
253
  this.setBounds(bounds);
205
- }), addDisposableListener(window, 'pointerup', () => {
206
- toggleClass(this._element, 'dv-resize-container-dragging', false);
207
- move.dispose();
208
- this._onDidChangeEnd.fire();
209
- }));
254
+ if (!hasMoved) {
255
+ hasMoved = true;
256
+ this._onDidStartMoving.fire();
257
+ }
258
+ }), addDisposableListener(window, 'pointerup', end), addDisposableListener(window, 'pointercancel', end));
210
259
  };
211
- this.addDisposables(move, addDisposableListener(dragTarget, 'pointerdown', (event) => {
260
+ this.addDisposables(addDisposableListener(dragTarget, 'pointerdown', (event) => {
212
261
  if (event.defaultPrevented) {
213
262
  event.preventDefault();
214
263
  return;
@@ -218,7 +267,7 @@ export class Overlay extends CompositeDisposable {
218
267
  if (quasiDefaultPrevented(event)) {
219
268
  return;
220
269
  }
221
- track();
270
+ track(dragTarget, event.pointerId);
222
271
  }), addDisposableListener(this.options.content, 'pointerdown', (event) => {
223
272
  if (event.defaultPrevented) {
224
273
  return;
@@ -229,7 +278,7 @@ export class Overlay extends CompositeDisposable {
229
278
  return;
230
279
  }
231
280
  if (event.shiftKey) {
232
- track();
281
+ track(this.options.content, event.pointerId);
233
282
  }
234
283
  }), addDisposableListener(this.options.content, 'pointerdown', () => {
235
284
  arialLevelTracker.push(this._element);
@@ -247,6 +296,19 @@ export class Overlay extends CompositeDisposable {
247
296
  e.preventDefault();
248
297
  let startPosition = null;
249
298
  const iframes = disableIframePointEvents();
299
+ const pointerId = e.pointerId;
300
+ if (typeof resizeHandleElement.setPointerCapture === 'function') {
301
+ try {
302
+ resizeHandleElement.setPointerCapture(pointerId);
303
+ }
304
+ catch (_a) {
305
+ // ignore – non-fatal if the browser refuses capture
306
+ }
307
+ }
308
+ const end = () => {
309
+ move.dispose();
310
+ this._onDidChangeEnd.fire();
311
+ };
250
312
  move.value = new CompositeDisposable(addDisposableListener(window, 'pointermove', (e) => {
251
313
  const containerRect = this.options.container.getBoundingClientRect();
252
314
  const overlayRect = this._element.getBoundingClientRect();
@@ -381,11 +443,17 @@ export class Overlay extends CompositeDisposable {
381
443
  }), {
382
444
  dispose: () => {
383
445
  iframes.release();
446
+ if (typeof resizeHandleElement.releasePointerCapture ===
447
+ 'function') {
448
+ try {
449
+ resizeHandleElement.releasePointerCapture(pointerId);
450
+ }
451
+ catch (_a) {
452
+ // ignore – pointer may already be released
453
+ }
454
+ }
384
455
  },
385
- }, addDisposableListener(window, 'pointerup', () => {
386
- move.dispose();
387
- this._onDidChangeEnd.fire();
388
- }));
456
+ }, addDisposableListener(window, 'pointerup', end), addDisposableListener(window, 'pointercancel', end));
389
457
  }));
390
458
  }
391
459
  getMinimumWidth(width) {
@@ -12,8 +12,10 @@ export interface PaneviewDidDropEvent extends DroptargetEvent {
12
12
  api: PaneviewApi;
13
13
  }
14
14
  export declare abstract class DraggablePaneviewPanel extends PaneviewPanel {
15
- private handler;
15
+ private html5DragSource;
16
+ private pointerDragSource;
16
17
  private target;
18
+ private pointerTarget;
17
19
  private readonly _onDidDrop;
18
20
  readonly onDidDrop: Event<PaneviewDidDropEvent>;
19
21
  private readonly _onUnhandledDragOverEvent;
@@ -1,7 +1,6 @@
1
1
  import { PaneviewApi } from '../api/component.api';
2
- import { DragHandler } from '../dnd/abstractDragHandler';
2
+ import { html5Backend, pointerBackend, } from '../dnd/backend';
3
3
  import { getPaneData, LocalSelectionTransfer, PaneTransfer, } from '../dnd/dataTransfer';
4
- import { Droptarget } from '../dnd/droptarget';
5
4
  import { Emitter } from '../events';
6
5
  import { PaneviewUnhandledDragOverEvent, } from './options';
7
6
  import { PaneviewPanel, } from './paneviewPanel';
@@ -35,35 +34,42 @@ export class DraggablePaneviewPanel extends PaneviewPanel {
35
34
  const id = this.id;
36
35
  const accessorId = this.accessor.id;
37
36
  this.header.draggable = true;
38
- this.handler = new (class PaneDragHandler extends DragHandler {
39
- getData() {
37
+ const sharedDragOptions = {
38
+ getData: () => {
40
39
  LocalSelectionTransfer.getInstance().setData([new PaneTransfer(accessorId, id)], PaneTransfer.prototype);
41
40
  return {
42
41
  dispose: () => {
43
42
  LocalSelectionTransfer.getInstance().clearData(PaneTransfer.prototype);
44
43
  },
45
44
  };
45
+ },
46
+ };
47
+ this.html5DragSource = html5Backend.createDragSource(this.header, sharedDragOptions);
48
+ this.pointerDragSource = pointerBackend.createDragSource(this.header, sharedDragOptions);
49
+ const canDisplayOverlay = (event, position) => {
50
+ const data = getPaneData();
51
+ if (data) {
52
+ if (data.paneId !== this.id &&
53
+ data.viewId === this.accessor.id) {
54
+ return true;
55
+ }
46
56
  }
47
- })(this.header);
48
- this.target = new Droptarget(this.element, {
57
+ const firedEvent = new PaneviewUnhandledDragOverEvent(event, position, getPaneData, this);
58
+ this._onUnhandledDragOverEvent.fire(firedEvent);
59
+ return firedEvent.isAccepted;
60
+ };
61
+ const dropTargetOptions = {
49
62
  acceptedTargetZones: ['top', 'bottom'],
50
63
  overlayModel: {
51
64
  activationSize: { type: 'percentage', value: 50 },
52
65
  },
53
- canDisplayOverlay: (event, position) => {
54
- const data = getPaneData();
55
- if (data) {
56
- if (data.paneId !== this.id &&
57
- data.viewId === this.accessor.id) {
58
- return true;
59
- }
60
- }
61
- const firedEvent = new PaneviewUnhandledDragOverEvent(event, position, getPaneData, this);
62
- this._onUnhandledDragOverEvent.fire(firedEvent);
63
- return firedEvent.isAccepted;
64
- },
65
- });
66
- this.addDisposables(this._onDidDrop, this.handler, this.target, this.target.onDrop((event) => {
66
+ canDisplayOverlay,
67
+ };
68
+ this.target = html5Backend.createDropTarget(this.element, dropTargetOptions);
69
+ this.pointerTarget = pointerBackend.createDropTarget(this.element, dropTargetOptions);
70
+ this.addDisposables(this._onDidDrop, this.html5DragSource, this.pointerDragSource, this.target, this.pointerTarget, this.target.onDrop((event) => {
71
+ this.onDrop(event);
72
+ }), this.pointerTarget.onDrop((event) => {
67
73
  this.onDrop(event);
68
74
  }));
69
75
  }
@@ -15,15 +15,16 @@ export interface PaneviewFrameworkOptions {
15
15
  export type PaneviewComponentOptions = PaneviewOptions & PaneviewFrameworkOptions;
16
16
  export declare const PROPERTY_KEYS_PANEVIEW: (keyof PaneviewOptions)[];
17
17
  export interface PaneviewDndOverlayEvent extends IAcceptableEvent {
18
- nativeEvent: DragEvent;
18
+ /** Narrow with `instanceof DragEvent` before reading `dataTransfer`. */
19
+ nativeEvent: DragEvent | PointerEvent;
19
20
  position: Position;
20
21
  panel: IPaneviewPanel;
21
22
  getData: () => PaneTransfer | undefined;
22
23
  }
23
24
  export declare class PaneviewUnhandledDragOverEvent extends AcceptableEvent implements PaneviewDndOverlayEvent {
24
- readonly nativeEvent: DragEvent;
25
+ readonly nativeEvent: DragEvent | PointerEvent;
25
26
  readonly position: Position;
26
27
  readonly getData: () => PaneTransfer | undefined;
27
28
  readonly panel: IPaneviewPanel;
28
- constructor(nativeEvent: DragEvent, position: Position, getData: () => PaneTransfer | undefined, panel: IPaneviewPanel);
29
+ constructor(nativeEvent: DragEvent | PointerEvent, position: Position, getData: () => PaneTransfer | undefined, panel: IPaneviewPanel);
29
30
  }