browserslist 0.3.1 → 0.5.0

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/.eslintrc ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "rules": {
3
+ "no-unused-expressions": [0],
4
+ "no-underscore-dangle": [0],
5
+ "no-reserved-keys": [2],
6
+ "no-multi-spaces": [0],
7
+ "no-extra-parens": [2],
8
+ "no-unused-vars": [2],
9
+ "no-loop-func": [0],
10
+ "key-spacing": [0],
11
+ "max-len": [2],
12
+ "strict": [0],
13
+ "indent": [2],
14
+ "quotes": [2, "single", "avoid-escape"],
15
+ "curly": [0]
16
+ },
17
+ "env": {
18
+ "mocha": true,
19
+ "node": true
20
+ }
21
+ }
@@ -1,3 +1,16 @@
1
+ ## 0.5
2
+ * Add version ranges `IE 6-9` (by Ben Briggs).
3
+
4
+ ## 0.4
5
+ * Add `config` option and `BROWSERSLIST_CONFIG` environment variable support.
6
+ * Add symlink config support.
7
+
8
+ ## 0.3.3
9
+ * Fix DynJS compatibility (by Nick Howes).
10
+
11
+ ## 0.3.2
12
+ * Fix joined versions on versions query (by Vincent De Oliveira).
13
+
1
14
  ## 0.3.1
2
15
  * Fix global variable leak (by Peter Müller).
3
16
 
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Browserslist [![Build Status](https://travis-ci.org/ai/browserslist.svg)](https://travis-ci.org/ai/browserslist)
1
+ # Browserslist [![Build Status][ci-img]][ci]
2
2
 
3
3
  Get browser versions that match given criteria.
4
4
  Useful for tools like [Autoprefixer].
@@ -11,8 +11,8 @@ with a usage of over 5% in global usage statistics:
11
11
 
12
12
  ```js
13
13
  browserslist('last 1 version, > 5%');
14
- //=> ['and_chr 40', 'chrome 40', 'chrome 39', 'firefox 36', 'firefox 34',
15
- // 'ie 11', 'ie_mob 11', 'ios_saf 8.1', 'opera 27', 'safari 8']
14
+ //=> ['and_chr 42', 'and_uc 9.9', 'chrome 43', 'chrome 42', 'firefox 38',
15
+ // 'ie 11', 'ie_mob 11', 'ios_saf 8.1-8.3', 'opera 30', 'safari 8']
16
16
  ```
17
17
 
18
18
  Browserslist will use browsers criterias from:
@@ -28,15 +28,18 @@ Browserslist will use browsers criterias from:
28
28
  </a>
29
29
 
30
30
  [Autoprefixer]: https://github.com/postcss/autoprefixer
31
+ [ci-img]: https://travis-ci.org/ai/browserslist.svg
32
+ [ci]: https://travis-ci.org/ai/browserslist
31
33
 
32
34
  ## Queries
33
35
 
34
- You can specify the browsers by queries (case insensitive):
36
+ You can specify the versions by queries (case insensitive):
35
37
 
36
38
  * `last 2 versions`: the last 2 versions for each major browser.
37
39
  * `last 2 Chrome versions`: the last 2 versions of Chrome browser.
38
40
  * `> 5%`: versions selected by global usage statistics.
39
41
  * `> 5% in US`: uses USA usage statistics. It accepts [two-letter country code].
42
+ * `ie 6-8`: selects an inclusive range of versions.
40
43
  * `Firefox > 20`: versions of Firefox newer than 20.
41
44
  * `Firefox >= 20`: versions of Firefox newer than or equal to 20.
42
45
  * `Firefox < 20`: versions of Firefox less than 20.
@@ -47,6 +50,10 @@ You can specify the browsers by queries (case insensitive):
47
50
  Blackberry and Android WebView will not be used in `last n versions`.
48
51
  You should add them by name.
49
52
 
53
+ Browserslist works with separated versions of browsers. To use all versions
54
+ of some browsers you can use for example `Firefox > 0`,
55
+ but it is bad practice.
56
+
50
57
  [two-letter country code]: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements
51
58
 
52
59
  ## Browsers
@@ -100,3 +107,5 @@ split by a new line. You can write a comment after `#`:
100
107
  Last 2 versions
101
108
  IE 8 # sorry
102
109
  ```
110
+
111
+ You can specify direct path to config by `config` option.
package/index.js CHANGED
@@ -5,30 +5,28 @@ var fs = require('fs');
5
5
  var uniq = function (array) {
6
6
  var filtered = [];
7
7
  for ( var i = 0; i < array.length; i++ ) {
8
- if ( filtered.indexOf(array[i]) == -1 ) filtered.push(array[i]);
8
+ if ( filtered.indexOf(array[i]) === -1 ) filtered.push(array[i]);
9
9
  }
10
10
  return filtered;
11
11
  };
12
12
 
13
- var normalizeVersion = function (data, version) {
14
- if ( data.versions.indexOf(version) != -1 ) {
15
- return version;
16
- } else {
17
- var alias = browserslist.versionAliases[data.name][version];
18
- if ( alias ) return alias;
19
- }
20
- };
21
-
22
13
  // Return array of browsers by selection queries:
23
14
  //
24
15
  // browserslist('IE >= 10, IE 8') //=> ['ie 11', 'ie 10', 'ie 8']
25
16
  var browserslist = function (selections, opts) {
26
- if ( typeof(opts) == 'undefined' ) opts = { };
17
+ if ( typeof opts === 'undefined' ) opts = { };
27
18
 
28
- if ( typeof(selections) == 'undefined' || selections === null ) {
19
+ if ( typeof selections === 'undefined' || selections === null ) {
29
20
 
30
21
  if ( process.env.BROWSERSLIST ) {
31
22
  selections = process.env.BROWSERSLIST;
23
+ } else if ( opts.config || process.env.BROWSERSLIST_CONFIG ) {
24
+ var file = opts.config || process.env.BROWSERSLIST_CONFIG;
25
+ if ( fs.existsSync(file) && fs.statSync(file).isFile() ) {
26
+ selections = browserslist.parseConfig( fs.readFileSync(file) );
27
+ } else {
28
+ throw 'Can\'t read ' + file + ' config';
29
+ }
32
30
  } else {
33
31
  var config = browserslist.readConfig(opts.path);
34
32
  if ( config !== false ) {
@@ -39,7 +37,7 @@ var browserslist = function (selections, opts) {
39
37
  }
40
38
  }
41
39
 
42
- if ( typeof(selections) == 'string' ) {
40
+ if ( typeof selections === 'string' ) {
43
41
  selections = selections.split(/,\s*/);
44
42
  }
45
43
 
@@ -69,14 +67,44 @@ var browserslist = function (selections, opts) {
69
67
  return uniq(result).sort(function (name1, name2) {
70
68
  name1 = name1.split(' ');
71
69
  name2 = name2.split(' ');
72
- if ( name1[0] == name2[0] ) {
73
- return parseFloat(name2[1]) - parseFloat(name1[1]);
70
+ if ( name1[0] === name2[0] ) {
71
+ var d = parseFloat(name2[1]) - parseFloat(name1[1]);
72
+ if ( d > 0 ) {
73
+ return 1;
74
+ } else if ( d < 0 ) {
75
+ return -1;
76
+ } else {
77
+ return 0;
78
+ }
74
79
  } else {
75
80
  return name1[0].localeCompare(name2[0]);
76
81
  }
77
82
  });
78
83
  };
79
84
 
85
+ // Helpers
86
+
87
+ var normalizeVersion = function (data, version) {
88
+ if ( data.versions.indexOf(version) !== -1 ) {
89
+ return version;
90
+ } else {
91
+ var alias = browserslist.versionAliases[data.name][version];
92
+ if ( alias ) return alias;
93
+ }
94
+ };
95
+
96
+ var normalize = function (versions) {
97
+ return versions.filter(function (version) {
98
+ return typeof version === 'string';
99
+ });
100
+ };
101
+
102
+ var fillUsage = function (result, name, data) {
103
+ for ( var i in data ) {
104
+ result[name + ' ' + i] = data[i];
105
+ }
106
+ };
107
+
80
108
  // Will be filled by Can I Use data below
81
109
  browserslist.data = { };
82
110
  browserslist.usage = {
@@ -116,8 +144,13 @@ browserslist.versionAliases = { };
116
144
  browserslist.byName = function (name) {
117
145
  name = name.toLowerCase();
118
146
  name = browserslist.aliases[name] || name;
147
+ return browserslist.data[name];
148
+ };
119
149
 
120
- var data = browserslist.data[name];
150
+ // Get browser data by alias or case insensitive name and throw error
151
+ // on unknown browser
152
+ browserslist.checkName = function (name) {
153
+ var data = browserslist.byName(name);
121
154
  if ( !data ) throw 'Unknown browser ' + name;
122
155
  return data;
123
156
  };
@@ -126,14 +159,14 @@ browserslist.byName = function (name) {
126
159
  browserslist.readConfig = function (from) {
127
160
  if ( from === false ) return false;
128
161
  if ( !fs.readFileSync ) return false;
129
- if ( typeof(from) == 'undefined' ) from = '.';
162
+ if ( typeof from === 'undefined' ) from = '.';
130
163
 
131
164
  var dirs = path.resolve(from).split(path.sep);
132
- var config, stat;
165
+ var config;
133
166
  while ( dirs.length ) {
134
167
  config = dirs.concat(['browserslist']).join(path.sep);
135
168
 
136
- if ( fs.existsSync(config) && fs.lstatSync(config).isFile() ) {
169
+ if ( fs.existsSync(config) && fs.statSync(config).isFile() ) {
137
170
  return browserslist.parseConfig( fs.readFileSync(config) );
138
171
  }
139
172
 
@@ -149,10 +182,10 @@ browserslist.parseConfig = function (string) {
149
182
  .replace(/#[^\n]*/g, '')
150
183
  .split(/\n/)
151
184
  .map(function (i) {
152
- return i.trim();
185
+ return i.trim();
153
186
  })
154
187
  .filter(function (i) {
155
- return i !== '';
188
+ return i !== '';
156
189
  });
157
190
  };
158
191
 
@@ -164,6 +197,7 @@ browserslist.queries = {
164
197
  var selected = [];
165
198
  browserslist.major.forEach(function (name) {
166
199
  var data = browserslist.byName(name);
200
+ if ( !data ) return;
167
201
  var array = data.released.slice(-versions);
168
202
 
169
203
  array = array.map(function (v) {
@@ -178,7 +212,7 @@ browserslist.queries = {
178
212
  lastByBrowser: {
179
213
  regexp: /^last (\d+) (\w+) versions?$/i,
180
214
  select: function (versions, name) {
181
- var data = browserslist.byName(name);
215
+ var data = browserslist.checkName(name);
182
216
  return data.released.slice(-versions).map(function (v) {
183
217
  return data.name + ' ' + v;
184
218
  });
@@ -228,31 +262,52 @@ browserslist.queries = {
228
262
  }
229
263
  },
230
264
 
265
+ range: {
266
+ regexp: /^(\w+) ([\d\.]+)-([\d\.]+)/i,
267
+ select: function (name, from, to) {
268
+ var data = browserslist.checkName(name);
269
+ from = parseFloat(normalizeVersion(data, from) || from);
270
+ to = parseFloat(normalizeVersion(data, to) || to);
271
+
272
+ var filter = function (v) {
273
+ var parsed = parseFloat(v);
274
+ return parsed >= from && parsed <= to;
275
+ };
276
+
277
+ return data.released.filter(filter).map(function (v) {
278
+ return data.name + ' ' + v;
279
+ });
280
+ }
281
+ },
282
+
231
283
  versions: {
232
284
  regexp: /^(\w+) (>=?|<=?)\s*([\d\.]+)/,
233
285
  select: function (name, sign, version) {
234
- var data = browserslist.byName(name);
235
- version = parseFloat(version);
286
+ var data = browserslist.checkName(name);
287
+ var alias = normalizeVersion(data, version);
288
+ if ( alias ) {
289
+ version = alias;
290
+ }
291
+ version = parseFloat(version);
236
292
 
237
293
  var filter;
238
- if ( sign == '>' ) {
294
+ if ( sign === '>' ) {
239
295
  filter = function (v) {
240
296
  return parseFloat(v) > version;
241
297
  };
242
- } else if ( sign == '>=' ) {
298
+ } else if ( sign === '>=' ) {
243
299
  filter = function (v) {
244
300
  return parseFloat(v) >= version;
245
301
  };
246
- } else if ( sign == '<' ) {
302
+ } else if ( sign === '<' ) {
247
303
  filter = function (v) {
248
304
  return parseFloat(v) < version;
249
305
  };
250
- } else if ( sign == '<=' ) {
306
+ } else if ( sign === '<=' ) {
251
307
  filter = function (v) {
252
308
  return parseFloat(v) <= version;
253
309
  };
254
310
  }
255
-
256
311
  return data.released.filter(filter).map(function (v) {
257
312
  return data.name + ' ' + v;
258
313
  });
@@ -261,7 +316,7 @@ browserslist.queries = {
261
316
 
262
317
  esr: {
263
318
  regexp: /^(firefox|ff|fx) esr$/i,
264
- select: function (versions) {
319
+ select: function () {
265
320
  return ['firefox 31'];
266
321
  }
267
322
  },
@@ -269,12 +324,12 @@ browserslist.queries = {
269
324
  direct: {
270
325
  regexp: /^(\w+) ([\d\.]+)$/,
271
326
  select: function (name, version) {
272
- var data = browserslist.byName(name);
327
+ var data = browserslist.checkName(name);
273
328
  var alias = normalizeVersion(data, version);
274
329
  if ( alias ) {
275
330
  version = alias;
276
331
  } else {
277
- if ( version.indexOf('.') == -1 ) {
332
+ if ( version.indexOf('.') === -1 ) {
278
333
  alias = version + '.0';
279
334
  } else if ( /\.0$/.test(version) ) {
280
335
  alias = version.replace(/\.0$/, '');
@@ -286,7 +341,6 @@ browserslist.queries = {
286
341
  throw 'Unknown version ' + version + ' of ' + name;
287
342
  }
288
343
  }
289
-
290
344
  return [data.name + ' ' + version];
291
345
  }
292
346
  }
@@ -295,38 +349,28 @@ browserslist.queries = {
295
349
 
296
350
  // Get and convert Can I Use data
297
351
 
298
- var normalize = function (versions) {
299
- return versions.filter(function (version) {
300
- return typeof(version) == 'string';
301
- });
302
- };
303
-
304
- var fillUsage = function (result, name, data) {
305
- for ( var i in data ) {
306
- result[name + ' ' + i] = data[i];
307
- }
308
- };
309
-
310
- for ( var name in caniuse ) {
311
- browserslist.data[name] = {
312
- name: name,
313
- versions: normalize(caniuse[name].versions),
314
- released: normalize(caniuse[name].versions.slice(0, -3))
315
- };
316
- fillUsage(browserslist.usage.global, name, caniuse[name].usage_global);
317
-
318
- browserslist.versionAliases[name] = { };
319
- for ( var i = 0; i < caniuse[name].versions.length; i++ ) {
320
- if ( !caniuse[name].versions[i] ) continue;
321
- var full = caniuse[name].versions[i];
322
-
323
- if ( full.indexOf('-') != -1 ) {
324
- var interval = full.split('-');
325
- for ( var j = 0; j < interval.length; j++ ) {
326
- browserslist.versionAliases[name][ interval[j] ] = full;
352
+ (function () {
353
+ for ( var name in caniuse ) {
354
+ browserslist.data[name] = {
355
+ name: name,
356
+ versions: normalize(caniuse[name].versions),
357
+ released: normalize(caniuse[name].versions.slice(0, -3))
358
+ };
359
+ fillUsage(browserslist.usage.global, name, caniuse[name].usage_global);
360
+
361
+ browserslist.versionAliases[name] = { };
362
+ for ( var i = 0; i < caniuse[name].versions.length; i++ ) {
363
+ if ( !caniuse[name].versions[i] ) continue;
364
+ var full = caniuse[name].versions[i];
365
+
366
+ if ( full.indexOf('-') !== -1 ) {
367
+ var interval = full.split('-');
368
+ for ( var j = 0; j < interval.length; j++ ) {
369
+ browserslist.versionAliases[name][ interval[j] ] = full;
370
+ }
327
371
  }
328
372
  }
329
373
  }
330
- }
374
+ })();
331
375
 
332
376
  module.exports = browserslist;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browserslist",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
4
  "description": "Get browsers versions that matches given criterias like in Autoprefixer",
5
5
  "keywords": ["caniuse", "browsers"],
6
6
  "author": "Andrey Sitnik <andrey@sitnik.ru>",
@@ -10,15 +10,14 @@
10
10
  "url": "https://github.com/ai/browserslist.git"
11
11
  },
12
12
  "dependencies": {
13
- "caniuse-db": "^1.0.30000081"
13
+ "caniuse-db": "^1.0.30000214"
14
14
  },
15
15
  "devDependencies": {
16
- "jshint-stylish": "1.0.1",
17
- "gulp-jshint": "1.9.2",
18
- "gulp-mocha": "2.0.0",
19
- "mocha": "2.1.0",
20
- "chai": "2.1.0",
21
- "gulp": "3.8.11"
16
+ "gulp-eslint": "0.14.0",
17
+ "gulp-mocha": "2.1.2",
18
+ "mocha": "2.2.5",
19
+ "chai": "3.0.0",
20
+ "gulp": "3.9.0"
22
21
  },
23
22
  "scripts": {
24
23
  "test": "gulp"