Last active
October 23, 2016 12:21
-
-
Save pixiebox/ee2074e2314da7d29d4f52d07eab5cd3 to your computer and use it in GitHub Desktop.
This file contains 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
(function () { | |
/** | |
* docElement is a convenience wrapper to grab the root element of the document | |
* | |
* @access private | |
* @returns {HTMLElement|SVGElement} The root element of the document | |
*/ | |
var docElement = document.documentElement; | |
/** | |
* A convenience helper to check if the document we are running in is an SVG document | |
* | |
* @access private | |
* @returns {boolean} | |
*/ | |
var isSVG = docElement.nodeName.toLowerCase() === 'svg'; | |
/** | |
* getBody returns the body of a document, or an element that can stand in for | |
* the body if a real body does not exist | |
* | |
* @access private | |
* @function getBody | |
* @returns {HTMLElement|SVGElement} Returns the real body of a document, or an | |
* artificially created element that stands in for the body | |
*/ | |
function getBody() { | |
// After page load injecting a fake body doesn't work so check if body exists | |
var body = document.body; | |
if (!body) { | |
// Can't use the real body create a fake one. | |
body = createElement(isSVG ? 'svg' : 'body'); | |
body.fake = true; | |
} | |
return body; | |
} | |
function createElement() { | |
if (typeof document.createElement !== 'function') { | |
// This is the case in IE7, where the type of createElement is "object". | |
// For this reason, we cannot call apply() as Object is not a Function. | |
return document.createElement(arguments[0]); | |
} else if (isSVG) { | |
return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]); | |
} else { | |
return document.createElement.apply(document, arguments); | |
} | |
} | |
function injectElementWithStyles(rule, callback, nodes, testnames) { | |
var mod = 'device'; | |
var style; | |
var ret; | |
var node; | |
var docOverflow; | |
var div = createElement('div'); | |
var body = getBody(); | |
if (parseInt(nodes, 10)) { | |
// In order not to give false positives we create a node for each test | |
// This also allows the method to scale for unspecified uses | |
while (nodes--) { | |
node = createElement('div'); | |
node.id = testnames ? testnames[nodes] : mod + (nodes + 1); | |
div.appendChild(node); | |
} | |
} | |
style = createElement('style'); | |
style.type = 'text/css'; | |
style.id = 's' + mod; | |
// IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody. | |
// Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270 | |
(!body.fake ? div : body).appendChild(style); | |
body.appendChild(div); | |
if (style.styleSheet) { | |
style.styleSheet.cssText = rule; | |
} else { | |
style.appendChild(document.createTextNode(rule)); | |
} | |
div.id = mod; | |
if (body.fake) { | |
//avoid crashing IE8, if background image is used | |
body.style.background = ''; | |
//Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible | |
body.style.overflow = 'hidden'; | |
docOverflow = docElement.style.overflow; | |
docElement.style.overflow = 'hidden'; | |
docElement.appendChild(body); | |
} | |
ret = callback(div, rule); | |
// If this is done after page load we don't want to remove the body so check if body exists | |
if (body.fake) { | |
body.parentNode.removeChild(body); | |
docElement.style.overflow = docOverflow; | |
// Trigger layout so kinetic scrolling isn't disabled in iOS6+ | |
docElement.offsetHeight; | |
} else { | |
div.parentNode.removeChild(div); | |
} | |
return !!ret; | |
} | |
function isTouch() { | |
var bool; | |
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' '); | |
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { | |
bool = true; | |
} else { | |
// include the 'heartz' as a way to have a non matching MQ to help terminate the join | |
// https://git.io/vznFH | |
var query = ['@media (', prefixes.join('touch-enabled),('), 'heartz', ')', '{#device{top:9px;position:absolute}}'].join(''); | |
injectElementWithStyles(query, function(node) { | |
bool = node.offsetTop === 9; | |
}); | |
} | |
return bool; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment