modernizr.client.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. export default defineNuxtPlugin(nuxtApp => {
  2. /*!
  3. * modernizr v3.6.0
  4. * Build https://modernizr.com/download?-webp-setclasses-dontmin
  5. *
  6. * Copyright (c)
  7. * Faruk Ates
  8. * Paul Irish
  9. * Alex Sexton
  10. * Ryan Seddon
  11. * Patrick Kettner
  12. * Stu Cox
  13. * Richard Herrera
  14. * MIT License
  15. */
  16. /*
  17. * Modernizr tests which native CSS3 and HTML5 features are available in the
  18. * current UA and makes the results available to you in two ways: as properties on
  19. * a global `Modernizr` object, and as classes on the `<html>` element. This
  20. * information allows you to progressively enhance your pages with a granular level
  21. * of control over the experience.
  22. */
  23. ;(function(window, document, undefined){
  24. var classes = [];
  25. var tests = [];
  26. /**
  27. *
  28. * ModernizrProto is the constructor for Modernizr
  29. *
  30. * @class
  31. * @access public
  32. */
  33. var ModernizrProto = {
  34. // The current version, dummy
  35. _version: '3.6.0',
  36. // Any settings that don't work as separate modules
  37. // can go in here as configuration.
  38. _config: {
  39. 'classPrefix': '',
  40. 'enableClasses': true,
  41. 'enableJSClass': true,
  42. 'usePrefixes': true
  43. },
  44. // Queue of tests
  45. _q: [],
  46. // Stub these for people who are listening
  47. on: function(test, cb) {
  48. // I don't really think people should do this, but we can
  49. // safe guard it a bit.
  50. // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests.
  51. // This is in case people listen to synchronous tests. I would leave it out,
  52. // but the code to *disallow* sync tests in the real version of this
  53. // function is actually larger than this.
  54. var self = this;
  55. setTimeout(function() {
  56. cb(self[test]);
  57. }, 0);
  58. },
  59. addTest: function(name, fn, options) {
  60. tests.push({name: name, fn: fn, options: options});
  61. },
  62. addAsyncTest: function(fn) {
  63. tests.push({name: null, fn: fn});
  64. }
  65. };
  66. // Fake some of Object.create so we can force non test results to be non "own" properties.
  67. var Modernizr = function() {};
  68. Modernizr.prototype = ModernizrProto;
  69. // Leak modernizr globally when you `require` it rather than force it here.
  70. // Overwrite name so constructor name is nicer :D
  71. Modernizr = new Modernizr();
  72. /**
  73. * docElement is a convenience wrapper to grab the root element of the document
  74. *
  75. * @access private
  76. * @returns {HTMLElement|SVGElement} The root element of the document
  77. */
  78. var docElement = document.documentElement;
  79. /**
  80. * is returns a boolean if the typeof an obj is exactly type.
  81. *
  82. * @access private
  83. * @function is
  84. * @param {*} obj - A thing we want to check the type of
  85. * @param {string} type - A string to compare the typeof against
  86. * @returns {boolean}
  87. */
  88. function is(obj, type) {
  89. return typeof obj === type;
  90. }
  91. ;
  92. /**
  93. * Run through all tests and detect their support in the current UA.
  94. *
  95. * @access private
  96. */
  97. function testRunner() {
  98. var featureNames;
  99. var feature;
  100. var aliasIdx;
  101. var result;
  102. var nameIdx;
  103. var featureName;
  104. var featureNameSplit;
  105. for (var featureIdx in tests) {
  106. if (tests.hasOwnProperty(featureIdx)) {
  107. featureNames = [];
  108. feature = tests[featureIdx];
  109. // run the test, throw the return value into the Modernizr,
  110. // then based on that boolean, define an appropriate className
  111. // and push it into an array of classes we'll join later.
  112. //
  113. // If there is no name, it's an 'async' test that is run,
  114. // but not directly added to the object. That should
  115. // be done with a post-run addTest call.
  116. if (feature.name) {
  117. featureNames.push(feature.name.toLowerCase());
  118. if (feature.options && feature.options.aliases && feature.options.aliases.length) {
  119. // Add all the aliases into the names list
  120. for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) {
  121. featureNames.push(feature.options.aliases[aliasIdx].toLowerCase());
  122. }
  123. }
  124. }
  125. // Run the test, or use the raw value if it's not a function
  126. result = is(feature.fn, 'function') ? feature.fn() : feature.fn;
  127. // Set each of the names on the Modernizr object
  128. for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) {
  129. featureName = featureNames[nameIdx];
  130. // Support dot properties as sub tests. We don't do checking to make sure
  131. // that the implied parent tests have been added. You must call them in
  132. // order (either in the test, or make the parent test a dependency).
  133. //
  134. // Cap it to TWO to make the logic simple and because who needs that kind of subtesting
  135. // hashtag famous last words
  136. featureNameSplit = featureName.split('.');
  137. if (featureNameSplit.length === 1) {
  138. Modernizr[featureNameSplit[0]] = result;
  139. } else {
  140. // cast to a Boolean, if not one already
  141. if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
  142. Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
  143. }
  144. Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;
  145. }
  146. classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));
  147. }
  148. }
  149. }
  150. }
  151. ;
  152. /**
  153. * A convenience helper to check if the document we are running in is an SVG document
  154. *
  155. * @access private
  156. * @returns {boolean}
  157. */
  158. var isSVG = docElement.nodeName.toLowerCase() === 'svg';
  159. /**
  160. * setClasses takes an array of class names and adds them to the root element
  161. *
  162. * @access private
  163. * @function setClasses
  164. * @param {string[]} classes - Array of class names
  165. */
  166. // Pass in an and array of class names, e.g.:
  167. // ['no-webp', 'borderradius', ...]
  168. function setClasses(classes) {
  169. var className = docElement.className;
  170. var classPrefix = Modernizr._config.classPrefix || '';
  171. if (isSVG) {
  172. className = className.baseVal;
  173. }
  174. // Change `no-js` to `js` (independently of the `enableClasses` option)
  175. // Handle classPrefix on this too
  176. if (Modernizr._config.enableJSClass) {
  177. var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)');
  178. className = className.replace(reJS, '$1' + classPrefix + 'js$2');
  179. }
  180. if (Modernizr._config.enableClasses) {
  181. // Add the new classes
  182. className += ' ' + classPrefix + classes.join(' ' + classPrefix);
  183. if (isSVG) {
  184. docElement.className.baseVal = className;
  185. } else {
  186. docElement.className = className;
  187. }
  188. }
  189. }
  190. ;
  191. /**
  192. * hasOwnProp is a shim for hasOwnProperty that is needed for Safari 2.0 support
  193. *
  194. * @author kangax
  195. * @access private
  196. * @function hasOwnProp
  197. * @param {object} object - The object to check for a property
  198. * @param {string} property - The property to check for
  199. * @returns {boolean}
  200. */
  201. // hasOwnProperty shim by kangax needed for Safari 2.0 support
  202. var hasOwnProp;
  203. (function() {
  204. var _hasOwnProperty = ({}).hasOwnProperty;
  205. /* istanbul ignore else */
  206. /* we have no way of testing IE 5.5 or safari 2,
  207. * so just assume the else gets hit */
  208. if (!is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined')) {
  209. hasOwnProp = function(object, property) {
  210. return _hasOwnProperty.call(object, property);
  211. };
  212. }
  213. else {
  214. hasOwnProp = function(object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
  215. return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
  216. };
  217. }
  218. })();
  219. // _l tracks listeners for async tests, as well as tests that execute after the initial run
  220. ModernizrProto._l = {};
  221. /**
  222. * Modernizr.on is a way to listen for the completion of async tests. Being
  223. * asynchronous, they may not finish before your scripts run. As a result you
  224. * will get a possibly false negative `undefined` value.
  225. *
  226. * @memberof Modernizr
  227. * @name Modernizr.on
  228. * @access public
  229. * @function on
  230. * @param {string} feature - String name of the feature detect
  231. * @param {function} cb - Callback function returning a Boolean - true if feature is supported, false if not
  232. * @example
  233. *
  234. * ```js
  235. * Modernizr.on('flash', function( result ) {
  236. * if (result) {
  237. * // the browser has flash
  238. * } else {
  239. * // the browser does not have flash
  240. * }
  241. * });
  242. * ```
  243. */
  244. ModernizrProto.on = function(feature, cb) {
  245. // Create the list of listeners if it doesn't exist
  246. if (!this._l[feature]) {
  247. this._l[feature] = [];
  248. }
  249. // Push this test on to the listener list
  250. this._l[feature].push(cb);
  251. // If it's already been resolved, trigger it on next tick
  252. if (Modernizr.hasOwnProperty(feature)) {
  253. // Next Tick
  254. setTimeout(function() {
  255. Modernizr._trigger(feature, Modernizr[feature]);
  256. }, 0);
  257. }
  258. };
  259. /**
  260. * _trigger is the private function used to signal test completion and run any
  261. * callbacks registered through [Modernizr.on](#modernizr-on)
  262. *
  263. * @memberof Modernizr
  264. * @name Modernizr._trigger
  265. * @access private
  266. * @function _trigger
  267. * @param {string} feature - string name of the feature detect
  268. * @param {function|boolean} [res] - A feature detection function, or the boolean =
  269. * result of a feature detection function
  270. */
  271. ModernizrProto._trigger = function(feature, res) {
  272. if (!this._l[feature]) {
  273. return;
  274. }
  275. var cbs = this._l[feature];
  276. // Force async
  277. setTimeout(function() {
  278. var i, cb;
  279. for (i = 0; i < cbs.length; i++) {
  280. cb = cbs[i];
  281. cb(res);
  282. }
  283. }, 0);
  284. // Don't trigger these again
  285. delete this._l[feature];
  286. };
  287. /**
  288. * addTest allows you to define your own feature detects that are not currently
  289. * included in Modernizr (under the covers it's the exact same code Modernizr
  290. * uses for its own [feature detections](https://github.com/Modernizr/Modernizr/tree/master/feature-detects)). Just like the offical detects, the result
  291. * will be added onto the Modernizr object, as well as an appropriate className set on
  292. * the html element when configured to do so
  293. *
  294. * @memberof Modernizr
  295. * @name Modernizr.addTest
  296. * @optionName Modernizr.addTest()
  297. * @optionProp addTest
  298. * @access public
  299. * @function addTest
  300. * @param {string|object} feature - The string name of the feature detect, or an
  301. * object of feature detect names and test
  302. * @param {function|boolean} test - Function returning true if feature is supported,
  303. * false if not. Otherwise a boolean representing the results of a feature detection
  304. * @example
  305. *
  306. * The most common way of creating your own feature detects is by calling
  307. * `Modernizr.addTest` with a string (preferably just lowercase, without any
  308. * punctuation), and a function you want executed that will return a boolean result
  309. *
  310. * ```js
  311. * Modernizr.addTest('itsTuesday', function() {
  312. * var d = new Date();
  313. * return d.getDay() === 2;
  314. * });
  315. * ```
  316. *
  317. * When the above is run, it will set Modernizr.itstuesday to `true` when it is tuesday,
  318. * and to `false` every other day of the week. One thing to notice is that the names of
  319. * feature detect functions are always lowercased when added to the Modernizr object. That
  320. * means that `Modernizr.itsTuesday` will not exist, but `Modernizr.itstuesday` will.
  321. *
  322. *
  323. * Since we only look at the returned value from any feature detection function,
  324. * you do not need to actually use a function. For simple detections, just passing
  325. * in a statement that will return a boolean value works just fine.
  326. *
  327. * ```js
  328. * Modernizr.addTest('hasJquery', 'jQuery' in window);
  329. * ```
  330. *
  331. * Just like before, when the above runs `Modernizr.hasjquery` will be true if
  332. * jQuery has been included on the page. Not using a function saves a small amount
  333. * of overhead for the browser, as well as making your code much more readable.
  334. *
  335. * Finally, you also have the ability to pass in an object of feature names and
  336. * their tests. This is handy if you want to add multiple detections in one go.
  337. * The keys should always be a string, and the value can be either a boolean or
  338. * function that returns a boolean.
  339. *
  340. * ```js
  341. * var detects = {
  342. * 'hasjquery': 'jQuery' in window,
  343. * 'itstuesday': function() {
  344. * var d = new Date();
  345. * return d.getDay() === 2;
  346. * }
  347. * }
  348. *
  349. * Modernizr.addTest(detects);
  350. * ```
  351. *
  352. * There is really no difference between the first methods and this one, it is
  353. * just a convenience to let you write more readable code.
  354. */
  355. function addTest(feature, test) {
  356. if (typeof feature == 'object') {
  357. for (var key in feature) {
  358. if (hasOwnProp(feature, key)) {
  359. addTest(key, feature[ key ]);
  360. }
  361. }
  362. } else {
  363. feature = feature.toLowerCase();
  364. var featureNameSplit = feature.split('.');
  365. var last = Modernizr[featureNameSplit[0]];
  366. // Again, we don't check for parent test existence. Get that right, though.
  367. if (featureNameSplit.length == 2) {
  368. last = last[featureNameSplit[1]];
  369. }
  370. if (typeof last != 'undefined') {
  371. // we're going to quit if you're trying to overwrite an existing test
  372. // if we were to allow it, we'd do this:
  373. // var re = new RegExp("\\b(no-)?" + feature + "\\b");
  374. // docElement.className = docElement.className.replace( re, '' );
  375. // but, no rly, stuff 'em.
  376. return Modernizr;
  377. }
  378. test = typeof test == 'function' ? test() : test;
  379. // Set the value (this is the magic, right here).
  380. if (featureNameSplit.length == 1) {
  381. Modernizr[featureNameSplit[0]] = test;
  382. } else {
  383. // cast to a Boolean, if not one already
  384. if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
  385. Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
  386. }
  387. Modernizr[featureNameSplit[0]][featureNameSplit[1]] = test;
  388. }
  389. // Set a single class (either `feature` or `no-feature`)
  390. setClasses([(!!test && test != false ? '' : 'no-') + featureNameSplit.join('-')]);
  391. // Trigger the event
  392. Modernizr._trigger(feature, test);
  393. }
  394. return Modernizr; // allow chaining.
  395. }
  396. // After all the tests are run, add self to the Modernizr prototype
  397. Modernizr._q.push(function() {
  398. ModernizrProto.addTest = addTest;
  399. });
  400. /*!
  401. {
  402. "name": "Webp",
  403. "async": true,
  404. "property": "webp",
  405. "tags": ["image"],
  406. "builderAliases": ["img_webp"],
  407. "authors": ["Krister Kari", "@amandeep", "Rich Bradshaw", "Ryan Seddon", "Paul Irish"],
  408. "notes": [{
  409. "name": "Webp Info",
  410. "href": "https://developers.google.com/speed/webp/"
  411. }, {
  412. "name": "Chormium blog - Chrome 32 Beta: Animated WebP images and faster Chrome for Android touch input",
  413. "href": "https://blog.chromium.org/2013/11/chrome-32-beta-animated-webp-images-and.html"
  414. }, {
  415. "name": "Webp Lossless Spec",
  416. "href": "https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification"
  417. }, {
  418. "name": "Article about WebP support on Android browsers",
  419. "href": "http://www.wope-framework.com/en/2013/06/24/webp-support-on-android-browsers/"
  420. }, {
  421. "name": "Chormium WebP announcement",
  422. "href": "https://blog.chromium.org/2011/11/lossless-and-transparency-encoding-in.html?m=1"
  423. }]
  424. }
  425. !*/
  426. /* DOC
  427. Tests for lossy, non-alpha webp support.
  428. Tests for all forms of webp support (lossless, lossy, alpha, and animated)..
  429. Modernizr.webp // Basic support (lossy)
  430. Modernizr.webp.lossless // Lossless
  431. Modernizr.webp.alpha // Alpha (both lossy and lossless)
  432. Modernizr.webp.animation // Animated WebP
  433. */
  434. Modernizr.addAsyncTest(function() {
  435. var webpTests = [{
  436. 'uri': 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA=',
  437. 'name': 'webp'
  438. }, {
  439. 'uri': 'data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA==',
  440. 'name': 'webp.alpha'
  441. }, {
  442. 'uri': 'data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA',
  443. 'name': 'webp.animation'
  444. }, {
  445. 'uri': 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=',
  446. 'name': 'webp.lossless'
  447. }];
  448. var webp = webpTests.shift();
  449. function test(name, uri, cb) {
  450. var image = new Image();
  451. function addResult(event) {
  452. // if the event is from 'onload', check the see if the image's width is
  453. // 1 pixel (which indiciates support). otherwise, it fails
  454. var result = event && event.type === 'load' ? image.width == 1 : false;
  455. var baseTest = name === 'webp';
  456. // if it is the base test, and the result is false, just set a literal false
  457. // rather than use the Boolean contrsuctor
  458. addTest(name, (baseTest && result) ? new Boolean(result) : result);
  459. if (cb) {
  460. cb(event);
  461. }
  462. }
  463. image.onerror = addResult;
  464. image.onload = addResult;
  465. image.src = uri;
  466. }
  467. // test for webp support in general
  468. test(webp.name, webp.uri, function(e) {
  469. // if the webp test loaded, test everything else.
  470. if (e && e.type === 'load') {
  471. for (var i = 0; i < webpTests.length; i++) {
  472. test(webpTests[i].name, webpTests[i].uri);
  473. }
  474. }
  475. });
  476. });
  477. // Run each test
  478. testRunner();
  479. // Remove the "no-js" class if it exists
  480. setClasses(classes);
  481. delete ModernizrProto.addTest;
  482. delete ModernizrProto.addAsyncTest;
  483. // Run the things that are supposed to run after the tests
  484. for (var i = 0; i < Modernizr._q.length; i++) {
  485. Modernizr._q[i]();
  486. }
  487. // Leak Modernizr namespace
  488. window.Modernizr = Modernizr;
  489. ;
  490. })(window, document);
  491. });