modernizr.client.js 19 KB

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