mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-12 05:17:28 -08:00
fix(editor): Improve touch device detection (#9675)
This commit is contained in:
parent
dc17cf3a49
commit
3b86f52b02
|
@ -1,5 +1,11 @@
|
|||
import { useDeviceSupport } from 'n8n-design-system/composables/useDeviceSupport';
|
||||
|
||||
const detectPointerType = (query: string) => {
|
||||
const isCoarse = query === '(any-pointer: coarse)';
|
||||
const isFine = query === '(any-pointer: fine)';
|
||||
return { fine: isFine, coarse: isCoarse };
|
||||
};
|
||||
|
||||
describe('useDeviceSupport()', () => {
|
||||
beforeEach(() => {
|
||||
global.window = Object.create(window);
|
||||
|
@ -7,24 +13,38 @@ describe('useDeviceSupport()', () => {
|
|||
});
|
||||
|
||||
describe('isTouchDevice', () => {
|
||||
it('should be true if ontouchstart is in window', () => {
|
||||
Object.defineProperty(window, 'ontouchstart', {});
|
||||
const { isTouchDevice } = useDeviceSupport();
|
||||
expect(isTouchDevice).toEqual(true);
|
||||
});
|
||||
|
||||
it('should be true if navigator.maxTouchPoints > 0', () => {
|
||||
Object.defineProperty(navigator, 'maxTouchPoints', { value: 1 });
|
||||
const { isTouchDevice } = useDeviceSupport();
|
||||
expect(isTouchDevice).toEqual(true);
|
||||
});
|
||||
|
||||
it('should be false if no touch support', () => {
|
||||
delete window.ontouchstart;
|
||||
Object.defineProperty(navigator, 'maxTouchPoints', { value: 0 });
|
||||
it('should be false if window matches `any-pointer: fine` and `!any-pointer: coarse`', () => {
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
value: vi.fn().mockImplementation((query: string) => {
|
||||
const { fine, coarse } = detectPointerType(query);
|
||||
return { matches: fine && !coarse };
|
||||
}),
|
||||
});
|
||||
const { isTouchDevice } = useDeviceSupport();
|
||||
expect(isTouchDevice).toEqual(false);
|
||||
});
|
||||
|
||||
it('should be false if window matches `any-pointer: fine` and `any-pointer: coarse`', () => {
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
value: vi.fn().mockImplementation((query: string) => {
|
||||
const { fine, coarse } = detectPointerType(query);
|
||||
return { matches: fine && coarse };
|
||||
}),
|
||||
});
|
||||
const { isTouchDevice } = useDeviceSupport();
|
||||
expect(isTouchDevice).toEqual(false);
|
||||
});
|
||||
|
||||
it('should be true if window matches `any-pointer: coarse` and `!any-pointer: fine`', () => {
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
value: vi.fn().mockImplementation((query: string) => {
|
||||
const { fine, coarse } = detectPointerType(query);
|
||||
return { matches: coarse && !fine };
|
||||
}),
|
||||
});
|
||||
const { isTouchDevice } = useDeviceSupport();
|
||||
expect(isTouchDevice).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isMacOs', () => {
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
import { ref } from 'vue';
|
||||
|
||||
export function useDeviceSupport() {
|
||||
const isTouchDevice = ref(window.hasOwnProperty('ontouchstart') || navigator.maxTouchPoints > 0);
|
||||
/**
|
||||
* Check if the device is a touch device but exclude devices that have a fine pointer (mouse or track-pad)
|
||||
* - `fine` will check for an accurate pointing device. Examples include mice, touch-pads, and drawing styluses
|
||||
* - `coarse` will check for a pointing device of limited accuracy. Examples include touchscreens and motion-detection sensors
|
||||
* - `any-pointer` will check for the presence of any pointing device, if there are multiple of them
|
||||
*/
|
||||
const isTouchDevice = ref(
|
||||
window.matchMedia('(any-pointer: coarse)').matches &&
|
||||
!window.matchMedia('(any-pointer: fine)').matches,
|
||||
);
|
||||
const userAgent = ref(navigator.userAgent.toLowerCase());
|
||||
const isMacOs = ref(
|
||||
userAgent.value.includes('macintosh') ||
|
||||
|
|
|
@ -44,3 +44,18 @@ export class IntersectionObserver {
|
|||
|
||||
window.IntersectionObserver = IntersectionObserver;
|
||||
global.IntersectionObserver = IntersectionObserver;
|
||||
|
||||
// Mocks for useDeviceSupport
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
value: vi.fn().mockImplementation((query) => ({
|
||||
matches: true,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: vi.fn(),
|
||||
removeListener: vi.fn(),
|
||||
addEventListener: vi.fn(),
|
||||
removeEventListener: vi.fn(),
|
||||
dispatchEvent: vi.fn(),
|
||||
})),
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue