Merge pull request #698 from mathuo/696-touch-support-for-dragging-dockview-panels

feat: ensure use of pointerevents for touch support
This commit is contained in:
mathuo 2024-08-28 20:32:07 +01:00 committed by GitHub
commit fc7b9fb2e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 41 additions and 35 deletions

View File

@ -54,7 +54,7 @@ describe('defaultTab', () => {
let el = cut.element.querySelector('.dv-default-tab-action'); let el = cut.element.querySelector('.dv-default-tab-action');
fireEvent.mouseDown(el!); fireEvent.pointerDown(el!);
expect(api.close).toHaveBeenCalledTimes(0); expect(api.close).toHaveBeenCalledTimes(0);
fireEvent.click(el!); fireEvent.click(el!);

View File

@ -459,6 +459,7 @@ describe('tabsContainer', () => {
onDidRemovePanel: jest.fn(), onDidRemovePanel: jest.fn(),
element: document.createElement('div'), element: document.createElement('div'),
addFloatingGroup: jest.fn(), addFloatingGroup: jest.fn(),
doSetGroupActive: jest.fn(),
}); });
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => { const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
@ -486,10 +487,11 @@ describe('tabsContainer', () => {
return { top: 10, left: 20, width: 0, height: 0 } as any; return { top: 10, left: 20, width: 0, height: 0 } as any;
}); });
const event = new KeyboardEvent('mousedown', { shiftKey: true }); const event = new KeyboardEvent('pointerdown', { shiftKey: true });
const eventPreventDefaultSpy = jest.spyOn(event, 'preventDefault'); const eventPreventDefaultSpy = jest.spyOn(event, 'preventDefault');
fireEvent(container, event); fireEvent(container, event);
expect(accessor.doSetGroupActive).toHaveBeenCalledWith(groupPanel);
expect(accessor.addFloatingGroup).toHaveBeenCalledWith(groupPanel, { expect(accessor.addFloatingGroup).toHaveBeenCalledWith(groupPanel, {
x: 100, x: 100,
y: 60, y: 60,
@ -498,7 +500,7 @@ describe('tabsContainer', () => {
expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(1); expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(1);
expect(eventPreventDefaultSpy).toHaveBeenCalledTimes(1); expect(eventPreventDefaultSpy).toHaveBeenCalledTimes(1);
const event2 = new KeyboardEvent('mousedown', { shiftKey: false }); const event2 = new KeyboardEvent('pointerdown', { shiftKey: false });
const eventPreventDefaultSpy2 = jest.spyOn(event2, 'preventDefault'); const eventPreventDefaultSpy2 = jest.spyOn(event2, 'preventDefault');
fireEvent(container, event2); fireEvent(container, event2);
@ -513,6 +515,7 @@ describe('tabsContainer', () => {
onDidRemovePanel: jest.fn(), onDidRemovePanel: jest.fn(),
element: document.createElement('div'), element: document.createElement('div'),
addFloatingGroup: jest.fn(), addFloatingGroup: jest.fn(),
doSetGroupActive: jest.fn(),
}); });
const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => { const groupPanelMock = jest.fn<DockviewGroupPanel, []>(() => {
@ -540,14 +543,15 @@ describe('tabsContainer', () => {
return { top: 10, left: 20, width: 0, height: 0 } as any; return { top: 10, left: 20, width: 0, height: 0 } as any;
}); });
const event = new KeyboardEvent('mousedown', { shiftKey: true }); const event = new KeyboardEvent('pointerdown', { shiftKey: true });
const eventPreventDefaultSpy = jest.spyOn(event, 'preventDefault'); const eventPreventDefaultSpy = jest.spyOn(event, 'preventDefault');
fireEvent(container, event); fireEvent(container, event);
expect(accessor.doSetGroupActive).toHaveBeenCalledWith(groupPanel);
expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(0); expect(accessor.addFloatingGroup).toHaveBeenCalledTimes(0);
expect(eventPreventDefaultSpy).toHaveBeenCalledTimes(0); expect(eventPreventDefaultSpy).toHaveBeenCalledTimes(0);
const event2 = new KeyboardEvent('mousedown', { shiftKey: false }); const event2 = new KeyboardEvent('pointerdown', { shiftKey: false });
const eventPreventDefaultSpy2 = jest.spyOn(event2, 'preventDefault'); const eventPreventDefaultSpy2 = jest.spyOn(event2, 'preventDefault');
fireEvent(container, event2); fireEvent(container, event2);
@ -595,7 +599,7 @@ describe('tabsContainer', () => {
const el = cut.element.querySelector('.tab')!; const el = cut.element.querySelector('.tab')!;
expect(el).toBeTruthy(); expect(el).toBeTruthy();
const event = new KeyboardEvent('mousedown', { shiftKey: true }); const event = new KeyboardEvent('pointerdown', { shiftKey: true });
const preventDefaultSpy = jest.spyOn(event, 'preventDefault'); const preventDefaultSpy = jest.spyOn(event, 'preventDefault');
fireEvent(el, event); fireEvent(el, event);

View File

@ -153,14 +153,14 @@ describe('events', () => {
const disposable = addDisposableWindowListener( const disposable = addDisposableWindowListener(
element as any, element as any,
'mousedown', 'pointerdown',
handler, handler,
true true
); );
expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toBeCalledTimes(1);
expect(element.addEventListener).toHaveBeenCalledWith( expect(element.addEventListener).toHaveBeenCalledWith(
'mousedown', 'pointerdown',
handler, handler,
true true
); );
@ -171,7 +171,7 @@ describe('events', () => {
expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toBeCalledTimes(1);
expect(element.removeEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledTimes(1);
expect(element.removeEventListener).toBeCalledWith( expect(element.removeEventListener).toBeCalledWith(
'mousedown', 'pointerdown',
handler, handler,
true true
); );
@ -187,13 +187,13 @@ describe('events', () => {
const disposable = addDisposableWindowListener( const disposable = addDisposableWindowListener(
element as any, element as any,
'mousedown', 'pointerdown',
handler handler
); );
expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toBeCalledTimes(1);
expect(element.addEventListener).toHaveBeenCalledWith( expect(element.addEventListener).toHaveBeenCalledWith(
'mousedown', 'pointerdown',
handler, handler,
undefined undefined
); );
@ -204,7 +204,7 @@ describe('events', () => {
expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toBeCalledTimes(1);
expect(element.removeEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledTimes(1);
expect(element.removeEventListener).toBeCalledWith( expect(element.removeEventListener).toBeCalledWith(
'mousedown', 'pointerdown',
handler, handler,
undefined undefined
); );
@ -220,14 +220,14 @@ describe('events', () => {
const disposable = addDisposableListener( const disposable = addDisposableListener(
element as any, element as any,
'mousedown', 'pointerdown',
handler, handler,
true true
); );
expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toBeCalledTimes(1);
expect(element.addEventListener).toHaveBeenCalledWith( expect(element.addEventListener).toHaveBeenCalledWith(
'mousedown', 'pointerdown',
handler, handler,
true true
); );
@ -238,7 +238,7 @@ describe('events', () => {
expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toBeCalledTimes(1);
expect(element.removeEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledTimes(1);
expect(element.removeEventListener).toBeCalledWith( expect(element.removeEventListener).toBeCalledWith(
'mousedown', 'pointerdown',
handler, handler,
true true
); );
@ -254,13 +254,13 @@ describe('events', () => {
const disposable = addDisposableListener( const disposable = addDisposableListener(
element as any, element as any,
'mousedown', 'pointerdown',
handler handler
); );
expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toBeCalledTimes(1);
expect(element.addEventListener).toHaveBeenCalledWith( expect(element.addEventListener).toHaveBeenCalledWith(
'mousedown', 'pointerdown',
handler, handler,
undefined undefined
); );
@ -271,7 +271,7 @@ describe('events', () => {
expect(element.addEventListener).toBeCalledTimes(1); expect(element.addEventListener).toBeCalledTimes(1);
expect(element.removeEventListener).toBeCalledTimes(1); expect(element.removeEventListener).toBeCalledTimes(1);
expect(element.removeEventListener).toBeCalledWith( expect(element.removeEventListener).toBeCalledWith(
'mousedown', 'pointerdown',
handler, handler,
undefined undefined
); );

View File

@ -21,7 +21,7 @@ export class GroupDragHandler extends DragHandler {
this.addDisposables( this.addDisposables(
addDisposableListener( addDisposableListener(
element, element,
'mousedown', 'pointerdown',
(e) => { (e) => {
if (e.shiftKey) { if (e.shiftKey) {
/** /**

View File

@ -30,7 +30,7 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer {
this._element.appendChild(this.action); this._element.appendChild(this.action);
this.addDisposables( this.addDisposables(
addDisposableListener(this.action, 'mousedown', (ev) => { addDisposableListener(this.action, 'pointerdown', (ev) => {
ev.preventDefault(); ev.preventDefault();
}) })
); );
@ -46,7 +46,7 @@ export class DefaultTab extends CompositeDisposable implements ITabRenderer {
this._title = event.title; this._title = event.title;
this.render(); this.render();
}), }),
addDisposableListener(this.action, 'mousedown', (ev) => { addDisposableListener(this.action, 'pointerdown', (ev) => {
ev.preventDefault(); ev.preventDefault();
}), }),
addDisposableListener(this.action, 'click', (ev) => { addDisposableListener(this.action, 'click', (ev) => {

View File

@ -124,7 +124,7 @@ export class Tab extends CompositeDisposable {
this._onDragStart.fire(event); this._onDragStart.fire(event);
}), }),
dragHandler, dragHandler,
addDisposableListener(this._element, 'mousedown', (event) => { addDisposableListener(this._element, 'pointerdown', (event) => {
if (event.defaultPrevented) { if (event.defaultPrevented) {
return; return;
} }

View File

@ -253,7 +253,7 @@ export class TabsContainer
}), }),
addDisposableListener( addDisposableListener(
this.voidContainer.element, this.voidContainer.element,
'mousedown', 'pointerdown',
(event) => { (event) => {
const isFloatingGroupsEnabled = const isFloatingGroupsEnabled =
!this.accessor.options.disableFloatingGroups; !this.accessor.options.disableFloatingGroups;
@ -278,7 +278,7 @@ export class TabsContainer
} }
} }
), ),
addDisposableListener(this.tabContainer, 'mousedown', (event) => { addDisposableListener(this.tabContainer, 'pointerdown', (event) => {
if (event.defaultPrevented) { if (event.defaultPrevented) {
return; return;
} }

View File

@ -37,7 +37,9 @@ class AriaLevelTracker {
private update(): void { private update(): void {
for (let i = 0; i < this._orderedList.length; i++) { for (let i = 0; i < this._orderedList.length; i++) {
this._orderedList[i].setAttribute('aria-level', `${i}`); this._orderedList[i].setAttribute('aria-level', `${i}`);
this._orderedList[i].style.zIndex = `${DEFAULT_OVERLAY_Z_INDEX + i * 2}`; this._orderedList[i].style.zIndex = `${
DEFAULT_OVERLAY_Z_INDEX + i * 2
}`;
} }
} }
} }
@ -241,7 +243,7 @@ export class Overlay extends CompositeDisposable {
iframes.release(); iframes.release();
}, },
}, },
addDisposableWindowListener(window, 'mousemove', (e) => { addDisposableWindowListener(window, 'pointermove', (e) => {
const containerRect = const containerRect =
this.options.container.getBoundingClientRect(); this.options.container.getBoundingClientRect();
const x = e.clientX - containerRect.left; const x = e.clientX - containerRect.left;
@ -342,7 +344,7 @@ export class Overlay extends CompositeDisposable {
this.addDisposables( this.addDisposables(
move, move,
addDisposableListener(dragTarget, 'mousedown', (event) => { addDisposableListener(dragTarget, 'pointerdown', (event) => {
if (event.defaultPrevented) { if (event.defaultPrevented) {
event.preventDefault(); event.preventDefault();
return; return;
@ -358,7 +360,7 @@ export class Overlay extends CompositeDisposable {
}), }),
addDisposableListener( addDisposableListener(
this.options.content, this.options.content,
'mousedown', 'pointerdown',
(event) => { (event) => {
if (event.defaultPrevented) { if (event.defaultPrevented) {
return; return;
@ -377,7 +379,7 @@ export class Overlay extends CompositeDisposable {
), ),
addDisposableListener( addDisposableListener(
this.options.content, this.options.content,
'mousedown', 'pointerdown',
() => { () => {
arialLevelTracker.push(this._element); arialLevelTracker.push(this._element);
}, },
@ -409,7 +411,7 @@ export class Overlay extends CompositeDisposable {
this.addDisposables( this.addDisposables(
move, move,
addDisposableListener(resizeHandleElement, 'mousedown', (e) => { addDisposableListener(resizeHandleElement, 'pointerdown', (e) => {
e.preventDefault(); e.preventDefault();
let startPosition: { let startPosition: {
@ -422,7 +424,7 @@ export class Overlay extends CompositeDisposable {
const iframes = disableIframePointEvents(); const iframes = disableIframePointEvents();
move.value = new CompositeDisposable( move.value = new CompositeDisposable(
addDisposableWindowListener(window, 'mousemove', (e) => { addDisposableWindowListener(window, 'pointermove', (e) => {
const containerRect = const containerRect =
this.options.container.getBoundingClientRect(); this.options.container.getBoundingClientRect();
const overlayRect = const overlayRect =

View File

@ -176,7 +176,7 @@ describe('defaultTab', () => {
expect(element.querySelector('.dv-default-tab-action')).toBeTruthy(); expect(element.querySelector('.dv-default-tab-action')).toBeTruthy();
}); });
test('that mouseDown on close button prevents panel becoming active', async () => { test('that pointerDown on close button prevents panel becoming active', async () => {
const api = fromPartial<DockviewPanelApi>({ const api = fromPartial<DockviewPanelApi>({
setActive: jest.fn(), setActive: jest.fn(),
onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE), onDidTitleChange: jest.fn().mockImplementation(() => Disposable.NONE),
@ -197,7 +197,7 @@ describe('defaultTab', () => {
'.dv-default-tab-action' '.dv-default-tab-action'
) as HTMLElement; ) as HTMLElement;
fireEvent.mouseDown(btn); fireEvent.pointerDown(btn);
expect(api.setActive).toHaveBeenCalledTimes(0); expect(api.setActive).toHaveBeenCalledTimes(0);
fireEvent.click(element); fireEvent.click(element);

View File

@ -49,7 +49,7 @@ export const DockviewDefaultTab: React.FunctionComponent<
[api, closeActionOverride] [api, closeActionOverride]
); );
const onMouseDown = React.useCallback((e: React.MouseEvent) => { const onPointerDown = React.useCallback((e: React.MouseEvent) => {
e.preventDefault(); e.preventDefault();
}, []); }, []);
@ -79,7 +79,7 @@ export const DockviewDefaultTab: React.FunctionComponent<
{!hideClose && ( {!hideClose && (
<div <div
className="dv-default-tab-action" className="dv-default-tab-action"
onMouseDown={onMouseDown} onPointerDown={onPointerDown}
onClick={onClose} onClick={onClose}
> >
<CloseButton /> <CloseButton />