export default defineNuxtPlugin(nuxtApp => { /*! * modernizr v3.6.0 * Build https://modernizr.com/download?-webp-setclasses-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 `` element. This * information allows you to progressively enhance your pages with a granular level * of control over the experience. */ ;(function(window, document, undefined){ var classes = []; var tests = []; /** * * ModernizrProto is the constructor for Modernizr * * @class * @access public */ var ModernizrProto = { // The current version, dummy _version: '3.6.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(); /** * 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; /** * is returns a boolean if the typeof an obj is exactly type. * * @access private * @function is * @param {*} obj - A thing we want to check the type of * @param {string} type - A string to compare the typeof against * @returns {boolean} */ function is(obj, type) { return typeof obj === type; } ; /** * Run through all tests and detect their support in the current UA. * * @access private */ function testRunner() { var featureNames; var feature; var aliasIdx; var result; var nameIdx; var featureName; var featureNameSplit; for (var featureIdx in tests) { if (tests.hasOwnProperty(featureIdx)) { featureNames = []; feature = tests[featureIdx]; // run the test, throw the return value into the Modernizr, // then based on that boolean, define an appropriate className // and push it into an array of classes we'll join later. // // If there is no name, it's an 'async' test that is run, // but not directly added to the object. That should // be done with a post-run addTest call. if (feature.name) { featureNames.push(feature.name.toLowerCase()); if (feature.options && feature.options.aliases && feature.options.aliases.length) { // Add all the aliases into the names list for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) { featureNames.push(feature.options.aliases[aliasIdx].toLowerCase()); } } } // Run the test, or use the raw value if it's not a function result = is(feature.fn, 'function') ? feature.fn() : feature.fn; // Set each of the names on the Modernizr object for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) { featureName = featureNames[nameIdx]; // Support dot properties as sub tests. We don't do checking to make sure // that the implied parent tests have been added. You must call them in // order (either in the test, or make the parent test a dependency). // // Cap it to TWO to make the logic simple and because who needs that kind of subtesting // hashtag famous last words featureNameSplit = featureName.split('.'); if (featureNameSplit.length === 1) { Modernizr[featureNameSplit[0]] = result; } else { // cast to a Boolean, if not one already if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) { Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]); } Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result; } classes.push((result ? '' : 'no-') + featureNameSplit.join('-')); } } } } ; /** * A convenience helper to check if the document we are running in is an SVG document * * @access private * @returns {boolean} */ var isSVG = docElement.nodeName.toLowerCase() === 'svg'; /** * setClasses takes an array of class names and adds them to the root element * * @access private * @function setClasses * @param {string[]} classes - Array of class names */ // Pass in an and array of class names, e.g.: // ['no-webp', 'borderradius', ...] function setClasses(classes) { var className = docElement.className; var classPrefix = Modernizr._config.classPrefix || ''; if (isSVG) { className = className.baseVal; } // Change `no-js` to `js` (independently of the `enableClasses` option) // Handle classPrefix on this too if (Modernizr._config.enableJSClass) { var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)'); className = className.replace(reJS, '$1' + classPrefix + 'js$2'); } if (Modernizr._config.enableClasses) { // Add the new classes className += ' ' + classPrefix + classes.join(' ' + classPrefix); if (isSVG) { docElement.className.baseVal = className; } else { docElement.className = className; } } } ; /** * hasOwnProp is a shim for hasOwnProperty that is needed for Safari 2.0 support * * @author kangax * @access private * @function hasOwnProp * @param {object} object - The object to check for a property * @param {string} property - The property to check for * @returns {boolean} */ // hasOwnProperty shim by kangax needed for Safari 2.0 support var hasOwnProp; (function() { var _hasOwnProperty = ({}).hasOwnProperty; /* istanbul ignore else */ /* we have no way of testing IE 5.5 or safari 2, * so just assume the else gets hit */ if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) { hasOwnProp = function(object, property) { return _hasOwnProperty.call(object, property); }; } else { hasOwnProp = function(object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */ return ((property in object) && is(object.constructor.prototype[property], 'undefined')); }; } })(); // _l tracks listeners for async tests, as well as tests that execute after the initial run ModernizrProto._l = {}; /** * Modernizr.on is a way to listen for the completion of async tests. Being * asynchronous, they may not finish before your scripts run. As a result you * will get a possibly false negative `undefined` value. * * @memberof Modernizr * @name Modernizr.on * @access public * @function on * @param {string} feature - String name of the feature detect * @param {function} cb - Callback function returning a Boolean - true if feature is supported, false if not * @example * * ```js * Modernizr.on('flash', function( result ) { * if (result) { * // the browser has flash * } else { * // the browser does not have flash * } * }); * ``` */ ModernizrProto.on = function(feature, cb) { // Create the list of listeners if it doesn't exist if (!this._l[feature]) { this._l[feature] = []; } // Push this test on to the listener list this._l[feature].push(cb); // If it's already been resolved, trigger it on next tick if (Modernizr.hasOwnProperty(feature)) { // Next Tick setTimeout(function() { Modernizr._trigger(feature, Modernizr[feature]); }, 0); } }; /** * _trigger is the private function used to signal test completion and run any * callbacks registered through [Modernizr.on](#modernizr-on) * * @memberof Modernizr * @name Modernizr._trigger * @access private * @function _trigger * @param {string} feature - string name of the feature detect * @param {function|boolean} [res] - A feature detection function, or the boolean = * result of a feature detection function */ ModernizrProto._trigger = function(feature, res) { if (!this._l[feature]) { return; } var cbs = this._l[feature]; // Force async setTimeout(function() { var i, cb; for (i = 0; i < cbs.length; i++) { cb = cbs[i]; cb(res); } }, 0); // Don't trigger these again delete this._l[feature]; }; /** * addTest allows you to define your own feature detects that are not currently * included in Modernizr (under the covers it's the exact same code Modernizr * uses for its own [feature detections](https://github.com/Modernizr/Modernizr/tree/master/feature-detects)). Just like the offical detects, the result * will be added onto the Modernizr object, as well as an appropriate className set on * the html element when configured to do so * * @memberof Modernizr * @name Modernizr.addTest * @optionName Modernizr.addTest() * @optionProp addTest * @access public * @function addTest * @param {string|object} 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 * @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; }); /*! { "name": "Webp", "async": true, "property": "webp", "tags": ["image"], "builderAliases": ["img_webp"], "authors": ["Krister Kari", "@amandeep", "Rich Bradshaw", "Ryan Seddon", "Paul Irish"], "notes": [{ "name": "Webp Info", "href": "https://developers.google.com/speed/webp/" }, { "name": "Chormium blog - Chrome 32 Beta: Animated WebP images and faster Chrome for Android touch input", "href": "https://blog.chromium.org/2013/11/chrome-32-beta-animated-webp-images-and.html" }, { "name": "Webp Lossless Spec", "href": "https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification" }, { "name": "Article about WebP support on Android browsers", "href": "http://www.wope-framework.com/en/2013/06/24/webp-support-on-android-browsers/" }, { "name": "Chormium WebP announcement", "href": "https://blog.chromium.org/2011/11/lossless-and-transparency-encoding-in.html?m=1" }] } !*/ /* DOC Tests for lossy, non-alpha webp support. Tests for all forms of webp support (lossless, lossy, alpha, and animated).. Modernizr.webp // Basic support (lossy) Modernizr.webp.lossless // Lossless Modernizr.webp.alpha // Alpha (both lossy and lossless) Modernizr.webp.animation // Animated WebP */ Modernizr.addAsyncTest(function() { var webpTests = [{ 'uri': 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA=', 'name': 'webp' }, { 'uri': 'data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA==', 'name': 'webp.alpha' }, { 'uri': 'data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA', 'name': 'webp.animation' }, { 'uri': 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=', 'name': 'webp.lossless' }]; var webp = webpTests.shift(); function test(name, uri, cb) { var image = new Image(); function addResult(event) { // if the event is from 'onload', check the see if the image's width is // 1 pixel (which indiciates support). otherwise, it fails var result = event && event.type === 'load' ? image.width == 1 : false; var baseTest = name === 'webp'; // if it is the base test, and the result is false, just set a literal false // rather than use the Boolean contrsuctor addTest(name, (baseTest && result) ? new Boolean(result) : result); if (cb) { cb(event); } } image.onerror = addResult; image.onload = addResult; image.src = uri; } // test for webp support in general test(webp.name, webp.uri, function(e) { // if the webp test loaded, test everything else. if (e && e.type === 'load') { for (var i = 0; i < webpTests.length; i++) { test(webpTests[i].name, webpTests[i].uri); } } }); }); // 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); });