Comparing version 2.1.1 to 3.0.0
@@ -45,15 +45,31 @@ 'use strict'; | ||
function determineDeviceType(hasTouch, anyHover, anyFine) { | ||
/* | ||
* A hybrid device is one that both hasTouch and any input device can hover | ||
* or has a fine pointer. | ||
*/ | ||
function determineDeviceType(hasTouch, anyHover, anyFine, state) { | ||
// A hybrid device is one that both hasTouch and any input device can hover | ||
// or has a fine pointer. | ||
if (hasTouch && (anyHover || anyFine)) return 'hybrid'; | ||
/* | ||
* In almost all cases a device that doesn’t support touch will have a mouse, | ||
* but there may be rare exceptions. Note that it doesn’t work to do additional tests | ||
* based on hover and pointer media queries as older browsers don’t support these. | ||
* Essentially, 'mouseOnly' is the default. | ||
*/ | ||
// workaround for browsers that have the touch events api, | ||
// and have implemented Level 4 media queries but not the | ||
// hover and pointer media queries, so the tests are all false (notable Firefox) | ||
// if it hasTouch, no pointer and hover support, and on an android assume it's touchOnly | ||
// if it hasTouch, no pointer and hover support, and not on an android assume it's a hybrid | ||
if (hasTouch && Object.keys(state.detectHover).filter(function (key) { | ||
return key !== 'update'; | ||
}).every(function (key) { | ||
return state.detectHover[key] === false; | ||
}) && Object.keys(state.detectPointer).filter(function (key) { | ||
return key !== 'update'; | ||
}).every(function (key) { | ||
return state.detectPointer[key] === false; | ||
})) { | ||
if (window.navigator && /android/.test(window.navigator.userAgent.toLowerCase())) { | ||
return 'touchOnly'; | ||
} | ||
return 'hybrid'; | ||
} | ||
// In almost all cases a device that doesn’t support touch will have a mouse, | ||
// but there may be rare exceptions. Note that it doesn’t work to do additional tests | ||
// based on hover and pointer media queries as older browsers don’t support these. | ||
// Essentially, 'mouseOnly' is the default. | ||
return hasTouch ? 'touchOnly' : 'mouseOnly'; | ||
@@ -80,24 +96,14 @@ } | ||
detectIt.hasTouch = detectIt.state.detectTouchEvents.hasApi || false; | ||
detectIt.hasTouch = detectIt.state.detectTouchEvents.hasSupport || false; | ||
detectIt.deviceType = determineDeviceType(detectIt.hasTouch, detectIt.state.detectHover.anyHover, detectIt.state.detectPointer.anyFine); | ||
detectIt.deviceType = determineDeviceType(detectIt.hasTouch, detectIt.state.detectHover.anyHover, detectIt.state.detectPointer.anyFine, detectIt.state); | ||
detectIt.hasMouse = detectIt.deviceType !== 'touchOnly'; | ||
detectIt.maxTouchPoints = detectIt.state.detectTouchEvents.maxTouchPoints; | ||
detectIt.primaryHover = detectIt.state.detectHover.hover && 'hover' || detectIt.state.detectHover.none && 'none' || | ||
// if it's a mouseOnly device that doesn't support level 4 media queries, | ||
// then assume it hovers | ||
detectIt.deviceType === 'mouseOnly' && 'hover' || | ||
// if it's a touchOnly device that doesn't support level 4 media queries, | ||
// then assume it doesn't hover, otherwise it's undefined | ||
detectIt.deviceType === 'touchOnly' && 'none' || undefined; | ||
detectIt.primaryPointer = detectIt.state.detectPointer.fine && 'fine' || detectIt.state.detectPointer.coarse && 'coarse' || detectIt.state.detectPointer.none && 'none' || | ||
// if it's a mouseOnly device that doesn't support level 4 media queries, | ||
// then assume it has a fine pointer | ||
detectIt.deviceType === 'mouseOnly' && 'fine' || | ||
// if it's a touchOnly device that doesn't support level 4 media queries, | ||
// then assume it has a coarse pointer, otherwise it's undefined | ||
detectIt.deviceType === 'touchOnly' && 'coarse' || undefined; | ||
detectIt.primaryInput = detectIt.deviceType === 'mouseOnly' && 'mouse' || detectIt.deviceType === 'touchOnly' && 'touch' || | ||
// deviceType is hybrid: | ||
detectIt.state.detectHover.hover && 'mouse' || detectIt.state.detectHover.none && 'touch' || | ||
// if there's no support for hover media queries but detectIt determined it's | ||
// a hybrid device, then assume it's a mouse first device | ||
'mouse'; | ||
} | ||
@@ -104,0 +110,0 @@ } |
{ | ||
"name": "detect-it", | ||
"version": "2.1.1", | ||
"version": "3.0.0", | ||
"description": "Detect if a device is mouse only, touch only, or hybrid", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"build": "rm -rf lib && babel src --presets babel-preset-es2015 -d lib", | ||
"prepublish": "npm run build" | ||
"build": "rm -rf lib && babel src -d lib --presets=env", | ||
"prepublish": "npm run build", | ||
"dev": "npm link && babel src -d lib --watch --presets=env" | ||
}, | ||
@@ -36,12 +37,12 @@ "files": [ | ||
"detect-pointer": "^1.0.1", | ||
"detect-touch-events": "^1.0.1" | ||
"detect-touch-events": "^2.0.0" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.23.0", | ||
"babel-eslint": "^7.1.0", | ||
"babel-preset-es2015": "^6.22.0", | ||
"eslint": "^3.10.1", | ||
"eslint-config-airbnb-base": "^10.0.1", | ||
"babel-cli": "^6.24.1", | ||
"babel-eslint": "^7.2.3", | ||
"babel-preset-env": "^1.4.0", | ||
"eslint": "^3.19.0", | ||
"eslint-config-airbnb-base": "^11.1.3", | ||
"eslint-plugin-import": "^2.2.0" | ||
} | ||
} |
@@ -9,5 +9,5 @@ # Detect It | ||
`detect-it`'s state is a deterministic function of the state of the four micro state machines that it contains ([`detect-hover`][detectHoverRepo], [`detect-pointer`][detectPointerRepo], [`detect-touch-events`][detectTouchEventsRepo], and [`detect-passive-events`][detectPassiveEventsRepo]). `detect-it`'s `update()` function first runs the `update()` function on each micro state machine that it contains, and then updates it own state. | ||
`detect-it`'s state is based on the state of the four micro state machines that it contains ([`detect-hover`][detectHoverRepo], [`detect-pointer`][detectPointerRepo], [`detect-touch-events`][detectTouchEventsRepo], and [`detect-passive-events`][detectPassiveEventsRepo]). `detect-it`'s `update()` function first runs the `update()` function on each micro state machine that it contains, and then updates it own state. | ||
Note that Detect It v2 removed support for Pointer Events detection because they're just not relevant enough (only used by IE and Edge and not supported by React). If you need Pointer Events detection, use [Detect It v1.1][detectItv1.1]. | ||
Note that Detect It has removed support for Pointer Events detection because they're just not relevant enough (support for less than 60% of users, [see Can I Use][canIUsePointerEvents], and not supported by React). If you need Pointer Events detection, use [Detect It v1.1][detectItv1.1]. | ||
@@ -18,8 +18,6 @@ ### `detectIt` micro state machine | ||
deviceType: 'mouseOnly' / 'touchOnly' / 'hybrid', | ||
passiveEvents: boolean, | ||
hasMouse: boolean, | ||
hasTouch: boolean, | ||
maxTouchPoints: whole number, | ||
primaryHover: 'hover' / 'none', | ||
primaryPointer: 'fine' / 'coarse' / 'none', | ||
passiveEvents: true / false, | ||
hasMouse: true / false, | ||
hasTouch: true / false, | ||
primaryInput: 'mouse' / 'touch', | ||
@@ -59,8 +57,5 @@ // access to the four micro state machines that it contains | ||
detectIt.maxTouchPoints; // max number of touch points supported | ||
detectIt.primaryInput === 'mouse' / 'touch'; // the primary input type | ||
detectIt.primaryHover === 'hover' / 'none'; // can the primary pointing system easily hover | ||
detectIt.primaryPointer === 'fine' / `coarse` / 'none'; // how accurate is the primary pointing system | ||
// accessing the state of the micro state machines that detectIt contains | ||
@@ -78,6 +73,4 @@ detectIt.state.detectHover; // see the detect-hover repo for more info | ||
```javascript | ||
/* | ||
* note that in the case of a legacy computer and browser, one that | ||
* doesn't support any of detect-it's detection tests, the default state will be: | ||
*/ | ||
// note that in the case of a legacy computer and browser, one that | ||
// doesn't support any of detect-it's detection tests, the default state will be: | ||
const detectIt = { | ||
@@ -88,11 +81,7 @@ deviceType: 'mouseOnly', | ||
hasTouch: false, | ||
maxTouchPoints: undefined, | ||
primaryHover: 'hover', | ||
primaryPointer: 'fine', | ||
primaryInput: 'mouse', | ||
} | ||
/* | ||
* note that in the case of a legacy touch device, one that supports the touch events api, | ||
* but not any of the other detection tests, the default state will be: | ||
*/ | ||
// note that in the case of a legacy touch device, one that supports the touch events api, | ||
// but not any of the other detection tests, the default state will be: | ||
const detectIt = { | ||
@@ -103,5 +92,3 @@ deviceType: 'touchOnly', | ||
hasTouch: true, | ||
maxTouchPoints: undefined, | ||
primaryHover: 'none', | ||
primaryPointer: 'coarse', | ||
primaryInput: 'touch', | ||
} | ||
@@ -141,15 +128,4 @@ ``` | ||
#### Using `detect-it` to adjust the user interface | ||
```javascript | ||
if (detectIt.primaryPointer === 'coarse') { | ||
// make clickable elements bigger | ||
} | ||
if (detectIt.primaryHover === 'hover') { | ||
// can add hover features | ||
} | ||
``` | ||
#### Real world example using `detect-it` | ||
- [`react-interactive`][reactInteractive] - a better interactive state machine than CSS | ||
- [React Interactive][reactInteractive] - a better interactive state machine than CSS | ||
@@ -176,14 +152,10 @@ ### Part of the `detect-it` family | ||
function determineDeviceType(hasTouch, anyHover, anyFine) { | ||
/* | ||
* A hybrid device is one that both hasTouch and any input device can hover | ||
* or has a fine pointer. | ||
*/ | ||
// A hybrid device is one that both hasTouch and any input device can hover | ||
// or has a fine pointer. | ||
if (hasTouch && (anyHover || anyFine)) return 'hybrid'; | ||
/* | ||
* In almost all cases a device that doesn’t support touch will have a mouse, | ||
* but there may be rare exceptions. Note that it doesn’t work to do additional tests | ||
* based on hover and pointer media queries as older browsers don’t support these. | ||
* Essentially, 'mouseOnly' is the default. | ||
*/ | ||
// In almost all cases a device that doesn’t support touch will have a mouse, | ||
// but there may be rare exceptions. Note that it doesn’t work to do additional tests | ||
// based on hover and pointer media queries as older browsers don’t support these. | ||
// Essentially, 'mouseOnly' is the default. | ||
return hasTouch ? 'touchOnly' : 'mouseOnly'; | ||
@@ -195,3 +167,3 @@ } | ||
- A touch capable Chromebook with Chrome browser registers that `hasTouch`, `anyHover`, and `anyFine` are all true. | ||
- The Galaxy Note with stylus running the Chrome mobile browser registers that `hasTouch` and `anyFine` are true, but that `anyHover` is false - as a side note I think that since the stylus hovers effectively, the Note should register as `anyHover` true, but for some reason it doesn't. | ||
- The Galaxy Note with stylus running the Chrome mobile browser registers that `hasTouch` and `anyFine` are true, but that `anyHover` is false. | ||
- The Microsoft Surface (and other Windows 10 touchscreen computers) | ||
@@ -214,2 +186,3 @@ - When using the Chrome browser, `hasTouch`, `anyHover` and `anyFine` are all true because Chrome supports the Touch Events API, so the device registers as a `hybrid`. | ||
[canIUsePointerEvents]: http://caniuse.com/#feat=pointer | ||
[w3cMediaQueriesSpecLatestHover]: https://www.w3.org/TR/mediaqueries-4/#hover | ||
@@ -219,5 +192,4 @@ [w3cMediaQueriesSpecLatestPointer]: https://www.w3.org/TR/mediaqueries-4/#pointer | ||
[w3cTouchEventsSpecLatest]: https://w3c.github.io/touch-events/ | ||
[mdnPointerEvents]: https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events | ||
[touchTests]: https://patrickhlauke.github.io/touch/ | ||
[passiveExplainer]: https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md |
@@ -26,15 +26,25 @@ import detectHover from 'detect-hover'; | ||
function determineDeviceType(hasTouch, anyHover, anyFine) { | ||
/* | ||
* A hybrid device is one that both hasTouch and any input device can hover | ||
* or has a fine pointer. | ||
*/ | ||
function determineDeviceType(hasTouch, anyHover, anyFine, state) { | ||
// A hybrid device is one that both hasTouch and any input device can hover | ||
// or has a fine pointer. | ||
if (hasTouch && (anyHover || anyFine)) return 'hybrid'; | ||
/* | ||
* In almost all cases a device that doesn’t support touch will have a mouse, | ||
* but there may be rare exceptions. Note that it doesn’t work to do additional tests | ||
* based on hover and pointer media queries as older browsers don’t support these. | ||
* Essentially, 'mouseOnly' is the default. | ||
*/ | ||
// workaround for browsers that have the touch events api, | ||
// and have implemented Level 4 media queries but not the | ||
// hover and pointer media queries, so the tests are all false (notable Firefox) | ||
// if it hasTouch, no pointer and hover support, and on an android assume it's touchOnly | ||
// if it hasTouch, no pointer and hover support, and not on an android assume it's a hybrid | ||
if (hasTouch && | ||
Object.keys(state.detectHover).filter(key => key !== 'update').every(key => state.detectHover[key] === false) && | ||
Object.keys(state.detectPointer).filter(key => key !== 'update').every(key => state.detectPointer[key] === false)) { | ||
if (window.navigator && /android/.test(window.navigator.userAgent.toLowerCase())) { | ||
return 'touchOnly'; | ||
} | ||
return 'hybrid'; | ||
} | ||
// In almost all cases a device that doesn’t support touch will have a mouse, | ||
// but there may be rare exceptions. Note that it doesn’t work to do additional tests | ||
// based on hover and pointer media queries as older browsers don’t support these. | ||
// Essentially, 'mouseOnly' is the default. | ||
return hasTouch ? 'touchOnly' : 'mouseOnly'; | ||
@@ -61,3 +71,3 @@ } | ||
detectIt.hasTouch = detectIt.state.detectTouchEvents.hasApi || false; | ||
detectIt.hasTouch = detectIt.state.detectTouchEvents.hasSupport || false; | ||
@@ -68,27 +78,16 @@ detectIt.deviceType = determineDeviceType( | ||
detectIt.state.detectPointer.anyFine, | ||
detectIt.state, | ||
); | ||
detectIt.hasMouse = detectIt.deviceType !== 'touchOnly'; | ||
detectIt.maxTouchPoints = detectIt.state.detectTouchEvents.maxTouchPoints; | ||
detectIt.primaryHover = | ||
(detectIt.state.detectHover.hover && 'hover') || | ||
(detectIt.state.detectHover.none && 'none') || | ||
// if it's a mouseOnly device that doesn't support level 4 media queries, | ||
// then assume it hovers | ||
(detectIt.deviceType === 'mouseOnly' && 'hover') || | ||
// if it's a touchOnly device that doesn't support level 4 media queries, | ||
// then assume it doesn't hover, otherwise it's undefined | ||
(detectIt.deviceType === 'touchOnly' && 'none') || undefined; | ||
detectIt.primaryPointer = | ||
(detectIt.state.detectPointer.fine && 'fine') || | ||
(detectIt.state.detectPointer.coarse && 'coarse') || | ||
(detectIt.state.detectPointer.none && 'none') || | ||
// if it's a mouseOnly device that doesn't support level 4 media queries, | ||
// then assume it has a fine pointer | ||
(detectIt.deviceType === 'mouseOnly' && 'fine') || | ||
// if it's a touchOnly device that doesn't support level 4 media queries, | ||
// then assume it has a coarse pointer, otherwise it's undefined | ||
(detectIt.deviceType === 'touchOnly' && 'coarse') || undefined; | ||
detectIt.primaryInput = | ||
(detectIt.deviceType === 'mouseOnly' && 'mouse') || | ||
(detectIt.deviceType === 'touchOnly' && 'touch') || | ||
// deviceType is hybrid: | ||
(detectIt.state.detectHover.hover && 'mouse') || | ||
(detectIt.state.detectHover.none && 'touch') || | ||
// if there's no support for hover media queries but detectIt determined it's | ||
// a hybrid device, then assume it's a mouse first device | ||
'mouse'; | ||
} | ||
@@ -95,0 +94,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
176
18316
185
+ Addeddetect-touch-events@2.0.2(transitive)
- Removeddetect-touch-events@1.0.1(transitive)
Updateddetect-touch-events@^2.0.0