UNPKG

uix-kit

Version:

A free web kits for fast web design and development, compatible with Bootstrap v5.

1,680 lines (1,443 loc) 87.1 kB
/*! * modernizr v3.5.0 * Build https://modernizr.com/download?-addtest-atrule-domprefixes-hasevent-mq-prefixed-prefixedcss-prefixedcssvalue-prefixes-printshiv-setclasses-testallprops-testprop-teststyles-dontmin * * Copyright (c) * Faruk Ates * Paul Irish * Alex Sexton * Ryan Seddon * Patrick Kettner * Stu Cox * Richard Herrera * MIT License */ /* * Modernizr tests which native CSS3 and HTML5 features are available in the * current UA and makes the results available to you in two ways: as properties on * a global `Modernizr` object, and as classes on the `<html>` element. This * information allows you to progressively enhance your pages with a granular level * of control over the experience. */ /* //------ .no-svg .box { color: red; } .svg .box { color: green; } JS if (Modernizr.svg) { // supported } else { // not-supported } //------ .no-touchevents .box { color: red; } .touchevents .box { color: green; } JS if (Modernizr.touchevents) { // supported } else { // not-supported } //------ .no-webgl .box { color: red; } .webgl .box { color: green; } JS if (Modernizr.webgl) { // supported } else { // not-supported } //------ .no-websockets .box { color: red; } .websockets .box { color: green; } JS if (Modernizr.websockets) { // supported } else { // not-supported } //------ .no-canvas .box { color: red; } .canvas .box { color: green; } JS if (Modernizr.canvas) { // supported } else { // not-supported } //------ .no-ie8compat .box { color: red; } .ie8compat .box { color: green; } JS if (Modernizr.ie8compat) { // supported } else { // not-supported } //------ .no-cssanimations .box { color: red; } .cssanimations .box { color: green; } JS if (Modernizr.cssanimations) { // supported } else { // not-supported } //------- .no-csstransforms .box { color: red; } .csstransforms .box { color: green; } JS if (Modernizr.csstransforms) { // supported } else { // not-supported } //------- .no-csstransforms3d .box { color: red; } .csstransforms3d .box { color: green; } JS if (Modernizr.csstransforms3d) { // supported } else { // not-supported } //------- .no-csstransitions .box { color: red; } .csstransitions .box { color: green; } JS if (Modernizr.csstransitions) { // supported } else { // not-supported } //------- .no-cookies .box { color: red; } .cookies .box { color: green; } JS if (Modernizr.cookies) { // supported } else { // not-supported } //------- ES6... */ ;(function(window, document, undefined){ var classes = []; var tests = []; /** * * ModernizrProto is the constructor for Modernizr * * @class * @access public */ var ModernizrProto = { // The current version, dummy _version: '3.5.0', // Any settings that don't work as separate modules // can go in here as configuration. _config: { 'classPrefix': '', 'enableClasses': true, 'enableJSClass': true, 'usePrefixes': true }, // Queue of tests _q: [], // Stub these for people who are listening on: function(test, cb) { // I don't really think people should do this, but we can // safe guard it a bit. // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests. // This is in case people listen to synchronous tests. I would leave it out, // but the code to *disallow* sync tests in the real version of this // function is actually larger than this. var self = this; setTimeout(function() { cb(self[test]); }, 0); }, addTest: function(name, fn, options) { tests.push({name: name, fn: fn, options: options}); }, addAsyncTest: function(fn) { tests.push({name: null, fn: fn}); } }; // Fake some of Object.create so we can force non test results to be non "own" properties. var Modernizr = function() {}; Modernizr.prototype = ModernizrProto; // Leak modernizr globally when you `require` it rather than force it here. // Overwrite name so constructor name is nicer :D Modernizr = new Modernizr(); /*! { "name": "Cookies", "property": "cookies", "tags": ["storage"], "authors": ["tauren"] } !*/ /* DOC Detects whether cookie support is enabled. */ // https://github.com/Modernizr/Modernizr/issues/191 Modernizr.addTest('cookies', function() { // navigator.cookieEnabled cannot detect custom or nuanced cookie blocking // configurations. For example, when blocking cookies via the Advanced // Privacy Settings in IE9, it always returns true. And there have been // issues in the past with site-specific exceptions. // Don't rely on it. // try..catch because some in situations `document.cookie` is exposed but throws a // SecurityError if you try to access it; e.g. documents created from data URIs // or in sandboxed iframes (depending on flags/context) try { // Create cookie document.cookie = 'cookietest=1'; var ret = document.cookie.indexOf('cookietest=') != -1; // Delete cookie document.cookie = 'cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT'; return ret; } catch (e) { return false; } }); /*! { "name": "IE8 compat mode", "property": "ie8compat", "authors": ["Erich Ocean"] } !*/ /* DOC Detects whether or not the current browser is IE8 in compatibility mode (i.e. acting as IE7). */ // In this case, IE8 will be acting as IE7. You may choose to remove features in this case. // related: // james.padolsey.com/javascript/detect-ie-in-js-using-conditional-comments/ Modernizr.addTest('ie8compat', (!window.addEventListener && !!document.documentMode && document.documentMode === 7)); /*! { "name": "SVG", "property": "svg", "caniuse": "svg", "tags": ["svg"], "authors": ["Erik Dahlstrom"], "polyfills": [ "svgweb", "raphael", "amplesdk", "canvg", "svg-boilerplate", "sie", "dojogfx", "fabricjs" ] } !*/ /* DOC Detects support for SVG in `<embed>` or `<object>` elements. */ Modernizr.addTest('svg', !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect); /*! { "name": "WebSockets Support", "property": "websockets", "authors": ["Phread [fearphage]", "Mike Sherov [mikesherov]", "Burak Yigit Kaya [BYK]"], "caniuse": "websockets", "tags": ["html5"], "warnings": [ "This test will reject any old version of WebSockets even if it is not prefixed such as in Safari 5.1" ], "notes": [{ "name": "CLOSING State and Spec", "href": "https://www.w3.org/TR/websockets/#the-websocket-interface" }], "polyfills": [ "sockjs", "socketio", "kaazing-websocket-gateway", "websocketjs", "atmosphere", "graceful-websocket", "portal", "datachannel" ] } !*/ var supports = false; try { supports = 'WebSocket' in window && window.WebSocket.CLOSING === 2; } catch (e) {} Modernizr.addTest('websockets', supports); /*! { "name": "ES6 Array", "property": "es6array", "notes": [{ "name": "unofficial ECMAScript 6 draft specification", "href": "https://people.mozilla.org/~jorendorff/es6-draft.html" }], "polyfills": ["es6shim"], "authors": ["Ron Waldon (@jokeyrhyme)"], "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."], "tags": ["es6"] } !*/ /* DOC Check if browser implements ECMAScript 6 Array per specification. */ Modernizr.addTest('es6array', !!(Array.prototype && Array.prototype.copyWithin && Array.prototype.fill && Array.prototype.find && Array.prototype.findIndex && Array.prototype.keys && Array.prototype.entries && Array.prototype.values && Array.from && Array.of)); /*! { "name": "ES6 Arrow Functions", "property": "arrow", "authors": ["Vincent Riemer"], "tags": ["es6"] } !*/ /* DOC Check if browser implements ECMAScript 6 Arrow Functions per specification. */ Modernizr.addTest('arrow', function() { try { // eslint-disable-next-line eval('()=>{}'); } catch (e) { return false; } return true; }); /*! { "name": "ES6 Collections", "property": "es6collections", "notes": [{ "name": "unofficial ECMAScript 6 draft specification", "href": "https://people.mozilla.org/~jorendorff/es6-draft.html" }], "polyfills": ["es6shim", "weakmap"], "authors": ["Ron Waldon (@jokeyrhyme)"], "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."], "tags": ["es6"] } !*/ /* DOC Check if browser implements ECMAScript 6 Map, Set, WeakMap and WeakSet */ Modernizr.addTest('es6collections', !!( window.Map && window.Set && window.WeakMap && window.WeakSet )); /*! { "name": "ES6 Generators", "property": "generators", "authors": ["Michael Kachanovskyi"], "tags": ["es6"] } !*/ /* DOC Check if browser implements ECMAScript 6 Generators per specification. */ Modernizr.addTest('generators', function() { try { new Function('function* test() {}')(); } catch (e) { return false; } return true; }); /*! { "name": "ES6 Math", "property": "es6math", "notes": [{ "name": "unofficial ECMAScript 6 draft specification", "href": "https://people.mozilla.org/~jorendorff/es6-draft.html" }], "polyfills": ["es6shim"], "authors": ["Ron Waldon (@jokeyrhyme)"], "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."], "tags": ["es6"] } !*/ /* DOC Check if browser implements ECMAScript 6 Math per specification. */ Modernizr.addTest('es6math', !!(Math && Math.clz32 && Math.cbrt && Math.imul && Math.sign && Math.log10 && Math.log2 && Math.log1p && Math.expm1 && Math.cosh && Math.sinh && Math.tanh && Math.acosh && Math.asinh && Math.atanh && Math.hypot && Math.trunc && Math.fround)); /*! { "name": "ES6 Number", "property": "es6number", "notes": [{ "name": "unofficial ECMAScript 6 draft specification", "href": "https://people.mozilla.org/~jorendorff/es6-draft.html" }], "polyfills": ["es6shim"], "authors": ["Ron Waldon (@jokeyrhyme)"], "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."], "tags": ["es6"] } !*/ /* DOC Check if browser implements ECMAScript 6 Number per specification. */ Modernizr.addTest('es6number', !!(Number.isFinite && Number.isInteger && Number.isSafeInteger && Number.isNaN && Number.parseInt && Number.parseFloat && Number.isInteger(Number.MAX_SAFE_INTEGER) && Number.isInteger(Number.MIN_SAFE_INTEGER) && Number.isFinite(Number.EPSILON))); /*! { "name": "ES6 Object", "property": "es6object", "notes": [{ "name": "unofficial ECMAScript 6 draft specification", "href": "https://people.mozilla.org/~jorendorff/es6-draft.html" }], "polyfills": ["es6shim"], "authors": ["Ron Waldon (@jokeyrhyme)"], "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."], "tags": ["es6"] } !*/ /* DOC Check if browser implements ECMAScript 6 Object per specification. */ Modernizr.addTest('es6object', !!(Object.assign && Object.is && Object.setPrototypeOf)); /*! { "name": "ES6 Promises", "property": "promises", "caniuse": "promises", "polyfills": ["es6promises"], "authors": ["Krister Kari", "Jake Archibald"], "tags": ["es6"], "notes": [{ "name": "The ES6 promises spec", "href": "https://github.com/domenic/promises-unwrapping" },{ "name": "Chromium dashboard - ES6 Promises", "href": "https://www.chromestatus.com/features/5681726336532480" },{ "name": "JavaScript Promises: There and back again - HTML5 Rocks", "href": "http://www.html5rocks.com/en/tutorials/es6/promises/" }] } !*/ /* DOC Check if browser implements ECMAScript 6 Promises per specification. */ Modernizr.addTest('promises', function() { return 'Promise' in window && // Some of these methods are missing from // Firefox/Chrome experimental implementations 'resolve' in window.Promise && 'reject' in window.Promise && 'all' in window.Promise && 'race' in window.Promise && // Older version of the spec had a resolver object // as the arg rather than a function (function() { var resolve; new window.Promise(function(r) { resolve = r; }); return typeof resolve === 'function'; }()); }); /*! { "name": "ES6 String", "property": "es6string", "notes": [{ "name": "unofficial ECMAScript 6 draft specification", "href": "https://people.mozilla.org/~jorendorff/es6-draft.html" }], "polyfills": ["es6shim"], "authors": ["Ron Waldon (@jokeyrhyme)"], "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."], "tags": ["es6"] } !*/ /* DOC Check if browser implements ECMAScript 6 String per specification. */ Modernizr.addTest('es6string', !!(String.fromCodePoint && String.raw && String.prototype.codePointAt && String.prototype.repeat && String.prototype.startsWith && String.prototype.endsWith && String.prototype.includes)); /** * List of property values to set for css tests. See ticket #21 * http://git.io/vUGl4 * * @memberof Modernizr * @name Modernizr._prefixes * @optionName Modernizr._prefixes * @optionProp prefixes * @access public * @example * * Modernizr._prefixes is the internal list of prefixes that we test against * inside of things like [prefixed](#modernizr-prefixed) and [prefixedCSS](#-code-modernizr-prefixedcss). It is simply * an array of kebab-case vendor prefixes you can use within your code. * * Some common use cases include * * Generating all possible prefixed version of a CSS property * ```js * var rule = Modernizr._prefixes.join('transform: rotate(20deg); '); * * rule === 'transform: rotate(20deg); webkit-transform: rotate(20deg); moz-transform: rotate(20deg); o-transform: rotate(20deg); ms-transform: rotate(20deg);' * ``` * * Generating all possible prefixed version of a CSS value * ```js * rule = 'display:' + Modernizr._prefixes.join('flex; display:') + 'flex'; * * rule === 'display:flex; display:-webkit-flex; display:-moz-flex; display:-o-flex; display:-ms-flex; display:flex' * ``` */ // we use ['',''] rather than an empty array in order to allow a pattern of .`join()`ing prefixes to test // values in feature detects to continue to work var prefixes = (ModernizrProto._config.usePrefixes ? ' -webkit- -moz- -o- -ms- '.split(' ') : ['','']); // expose these for the plugin API. Look in the source for how to join() them against your input ModernizrProto._prefixes = prefixes; /** * is returns a boolean if the typeof an obj is exactly type. * * @access private * @function is * @param {*} obj - A thing we want to check the type of * @param {string} type - A string to compare the typeof against * @returns {boolean} */ function is(obj, type) { return typeof obj === type; } ; /** * Run through all tests and detect their support in the current UA. * * @access private */ function testRunner() { var featureNames; var feature; var aliasIdx; var result; var nameIdx; var featureName; var featureNameSplit; for (var featureIdx in tests) { if (tests.hasOwnProperty(featureIdx)) { featureNames = []; feature = tests[featureIdx]; // run the test, throw the return value into the Modernizr, // then based on that boolean, define an appropriate className // and push it into an array of classes we'll join later. // // If there is no name, it's an 'async' test that is run, // but not directly added to the object. That should // be done with a post-run addTest call. if (feature.name) { featureNames.push(feature.name.toLowerCase()); if (feature.options && feature.options.aliases && feature.options.aliases.length) { // Add all the aliases into the names list for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) { featureNames.push(feature.options.aliases[aliasIdx].toLowerCase()); } } } // Run the test, or use the raw value if it's not a function result = is(feature.fn, 'function') ? feature.fn() : feature.fn; // Set each of the names on the Modernizr object for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) { featureName = featureNames[nameIdx]; // Support dot properties as sub tests. We don't do checking to make sure // that the implied parent tests have been added. You must call them in // order (either in the test, or make the parent test a dependency). // // Cap it to TWO to make the logic simple and because who needs that kind of subtesting // hashtag famous last words featureNameSplit = featureName.split('.'); if (featureNameSplit.length === 1) { Modernizr[featureNameSplit[0]] = result; } else { // cast to a Boolean, if not one already if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) { Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]); } Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result; } classes.push((result ? '' : 'no-') + featureNameSplit.join('-')); } } } } ; /** * 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'; /** * setClasses takes an array of class names and adds them to the root element * * @access private * @function setClasses * @param {string[]} classes - Array of class names */ // Pass in an and array of class names, e.g.: // ['no-webp', 'borderradius', ...] function setClasses(classes) { var className = docElement.className; var classPrefix = Modernizr._config.classPrefix || ''; if (isSVG) { className = className.baseVal; } // Change `no-js` to `js` (independently of the `enableClasses` option) // Handle classPrefix on this too if (Modernizr._config.enableJSClass) { var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)'); className = className.replace(reJS, '$1' + classPrefix + 'js$2'); } if (Modernizr._config.enableClasses) { // Add the new classes className += ' ' + classPrefix + classes.join(' ' + classPrefix); if (isSVG) { docElement.className.baseVal = className; } else { docElement.className = className; } } } ; /** * @optionName html5printshiv * @optionProp html5printshiv */ // Take the html5 variable out of the html5shiv scope so we can return it. var html5; if (!isSVG) { /** * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed */ ;(function(window, document) { /** version */ var version = '3.7.3'; /** Preset options */ var options = window.html5 || {}; /** Used to skip problem elements */ var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; /** Not all elements can be cloned in IE **/ var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; /** Detect whether the browser supports default html5 styles */ var supportsHtml5Styles; /** Name of the expando, to work with multiple documents or to re-shiv one document */ var expando = '_html5shiv'; /** The id for the the documents expando */ var expanID = 0; /** Cached data for each document */ var expandoData = {}; /** Detect whether the browser supports unknown elements */ var supportsUnknownElements; (function() { try { var a = document.createElement('a'); a.innerHTML = '<xyz></xyz>'; //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles supportsHtml5Styles = ('hidden' in a); supportsUnknownElements = a.childNodes.length == 1 || (function() { // assign a false positive if unable to shiv (document.createElement)('a'); var frag = document.createDocumentFragment(); return ( typeof frag.cloneNode == 'undefined' || typeof frag.createDocumentFragment == 'undefined' || typeof frag.createElement == 'undefined' ); }()); } catch(e) { // assign a false positive if detection fails => unable to shiv supportsHtml5Styles = true; supportsUnknownElements = true; } }()); /*--------------------------------------------------------------------------*/ /** * Creates a style sheet with the given CSS text and adds it to the document. * @private * @param {Document} ownerDocument The document. * @param {String} cssText The CSS text. * @returns {StyleSheet} The style element. */ function addStyleSheet(ownerDocument, cssText) { var p = ownerDocument.createElement('p'), parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; p.innerHTML = 'x<style>' + cssText + '</style>'; return parent.insertBefore(p.lastChild, parent.firstChild); } /** * Returns the value of `html5.elements` as an array. * @private * @returns {Array} An array of shived element node names. */ function getElements() { var elements = html5.elements; return typeof elements == 'string' ? elements.split(' ') : elements; } /** * Extends the built-in list of html5 elements * @memberOf html5 * @param {String|Array} newElements whitespace separated list or array of new element names to shiv * @param {Document} ownerDocument The context document. */ function addElements(newElements, ownerDocument) { var elements = html5.elements; if(typeof elements != 'string'){ elements = elements.join(' '); } if(typeof newElements != 'string'){ newElements = newElements.join(' '); } html5.elements = elements +' '+ newElements; shivDocument(ownerDocument); } /** * Returns the data associated to the given document * @private * @param {Document} ownerDocument The document. * @returns {Object} An object of data. */ function getExpandoData(ownerDocument) { var data = expandoData[ownerDocument[expando]]; if (!data) { data = {}; expanID++; ownerDocument[expando] = expanID; expandoData[expanID] = data; } return data; } /** * returns a shived element for the given nodeName and document * @memberOf html5 * @param {String} nodeName name of the element * @param {Document} ownerDocument The context document. * @returns {Object} The shived element. */ function createElement(nodeName, ownerDocument, data){ if (!ownerDocument) { ownerDocument = document; } if(supportsUnknownElements){ return ownerDocument.createElement(nodeName); } if (!data) { data = getExpandoData(ownerDocument); } var node; if (data.cache[nodeName]) { node = data.cache[nodeName].cloneNode(); } else if (saveClones.test(nodeName)) { node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); } else { node = data.createElem(nodeName); } // Avoid adding some elements to fragments in IE < 9 because // * Attributes like `name` or `type` cannot be set/changed once an element // is inserted into a document/fragment // * Link elements with `src` attributes that are inaccessible, as with // a 403 response, will cause the tab/window to crash // * Script elements appended to fragments will execute when their `src` // or `text` property is set return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node; } /** * returns a shived DocumentFragment for the given document * @memberOf html5 * @param {Document} ownerDocument The context document. * @returns {Object} The shived DocumentFragment. */ function createDocumentFragment(ownerDocument, data){ if (!ownerDocument) { ownerDocument = document; } if(supportsUnknownElements){ return ownerDocument.createDocumentFragment(); } data = data || getExpandoData(ownerDocument); var clone = data.frag.cloneNode(), i = 0, elems = getElements(), l = elems.length; for(;i<l;i++){ clone.createElement(elems[i]); } return clone; } /** * Shivs the `createElement` and `createDocumentFragment` methods of the document. * @private * @param {Document|DocumentFragment} ownerDocument The document. * @param {Object} data of the document. */ function shivMethods(ownerDocument, data) { if (!data.cache) { data.cache = {}; data.createElem = ownerDocument.createElement; data.createFrag = ownerDocument.createDocumentFragment; data.frag = data.createFrag(); } ownerDocument.createElement = function(nodeName) { //abort shiv if (!html5.shivMethods) { return data.createElem(nodeName); } return createElement(nodeName, ownerDocument, data); }; ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + 'var n=f.cloneNode(),c=n.createElement;' + 'h.shivMethods&&(' + // unroll the `createElement` calls getElements().join().replace(/[\w\-:]+/g, function(nodeName) { data.createElem(nodeName); data.frag.createElement(nodeName); return 'c("' + nodeName + '")'; }) + ');return n}' )(html5, data.frag); } /*--------------------------------------------------------------------------*/ /** * Shivs the given document. * @memberOf html5 * @param {Document} ownerDocument The document to shiv. * @returns {Document} The shived document. */ function shivDocument(ownerDocument) { if (!ownerDocument) { ownerDocument = document; } var data = getExpandoData(ownerDocument); if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) { data.hasCSS = !!addStyleSheet(ownerDocument, // corrects block display not defined in IE6/7/8/9 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' + // adds styling not present in IE6/7/8/9 'mark{background:#FF0;color:#000}' + // hides non-rendered elements 'template{display:none}' ); } if (!supportsUnknownElements) { shivMethods(ownerDocument, data); } return ownerDocument; } /*--------------------------------------------------------------------------*/ /** * The `html5` object is exposed so that more elements can be shived and * existing shiving can be detected on iframes. * @type Object * @example * * // options can be changed before the script is included * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false }; */ var html5 = { /** * An array or space separated string of node names of the elements to shiv. * @memberOf html5 * @type Array|String */ 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video', /** * current version of html5shiv */ 'version': version, /** * A flag to indicate that the HTML5 style sheet should be inserted. * @memberOf html5 * @type Boolean */ 'shivCSS': (options.shivCSS !== false), /** * Is equal to true if a browser supports creating unknown/HTML5 elements * @memberOf html5 * @type boolean */ 'supportsUnknownElements': supportsUnknownElements, /** * A flag to indicate that the document's `createElement` and `createDocumentFragment` * methods should be overwritten. * @memberOf html5 * @type Boolean */ 'shivMethods': (options.shivMethods !== false), /** * A string to describe the type of `html5` object ("default" or "default print"). * @memberOf html5 * @type String */ 'type': 'default', // shivs the document according to the specified `html5` object options 'shivDocument': shivDocument, //creates a shived element createElement: createElement, //creates a shived documentFragment createDocumentFragment: createDocumentFragment, //extends list of elements addElements: addElements }; /*--------------------------------------------------------------------------*/ // expose html5 window.html5 = html5; // shiv the document shivDocument(document); /*------------------------------- Print Shiv -------------------------------*/ /** Used to filter media types */ var reMedia = /^$|\b(?:all|print)\b/; /** Used to namespace printable elements */ var shivNamespace = 'html5shiv'; /** Detect whether the browser supports shivable style sheets */ var supportsShivableSheets = !supportsUnknownElements && (function() { // assign a false negative if unable to shiv var docEl = document.documentElement; return !( typeof document.namespaces == 'undefined' || typeof document.parentWindow == 'undefined' || typeof docEl.applyElement == 'undefined' || typeof docEl.removeNode == 'undefined' || typeof window.attachEvent == 'undefined' ); }()); /*--------------------------------------------------------------------------*/ /** * Wraps all HTML5 elements in the given document with printable elements. * (eg. the "header" element is wrapped with the "html5shiv:header" element) * @private * @param {Document} ownerDocument The document. * @returns {Array} An array wrappers added. */ function addWrappers(ownerDocument) { var node, nodes = ownerDocument.getElementsByTagName('*'), index = nodes.length, reElements = RegExp('^(?:' + getElements().join('|') + ')$', 'i'), result = []; while (index--) { node = nodes[index]; if (reElements.test(node.nodeName)) { result.push(node.applyElement(createWrapper(node))); } } return result; } /** * Creates a printable wrapper for the given element. * @private * @param {Element} element The element. * @returns {Element} The wrapper. */ function createWrapper(element) { var node, nodes = element.attributes, index = nodes.length, wrapper = element.ownerDocument.createElement(shivNamespace + ':' + element.nodeName); // copy element attributes to the wrapper while (index--) { node = nodes[index]; node.specified && wrapper.setAttribute(node.nodeName, node.nodeValue); } // copy element styles to the wrapper wrapper.style.cssText = element.style.cssText; return wrapper; } /** * Shivs the given CSS text. * (eg. header{} becomes html5shiv\:header{}) * @private * @param {String} cssText The CSS text to shiv. * @returns {String} The shived CSS text. */ function shivCssText(cssText) { var pair, parts = cssText.split('{'), index = parts.length, reElements = RegExp('(^|[\\s,>+~])(' + getElements().join('|') + ')(?=[[\\s,>+~#.:]|$)', 'gi'), replacement = '$1' + shivNamespace + '\\:$2'; while (index--) { pair = parts[index] = parts[index].split('}'); pair[pair.length - 1] = pair[pair.length - 1].replace(reElements, replacement); parts[index] = pair.join('}'); } return parts.join('{'); } /** * Removes the given wrappers, leaving the original elements. * @private * @params {Array} wrappers An array of printable wrappers. */ function removeWrappers(wrappers) { var index = wrappers.length; while (index--) { wrappers[index].removeNode(); } } /*--------------------------------------------------------------------------*/ /** * Shivs the given document for print. * @memberOf html5 * @param {Document} ownerDocument The document to shiv. * @returns {Document} The shived document. */ function shivPrint(ownerDocument) { var shivedSheet, wrappers, data = getExpandoData(ownerDocument), namespaces = ownerDocument.namespaces, ownerWindow = ownerDocument.parentWindow; if (!supportsShivableSheets || ownerDocument.printShived) { return ownerDocument; } if (typeof namespaces[shivNamespace] == 'undefined') { namespaces.add(shivNamespace); } function removeSheet() { clearTimeout(data._removeSheetTimer); if (shivedSheet) { shivedSheet.removeNode(true); } shivedSheet= null; } ownerWindow.attachEvent('onbeforeprint', function() { removeSheet(); var imports, length, sheet, collection = ownerDocument.styleSheets, cssText = [], index = collection.length, sheets = Array(index); // convert styleSheets collection to an array while (index--) { sheets[index] = collection[index]; } // concat all style sheet CSS text while ((sheet = sheets.pop())) { // IE does not enforce a same origin policy for external style sheets... // but has trouble with some dynamically created stylesheets if (!sheet.disabled && reMedia.test(sheet.media)) { try { imports = sheet.imports; length = imports.length; } catch(er){ length = 0; } for (index = 0; index < length; index++) { sheets.push(imports[index]); } try { cssText.push(sheet.cssText); } catch(er){} } } // wrap all HTML5 elements with printable elements and add the shived style sheet cssText = shivCssText(cssText.reverse().join('')); wrappers = addWrappers(ownerDocument); shivedSheet = addStyleSheet(ownerDocument, cssText); }); ownerWindow.attachEvent('onafterprint', function() { // remove wrappers, leaving the original elements, and remove the shived style sheet removeWrappers(wrappers); clearTimeout(data._removeSheetTimer); data._removeSheetTimer = setTimeout(removeSheet, 500); }); ownerDocument.printShived = true; return ownerDocument; } /*--------------------------------------------------------------------------*/ // expose API html5.type += ' print'; html5.shivPrint = shivPrint; // shiv for print shivPrint(document); if(typeof module == 'object' && module.exports){ module.exports = html5; } }(typeof window !== 'undefined' ? window : this, document)); } ; /** * createElement is a convenience wrapper around document.createElement. Since we * use createElement all over the place, this allows for (slightly) smaller code * as well as abstracting away issues with creating elements in contexts other than * HTML documents (e.g. SVG documents). * * @access private * @function createElement * @returns {HTMLElement|SVGElement} An HTML or SVG element */ 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); } } ; /*! { "name": "Canvas", "property": "canvas", "caniuse": "canvas", "tags": ["canvas", "graphics"], "polyfills": ["flashcanvas", "excanvas", "slcanvas", "fxcanvas"] } !*/ /* DOC Detects support for the `<canvas>` element for 2D drawing. */ // On the S60 and BB Storm, getContext exists, but always returns undefined // so we actually have to call getContext() to verify // github.com/Modernizr/Modernizr/issues/issue/97/ Modernizr.addTest('canvas', function() { var elem = createElement('canvas'); return !!(elem.getContext && elem.getContext('2d')); }); /*! { "name": "WebGL", "property": "webgl", "caniuse": "webgl", "tags": ["webgl", "graphics"], "polyfills": ["jebgl", "cwebgl", "iewebgl"] } !*/ Modernizr.addTest('webgl', function() { var canvas = createElement('canvas'); var supports = 'probablySupportsContext' in canvas ? 'probablySupportsContext' : 'supportsContext'; if (supports in canvas) { return canvas[supports]('webgl') || canvas[supports]('experimental-webgl'); } return 'WebGLRenderingContext' in window; }); /** * Modernizr.hasEvent() detects support for a given event * * @memberof Modernizr * @name Modernizr.hasEvent * @optionName Modernizr.hasEvent() * @optionProp hasEvent * @access public * @function hasEvent * @param {string|*} eventName - the name of an event to test for (e.g. "resize") * @param {Element|string} [element=HTMLDivElement] - is the element|document|window|tagName to test on * @returns {boolean} * @example * `Modernizr.hasEvent` lets you determine if the browser supports a supplied event. * By default, it does this detection on a div element * * ```js * hasEvent('blur') // true; * ``` * * However, you are able to give an object as a second argument to hasEvent to * detect an event on something other than a div. * * ```js * hasEvent('devicelight', window) // true; * ``` * */ var hasEvent = (function() { // Detect whether event support can be detected via `in`. Test on a DOM element // using the "blur" event b/c it should always exist. bit.ly/event-detection var needsFallback = !('onblur' in document.documentElement); function inner(eventName, element) { var isSupported; if (!eventName) { return false; } if (!element || typeof element === 'string') { element = createElement(element || 'div'); } // Testing via the `in` operator is sufficient for modern browsers and IE. // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and // "resize", whereas `in` "catches" those. eventName = 'on' + eventName; isSupported = eventName in element; // Fallback technique for old Firefox - bit.ly/event-detection if (!isSupported && needsFallback) { if (!element.setAttribute) { // Switch to generic element if it lacks `setAttribute`. // It could be the `document`, `window`, or something else. element = createElement('div'); } element.setAttribute(eventName, ''); isSupported = typeof element[eventName] === 'function'; if (element[eventName] !== undefined) { // If property was created, "remove it" by setting value to `undefined`. element[eventName] = undefined; } element.removeAttribute(eventName); } return isSupported; } return inner; })(); ModernizrProto.hasEvent = hasEvent; /*! { "name": "CSS Supports", "property": "supports", "caniuse": "css-featurequeries", "tags": ["css"], "builderAliases": ["css_supports"], "notes": [{ "name": "W3 Spec", "href": "http://dev.w3.org/csswg/css3-conditional/#at-supports" },{ "name": "Related Github Issue", "href": "https://github.com/Modernizr/Modernizr/issues/648" },{ "name": "W3 Info", "href": "http://dev.w3.org/csswg/css3-conditional/#the-csssupportsrule-interface" }] } !*/ var newSyntax = 'CSS' in window && 'supports' in window.CSS; var oldSyntax = 'supportsCSS' in window; Modernizr.addTest('supports', newSyntax || oldSyntax); /** * If the browsers follow the spec, then they would expose vendor-specific styles as: * elem.style.WebkitBorderRadius * instead of something like the following (which is technically incorrect): * elem.style.webkitBorderRadius * WebKit ghosts their properties in lowercase but Opera & Moz do not. * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+ * erik.eae.net/archives/2008/03/10/21.48.10/ * More here: github.com/Modernizr/Modernizr/issues/issue/21 * * @access private * @returns {string} The string representing the vendor-specific style properties */ var omPrefixes = 'Moz O ms Webkit'; /** * List of JavaScript DOM values used for tests * * @memberof Modernizr * @name Modernizr._domPrefixes * @optionName Modernizr._domPrefixes * @optionProp domPrefixes * @access public * @example * * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather * than kebab-case properties, all properties are their Capitalized variant * * ```js * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ]; * ``` */ var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []); ModernizrProto._domPrefixes = domPrefixes; /** * prefixedCSSValue is a way test for prefixed css properties (e.g. display: -webkit-flex) * * @memberof Modernizr * @name Modernizr.prefixedCSSValue * @optionName Modernizr.prefixedCSSValue() * @optionProp prefixedCSSValue * @access public * @function prefixedCSSValue * @param {string} prop - String name of the property to test for * @param {string} value - String value of the non prefixed version of the value you want to test for * @returns {string|false} The string representing the (possibly prefixed) * valid version of the property, or `false` when it is unsupported. * @example * * `Modernizr.prefixedCSSValue` is a way test for prefixed css properties (e.g. display: -webkit-flex) * * ```js * Modernizr.prefixedCSSValue('background', 'linear-gradient(left, red, red)') * ``` * */ var prefixedCSSValue = function(prop, value) { var result = false; var elem = createElement('div'); var style = elem.style; if (prop in style) { var i = domPrefixes.length; style[prop] = value; result = style[prop]; while (i-- && !result) { style[prop] = '-' + domPrefixes[i] + '-' + value; result = style[prop]; } } if (result === '') { result = false; } return result; }; ModernizrProto.prefixedCSSValue = prefixedCSSValue; /** * hasOwnProp is a shim for hasOwnProperty that is needed for Safari 2.0 support * * @author kangax * @access private * @function hasOwnProp * @param {object} object - The object to check for a property * @param {string} property - The property to check for * @returns {boolean} */ // hasOwnProperty shim by kangax needed for Safari 2.0 support var hasOwnProp; (function() { var _hasOwnProperty = ({}).hasOwnProperty; /* istanbul ignore else */ /* we have no way of testing IE 5.5 or safari 2, * so just assume the else gets hit */ if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) { hasOwnProp = function(object, property) { return _hasOwnProperty.call(object, property); }; } else { hasOwnProp = function(object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */ return ((property in object) && is(object.constructor.prototype[property], 'undefined')); }; } })(); // _l tracks listeners for async tests, as well as tests that execute after the initial run ModernizrProto._l = {}; /** * Modernizr.on is a way to listen for the completion of async tests. Being * asynchronous, they may not finish before your scripts run. As a result you * will get a possibly false negative `undefined` value. * * @memberof Modernizr * @name Modernizr.on * @access public * @function on * @param {string} feature - String name of the feature detect * @param {function} cb - Callback function returning a Boolean - true if feature is supported, false if not * @example * * ```js * Modernizr.on('flash', function( result ) { * if (result) { * // the browser has flash * } else { * // the browser does not have flash * } * }); * ``` */ ModernizrProto.on = function(feature, cb) { // Create the list of listeners if it doesn't exist if (!this._l[feature]) { this._l[feature] = []; } // Push this test on to the listener list this._l[feature].push(cb); // If it's already been resolved, trigger it on next tick if (Modernizr.hasOwnProperty(feature)) { // Next Tick setTimeout(function() { Modernizr._trigger(feature, Modernizr[feature]); }, 0); } }; /** * _trigger is the private function used to signal test completion and run any * callbacks registered through [Modernizr.on](#modernizr-on) * * @memberof Modernizr * @name Modernizr._trigger * @access private * @function _trigger * @param {string} feature - string name of the feature detect * @param {function|boolean} [res] - A feature detection function, or the boolean = * result of a feature detection function */ ModernizrProto._trigger = function(feature, res) { if (!this._l[feature]) { return; } var cbs = this._l[feature]; // Force async setTimeout(function() { var i, cb; for (i = 0; i < cbs.length; i++) { cb = cbs[i]; cb(res); } }, 0); // Don't trigger these again delete this._l[feature]; }; /** * addTest allows you to define your own feature detects that are not currently * included in Modernizr (under the covers it's the exact same code Modernizr * uses for its own [feature detections](https://github.com/Modernizr/Modernizr/tree/master/feature-detects)). Just like the offical detects, the result * will be added onto the Modernizr object, as well as an appropriate className set on * the html element when configured to do so * * @memberof Modernizr * @name Modernizr.addTest * @optionName Modernizr.addTest() * @optionProp addTest * @access public * @function addTest * @param {string|object}