123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554 |
- /*!
- * modernizr v3.7.0
- * Build https://modernizr.com/download?-cors-input-smil-addtest-printshiv-setclasses-testprop-dontmin-cssclassprefix:prefixed-
- *
- * 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.
- */
- ;(function(window, document, undefined){
- var tests = [];
-
- /**
- * ModernizrProto is the constructor for Modernizr
- *
- * @class
- * @access public
- */
- var ModernizrProto = {
- // The current version, dummy
- _version: '3.7.0',
- // Any settings that don't work as separate modules
- // can go in here as configuration.
- _config: {
- 'classPrefix': 'prefixed-',
- '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();
-
- var classes = [];
-
- /**
- * 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} true if the typeof the first parameter is exactly the specified type, false otherwise
- */
- function is(obj, type) {
- return typeof obj === type;
- }
- ;
- /**
- * Run through all tests and detect their support in the current UA.
- *
- * @access private
- * @returns {void}
- */
- 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
- if (classes.length > 0) {
- className += ' ' + classPrefix + classes.join(' ' + classPrefix);
- }
- if (isSVG) {
- docElement.className.baseVal = className;
- } else {
- docElement.className = className;
- }
- }
- }
- ;
- /**
- * 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
- * @returns {void}
- * @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
- * @returns {void}
- */
- 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 official 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} feature - The string name of the feature detect, or an
- * object of feature detect names and test
- * @param {Function|boolean} test - Function returning true if feature is supported,
- * false if not. Otherwise a boolean representing the results of a feature detection
- * @returns {Object} the Modernizr object to allow chaining
- * @example
- *
- * The most common way of creating your own feature detects is by calling
- * `Modernizr.addTest` with a string (preferably just lowercase, without any
- * punctuation), and a function you want executed that will return a boolean result
- *
- * ```js
- * Modernizr.addTest('itsTuesday', function() {
- * var d = new Date();
- * return d.getDay() === 2;
- * });
- * ```
- *
- * When the above is run, it will set Modernizr.itstuesday to `true` when it is tuesday,
- * and to `false` every other day of the week. One thing to notice is that the names of
- * feature detect functions are always lowercased when added to the Modernizr object. That
- * means that `Modernizr.itsTuesday` will not exist, but `Modernizr.itstuesday` will.
- *
- *
- * Since we only look at the returned value from any feature detection function,
- * you do not need to actually use a function. For simple detections, just passing
- * in a statement that will return a boolean value works just fine.
- *
- * ```js
- * Modernizr.addTest('hasjquery', 'jQuery' in window);
- * ```
- *
- * Just like before, when the above runs `Modernizr.hasjquery` will be true if
- * jQuery has been included on the page. Not using a function saves a small amount
- * of overhead for the browser, as well as making your code much more readable.
- *
- * Finally, you also have the ability to pass in an object of feature names and
- * their tests. This is handy if you want to add multiple detections in one go.
- * The keys should always be a string, and the value can be either a boolean or
- * function that returns a boolean.
- *
- * ```js
- * var detects = {
- * 'hasjquery': 'jQuery' in window,
- * 'itstuesday': function() {
- * var d = new Date();
- * return d.getDay() === 2;
- * }
- * }
- *
- * Modernizr.addTest(detects);
- * ```
- *
- * There is really no difference between the first methods and this one, it is
- * just a convenience to let you write more readable code.
- */
- function addTest(feature, test) {
- if (typeof feature === 'object') {
- for (var key in feature) {
- if (hasOwnProp(feature, key)) {
- addTest(key, feature[ key ]);
- }
- }
- } else {
- feature = feature.toLowerCase();
- var featureNameSplit = feature.split('.');
- var last = Modernizr[featureNameSplit[0]];
- // Again, we don't check for parent test existence. Get that right, though.
- if (featureNameSplit.length === 2) {
- last = last[featureNameSplit[1]];
- }
- if (typeof last !== 'undefined') {
- // we're going to quit if you're trying to overwrite an existing test
- // if we were to allow it, we'd do this:
- // var re = new RegExp("\\b(no-)?" + feature + "\\b");
- // docElement.className = docElement.className.replace( re, '' );
- // but, no rly, stuff 'em.
- return Modernizr;
- }
- test = typeof test === 'function' ? test() : test;
- // Set the value (this is the magic, right here).
- if (featureNameSplit.length === 1) {
- Modernizr[featureNameSplit[0]] = test;
- } 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]] = test;
- }
- // Set a single class (either `feature` or `no-feature`)
- setClasses([(!!test && test !== false ? '' : 'no-') + featureNameSplit.join('-')]);
- // Trigger the event
- Modernizr._trigger(feature, test);
- }
- return Modernizr; // allow chaining.
- }
- // After all the tests are run, add self to the Modernizr prototype
- Modernizr._q.push(function() {
- ModernizrProto.addTest = addTest;
- });
-
- /**
- * @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) {
- /*jshint evil:true */
- /** 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));
- }
- ;
- /**
- * contains checks to see if a string contains another string
- *
- * @access private
- * @function contains
- * @param {string} str - The string we want to check for substrings
- * @param {string} substr - The substring we want to search the first string for
- * @returns {boolean} true if and only if the first string 'str' contains the second string 'substr'
- */
- function contains(str, substr) {
- return !!~('' + str).indexOf(substr);
- }
- ;
- /**
- * 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);
- }
- }
- ;
- /**
- * Create our "modernizr" element that we do most feature tests on.
- *
- * @access private
- */
- var modElem = {
- elem: createElement('modernizr')
- };
- // Clean up this element
- Modernizr._q.push(function() {
- delete modElem.elem;
- });
-
- var mStyle = {
- style: modElem.elem.style
- };
- // kill ref for gc, must happen before mod.elem is removed, so we unshift on to
- // the front of the queue.
- Modernizr._q.unshift(function() {
- delete mStyle.style;
- });
-
- /**
- * 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;
- }
- ;
- /**
- * injectElementWithStyles injects an element with style element and some CSS rules
- *
- * @access private
- * @function injectElementWithStyles
- * @param {string} rule - String representing a css rule
- * @param {Function} callback - A function that is used to test the injected element
- * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
- * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes
- * @returns {boolean} the result of the specified callback test
- */
- function injectElementWithStyles(rule, callback, nodes, testnames) {
- var mod = 'modernizr';
- 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+
- // eslint-disable-next-line
- docElement.offsetHeight;
- } else {
- div.parentNode.removeChild(div);
- }
- return !!ret;
- }
- ;
- /**
- * domToCSS takes a camelCase string and converts it to kebab-case
- * e.g. boxSizing -> box-sizing
- *
- * @access private
- * @function domToCSS
- * @param {string} name - String name of camelCase prop we want to convert
- * @returns {string} The kebab-case version of the supplied name
- */
- function domToCSS(name) {
- return name.replace(/([A-Z])/g, function(str, m1) {
- return '-' + m1.toLowerCase();
- }).replace(/^ms-/, '-ms-');
- }
- ;
- /**
- * wrapper around getComputedStyle, to fix issues with Firefox returning null when
- * called inside of a hidden iframe
- *
- * @access private
- * @function computedStyle
- * @param {HTMLElement|SVGElement} elem - The element we want to find the computed styles of
- * @param {string|null} [pseudo] - An optional pseudo element selector (e.g. :before), of null if none
- * @param {string} prop - A CSS property
- * @returns {CSSStyleDeclaration} the value of the specified CSS property
- */
- function computedStyle(elem, pseudo, prop) {
- var result;
- if ('getComputedStyle' in window) {
- result = getComputedStyle.call(window, elem, pseudo);
- var console = window.console;
- if (result !== null) {
- if (prop) {
- result = result.getPropertyValue(prop);
- }
- } else {
- if (console) {
- var method = console.error ? 'error' : 'log';
- console[method].call(console, 'getComputedStyle returning null, its possible modernizr test results are inaccurate');
- }
- }
- } else {
- result = !pseudo && elem.currentStyle && elem.currentStyle[prop];
- }
- return result;
- }
- ;
- /**
- * nativeTestProps allows for us to use native feature detection functionality if available.
- * some prefixed form, or false, in the case of an unsupported rule
- *
- * @access private
- * @function nativeTestProps
- * @param {array} props - An array of property names
- * @param {string} value - A string representing the value we want to check via @supports
- * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise
- */
- // Accepts a list of property names and a single value
- // Returns `undefined` if native detection not available
- function nativeTestProps(props, value) {
- var i = props.length;
- // Start with the JS API: https://www.w3.org/TR/css3-conditional/#the-css-interface
- if ('CSS' in window && 'supports' in window.CSS) {
- // Try every prefixed variant of the property
- while (i--) {
- if (window.CSS.supports(domToCSS(props[i]), value)) {
- return true;
- }
- }
- return false;
- }
- // Otherwise fall back to at-rule (for Opera 12.x)
- else if ('CSSSupportsRule' in window) {
- // Build a condition string for every prefixed variant
- var conditionText = [];
- while (i--) {
- conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');
- }
- conditionText = conditionText.join(' or ');
- return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) {
- return computedStyle(node, null, 'position') === 'absolute';
- });
- }
- return undefined;
- }
- ;
- /**
- * cssToDOM takes a kebab-case string and converts it to camelCase
- * e.g. box-sizing -> boxSizing
- *
- * @access private
- * @function cssToDOM
- * @param {string} name - String name of kebab-case prop we want to convert
- * @returns {string} The camelCase version of the supplied name
- */
- function cssToDOM(name) {
- return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {
- return m1 + m2.toUpperCase();
- }).replace(/^-/, '');
- }
- ;
- // testProps is a generic CSS / DOM property test.
- // In testing support for a given CSS property, it's legit to test:
- // `elem.style[styleName] !== undefined`
- // If the property is supported it will return an empty string,
- // if unsupported it will return undefined.
- // We'll take advantage of this quick test and skip setting a style
- // on our modernizr element, but instead just testing undefined vs
- // empty string.
- // Property names can be provided in either camelCase or kebab-case.
- function testProps(props, prefixed, value, skipValueTest) {
- skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest;
- // Try native detect first
- if (!is(value, 'undefined')) {
- var result = nativeTestProps(props, value);
- if (!is(result, 'undefined')) {
- return result;
- }
- }
- // Otherwise do it properly
- var afterInit, i, propsLength, prop, before;
- // If we don't have a style element, that means we're running async or after
- // the core tests, so we'll need to create our own elements to use
- // inside of an SVG element, in certain browsers, the `style` element is only
- // defined for valid tags. Therefore, if `modernizr` does not have one, we
- // fall back to a less used element and hope for the best.
- // for strict XHTML browsers the hardly used samp element is used
- var elems = ['modernizr', 'tspan', 'samp'];
- while (!mStyle.style && elems.length) {
- afterInit = true;
- mStyle.modElem = createElement(elems.shift());
- mStyle.style = mStyle.modElem.style;
- }
- // Delete the objects if we created them.
- function cleanElems() {
- if (afterInit) {
- delete mStyle.style;
- delete mStyle.modElem;
- }
- }
- propsLength = props.length;
- for (i = 0; i < propsLength; i++) {
- prop = props[i];
- before = mStyle.style[prop];
- if (contains(prop, '-')) {
- prop = cssToDOM(prop);
- }
- if (mStyle.style[prop] !== undefined) {
- // If value to test has been passed in, do a set-and-check test.
- // 0 (integer) is a valid property value, so check that `value` isn't
- // undefined, rather than just checking it's truthy.
- if (!skipValueTest && !is(value, 'undefined')) {
- // Needs a try catch block because of old IE. This is slow, but will
- // be avoided in most cases because `skipValueTest` will be used.
- try {
- mStyle.style[prop] = value;
- } catch (e) {}
- // If the property value has changed, we assume the value used is
- // supported. If `value` is empty string, it'll fail here (because
- // it hasn't changed), which matches how browsers have implemented
- // CSS.supports()
- if (mStyle.style[prop] !== before) {
- cleanElems();
- return prefixed === 'pfx' ? prop : true;
- }
- }
- // Otherwise just return true, or the property name if this is a
- // `prefixed()` call
- else {
- cleanElems();
- return prefixed === 'pfx' ? prop : true;
- }
- }
- }
- cleanElems();
- return false;
- }
- ;
- /**
- * testProp() investigates whether a given style property is recognized
- * Property names can be provided in either camelCase or kebab-case.
- *
- * @memberOf Modernizr
- * @name Modernizr.testProp
- * @access public
- * @optionName Modernizr.testProp()
- * @optionProp testProp
- * @function testProp
- * @param {string} prop - Name of the CSS property to check
- * @param {string} [value] - Name of the CSS value to check
- * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported
- * @returns {boolean} an empty string if the property is supported, undefined if its unsupported
- * @example
- *
- * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed
- * version of the string.
- *
- * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing)
- *
- * ```js
- * Modernizr.testProp('pointerEvents') // true
- * ```
- *
- * You can also provide a value as an optional second argument to check if a
- * specific value is supported
- *
- * ```js
- * Modernizr.testProp('pointerEvents', 'none') // true
- * Modernizr.testProp('pointerEvents', 'penguin') // false
- * ```
- */
- var testProp = ModernizrProto.testProp = function(prop, value, useValue) {
- return testProps([prop], undefined, value, useValue);
- };
-
- /*!
- {
- "name": "Cross-Origin Resource Sharing",
- "property": "cors",
- "caniuse": "cors",
- "authors": ["Theodoor van Donge"],
- "notes": [{
- "name": "MDN Docs",
- "href": "https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS"
- }],
- "polyfills": ["pmxdr", "ppx", "flxhr"]
- }
- !*/
- /* DOC
- Detects support for Cross-Origin Resource Sharing: method of performing XMLHttpRequests across domains.
- */
- Modernizr.addTest('cors', 'XMLHttpRequest' in window && 'withCredentials' in new XMLHttpRequest());
- /**
- * since we have a fairly large number of input tests that don't mutate the input
- * we create a single element that can be shared with all of those tests for a
- * minor perf boost
- *
- * @access private
- * @returns {HTMLInputElement}
- */
- var inputElem = createElement('input');
-
- /*!
- {
- "name": "Input attributes",
- "property": "input",
- "tags": ["forms"],
- "authors": ["Mike Taylor"],
- "notes": [{
- "name": "WHATWG Spec",
- "href": "https://html.spec.whatwg.org/multipage/input.html#input-type-attr-summary"
- }],
- "knownBugs": ["Some blackberry devices report false positive for input.multiple"]
- }
- !*/
- /* DOC
- Detects support for HTML5 `<input>` element attributes and exposes Boolean subproperties with the results:
- ```javascript
- Modernizr.input.autocomplete
- Modernizr.input.autofocus
- Modernizr.input.list
- Modernizr.input.max
- Modernizr.input.min
- Modernizr.input.multiple
- Modernizr.input.pattern
- Modernizr.input.placeholder
- Modernizr.input.required
- Modernizr.input.step
- ```
- */
- // Run through HTML5's new input attributes to see if the UA understands any.
- // Mike Taylr has created a comprehensive resource for testing these attributes
- // when applied to all input types:
- // miketaylr.com/code/input-type-attr.html
- // Only input placeholder is tested while textarea's placeholder is not.
- // Currently Safari 4 and Opera 11 have support only for the input placeholder
- // Both tests are available in feature-detects/forms-placeholder.js
- var inputattrs = 'autocomplete autofocus list placeholder max min multiple pattern required step'.split(' ');
- var attrs = {};
- Modernizr.input = (function(props) {
- for (var i = 0, len = props.length; i < len; i++) {
- attrs[ props[i] ] = !!(props[i] in inputElem);
- }
- if (attrs.list) {
- // safari false positive's on datalist: webk.it/74252
- // see also github.com/Modernizr/Modernizr/issues/146
- attrs.list = !!(createElement('datalist') && window.HTMLDataListElement);
- }
- return attrs;
- })(inputattrs);
- /**
- * Object.prototype.toString can be used with every object and allows you to
- * get its class easily. Abstracting it off of an object prevents situations
- * where the toString property has been overridden
- *
- * @access private
- * @function toStringFn
- * @returns {function} An abstracted toString function
- */
- var toStringFn = ({}).toString;
-
- /*!
- {
- "name": "SVG SMIL animation",
- "property": "smil",
- "caniuse": "svg-smil",
- "tags": ["svg"],
- "notes": [{
- "name": "W3C Spec",
- "href": "https://www.w3.org/AudioVideo/"
- }]
- }
- !*/
- // SVG SMIL animation
- Modernizr.addTest('smil', function() {
- return !!document.createElementNS &&
- /SVGAnimate/.test(toStringFn.call(document.createElementNS('http://www.w3.org/2000/svg', 'animate')));
- });
- // Run each test
- testRunner();
- // Remove the "no-js" class if it exists
- setClasses(classes);
- delete ModernizrProto.addTest;
- delete ModernizrProto.addAsyncTest;
- // Run the things that are supposed to run after the tests
- for (var i = 0; i < Modernizr._q.length; i++) {
- Modernizr._q[i]();
- }
- // Leak Modernizr namespace
- window.Modernizr = Modernizr;
- ;
- })(window, document);
|