browserslist 1.0.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.npmignore CHANGED
@@ -5,4 +5,5 @@ node_modules/
5
5
  test/
6
6
  .travis.yml
7
7
 
8
- gulpfile.js
8
+ .editorconfig
9
+ .eslintrc
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
- ## 1.0.0
1
+ ## 1.1.2
2
+ * Fix JSPM support (by Sean Anderson).
3
+
4
+ ## 1.1.1
5
+ * Fix space-less `>10%` and `>10% in my stats` queries.
6
+ * Normalize error messages.
7
+ * Remove development files from npm package.
8
+
9
+ ## 1.1
10
+ * Added query against custom browser usage data (by Daniel Rey).
11
+
12
+ ## 1.0.1
13
+ * Update Firefox ESR (by Rouven Weßling).
14
+
15
+ ## 1.0
2
16
  * Remove Opera 12.1 from default query.
17
+ * Add `not` keyword and exclude browsers by query.
3
18
  * Add Microsoft Edge support (by Andrey Polischuk).
4
19
  * Add CLI for debug and non-JS usage (by Luke Horvat).
5
20
  * Use own class in Browserslist errors.
package/README.md CHANGED
@@ -3,29 +3,23 @@
3
3
  Get browser versions that match given criteria.
4
4
  Useful for tools like [Autoprefixer].
5
5
 
6
- You can select browsers by passing a string. This library will use Can I Use
7
- data to return the appropriate list of all matching versions.
8
-
9
- For example, the last version of each major browser and versions,
10
- with a usage of over 5% in global usage statistics:
6
+ You can select browsers by passing a string. This library will use
7
+ Can I Use data to return list of all matching versions.
8
+ For example, query to select all browser versions that are the last version
9
+ of each major browser, or have a usage of over 10% in global usage statistics:
11
10
 
12
11
  ```js
13
- browserslist('last 1 version, > 5%');
14
- //=> ['and_chr 44', 'and_uc 9.9', 'chrome 44', 'chrome 43', 'edge 1',
15
- // 'firefox 40', 'firefox 39', 'ie 11', 'ie_mob 11', 'ios_saf 8.1-8.4',
16
- // 'opera 30', 'safari 8']
12
+ browserslist('last 1 version, > 10%');
13
+ //=> ["and_chr 47", "chrome 48", "chrome 47", "edge 13", "firefox 44",
14
+ // "ie 11", "ie_mob 11", "ios_saf 9.0-9.2", "opera 34", "safari 9"]
17
15
  ```
18
16
 
19
- Browserslist will use browsers criterias from:
20
-
21
- 1. First argument.
22
- 2. `BROWSERSLIST` environment variable.
23
- 3. `browserslist` config file in current or parent directories.
24
- 4. If all methods will not give a result, Browserslist will use defaults:<br>
25
- `> 1%, last 2 versions, Firefox ESR`.
26
-
27
17
  <a href="https://evilmartians.com/?utm_source=browserslist">
28
- <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
18
+ <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
19
+ alt="Sponsored by Evil Martians"
20
+ width="236"
21
+ height="54"
22
+ \>
29
23
  </a>
30
24
 
31
25
  [Autoprefixer]: https://github.com/postcss/autoprefixer
@@ -34,12 +28,24 @@ Browserslist will use browsers criterias from:
34
28
 
35
29
  ## Queries
36
30
 
31
+ Browserslist will use browsers criterias from:
32
+
33
+ 1. First argument.
34
+ 2. `BROWSERSLIST` environment variable.
35
+ 3. `browserslist` config file in current or parent directories.
36
+ 4. If all methods will not give a result, Browserslist will use defaults:
37
+ `> 1%, last 2 versions, Firefox ESR`.
38
+
39
+ Multiple criteria are combined as a boolean `OR`. A browser version must match
40
+ at least one of the criteria to be selected.
41
+
37
42
  You can specify the versions by queries (case insensitive):
38
43
 
39
44
  * `last 2 versions`: the last 2 versions for each major browser.
40
45
  * `last 2 Chrome versions`: the last 2 versions of Chrome browser.
41
46
  * `> 5%`: versions selected by global usage statistics.
42
47
  * `> 5% in US`: uses USA usage statistics. It accepts [two-letter country code].
48
+ * `> 5% in my stats`: uses [custom usage data].
43
49
  * `ie 6-8`: selects an inclusive range of versions.
44
50
  * `Firefox > 20`: versions of Firefox newer than 20.
45
51
  * `Firefox >= 20`: versions of Firefox newer than or equal to 20.
@@ -47,24 +53,21 @@ You can specify the versions by queries (case insensitive):
47
53
  * `Firefox <= 20`: versions of Firefox less than or equal to 20.
48
54
  * `Firefox ESR`: the latest [Firefox ESR] version.
49
55
  * `iOS 7`: the iOS browser version 7 directly.
50
- * `not ie <= 8`: exclude browsers selected before by this query.
56
+ * `not ie <= 8`: exclude browsers selected before by previous queries.
51
57
  You can add `not ` to any query.
52
58
 
53
- Blackberry and Android WebView will not be used in `last n versions`.
54
- You should add them by name.
55
-
56
- Browserslist works with separated versions of browsers. To use all versions
57
- of some browsers you can use for example `Firefox > 0`,
58
- but it is bad practice.
59
+ Browserslist works with separated versions of browsers.
60
+ You should avoid queries like `Firefox > 0`.
59
61
 
60
62
  [two-letter country code]: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements
63
+ [custom usage data]: #custom-usage-data
61
64
 
62
65
  ## Browsers
63
66
 
64
67
  Names are case insensitive:
65
68
 
66
- * `Android` for Android WebView.
67
- * `BlackBerry` or `bb` for Blackberry browser.
69
+ ### Major Browsers
70
+
68
71
  * `Chrome` for Google Chrome.
69
72
  * `Firefox` or `ff` for Mozilla Firefox.
70
73
  * `Explorer` or `ie` for Internet Explorer.
@@ -72,17 +75,22 @@ Names are case insensitive:
72
75
  * `iOS` or `ios_saf` for iOS Safari.
73
76
  * `Opera` for Opera.
74
77
  * `Safari` for desktop Safari.
75
- * `OperaMobile` or `op_mob` for Opera Mobile.
76
- * `OperaMini` or `op_mini` for Opera Mini.
78
+ * `ExplorerMobile` or `ie_mob` for Internet Explorer Mobile.
79
+
80
+ ### Other
81
+
82
+ * `Android` for Android WebView.
83
+ * `BlackBerry` or `bb` for Blackberry browser.
77
84
  * `ChromeAndroid` or `and_chr` for Chrome for Android
78
- (mostly same as common `Chrome`).
85
+ (in Other section, because mostly same as common `Chrome`).
79
86
  * `FirefoxAndroid` or `and_ff` for Firefox for Android.
80
- * `ExplorerMobile` or `ie_mob` for Internet Explorer Mobile.
87
+ * `OperaMobile` or `op_mob` for Opera Mobile.
88
+ * `OperaMini` or `op_mini` for Opera Mini.
81
89
 
82
90
  ## Config File
83
91
 
84
92
  Browserslist’s config should be named `browserslist` and have browsers queries
85
- split by a new line. You can write a comment after `#`:
93
+ split by a new line. Comments starts with `#` symbol:
86
94
 
87
95
  ```yaml
88
96
  # Browsers that we support
@@ -92,9 +100,9 @@ Last 2 versions
92
100
  IE 8 # sorry
93
101
  ```
94
102
 
95
- Browserslist will check config in every directory in `config.path` path.
96
- So, if tool with Browserslist process `app/styles/main.css`, you can put
97
- config to root, `app/` or `app/styles`.
103
+ Browserslist will check config in every directory in `path`.
104
+ So, if tool process `app/styles/main.css`, you can put config to root,
105
+ `app/` or `app/styles`.
98
106
 
99
107
  You can specify direct path to config by `config` option
100
108
  or `BROWSERSLIST_CONFIG` environment variables.
@@ -116,8 +124,58 @@ by [environment variables]:
116
124
  BROWSERSLIST_CONFIG=./config/browserslist gulp css
117
125
  ```
118
126
 
127
+ * `BROWSERSLIST_STATS` with path to the custom usage data.
128
+
129
+ ```sh
130
+ BROWSERSLIST_STATS=./config/usage_data.json gulp css
131
+ ```
132
+
119
133
  [environment variables]: https://en.wikipedia.org/wiki/Environment_variable
120
134
 
135
+ ## Custom Usage Data
136
+
137
+ If you have a website, you can query against the usage statistics of your site:
138
+
139
+ 1. Import your Google Analytics data into [Can I Use].
140
+ Press `Import…` button in Settings page.
141
+ 2. Open browser DevTools on [caniuse.com] add paste this snippet into Console:
142
+
143
+ ```js
144
+ 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);}
145
+ ```
146
+ 3. Save data to file in your project.
147
+ 4. Give it to Browserslist by `stats` option
148
+ or `BROWSERSLIST_STATS` environment variable:
149
+
150
+ ```js
151
+ browserslist('> 5% in my stats', { stats: 'path/to/the/stats.json' });
152
+ ```
153
+
154
+ Of course, you can generate usage statistics file by any other method.
155
+ Option `stats` accepts path to file or data itself:
156
+
157
+ ```js
158
+ var custom = {
159
+ ie: {
160
+ 6: 0.01,
161
+ 7: 0.4,
162
+ 8: 1.5
163
+ },
164
+ chrome: {
165
+
166
+ },
167
+
168
+ };
169
+
170
+ browserslist('> 5% in my stats', { stats: custom });
171
+ ```
172
+
173
+ Note that you can query against your custom usage data while also querying
174
+ against global or regional data. For example, the query
175
+ `> 5% in my stats, > 1%, > 10% in US` is permitted.
176
+
177
+ [Can I Use]: http://caniuse.com/
178
+
121
179
  ## Usage
122
180
 
123
181
  ```js
@@ -130,13 +188,13 @@ var process = function (css, opts) {
130
188
  }
131
189
  ```
132
190
 
133
- If a list is missing, Browserslist will look for a config file.
134
- You can provide a `path` option (that can be a file) to find the config file
135
- relatively to it.
136
-
137
191
  Queries can be a string `"> 5%, last 1 version"`
138
192
  or an array `['> 5%', 'last 1 version']`.
139
193
 
194
+ If a query is missing, Browserslist will look for a config file.
195
+ You can provide a `path` option (that can be a file) to find the config file
196
+ relatively to it.
197
+
140
198
  For non-JS environment and debug purpose you can use CLI tool:
141
199
 
142
200
  ```sh
package/index.js CHANGED
@@ -25,6 +25,20 @@ function error(name) {
25
25
  throw obj;
26
26
  }
27
27
 
28
+ // Helpers
29
+
30
+ var normalize = function (versions) {
31
+ return versions.filter(function (version) {
32
+ return typeof version === 'string';
33
+ });
34
+ };
35
+
36
+ var fillUsage = function (result, name, data) {
37
+ for ( var i in data ) {
38
+ result[name + ' ' + i] = data[i];
39
+ }
40
+ };
41
+
28
42
  // Return array of browsers by selection queries:
29
43
  //
30
44
  // browserslist('IE >= 10, IE 8') //=> ['ie 11', 'ie 10', 'ie 8']
@@ -56,6 +70,25 @@ var browserslist = function (selections, opts) {
56
70
  selections = selections.split(/,\s*/);
57
71
  }
58
72
 
73
+ if ( opts.stats || process.env.BROWSERSLIST_STATS ) {
74
+ browserslist.usage.custom = { };
75
+ var stats = opts.stats || process.env.BROWSERSLIST_STATS;
76
+ if ( typeof stats === 'string' ) {
77
+ try {
78
+ stats = JSON.parse(fs.readFileSync(stats));
79
+ } catch (e) {
80
+ error('Can\'t read ' + stats);
81
+ }
82
+ }
83
+ if ( 'dataByBrowser' in stats ) {
84
+ // Allow to use the data as-is from the caniuse.com website
85
+ stats = stats.dataByBrowser;
86
+ }
87
+ for ( var browser in stats ) {
88
+ fillUsage(browserslist.usage.custom, browser, stats[browser]);
89
+ }
90
+ }
91
+
59
92
  var result = [];
60
93
 
61
94
  var exclude, query, match, array, used;
@@ -109,8 +142,6 @@ var browserslist = function (selections, opts) {
109
142
  });
110
143
  };
111
144
 
112
- // Helpers
113
-
114
145
  var normalizeVersion = function (data, version) {
115
146
  if ( data.versions.indexOf(version) !== -1 ) {
116
147
  return version;
@@ -120,24 +151,11 @@ var normalizeVersion = function (data, version) {
120
151
  }
121
152
  };
122
153
 
123
- var normalize = function (versions) {
124
- return versions.filter(function (version) {
125
- return typeof version === 'string';
126
- });
127
- };
128
-
129
- var fillUsage = function (result, name, data) {
130
- for ( var i in data ) {
131
- result[name + ' ' + i] = data[i];
132
- }
133
- };
134
-
135
- browserslist.Error = BrowserslistError;
136
-
137
154
  // Will be filled by Can I Use data below
138
155
  browserslist.data = { };
139
156
  browserslist.usage = {
140
- global: { }
157
+ global: { },
158
+ custom: null
141
159
  };
142
160
 
143
161
  // Default browsers query
@@ -186,7 +204,7 @@ browserslist.checkName = function (name) {
186
204
  // Find config, read file and parse it
187
205
  browserslist.readConfig = function (from) {
188
206
  if ( from === false ) return false;
189
- if ( !fs.readFileSync ) return false;
207
+ if ( !fs.readFileSync || !fs.existsSync || !fs.statSync ) return false;
190
208
  if ( typeof from === 'undefined' ) from = '.';
191
209
 
192
210
  var dirs = path.resolve(from).split(path.sep);
@@ -247,7 +265,7 @@ browserslist.queries = {
247
265
  },
248
266
 
249
267
  globalStatistics: {
250
- regexp: /^> (\d+\.?\d*)%$/,
268
+ regexp: /^>\s?(\d+\.?\d*)%$/,
251
269
  select: function (popularity) {
252
270
  popularity = parseFloat(popularity);
253
271
  var result = [];
@@ -262,6 +280,27 @@ browserslist.queries = {
262
280
  }
263
281
  },
264
282
 
283
+ customStatistics: {
284
+ regexp: /^>\s?(\d+\.?\d*)% in my stats$/,
285
+ select: function (popularity) {
286
+ popularity = parseFloat(popularity);
287
+ var result = [];
288
+
289
+ var usage = browserslist.usage.custom;
290
+ if ( !usage ) {
291
+ error('Custom usage statistics was not provided');
292
+ }
293
+
294
+ for ( var version in usage ) {
295
+ if ( usage[version] > popularity ) {
296
+ result.push(version);
297
+ }
298
+ }
299
+
300
+ return result;
301
+ }
302
+ },
303
+
265
304
  countryStatistics: {
266
305
  regexp: /^> (\d+\.?\d*)% in (\w\w)$/,
267
306
  select: function (popularity, country) {
@@ -344,7 +383,7 @@ browserslist.queries = {
344
383
  esr: {
345
384
  regexp: /^(firefox|ff|fx) esr$/i,
346
385
  select: function () {
347
- return ['firefox 31'];
386
+ return ['firefox 38'];
348
387
  }
349
388
  },
350
389
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browserslist",
3
- "version": "1.0.0",
3
+ "version": "1.1.2",
4
4
  "description": "Get browsers versions that matches given criterias like in Autoprefixer",
5
5
  "keywords": [
6
6
  "caniuse",
@@ -13,17 +13,15 @@
13
13
  "url": "https://github.com/ai/browserslist.git"
14
14
  },
15
15
  "dependencies": {
16
- "caniuse-db": "^1.0.30000281"
16
+ "caniuse-db": "^1.0.30000409"
17
17
  },
18
18
  "bin": "./cli.js",
19
19
  "devDependencies": {
20
- "gulp-eslint": "1.0.0",
21
- "gulp-mocha": "2.1.3",
22
- "mocha": "2.3.0",
23
- "chai": "3.2.0",
24
- "gulp": "3.9.0"
20
+ "eslint-config-postcss": "^1.0.0",
21
+ "eslint": "1.10.3",
22
+ "ava": "0.11.0"
25
23
  },
26
24
  "scripts": {
27
- "test": "gulp"
25
+ "test": "ava && eslint *.js test/*.js"
28
26
  }
29
27
  }
package/.eslintrc DELETED
@@ -1,126 +0,0 @@
1
- {
2
- "rules": {
3
- "space-before-function-paren": [2, { "named": "never" }],
4
- "no-shadow-restricted-names": [2],
5
- "computed-property-spacing": [2],
6
- "no-empty-character-class": [2],
7
- "no-irregular-whitespace": [2],
8
- "no-unexpected-multiline": [2],
9
- "no-multiple-empty-lines": [2],
10
- "space-return-throw-case": [2],
11
- "no-constant-condition": [2],
12
- "no-extra-boolean-cast": [2],
13
- "no-inner-declarations": [2],
14
- "no-this-before-super": [2],
15
- "no-use-before-define": [2],
16
- "no-array-constructor": [2],
17
- "object-curly-spacing": [2, "always"],
18
- "no-floating-decimal": [2],
19
- "no-warning-comments": [2],
20
- "handle-callback-err": [2],
21
- "no-unneeded-ternary": [2],
22
- "operator-assignment": [2],
23
- "space-before-blocks": [2],
24
- "no-native-reassign": [2],
25
- "no-trailing-spaces": [2],
26
- "operator-linebreak": [2, "after"],
27
- "consistent-return": [2],
28
- "no-duplicate-case": [2],
29
- "no-invalid-regexp": [2],
30
- "no-negated-in-lhs": [2],
31
- "constructor-super": [2],
32
- "no-nested-ternary": [2],
33
- "no-extend-native": [2],
34
- "block-scoped-var": [2],
35
- "no-control-regex": [2],
36
- "no-sparse-arrays": [2],
37
- "no-throw-literal": [2],
38
- "no-return-assign": [2],
39
- "no-const-assign": [2],
40
- "no-class-assign": [2],
41
- "no-extra-parens": [2],
42
- "no-regex-spaces": [2],
43
- "no-implied-eval": [2],
44
- "no-useless-call": [2],
45
- "no-self-compare": [2],
46
- "no-octal-escape": [2],
47
- "no-new-wrappers": [2],
48
- "no-process-exit": [2],
49
- "no-catch-shadow": [2],
50
- "linebreak-style": [2],
51
- "space-infix-ops": [2],
52
- "space-unary-ops": [2],
53
- "no-cond-assign": [2],
54
- "no-func-assign": [2],
55
- "no-unreachable": [2],
56
- "accessor-pairs": [2],
57
- "no-empty-label": [2],
58
- "no-fallthrough": [2],
59
- "no-path-concat": [2],
60
- "no-new-require": [2],
61
- "no-spaced-func": [2],
62
- "no-unused-vars": [2],
63
- "spaced-comment": [2],
64
- "no-delete-var": [2],
65
- "comma-spacing": [2],
66
- "no-extra-semi": [2],
67
- "no-extra-bind": [2],
68
- "arrow-spacing": [2],
69
- "prefer-spread": [2],
70
- "no-new-object": [2],
71
- "no-multi-str": [2],
72
- "semi-spacing": [2],
73
- "no-lonely-if": [2],
74
- "dot-notation": [2],
75
- "dot-location": [2, "property"],
76
- "comma-dangle": [2, "never"],
77
- "no-dupe-args": [2],
78
- "no-dupe-keys": [2],
79
- "no-ex-assign": [2],
80
- "no-obj-calls": [2],
81
- "valid-typeof": [2],
82
- "default-case": [2],
83
- "no-redeclare": [2],
84
- "no-div-regex": [2],
85
- "no-sequences": [2],
86
- "no-label-var": [2],
87
- "comma-style": [2],
88
- "brace-style": [2],
89
- "no-debugger": [2],
90
- "quote-props": [2, "as-needed"],
91
- "no-iterator": [2],
92
- "no-new-func": [2],
93
- "key-spacing": [2, { "align": "value" }],
94
- "complexity": [2],
95
- "new-parens": [2],
96
- "no-eq-null": [2],
97
- "no-bitwise": [2],
98
- "wrap-iife": [2],
99
- "no-caller": [2],
100
- "use-isnan": [2],
101
- "no-labels": [2],
102
- "no-shadow": [2],
103
- "camelcase": [2],
104
- "eol-last": [2],
105
- "no-octal": [2],
106
- "no-empty": [2],
107
- "no-alert": [2],
108
- "no-proto": [2],
109
- "no-undef": [2],
110
- "no-eval": [2],
111
- "no-with": [2],
112
- "no-void": [2],
113
- "max-len": [2, 80],
114
- "new-cap": [2],
115
- "eqeqeq": [2],
116
- "no-new": [2],
117
- "quotes": [2, "single"],
118
- "indent": [2, 4],
119
- "semi": [2, "always"],
120
- "yoda": [2, "never"]
121
- },
122
- "env": {
123
- "mocha": true,
124
- "node": true
125
- }
126
- }