12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850 |
- /*!
- * modernizr v3.7.0
- * Build https://modernizr.com/download?-siblinggeneral-svg-webintents-addtest-printshiv-setclasses-testprop-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.
- */
- ;(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': '',
- '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);
- };
-
- /**
- * 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';
-
- var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []);
- ModernizrProto._cssomPrefixes = cssomPrefixes;
-
- /**
- * 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;
-
- /**
- * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill.
- *
- * @access private
- * @function fnBind
- * @param {Function} fn - a function you want to change `this` reference to
- * @param {Object} that - the `this` you want to call the function with
- * @returns {Function} The wrapped version of the supplied function
- */
- function fnBind(fn, that) {
- return function() {
- return fn.apply(that, arguments);
- };
- }
- ;
- /**
- * testDOMProps is a generic DOM property test; if a browser supports
- * a certain property, it won't return undefined for it.
- *
- * @access private
- * @function testDOMProps
- * @param {Array<string>} props - An array of properties to test for
- * @param {Object} obj - An object or Element you want to use to test the parameters again
- * @param {boolean|Object} elem - An Element to bind the property lookup again. Use `false` to prevent the check
- * @returns {false|*} returns false if the prop is unsupported, otherwise the value that is supported
- */
- function testDOMProps(props, obj, elem) {
- var item;
- for (var i in props) {
- if (props[i] in obj) {
- // return the property name as a string
- if (elem === false) {
- return props[i];
- }
- item = obj[props[i]];
- // let's bind a function
- if (is(item, 'function')) {
- // bind to obj unless overridden
- return fnBind(item, elem || obj);
- }
- // return the unbound function or obj or value
- return item;
- }
- }
- return false;
- }
- ;
- /**
- * testPropsAll tests a list of DOM properties we want to check against.
- * We specify literally ALL possible (known and/or likely) properties on
- * the element including the non-vendor prefixed one, for forward-
- * compatibility.
- *
- * @access private
- * @function testPropsAll
- * @param {string} prop - A string of the property to test for
- * @param {string|Object} [prefixed] - An object to check the prefixed properties on. Use a string to skip
- * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against
- * @param {string} [value] - A string of a css value
- * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set
- * @returns {false|string} returns the string version of the property, or false if it is unsupported
- */
- function testPropsAll(prop, prefixed, elem, value, skipValueTest) {
- var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
- props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
- // did they call .prefixed('boxSizing') or are we just testing a prop?
- if (is(prefixed, 'string') || is(prefixed, 'undefined')) {
- return testProps(props, prefixed, value, skipValueTest);
- // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
- } else {
- props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
- return testDOMProps(props, prefixed, elem);
- }
- }
- // Modernizr.testAllProps() investigates whether a given style property,
- // or any of its vendor-prefixed variants, is recognized
- //
- // Note that the property names must be provided in the camelCase variant.
- // Modernizr.testAllProps('boxSizing')
- ModernizrProto.testAllProps = testPropsAll;
-
- /**
- * atRule returns a given CSS property at-rule (eg @keyframes), possibly in
- * some prefixed form, or false, in the case of an unsupported rule
- *
- * @memberOf Modernizr
- * @name Modernizr.atRule
- * @optionName Modernizr.atRule()
- * @optionProp atRule
- * @access public
- * @function atRule
- * @param {string} prop - String name of the @-rule to test for
- * @returns {string|boolean} The string representing the (possibly prefixed)
- * valid version of the @-rule, or `false` when it is unsupported.
- * @example
- * ```js
- * var keyframes = Modernizr.atRule('@keyframes');
- *
- * if (keyframes) {
- * // keyframes are supported
- * // could be `@-webkit-keyframes` or `@keyframes`
- * } else {
- * // keyframes === `false`
- * }
- * ```
- */
- var atRule = function(prop) {
- var length = prefixes.length;
- var cssrule = window.CSSRule;
- var rule;
- if (typeof cssrule === 'undefined') {
- return undefined;
- }
- if (!prop) {
- return false;
- }
- // remove literal @ from beginning of provided property
- prop = prop.replace(/^@/, '');
- // CSSRules use underscores instead of dashes
- rule = prop.replace(/-/g, '_').toUpperCase() + '_RULE';
- if (rule in cssrule) {
- return '@' + prop;
- }
- for (var i = 0; i < length; i++) {
- // prefixes gives us something like -o-, and we want O_
- var prefix = prefixes[i];
- var thisRule = prefix.toUpperCase() + '_' + rule;
- if (thisRule in cssrule) {
- return '@-' + prefix.toLowerCase() + '-' + prop;
- }
- }
- return false;
- };
- ModernizrProto.atRule = atRule;
-
- /**
- * prefixed returns the prefixed or nonprefixed property name variant of your input
- *
- * @memberOf Modernizr
- * @name Modernizr.prefixed
- * @optionName Modernizr.prefixed()
- * @optionProp prefixed
- * @access public
- * @function prefixed
- * @param {string} prop - String name of the property to test for
- * @param {Object} [obj] - An object to test for the prefixed properties on
- * @param {HTMLElement} [elem] - An element used to test specific properties against
- * @returns {string|false} The string representing the (possibly prefixed) valid
- * version of the property, or `false` when it is unsupported.
- * @example
- *
- * Modernizr.prefixed takes a string css value in the DOM style camelCase (as
- * opposed to the css style kebab-case) form and returns the (possibly prefixed)
- * version of that property that the browser actually supports.
- *
- * For example, in older Firefox...
- * ```js
- * prefixed('boxSizing')
- * ```
- * returns 'MozBoxSizing'
- *
- * In newer Firefox, as well as any other browser that support the unprefixed
- * version would simply return `boxSizing`. Any browser that does not support
- * the property at all, it will return `false`.
- *
- * By default, prefixed is checked against a DOM element. If you want to check
- * for a property on another object, just pass it as a second argument
- *
- * ```js
- * var rAF = prefixed('requestAnimationFrame', window);
- *
- * raf(function() {
- * renderFunction();
- * })
- * ```
- *
- * Note that this will return _the actual function_ - not the name of the function.
- * If you need the actual name of the property, pass in `false` as a third argument
- *
- * ```js
- * var rAFProp = prefixed('requestAnimationFrame', window, false);
- *
- * rafProp === 'WebkitRequestAnimationFrame' // in older webkit
- * ```
- *
- * One common use case for prefixed is if you're trying to determine which transition
- * end event to bind to, you might do something like...
- * ```js
- * var transEndEventNames = {
- * 'WebkitTransition' : 'webkitTransitionEnd', * Saf 6, Android Browser
- * 'MozTransition' : 'transitionend', * only for FF < 15
- * 'transition' : 'transitionend' * IE10, Opera, Chrome, FF 15+, Saf 7+
- * };
- *
- * var transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
- * ```
- *
- * If you want a similar lookup, but in kebab-case, you can use [prefixedCSS](#modernizr-prefixedcss).
- */
- var prefixed = ModernizrProto.prefixed = function(prop, obj, elem) {
- if (prop.indexOf('@') === 0) {
- return atRule(prop);
- }
- if (prop.indexOf('-') !== -1) {
- // Convert kebab-case to camelCase
- prop = cssToDOM(prop);
- }
- if (!obj) {
- return testPropsAll(prop, 'pfx');
- } else {
- // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
- return testPropsAll(prop, obj, elem);
- }
- };
-
- /*!
- {
- "name": "Web Intents",
- "property": "webintents",
- "authors": ["Eric Bidelman"],
- "notes": [{
- "name": "Web Intents project site",
- "href": "http://www.webintents.org/"
- }],
- "polyfills": ["webintents"],
- "builderAliases": ["web_intents"]
- }
- !*/
- /* DOC
- Detects native support for the Web Intents APIs for service discovery and inter-application communication.
- Chrome added support for this in v19, but [removed it again in v24](https://lists.w3.org/Archives/Public/public-web-intents/2012Nov/0000.html) because of "a number of areas for
- development in both the API and specific user experience in Chrome". No other browsers currently support it, however a [JavaScript shim](http://www.webintents.org/#javascriptshim) is available.
- */
- Modernizr.addTest('webintents', !!prefixed('startActivity', navigator));
- /**
- * testStyles injects an element with style element and some CSS rules
- *
- * @memberOf Modernizr
- * @name Modernizr.testStyles
- * @optionName Modernizr.testStyles()
- * @optionProp testStyles
- * @access public
- * @function testStyles
- * @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}
- * @example
- *
- * `Modernizr.testStyles` takes a CSS rule and injects it onto the current page
- * along with (possibly multiple) DOM elements. This lets you check for features
- * that can not be detected by simply checking the [IDL](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Interface_development_guide/IDL_interface_rules).
- *
- * ```js
- * Modernizr.testStyles('#modernizr { width: 9px; color: papayawhip; }', function(elem, rule) {
- * // elem is the first DOM node in the page (by default #modernizr)
- * // rule is the first argument you supplied - the CSS rule in string form
- *
- * addTest('widthworks', elem.style.width === '9px')
- * });
- * ```
- *
- * If your test requires multiple nodes, you can include a third argument
- * indicating how many additional div elements to include on the page. The
- * additional nodes are injected as children of the `elem` that is returned as
- * the first argument to the callback.
- *
- * ```js
- * Modernizr.testStyles('#modernizr {width: 1px}; #modernizr2 {width: 2px}', function(elem) {
- * document.getElementById('modernizr').style.width === '1px'; // true
- * document.getElementById('modernizr2').style.width === '2px'; // true
- * elem.firstChild === document.getElementById('modernizr2'); // true
- * }, 1);
- * ```
- *
- * By default, all of the additional elements have an ID of `modernizr[n]`, where
- * `n` is its index (e.g. the first additional, second overall is `#modernizr2`,
- * the second additional is `#modernizr3`, etc.).
- * If you want to have more meaningful IDs for your function, you can provide
- * them as the fourth argument, as an array of strings
- *
- * ```js
- * Modernizr.testStyles('#foo {width: 10px}; #bar {height: 20px}', function(elem) {
- * elem.firstChild === document.getElementById('foo'); // true
- * elem.lastChild === document.getElementById('bar'); // true
- * }, 2, ['foo', 'bar']);
- * ```
- */
- var testStyles = ModernizrProto.testStyles = injectElementWithStyles;
-
- /*!
- {
- "name": "CSS general sibling selector",
- "caniuse": "css-sel3",
- "property": "siblinggeneral",
- "tags": ["css"],
- "notes": [{
- "name": "Related Github Issue",
- "href": "https://github.com/Modernizr/Modernizr/pull/889"
- }]
- }
- !*/
- Modernizr.addTest('siblinggeneral', function() {
- return testStyles('#modernizr div {width:100px} #modernizr div ~ div {width:200px;display:block}', function(elem) {
- return elem.lastChild.offsetWidth === 200;
- }, 2);
- });
- /*!
- {
- "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);
- // 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);
|