diff options
Diffstat (limited to 'node_modules/browserslist')
| l--------- | node_modules/browserslist/.bin/browserslist | 1 | ||||
| -rw-r--r-- | node_modules/browserslist/CHANGELOG.md | 135 | ||||
| -rw-r--r-- | node_modules/browserslist/LICENSE | 20 | ||||
| -rw-r--r-- | node_modules/browserslist/README.md | 331 | ||||
| -rwxr-xr-x | node_modules/browserslist/cli.js | 95 | ||||
| -rw-r--r-- | node_modules/browserslist/index.js | 648 | ||||
| -rw-r--r-- | node_modules/browserslist/package.json | 54 |
7 files changed, 1284 insertions, 0 deletions
diff --git a/node_modules/browserslist/.bin/browserslist b/node_modules/browserslist/.bin/browserslist new file mode 120000 index 00000000..9fbea327 --- /dev/null +++ b/node_modules/browserslist/.bin/browserslist @@ -0,0 +1 @@ +../cli.js
\ No newline at end of file diff --git a/node_modules/browserslist/CHANGELOG.md b/node_modules/browserslist/CHANGELOG.md new file mode 100644 index 00000000..5e895bcb --- /dev/null +++ b/node_modules/browserslist/CHANGELOG.md @@ -0,0 +1,135 @@ +# Change Log +This project adheres to [Semantic Versioning](http://semver.org/). + +## 1.7.7 +* Update Firefox ESR. + +## 1.7.6 +* Fix Android Chrome selection. + +## 1.7.5 +* Fix combining `not` query with country based statistics. +* Fix `--env` argument in CLI (by Tuure Savuoja). + +## 1.7.4 +* Speed up browser sorting (by Aarni Koskela). + +## 1.7.3 +* Fix config finding when directory was passed to `path` (by Aarni Koskela). + +## 1.7.2 +* Fix config finding algorithm (by Aarni Koskela). + +## 1.7.1 +* Fix unreleased browsers version detection. + +## 1.7 +* Add `--config` and `--env` arguments to CLI (by Jarek Rencz). + +## 1.6 +* Convert Electron version to Chrome (by Kilian Valkhof). +* Fix `0` version mistake in Can I Use data. + +## 1.5.2 +* Fix browser versions ordering (by Marco Massarotto). + +## 1.5.1 +* Fix error on `package.json` and `browserslist` in same directory. + +## 1.5 +* Add `package.json` support (by Stepan Kuzmin). +* Add environments support (by Maksim Semenov and openlibser). +* Add `browserslist-stats.json` file support (by Oleh Aloshkin). +* Add `config` option to CLI (by Evilebot Tnawi). +* Add JSDoc. +* Fix tests on Windows (by Anna Stoliar). +* Don’t set custom usage statistics globally. + +## 1.4 +* Add `defaults` keyword. + +## 1.3.6 +* Add `UCAndroid` alias to `and_uc` (by Evilebot Tnawi). + +## 1.3.5 +* Fix Opera Mini support. Use `op_mini all`. + +## 1.3.4 +* Add space-less `>1%` and `>.5%` syntax support (by Andreas Lind). + +## 1.3.3 +* Clean `0` versions in some country-based requests. + +## 1.3.2 +* Update Firefox ESR. + +## 1.3.1 +* Add Safari TP support. + +## 1.3 +* Add coverage for specific country (by Joshua Wise). + +## 1.2 +* Add `browserslist.coverage()` method. +* Add `--coverage` and `-c` argument to CLI. +* Add `-v` argument support to CLI. +* Better error handling in CLI. + +## 1.1.3 +* Fix jspm support (by Sean Anderson). + +## 1.1.2 +* Fix jspm support (by Sean Anderson). + +## 1.1.1 +* Fix space-less `>10%` and `>10% in my stats` queries. +* Normalize error messages. +* Remove development files from npm package. + +## 1.1 +* Added query against custom browser usage data (by Daniel Rey). + +## 1.0.1 +* Update Firefox ESR (by Rouven Weßling). + +## 1.0 +* Remove Opera 12.1 from default query. +* Add `not` keyword and exclude browsers by query. +* Add Microsoft Edge support (by Andrey Polischuk). +* Add CLI for debug and non-JS usage (by Luke Horvat). +* Use own class in Browserslist errors. + +## 0.5 +* Add version ranges `IE 6-9` (by Ben Briggs). + +## 0.4 +* Add `config` option and `BROWSERSLIST_CONFIG` environment variable support. +* Add symlink config support. + +## 0.3.3 +* Fix DynJS compatibility (by Nick Howes). + +## 0.3.2 +* Fix joined versions on versions query (by Vincent De Oliveira). + +## 0.3.1 +* Fix global variable leak (by Peter Müller). + +## 0.3 +* Takes queries from `BROWSERSLIST` environment variable. + +## 0.2 +* Return Can I Use joined versions as `ios_saf 7.0-7.1`. + +## 0.1.3 +* Better work with Can I Use joined versions like `ios_saf 7.0-7.1`. +* Browserslist now understands `ios_saf 7.0` or `ios_saf 7`. + +## 0.1.2 +* Do not create global `browserslist` var (by Maxime Thirouin). + +## 0.1.1 +* Sort browsers by name and version. + +## 0.1 +* Initial release. diff --git a/node_modules/browserslist/LICENSE b/node_modules/browserslist/LICENSE new file mode 100644 index 00000000..1ae47a20 --- /dev/null +++ b/node_modules/browserslist/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright 2014 Andrey Sitnik <andrey@sitnik.ru> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/browserslist/README.md b/node_modules/browserslist/README.md new file mode 100644 index 00000000..0de38817 --- /dev/null +++ b/node_modules/browserslist/README.md @@ -0,0 +1,331 @@ +# Browserslist + +Library to share supported browsers list between different front-end tools. +It is used in [Autoprefixer], [Stylelint], [eslint-plugin-compat] +and [babel-env-preset]. + +All tools that rely on Browserslist will find its config automatically, +when you add the following to `package.json`: + +```json +{ + "browserslist": [ + "> 1%", + "last 2 versions" + ] +} +``` + +Or in `browserslist` config: + +```yaml +# Browsers that we support + +> 1% +Last 2 versions +IE 10 # sorry +``` + +Developers set browsers list in queries like `last 2 version` +to be free from updating browser versions manually. +Browserslist will use [Can i Use] data for this queries. + +Browserslist will take browsers queries from tool option, +`browserslist` config, `browserslist` section in `package.json` +or environment variables. + +You can test Browserslist queries in [online demo]. + +<a href="https://evilmartians.com/?utm_source=browserslist"> + <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" + alt="Sponsored by Evil Martians" + width="236" + height="54" + \> +</a> + +[eslint-plugin-compat]: https://github.com/amilajack/eslint-plugin-compat +[babel-env-preset]: https://github.com/babel/babel-preset-env +[Autoprefixer]: https://github.com/postcss/autoprefixer +[online demo]: http://browserl.ist/ +[Stylelint]: http://stylelint.io/ +[Can I Use]: http://caniuse.com/ + +## Queries + +Browserslist will use browsers query from one of this sources: + +1. Tool options. For example `browsers` option in Autoprefixer. +2. `BROWSERSLIST` environment variable. +3. `browserslist` config file in current or parent directories. +4. `browserslist` key in `package.json` file in current or parent directories. +5. If the above methods did not produce a valid result + Browserslist will use defaults: `> 1%, last 2 versions, Firefox ESR`. + +We recommend to write queries in `browserslist` config or `package.json`. + +You can specify the versions by queries (case insensitive): + +* `last 2 versions`: the last 2 versions for each major browser. +* `last 2 Chrome versions`: the last 2 versions of Chrome browser. +* `> 5%`: versions selected by global usage statistics. +* `> 5% in US`: uses USA usage statistics. It accepts [two-letter country code]. +* `> 5% in my stats`: uses [custom usage data]. +* `ie 6-8`: selects an inclusive range of versions. +* `Firefox > 20`: versions of Firefox newer than 20. +* `Firefox >= 20`: versions of Firefox newer than or equal to 20. +* `Firefox < 20`: versions of Firefox less than 20. +* `Firefox <= 20`: versions of Firefox less than or equal to 20. +* `Firefox ESR`: the latest [Firefox ESR] version. +* `iOS 7`: the iOS browser version 7 directly. +* `not ie <= 8`: exclude browsers selected before by previous queries. + You can add `not ` to any query. + +Browserslist works with separated versions of browsers. +You should avoid queries like `Firefox > 0`. + +Multiple criteria are combined as a boolean `OR`. A browser version must match +at least one of the criteria to be selected. + +All queries are based on the [Can I Use] support table, +e.g. `last 3 iOS versions` might select `8.4, 9.2, 9.3` (mixed major and minor), +whereas `last 3 Chrome versions` might select `50, 49, 48` (major only). + +[two-letter country code]: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements +[custom usage data]: #custom-usage-data +[Can I Use]: http://caniuse.com/ + +## Browsers + +Names are case insensitive: + +### Major Browsers + +* `Chrome` for Google Chrome. +* `Firefox` or `ff` for Mozilla Firefox. +* `Explorer` or `ie` for Internet Explorer. +* `Edge` for Microsoft Edge. +* `iOS` or `ios_saf` for iOS Safari. +* `Opera` for Opera. +* `Safari` for desktop Safari. +* `ExplorerMobile` or `ie_mob` for Internet Explorer Mobile. + +### Others + +* `Android` for Android WebView. +* `BlackBerry` or `bb` for Blackberry browser. +* `ChromeAndroid` or `and_chr` for Chrome for Android + (in Other section, because mostly same as common `Chrome`). +* `FirefoxAndroid` or `and_ff` for Firefox for Android. +* `OperaMobile` or `op_mob` for Opera Mobile. +* `OperaMini` or `op_mini` for Opera Mini. +* `Samsung` for Samsung Internet. +* `UCAndroid` or `and_uc` for UC Browser for Android. +* `Electron` for Electron framework. It will be converted to Chrome version. + +### Electron + +[`electron-to-chromium`](https://www.npmjs.com/package/electron-to-chromium) +could return a compatible Browserslist query +for your (major) Electron version: + +```js +const e2c = require('electron-to-chromium') +autoprefixer({ + browsers: e2c.electronToBrowserList('1.4') //=> "Chrome >= 53" +}) +``` + +## Config File + +Browserslist config should be named `browserslist` and have browsers queries +split by a new line. Comments starts with `#` symbol: + +```yaml +# Browsers that we support + +> 1% +Last 2 versions +IE 8 # sorry +``` + +Browserslist will check config in every directory in `path`. +So, if tool process `app/styles/main.css`, you can put config to root, +`app/` or `app/styles`. + +You can specify direct path in `BROWSERSLIST_CONFIG` environment variables. + +## `package.json` + +If you want to reduce config files in project root, you can specify +browsers in `package.json` with `browserslist` key: + +```js +{ + "private": true, + "dependencies": { + "autoprefixer": "^6.5.4" + }, + "browserslist": [ + "> 1%", + "last 2 versions" + ] +} +``` + +## Environments + +You can also specify different browser queries for various environments. +Browserslist will choose query according to `BROWSERSLIST_ENV` or `NODE_ENV` +variables. If none of them is declared, Browserslist will firstly look +for `development` queries and then use defaults. + +In `package.json`: + +```js +{ + … + "browserslist": { + "production": [ + "last 2 version", + "ie 9" + ], + "development": [ + "last 1 version" + ] + } +} +``` + +In `browserslist` config: + +```ini +[production] +last 2 version +ie 9 + +[development] +last 1 version +``` + +## Environment Variables + +If some tool use Browserslist inside, you can change browsers settings +by [environment variables]: + +* `BROWSERSLIST` with browsers queries. + + ```sh + BROWSERSLIST="> 5%" gulp css + ``` + +* `BROWSERSLIST_CONFIG` with path to config file. + + ```sh + BROWSERSLIST_CONFIG=./config/browserslist gulp css + ``` + +* `BROWSERSLIST_ENV` with environments string. + + ```sh + BROWSERSLIST_ENV="development" gulp css + ``` + +* `BROWSERSLIST_STATS` with path to the custom usage data + for `> 1% in my stats` query. + + ```sh + BROWSERSLIST_STATS=./config/usage_data.json gulp css + ``` + +[environment variables]: https://en.wikipedia.org/wiki/Environment_variable + +## Custom Usage Data + +If you have a website, you can query against the usage statistics of your site: + +1. Import your Google Analytics data into [Can I Use]. + Press `Import…` button in Settings page. +2. Open browser DevTools on [Can I Use] and paste this snippet + into the browser console: + + ```js + var e=document.createElement('a');e.setAttribute('href', 'data:text/plain;charset=utf-8,'+encodeURIComponent(JSON.stringify(JSON.parse(localStorage['usage-data-by-id'])[localStorage['config-primary_usage']])));e.setAttribute('download','stats.json');document.body.appendChild(e);e.click();document.body.removeChild(e); + ``` +3. Save the data to a `browserslist-stats.json` file in your project. + +Of course, you can generate usage statistics file by any other method. +File format should be like: + +```js +{ + "ie": { + "6": 0.01, + "7": 0.4, + "8": 1.5 + }, + "chrome": { + … + }, + … +} +``` + +Note that you can query against your custom usage data +while also querying against global or regional data. +For example, the query `> 1% in my stats, > 5% in US, 10%` is permitted. + +[Can I Use]: http://caniuse.com/ + +## JS API + +```js +var browserslist = require('browserslist'); + +// Your CSS/JS build tool code +var process = function (source, opts) { + var browsers = browserslist(opts.browsers, { + stats: opts.stats, + path: opts.file, + env: opts.env + }); + // Your code to add features for selected browsers +} +``` + +Queries can be a string `"> 5%, last 1 version"` +or an array `['> 5%', 'last 1 version']`. + +If a query is missing, Browserslist will look for a config file. +You can provide a `path` option (that can be a file) to find the config file +relatively to it. + +For non-JS environment and debug purpose you can use CLI tool: + +```sh +browserslist "> 1%, last 2 versions" +``` + +## Coverage + +You can get total users coverage for selected browsers by JS API: + +```js +browserslist.coverage(browserslist('> 1%')) //=> 81.4 +``` + +```js +browserslist.coverage(browserslist('> 1% in US'), 'US') //=> 83.1 +``` + +Or by CLI: + +```sh +$ browserslist --coverage "> 1%" +These browsers account for 81.4% of all users globally +``` + +```sh +$ browserslist --coverage=US "> 1% in US" +These browsers account for 83.1% of all users in the US +``` diff --git a/node_modules/browserslist/cli.js b/node_modules/browserslist/cli.js new file mode 100755 index 00000000..c0848b20 --- /dev/null +++ b/node_modules/browserslist/cli.js @@ -0,0 +1,95 @@ +#!/usr/bin/env node + +var browserslist = require('./'); +var pkg = require('./package.json'); +var args = process.argv.slice(2); + +function isArg(arg) { + return args.some(function (str) { + return str === arg || str.indexOf(arg + '=') === 0; + }); +} + +function getArgValue(arg) { + var found = args.filter(function (str) { + return str.indexOf(arg + '=') === 0; + })[0]; + var value = found && found.split('=')[1]; + return value && value.replace(/^['"]|['"]$/g, ''); +} + +function error(msg) { + process.stderr.write(pkg.name + ': ' + msg + '\n'); + process.exit(1); +} + +function query(queries, opts) { + try { + return browserslist(queries, opts); + } catch (e) { + if ( e.name === 'BrowserslistError' ) { + return error(e.message); + } else { + throw e; + } + } +} + +if ( args.length === 0 || isArg('--help') || isArg('-h') ) { + process.stdout.write([ + pkg.description, + '', + 'Usage:', + ' ' + pkg.name + ' "QUERIES"', + ' ' + pkg.name + ' --coverage "QUERIES"', + ' ' + pkg.name + ' --coverage=US "QUERIES"', + ' ' + pkg.name + ' --config=browserslist "path/to/browserlist/file"', + ' ' + pkg.name + ' --env="environment name defined in config"', + ' ' + pkg.name + ' --stats="path/to/browserlist/stats/file"' + ].join('\n') + '\n'); + +} else if ( isArg('--version') || isArg('-v') ) { + process.stdout.write(pkg.name + ' ' + pkg.version + '\n'); + +} else if ( isArg('--coverage') || isArg('-c') ) { + var browsers = args.find(function (i) { + return i[0] !== '-'; + }); + if ( !browsers ) error('Define a browsers query to get coverage'); + + var country = getArgValue('--coverage') || getArgValue('-c'); + var result = browserslist.coverage(query(browsers), country); + var round = Math.round(result * 100) / 100.0; + + var end = 'globally'; + if (country && country !== 'global') { + end = 'in the ' + country.toUpperCase(); + } + + process.stdout.write( + 'These browsers account for ' + round + '% of all users ' + end + '\n'); + +} else if ( args.length === 1 && args[0][0] !== '-' ) { + query(args[0]).forEach(function (browser) { + process.stdout.write(browser + '\n'); + }); + +} else if (isArg('--config') || isArg('-b')) { + var opts = { + config: getArgValue('--config') || getArgValue('-b') + }; + + if (isArg('--env') || isArg('-e')) { + opts.env = getArgValue('--env') || getArgValue('-e'); + } + + if (isArg('--stats') || isArg('-s')) { + opts.stats = getArgValue('--stats') || getArgValue('-s'); + } + + query(null, opts).forEach(function (browser) { + process.stdout.write(browser + '\n'); + }); +} else { + error('Unknown arguments. Use --help to pick right one.'); +} diff --git a/node_modules/browserslist/index.js b/node_modules/browserslist/index.js new file mode 100644 index 00000000..40623b03 --- /dev/null +++ b/node_modules/browserslist/index.js @@ -0,0 +1,648 @@ +var path = require('path'); +var e2c = require('electron-to-chromium/versions'); +var fs = require('fs'); + +var caniuse = require('caniuse-db/data.json').agents; + +function normalize(versions) { + return versions.filter(function (version) { + return typeof version === 'string'; + }); +} + +var FLOAT_RANGE = /^\d+(\.\d+)?(-\d+(\.\d+)?)*$/; +var IS_SECTION = /^\s*\[(.+)\]\s*$/; + +function uniq(array) { + var filtered = []; + for ( var i = 0; i < array.length; i++ ) { + if ( filtered.indexOf(array[i]) === -1 ) filtered.push(array[i]); + } + return filtered; +} + +function BrowserslistError(message) { + this.name = 'BrowserslistError'; + this.message = message || ''; + this.browserslist = true; + if ( Error.captureStackTrace ) { + Error.captureStackTrace(this, BrowserslistError); + } +} +BrowserslistError.prototype = Error.prototype; + +// Helpers + +function error(name) { + throw new BrowserslistError(name); +} + +function fillUsage(result, name, data) { + for ( var i in data ) { + result[name + ' ' + i] = data[i]; + } +} + +function isFile(file) { + return fs.existsSync(file) && fs.statSync(file).isFile(); +} + +function eachParent(file, callback) { + if ( !fs.readFileSync || !fs.existsSync || !fs.statSync ) { + /* istanbul ignore next */ + return undefined; + } + + if ( file === false ) return undefined; + if ( typeof file === 'undefined' ) file = '.'; + var loc = path.resolve(file); + do { + var result = callback(loc); + if (typeof result !== 'undefined') return result; + } while (loc !== (loc = path.dirname(loc))); + return undefined; +} + +function getStat(opts) { + if ( opts.stats ) { + return opts.stats; + } else if ( process.env.BROWSERSLIST_STATS ) { + return process.env.BROWSERSLIST_STATS; + } else { + return eachParent(opts.path, function (dir) { + var file = path.join(dir, 'browserslist-stats.json'); + if ( isFile(file) ) { + return file; + } + }); + } +} + +function parsePackage(file) { + var config = JSON.parse(fs.readFileSync(file)).browserslist; + if ( typeof config === 'object' && config.length ) { + config = { defaults: config }; + } + return config; +} + +function pickEnv(config, opts) { + if ( typeof config !== 'object' ) return config; + + var env; + if ( typeof opts.env === 'string' ) { + env = opts.env; + } else if ( typeof process.env.BROWSERSLIST_ENV === 'string' ) { + env = process.env.BROWSERSLIST_ENV; + } else if ( typeof process.env.NODE_ENV === 'string' ) { + env = process.env.NODE_ENV; + } else { + env = 'development'; + } + + return config[env] || config.defaults; +} + +function generateFilter(sign, version) { + version = parseFloat(version); + if ( sign === '>' ) { + return function (v) { + return parseFloat(v) > version; + }; + } else if ( sign === '>=' ) { + return function (v) { + return parseFloat(v) >= version; + }; + } else if ( sign === '<' ) { + return function (v) { + return parseFloat(v) < version; + }; + } else if ( sign === '<=' ) { + return function (v) { + return parseFloat(v) <= version; + }; + } +} + +function compareStrings(a, b) { + if (a < b) return -1; + if (a > b) return +1; + return 0; +} + +/** + * Return array of browsers by selection queries. + * + * @param {string[]} queries Browser queries. + * @param {object} opts Options. + * @param {string} [opts.path="."] Path to processed file. + * It will be used to find config files. + * @param {string} [opts.env="development"] Processing environment. + * It will be used to take right + * queries from config file. + * @param {string} [opts.config] Path to config file with queries. + * @param {object} [opts.stats] Custom browser usage statistics + * for "> 1% in my stats" query. + * @return {string[]} Array with browser names in Can I Use. + * + * @example + * browserslist('IE >= 10, IE 8') //=> ['ie 11', 'ie 10', 'ie 8'] + */ +var browserslist = function (queries, opts) { + if ( typeof opts === 'undefined' ) opts = { }; + + if ( typeof queries === 'undefined' || queries === null ) { + if ( process.env.BROWSERSLIST ) { + queries = process.env.BROWSERSLIST; + } else if ( opts.config || process.env.BROWSERSLIST_CONFIG ) { + var file = opts.config || process.env.BROWSERSLIST_CONFIG; + queries = pickEnv(browserslist.readConfig(file), opts); + } else { + queries = pickEnv(browserslist.findConfig(opts.path), opts); + } + } + + if ( typeof queries === 'undefined' || queries === null ) { + queries = browserslist.defaults; + } + + if ( typeof queries === 'string' ) { + queries = queries.split(/,\s*/); + } + + var context = { }; + + var stats = getStat(opts); + if ( stats ) { + if ( typeof stats === 'string' ) { + try { + stats = JSON.parse(fs.readFileSync(stats)); + } catch (e) { + error('Can\'t read ' + stats); + } + } + if ( 'dataByBrowser' in stats ) { + stats = stats.dataByBrowser; + } + + context.customUsage = { }; + for ( var browser in stats ) { + fillUsage(context.customUsage, browser, stats[browser]); + } + } + + var result = []; + + queries.forEach(function (selection) { + if ( selection.trim() === '' ) return; + + var exclude = selection.indexOf('not ') === 0; + if ( exclude ) selection = selection.slice(4); + + for ( var i in browserslist.queries ) { + var type = browserslist.queries[i]; + var match = selection.match(type.regexp); + if ( match ) { + var args = [context].concat(match.slice(1)); + var array = type.select.apply(browserslist, args); + if ( exclude ) { + array = array.concat(array.map(function (j) { + return j.replace(/\s\d+/, ' 0'); + })); + result = result.filter(function (j) { + return array.indexOf(j) === -1; + }); + } else { + result = result.concat(array); + } + return; + } + } + + error('Unknown browser query `' + selection + '`'); + }); + result = result.map(function (i) { + var parts = i.split(' '); + var name = parts[0]; + var version = parts[1]; + if ( version === '0' ) { + return name + ' ' + browserslist.byName(name).versions[0]; + } else { + return i; + } + }).sort(function (name1, name2) { + name1 = name1.split(' '); + name2 = name2.split(' '); + if ( name1[0] === name2[0] ) { + if ( FLOAT_RANGE.test(name1[1]) && FLOAT_RANGE.test(name2[1]) ) { + return parseFloat(name2[1]) - parseFloat(name1[1]); + } else { + return compareStrings(name2[1], name1[1]); + } + } else { + return compareStrings(name1[0], name2[0]); + } + }); + + return uniq(result); +}; + +var normalizeVersion = function (data, version) { + if ( data.versions.indexOf(version) !== -1 ) { + return version; + } else if ( browserslist.versionAliases[data.name][version] ) { + return browserslist.versionAliases[data.name][version]; + } else if ( data.versions.length === 1 ) { + return data.versions[0]; + } +}; + +var loadCountryStatistics = function (country) { + if ( !browserslist.usage[country] ) { + var usage = { }; + var data = require( + 'caniuse-db/region-usage-json/' + country + '.json'); + for ( var i in data.data ) { + fillUsage(usage, i, data.data[i]); + } + browserslist.usage[country] = usage; + } +}; + +// Will be filled by Can I Use data below +browserslist.data = { }; +browserslist.usage = { + global: { }, + custom: null +}; + +// Default browsers query +browserslist.defaults = [ + '> 1%', + 'last 2 versions', + 'Firefox ESR' +]; + +// What browsers will be used in `last n version` query +browserslist.major = [ + 'safari', 'opera', 'ios_saf', 'ie_mob', 'ie', 'edge', 'firefox', 'chrome' +]; + +// Browser names aliases +browserslist.aliases = { + fx: 'firefox', + ff: 'firefox', + ios: 'ios_saf', + explorer: 'ie', + blackberry: 'bb', + explorermobile: 'ie_mob', + operamini: 'op_mini', + operamobile: 'op_mob', + chromeandroid: 'and_chr', + firefoxandroid: 'and_ff', + ucandroid: 'and_uc' +}; + +// Aliases to work with joined versions like `ios_saf 7.0-7.1` +browserslist.versionAliases = { }; + +// Get browser data by alias or case insensitive name +browserslist.byName = function (name) { + name = name.toLowerCase(); + name = browserslist.aliases[name] || name; + return browserslist.data[name]; +}; + +// Get browser data by alias or case insensitive name and throw error +// on unknown browser +browserslist.checkName = function (name) { + var data = browserslist.byName(name); + if ( !data ) error('Unknown browser ' + name); + return data; +}; + +// Read and parse config +browserslist.readConfig = function (file) { + if ( !fs.existsSync(file) || !fs.statSync(file).isFile() ) { + error('Can\'t read ' + file + ' config'); + } + return browserslist.parseConfig(fs.readFileSync(file)); +}; + +// Find config, read file and parse it +browserslist.findConfig = function (from) { + return eachParent(from, function (dir) { + var config = path.join(dir, 'browserslist'); + var pkg = path.join(dir, 'package.json'); + + var pkgBrowserslist; + if ( isFile(pkg) ) { + try { + pkgBrowserslist = parsePackage(pkg); + } catch (e) { + console.warn( + '[Browserslist] Could not parse ' + pkg + '. ' + + 'Ignoring it.'); + } + } + + if ( isFile(config) && pkgBrowserslist ) { + error( + dir + ' contains both browserslist ' + + 'and package.json with browsers'); + } else if ( isFile(config) ) { + return browserslist.readConfig(config); + } else if ( pkgBrowserslist ) { + return pkgBrowserslist; + } + }); +}; + +/** + * Return browsers market coverage. + * + * @param {string[]} browsers Browsers names in Can I Use. + * @param {string} [country="global"] Which country statistics should be used. + * + * @return {number} Total market coverage for all selected browsers. + * + * @example + * browserslist.coverage(browserslist('> 1% in US'), 'US') //=> 83.1 + */ +browserslist.coverage = function (browsers, country) { + if ( country && country !== 'global') { + country = country.toUpperCase(); + loadCountryStatistics(country); + } else { + country = 'global'; + } + + return browsers.reduce(function (all, i) { + var usage = browserslist.usage[country][i]; + if ( usage === undefined ) { + usage = browserslist.usage[country][i.replace(/ [\d.]+$/, ' 0')]; + } + return all + (usage || 0); + }, 0); +}; + +// Return array of queries from config content +browserslist.parseConfig = function (string) { + var result = { defaults: [] }; + var section = 'defaults'; + + string.toString() + .replace(/#[^\n]*/g, '') + .split(/\n/) + .map(function (line) { + return line.trim(); + }) + .filter(function (line) { + return line !== ''; + }) + .forEach(function (line) { + if ( IS_SECTION.test(line) ) { + section = line.match(IS_SECTION)[1].trim(); + result[section] = result[section] || []; + } else { + result[section].push(line); + } + }); + + return result; +}; + +browserslist.queries = { + + lastVersions: { + regexp: /^last\s+(\d+)\s+versions?$/i, + select: function (context, versions) { + var selected = []; + browserslist.major.forEach(function (name) { + var data = browserslist.byName(name); + if ( !data ) return; + var array = data.released.slice(-versions); + + array = array.map(function (v) { + return data.name + ' ' + v; + }); + selected = selected.concat(array); + }); + return selected; + } + }, + + lastByBrowser: { + regexp: /^last\s+(\d+)\s+(\w+)\s+versions?$/i, + select: function (context, versions, name) { + var data = browserslist.checkName(name); + return data.released.slice(-versions).map(function (v) { + return data.name + ' ' + v; + }); + } + }, + + globalStatistics: { + regexp: /^>\s*(\d*\.?\d+)%$/, + select: function (context, popularity) { + popularity = parseFloat(popularity); + var result = []; + + for ( var version in browserslist.usage.global ) { + if ( browserslist.usage.global[version] > popularity ) { + result.push(version); + } + } + + return result; + } + }, + + customStatistics: { + regexp: /^>\s*(\d*\.?\d+)%\s+in\s+my\s+stats$/, + select: function (context, popularity) { + popularity = parseFloat(popularity); + var result = []; + + if ( !context.customUsage ) { + error('Custom usage statistics was not provided'); + } + + for ( var version in context.customUsage ) { + if ( context.customUsage[version] > popularity ) { + result.push(version); + } + } + + return result; + } + }, + + countryStatistics: { + regexp: /^>\s*(\d*\.?\d+)%\s+in\s+(\w\w)$/, + select: function (context, popularity, country) { + popularity = parseFloat(popularity); + country = country.toUpperCase(); + var result = []; + + loadCountryStatistics(country); + var usage = browserslist.usage[country]; + + for ( var version in usage ) { + if ( usage[version] > popularity ) { + result.push(version); + } + } + + return result; + } + }, + + electronRange: { + regexp: /^electron\s+([\d\.]+)\s*-\s*([\d\.]+)$/i, + select: function (context, from, to) { + if ( !e2c[from] ) error('Unknown version ' + from + ' of electron'); + if ( !e2c[to] ) error('Unknown version ' + to + ' of electron'); + + from = parseFloat(from); + to = parseFloat(to); + + return Object.keys(e2c).filter(function (i) { + var parsed = parseFloat(i); + return parsed >= from && parsed <= to; + }).map(function (i) { + return 'chrome ' + e2c[i]; + }); + } + }, + + range: { + regexp: /^(\w+)\s+([\d\.]+)\s*-\s*([\d\.]+)$/i, + select: function (context, name, from, to) { + var data = browserslist.checkName(name); + from = parseFloat(normalizeVersion(data, from) || from); + to = parseFloat(normalizeVersion(data, to) || to); + + var filter = function (v) { + var parsed = parseFloat(v); + return parsed >= from && parsed <= to; + }; + + return data.released.filter(filter).map(function (v) { + return data.name + ' ' + v; + }); + } + }, + + electronVersions: { + regexp: /^electron\s*(>=?|<=?)\s*([\d\.]+)$/i, + select: function (context, sign, version) { + return Object.keys(e2c) + .filter(generateFilter(sign, version)) + .map(function (i) { + return 'chrome ' + e2c[i]; + }); + } + }, + + versions: { + regexp: /^(\w+)\s*(>=?|<=?)\s*([\d\.]+)$/, + select: function (context, name, sign, version) { + var data = browserslist.checkName(name); + var alias = normalizeVersion(data, version); + if ( alias ) { + version = alias; + } + return data.released + .filter(generateFilter(sign, version)) + .map(function (v) { + return data.name + ' ' + v; + }); + } + }, + + esr: { + regexp: /^(firefox|ff|fx)\s+esr$/i, + select: function () { + return ['firefox 52']; + } + }, + + opMini: { + regexp: /(operamini|op_mini)\s+all/i, + select: function () { + return ['op_mini all']; + } + }, + + electron: { + regexp: /^electron\s+([\d\.]+)$/i, + select: function (context, version) { + var chrome = e2c[version]; + if ( !chrome ) error('Unknown version ' + version + ' of electron'); + return ['chrome ' + chrome]; + } + }, + + direct: { + regexp: /^(\w+)\s+(tp|[\d\.]+)$/i, + select: function (context, name, version) { + if ( /tp/i.test(version) ) version = 'TP'; + var data = browserslist.checkName(name); + var alias = normalizeVersion(data, version); + if ( alias ) { + version = alias; + } else { + if ( version.indexOf('.') === -1 ) { + alias = version + '.0'; + } else if ( /\.0$/.test(version) ) { + alias = version.replace(/\.0$/, ''); + } + alias = normalizeVersion(data, alias); + if ( alias ) { + version = alias; + } else { + error('Unknown version ' + version + ' of ' + name); + } + } + return [data.name + ' ' + version]; + } + }, + + defaults: { + regexp: /^defaults$/i, + select: function () { + return browserslist(browserslist.defaults); + } + } + +}; + +// Get and convert Can I Use data + +(function () { + for ( var name in caniuse ) { + var browser = caniuse[name]; + browserslist.data[name] = { + name: name, + versions: normalize(caniuse[name].versions), + released: normalize(caniuse[name].versions.slice(0, -3)) + }; + fillUsage(browserslist.usage.global, name, browser.usage_global); + + browserslist.versionAliases[name] = { }; + for ( var i = 0; i < browser.versions.length; i++ ) { + var full = browser.versions[i]; + if (!full) continue; + + if ( full.indexOf('-') !== -1 ) { + var interval = full.split('-'); + for ( var j = 0; j < interval.length; j++ ) { + browserslist.versionAliases[name][interval[j]] = full; + } + } + } + } +}()); + +module.exports = browserslist; diff --git a/node_modules/browserslist/package.json b/node_modules/browserslist/package.json new file mode 100644 index 00000000..56d7529a --- /dev/null +++ b/node_modules/browserslist/package.json @@ -0,0 +1,54 @@ +{ + "name": "browserslist", + "version": "1.7.7", + "description": "Share browsers list between different front-end tools, like Autoprefixer, Stylelint and babel-env-preset", + "keywords": [ + "caniuse", + "browsers" + ], + "author": "Andrey Sitnik <andrey@sitnik.ru>", + "license": "MIT", + "repository": "ai/browserslist", + "dependencies": { + "caniuse-db": "^1.0.30000639", + "electron-to-chromium": "^1.2.7" + }, + "bin": "./cli.js", + "devDependencies": { + "eslint": "^3.18.0", + "eslint-config-postcss": "^2.0.2", + "jest": "^19.0.2", + "lint-staged": "^3.4.0", + "pre-commit": "^1.1.3", + "yaspeller-ci": "^0.3.0" + }, + "eslintConfig": { + "extends": "eslint-config-postcss/es5", + "env": { + "jest": true + }, + "rules": { + "consistent-return": "off", + "no-process-exit": "off", + "valid-jsdoc": "error" + } + }, + "jest": { + "coverageThreshold": { + "global": { + "statements": 100 + } + } + }, + "scripts": { + "lint-staged": "lint-staged", + "test": "jest --coverage && eslint *.js test/*.js && yaspeller-ci *.md" + }, + "lint-staged": { + "*.md": "yaspeller-ci", + "*.js": "eslint" + }, + "pre-commit": [ + "lint-staged" + ] +} |
