diff --git a/README.md b/README.md index 996d624..9069b2b 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,63 @@ import { default as figlet } from './figlet.js'; console.log(figlet); ``` +### Modernizr + +Example shows how to build [`modernizr`](https://www.npmjs.com/package/modernizr) + +**src/modernizr.js** + +```js +const modernizr = require('modernizr'); + +module.exports = function(options) { + return new Promise(function(resolve) { + // It is impossible to throw an error because modernizr causes the process.exit(1) + modernizr.build(options, function(output) { + resolve({ + cacheable: true, + code: `var modernizr; var hadGlobal = 'Modernizr' in window; var oldGlobal = window.Modernizr; ${output} modernizr = window.Modernizr; if (hadGlobal) { window.Modernizr = oldGlobal; } else { delete window.Modernizr; } export default modernizr;`, + }); + }); + }); +}; +``` + +**webpack.config.js** + +```js +const path = require('path'); +module.exports = { + module: { + rules: [ + { + test: path.resolve(__dirname, 'src', 'modernizr.js'), + use: [ + { + loader: 'val-loader', + options: { + minify: false, + options: ['setClasses'], + 'feature-detects': [ + 'test/css/flexbox', + 'test/es6/promises', + 'test/serviceworker', + ], + }, + }, + ], + }, + ], + }, +}; +``` + +**src/entry.js** + +```js +import modenizr from './modernizr.js'; +``` + ## Contributing Please take a moment to read our contributing guidelines if you haven't yet done so. diff --git a/package-lock.json b/package-lock.json index 478f6e3..be3ffde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1438,6 +1438,12 @@ "@babel/types": "^7.3.0" } }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -4153,6 +4159,12 @@ } } }, + "entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==", + "dev": true + }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -4875,6 +4887,12 @@ "escape-string-regexp": "^1.0.5" } }, + "file": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/file/-/file-0.2.2.tgz", + "integrity": "sha1-w9/Y+M81Na5FXCtCPC5SY112tNM=", + "dev": true + }, "file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", @@ -7689,6 +7707,15 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "lint-staged": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.5.0.tgz", @@ -8288,6 +8315,19 @@ "object-visit": "^1.0.0" } }, + "markdown-it": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", + "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -8299,6 +8339,12 @@ "safe-buffer": "^5.1.2" } }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, "memfs": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.0.1.tgz", @@ -8512,6 +8558,184 @@ } } }, + "modernizr": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/modernizr/-/modernizr-3.10.0.tgz", + "integrity": "sha512-ckbj+oUvkQ1NfKH4fuejIidP2HIwHMMQm2czSOWSjlv9LbWPC7gDYk8phXvEO52GJjZre6iODvK84+KEStqpzw==", + "dev": true, + "requires": { + "doctrine": "^3.0.0", + "file": "^0.2.2", + "lodash": "^4.17.15", + "markdown-it": "^10.0.0", + "mkdirp": "0.5.5", + "requirejs": "^2.3.6", + "yargs": "^15.3.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" + } + }, + "yargs-parser": { + "version": "18.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz", + "integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", @@ -9776,6 +10000,12 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requirejs": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", + "dev": true + }, "resolve": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", @@ -11192,6 +11422,12 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, "uglify-js": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz", diff --git a/package.json b/package.json index b33dac9..dbc11b6 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "jest-junit": "^10.0.0", "lint-staged": "^9.5.0", "memfs": "^3.0.1", + "modernizr": "^3.10.0", "npm-run-all": "^4.1.5", "prettier": "^1.19.1", "standard-version": "^7.0.1", diff --git a/test/__snapshots__/loader.test.js.snap b/test/__snapshots__/loader.test.js.snap index d9edd85..5ac28e2 100644 --- a/test/__snapshots__/loader.test.js.snap +++ b/test/__snapshots__/loader.test.js.snap @@ -211,6 +211,22 @@ exports[`loader should pass on the code from the presets/figlet fixture: result exports[`loader should pass on the code from the presets/figlet fixture: warnings 1`] = `Array []`; +exports[`loader should pass on the code from the presets/modernizr fixture: errors 1`] = `Array []`; + +exports[`loader should pass on the code from the presets/modernizr fixture: result 1`] = ` +"{ + \\"content\\": \\"var modernizr; var hadGlobal = 'Modernizr' in window; var oldGlobal = window.Modernizr; /*!\\\\n * modernizr v3.10.0\\\\n * Build https://modernizr.com/download?-flexbox-promises-serviceworker-setclasses-dontmin\\\\n *\\\\n * Copyright (c)\\\\n * Faruk Ates\\\\n * Paul Irish\\\\n * Alex Sexton\\\\n * Ryan Seddon\\\\n * Patrick Kettner\\\\n * Stu Cox\\\\n * Richard Herrera\\\\n * Veeck\\\\n\\\\n * MIT License\\\\n */\\\\n\\\\n/*\\\\n * Modernizr tests which native CSS3 and HTML5 features are available in the\\\\n * current UA and makes the results available to you in two ways: as properties on\\\\n * a global \`Modernizr\` object, and as classes on the \`\` element. This\\\\n * information allows you to progressively enhance your pages with a granular level\\\\n * of control over the experience.\\\\n*/\\\\n\\\\n;(function(scriptGlobalObject, window, document, undefined){\\\\n\\\\n var tests = [];\\\\n \\\\n\\\\n /**\\\\n * ModernizrProto is the constructor for Modernizr\\\\n *\\\\n * @class\\\\n * @access public\\\\n */\\\\n var ModernizrProto = {\\\\n // The current version, dummy\\\\n _version: '3.10.0',\\\\n\\\\n // Any settings that don't work as separate modules\\\\n // can go in here as configuration.\\\\n _config: {\\\\n 'classPrefix': '',\\\\n 'enableClasses': true,\\\\n 'enableJSClass': true,\\\\n 'usePrefixes': true\\\\n },\\\\n\\\\n // Queue of tests\\\\n _q: [],\\\\n\\\\n // Stub these for people who are listening\\\\n on: function(test, cb) {\\\\n // I don't really think people should do this, but we can\\\\n // safe guard it a bit.\\\\n // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests.\\\\n // This is in case people listen to synchronous tests. I would leave it out,\\\\n // but the code to *disallow* sync tests in the real version of this\\\\n // function is actually larger than this.\\\\n var self = this;\\\\n setTimeout(function() {\\\\n cb(self[test]);\\\\n }, 0);\\\\n },\\\\n\\\\n addTest: function(name, fn, options) {\\\\n tests.push({name: name, fn: fn, options: options});\\\\n },\\\\n\\\\n addAsyncTest: function(fn) {\\\\n tests.push({name: null, fn: fn});\\\\n }\\\\n };\\\\n\\\\n \\\\n\\\\n // Fake some of Object.create so we can force non test results to be non \\\\\\"own\\\\\\" properties.\\\\n var Modernizr = function() {};\\\\n Modernizr.prototype = ModernizrProto;\\\\n\\\\n // Leak modernizr globally when you \`require\` it rather than force it here.\\\\n // Overwrite name so constructor name is nicer :D\\\\n Modernizr = new Modernizr();\\\\n\\\\n \\\\n\\\\n var classes = [];\\\\n \\\\n\\\\n /**\\\\n * is returns a boolean if the typeof an obj is exactly type.\\\\n *\\\\n * @access private\\\\n * @function is\\\\n * @param {*} obj - A thing we want to check the type of\\\\n * @param {string} type - A string to compare the typeof against\\\\n * @returns {boolean} true if the typeof the first parameter is exactly the specified type, false otherwise\\\\n */\\\\n function is(obj, type) {\\\\n return typeof obj === type;\\\\n }\\\\n\\\\n ;\\\\n\\\\n /**\\\\n * Run through all tests and detect their support in the current UA.\\\\n *\\\\n * @access private\\\\n * @returns {void}\\\\n */\\\\n function testRunner() {\\\\n var featureNames;\\\\n var feature;\\\\n var aliasIdx;\\\\n var result;\\\\n var nameIdx;\\\\n var featureName;\\\\n var featureNameSplit;\\\\n\\\\n for (var featureIdx in tests) {\\\\n if (tests.hasOwnProperty(featureIdx)) {\\\\n featureNames = [];\\\\n feature = tests[featureIdx];\\\\n // run the test, throw the return value into the Modernizr,\\\\n // then based on that boolean, define an appropriate className\\\\n // and push it into an array of classes we'll join later.\\\\n //\\\\n // If there is no name, it's an 'async' test that is run,\\\\n // but not directly added to the object. That should\\\\n // be done with a post-run addTest call.\\\\n if (feature.name) {\\\\n featureNames.push(feature.name.toLowerCase());\\\\n\\\\n if (feature.options && feature.options.aliases && feature.options.aliases.length) {\\\\n // Add all the aliases into the names list\\\\n for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) {\\\\n featureNames.push(feature.options.aliases[aliasIdx].toLowerCase());\\\\n }\\\\n }\\\\n }\\\\n\\\\n // Run the test, or use the raw value if it's not a function\\\\n result = is(feature.fn, 'function') ? feature.fn() : feature.fn;\\\\n\\\\n // Set each of the names on the Modernizr object\\\\n for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) {\\\\n featureName = featureNames[nameIdx];\\\\n // Support dot properties as sub tests. We don't do checking to make sure\\\\n // that the implied parent tests have been added. You must call them in\\\\n // order (either in the test, or make the parent test a dependency).\\\\n //\\\\n // Cap it to TWO to make the logic simple and because who needs that kind of subtesting\\\\n // hashtag famous last words\\\\n featureNameSplit = featureName.split('.');\\\\n\\\\n if (featureNameSplit.length === 1) {\\\\n Modernizr[featureNameSplit[0]] = result;\\\\n } else {\\\\n // cast to a Boolean, if not one already or if it doesnt exist yet (like inputtypes)\\\\n if (!Modernizr[featureNameSplit[0]] || Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {\\\\n Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);\\\\n }\\\\n\\\\n Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;\\\\n }\\\\n\\\\n classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));\\\\n }\\\\n }\\\\n }\\\\n }\\\\n ;\\\\n\\\\n /**\\\\n * docElement is a convenience wrapper to grab the root element of the document\\\\n *\\\\n * @access private\\\\n * @returns {HTMLElement|SVGElement} The root element of the document\\\\n */\\\\n var docElement = document.documentElement;\\\\n \\\\n\\\\n /**\\\\n * A convenience helper to check if the document we are running in is an SVG document\\\\n *\\\\n * @access private\\\\n * @returns {boolean}\\\\n */\\\\n var isSVG = docElement.nodeName.toLowerCase() === 'svg';\\\\n\\\\n \\\\n\\\\n /**\\\\n * setClasses takes an array of class names and adds them to the root element\\\\n *\\\\n * @access private\\\\n * @function setClasses\\\\n * @param {string[]} classes - Array of class names\\\\n */\\\\n // Pass in an and array of class names, e.g.:\\\\n // ['no-webp', 'borderradius', ...]\\\\n function setClasses(classes) {\\\\n var className = docElement.className;\\\\n var classPrefix = Modernizr._config.classPrefix || '';\\\\n\\\\n if (isSVG) {\\\\n className = className.baseVal;\\\\n }\\\\n\\\\n // Change \`no-js\` to \`js\` (independently of the \`enableClasses\` option)\\\\n // Handle classPrefix on this too\\\\n if (Modernizr._config.enableJSClass) {\\\\n var reJS = new RegExp('(^|\\\\\\\\\\\\\\\\s)' + classPrefix + 'no-js(\\\\\\\\\\\\\\\\s|$)');\\\\n className = className.replace(reJS, '$1' + classPrefix + 'js$2');\\\\n }\\\\n\\\\n if (Modernizr._config.enableClasses) {\\\\n // Add the new classes\\\\n if (classes.length > 0) {\\\\n className += ' ' + classPrefix + classes.join(' ' + classPrefix);\\\\n }\\\\n if (isSVG) {\\\\n docElement.className.baseVal = className;\\\\n } else {\\\\n docElement.className = className;\\\\n }\\\\n }\\\\n }\\\\n\\\\n ;\\\\n\\\\n /**\\\\n * If the browsers follow the spec, then they would expose vendor-specific styles as:\\\\n * elem.style.WebkitBorderRadius\\\\n * instead of something like the following (which is technically incorrect):\\\\n * elem.style.webkitBorderRadius\\\\n *\\\\n * WebKit ghosts their properties in lowercase but Opera & Moz do not.\\\\n * Microsoft uses a lowercase \`ms\` instead of the correct \`Ms\` in IE8+\\\\n * erik.eae.net/archives/2008/03/10/21.48.10/\\\\n *\\\\n * More here: github.com/Modernizr/Modernizr/issues/issue/21\\\\n *\\\\n * @access private\\\\n * @returns {string} The string representing the vendor-specific style properties\\\\n */\\\\n var omPrefixes = 'Moz O ms Webkit';\\\\n \\\\n\\\\n var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []);\\\\n ModernizrProto._cssomPrefixes = cssomPrefixes;\\\\n \\\\n\\\\n /**\\\\n * contains checks to see if a string contains another string\\\\n *\\\\n * @access private\\\\n * @function contains\\\\n * @param {string} str - The string we want to check for substrings\\\\n * @param {string} substr - The substring we want to search the first string for\\\\n * @returns {boolean} true if and only if the first string 'str' contains the second string 'substr'\\\\n */\\\\n function contains(str, substr) {\\\\n return !!~('' + str).indexOf(substr);\\\\n }\\\\n\\\\n ;\\\\n\\\\n /**\\\\n * createElement is a convenience wrapper around document.createElement. Since we\\\\n * use createElement all over the place, this allows for (slightly) smaller code\\\\n * as well as abstracting away issues with creating elements in contexts other than\\\\n * HTML documents (e.g. SVG documents).\\\\n *\\\\n * @access private\\\\n * @function createElement\\\\n * @returns {HTMLElement|SVGElement} An HTML or SVG element\\\\n */\\\\n function createElement() {\\\\n if (typeof document.createElement !== 'function') {\\\\n // This is the case in IE7, where the type of createElement is \\\\\\"object\\\\\\".\\\\n // For this reason, we cannot call apply() as Object is not a Function.\\\\n return document.createElement(arguments[0]);\\\\n } else if (isSVG) {\\\\n return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]);\\\\n } else {\\\\n return document.createElement.apply(document, arguments);\\\\n }\\\\n }\\\\n\\\\n ;\\\\n\\\\n /**\\\\n * Create our \\\\\\"modernizr\\\\\\" element that we do most feature tests on.\\\\n *\\\\n * @access private\\\\n */\\\\n var modElem = {\\\\n elem: createElement('modernizr')\\\\n };\\\\n\\\\n // Clean up this element\\\\n Modernizr._q.push(function() {\\\\n delete modElem.elem;\\\\n });\\\\n\\\\n \\\\n\\\\n var mStyle = {\\\\n style: modElem.elem.style\\\\n };\\\\n\\\\n // kill ref for gc, must happen before mod.elem is removed, so we unshift on to\\\\n // the front of the queue.\\\\n Modernizr._q.unshift(function() {\\\\n delete mStyle.style;\\\\n });\\\\n\\\\n \\\\n\\\\n /**\\\\n * getBody returns the body of a document, or an element that can stand in for\\\\n * the body if a real body does not exist\\\\n *\\\\n * @access private\\\\n * @function getBody\\\\n * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an\\\\n * artificially created element that stands in for the body\\\\n */\\\\n function getBody() {\\\\n // After page load injecting a fake body doesn't work so check if body exists\\\\n var body = document.body;\\\\n\\\\n if (!body) {\\\\n // Can't use the real body create a fake one.\\\\n body = createElement(isSVG ? 'svg' : 'body');\\\\n body.fake = true;\\\\n }\\\\n\\\\n return body;\\\\n }\\\\n\\\\n ;\\\\n\\\\n /**\\\\n * injectElementWithStyles injects an element with style element and some CSS rules\\\\n *\\\\n * @access private\\\\n * @function injectElementWithStyles\\\\n * @param {string} rule - String representing a css rule\\\\n * @param {Function} callback - A function that is used to test the injected element\\\\n * @param {number} [nodes] - An integer representing the number of additional nodes you want injected\\\\n * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes\\\\n * @returns {boolean} the result of the specified callback test\\\\n */\\\\n function injectElementWithStyles(rule, callback, nodes, testnames) {\\\\n var mod = 'modernizr';\\\\n var style;\\\\n var ret;\\\\n var node;\\\\n var docOverflow;\\\\n var div = createElement('div');\\\\n var body = getBody();\\\\n\\\\n if (parseInt(nodes, 10)) {\\\\n // In order not to give false positives we create a node for each test\\\\n // This also allows the method to scale for unspecified uses\\\\n while (nodes--) {\\\\n node = createElement('div');\\\\n node.id = testnames ? testnames[nodes] : mod + (nodes + 1);\\\\n div.appendChild(node);\\\\n }\\\\n }\\\\n\\\\n style = createElement('style');\\\\n style.type = 'text/css';\\\\n style.id = 's' + mod;\\\\n\\\\n // 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.\\\\n // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270\\\\n (!body.fake ? div : body).appendChild(style);\\\\n body.appendChild(div);\\\\n\\\\n if (style.styleSheet) {\\\\n style.styleSheet.cssText = rule;\\\\n } else {\\\\n style.appendChild(document.createTextNode(rule));\\\\n }\\\\n div.id = mod;\\\\n\\\\n if (body.fake) {\\\\n //avoid crashing IE8, if background image is used\\\\n body.style.background = '';\\\\n //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible\\\\n body.style.overflow = 'hidden';\\\\n docOverflow = docElement.style.overflow;\\\\n docElement.style.overflow = 'hidden';\\\\n docElement.appendChild(body);\\\\n }\\\\n\\\\n ret = callback(div, rule);\\\\n // If this is done after page load we don't want to remove the body so check if body exists\\\\n if (body.fake) {\\\\n body.parentNode.removeChild(body);\\\\n docElement.style.overflow = docOverflow;\\\\n // Trigger layout so kinetic scrolling isn't disabled in iOS6+\\\\n // eslint-disable-next-line\\\\n docElement.offsetHeight;\\\\n } else {\\\\n div.parentNode.removeChild(div);\\\\n }\\\\n\\\\n return !!ret;\\\\n }\\\\n\\\\n ;\\\\n\\\\n /**\\\\n * domToCSS takes a camelCase string and converts it to kebab-case\\\\n * e.g. boxSizing -> box-sizing\\\\n *\\\\n * @access private\\\\n * @function domToCSS\\\\n * @param {string} name - String name of camelCase prop we want to convert\\\\n * @returns {string} The kebab-case version of the supplied name\\\\n */\\\\n function domToCSS(name) {\\\\n return name.replace(/([A-Z])/g, function(str, m1) {\\\\n return '-' + m1.toLowerCase();\\\\n }).replace(/^ms-/, '-ms-');\\\\n }\\\\n\\\\n ;\\\\n\\\\n\\\\n /**\\\\n * wrapper around getComputedStyle, to fix issues with Firefox returning null when\\\\n * called inside of a hidden iframe\\\\n *\\\\n * @access private\\\\n * @function computedStyle\\\\n * @param {HTMLElement|SVGElement} elem - The element we want to find the computed styles of\\\\n * @param {string|null} [pseudo] - An optional pseudo element selector (e.g. :before), of null if none\\\\n * @param {string} prop - A CSS property\\\\n * @returns {CSSStyleDeclaration} the value of the specified CSS property\\\\n */\\\\n function computedStyle(elem, pseudo, prop) {\\\\n var result;\\\\n\\\\n if ('getComputedStyle' in window) {\\\\n result = getComputedStyle.call(window, elem, pseudo);\\\\n var console = window.console;\\\\n\\\\n if (result !== null) {\\\\n if (prop) {\\\\n result = result.getPropertyValue(prop);\\\\n }\\\\n } else {\\\\n if (console) {\\\\n var method = console.error ? 'error' : 'log';\\\\n console[method].call(console, 'getComputedStyle returning null, its possible modernizr test results are inaccurate');\\\\n }\\\\n }\\\\n } else {\\\\n result = !pseudo && elem.currentStyle && elem.currentStyle[prop];\\\\n }\\\\n\\\\n return result;\\\\n }\\\\n\\\\n ;\\\\n\\\\n /**\\\\n * nativeTestProps allows for us to use native feature detection functionality if available.\\\\n * some prefixed form, or false, in the case of an unsupported rule\\\\n *\\\\n * @access private\\\\n * @function nativeTestProps\\\\n * @param {Array} props - An array of property names\\\\n * @param {string} value - A string representing the value we want to check via @supports\\\\n * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise\\\\n */\\\\n // Accepts a list of property names and a single value\\\\n // Returns \`undefined\` if native detection not available\\\\n function nativeTestProps(props, value) {\\\\n var i = props.length;\\\\n // Start with the JS API: https://www.w3.org/TR/css3-conditional/#the-css-interface\\\\n if ('CSS' in window && 'supports' in window.CSS) {\\\\n // Try every prefixed variant of the property\\\\n while (i--) {\\\\n if (window.CSS.supports(domToCSS(props[i]), value)) {\\\\n return true;\\\\n }\\\\n }\\\\n return false;\\\\n }\\\\n // Otherwise fall back to at-rule (for Opera 12.x)\\\\n else if ('CSSSupportsRule' in window) {\\\\n // Build a condition string for every prefixed variant\\\\n var conditionText = [];\\\\n while (i--) {\\\\n conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');\\\\n }\\\\n conditionText = conditionText.join(' or ');\\\\n return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) {\\\\n return computedStyle(node, null, 'position') === 'absolute';\\\\n });\\\\n }\\\\n return undefined;\\\\n }\\\\n ;\\\\n\\\\n /**\\\\n * cssToDOM takes a kebab-case string and converts it to camelCase\\\\n * e.g. box-sizing -> boxSizing\\\\n *\\\\n * @access private\\\\n * @function cssToDOM\\\\n * @param {string} name - String name of kebab-case prop we want to convert\\\\n * @returns {string} The camelCase version of the supplied name\\\\n */\\\\n function cssToDOM(name) {\\\\n return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {\\\\n return m1 + m2.toUpperCase();\\\\n }).replace(/^-/, '');\\\\n }\\\\n\\\\n ;\\\\n\\\\n // testProps is a generic CSS / DOM property test.\\\\n\\\\n // In testing support for a given CSS property, it's legit to test:\\\\n // \`elem.style[styleName] !== undefined\`\\\\n // If the property is supported it will return an empty string,\\\\n // if unsupported it will return undefined.\\\\n\\\\n // We'll take advantage of this quick test and skip setting a style\\\\n // on our modernizr element, but instead just testing undefined vs\\\\n // empty string.\\\\n\\\\n // Property names can be provided in either camelCase or kebab-case.\\\\n\\\\n function testProps(props, prefixed, value, skipValueTest) {\\\\n skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest;\\\\n\\\\n // Try native detect first\\\\n if (!is(value, 'undefined')) {\\\\n var result = nativeTestProps(props, value);\\\\n if (!is(result, 'undefined')) {\\\\n return result;\\\\n }\\\\n }\\\\n\\\\n // Otherwise do it properly\\\\n var afterInit, i, propsLength, prop, before;\\\\n\\\\n // If we don't have a style element, that means we're running async or after\\\\n // the core tests, so we'll need to create our own elements to use.\\\\n\\\\n // Inside of an SVG element, in certain browsers, the \`style\` element is only\\\\n // defined for valid tags. Therefore, if \`modernizr\` does not have one, we\\\\n // fall back to a less used element and hope for the best.\\\\n // For strict XHTML browsers the hardly used samp element is used.\\\\n var elems = ['modernizr', 'tspan', 'samp'];\\\\n while (!mStyle.style && elems.length) {\\\\n afterInit = true;\\\\n mStyle.modElem = createElement(elems.shift());\\\\n mStyle.style = mStyle.modElem.style;\\\\n }\\\\n\\\\n // Delete the objects if we created them.\\\\n function cleanElems() {\\\\n if (afterInit) {\\\\n delete mStyle.style;\\\\n delete mStyle.modElem;\\\\n }\\\\n }\\\\n\\\\n propsLength = props.length;\\\\n for (i = 0; i < propsLength; i++) {\\\\n prop = props[i];\\\\n before = mStyle.style[prop];\\\\n\\\\n if (contains(prop, '-')) {\\\\n prop = cssToDOM(prop);\\\\n }\\\\n\\\\n if (mStyle.style[prop] !== undefined) {\\\\n\\\\n // If value to test has been passed in, do a set-and-check test.\\\\n // 0 (integer) is a valid property value, so check that \`value\` isn't\\\\n // undefined, rather than just checking it's truthy.\\\\n if (!skipValueTest && !is(value, 'undefined')) {\\\\n\\\\n // Needs a try catch block because of old IE. This is slow, but will\\\\n // be avoided in most cases because \`skipValueTest\` will be used.\\\\n try {\\\\n mStyle.style[prop] = value;\\\\n } catch (e) {}\\\\n\\\\n // If the property value has changed, we assume the value used is\\\\n // supported. If \`value\` is empty string, it'll fail here (because\\\\n // it hasn't changed), which matches how browsers have implemented\\\\n // CSS.supports()\\\\n if (mStyle.style[prop] !== before) {\\\\n cleanElems();\\\\n return prefixed === 'pfx' ? prop : true;\\\\n }\\\\n }\\\\n // Otherwise just return true, or the property name if this is a\\\\n // \`prefixed()\` call\\\\n else {\\\\n cleanElems();\\\\n return prefixed === 'pfx' ? prop : true;\\\\n }\\\\n }\\\\n }\\\\n cleanElems();\\\\n return false;\\\\n }\\\\n\\\\n ;\\\\n\\\\n /**\\\\n * List of JavaScript DOM values used for tests\\\\n *\\\\n * @memberOf Modernizr\\\\n * @name Modernizr._domPrefixes\\\\n * @optionName Modernizr._domPrefixes\\\\n * @optionProp domPrefixes\\\\n * @access public\\\\n * @example\\\\n *\\\\n * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather\\\\n * than kebab-case properties, all properties are their Capitalized variant\\\\n *\\\\n * \`\`\`js\\\\n * Modernizr._domPrefixes === [ \\\\\\"Moz\\\\\\", \\\\\\"O\\\\\\", \\\\\\"ms\\\\\\", \\\\\\"Webkit\\\\\\" ];\\\\n * \`\`\`\\\\n */\\\\n var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []);\\\\n ModernizrProto._domPrefixes = domPrefixes;\\\\n \\\\n\\\\n /**\\\\n * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill.\\\\n *\\\\n * @access private\\\\n * @function fnBind\\\\n * @param {Function} fn - a function you want to change \`this\` reference to\\\\n * @param {object} that - the \`this\` you want to call the function with\\\\n * @returns {Function} The wrapped version of the supplied function\\\\n */\\\\n function fnBind(fn, that) {\\\\n return function() {\\\\n return fn.apply(that, arguments);\\\\n };\\\\n }\\\\n\\\\n ;\\\\n\\\\n /**\\\\n * testDOMProps is a generic DOM property test; if a browser supports\\\\n * a certain property, it won't return undefined for it.\\\\n *\\\\n * @access private\\\\n * @function testDOMProps\\\\n * @param {Array} props - An array of properties to test for\\\\n * @param {object} obj - An object or Element you want to use to test the parameters again\\\\n * @param {boolean|object} elem - An Element to bind the property lookup again. Use \`false\` to prevent the check\\\\n * @returns {boolean|*} returns \`false\` if the prop is unsupported, otherwise the value that is supported\\\\n */\\\\n function testDOMProps(props, obj, elem) {\\\\n var item;\\\\n\\\\n for (var i in props) {\\\\n if (props[i] in obj) {\\\\n\\\\n // return the property name as a string\\\\n if (elem === false) {\\\\n return props[i];\\\\n }\\\\n\\\\n item = obj[props[i]];\\\\n\\\\n // let's bind a function\\\\n if (is(item, 'function')) {\\\\n // bind to obj unless overridden\\\\n return fnBind(item, elem || obj);\\\\n }\\\\n\\\\n // return the unbound function or obj or value\\\\n return item;\\\\n }\\\\n }\\\\n return false;\\\\n }\\\\n\\\\n ;\\\\n\\\\n /**\\\\n * testPropsAll tests a list of DOM properties we want to check against.\\\\n * We specify literally ALL possible (known and/or likely) properties on\\\\n * the element including the non-vendor prefixed one, for forward-\\\\n * compatibility.\\\\n *\\\\n * @access private\\\\n * @function testPropsAll\\\\n * @param {string} prop - A string of the property to test for\\\\n * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip\\\\n * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against\\\\n * @param {string} [value] - A string of a css value\\\\n * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set\\\\n * @returns {string|boolean} returns the string version of the property, or \`false\` if it is unsupported\\\\n */\\\\n function testPropsAll(prop, prefixed, elem, value, skipValueTest) {\\\\n\\\\n var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),\\\\n props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');\\\\n\\\\n // did they call .prefixed('boxSizing') or are we just testing a prop?\\\\n if (is(prefixed, 'string') || is(prefixed, 'undefined')) {\\\\n return testProps(props, prefixed, value, skipValueTest);\\\\n\\\\n // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])\\\\n } else {\\\\n props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');\\\\n return testDOMProps(props, prefixed, elem);\\\\n }\\\\n }\\\\n\\\\n // Modernizr.testAllProps() investigates whether a given style property,\\\\n // or any of its vendor-prefixed variants, is recognized\\\\n //\\\\n // Note that the property names must be provided in the camelCase variant.\\\\n // Modernizr.testAllProps('boxSizing')\\\\n ModernizrProto.testAllProps = testPropsAll;\\\\n\\\\n \\\\n\\\\n /**\\\\n * testAllProps determines whether a given CSS property is supported in the browser\\\\n *\\\\n * @memberOf Modernizr\\\\n * @name Modernizr.testAllProps\\\\n * @optionName Modernizr.testAllProps()\\\\n * @optionProp testAllProps\\\\n * @access public\\\\n * @function testAllProps\\\\n * @param {string} prop - String naming the property to test (either camelCase or kebab-case)\\\\n * @param {string} [value] - String of the value to test\\\\n * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection\\\\n * @returns {string|boolean} returns the string version of the property, or \`false\` if it is unsupported\\\\n * @example\\\\n *\\\\n * testAllProps determines whether a given CSS property, in some prefixed form,\\\\n * is supported by the browser.\\\\n *\\\\n * \`\`\`js\\\\n * testAllProps('boxSizing') // true\\\\n * \`\`\`\\\\n *\\\\n * It can optionally be given a CSS value in string form to test if a property\\\\n * value is valid\\\\n *\\\\n * \`\`\`js\\\\n * testAllProps('display', 'block') // true\\\\n * testAllProps('display', 'penguin') // false\\\\n * \`\`\`\\\\n *\\\\n * A boolean can be passed as a third parameter to skip the value check when\\\\n * native detection (@supports) isn't available.\\\\n *\\\\n * \`\`\`js\\\\n * testAllProps('shapeOutside', 'content-box', true);\\\\n * \`\`\`\\\\n */\\\\n function testAllProps(prop, value, skipValueTest) {\\\\n return testPropsAll(prop, undefined, undefined, value, skipValueTest);\\\\n }\\\\n\\\\n ModernizrProto.testAllProps = testAllProps;\\\\n\\\\n \\\\n/*!\\\\n{\\\\n \\\\\\"name\\\\\\": \\\\\\"Flexbox\\\\\\",\\\\n \\\\\\"property\\\\\\": \\\\\\"flexbox\\\\\\",\\\\n \\\\\\"caniuse\\\\\\": \\\\\\"flexbox\\\\\\",\\\\n \\\\\\"tags\\\\\\": [\\\\\\"css\\\\\\"],\\\\n \\\\\\"notes\\\\\\": [{\\\\n \\\\\\"name\\\\\\": \\\\\\"The _new_ flexbox\\\\\\",\\\\n \\\\\\"href\\\\\\": \\\\\\"https://www.w3.org/TR/css-flexbox-1/\\\\\\"\\\\n }],\\\\n \\\\\\"warnings\\\\\\": [\\\\n \\\\\\"A \`true\` result for this detect does not imply that the \`flex-wrap\` property is supported; see the \`flexwrap\` detect.\\\\\\"\\\\n ]\\\\n}\\\\n!*/\\\\n/* DOC\\\\nDetects support for the Flexible Box Layout model, a.k.a. Flexbox, which allows easy manipulation of layout order and sizing within a container.\\\\n*/\\\\n\\\\n Modernizr.addTest('flexbox', testAllProps('flexBasis', '1px', true));\\\\n\\\\n/*!\\\\n{\\\\n \\\\\\"name\\\\\\": \\\\\\"ES6 Promises\\\\\\",\\\\n \\\\\\"property\\\\\\": \\\\\\"promises\\\\\\",\\\\n \\\\\\"caniuse\\\\\\": \\\\\\"promises\\\\\\",\\\\n \\\\\\"polyfills\\\\\\": [\\\\\\"es6promises\\\\\\"],\\\\n \\\\\\"authors\\\\\\": [\\\\\\"Krister Kari\\\\\\", \\\\\\"Jake Archibald\\\\\\"],\\\\n \\\\\\"tags\\\\\\": [\\\\\\"es6\\\\\\"],\\\\n \\\\\\"notes\\\\\\": [{\\\\n \\\\\\"name\\\\\\": \\\\\\"The ES6 promises spec\\\\\\",\\\\n \\\\\\"href\\\\\\": \\\\\\"https://github.com/domenic/promises-unwrapping\\\\\\"\\\\n }, {\\\\n \\\\\\"name\\\\\\": \\\\\\"Chromium dashboard - ES6 Promises\\\\\\",\\\\n \\\\\\"href\\\\\\": \\\\\\"https://www.chromestatus.com/features/5681726336532480\\\\\\"\\\\n }, {\\\\n \\\\\\"name\\\\\\": \\\\\\"JavaScript Promises: an Introduction\\\\\\",\\\\n \\\\\\"href\\\\\\": \\\\\\"https://developers.google.com/web/fundamentals/primers/promises/\\\\\\"\\\\n }]\\\\n}\\\\n!*/\\\\n/* DOC\\\\nCheck if browser implements ECMAScript 6 Promises per specification.\\\\n*/\\\\n\\\\n Modernizr.addTest('promises', function() {\\\\n return 'Promise' in window &&\\\\n // Some of these methods are missing from\\\\n // Firefox/Chrome experimental implementations\\\\n 'resolve' in window.Promise &&\\\\n 'reject' in window.Promise &&\\\\n 'all' in window.Promise &&\\\\n 'race' in window.Promise &&\\\\n // Older version of the spec had a resolver object\\\\n // as the arg rather than a function\\\\n (function() {\\\\n var resolve;\\\\n new window.Promise(function(r) { resolve = r; });\\\\n return typeof resolve === 'function';\\\\n }());\\\\n });\\\\n\\\\n/*!\\\\n{\\\\n \\\\\\"name\\\\\\": \\\\\\"ServiceWorker API\\\\\\",\\\\n \\\\\\"property\\\\\\": \\\\\\"serviceworker\\\\\\",\\\\n \\\\\\"notes\\\\\\": [{\\\\n \\\\\\"name\\\\\\": \\\\\\"ServiceWorkers Explained\\\\\\",\\\\n \\\\\\"href\\\\\\": \\\\\\"https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md\\\\\\"\\\\n }]\\\\n}\\\\n!*/\\\\n/* DOC\\\\nServiceWorkers (formerly Navigation Controllers) are a way to persistently cache resources to built apps that work better offline.\\\\n*/\\\\n\\\\n Modernizr.addTest('serviceworker', 'serviceWorker' in navigator);\\\\n\\\\n\\\\n // Run each test\\\\n testRunner();\\\\n\\\\n // Remove the \\\\\\"no-js\\\\\\" class if it exists\\\\n setClasses(classes);\\\\n\\\\n delete ModernizrProto.addTest;\\\\n delete ModernizrProto.addAsyncTest;\\\\n\\\\n // Run the things that are supposed to run after the tests\\\\n for (var i = 0; i < Modernizr._q.length; i++) {\\\\n Modernizr._q[i]();\\\\n }\\\\n\\\\n // Leak Modernizr namespace\\\\n scriptGlobalObject.Modernizr = Modernizr;\\\\n\\\\n\\\\n;\\\\n\\\\n})(window, window, document);\\\\n modernizr = window.Modernizr; if (hadGlobal) { window.Modernizr = oldGlobal; } else { delete window.Modernizr; } export default modernizr;\\", + \\"map\\": null, + \\"meta\\": null, + \\"dependencies\\": [ + \\"test/fixtures/presets/modernizr.js\\" + ], + \\"contextDependencies\\": [] +}" +`; + +exports[`loader should pass on the code from the presets/modernizr fixture: warnings 1`] = `Array []`; + exports[`loader should pass on the code from the simple fixture without options: errors 1`] = `Array []`; exports[`loader should pass on the code from the simple fixture without options: result 1`] = ` diff --git a/test/fixtures/presets/modernizr.js b/test/fixtures/presets/modernizr.js new file mode 100644 index 0000000..64a52b9 --- /dev/null +++ b/test/fixtures/presets/modernizr.js @@ -0,0 +1,13 @@ +const modernizr = require("modernizr"); + +module.exports = function(options) { + return new Promise(function(resolve) { + // It is impossible to throw an error because modernizr causes the process.exit(1) + modernizr.build(options, function(output) { + resolve({ + cacheable: true, + code: `var modernizr; var hadGlobal = 'Modernizr' in window; var oldGlobal = window.Modernizr; ${output} modernizr = window.Modernizr; if (hadGlobal) { window.Modernizr = oldGlobal; } else { delete window.Modernizr; } export default modernizr;` + }); + }); + }); +}; diff --git a/test/loader.test.js b/test/loader.test.js index b028fab..70609cc 100644 --- a/test/loader.test.js +++ b/test/loader.test.js @@ -309,4 +309,25 @@ describe('loader', () => { ); expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors'); }); + + it('should pass on the code from the presets/modernizr fixture', async () => { + const compiler = getCompiler('presets/modernizr.js', { + minify: false, + options: ['setClasses'], + 'feature-detects': [ + 'test/css/flexbox', + 'test/es6/promises', + 'test/serviceworker', + ], + }); + const stats = await compile(compiler); + + expect(readAsset('val-loader.js', compiler, stats)).toMatchSnapshot( + 'result' + ); + expect(normalizeErrors(stats.compilation.warnings)).toMatchSnapshot( + 'warnings' + ); + expect(normalizeErrors(stats.compilation.errors)).toMatchSnapshot('errors'); + }); });