Skip to content
This repository was archived by the owner on Dec 19, 2024. It is now read-only.

Commit eddce29

Browse files
committed
Add browsers option
Close #32
1 parent 1d43cd1 commit eddce29

File tree

5 files changed

+104
-22
lines changed

5 files changed

+104
-22
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ cssnext({
2828

2929
- Added: `url` option: non absolute url() are now rebased according to `from` (and `to` options if provided). Enabled by default.
3030
- Added: `compress` option now accept CSSWring options directly.
31+
- Added: `browsers` option can enable or disable features and is propagated to autoprefixer
3132

3233
# 0.6.6 - 2014-12-22
3334

README.md

+14-20
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,22 @@ fs.writeFileSync("dist/index.css", output)
191191

192192
#### Node.js options
193193

194+
##### `browsers` (default: [browserslist default](https://github.com/ai/browserslist#readme) - `> 1%, last 2 versions, Firefox ESR, Opera 12.1`)
195+
196+
Allow you to specify your browser scope.
197+
**This option enable or disable `features` according to [caniuse](http://caniuse.com/) database.**
198+
This is the exact same option that you might know in Autoprefixer.
199+
Since cssnext includes Autoprefixer, the option is propagated.
200+
201+
See [Browserslist](https://github.com/ai/browserslist#queries) queries syntax to adjust this option to your need.
202+
203+
_Note: if you don't specify this option, Browserslist will automatically try to find `browserslist`
204+
config file or use its default value._
205+
194206
##### `features` (default: all features)
195207

208+
**You should probably use `browsers` option instead of this one.**
209+
196210
Object containing key of features to enable/disable.
197211
_Features are enabled by default: no key means feature is enabled_.
198212

@@ -293,26 +307,6 @@ var output = cssnext(
293307
fs.writeFileSync("dist/index.css", output)
294308
```
295309

296-
##### Some feature options
297-
298-
###### `features.autoprefixer.browsers` (default: _autoprefixer default_)
299-
300-
Array to specify browsers you want to target (for now only used by [autoprefixer](https://github.com/postcss/autoprefixer)).
301-
See [autoprefixer documentation of this option for more details](https://github.com/postcss/autoprefixer#browsers).
302-
303-
Defaults to something like `["> 1%", "last 2 versions", "Firefox ESR"]`.
304-
305-
```js
306-
//eg
307-
var output = cssnext(input, {
308-
features: {
309-
autoprefixer: {
310-
browsers: ["> 1%", "last 2 versions", "Firefox ESR"]
311-
}
312-
}
313-
})
314-
```
315-
316310
### Usage with other tools
317311

318312
Here are some tools that will help you use cssnext in your current workflow

index.js

+41-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,28 @@
33
*/
44
var Postcss = require("postcss")
55
var assign = require("object-assign")
6+
var caniuse = require("caniuse-api")
7+
8+
// Some features might affect others (eg: var() in a calc()
9+
// in order to prevent issue, the map contains a sort of dependencies list
10+
//
11+
// null == always enable (& no caniuse data)
12+
var caniuseFeaturesMap = {
13+
customProperties: ["css-variables"],
14+
// calc: null, // calc() transformation only make sense with transformed custom properties, don't you think ?
15+
// @todo open PR on caniuse repo https://github.com/Fyrd/caniuse
16+
// customMedia: [null],
17+
// mediaQueriesRange: [null],
18+
// customSelectors: [null],
19+
// colorRebeccapurple: [null], // @todo can be done easily
20+
// colorHwb: [null],
21+
// colorGray: [null],
22+
// colorHexAlpha: [null],
23+
// colorFunction:[null],
24+
// fontVariant: [null],
25+
// filter: [null], // @todo can be done using a callback, this is only used for Firefox < 35
26+
// autoprefixer: [null] // will always be null since autoprefixer does the same game as we do
27+
}
628

729
var features = {
830
// Reminder: order is important
@@ -51,11 +73,21 @@ function cssnext(string, options) {
5173

5274
var features = options.features || {}
5375

76+
// options.browsers is deliberately undefined by defaut to inherit browserslist default behavior
77+
5478
// default sourcemap
5579
// if `map` option is passed, `sourcemap` option is ignored
5680
// if `sourcemap` option is passed, a inline map is used
5781
options.map = options.map || (options.sourcemap ? true : null)
5882

83+
// propagate browsers option to autoprefixer
84+
if (features.autoprefixer !== false) {
85+
features.autoprefixer = features.autoprefixer || {}
86+
features.autoprefixer.browsers = features.autoprefixer.browsers || options.browsers
87+
// autoprefixer doesn't like an "undefined" value. Related to coffee ?
88+
if (features.autoprefixer.browsers === undefined) {delete features.autoprefixer.browsers}
89+
}
90+
5991
var postcss = Postcss()
6092

6193
// only enable import & url if fs module is available
@@ -74,8 +106,15 @@ function cssnext(string, options) {
74106

75107
// features
76108
Object.keys(cssnext.features).forEach(function(key) {
77-
// if undefined, we default to assuming this feature is wanted by the user
78-
if (features[key] !== false) {
109+
// feature is enabled if: not force disable && (force enabled || no data yet || !supported yet)
110+
if (
111+
features[key] !== false && // feature is force disabled
112+
(
113+
features[key] === true || // feature is forced enabled
114+
caniuseFeaturesMap[key] === undefined || // feature don't have any browsers data (yet)
115+
(caniuseFeaturesMap[key] && caniuseFeaturesMap[key][0] && !caniuse.isSupported(caniuseFeaturesMap[key][0], options.browsers)) // feature is not yet supported by the browsers scope
116+
)
117+
) {
79118
postcss.use(cssnext.features[key](typeof features[key] === "object" ? features[key] : undefined))
80119
}
81120
})

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
],
2929
"dependencies": {
3030
"autoprefixer-core": "^5.0.0",
31+
"caniuse-api": "^1.2.1",
3132
"colors": "^1.0.2",
3233
"commander": "^2.3.0",
3334
"csswring": "^3.0.0",

test/options.browsers.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
var test = require("tape")
2+
3+
var cssnext = require("..")
4+
5+
test("cssnext browsers option", function(t) {
6+
var input = ":root{--foo:bar}baz{qux:var(--foo)}"
7+
var output = "baz{qux: bar}"
8+
9+
t.equal(
10+
cssnext(input, {browsers: "Firefox >= 30"}), // fx 30 doesn't handle custom prop
11+
output,
12+
"should enable custom properties when browsers do not support it"
13+
)
14+
15+
t.equal(
16+
cssnext(input, {browsers: "Firefox >= 31"}), // fx 31 handle custom prop
17+
input,
18+
"should NOT enable custom properties when browsers support it"
19+
)
20+
21+
t.equal(
22+
cssnext(input, {browsers: "Firefox >= 31, IE 8"}), // fx 31 support but not IE 8
23+
output,
24+
"should enable custom properties when at least one browsers do not support it"
25+
)
26+
27+
t.end()
28+
})
29+
30+
test("cssnext browsers option propagation", function(t) {
31+
var input = "body{transition: 1s}"
32+
var output = "body{-webkit-transition: 1s;transition: 1s}"
33+
34+
t.equal(
35+
cssnext(input, {browsers: "Safari 6"}), // Safari 6 need -webkit prefix
36+
output,
37+
"should propagate browsers option to autoprefixer"
38+
)
39+
40+
t.equal(
41+
cssnext(input, {browsers: "Safari 6.1"}), // Safari 6.1 do not need -webkit prefix
42+
input,
43+
"should propagate browsers option to autoprefixer"
44+
)
45+
46+
t.end()
47+
})

0 commit comments

Comments
 (0)