detect-passive-events
Version:
Detect if the browser supports passive events
79 lines (74 loc) • 4.87 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.DetectPassiveEvents = {}));
}(this, (function (exports) { 'use strict';
// so it doesn't throw if no window or matchMedia
var w = typeof window !== 'undefined' ? window : { screen: {}, navigator: {} };
var matchMedia = (w.matchMedia || (function () { return ({ matches: false }); })).bind(w);
// passive events test
// adapted from https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
var passiveOptionAccessed = false;
var options = {
get passive() {
return (passiveOptionAccessed = true);
},
};
// have to set and remove a no-op listener instead of null
// (which was used previously), because Edge v15 throws an error
// when providing a null callback.
// https://github.com/rafgraph/detect-passive-events/pull/3
// eslint-disable-next-line @typescript-eslint/no-empty-function
var noop = function () { };
w.addEventListener && w.addEventListener('p', noop, options);
w.removeEventListener && w.removeEventListener('p', noop, false);
var supportsPassiveEvents = passiveOptionAccessed;
var onTouchStartInWindow = 'ontouchstart' in w;
var touchEventInWindow = 'TouchEvent' in w;
// onTouchStartInWindow is the old-old-legacy way to determine a touch device
// and many websites interpreted it to mean that the device is a touch only phone,
// so today browsers on a desktop/laptop computer with a touch screen (primary input mouse)
// have onTouchStartInWindow as false (to prevent from being confused with a
// touchOnly phone) even though they support the TouchEvents API, so need to check
// both onTouchStartInWindow and touchEventInWindow for TouchEvent support,
// however, some browsers (chromium) support the TouchEvents API even when running on
// a mouse only device (touchEventInWindow true, but onTouchStartInWindow false)
// so the touchEventInWindow check needs to include an coarse pointer media query
onTouchStartInWindow ||
(touchEventInWindow && matchMedia('(any-pointer: coarse)').matches);
// userAgent is used as a backup to correct for known device/browser bugs
// and when the browser doesn't support interaction media queries (pointer and hover)
// see https://caniuse.com/css-media-interaction
var userAgent = w.navigator.userAgent || '';
// iPads now support a mouse that can hover, however the media query interaction
// feature results always say iPads only have a coarse pointer that can't hover
// even when a mouse is connected (anyFine and anyHover are always false),
// this unfortunately indicates a touch only device but iPads should
// be classified as a hybrid device, so determine if it is an iPad
// to indicate it should be treated as a hybrid device with anyHover true
var isIPad = matchMedia('(pointer: coarse)').matches &&
// both iPad and iPhone can "request desktop site", which sets the userAgent to Macintosh
// so need to check both userAgents to determine if it is an iOS device
// and screen size to separate iPad from iPhone
/iPad|Macintosh/.test(userAgent) &&
Math.min(w.screen.width || 0, w.screen.height || 0) >= 768;
(matchMedia('(pointer: coarse)').matches ||
// if the pointer is not coarse and not fine then the browser doesn't support
// interaction media queries (see https://caniuse.com/css-media-interaction)
// so if it has onTouchStartInWindow assume it has a coarse primary pointer
(!matchMedia('(pointer: fine)').matches && onTouchStartInWindow)) &&
// bug in firefox (as of v81) on hybrid windows devices where the interaction media queries
// always indicate a touch only device (only has a coarse pointer that can't hover)
// so assume that the primary pointer is not coarse for firefox windows
!/Windows.*Firefox/.test(userAgent);
matchMedia('(any-pointer: fine)').matches ||
matchMedia('(any-hover: hover)').matches ||
// iPads might have an input device that can hover, so assume it has anyHover
isIPad ||
// if no onTouchStartInWindow then the browser is indicating that it is not a touch only device
// see above note for supportsTouchEvents
!onTouchStartInWindow;
exports.supportsPassiveEvents = supportsPassiveEvents;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=detect-passive-events.umd.development.js.map