Created
September 23, 2014 14:21
-
-
Save richtr/eda598ad98b11f5d7660 to your computer and use it in GitHub Desktop.
A reliable DeviceOrientation and DeviceMotion Events API feature detection library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* DeviceOrientation and DeviceMotion Events Detection API | |
* | |
* Example API Usage (Promise-based API): | |
* | |
* supportsDeviceOrientationEvents().then(function() { | |
* console.log("Platform DeviceOrientation Events support OK"); | |
* }, function(error) { | |
* console.error("Platform DeviceOrientation Events support KO"); | |
* }); | |
* | |
**/ | |
(function() { | |
var SENSOR_TYPE = [ | |
{ | |
name: "deviceorientation", | |
testPaths: [["alpha"]], | |
isSupported: undefined | |
}, | |
{ | |
name: "devicemotion", | |
testPaths: [["acceleration", "x"], ["accelerationIncludingGravity", "x"]], | |
isSupported: undefined | |
} | |
]; | |
function SensorCheck(sensor, successCallback, errorCallback) { | |
// We only need to run each sensor check once per page load | |
// so this is a neat performance optimization | |
if (sensor.isSupported === true) { | |
successCallback.call(this); | |
return; | |
} else if (sensor.isSupported === false) { | |
errorCallback.call(this); | |
return; | |
} | |
var e = {}; | |
var read = function(evt) { e = evt; }; | |
window.addEventListener(sensor.name, read, false); | |
var c = 0; | |
// Recursive IIFE sensor data checker | |
(function runCheck() { | |
setTimeout(function(){ | |
if (++c === 10) { // run test 10 times then time out | |
sensor.isSupported = false; | |
errorCallback.call(this); | |
window.removeEventListener(sensor.name, read, false); | |
return; | |
} | |
if (e === undefined || e === null) { | |
runCheck(); | |
return; | |
} | |
try { | |
// Test that all of the event object property paths | |
// are defined and not null | |
for (var i = 0, l = sensor.testPaths.length; i < l; i++) { | |
var testObj = e; | |
sensor.testPaths[i].forEach(function(val) { | |
testObj = testObj[val]; | |
if (testObj === undefined || testObj === null) { | |
runCheck(); | |
throw BreakException; | |
} | |
}); | |
} | |
sensor.isSupported = true; | |
successCallback.call(this); | |
window.removeEventListener(sensor.name, read, false); | |
} catch(e) {} | |
}, 100); | |
})(); | |
}; | |
// Add Sensor Test Promise APIs to DOM if they don't already exist | |
if (!window.supportsDeviceOrientationEvents) { | |
window.supportsDeviceOrientationEvents = function() { | |
return new Promise(function(resolve, reject) { | |
new SensorCheck(SENSOR_TYPE[0], resolve, reject); | |
}); | |
}; | |
} | |
if (!window.supportsDeviceMotionEvents) { | |
window.supportsDeviceMotionEvents = function() { | |
return new Promise(function(resolve, reject) { | |
new SensorCheck(SENSOR_TYPE[1], resolve, reject); | |
}); | |
}; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment