├── .editorconfig
├── .eslintignore
├── .gitignore
├── .npmignore
├── .prettierignore
├── .travis.yml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── appveyor.yml
├── build.config.js
├── docs
├── content
│ ├── CNAME
│ ├── credits.md
│ ├── features.md
│ ├── index.md
│ ├── it-s-cssnext-not-CSSNext.md
│ ├── playground.html
│ ├── postcss.md
│ ├── setup.md
│ └── usage.md
├── scripts
│ ├── build.js
│ ├── deploy-to-gh-pages.sh
│ ├── markdown.js
│ ├── webpack-dev-server.js
│ └── webpack.js
└── src
│ ├── assets
│ ├── cssnext.svg
│ ├── delorean-back.jpg
│ ├── delorean-front.jpg
│ ├── engine.jpg
│ ├── fast.jpg
│ ├── github.svg
│ ├── road.jpg
│ ├── team.jpg
│ └── twitter.svg
│ ├── favicon.png
│ ├── index.css
│ ├── index.js
│ ├── layouts
│ ├── Default.js
│ └── Simple.js
│ └── modules
│ ├── Analytics
│ └── index.js
│ ├── Body
│ └── index.js
│ ├── Footer
│ └── index.js
│ ├── Head
│ └── index.js
│ ├── Header
│ ├── index.js
│ └── link.js
│ ├── Html
│ └── index.js
│ ├── dashify.js
│ ├── formatDate.js
│ ├── headroom.js
│ ├── move-toc.js
│ ├── onAnimationFrame.js
│ ├── playground
│ ├── index.js
│ └── messages.styles.js
│ └── requireRaw.js
├── logo
├── cssnext-256.png
├── cssnext-favicon.svg
├── cssnext-icon-256.png
├── cssnext-icon.svg
├── cssnext-text.svg
└── cssnext.svg
├── package-lock.json
├── package.json
├── src
├── __tests__
│ ├── fixtures
│ │ ├── features
│ │ │ ├── apply-rule.css
│ │ │ ├── apply-rule.expected.css
│ │ │ ├── attribute-case-insensitive.browsers
│ │ │ ├── attribute-case-insensitive.css
│ │ │ ├── attribute-case-insensitive.expected.css
│ │ │ ├── autoprefixer.browsers
│ │ │ ├── autoprefixer.css
│ │ │ ├── autoprefixer.expected.css
│ │ │ ├── calc.css
│ │ │ ├── calc.expected.css
│ │ │ ├── color-function.css
│ │ │ ├── color-function.expected.css
│ │ │ ├── color-gray.css
│ │ │ ├── color-gray.expected.css
│ │ │ ├── color-hex-alpha.browsers
│ │ │ ├── color-hex-alpha.css
│ │ │ ├── color-hex-alpha.expected.css
│ │ │ ├── color-hsl.css
│ │ │ ├── color-hsl.expected.css
│ │ │ ├── color-hwb.css
│ │ │ ├── color-hwb.expected.css
│ │ │ ├── color-rebeccapurple.css
│ │ │ ├── color-rebeccapurple.expected.css
│ │ │ ├── color-rgb.css
│ │ │ ├── color-rgb.expected.css
│ │ │ ├── color-rgba.browsers
│ │ │ ├── color-rgba.css
│ │ │ ├── color-rgba.expected.css
│ │ │ ├── custom-media.css
│ │ │ ├── custom-media.expected.css
│ │ │ ├── custom-properties.browsers
│ │ │ ├── custom-properties.css
│ │ │ ├── custom-properties.expected.css
│ │ │ ├── custom-selectors.css
│ │ │ ├── custom-selectors.expected.css
│ │ │ ├── filter.browsers
│ │ │ ├── filter.css
│ │ │ ├── filter.expected.css
│ │ │ ├── font-family-system-ui.css
│ │ │ ├── font-family-system-ui.expected.css
│ │ │ ├── font-variant.css
│ │ │ ├── font-variant.expected.css
│ │ │ ├── image-set.browsers
│ │ │ ├── image-set.css
│ │ │ ├── image-set.expected.css
│ │ │ ├── initial.browsers
│ │ │ ├── initial.css
│ │ │ ├── initial.expected.css
│ │ │ ├── media-queries-range.css
│ │ │ ├── media-queries-range.expected.css
│ │ │ ├── nesting.css
│ │ │ ├── nesting.expected.css
│ │ │ ├── overflow-wrap.browsers
│ │ │ ├── overflow-wrap.css
│ │ │ ├── overflow-wrap.expected.css
│ │ │ ├── pseudo-class-any-link.css
│ │ │ ├── pseudo-class-any-link.expected.css
│ │ │ ├── pseudo-class-matches.browsers
│ │ │ ├── pseudo-class-matches.css
│ │ │ ├── pseudo-class-matches.expected.css
│ │ │ ├── pseudo-class-not.browsers
│ │ │ ├── pseudo-class-not.css
│ │ │ ├── pseudo-class-not.expected.css
│ │ │ ├── pseudo-elements.browsers
│ │ │ ├── pseudo-elements.css
│ │ │ ├── pseudo-elements.expected.css
│ │ │ ├── rem.browsers
│ │ │ ├── rem.css
│ │ │ └── rem.expected.css
│ │ ├── regression.css
│ │ └── regression.expected.css
│ ├── index.js
│ ├── option.browsers.js
│ ├── option.features.js
│ ├── option.warnForDeprecations.js
│ ├── option.warnForDuplicates.js
│ └── utils
│ │ └── index.js
├── features-activation-map.js
├── features.js
├── index.js
├── warn-for-deprecations.js
└── warn-for-duplicates.js
├── tea.yaml
├── webpack.config.js
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | end_of_line = lf
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 | indent_style = space
10 | indent_size = 2
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | .gitignore
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # npm
2 | node_modules
3 |
4 | # build
5 | lib
6 | docs/dist
7 | src/__tests__/fixtures/**/*.actual.css
8 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # no need for compiled tests
2 | dist/__tests__
3 |
4 | # no need for website sources on npm
5 | docs/dist
6 | docs/scripts
7 | docs/src
8 |
9 | logo
10 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist
2 | lib
3 | src/__tests__/fixtures
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | language: node_js
4 | node_js:
5 | - 10
6 | - 8
7 | - 6
8 |
9 | before_install:
10 | - npm i -g npm@latest
11 | install:
12 | - npm ci
13 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 3.1.0 - 2018-01-22
2 |
3 | * Update postcss-font-family-system-ui to version 3.0 by @JLHwung in
4 | [#443](https://github.com/MoOx/postcss-cssnext/pull/443)
5 | * Update postcss-cli usage example in docs by @RyanZim in
6 | [#444](https://github.com/MoOx/postcss-cssnext/pull/444)
7 |
8 | # 3.0.2 - 2017-07-10
9 |
10 | * Fixed: remove incorrect "postinstall" npm script
11 | ([#404](https://github.com/MoOx/postcss-cssnext/issues/404) - @MoOx)
12 |
13 | # 3.0.1 - 2017-07-10
14 |
15 | * Fixed: specify the actual require peer dependency for caniuse database
16 | (caniuse-lite is used since latest caniuse-api latest major bump) (@MoOx)
17 | * Fixed: bump dependencies not updated to PostCSS@6
18 | ([#401](https://github.com/MoOx/postcss-cssnext/issues/401) - @MoOx)
19 |
20 | # 3.0.0 - 2017-07-05
21 |
22 | ## Removed: support for node 0.12
23 |
24 | Node 4+ is supported.
25 |
26 | ## Changed: upgrade to PostCSS 6
27 |
28 | All postcss plugins dependencies have been updated to latest version to ensure
29 | full PostCSS 6 compatibility.
30 |
31 | Some breaking (minor) changes:
32 |
33 | * image-set polyfill change 2x from 144dpi to 192dpi
34 | * whitespace changes for image-set polyfill output
35 | * rebeccapurpule is now an hexa number
36 | * custom-selector does not output useless (empty) blocks with a selector with no
37 | rules associated
38 |
39 | You can expect some other since all postcss plugins used have been updated to
40 | latest versions. If you have unexpected regression, please check corresponding
41 | plugins changelog before opening an issue.
42 |
43 | ## Added: warning is emitted is you use custom property sets and `@apply`
44 |
45 | This feature won't be included in next the major release of postcss-cssnext.
46 |
47 | This most likely won't get any more support from browser vendors as the spec is
48 | yet considered deprecated and alternative solutions are being discussed. Read
49 | more about the reason here https://github.com/pascalduez/postcss-apply
50 |
51 | # 2.11.0 - 2017-05-15
52 |
53 | * Added: `image-set()` support (via
54 | [postcss-image-set-polyfill](https://github.com/SuperOl3g/postcss-image-set-polyfill))
55 | ([#373](https://github.com/MoOx/postcss-cssnext/pull/373) - @SuperOl3g)
56 | * Added: new auto-deactivation rule in features map
57 | ([#369](https://github.com/MoOx/postcss-cssnext/pull/369) - @Semigradsky)
58 |
59 | # 2.10.0 - 2017-03-16
60 |
61 | * Added: `system-ui` keyword to define current System font-size (via
62 | [postcss-font-family-system-ui](https://github.com/JLHwung/postcss-font-family-system-ui))
63 | ([#342](https://github.com/MoOx/postcss-cssnext/pull/342) - @JLHwung)
64 | * Added: new auto-deactivation rules in features map
65 | ([#345](https://github.com/MoOx/postcss-cssnext/pull/345) - @Semigradsky)
66 |
67 | # 2.9.0 - 2016-11-28
68 |
69 | * Added: new rgb() & hsl() functional notation (via
70 | [postcss-color-rgb](https://github.com/dmarchena/postcss-color-rgb) &
71 | [postcss-color-hsl](https://github.com/dmarchena/postcss-color-hsl) )
72 | ([#330](https://github.com/MoOx/postcss-cssnext/pull/330) - @dmarchena)
73 |
74 | # 2.8.0 - 2016-09-05
75 |
76 | * Added: attribute case insensitive support (eg: `[data-thing=stuff i] {` to be
77 | able to select all `data-thing` attribute, without having to thing about the
78 | case of the value) ([#306](https://github.com/MoOx/postcss-cssnext/pull/306) -
79 | @Semigradsky)
80 |
81 | # 2.7.0 - 2016-06-28
82 |
83 | * Added: `@apply` support (definitions limited to `:root` selector)
84 | ([#291](https://github.com/MoOx/postcss-cssnext/issues/291)) - @pascalduez)
85 |
86 | # 2.6.0 - 2016-06-01
87 |
88 | * Added: `overflow-wrap` fallback
89 | ([#280](https://github.com/MoOx/postcss-cssnext/pull/280) - @MattDiMu)
90 |
91 | # 2.5.2 - 2016-04-04
92 |
93 | * Fixed: pleeease-filters has been udpated to v3, in order to provide a real
94 | PostCSS plugin ([#274](https://github.com/MoOx/postcss-cssnext/pull/274))
95 |
96 | # 2.5.1 - 2016-03-14
97 |
98 | > Oops!
99 |
100 | * Fixed: `"chalk" is undefined`.
101 | ([#266](https://github.com/MoOx/postcss-cssnext/pull/266))
102 | * Fixed: typo in related warning.
103 |
104 | # 2.5.0 - 2016-03-14
105 |
106 | * Added: cssnext will now warn you when you have duplicates plugins. This is a
107 | really common mistake, people include plugins that are already included in
108 | cssnext and maybe sometimes in an inaccurate position.
109 | **Most tutorial on the internet are wrong (probably 99%) and show provide duplicates
110 | in their examples. (eg: autoprefixer + cssnext - but cssnext already includes autoprefixer).**
111 | _In order to fix this, here is a warning. You are welcome._
112 | [Read more about this issue](https://github.com/postcss/postcss/issues/764)
113 | * Added: `rem` will now adjust its behavior according to browser option (IE 9
114 | and IE 10 will only have `px` in some places, where rem support is buggy, per
115 | caniuse notes) ([#264](https://github.com/MoOx/postcss-cssnext/issues/264))
116 |
117 | # 2.4.0 - 2016-01-08
118 |
119 | * Added: documentation is now included in the npm package in
120 | `postcss-cssnext/docs/content`
121 |
122 | # 2.3.0 - 2015-12-16
123 |
124 | * Added: we use latest version of pixrem(@^3)
125 | ([6d44410](https://github.com/MoOx/postcss-cssnext/commit/6d4441023f30895211f010776b142d02359f4d0a))
126 | So now `rem` have
127 | [2 new parameters](https://github.com/robwierzbowski/node-pixrem#options):
128 | * `rootValue` to define the root element font-size manually
129 | * `unitPrecision` for rounded values
130 |
131 | # 2.2.0 - 2015-10-21
132 |
133 | * Added: [postcss-nesting](https://github.com/jonathantneal/postcss-nesting)
134 | ([b31f167](https://github.com/MoOx/postcss-cssnext/commit/b31f167d7659a18a14fce65a7a94da07560e6a59)).
135 | Supports nesting via the `@nest` syntax. See postcss-nesting documentation.
136 |
137 | # 2.1.0 - 2015-09-16
138 |
139 | * Added: [postcss-initial](https://github.com/maximkoretskiy/postcss-initial)
140 | ([a907881](https://github.com/MoOx/postcss-cssnext/commit/a90788153801a3f898f6cc1ade189d4de2af3367)).
141 | Supports `initial` value for all properties. Also it supports `all: initial`.
142 | _Does not support `all: unset` and `all: inherit`._ Plugin can be useful for
143 | creating isolated components.
144 | * `all` specification: https://drafts.csswg.org/css-cascade/#all-shorthand
145 | * `all` browsers support: http://caniuse.com/#feat=css-all
146 | * `initial` value specification:
147 | https://drafts.csswg.org/css-cascade/#initial-value
148 | * `initial` value browser support: http://caniuse.com/#feat=css-initial-value
149 |
150 | # 2.0.1 - 2015-09-14
151 |
152 | * Fixed: plugin can be consumed correctly from es5 environment
153 | ([7d6d3c0](https://github.com/MoOx/postcss-cssnext/commit/7d6d3c018d8ca17091d4cfe3d5d61e246ad8775d)).
154 |
155 | # 2.0.0 - 2015-09-14
156 |
157 | * Added: support for PostCSS v5.x
158 | * Removed: support for PostCSS v4.x
159 | ([b5ece99...8907c13](https://github.com/MoOx/postcss-cssnext/compare/b5ece99c1e1b5e4cdfd6c25f856946bbcbc2247c...8907c13d31662a2cb393edb0387144dfbba81659)).
160 |
161 | ---
162 |
163 | **pre 2.0.0 information was related to `cssnext` package.**
164 |
165 | ---
166 |
167 | # 1.8.4 - 2015-08-24
168 |
169 | * Fixed: `compress` option now works again correctly. A recent update in cssnano
170 | has introduced some minor breaking changes the way cssnext changed plugins
171 | metadata (`pluginName`). A direct minor change is that `messages` (in console
172 | or in css output) now show real origin (postcss plugin name) instead of a
173 | vague "cssnext" origin.
174 | ([#195](https://github.com/MoOx/postcss-cssnext/issues/195))
175 |
176 | # 1.8.3 - 2015-08-06
177 |
178 | * Fixed: `url` option (postcss-url) have been updated in order to benefit from
179 | severals fixes.
180 |
181 | # 1.8.2 - 2015-07-23
182 |
183 | * Fixed: CLI watcher now works watchs correctl multiples `@import`
184 | ([#123](https://github.com/MoOx/postcss-cssnext/issues/123))
185 |
186 | # 1.8.1 - 2015-07-15
187 |
188 | * Added: cssnext now throw an error if used as a webpack loader to prevent
189 | unexpected usage with a recommendation for
190 | [cssnext-loader](https://github.com/MoOx/postcss-cssnext-loader)
191 | ([#61](https://github.com/MoOx/postcss-cssnext/issues/61))
192 |
193 | # 1.8.0 - 2015-06-29
194 |
195 | * Fixed: replacement of `postcss-log-warnings` (deprecated) by
196 | `postcss-reporter`
197 | ([#162](https://github.com/MoOx/postcss-cssnext/issues/162))
198 | * Fixed: CLI now add `to` option automatically
199 | ([#159](https://github.com/MoOx/postcss-cssnext/issues/159)) If you were happy
200 | with the previous CLI behavior (which was not rebasing url), you should
201 | probably just add the `--no-url` to keep the CSS as it was.
202 | * Changed: `compress` option now use cssnano v2.x
203 | ([#166](https://github.com/MoOx/postcss-cssnext/issues/166))
204 | * Added: CLI output file dirname is now automatically created (using `mkdirp`)
205 | ([#146](https://github.com/MoOx/postcss-cssnext/issues/146))
206 |
207 | # 1.7.1 - 2015-06-19
208 |
209 | * Fixed: bullet for browser messages should be visible on Chrome Windows.
210 | Changed from `〉` to `›`
211 |
212 | # 1.7.0 - 2015-06-17
213 |
214 | * Added: warning to deprecate previous (wrong) custom selectors syntax.
215 | Previously they were working with **and without** pseudo syntax ':'
216 | [which is incorrect according to specs](https://github.com/postcss/postcss-custom-selectors/issues/5#issuecomment-90774654)
217 | Now you must use `@custom-selector :--{name}` syntax instead of
218 | `@custom-selector --{name}` The support of syntax without : and the warning
219 | message will be remove in the next major release
220 | ([#97](https://github.com/MoOx/postcss-cssnext/issues/97))
221 | * Added: `plugins` option that allows you to pipe your own transformations
222 | ([#118](https://github.com/MoOx/postcss-cssnext/issues/118))
223 | * Added: `messages` option that allows you to see messages of transformations
224 | ([#88](https://github.com/MoOx/postcss-cssnext/issues/88))
225 | * Added: `:any-link` pseudo class support
226 |
227 | # 1.6.0 - 2015-06-02
228 |
229 | * Added: prevent mutability issues with frozen options objects
230 | ([#147](https://github.com/MoOx/postcss-cssnext/pull/147))
231 |
232 | # 1.5.2 - 2015-05-27
233 |
234 | * Fixed: support for autoprefixer 5.2
235 | ([#131](https://github.com/MoOx/postcss-cssnext/issues/131))
236 |
237 | # 1.5.1 - 2015-05-25
238 |
239 | * Fixed: when printing a bug report in CLI, url was not printed, due to a
240 | replacement of colors lib by chalk in 1.5.0
241 | ([#129](https://github.com/MoOx/postcss-cssnext/pull/129))
242 |
243 | # 1.5.0 - 2015-05-23
244 |
245 | * Changed: `compress` option use [cssnano](https://github.com/ben-eb/cssnano)
246 | instead of CSSWring.
247 |
248 | # 1.4.0 - 2015-05-01
249 |
250 | * Added: support for `:matches()` selector pseudo class
251 | * Added: support for `:not()` selector pseudo class level 4 (transpiled to
252 | level 3)
253 |
254 | # 1.3.1 - 2015-05-01
255 |
256 | * Fixed: CLI `--watch` doesn't make some duplicate rebuild anymore.
257 |
258 | # 1.3.0 - 2015-04-15
259 |
260 | * Added: hexadecimal fallback for rgba() color
261 |
262 | # 1.2.3 - 2015-04-10
263 |
264 | * Fixed: --watch doesn't output console.log() related to watcherd/unwatched
265 | files anymore
266 |
267 | # 1.2.2 - 2015-04-09
268 |
269 | * Changed: upgrade chokidar to stable 1.0.0 (used for cssnext --watch)
270 |
271 | # 1.2.1 - 2015-03-02
272 |
273 | * Fixed: remove some deprecation notice related to postcss 4.1
274 | ([postcss#272](https://github.com/postcss/postcss/issues/272))
275 |
276 | # 1.2.0 - 2015-04-02
277 |
278 | * Added: pseudoElements single colon fallback for pseudoElements double colons
279 | * Added: `--watch` CLI option now checks for changes in imported files
280 |
281 | # 1.1.0 - 2015-03-05
282 |
283 | * Added: `--config` CLI option
284 | * Added: `--browsers`CLI option
285 |
286 | # 1.0.1 - 2015-02-18
287 |
288 | * Fixed: cssnext binary doesn't exit on an error if --watch is enabled
289 | ([#69](https://github.com/MoOx/postcss-cssnext/pull/69))
290 |
291 | # 1.0.0 - 2015-02-06
292 |
293 | * Changed: upgraded to postcss v4.x
294 | * Changed: `import` is not considered as a `feature` anymore, but is now
295 | directly an option for the API. It is still enabled by default.
296 |
297 | Before
298 |
299 | ```js
300 | cssnext({
301 | features: {
302 | import: {
303 | root: "./src"
304 | }
305 | }
306 | });
307 | ```
308 |
309 | After
310 |
311 | ```js
312 | cssnext({
313 | import: {
314 | root: "./src"
315 | }
316 | });
317 | ```
318 |
319 | * Added: `url` option: non absolute url() are now rebased according to `from`
320 | (and `to` options if provided). Enabled by default.
321 | * Added: `compress` option now accept CSSWring options directly.
322 | * Added: `browsers` option can enable or disable features and is propagated to
323 | autoprefixer
324 | * Added: px fallback for `rem` unit
325 |
326 | # 0.6.6 - 2014-12-22
327 |
328 | * Fixed: `Cannot find module 'exit'` error when an error came out
329 | ([#54](https://github.com/MoOx/postcss-cssnext/issues/54))
330 |
331 | # 0.6.5 - 2014-12-16
332 |
333 | * Added: [media queries range](http://dev.w3.org/csswg/mediaqueries/#mq-ranges)
334 | feature ([ref](https://github.com/postcss/postcss-media-minmax))
335 | * Added: [filter](http://www.w3.org/TR/filter-effects/) feature
336 | ([ref](https://github.com/iamvdo/pleeease-filters))
337 |
338 | # 0.6.4 - 2014-12-11
339 |
340 | * Changed: upgrade postcss-import to 4.0.0 for windows compatibility
341 | * Added: Windows compatibility (by building test on AppVeyor)
342 |
343 | # 0.6.3 - 2014-12-09
344 |
345 | * Changed: upgrade to csswring v2.0.0 (postcss 3 ready). This is removing the
346 | boring warnings.
347 | * Changed: update postcss-custom-selectors reference (with an S)
348 |
349 | # 0.6.2 - 2014-12-04
350 |
351 | * Added:
352 | [custom selectors](http://dev.w3.org/csswg/css-extensions/#custom-selectors)
353 | feature ([ref](https://github.com/postcss/postcss-custom-selector)).
354 |
355 | # 0.6.1 - 2014-12-01
356 |
357 | * Changed: update to postcss-calc v3 (which add `precision` & `preserve`) & some
358 | useless minor updates
359 | * Changed: standalone version is now uglified (`dist/cssnext.js`)
360 |
361 | # 0.6.0 - 2014-11-24
362 |
363 | * Changed: upgrade to postcss-import v3 which allow to easily consume
364 | node_modules
365 | * Changed: "prefixes" feature is now "autoprefixer"
366 | * Added: cssnext can be used as a postcss plugin
367 |
368 | # 0.5.0 - 2014-11-13
369 |
370 | * Fixed: cssnext returns a string only if the first parameter is a real string
371 | (typeof === string)
372 | * Changed: upgrade to postcss 3
373 | * Changed: if sourcemap is set to true, default map is now true since postcss
374 | v3.0.0 have by default `{inline: true, sourceContent: true}`
375 | * Changed: upgrade read-file-stdin from 0.0.4 to 0.2.0
376 |
377 | # 0.4.4 - 2014-11-11
378 |
379 | * Fixed: bug introduced by `options` mutations
380 | ([gulp-cssnext#1](https://github.com/cssnext/gulp-cssnext/issues/1))
381 |
382 | # 0.4.3 - 2014-11-09
383 |
384 | * Added: font-variant support
385 | ([#42](https://github.com/MoOx/postcss-cssnext/issues/42))
386 |
387 | # 0.4.2 - 2014-11-02
388 |
389 | * Fixed: support !important for custom properties
390 | ([#12](https://github.com/postcss/postcss-custom-properties/issues/12))
391 | * Added: echo a warning when using a non root custom properties
392 | ([#13](https://github.com/postcss/postcss-custom-properties/issues/13))
393 | * Added: cssnext can return a postcss instance of no string given
394 | ([#3](https://github.com/MoOx/postcss-cssnext/issues/3))
395 |
396 | # 0.4.1 - 2014-11-01
397 |
398 | * Added: gray() support
399 | ([#44](https://github.com/MoOx/postcss-cssnext/issues/44))
400 |
401 | # 0.4.0 - 2014-10-23
402 |
403 | * Changed: color feature has been exploded to multiples features
404 | ([#40](https://github.com/MoOx/postcss-cssnext/issues/40)).
405 |
406 | Before
407 |
408 | ```js
409 | var output = cssnext(input, {
410 | features: {
411 | // providing `true` (or omitting this value) instead of the following object
412 | // was the default behavior
413 | color: {
414 | color: true
415 | hexAlpha: true
416 | hwb: true
417 | rebeccapurple: true
418 | }
419 | }
420 | })
421 | ```
422 |
423 | Now
424 |
425 | ```js
426 | var output = cssnext(input, {
427 | // as usual if you where using all features, you can just omit this values
428 | features: {
429 | colorFunction: true,
430 | colorHexAlpha: true,
431 | colorHwb: true,
432 | colorRebeccapurple: true
433 | }
434 | }
435 | })
436 | ```
437 |
438 | * Changed: cssnext options are not passed to all plugins anymore. You know need
439 | to specify feature options by passing object to `features` properties
440 | ([#39](https://github.com/MoOx/postcss-cssnext/issues/39)).
441 |
442 | Before
443 |
444 | ```js
445 | //eg: preserve custom properties
446 | var output = cssnext(input, {
447 | preserve: true
448 | });
449 | ```
450 |
451 | Now
452 |
453 | ```js
454 | //eg: preserve custom properties
455 | var output = cssnext(input, {
456 | features: {
457 | customProperties: {
458 | preserve: true
459 | }
460 | }
461 | });
462 | ```
463 |
464 | * Added: more control on sourcemap is possible using the new `map` option
465 | (direct postcss option). Using this option make `sourcemap` one to be ignored
466 | and change the return value of `cssnext()` (object instead of string)
467 |
468 | This change have been made to avoid collision between options (of each
469 | features).
470 |
471 | # 0.3.1 - 2014-08-27
472 |
473 | * Fixed: nested custom properties usages
474 | ([#25](https://github.com/MoOx/postcss-cssnext/issues/25))
475 |
476 | # 0.3.0 - 2014-08-26
477 |
478 | * Added: better custom properties fallbacks (thanks to postcss-custom-properties
479 | 0.3.0)
480 |
481 | # 0.2.3 - 2014-08-26
482 |
483 | * Fixed: support empty files
484 | ([#24](https://github.com/MoOx/postcss-cssnext/issues/24))
485 |
486 | # 0.2.2 - 2014-08-22
487 |
488 | * Fixed: missing `bin` in npm files...
489 |
490 | # 0.2.1 - 2014-08-22
491 |
492 | * Fixed: missing `bin` in `package.json` for npm
493 |
494 | # 0.2.0 - 2014-08-20
495 |
496 | * Changed: `from` option doesn't enable `sourcemap` automatically anymore
497 |
498 | # 0.1.0 - 2014-08-19
499 |
500 | ✨ First release
501 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Code of Conduct
2 |
3 | As contributors and maintainers of this project, we pledge to respect all people
4 | who contribute through reporting issues, posting feature requests, updating
5 | documentation, submitting pull requests or patches, and other activities.
6 |
7 | We are committed to making participation in this project a harassment-free
8 | experience for everyone, regardless of level of experience, gender, gender
9 | identity and expression, sexual orientation, disability, personal appearance,
10 | body size, race, age, or religion.
11 |
12 | Examples of unacceptable behavior by participants include the use of sexual
13 | language or imagery, derogatory comments or personal attacks, trolling, public
14 | or private harassment, insults, or other unprofessional conduct.
15 |
16 | Project maintainers have the right and responsibility to remove, edit, or reject
17 | comments, commits, code, wiki edits, issues, and other contributions that are
18 | not aligned to this Code of Conduct. Project maintainers who do not follow the
19 | Code of Conduct may be removed from the project team.
20 |
21 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
22 | reported by opening an issue or contacting one or more of the project
23 | maintainers.
24 |
25 | This Code of Conduct is adapted from the
26 | [Contributor Covenant](http://contributor-covenant.org), version 1.0.0,
27 | available at
28 | [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
29 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | _postcss-cssnext uses a lot of [postcss](https://github.com/postcss) plugins, so
4 | you might need to take a look at them if you find an issue or want to create or
5 | enhance a feature._
6 |
7 | Otherwise, fork, work on a branch, install dev-dependencies, respect coding
8 | style & run tests before submitting a bug fix or a feature.
9 |
10 | ```console
11 | $ git clone https://github.com/YOU/postcss-cssnext.git
12 | $ npm install
13 | $ npm test
14 | $ git checkout -b fix.bug423
15 | ```
16 |
17 | `npm test` will compile what is need to be and run all tests. If you want to
18 | work on one test only, you can run something like
19 |
20 | ```console
21 | $ babel-tape-runner src/__tests__/option.browsers.js
22 | ```
23 |
24 | _Be sure to have in your PATH `./node_modules/.bin` so you can use local module
25 | directly in console._
26 |
27 | ## Details
28 |
29 | ### Add a feature
30 |
31 | 1. Add test files (input + expected output) in
32 | [`src/__tests__/fixtures/features`](src/__tests__/features)
33 |
34 | * Choose a pretty simple and clear name (that match the specs), if you are not
35 | sure, ask using an issue.
36 | * Add the feature in :
37 | * `docs/content/index.md` (http://cssnext.io/)
38 | * `docs/content/features.md` (http://cssnext.io/features/) with an example +
39 | link to specs like others features
40 | * Add the dependency in the [`package.json`](package.json) (use
41 | `npm install --save postcss-...`)
42 | * Add the feature in the source (in [`src/features.js`](src/features.js)), in
43 | the appropriate place (order matter) For now, use a empty function instead of
44 | the right module
45 | * Run test, & check tests are broken (otherwise feature is useless) Now, call
46 | the right plugin in the function you just created
47 | * Run test and be happy
48 | * Add feature on [the playground](docs/content/playground.html) example
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Maxime Thirouin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## `postcss-cssnext` has been deprecated in favor of `postcss-preset-env`
2 |
3 | Read more at https://moox.io/blog/deprecating-cssnext/
4 |
5 | # postcss-cssnext
6 |
7 | > PostCSS plugin to use tomorrow’s CSS syntax, today.
8 |
9 | PostCSS-cssnext is a PostCSS plugin that helps you to use the latest CSS syntax
10 | today. It transforms CSS specs into more compatible CSS so you don’t need to
11 | wait for browser support.
12 |
13 | ---
14 |
15 | ## [Changelog](CHANGELOG.md)
16 |
17 | ## [License](LICENSE)
18 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | # http://www.appveyor.com/docs/appveyor-yml
2 |
3 | environment:
4 | matrix:
5 | - nodejs_version: 10
6 | - nodejs_version: 8
7 | - nodejs_version: 6
8 |
9 | version: "{build}"
10 | build: off
11 | deploy: off
12 | matrix:
13 | fast_finish: true
14 |
15 | install:
16 | - ps: Install-Product node $env:nodejs_version
17 | - npm install -g npm@latest
18 | - npm ci
19 |
20 | test_script:
21 | - node --version
22 | - npm --version
23 | - npm test
24 |
--------------------------------------------------------------------------------
/build.config.js:
--------------------------------------------------------------------------------
1 | const assign = require("object-assign");
2 |
3 | const dev = process.argv.indexOf("--dev") > -1;
4 | const devServer = process.argv.indexOf("--dev-server") > -1;
5 | const production = process.argv.indexOf("--production") > -1;
6 |
7 | const config = assign(
8 | {
9 | __DEV__: dev,
10 | __DEV_SERVER__: devServer,
11 | __PROD__: production,
12 | __SERVER_PROTOCOL__: "http://"
13 | },
14 | production
15 | ? {
16 | "process.env": {
17 | NODE_ENV: JSON.stringify("production")
18 | },
19 | __SERVER_HOSTNAME__: "cssnext.io",
20 | __SERVER_HOST__: "cssnext.io"
21 | }
22 | : {
23 | __SERVER_HOSTNAME__: "0.0.0.0",
24 | __SERVER_PORT__: 1985,
25 | __SERVER_HOST__: "0.0.0.0:1985",
26 | __LR_SERVER_PORT__: 1986
27 | }
28 | );
29 |
30 | config.__SERVER_URL__ = `${config.__SERVER_PROTOCOL__}${
31 | config.__SERVER_HOST__
32 | }`;
33 |
34 | module.exports = config;
35 |
--------------------------------------------------------------------------------
/docs/content/CNAME:
--------------------------------------------------------------------------------
1 | cssnext.io
2 |
--------------------------------------------------------------------------------
/docs/content/credits.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Credits
3 | footer: false
4 | ---
5 |
6 | * [delorean back](https://www.flickr.com/photos/jasoncipriani/11866004734)
7 | * [delorean with blue trails](https://www.flickr.com/photos/wizzer/9295055565)
8 | * [bttf legos](https://www.flickr.com/photos/brianneudorff/10047726604)
9 | * [delorean side](https://www.flickr.com/photos/mooshuu/5963681346)
10 |
--------------------------------------------------------------------------------
/docs/content/features.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: postcss-cssnext features
3 | subtitle: Discover the future of CSS
4 |
5 | backgroundModifier: darkRoad
6 | ---
7 |
8 | @[toc]
9 |
10 | **Note that according to your [browser scope](/usage/#browsers) some
11 | transformations can be skipped to avoid extra useless output.** Eg: if you use
12 | don't cover IE 8, rem fallback and rgba fallback might be skipped.
13 |
14 | ## automatic vendor prefixes
15 |
16 | Vendor prefixes are automatically added (and removed if deprecated/useless
17 | depending on your browser scope) using
18 | **[autoprefixer](https://github.com/postcss/autoprefixer)**.
19 |
20 | ## custom properties & `var()`
21 |
22 | The current transformation for custom properties aims to provide a future-proof
23 | way of using a **limited to `:root` selector** of the features provided by
24 | native CSS custom properties.
25 |
26 | ```css
27 | :root {
28 | --mainColor: red;
29 | }
30 |
31 | a {
32 | color: var(--mainColor);
33 | }
34 | ```
35 |
36 | ⚠️
37 | [_The definitions are **limited to `:root` selector.**_](https://github.com/postcss/postcss-custom-properties#readme)
38 |
39 | [Specification](http://www.w3.org/TR/css-variables/) |
40 | [Plugin documentation](https://github.com/postcss/postcss-custom-properties)
41 |
42 | ## custom properties set & `@apply`
43 |
44 | Allows you to store a set of properties in a named custom property, then
45 | reference them in other style rules.
46 |
47 | ```css
48 | :root {
49 | --danger-theme: {
50 | color: white;
51 | background-color: red;
52 | }
53 | }
54 |
55 | .danger {
56 | @apply --danger-theme;
57 | }
58 | ```
59 |
60 | ⚠️
61 | [_The definitions are **limited to `:root` selector.**_](https://github.com/postcss/postcss-custom-properties#readme)
62 |
63 | [Specification](https://tabatkins.github.io/specs/css-apply-rule) |
64 | [Plugin documentation](https://github.com/pascalduez/postcss-apply)
65 |
66 | ## reduced `calc()`
67 |
68 | Allows you to use safely calc with custom properties by optimizing previously
69 | parsed `var()` references.
70 |
71 | ```css
72 | :root {
73 | --fontSize: 1rem;
74 | }
75 |
76 | h1 {
77 | font-size: calc(var(--fontSize) * 2);
78 | }
79 | ```
80 |
81 | [Specification](https://github.com/MoOx/reduce-css-calc#readme) |
82 | [Plugin documentation](https://github.com/postcss/postcss-calc)
83 |
84 | ## custom media queries
85 |
86 | A nice way to have semantic media queries.
87 |
88 | ```css
89 | @custom-media --small-viewport (max-width: 30em);
90 | /* check out media queries ranges for a better syntax !*/
91 |
92 | @media (--small-viewport) {
93 | /* styles for small viewport */
94 | }
95 | ```
96 |
97 | [Specification](https://drafts.csswg.org/mediaqueries-5/#custom-mq) |
98 | [Plugin documentation](https://github.com/postcss/postcss-custom-media)
99 |
100 | ## media queries ranges
101 |
102 | Allows to replace min-/max- with `<=` & `>=` (syntax easier to read).
103 |
104 | ```css
105 | @media (width >= 500px) and (width <= 1200px) {
106 | /* your styles */
107 | }
108 |
109 | /* or coupled with custom media queries */
110 | @custom-media --only-medium-screen (width >= 500px) and (width <= 1200px);
111 |
112 | @media (--only-medium-screen) {
113 | /* your styles */
114 | }
115 | ```
116 |
117 | [Specification](http://dev.w3.org/csswg/mediaqueries/#mq-ranges) |
118 | [Plugin documentation](https://github.com/postcss/postcss-media-minmax)
119 |
120 | ## custom selectors
121 |
122 | Allows you to create your own selectors.
123 |
124 | ```css
125 | @custom-selector :--button button, .button;
126 | @custom-selector :--enter :hover, :focus;
127 |
128 | :--button {
129 | /* styles for your buttons */
130 | }
131 | :--button:--enter {
132 | /* hover/focus styles for your button */
133 | /* Read more about :enter proposal */
134 | /* http://discourse.specifiction.org/t/a-common-pseudo-class-for-hover-and-focus/877 */
135 | }
136 | ```
137 |
138 | [Specification](http://dev.w3.org/csswg/css-extensions/#custom-selectors) |
139 | [Plugin documentation](https://github.com/postcss/postcss-custom-selector)
140 |
141 | ## nesting
142 |
143 | Allows you to nest selectors.
144 |
145 | ```scss
146 | a {
147 | /* direct nesting (& MUST be the first part of selector)*/
148 | & span {
149 | color: white;
150 | }
151 |
152 | /* @nest rule (for complex nesting) */
153 | @nest span & {
154 | color: blue;
155 | }
156 |
157 | /* media query automatic nesting */
158 | @media (min-width: 30em) {
159 | color: yellow;
160 | }
161 | }
162 | ```
163 |
164 | [Specification](http://tabatkins.github.io/specs/css-nesting/) |
165 | [Plugin documentation](https://github.com/jonathantneal/postcss-nesting)
166 |
167 | ## `image-set()` function
168 |
169 | Allows you to set different images for each kind of resolution of user device.
170 |
171 | ```css
172 | .foo {
173 | background-image: image-set(
174 | url(img/test.png) 1x,
175 | url(img/test-2x.png) 2x,
176 | url(my-img-print.png) 600dpi
177 | );
178 | }
179 | ```
180 |
181 | [Specification](https://drafts.csswg.org/css-images-3/#image-set-notation) |
182 | [Plugin documentation](https://github.com/SuperOl3g/postcss-image-set-polyfill)
183 |
184 | ## `color()` function
185 |
186 | A color function to modify colors (transpiled to: `rgba()`).
187 |
188 | ```css
189 | a {
190 | color: color(red alpha(-10%));
191 | }
192 |
193 | a:hover {
194 | color: color(red blackness(80%));
195 | }
196 | ```
197 |
198 | There is a
199 | [lot of color modifiers available](https://github.com/postcss/postcss-color-function#list-of-color-adjuster),
200 | so be sure to check them !
201 |
202 | [Specification](http://dev.w3.org/csswg/css-color/#modifying-colors) |
203 | [Plugin documentation](https://github.com/postcss/postcss-color-function)
204 |
205 | ## `hwb()` function
206 |
207 | Similar to `hsl()` but easier for humans to work with (transpiled to: `rgba()`).
208 |
209 | ```css
210 | body {
211 | color: hwb(90, 0%, 0%, 0.5);
212 | }
213 | ```
214 |
215 | [Specification](http://dev.w3.org/csswg/css-color/#the-hwb-notation) |
216 | [Plugin documentation](https://github.com/postcss/postcss-color-hwb)
217 |
218 | ## `gray()` function
219 |
220 | Allows you to use more than 50 shades of gray (transpiled to: `rgba()`). For the
221 | first argument, you can use a number between 0 and 255 or a percentage.
222 |
223 | ```css
224 | .foo {
225 | color: gray(85);
226 | }
227 |
228 | .bar {
229 | color: gray(10%, 50%);
230 | }
231 | ```
232 |
233 | [Specification](http://dev.w3.org/csswg/css-color/#grays) |
234 | [Plugin documentation](https://github.com/postcss/postcss-color-gray)
235 |
236 | ## `#rrggbbaa` colors
237 |
238 | Allows you to use 4 or 8 digits hexadecimal notation (transpiled to: `rgba()`).
239 |
240 | ```css
241 | body {
242 | background: #9d9c;
243 | }
244 | ```
245 |
246 | [Specification](http://dev.w3.org/csswg/css-color/#hex-notation) |
247 | [Plugin documentation](https://github.com/postcss/postcss-color-hex-alpha)
248 |
249 | ## `rgba` function (`rgb` fallback)
250 |
251 | Add solid colors fallback for rgba colors (if your browser scope covers old
252 | browsers, eg: IE8).
253 |
254 | ```css
255 | body {
256 | background: rgba(153, 221, 153, 0.8);
257 | /* you will have the same value without alpha as a fallback */
258 | }
259 | ```
260 |
261 | [Specification](http://www.w3.org/TR/css3-color/) |
262 | [Plugin documentation](https://github.com/postcss/postcss-color-rgba-fallback)
263 |
264 | ## `rebeccapurple` color
265 |
266 | Allows you to use the new color keyword as a homage to
267 | [Eric Meyer’s daughter](https://github.com/postcss/postcss-color-rebeccapurple#why-this-plugin-).
268 |
269 | ```css
270 | body {
271 | color: rebeccapurple;
272 | }
273 | ```
274 |
275 | [Specification](http://dev.w3.org/csswg/css-color/#valdef-color-rebeccapurple) |
276 | [Plugin documentation](https://github.com/postcss/postcss-color-rebeccapurple)
277 |
278 | ## `font-variant` property
279 |
280 | properties (fallback: `font-feature-settings`).
281 |
282 | ```css
283 | h2 {
284 | font-variant-caps: small-caps;
285 | }
286 |
287 | table {
288 | font-variant-numeric: lining-nums;
289 | }
290 | ```
291 |
292 | `font-variant` are transformed to `font-feature-settings`. You might take a look
293 | at the support of
294 | [font feature settings](http://caniuse.com/#feat=font-feature).
295 |
296 | [Specification](http://dev.w3.org/csswg/css-fonts/#propdef-font-variant) |
297 | [Plugin documentation](https://github.com/postcss/postcss-font-variant)
298 |
299 | ## `filter` property
300 |
301 | The W3C filters are only transformed as svg filter using the `url(data:*)` trick
302 | for Firefox < 35.
303 |
304 | ```css
305 | .blur {
306 | filter: blur(4px);
307 | }
308 | ```
309 |
310 | [Specification](http://www.w3.org/TR/filter-effects/) |
311 | [Plugin documentation](https://github.com/iamvdo/pleeease-filters)
312 |
313 | ## `initial` value
314 |
315 | Allows you to use `initial` value for any property. This value represents the value
316 | specified as the property’s initial value. **It does not mean browser default.**
317 |
318 | For example, for the `display` property, `initial` always means `inline`,
319 | because that’s the designated initial value of the property. As an example,
320 | using `div { display: initial }`, will **not** be `block`, but `inline`.
321 |
322 | ```css
323 | div {
324 | display: initial; /* inline */
325 | }
326 | ```
327 |
328 | _Killer feature :_
329 |
330 | ```css
331 | div {
332 | all: initial; /* use initial for ALL PROPERTIES in one shot */
333 | }
334 | ```
335 |
336 | [Specification](http://www.w3.org/TR/css3-values/#common-keywords) |
337 | [Plugin documentation](https://github.com/maximkoretskiy/postcss-initial)
338 |
339 | ## `rem` unit (`px` fallback)
340 |
341 | `rem` fallback to `px` (if your browser scope covers old browsers, eg: IE8).
342 |
343 | ```css
344 | h1 {
345 | font-size: 1.5rem;
346 | }
347 | ```
348 |
349 | [Specification](http://www.w3.org/TR/css3-values/#rem-unit) |
350 | [Plugin documentation](https://github.com/robwierzbowski/node-pixrem)
351 |
352 | ## `:any-link` pseudo-class
353 |
354 | Allows you to use `:any-link` pseudo class.
355 |
356 | ```css
357 | nav :any-link {
358 | background-color: yellow;
359 | }
360 | ```
361 |
362 | [Specification](http://dev.w3.org/csswg/selectors/#any-link-pseudo) |
363 | [Plugin documentation](https://github.com/jonathantneal/postcss-pseudo-class-any-link)
364 |
365 | ## `:matches` pseudo-class
366 |
367 | Allows you to use `:matches()`.
368 |
369 | ```css
370 | p:matches(:first-child, .special) {
371 | color: red;
372 | }
373 | ```
374 |
375 | [Specification](http://dev.w3.org/csswg/selectors-4/#matches) |
376 | [Plugin documentation](https://github.com/postcss/postcss-selector-matches)
377 |
378 | ## `:not` pseudo-class
379 |
380 | Allows you to use `:not()` level 4 (which allows multiples selector).
381 | Transformed to `:not()` level 3 (which allows only one selector).
382 |
383 | ```css
384 | p:not(:first-child, .special) {
385 | color: red;
386 | }
387 | ```
388 |
389 | [Specification](http://dev.w3.org/csswg/selectors-4/#negation) |
390 | [Plugin documentation](https://github.com/postcss/postcss-selector-NOT)
391 |
392 | ## `::` pseudo syntax (`:` fallback)
393 |
394 | Adjust `::` to `:` (if your browser scope covers old browsers, eg: IE8).
395 |
396 | ```css
397 | a::before {
398 | /* ... */
399 | }
400 | ```
401 |
402 | [Specification](http://www.w3.org/TR/css3-selectors/#pseudo-elements) |
403 | [Plugin documentation](https://github.com/axa-ch/postcss-pseudoelements)
404 |
405 | ## `overflow-wrap` property (`word-wrap` fallback)
406 |
407 | Converts `overflow-wrap` to `word-wrap` (many browsers only support the old
408 | [word-wrap](http://caniuse.com/#feat=wordwrap) property).
409 |
410 | ```css
411 | body {
412 | overflow-wrap: break-word;
413 | }
414 | ```
415 |
416 | [Specification](https://drafts.csswg.org/css-text-3/#propdef-word-wrap) |
417 | [Plugin documentation](https://github.com/MattDiMu/postcss-replace-overflow-wrap)
418 |
419 | ## attribute case insensitive
420 |
421 | Allows you to use case insensitive attributes.
422 |
423 | ```css
424 | [frame="hsides" i] {
425 | border-style: solid none;
426 | }
427 | ```
428 |
429 | [Specification](https://www.w3.org/TR/selectors4/#attribute-case) |
430 | [Plugin documentation](https://github.com/Semigradsky/postcss-attribute-case-insensitive)
431 |
432 | ## `rgb()` function (functional-notation)
433 |
434 | Allows you to use its new syntax consisting of space-separated arguments and an
435 | optional slash-separated opacity.
436 |
437 | You can also use number for color channels.
438 |
439 | The alpha value accepts percentage as well as number and has been added to
440 | `rgb()` as optional argument. As a result, `rgb()` and `rgba()` are now aliases
441 | of each other.
442 |
443 | ```css
444 | div {
445 | background-color: rgb(100 222.2 100.9 / 30%);
446 | }
447 | ```
448 |
449 | [Specification](https://drafts.csswg.org/css-color/#rgb-functions) |
450 | [Plugin documentation](https://github.com/dmarchena/postcss-color-rgb)
451 |
452 | ## `hsl()` function (functional-notation)
453 |
454 | Allows you to use its new syntax consisting of space-separated arguments and an
455 | optional slash-separated opacity.
456 |
457 | `hsl()` now accepts angles (`deg`, `grad`, `rad`, `turn`) as well as numbers for
458 | hues and an optional percentage or number for alpha value. So, `hsl()` and
459 | `hsla()` are now aliases of each other too.
460 |
461 | ```css
462 | div {
463 | color: hsl(90deg 90% 70%);
464 | background-color: hsl(300grad 25% 15% / 70%);
465 | }
466 | ```
467 |
468 | [Specification](https://drafts.csswg.org/css-color/#the-hsl-notation) |
469 | [Plugin documentation](https://github.com/dmarchena/postcss-color-hsl)
470 |
471 | ## `system-ui` font-family
472 |
473 | Allows you to use `system-ui` generic font-family. The current transformation
474 | provides a practical font-family list as fallback.
475 |
476 | ```css
477 | body {
478 | font-family: system-ui;
479 | }
480 | ```
481 |
482 | [Specification](https://drafts.csswg.org/css-fonts-4/#valdef-font-family-system-ui)
483 | |
484 | [Plugin documentation](https://github.com/JLHwung/postcss-font-family-system-ui)
485 |
486 | ## @todo
487 |
488 | Any omissions of the CSS specifications (even in draft) that are subject to be
489 | handled by cssnext are not intentional. You can take a look at the
490 | [list of features that are waiting to be implemented](https://github.com/MoOx/postcss-cssnext/issues?q=is%3Aopen+is%3Aissue+label%3A%22type%3A+feature+request%22).
491 | Feel free to work on a feature ready to be added, or
492 | [open a new issue](https://github.com/MoOx/postcss-cssnext/issues/new) if you
493 | find something that should be handled. Keep in mind that, as of right now, this
494 | project is intended to support new CSS _syntax_ only.
495 |
--------------------------------------------------------------------------------
/docs/content/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | template: Simple
3 | title: cssnext - Use tomorrow’s CSS syntax, today.
4 | ---
5 |
6 |
32 |
33 |
34 |
35 |
What is cssnext?
36 |
37 | PostCSS-cssnext is a PostCSS
38 | plugin that helps you to use the latest CSS syntax today.
39 | It transforms
40 | new CSS specs
41 | into more compatible CSS
42 | so you don't need to wait for browser support.
43 |
44 | You can literally write future-proof CSS
45 | and forget old preprocessor specific syntax.
46 |
47 |
48 |
49 |
50 |
51 |
165 |
169 |
170 | l.* are level of the specification (when information is relevant)
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
Why cssnext?
180 |
181 | Prior to 2015, CSS was frustrating by not having any specification for features we were looking for.
182 | No variables, no math, no color manipulation & no customization.
183 | Things are going to change soon since a lot of work has been made by the W3C to write new specs to make our life easier.
184 | With cssnext, you can start using some new features today!
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
Future-proof code
194 |
195 | In a near future, browsers will implement new CSS specifications. As time passes, cssnext will remove some transformations that won't be necessary anymore.
196 | And maybe one day, you will be able to completely remove cssnext from your workflow without touching your CSS.
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
It's fast. Lightning fast.
207 |
208 | cssnext uses PostCSS
209 | which has
210 | a way faster CSS parser .
211 |
212 | It's a good competitor to libsass, a bit faster than LESS and Stylecow,
213 | and way faster than Myth or original Ruby Sass.
214 |
215 |
216 |
217 |
218 |
219 |
228 |
229 |
241 |
242 |
243 |
244 |
245 |
248 |
249 | You can also check
250 | suitcss
251 | or
252 | basscss
253 |
254 |
255 |
256 |
257 |
--------------------------------------------------------------------------------
/docs/content/it-s-cssnext-not-CSSNext.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "It's cssnext, not CSSNext"
3 | footer: false
4 | ---
5 |
6 | ## Is it cssnext or CSSNext or CSSnext?
7 |
8 | The official name is **cssnext**, which should never be capitalized, especially
9 | not at the start of a sentence, unless it is being displayed in a location that
10 | is customarily all-caps (such as the title of man pages).
11 |
12 | ### Why ?
13 |
14 | ```js
15 | function nameify(string) {
16 | return string.replace(" ", "").toLowerCase();
17 | }
18 |
19 | nameify("CSS Next");
20 | nameify("CSSNext");
21 | nameify("CSSnext");
22 | nameify("CSS next");
23 | nameify("css next");
24 | nameify("cssnext");
25 |
26 | // all the results above are just the same
27 | // -> "cssnext" !
28 | ```
29 |
--------------------------------------------------------------------------------
/docs/content/playground.html:
--------------------------------------------------------------------------------
1 | ---
2 | template: Simple
3 | title: cssnext Playground
4 | className: js-cssnext-Playground cssnext-Playground
5 | footer: false
6 | scripts:
7 | - /playground.js
8 | ---
9 |
10 |
11 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/docs/content/postcss.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Using postcss-cssnext
3 | subtitle: How to migrate from cssnext to postcss-cssnext
4 | ---
5 |
6 | ## Why **postcss-cssnext**? What is the difference with **cssnext**?
7 |
8 | ### Short answer: PostCSS
9 |
10 | If you're using [PostCSS](https://github.com/postcss/postcss) in your build
11 | process, and you were using `cssnext`, you can quickly switch to only
12 | `postcss-cssnext` (check the [Migration](#migration) section here below).
13 |
14 | ### Wait? What is PostCSS?
15 |
16 | At first, before PostCSS became popular, cssnext was designed to be a complete
17 | tool. Thus, cssnext included some options that don't really belong in a PostCSS
18 | plugin focused on the future of CSS (e.g., `import`, `url`, `compress`,
19 | `plugins`...) .
20 |
21 | These days, most people use [PostCSS](https://github.com/postcss/postcss)
22 | directly (so they can easily adjust and choose their CSS transformations). So we
23 | decided to make the integration of cssnext simpler by providing a simple (real)
24 | plugin.
25 |
26 | Also, having to maintain several cssnext and PostCSS runners that do almost the
27 | same thing is not optimal.
28 |
29 | ### Migration
30 |
31 | If you were using cssnext with some options, here is what you need to know:
32 |
33 | #### Options
34 |
35 | ##### Options `import`, `url`, `compress`, `messages`
36 |
37 | * `import` options is just
38 | [`postcss-import`](https://github.com/postcss/postcss-import)
39 | * `url` option is just [`postcss-url`](https://github.com/postcss/postcss-url)
40 | * `compress` option is just [`cssnano`](https://github.com/ben-eb/cssnano)
41 | * `messages`: was a combination of
42 | [`postcss-reporter`](https://github.com/postcss/postcss-reporter) and
43 | [`postcss-browser-reporter`](https://github.com/postcss/postcss-browser-reporter).
44 | Just pick up the one you want (or both).
45 |
46 | ##### Option `plugins`
47 |
48 | Just add the plugins directly in your PostCSS list.
49 |
50 | ##### Options `sourcemap`, `map`, `to`, `from`
51 |
52 | These options were just proxy to
53 | [PostCSS source map options](https://github.com/postcss/postcss/blob/master/docs/source-maps.md).
54 |
55 | #### Examples
56 |
57 | If you were using cssnext with default options, you might just need this:
58 |
59 | ```console
60 | $ npm uninstall cssnext [--save[-dev]]
61 | $ npm install postcss postcss-import postcss-url postcss-cssnext postcss-browser-reporter postcss-reporter [--save[-dev]]
62 | ```
63 |
64 | With the previous lines you might think that you are going backward by having a
65 | more complex boilerplate. But if you look carefully, you will notice that you
66 | might not be interested in some options.
67 |
68 | Now that you have the appropriate plugins, here are some examples with some
69 | runners and previous default cssnext behavior.
70 |
71 | ##### [postcss-cli](https://www.npmjs.com/package/postcss-cli)
72 |
73 | ```console
74 | $ npm install postcss-cli --save-dev
75 | ```
76 |
77 | Here is an example of the JS config you might use with something like
78 | `$ postcss input.css -o output.css`.
79 |
80 | **postcss.config.js**
81 |
82 | ```js
83 | module.exports = {
84 | plugins: [
85 | require("postcss-import"),
86 | require("postcss-url"),
87 | require("postcss-cssnext"),
88 | // add your "plugins" here
89 | // ...
90 | // and if you want to compress
91 | // require('cssnano'),
92 | require("postcss-browser-reporter")
93 | ]
94 | };
95 | ```
96 |
97 | ##### [grunt-postcss](https://www.npmjs.com/package/grunt-postcss)
98 |
99 | ```console
100 | $ npm uninstall grunt-cssnext --save-dev
101 | $ npm install grunt-postcss --save-dev
102 | ```
103 |
104 | ```js
105 | grunt.initConfig({
106 | postcss: {
107 | options: {
108 | processors: [
109 | require("postcss-import")(),
110 | require("postcss-url")(),
111 | require("postcss-cssnext")(),
112 | // add your "plugins" here
113 | // ...
114 | // and if you want to compress
115 | // Disable autoprefixer, because it's already included in cssnext
116 | // require("cssnano")({ autoprefixer: false }),
117 | require("postcss-browser-reporter")(),
118 | require("postcss-reporter")()
119 | ]
120 | },
121 | dist: {
122 | src: "css/*.css"
123 | }
124 | }
125 | });
126 | ```
127 |
128 | ##### [gulp-postcss](https://www.npmjs.com/package/gulp-postcss)
129 |
130 | ```console
131 | $ npm uninstall gulp-cssnext --save-dev
132 | $ npm install gulp-postcss --save-dev
133 | ```
134 |
135 | ```js
136 | var gulp = require("gulp");
137 | var postcss = require("gulp-postcss");
138 |
139 | gulp.task("css", function() {
140 | return gulp
141 | .src("./src/*.css")
142 | .pipe(
143 | postcss([
144 | require("postcss-import")(),
145 | require("postcss-url")(),
146 | require("postcss-cssnext")(),
147 | // add your "plugins" here
148 | // ...
149 | // and if you want to compress
150 | // Disable autoprefixer, because it's already included in cssnext
151 | // require("cssnano")({ autoprefixer: false }),
152 | require("postcss-browser-reporter")(),
153 | require("postcss-reporter")()
154 | ])
155 | )
156 | .pipe(gulp.dest("./dest"));
157 | });
158 | ```
159 |
160 | ##### [postcss-loader](https://www.npmjs.com/package/postcss-loader)
161 |
162 | ```console
163 | $ npm uninstall cssnext-loader --save-dev
164 | $ npm install postcss-loader --save-dev
165 | ```
166 |
167 | ```js
168 | module.exports = {
169 | module: {
170 | loaders: [
171 | {
172 | test: /\.css$/,
173 | loader: "style-loader!css-loader!postcss-loader"
174 | }
175 | ]
176 | },
177 | postcss: function(webpack) {
178 | return [
179 | require("postcss-import")({ addDependencyTo: webpack }),
180 | require("postcss-url")(),
181 | require("postcss-cssnext")(),
182 | // add your "plugins" here
183 | // ...
184 | // and if you want to compress,
185 | // just use css-loader option that already use cssnano under the hood
186 | require("postcss-browser-reporter")(),
187 | require("postcss-reporter")()
188 | ];
189 | }
190 | };
191 | ```
192 |
193 | **With these examples, you'll have future facing CSS. Feel free to adjust the
194 | configuration with the appropriate [PostCSS runner](/setup/#usage).**
195 |
--------------------------------------------------------------------------------
/docs/content/setup.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Install & setup postcss-cssnext
3 | subtitle: How to use postcss-cssnext in your workflow
4 | backgroundModifier: darkTeam
5 | ---
6 |
7 | @[toc]
8 |
9 | ## Installation
10 |
11 | postcss-cssnext is available on
12 | [npm](https://www.npmjs.org/package/postcss-cssnext)
13 |
14 | ```console
15 | $ npm install postcss postcss-cssnext
16 | ```
17 |
18 | ## Usage
19 |
20 | You can use directly PostCSS API but you will probably want to choose and use a
21 | PostCSS runner that suits your workflow:
22 |
23 |
24 | CLI ,
25 | webpack ,
26 | gulp ,
27 | grunt ,
28 | browserify ,
29 | brunch ,
30 | broccoli ,
31 | fly ,
32 | connect/express ,
33 | duo
34 | or in
35 | Prepros
36 |
37 |
38 | ---
39 |
40 | ## Wait, what? Where is the previous cssnext interface?
41 |
42 | [`cssnext` is dead. Long live to `postcss-cssnext`.](/postcss/)
43 |
44 | ## Wait, what is PostCSS?
45 |
46 | [Here is what you are looking for.](https://github.com/postcss/postcss#readme)
47 |
--------------------------------------------------------------------------------
/docs/content/usage.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Using postcss-cssnext
3 | subtitle: How to configure postcss-cssnext options
4 | ---
5 |
6 | @[toc]
7 |
8 | When you have correctly [setup](/setup/) cssnext, you might want to tweak it a
9 | little bit. You will find below all the available **options**.
10 |
11 | ## `browsers`
12 |
13 | _(default: [browserslist default](https://github.com/ai/browserslist#readme)
14 | `> 1%, last 2 versions, Firefox ESR, Opera 12.1`)_
15 |
16 | Allows you to specify your browser scope. **This option enables or disables
17 | `features` according to [caniuse](http://caniuse.com/) database.** This is the
18 | exact same option that you might know from Autoprefixer. Since cssnext includes
19 | Autoprefixer, the option is propagated.
20 |
21 | See [Browserslist](https://github.com/ai/browserslist#queries) queries syntax to
22 | adjust this option to your needs.
23 |
24 | _Note: if you don't specify this option, Browserslist will automatically try to
25 | find a `browserslist` config file or use its default value._
26 |
27 | ## `features`
28 |
29 | _(default: all features depending on your `browsers` options)_
30 |
31 | **You should probably use `browsers` option instead of this one.**
32 |
33 | Object containing key of features to enable/disable. _Features are enabled by
34 | default: no key means feature is enabled_. Keys can be found by looking in
35 | [src/features.js](https://github.com/MoOx/postcss-cssnext/blob/master/src/features.js).
36 |
37 | ```js
38 | //eg: disable custom properties support
39 |
40 | var postcss = require("postcss");
41 | var cssnext = require("postcss-cssnext");
42 |
43 | postcss([
44 | cssnext({
45 | features: {
46 | customProperties: false
47 | }
48 | })
49 | ]);
50 | ```
51 |
52 | Each feature is based on PostCSS plugins & can get its own options. To pass
53 | options to a feature, you can just pass an object to the feature:
54 |
55 | ```js
56 | //eg: pass variables
57 |
58 | var postcss = require("postcss");
59 | var cssnext = require("postcss-cssnext");
60 |
61 | postcss([
62 | cssnext({
63 | features: {
64 | customProperties: {
65 | variables: {
66 | mainColor: "red",
67 | altColor: "blue"
68 | }
69 | }
70 | }
71 | })
72 | ]);
73 | ```
74 |
75 | ## `warnForDuplicates`
76 |
77 | _(default: true)_
78 |
79 | This option should be left with its default value, unless you really know what
80 | you are doing.
81 | **Most tutorial on the internet are wrong (probably 99%) and show provide duplicates
82 | in their examples. (eg: autoprefixer + cssnext - but cssnext already includes autoprefixer).**
83 | _In order to fix this, here is a warning. You are welcome._
84 |
85 | ## `warnForDeprecations`
86 |
87 | _(default: true)_
88 |
89 | This option should be left with its default value, unless you are aware of the
90 | risk and plan to handle the situation.
91 |
92 | ---
93 |
94 | **To know all available options, please check corresponding postcss plugin by
95 | browsing the
96 | [feature mapping](https://github.com/MoOx/postcss-cssnext/blob/master/src/features.js)**
97 |
98 | _Note: order is important to get everything working correctly._
99 |
--------------------------------------------------------------------------------
/docs/scripts/build.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/max-dependencies */
2 | import path from "path";
3 |
4 | import { sync as rm } from "rimraf";
5 | import color from "chalk";
6 |
7 | import Metalsmith from "metalsmith";
8 | import markdown from "metalsmith-md";
9 | import addFilenames from "metalsmith-filenames";
10 | import url from "metalsmith-url";
11 | import rename from "metalsmith-rename";
12 | // import collections from "metalsmith-collections"
13 | // import rss from "metalsmith-rss"
14 | import react from "metalsmith-react";
15 | import nanoLogger from "nano-logger";
16 | import markdownIt from "markdown-it";
17 | import watch from "metalsmith-watch";
18 |
19 | import markdownOptions from "./markdown";
20 | import markdownItTocAndAnchor from "markdown-it-toc-and-anchor";
21 |
22 | import pkg from "../../package";
23 | import buildConfig from "../../build.config";
24 | import webpackConfig from "../../webpack.config";
25 | import webpack from "./webpack";
26 | import devServer from "./webpack-dev-server";
27 |
28 | const log = nanoLogger("./build");
29 |
30 | JSON.stringify(buildConfig, null, 2)
31 | .split("\n")
32 | .forEach(l => log(l));
33 |
34 | const mdToHtmlReplacement = [/\.md$/, ".html"];
35 |
36 | // We clean ./dist by hand mainly for prod, in order to be able to build
37 | // assets with webpack before metalsmith build.
38 | // This allows us to get hashes in filename and pass them to the build
39 | rm(path.join(__dirname, "..", "dist"));
40 |
41 | const smith = new Metalsmith(path.join(__dirname, ".."));
42 | smith
43 | .source("content")
44 | .destination("dist")
45 | // clean is made before
46 | .clean(false)
47 |
48 | // convert markdown
49 | .use(
50 | markdown({
51 | markdownIt: markdownIt(markdownOptions).use(markdownItTocAndAnchor, {
52 | tocFirstLevel: 2
53 | })
54 | })
55 | )
56 |
57 | // useful for some homemade plugins
58 | .use(addFilenames())
59 |
60 | // add url meta data with some replacements
61 | .use(url([mdToHtmlReplacement, [/index\.html?$/, ""]]))
62 | // wrap .html into react `template:`
63 | .use(
64 | react({
65 | pattern: ["**/*.md", "**/*.html"],
66 | templatesPath: "src/layouts",
67 | defaultTemplate: "Default",
68 | before: "",
69 | data: {
70 | pkg,
71 | metadata: smith.metadata()
72 | }
73 | })
74 | )
75 |
76 | .use(
77 | rename([
78 | mdToHtmlReplacement,
79 | // no .html at the end of urls
80 | [/\.html$/, "/index.html"],
81 | // ensure we only have index.html, no index/index
82 | [/index\/index\.html$/, "index.html"]
83 | ])
84 | );
85 |
86 | const webpackComputedConfig = {
87 | ...webpackConfig,
88 | entry: {
89 | index: ["./docs/src/index"],
90 | playground: ["./docs/src/modules/playground/index"]
91 | },
92 |
93 | output: {
94 | path: path.join(__dirname, "..", "dist"),
95 | filename: "[name].js",
96 | publicPath: "/"
97 | }
98 | };
99 |
100 | // for development, we build metalsmith first, then we serve via
101 | // webpack-dev-server which build assets too (no hashes involved)
102 | if (buildConfig.__DEV_SERVER__) {
103 | smith.metadata().assets = {
104 | version: String(new Date().getTime()),
105 | scripts: [
106 | "/index.js",
107 | `http://${buildConfig.__SERVER_HOSTNAME__}:${
108 | buildConfig.__LR_SERVER_PORT__
109 | }/livereload.js`
110 | ]
111 | // css is handled by the js via webpack style-loader
112 | };
113 | smith
114 | .use(
115 | watch({
116 | log: nanoLogger("watcher"),
117 | livereload: buildConfig.__LR_SERVER_PORT__,
118 | paths: {
119 | "${source}/**/*": true,
120 | "src/layouts/**/*": "**/*.md",
121 | "src/modules/**/*": "**/*.md"
122 | }
123 | })
124 | )
125 | .build(err => {
126 | if (err) {
127 | throw err;
128 | }
129 |
130 | devServer(webpackComputedConfig, {
131 | protocol: buildConfig.__SERVER_PROTOCOL__,
132 | host: buildConfig.__SERVER_HOSTNAME__,
133 | port: buildConfig.__SERVER_PORT__,
134 | open: process.argv.includes("--open")
135 | });
136 | });
137 | } else {
138 | // for production we build assets first to be able to pass some assets hashes
139 | // to metalsmith
140 | webpack(webpackComputedConfig, log, stats => {
141 | log(color.green("✓ Assets build completed"));
142 |
143 | smith.metadata().assets = {
144 | version: stats.hash,
145 | scripts: ["/index.js"],
146 | ...(buildConfig.__PROD__
147 | ? {
148 | stylesheets: ["/index.css"]
149 | }
150 | : {})
151 | };
152 |
153 | smith.build(buildErr => {
154 | if (buildErr) {
155 | throw buildErr;
156 | }
157 |
158 | log(color.green("✓ Static build completed"));
159 | });
160 | });
161 | }
162 |
--------------------------------------------------------------------------------
/docs/scripts/deploy-to-gh-pages.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o errexit #abort if any command fails
4 |
5 | # https://github.com/X1011/git-directory-deploy/pull/10
6 | deploy_directory=${GIT_DEPLOY_DIR:-dist}
7 | deploy_branch=${GIT_DEPLOY_BRANCH:-gh-pages}
8 |
9 | #if no user identity is already set in the current git environment, use this:
10 | default_username=${GIT_DEPLOY_USERNAME:-deploy.sh}
11 | default_email=${GIT_DEPLOY_EMAIL:-}
12 |
13 | #repository to deploy to. must be readable and writable.
14 | repo=${GIT_DEPLOY_REPO:-origin}
15 |
16 | # Parse arg flags
17 | while : ; do
18 | if [[ $1 = "-v" || $1 = "--verbose" ]]; then
19 | verbose=true
20 | shift
21 | elif [[ $1 = "-s" || $1 = "--setup" ]]; then
22 | setup=true
23 | shift
24 | elif [[ $1 = "-e" || $1 = "--allow-empty" ]]; then
25 | allow_empty=true
26 | shift
27 | else
28 | break
29 | fi
30 | done
31 |
32 | #echo expanded commands as they are executed (for debugging)
33 | function enable_expanded_output {
34 | if [ $verbose ]; then
35 | set -o xtrace
36 | set +o verbose
37 | fi
38 | }
39 |
40 | #this is used to avoid outputting the repo URL, which may contain a secret token
41 | function disable_expanded_output {
42 | if [ $verbose ]; then
43 | set +o xtrace
44 | set -o verbose
45 | fi
46 | }
47 |
48 | enable_expanded_output
49 |
50 | function set_user_id {
51 | if [[ -z `git config user.name` ]]; then
52 | git config user.name "$default_username"
53 | fi
54 | if [[ -z `git config user.email` ]]; then
55 | git config user.email "$default_email"
56 | fi
57 | }
58 |
59 | function restore_head {
60 | if [[ $previous_branch = "HEAD" ]]; then
61 | #we weren't on any branch before, so just set HEAD back to the commit it was on
62 | git update-ref --no-deref HEAD $commit_hash $deploy_branch
63 | else
64 | git symbolic-ref HEAD refs/heads/$previous_branch
65 | fi
66 |
67 | git reset --mixed
68 | }
69 |
70 | if ! git diff --exit-code --quiet --cached; then
71 | echo Aborting due to uncommitted changes in the index >&2
72 | exit 1
73 | fi
74 |
75 | commit_title=`git log -n 1 --format="%s" HEAD`
76 | commit_hash=`git log -n 1 --format="%H" HEAD`
77 | previous_branch=`git rev-parse --abbrev-ref HEAD`
78 |
79 | if [ $setup ]; then
80 | mkdir -p "$deploy_directory"
81 | git --work-tree "$deploy_directory" checkout --orphan $deploy_branch
82 | git --work-tree "$deploy_directory" rm -r "*"
83 | git --work-tree "$deploy_directory" add --all
84 | git --work-tree "$deploy_directory" commit -m "initial publish"$'\n\n'"generated from commit $commit_hash"
85 | git push $repo $deploy_branch
86 | restore_head
87 | exit
88 | fi
89 |
90 | if [ ! -d "$deploy_directory" ]; then
91 | echo "Deploy directory '$deploy_directory' does not exist. Aborting." >&2
92 | exit 1
93 | fi
94 |
95 | if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then
96 | echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the -e flag." >&2
97 | exit 1
98 | fi
99 |
100 | disable_expanded_output
101 | git fetch --force $repo $deploy_branch:$deploy_branch
102 | enable_expanded_output
103 |
104 | #make deploy_branch the current branch
105 | git symbolic-ref HEAD refs/heads/$deploy_branch
106 |
107 | #put the previously committed contents of deploy_branch branch into the index
108 | git --work-tree "$deploy_directory" reset --mixed --quiet
109 |
110 | git --work-tree "$deploy_directory" add --all
111 |
112 | set +o errexit
113 | diff=$(git --work-tree "$deploy_directory" diff --exit-code --quiet HEAD)$?
114 | set -o errexit
115 | case $diff in
116 | 0) echo No changes to files in $deploy_directory. Skipping commit.;;
117 | 1)
118 | set_user_id
119 | git --work-tree "$deploy_directory" commit -m \
120 | "publish: $commit_title"$'\n\n'"generated from commit $commit_hash"
121 |
122 | disable_expanded_output
123 | #--quiet is important here to avoid outputting the repo URL, which may contain a secret token
124 | git push --quiet $repo $deploy_branch
125 | enable_expanded_output
126 | ;;
127 | *)
128 | echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to master, use: git symbolic-ref HEAD refs/heads/master && git reset --mixed >&2
129 | exit $diff
130 | ;;
131 | esac
132 |
133 | restore_head
134 |
--------------------------------------------------------------------------------
/docs/scripts/markdown.js:
--------------------------------------------------------------------------------
1 | import hljs from "highlight.js";
2 |
3 | export default {
4 | html: true,
5 | linkify: true,
6 | typographer: true,
7 | highlight: (code, lang) => {
8 | code = code.trim();
9 | // language is recognized by highlight.js
10 | if (lang && hljs.getLanguage(lang)) {
11 | return hljs.highlight(lang, code).value;
12 | }
13 | // fallback to auto
14 | return hljs.highlightAuto(code).value;
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/docs/scripts/webpack-dev-server.js:
--------------------------------------------------------------------------------
1 | import webpack from "webpack";
2 | import webpackNanoLogs from "webpack-nano-logs";
3 | import WebpackDevServer from "webpack-dev-server";
4 | import opn from "opn";
5 | import logger from "nano-logger";
6 |
7 | const log = logger("webpack-dev-server");
8 |
9 | export default (config, options) => {
10 | options = {
11 | protocol: "http://",
12 | host: "0.0.0.0",
13 | port: 3000,
14 | open: true,
15 | noDevEntriesTest: /^tests/,
16 | ...(options || {})
17 | };
18 |
19 | const serverUrl = `${options.protocol}${options.host}:${options.port}`;
20 |
21 | const devEntries = [
22 | `webpack-dev-server/client?${serverUrl}`,
23 | "webpack/hot/only-dev-server"
24 | ];
25 |
26 | const devConfig = {
27 | ...config,
28 | entry: {
29 | // add devEntries
30 | ...Object.keys(config.entry).reduce((acc, key) => {
31 | // some entries do not need extra stuff
32 | acc[key] =
33 | key.match(options.noDevEntriesTest) !== null
34 | ? config.entry[key]
35 | : [...devEntries, ...config.entry[key]];
36 | return acc;
37 | }, {})
38 | },
39 | plugins: [
40 | ...(config.plugins || []),
41 | ...(options.plugins || []),
42 | new webpack.HotModuleReplacementPlugin(),
43 | webpackNanoLogs
44 | ]
45 | };
46 |
47 | return new WebpackDevServer(webpack(devConfig), {
48 | https: options.protocol === "https://",
49 | contentBase: config.output.path,
50 | hot: true,
51 | stats: {
52 | colors: true,
53 | // hide all chunk dependencies because it's unreadable
54 | chunkModules: false,
55 | // noize
56 | assets: false
57 | },
58 | noInfo: true
59 | }).listen(options.port, options.host, () => {
60 | log(`Dev server started on ${serverUrl}`);
61 | if (options.open) {
62 | opn(`${serverUrl}`);
63 | }
64 | });
65 | };
66 |
--------------------------------------------------------------------------------
/docs/scripts/webpack.js:
--------------------------------------------------------------------------------
1 | import webpack from "webpack";
2 | import color from "chalk";
3 |
4 | export default (webpackConfig, log, cb) => {
5 | webpack(webpackConfig, (err, stats) => {
6 | if (err) {
7 | throw err;
8 | }
9 |
10 | if (stats.hasErrors()) {
11 | stats.compilation.errors.forEach(item =>
12 | log(...[color.red("Error:"), ...item.message.split("\n")])
13 | );
14 | throw new Error("webpack build failed with errors");
15 | }
16 | if (stats.hasWarnings()) {
17 | stats.compilation.warnings.forEach(item =>
18 | log(...[color.yellow("Warning:"), ...item.message.split("\n")])
19 | );
20 | }
21 |
22 | cb(stats);
23 | });
24 | };
25 |
--------------------------------------------------------------------------------
/docs/src/assets/cssnext.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/docs/src/assets/delorean-back.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoOx/postcss-cssnext/dd4df46728f806e3301d5427950afa3e7a80cc26/docs/src/assets/delorean-back.jpg
--------------------------------------------------------------------------------
/docs/src/assets/delorean-front.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoOx/postcss-cssnext/dd4df46728f806e3301d5427950afa3e7a80cc26/docs/src/assets/delorean-front.jpg
--------------------------------------------------------------------------------
/docs/src/assets/engine.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoOx/postcss-cssnext/dd4df46728f806e3301d5427950afa3e7a80cc26/docs/src/assets/engine.jpg
--------------------------------------------------------------------------------
/docs/src/assets/fast.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoOx/postcss-cssnext/dd4df46728f806e3301d5427950afa3e7a80cc26/docs/src/assets/fast.jpg
--------------------------------------------------------------------------------
/docs/src/assets/github.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/docs/src/assets/road.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoOx/postcss-cssnext/dd4df46728f806e3301d5427950afa3e7a80cc26/docs/src/assets/road.jpg
--------------------------------------------------------------------------------
/docs/src/assets/team.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoOx/postcss-cssnext/dd4df46728f806e3301d5427950afa3e7a80cc26/docs/src/assets/team.jpg
--------------------------------------------------------------------------------
/docs/src/assets/twitter.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/src/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoOx/postcss-cssnext/dd4df46728f806e3301d5427950afa3e7a80cc26/docs/src/favicon.png
--------------------------------------------------------------------------------
/docs/src/index.js:
--------------------------------------------------------------------------------
1 | import "./favicon.png";
2 | import "./index.css";
3 |
4 | // import "./modules/polyfills"
5 |
6 | // move the toc in a grid cell
7 | import "./modules/move-toc";
8 | // sort of sticky header
9 | import "./modules/headroom";
10 |
--------------------------------------------------------------------------------
/docs/src/layouts/Default.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 | import cx from "classnames";
4 |
5 | import dashify from "../modules/dashify";
6 |
7 | import Html from "../modules/Html";
8 | import Head from "../modules/Head";
9 | import Body from "../modules/Body";
10 |
11 | class Default extends Component {
12 | getChildContext() {
13 | return {
14 | pkg: this.props.pkg,
15 | // collections: this.props.collections,
16 | file: this.props.file
17 | };
18 | }
19 |
20 | render() {
21 | const { file } = this.props;
22 | const footer = file.footer === undefined ? true : file.footer;
23 |
24 | if (!file.title) {
25 | console.log(`${file.filename} doesn't have a title`);
26 | }
27 | return (
28 |
29 |
41 |
72 |
73 | {file.incomplete && (
74 |
75 |
76 |
{"Incomplete"}
77 |
78 | {"This documentation is still a work in progress. "}
79 |
80 |
86 | {"Pull requests"}
87 |
88 | {" expanding on existing or adding additional content " +
89 | " are "}
90 | {"extremely"}
91 | {" appreciated."}
92 |
93 |
94 |
95 | )}
96 |
97 |
113 |
114 | {footer && (
115 |
129 | )}
130 |
131 |
132 | );
133 | }
134 | }
135 |
136 | Default.propTypes = {
137 | pkg: PropTypes.object.isRequired,
138 | metadata: PropTypes.object.isRequired,
139 | // collections: PropTypes.object.isRequired,
140 | file: PropTypes.object.isRequired
141 | };
142 |
143 | Default.childContextTypes = {
144 | pkg: PropTypes.object.isRequired,
145 | // collections: PropTypes.object.isRequired,
146 | file: PropTypes.object.isRequired
147 | };
148 |
149 | export default Default;
150 |
--------------------------------------------------------------------------------
/docs/src/layouts/Simple.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import Html from "../modules/Html";
5 | import Head from "../modules/Head";
6 | import Body from "../modules/Body";
7 |
8 | class Simple extends Component {
9 | getChildContext() {
10 | return {
11 | pkg: this.props.pkg,
12 | // collections: this.props.collections,
13 | file: this.props.file
14 | };
15 | }
16 |
17 | render() {
18 | const { file } = this.props;
19 | const footer = file.footer === undefined ? true : file.footer;
20 |
21 | if (!file.title) {
22 | console.log(`${file.filename} doesn't have a title`);
23 | }
24 | return (
25 |
26 |
38 |
42 |
43 |
44 | );
45 | }
46 | }
47 |
48 | Simple.propTypes = {
49 | pkg: PropTypes.object.isRequired,
50 | metadata: PropTypes.object.isRequired,
51 | // collections: PropTypes.object.isRequired,
52 | file: PropTypes.object.isRequired
53 | };
54 |
55 | Simple.childContextTypes = {
56 | pkg: PropTypes.object.isRequired,
57 | // collections: PropTypes.object.isRequired,
58 | file: PropTypes.object.isRequired
59 | };
60 |
61 | export default Simple;
62 |
--------------------------------------------------------------------------------
/docs/src/modules/Analytics/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 |
3 | import isogram from "isogram";
4 |
5 | export default class Analytics extends Component {
6 | render() {
7 | return (
8 |
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/docs/src/modules/Body/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import Header from "../Header";
5 | import Footer from "../Footer";
6 | import Analytics from "../Analytics";
7 |
8 | class Body extends Component {
9 | render() {
10 | const { version, scripts, footer } = this.props;
11 |
12 | return (
13 |
14 |
15 |
16 | {this.props.children}
17 |
18 |
19 | {scripts.map(script => (
20 |
21 | ))}
22 |
23 |
24 |
25 | );
26 | }
27 | }
28 |
29 | Body.propTypes = {
30 | children: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired,
31 | scripts: PropTypes.array,
32 | version: PropTypes.string,
33 | footer: PropTypes.bool
34 | };
35 |
36 | Body.contextTypes = {
37 | pkg: PropTypes.object.isRequired,
38 | file: PropTypes.object.isRequired
39 | };
40 |
41 | Body.defaultProps = {
42 | scripts: [],
43 | footer: true
44 | };
45 |
46 | export default Body;
47 |
--------------------------------------------------------------------------------
/docs/src/modules/Footer/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import SVGIcon from "react-svg-inline";
5 | import requireRaw from "../requireRaw";
6 |
7 | class Footer extends Component {
8 | render() {
9 | return (
10 |
48 | );
49 | }
50 | }
51 |
52 | Footer.contextTypes = {
53 | file: PropTypes.object.isRequired
54 | };
55 |
56 | export default Footer;
57 |
--------------------------------------------------------------------------------
/docs/src/modules/Head/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 |
4 | class Head extends Component {
5 | render() {
6 | return (
7 |
8 |
9 |
10 |
11 |
12 | {this.props.title}
13 | {this.props.stylesheets.map(stylesheet => (
14 |
15 | ))}
16 |
22 | {this.props.children}
23 |
24 | );
25 | }
26 | }
27 |
28 | Head.propTypes = {
29 | title: PropTypes.string.isRequired,
30 | children: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
31 | stylesheets: PropTypes.array
32 | };
33 |
34 | Head.defaultProps = {
35 | stylesheets: []
36 | };
37 |
38 | export default Head;
39 |
--------------------------------------------------------------------------------
/docs/src/modules/Header/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import SVGIcon from "react-svg-inline";
5 | import requireRaw from "../requireRaw";
6 |
7 | import Link from "./link";
8 |
9 | class Header extends Component {
10 | render() {
11 | return (
12 |
13 |
19 |
20 |
38 |
39 |
40 |
41 | {"Support"}
42 |
43 |
47 | {"GitHub"}
48 |
49 |
50 | {"Twitter"}
51 |
52 |
53 |
54 |
55 |
56 | );
57 | }
58 | }
59 |
60 | Header.contextTypes = {
61 | pkg: PropTypes.object.isRequired,
62 | file: PropTypes.object.isRequired
63 | };
64 |
65 | export default Header;
66 |
--------------------------------------------------------------------------------
/docs/src/modules/Header/link.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 | import cx from "classnames";
4 |
5 | class HeaderLink extends Component {
6 | render() {
7 | const currentUrl = "/" + this.context.file.url;
8 |
9 | return (
10 |
18 | {this.props.children}
19 |
20 | );
21 | }
22 | }
23 |
24 | HeaderLink.propTypes = {
25 | href: PropTypes.string.isRequired,
26 | className: PropTypes.oneOfType([
27 | PropTypes.string,
28 | PropTypes.object,
29 | PropTypes.array
30 | ]),
31 | children: PropTypes.oneOfType([
32 | PropTypes.string,
33 | PropTypes.array,
34 | PropTypes.object
35 | ]).isRequired
36 | };
37 |
38 | HeaderLink.contextTypes = {
39 | file: PropTypes.object.isRequired
40 | };
41 |
42 | export default HeaderLink;
43 |
--------------------------------------------------------------------------------
/docs/src/modules/Html/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import PropTypes from "prop-types";
3 |
4 | class Html extends Component {
5 | render() {
6 | return (
7 |
8 | {this.props.children}
9 |
10 | );
11 | }
12 | }
13 |
14 | Html.propTypes = {
15 | children: PropTypes.array.isRequired
16 | };
17 |
18 | export default Html;
19 |
--------------------------------------------------------------------------------
/docs/src/modules/dashify.js:
--------------------------------------------------------------------------------
1 | export default function dashify(str) {
2 | return (
3 | str
4 | .toLowerCase()
5 | // dashify
6 | .replace(/\W+/g, "-")
7 | // trim dash
8 | .replace(/^-+/, "")
9 | .replace(/-+$/, "")
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/docs/src/modules/formatDate.js:
--------------------------------------------------------------------------------
1 | const monthNames = [
2 | "jan.",
3 | "fév.",
4 | "mars",
5 | "avril",
6 | "mai",
7 | "juin",
8 | "juil.",
9 | "août",
10 | "sept.",
11 | "oct.",
12 | "nov.",
13 | "déc."
14 | ];
15 |
16 | export default function formatDate(date) {
17 | date = new Date(date);
18 |
19 | return [date.getDate(), monthNames[date.getMonth()], date.getFullYear()].join(
20 | " "
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/docs/src/modules/headroom.js:
--------------------------------------------------------------------------------
1 | import onAnimationFrame from "./onAnimationFrame";
2 |
3 | const headroom = document.querySelector(".js-Headroom");
4 | if (headroom) {
5 | const step = headroom.getBoundingClientRect().height;
6 |
7 | const getScrollTop = () =>
8 | window.pageYOffset || document.documentElement.scrollTop;
9 |
10 | let previousScroll = getScrollTop();
11 |
12 | const update = () => {
13 | const scroll = getScrollTop();
14 |
15 | // ignore scroll out of the page (hi Safari!)
16 | if (scroll < 0) {
17 | return true;
18 | }
19 |
20 | if (scroll > previousScroll + step) {
21 | headroom.classList.add("js-Headroom--hide");
22 | previousScroll = scroll;
23 | } else if (scroll < previousScroll - step) {
24 | headroom.classList.remove("js-Headroom--hide");
25 | previousScroll = scroll;
26 | }
27 | return true;
28 | };
29 |
30 | // order is kind of important
31 | // scroll, hashchange & onload
32 |
33 | window.addEventListener("scroll", () => onAnimationFrame(update), false);
34 |
35 | // force hide when url hash is updated
36 | window.addEventListener(
37 | "hashchange",
38 | () => {
39 | // hashchange can be triggered just after or BEFORE scroll event
40 | // ... so poor hack
41 | setTimeout(
42 | () =>
43 | onAnimationFrame(() => {
44 | headroom.classList.add("js-Headroom--hide");
45 | return true;
46 | }),
47 | 10
48 | );
49 | },
50 | false
51 | );
52 |
53 | // hide onload if there is a hash (not the top of the page)
54 | // since page loaded with hash can trigger scroll event...
55 | // again... poor hack
56 | setTimeout(
57 | () =>
58 | onAnimationFrame(() => {
59 | if (window.location.hash) {
60 | // check that the browser is really near the anchor
61 | // you can scroll up/down & refresh, your browser might keep the scroll
62 | // so you are not really at the exact place of the anchor
63 | // and you might be at the top of the page
64 | // AND WE DONT WANT TO HIDE THE HEADER IN THIS CASE
65 | const hashElement = document.getElementById(
66 | window.location.hash.slice(1)
67 | );
68 | if (
69 | hashElement.getBoundingClientRect().top < step &&
70 | hashElement.getBoundingClientRect().top > -step
71 | ) {
72 | headroom.classList.add("js-Headroom--hide");
73 | }
74 | }
75 | return true;
76 | }),
77 | 10
78 | );
79 | }
80 |
--------------------------------------------------------------------------------
/docs/src/modules/move-toc.js:
--------------------------------------------------------------------------------
1 | const toc = document.querySelector(".markdownIt-TOC");
2 | const tocOriginalContainer = document.querySelector(
3 | ".js-markdownIt-TOCOriginalContainer"
4 | );
5 | const tocPlaceholder = document.querySelector(".js-markdownIt-TOCPlaceholder");
6 | if (toc && tocOriginalContainer && tocPlaceholder) {
7 | tocOriginalContainer.classList.add("r-minM--4of5");
8 | tocPlaceholder.classList.add("r-minM--1of5");
9 | tocPlaceholder.appendChild(toc);
10 | } else {
11 | console.info("No TOC to move");
12 | }
13 |
--------------------------------------------------------------------------------
/docs/src/modules/onAnimationFrame.js:
--------------------------------------------------------------------------------
1 | const updateRequestedMap = {};
2 | const updateRequestedList = [];
3 |
4 | function update(cb) {
5 | // index should be defined from the requestUpdate()
6 | updateRequestedMap[updateRequestedList.indexOf(cb)] = !cb();
7 | }
8 |
9 | export default function requestUpdate(cb) {
10 | let index = updateRequestedList.indexOf(cb);
11 | if (index === -1) {
12 | updateRequestedList.push(cb);
13 | index = updateRequestedList.indexOf(cb); // === length - 1, I know...
14 | }
15 |
16 | if (!updateRequestedMap[index]) {
17 | updateRequestedMap[index] = true;
18 | requestAnimationFrame(() => update(cb));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/docs/src/modules/playground/index.js:
--------------------------------------------------------------------------------
1 | import stripColor from "strip-ansi";
2 |
3 | import cssnext from "../../../../src/index";
4 | import { version as cssnextVersion } from "../../../../package";
5 | import messagesStyles from "./messages.styles";
6 |
7 | const bullet = "›";
8 |
9 | function playground(opts) {
10 | opts.options = opts.options || {};
11 |
12 | if (!opts.from || !opts.to || !opts.console) {
13 | throw new Error(
14 | "cssnextPlayground needs at least `from`, `to` & `console` parameters"
15 | );
16 | }
17 |
18 | const transformer = cssnext(opts.options);
19 |
20 | function transformCSS() {
21 | const css = opts.from.value;
22 |
23 | opts.console.innerHTML = "";
24 | opts.messages.textContent = "";
25 |
26 | try {
27 | const result = transformer.process(css);
28 | opts.to.value = result.css.trim();
29 | const messages = result.warnings();
30 | if (messages.length) {
31 | opts.messages.textContent = `${bullet} ${stripColor(
32 | messages.map(message => message.toString())
33 | ).join("\n\n\n" + bullet + " ")}`;
34 | }
35 | } catch (e) {
36 | console.error(e);
37 | opts.to.value = "";
38 | opts.console.innerHTML =
39 | '";
46 | // use createTextNode to escape html entities
47 | opts.console.insertBefore(
48 | document.createTextNode(e.toString()),
49 | opts.console.firstChild
50 | );
51 | }
52 | }
53 |
54 | opts.from.addEventListener("change", transformCSS);
55 | opts.from.addEventListener("keyup", transformCSS);
56 |
57 | transformCSS();
58 | }
59 |
60 | Array.prototype.slice
61 | .call(document.querySelectorAll(".js-cssnext-Playground"))
62 | .forEach(function(elPlayground) {
63 | playground({
64 | from: elPlayground.querySelector(".js-cssnext-Playground-from"),
65 | to: elPlayground.querySelector(".js-cssnext-Playground-to"),
66 | console: elPlayground.querySelector(".js-cssnext-Playground-console"),
67 | messages: elPlayground.querySelector(".js-cssnext-Playground-messages"),
68 | options: {
69 | messages: false
70 | }
71 | });
72 | });
73 |
74 | const messagesStylesElement = document.createElement("style");
75 | const adjustedMessagesStyles = {
76 | ...messagesStyles,
77 | position: undefined,
78 | "border-top": messagesStyles["border-bottom"],
79 | "border-bottom": undefined,
80 | "box-shadow": undefined
81 | };
82 | messagesStylesElement.innerHTML = `.cssnext-Playground-messages {
83 | ${Object.keys(adjustedMessagesStyles)
84 | .map(
85 | prop =>
86 | adjustedMessagesStyles[prop] !== undefined
87 | ? prop + ": " + adjustedMessagesStyles[prop]
88 | : null
89 | )
90 | .filter(couple => couple !== null)
91 | .join(";\n ")}
92 | }
93 |
94 | .cssnext-Playground-messages:empty { display: none }`;
95 | document.body.appendChild(messagesStylesElement);
96 |
--------------------------------------------------------------------------------
/docs/src/modules/playground/messages.styles.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable max-len */
2 | // source: http://iconmonstr.com/warning-3-icon/
3 | const svgGradient = `
4 |
5 |
6 |
7 |
8 | `;
9 | const warningSVG = `
10 |
12 | ${svgGradient}
13 |
17 |
18 | `.trim();
19 | /* eslint-enable max-len */
20 |
21 | export default {
22 | display: "block",
23 | "white-space": "pre-wrap",
24 |
25 | // not a problem for old browsers, box will still be on top of body
26 | position: "fixed",
27 | top: 0,
28 | left: 0,
29 | right: 0,
30 | "z-index": 10000, // just in case you know
31 |
32 | "font-size": ".9em",
33 | padding: "1.5em 1em 1.5em 4.5em", // padding + background image padding
34 |
35 | color: "#318edf",
36 | "background-color": "#fff",
37 |
38 | background: `url(
39 | "data:image/svg+xml;charset=utf-8,${encodeURIComponent(warningSVG)}"
40 | ) 1em 1em / 2.5em 2.5em no-repeat, #fff`,
41 |
42 | // sugar
43 | "border-bottom": "4px solid #318edf",
44 | "box-shadow": "0 0 .6em rgba(0,0,0, .25)",
45 |
46 | // nice font
47 | "font-family": "Menlo, Monaco, monospace"
48 | };
49 |
--------------------------------------------------------------------------------
/docs/src/modules/requireRaw.js:
--------------------------------------------------------------------------------
1 | const BAD_ENV = "Cannot require raw file from the current environnement";
2 |
3 | const fs = require ? require("fs") : null;
4 | const path = require ? require("path") : null;
5 |
6 | /* eslint-disable import/no-mutable-exports */
7 | let requireRaw = () => {
8 | return BAD_ENV;
9 | };
10 |
11 | if (fs && fs.readFileSync) {
12 | requireRaw = filename => {
13 | return fs.readFileSync(path.join(__dirname, "..", "..", filename), {
14 | encoding: "utf8"
15 | });
16 | };
17 | }
18 |
19 | export default requireRaw;
20 |
--------------------------------------------------------------------------------
/logo/cssnext-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoOx/postcss-cssnext/dd4df46728f806e3301d5427950afa3e7a80cc26/logo/cssnext-256.png
--------------------------------------------------------------------------------
/logo/cssnext-favicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/logo/cssnext-icon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoOx/postcss-cssnext/dd4df46728f806e3301d5427950afa3e7a80cc26/logo/cssnext-icon-256.png
--------------------------------------------------------------------------------
/logo/cssnext-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/logo/cssnext-text.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/logo/cssnext.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "postcss-cssnext",
3 | "version": "3.1.0",
4 | "description": "Use tomorrow’s CSS syntax, today",
5 | "keywords": ["postcss", "postcss-plugin", "css", "w3c", "cssnext"],
6 | "author": "Maxime Thirouin",
7 | "license": "MIT",
8 | "repository": "https://github.com/MoOx/postcss-cssnext.git",
9 | "homepage": "http://cssnext.io/",
10 | "main": "lib/index.js",
11 | "files": ["docs/content", "lib", "src", "!**/__tests__"],
12 | "dependencies": {
13 | "autoprefixer": "^7.1.1",
14 | "caniuse-api": "^2.0.0",
15 | "chalk": "^2.0.1",
16 | "pixrem": "^4.0.0",
17 | "pleeease-filters": "^4.0.0",
18 | "postcss": "^6.0.5",
19 | "postcss-apply": "^0.8.0",
20 | "postcss-attribute-case-insensitive": "^2.0.0",
21 | "postcss-calc": "^6.0.0",
22 | "postcss-color-function": "^4.0.0",
23 | "postcss-color-gray": "^4.0.0",
24 | "postcss-color-hex-alpha": "^3.0.0",
25 | "postcss-color-hsl": "^2.0.0",
26 | "postcss-color-hwb": "^3.0.0",
27 | "postcss-color-rebeccapurple": "^3.0.0",
28 | "postcss-color-rgb": "^2.0.0",
29 | "postcss-color-rgba-fallback": "^3.0.0",
30 | "postcss-custom-media": "^6.0.0",
31 | "postcss-custom-properties": "^6.1.0",
32 | "postcss-custom-selectors": "^4.0.1",
33 | "postcss-font-family-system-ui": "^3.0.0",
34 | "postcss-font-variant": "^3.0.0",
35 | "postcss-image-set-polyfill": "^0.3.5",
36 | "postcss-initial": "^2.0.0",
37 | "postcss-media-minmax": "^3.0.0",
38 | "postcss-nesting": "^4.0.1",
39 | "postcss-pseudo-class-any-link": "^4.0.0",
40 | "postcss-pseudoelements": "^5.0.0",
41 | "postcss-replace-overflow-wrap": "^2.0.0",
42 | "postcss-selector-matches": "^3.0.1",
43 | "postcss-selector-not": "^3.0.1"
44 | },
45 | "peerDependencies": {
46 | "caniuse-lite": "^1.0.30000697"
47 | },
48 | "devDependencies": {
49 | "babel-cli": "^6.6.5",
50 | "babel-core": "^6.7.2",
51 | "babel-eslint": "^8.2.1",
52 | "babel-loader": "^6.2.4",
53 | "babel-preset-env": "^1.0.0",
54 | "babel-preset-react": "^6.5.0",
55 | "babel-preset-stage-3": "^6.24.1",
56 | "babel-tape-runner": "^2.0.1",
57 | "classnames": "^2.1.1",
58 | "css-loader": "^0.28.9",
59 | "eslint": "^3.0.0",
60 | "eslint-config-i-am-meticulous": "^7.0.0",
61 | "eslint-plugin-react": "^7.5.1",
62 | "extract-text-webpack-plugin": "^3.0.2",
63 | "file-loader": "^1.1.6",
64 | "highlight.js": "^8.6.0",
65 | "husky": "^0.14.3",
66 | "isogram": "^0.5.0",
67 | "js-yaml": "^3.3.1",
68 | "markdown-it": "^4.2.1",
69 | "markdown-it-toc-and-anchor": "^1.0.1",
70 | "metalsmith": "^2.0.1",
71 | "metalsmith-collections": "^0.7.0",
72 | "metalsmith-filenames": "^1.0.0",
73 | "metalsmith-md": "^2.0.1",
74 | "metalsmith-react": "^2.0.1",
75 | "metalsmith-rename": "^1.0.0",
76 | "metalsmith-rss": "^1.0.0",
77 | "metalsmith-url": "^1.0.0",
78 | "metalsmith-watch": "^1.0.1",
79 | "nano-logger": "^1.0.0",
80 | "node-libs-browser": "^0.5.0",
81 | "npmpub": "^3.1.0",
82 | "object-assign": "^3.0.0",
83 | "opn": "^1.0.2",
84 | "prettier": "^1.10.2",
85 | "pretty-quick": "^1.2.2",
86 | "prop-types": "^15.5.10",
87 | "react": "^15.0.0",
88 | "react-dom": "^15.0.0",
89 | "react-svg-inline": "^1.0.1",
90 | "rimraf": "^2.4.3",
91 | "strip-ansi": "^4.0.0",
92 | "style-loader": "^0.19.1",
93 | "tape": "^4.2.0",
94 | "to-slug-case": "^0.1.2",
95 | "uglifyjs-webpack-plugin": "^1.1.6",
96 | "webpack": "^3.0.0",
97 | "webpack-dev-server": "^2.11.0",
98 | "webpack-nano-logs": "^1.0.0"
99 | },
100 | "scripts": {
101 | "precommit": "pretty-quick --staged",
102 | "format": "prettier --write \"**/*.{js,json,css,md}\"",
103 | "prebabelify": "rimraf lib",
104 | "babelify": "babel src --out-dir lib",
105 | "prepare": "npm run babelify",
106 | "#lint":
107 | "even if there is a .eslintignore symlink, we use an explicit command because windows don't like unix symlink",
108 | "lint": "eslint --ignore-path .gitignore .",
109 | "#tape":
110 | "to avoid really slow tests, we run babel once & run tests on the result",
111 | "tape": "tape \"lib/__tests__/*.js\"",
112 | "test": "npm run lint && npm run babelify && npm run tape",
113 | "docs-build": "babel-node docs/scripts/build",
114 | "predocs-start": "npm run prepare",
115 | "docs-start": "npm run docs-build -- --dev --dev-server --open",
116 | "docs-test": "npm run docs-build -- --production",
117 | "_docs-deploy":
118 | "GIT_DEPLOY_DIR=docs/dist ./docs/scripts/deploy-to-gh-pages.sh -v",
119 | "docs-deploy": "npm run docs-test && npm run _docs-deploy",
120 | "release": "npmpub",
121 | "postrelease": "npm run docs-deploy"
122 | },
123 | "babel": {
124 | "presets": [
125 | "babel-preset-react",
126 | [
127 | "babel-preset-env",
128 | {
129 | "targets": {
130 | "node": "4.0"
131 | }
132 | }
133 | ],
134 | "babel-preset-stage-3"
135 | ],
136 | "env": {
137 | "browsers": {
138 | "presets": [
139 | "babel-preset-react",
140 | [
141 | "babel-preset-env",
142 | {
143 | "targets": {
144 | "browsers": ["last 5 versions"]
145 | }
146 | }
147 | ],
148 | "babel-preset-stage-3"
149 | ]
150 | }
151 | }
152 | },
153 | "eslintConfig": {
154 | "extends": "eslint-config-i-am-meticulous/react",
155 | "rules": {
156 | "import/order": "off",
157 | "import/default": "off",
158 | "react/prefer-stateless-function": "off"
159 | }
160 | },
161 | "prettier": {
162 | "proseWrap": "always"
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/apply-rule.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --foo-set: {
3 | color: tomato;
4 | content: 'foo';
5 | };
6 | }
7 |
8 | .foo {
9 | @apply --foo-set;
10 | }
11 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/apply-rule.expected.css:
--------------------------------------------------------------------------------
1 | .foo {
2 | color: tomato;
3 | content: 'foo';
4 | }
5 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/attribute-case-insensitive.browsers:
--------------------------------------------------------------------------------
1 | Safari 8
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/attribute-case-insensitive.css:
--------------------------------------------------------------------------------
1 | [data-foo=test i] {
2 | display: block;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/attribute-case-insensitive.expected.css:
--------------------------------------------------------------------------------
1 | [data-foo=test],[data-foo=Test],[data-foo=tEst],[data-foo=TEst],[data-foo=teSt],[data-foo=TeSt],[data-foo=tESt],[data-foo=TESt],[data-foo=tesT],[data-foo=TesT],[data-foo=tEsT],[data-foo=TEsT],[data-foo=teST],[data-foo=TeST],[data-foo=tEST],[data-foo=TEST] {
2 | display: block;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/autoprefixer.browsers:
--------------------------------------------------------------------------------
1 | Safari 6
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/autoprefixer.css:
--------------------------------------------------------------------------------
1 | * {
2 | transition: transform 1s;
3 | }
4 |
5 | @keyframes spin {
6 | 0% { transform: rotate(0deg) }
7 | 100% { transform: rotate(360deg) }
8 | }
9 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/autoprefixer.expected.css:
--------------------------------------------------------------------------------
1 | * {
2 | -webkit-transition: -webkit-transform 1s;
3 | transition: -webkit-transform 1s;
4 | transition: transform 1s;
5 | transition: transform 1s, -webkit-transform 1s;
6 | }
7 |
8 | @-webkit-keyframes spin {
9 | 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg) }
10 | 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg) }
11 | }
12 |
13 | @keyframes spin {
14 | 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg) }
15 | 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg) }
16 | }
17 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/calc.css:
--------------------------------------------------------------------------------
1 | html {
2 | font-size: calc(1em * 2)
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/calc.expected.css:
--------------------------------------------------------------------------------
1 | html {
2 | font-size: 2em
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-function.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: color(rgb(102, 51, 153) a(90%))
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-function.expected.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: rgba(102, 51, 153, 0.9)
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-gray.css:
--------------------------------------------------------------------------------
1 | .bar {
2 | color: gray(255, 50%);
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-gray.expected.css:
--------------------------------------------------------------------------------
1 | .bar {
2 | color: rgba(255, 255, 255, 0.5);
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-hex-alpha.browsers:
--------------------------------------------------------------------------------
1 | Safari 9
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-hex-alpha.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: #9d9c
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-hex-alpha.expected.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: rgba(153, 221, 153, 0.8)
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-hsl.css:
--------------------------------------------------------------------------------
1 | .foo {
2 | color: hsl(.25turn 90% 70%);
3 | background-color: hsl(300grad 25% 15% / 70%);
4 | border: 1px solid hsl(0 5% 10% / .6);
5 | }
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-hsl.expected.css:
--------------------------------------------------------------------------------
1 | .foo {
2 | color: hsl(90, 90%, 70%);
3 | background-color: hsla(270, 25%, 15%, .7);
4 | border: 1px solid hsla(0, 5%, 10%, .6);
5 | }
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-hwb.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: hwb(0, 20%, 40%)
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-hwb.expected.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: rgb(153, 51, 51)
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-rebeccapurple.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: rebeccapurple
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-rebeccapurple.expected.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: #639
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-rgb.css:
--------------------------------------------------------------------------------
1 | .foo {
2 | color: rgb(255 200 205);
3 | background-color: rgb(100 222.2 100.9 / 30%);
4 | border: 1px solid rgb(0% 5% 10% / .7);
5 | }
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-rgb.expected.css:
--------------------------------------------------------------------------------
1 | .foo {
2 | color: rgb(255, 200, 205);
3 | background-color: rgba(100, 222, 101, .3);
4 | border: 1px solid rgba(0%, 5%, 10%, .7);
5 | }
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-rgba.browsers:
--------------------------------------------------------------------------------
1 | IE 8
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-rgba.css:
--------------------------------------------------------------------------------
1 | .foo {
2 | background: rgba(153, 221, 153, 0.8);
3 | border: solid 1px rgba(100,102,103,.3);
4 | }
5 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/color-rgba.expected.css:
--------------------------------------------------------------------------------
1 | .foo {
2 | background: #99dd99;
3 | background: rgba(153, 221, 153, 0.8);
4 | border: solid 1px #646667;
5 | border: solid 1px rgba(100,102,103,.3);
6 | }
7 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/custom-media.css:
--------------------------------------------------------------------------------
1 | @custom-media --small-viewport (max-width: 30em);
2 |
3 | @media (--small-viewport) {
4 | /* styles for small viewport */
5 | }
6 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/custom-media.expected.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | @media (max-width: 30em) {
4 | /* styles for small viewport */
5 | }
6 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/custom-properties.browsers:
--------------------------------------------------------------------------------
1 | Safari 9
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/custom-properties.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --color: #e00
3 | }
4 |
5 | body {
6 | color: var(--color)
7 | }
8 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/custom-properties.expected.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | body {
4 | color: #e00
5 | }
6 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/custom-selectors.css:
--------------------------------------------------------------------------------
1 | @custom-selector :--heading h1, h2, h3, h4, h5, h6;
2 |
3 | article :--heading + p{
4 | margin-top: 0;
5 | }
6 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/custom-selectors.expected.css:
--------------------------------------------------------------------------------
1 | article h1 + p,
2 | article h2 + p,
3 | article h3 + p,
4 | article h4 + p,
5 | article h5 + p,
6 | article h6 + p{
7 | margin-top: 0;
8 | }
9 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/filter.browsers:
--------------------------------------------------------------------------------
1 | IE 11
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/filter.css:
--------------------------------------------------------------------------------
1 | .blur {
2 | filter: blur(4px);
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/filter.expected.css:
--------------------------------------------------------------------------------
1 | .blur {
2 | filter: url('data:image/svg+xml;charset=utf-8, #filter');
3 | filter: blur(4px);
4 | }
5 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/font-family-system-ui.css:
--------------------------------------------------------------------------------
1 | selector {
2 | font-family: system-ui, sans-serif;
3 | }
4 |
5 | selector {
6 | font-family: system-ui, Helvetica Neue, sans-serif;
7 | }
8 |
9 | selector {
10 | font-family: sans-serif;
11 | }
12 |
13 | selector {
14 | font: italic bold 12px/30px system-ui, sans-serif;
15 | }
16 |
17 | selector {
18 | font: italic bold 12px/30px system-ui, Helvetica Neue, sans-serif;
19 | }
20 |
21 | selector {
22 | font: italic 12px sans-serif;
23 | }
24 |
25 | selector {
26 | font-weight: 700;
27 | }
28 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/font-family-system-ui.expected.css:
--------------------------------------------------------------------------------
1 | selector {
2 | font-family: system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Droid Sans, Helvetica Neue, sans-serif;
3 | }
4 |
5 | selector {
6 | font-family: system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Droid Sans, Helvetica Neue, sans-serif;
7 | }
8 |
9 | selector {
10 | font-family: sans-serif;
11 | }
12 |
13 | selector {
14 | font: italic bold 12px/30px system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Droid Sans, Helvetica Neue, sans-serif;
15 | }
16 |
17 | selector {
18 | font: italic bold 12px/30px system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Droid Sans, Helvetica Neue, sans-serif;
19 | }
20 |
21 | selector {
22 | font: italic 12px sans-serif;
23 | }
24 |
25 | selector {
26 | font-weight: 700;
27 | }
28 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/font-variant.css:
--------------------------------------------------------------------------------
1 | h2 {
2 | font-variant-caps: small-caps;
3 | }
4 |
5 | table {
6 | font-variant-numeric: lining-nums;
7 | }
8 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/font-variant.expected.css:
--------------------------------------------------------------------------------
1 | h2 {
2 | font-feature-settings: "c2sc";
3 | font-variant-caps: small-caps;
4 | }
5 |
6 | table {
7 | font-feature-settings: "lnum";
8 | font-variant-numeric: lining-nums;
9 | }
10 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/image-set.browsers:
--------------------------------------------------------------------------------
1 | IE 11
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/image-set.css:
--------------------------------------------------------------------------------
1 | .image {
2 | background-image: image-set(
3 | url(img/test.png) 1x,
4 | url(img/test-2x.png) 2x,
5 | url(my-img-print.png) 600dpi
6 | );
7 | }
8 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/image-set.expected.css:
--------------------------------------------------------------------------------
1 | .image {
2 | background-image: url(img/test.png);
3 | }@media (min-resolution: 192dpi) {.image {
4 | background-image: url(img/test-2x.png);
5 | }
6 | }@media (min-resolution: 600dpi) {.image {
7 | background-image: url(my-img-print.png);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/initial.browsers:
--------------------------------------------------------------------------------
1 | Safari 9
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/initial.css:
--------------------------------------------------------------------------------
1 | a {
2 | all: initial;
3 | }
4 |
5 | a {
6 | animation: initial;
7 | background: initial;
8 | border: initial;
9 | column-rule: initial;
10 | font: initial;
11 | list-style: initial;
12 | outline: initial;
13 | text-decoration: initial;
14 | }
15 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/initial.expected.css:
--------------------------------------------------------------------------------
1 | a {
2 | animation: none 0s ease 0s 1 normal none running;
3 | backface-visibility: visible;
4 | background: transparent none repeat 0 0 / auto auto padding-box border-box scroll;
5 | border: medium none currentColor;
6 | border-collapse: separate;
7 | border-image: none;
8 | border-radius: 0;
9 | border-spacing: 0;
10 | bottom: auto;
11 | box-shadow: none;
12 | box-sizing: content-box;
13 | caption-side: top;
14 | clear: none;
15 | clip: auto;
16 | color: #000;
17 | columns: auto;
18 | column-count: auto;
19 | column-fill: balance;
20 | column-gap: normal;
21 | column-rule: medium none currentColor;
22 | column-span: 1;
23 | column-width: auto;
24 | content: normal;
25 | counter-increment: none;
26 | counter-reset: none;
27 | cursor: auto;
28 | direction: ltr;
29 | display: inline;
30 | empty-cells: show;
31 | float: none;
32 | font-family: serif;
33 | font-size: medium;
34 | font-style: normal;
35 | font-variant: normal;
36 | font-weight: normal;
37 | font-stretch: normal;
38 | line-height: normal;
39 | height: auto;
40 | hyphens: none;
41 | left: auto;
42 | letter-spacing: normal;
43 | list-style: disc outside none;
44 | margin: 0;
45 | max-height: none;
46 | max-width: none;
47 | min-height: 0;
48 | min-width: 0;
49 | opacity: 1;
50 | orphans: 2;
51 | outline: medium none invert;
52 | overflow: visible;
53 | overflow-x: visible;
54 | overflow-y: visible;
55 | padding: 0;
56 | page-break-after: auto;
57 | page-break-before: auto;
58 | page-break-inside: auto;
59 | perspective: none;
60 | perspective-origin: 50% 50%;
61 | position: static;
62 | right: auto;
63 | tab-size: 8;
64 | table-layout: auto;
65 | text-align: left;
66 | text-align-last: auto;
67 | text-decoration: none;
68 | text-indent: 0;
69 | text-shadow: none;
70 | text-transform: none;
71 | top: auto;
72 | transform: none;
73 | transform-origin: 50% 50% 0;
74 | transform-style: flat;
75 | transition: none 0s ease 0s;
76 | unicode-bidi: normal;
77 | vertical-align: baseline;
78 | visibility: visible;
79 | white-space: normal;
80 | widows: 2;
81 | width: auto;
82 | word-spacing: normal;
83 | z-index: auto;
84 | all: initial;
85 | }
86 |
87 | a {
88 | animation: none 0s ease 0s 1 normal none running;
89 | animation: initial;
90 | background: transparent none repeat 0 0 / auto auto padding-box border-box scroll;
91 | background: initial;
92 | border: medium none currentColor;
93 | border: initial;
94 | column-rule: medium none currentColor;
95 | column-rule: initial;
96 | font-family: serif;
97 | font-size: medium;
98 | font-style: normal;
99 | font-variant: normal;
100 | font-weight: normal;
101 | font-stretch: normal;
102 | line-height: normal;
103 | font: initial;
104 | list-style: disc outside none;
105 | list-style: initial;
106 | outline: medium none invert;
107 | outline: initial;
108 | text-decoration: none;
109 | text-decoration: initial;
110 | }
111 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/media-queries-range.css:
--------------------------------------------------------------------------------
1 | @media screen and (width >= 500px) and (width <= 1200px) {}
2 | @media screen and (500px <= width <= 1200px) {}
3 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/media-queries-range.expected.css:
--------------------------------------------------------------------------------
1 | @media screen and (min-width: 500px) and (max-width: 1200px) {}
2 | @media screen and (min-width: 500px) and (max-width: 1200px) {}
3 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/nesting.css:
--------------------------------------------------------------------------------
1 | .foo {
2 | color: red;
3 |
4 | @nest & .bar {
5 | color: white;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/nesting.expected.css:
--------------------------------------------------------------------------------
1 | .foo {
2 | color: red
3 | }
4 | .foo .bar {
5 | color: white;
6 | }
7 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/overflow-wrap.browsers:
--------------------------------------------------------------------------------
1 | IE 11
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/overflow-wrap.css:
--------------------------------------------------------------------------------
1 | body {
2 | overflow-wrap: break-word;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/overflow-wrap.expected.css:
--------------------------------------------------------------------------------
1 | body {
2 | word-wrap: break-word;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-class-any-link.css:
--------------------------------------------------------------------------------
1 | nav :any-link > span {
2 | background-color: yellow;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-class-any-link.expected.css:
--------------------------------------------------------------------------------
1 | nav :link > span,nav :visited > span {
2 | background-color: yellow;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-class-matches.browsers:
--------------------------------------------------------------------------------
1 | Safari 8
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-class-matches.css:
--------------------------------------------------------------------------------
1 | p:matches(:first-child, .specific) {
2 | color: red;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-class-matches.expected.css:
--------------------------------------------------------------------------------
1 | p:first-child, p.specific {
2 | color: red;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-class-not.browsers:
--------------------------------------------------------------------------------
1 | Safari 8
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-class-not.css:
--------------------------------------------------------------------------------
1 | p:not(:first-child, .specific) {
2 | background: blue;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-class-not.expected.css:
--------------------------------------------------------------------------------
1 | p:not(:first-child):not(.specific) {
2 | background: blue;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-elements.browsers:
--------------------------------------------------------------------------------
1 | IE 8
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-elements.css:
--------------------------------------------------------------------------------
1 | .foo::after {
2 | content:"pseudoelement"
3 | }
4 | .foo::before {
5 | content:"pseudoelement"
6 | }
7 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/pseudo-elements.expected.css:
--------------------------------------------------------------------------------
1 | .foo:after {
2 | content:"pseudoelement"
3 | }
4 | .foo:before {
5 | content:"pseudoelement"
6 | }
7 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/rem.browsers:
--------------------------------------------------------------------------------
1 | IE 8
2 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/rem.css:
--------------------------------------------------------------------------------
1 | .sky {
2 | margin: 2.5rem 2px 3em 100%;
3 | color: blue;
4 | }
5 |
6 | @media screen and (min-width: 20rem) {
7 | .leaf {
8 | margin-bottom: 1.333rem;
9 | font-size: 1.5rem;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/__tests__/fixtures/features/rem.expected.css:
--------------------------------------------------------------------------------
1 | .sky {
2 | margin: 40px 2px 3em 100%;
3 | margin: 2.5rem 2px 3em 100%;
4 | color: blue;
5 | }
6 |
7 | @media screen and (min-width: 20rem) {
8 | .leaf {
9 | margin-bottom: 1.333rem;
10 | font-size: 1.5rem;
11 | }
12 | }
--------------------------------------------------------------------------------
/src/__tests__/fixtures/regression.css:
--------------------------------------------------------------------------------
1 | @custom-selector :--button .button;
2 |
3 | :--button {
4 | & i {
5 | color: black;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/__tests__/fixtures/regression.expected.css:
--------------------------------------------------------------------------------
1 | .button i {
2 | color: black;
3 | }
4 |
--------------------------------------------------------------------------------
/src/__tests__/index.js:
--------------------------------------------------------------------------------
1 | import tape from "tape";
2 |
3 | import utils from "./utils";
4 | import postcssnext from "..";
5 |
6 | tape("postcss-cssnext is a postcss plugin", t => {
7 | t.ok(
8 | typeof postcssnext.process === "function",
9 | "should have the postcss process() function available"
10 | );
11 |
12 | t.end();
13 | });
14 |
15 | tape("cssnext regression test", t => {
16 | const input = utils.readFixture("regression");
17 | const expected = utils.readFixture("regression.expected");
18 | const actual = postcssnext({ browsers: "IE 6" })
19 | .process(input)
20 | .css.trim();
21 |
22 | utils.write(utils.fixturePath("regression.actual"), actual);
23 |
24 | t.equal(actual, expected.trim(), "should pass the regression");
25 |
26 | t.end();
27 | });
28 |
--------------------------------------------------------------------------------
/src/__tests__/option.browsers.js:
--------------------------------------------------------------------------------
1 | import tape from "tape";
2 |
3 | import cssnext from "..";
4 |
5 | tape("cssnext browsers option", function(t) {
6 | // no recent browser need pixrem
7 | const remInput = "body{font-size:2rem}";
8 | t.equal(
9 | cssnext({ browsers: "last 1 version" }).process(remInput).css,
10 | remInput,
11 | "should not enable px fallback when all browsers support it"
12 | );
13 |
14 | const customPropsInput = ":root{--foo:bar}baz{qux:var(--foo)}";
15 | const customPropsOutput = "baz{qux:bar}";
16 |
17 | // fx 30 doesn't handle custom prop
18 | t.equal(
19 | cssnext({ browsers: "Firefox >= 30" }).process(customPropsInput).css,
20 | customPropsOutput,
21 | "should enable custom properties when browsers do not support it"
22 | );
23 |
24 | // fx 31 handle custom prop
25 | t.equal(
26 | cssnext({ browsers: "Firefox >= 31" }).process(customPropsInput).css,
27 | customPropsInput,
28 | "should NOT enable custom properties when browsers support it"
29 | );
30 |
31 | // fx 31 support but not IE 8
32 | t.equal(
33 | cssnext({ browsers: "Firefox >= 31, IE 8" }).process(customPropsInput).css,
34 | customPropsOutput,
35 | "should enable custom properties when at least one browsers do not " +
36 | "support it"
37 | );
38 |
39 | t.end();
40 | });
41 |
42 | tape("cssnext browsers option propagation to autoprefixer", function(t) {
43 | const input = "body{transition: 1s}";
44 | const output = "body{-webkit-transition: 1s;transition: 1s}";
45 |
46 | // Safari 6 need -webkit prefix
47 | t.equal(
48 | cssnext({ browsers: "Safari 6" }).process(input).css,
49 | output,
50 | "should propagate browsers option to autoprefixer"
51 | );
52 |
53 | // Safari 6.1 do not need -webkit prefix
54 | t.equal(
55 | cssnext({ browsers: "Safari 6.1" }).process(input).css,
56 | input,
57 | "should propagate browsers option to autoprefixer"
58 | );
59 |
60 | t.end();
61 | });
62 |
63 | tape("cssnext browsers option propagation to pixrem", function(t) {
64 | const input = "body{font-size: 1rem}";
65 | const output = "body{font-size: 16px;font-size: 1rem}";
66 |
67 | // IE 8 needs rem fallback
68 | t.equal(
69 | cssnext({ browsers: "ie 8" }).process(input).css,
70 | output,
71 | "should propagate browsers option to pixrem"
72 | );
73 |
74 | // IE 9 doesn't need rem fallback on a simple font-size
75 | t.equal(
76 | cssnext({ browsers: "ie 9" }).process(input).css,
77 | input,
78 | "should propagate browsers option to pixrem"
79 | );
80 |
81 | // IE 9 needs rem on pseudo element
82 | const inputWeirdCase = input.replace("body", "body::before");
83 | const outputWeirdCase = output.replace("body", "body::before");
84 | t.equal(
85 | cssnext({ browsers: "ie 9" }).process(inputWeirdCase).css,
86 | outputWeirdCase,
87 | "should propagate browsers option to pixrem"
88 | );
89 |
90 | t.end();
91 | });
92 |
--------------------------------------------------------------------------------
/src/__tests__/option.features.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Test dependencies
3 | */
4 | import test from "tape";
5 | import { join } from "path";
6 |
7 | import utils from "./utils";
8 | // eslint-disable-next-line import/named
9 | import cssnext, { features } from "..";
10 |
11 | /**
12 | * Features tests
13 | */
14 | import toSlug from "to-slug-case";
15 |
16 | const testFeature = function(t, feature, source, input, expected, slug) {
17 | const options = { features: {} };
18 |
19 | const browsers = utils.readFixtureBrowsers(join("features", slug));
20 |
21 | if (browsers) {
22 | options.browsers = browsers;
23 | }
24 |
25 | // disable all features
26 | Object.keys(features).forEach(function(key) {
27 | options.features[key] = false;
28 | });
29 |
30 | const css = cssnext(options).process(input).css;
31 | t.notEqual(
32 | css,
33 | expected,
34 | "should not add " + feature + " support if disabled"
35 | );
36 | t.equal(
37 | css,
38 | input,
39 | "should not modify input if " + feature + " is disabled"
40 | );
41 |
42 | // enable only the one we want to test...
43 | options.features[feature] = true;
44 |
45 | const actual = cssnext(options)
46 | .process(input)
47 | .css.trim();
48 | utils.write(utils.fixturePath(join("features", slug + ".actual")), actual);
49 |
50 | t.equal(actual, expected.trim(), "should add " + feature + " support");
51 | };
52 |
53 | Object.keys(features).forEach(function(name) {
54 | const slug = toSlug(name);
55 | const source = utils.fixturePath(join("features", slug));
56 | const input = utils.readFixture(join("features", slug));
57 | const expected = utils.readFixture(join("features", slug + ".expected"));
58 |
59 | test(slug, function(t) {
60 | testFeature(t, name, source, input, expected, slug);
61 |
62 | t.end();
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/src/__tests__/option.warnForDeprecations.js:
--------------------------------------------------------------------------------
1 | import tape from "tape";
2 |
3 | import postcss from "postcss";
4 | import cssnext from "..";
5 | import { resetWarning } from "../warn-for-deprecations";
6 |
7 | const reportFail = t => error => {
8 | console.log(error);
9 | t.fail();
10 | };
11 |
12 | tape("cssnext warnForDeprecation option", t => {
13 | const messages = [];
14 | resetWarning();
15 | const instance = postcss([
16 | cssnext({
17 | console: { log: msg => messages.push(msg) }
18 | })
19 | ]);
20 |
21 | instance.process("body{}").then(() => {
22 | t.equal(
23 | messages.length,
24 | 0,
25 | "should not add warning there is no deprecated stuff"
26 | );
27 | t.end();
28 | }, reportFail(t));
29 | });
30 |
31 | tape("cssnext warnForDeprecation option", t => {
32 | const messages = [];
33 | resetWarning();
34 | const instance = postcss([
35 | cssnext({
36 | console: { log: msg => messages.push(msg) }
37 | })
38 | ]);
39 |
40 | instance
41 | .process(
42 | `
43 | :root {
44 | --toolbar-theme: {
45 | border: 1px solid green;
46 | };
47 | }
48 | .Toolbar {
49 | @apply --toolbar-theme;
50 | @apply --toolbar-theme;
51 | }
52 | `
53 | )
54 | .then(() => {
55 | t.equal(
56 | messages.length,
57 | 1,
58 | "should add a single warning if there are deprecated stuff"
59 | );
60 | t.end();
61 | }, reportFail(t));
62 | });
63 |
--------------------------------------------------------------------------------
/src/__tests__/option.warnForDuplicates.js:
--------------------------------------------------------------------------------
1 | import tape from "tape";
2 |
3 | import postcss from "postcss";
4 | import autoprefixer from "autoprefixer";
5 | import cssnext from "..";
6 | import { spotted } from "../warn-for-duplicates";
7 |
8 | const reportFail = t => error => {
9 | console.log(error);
10 | t.fail();
11 | };
12 |
13 | tape("cssnext warnForDuplicates option", t => {
14 | const messages = [];
15 | spotted.length = 0; // reset spotted plugins
16 | const instance = postcss([
17 | cssnext({
18 | console: { log: msg => messages.push(msg) }
19 | })
20 | ]);
21 |
22 | instance.process("body{}").then(() => {
23 | t.equal(messages.length, 0, "should not add warning if no duplicate");
24 | t.end();
25 | }, reportFail(t));
26 | });
27 |
28 | tape("cssnext warnForDuplicates option", t => {
29 | const messages = [];
30 | spotted.length = 0; // reset spotted plugins
31 | const instance = postcss([
32 | autoprefixer(),
33 | cssnext({
34 | console: { log: msg => messages.push(msg) }
35 | })
36 | ]);
37 |
38 | instance.process("body{}").then(() => {
39 | t.ok(
40 | messages[0].indexOf("Warning: postcss-cssnext found a duplicate plugin") >
41 | -1,
42 | "should add warning if there are duplicates before"
43 | );
44 | t.end();
45 | }, reportFail(t));
46 | });
47 |
48 | tape("cssnext warnForDuplicates option", t => {
49 | const messages = [];
50 | spotted.length = 0; // reset spotted plugins
51 | const instance = postcss([
52 | autoprefixer(),
53 | cssnext({
54 | warnForDuplicates: false,
55 | console: { log: msg => messages.push(msg) }
56 | })
57 | ]);
58 |
59 | instance.process("body{}").then(() => {
60 | t.equal(
61 | messages.length,
62 | 0,
63 | "should NOT add warning if there are duplicates but !warnForDuplicates"
64 | );
65 | t.end();
66 | }, reportFail(t));
67 | });
68 |
69 | tape("cssnext warnForDuplicates option", t => {
70 | const messages = [];
71 | spotted.length = 0; // reset spotted plugins
72 | const instance = postcss([
73 | cssnext({
74 | console: { log: msg => messages.push(msg) }
75 | }),
76 | autoprefixer()
77 | ]);
78 |
79 | instance.process("body{}").then(() => {
80 | t.ok(
81 | messages.length &&
82 | messages[0].indexOf(
83 | "Warning: postcss-cssnext found a duplicate plugin"
84 | ) > -1,
85 | "should add warning if there are duplicates after"
86 | );
87 | t.end();
88 | }, reportFail(t));
89 | });
90 |
--------------------------------------------------------------------------------
/src/__tests__/utils/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module dependencies
3 | */
4 | import fs from "fs";
5 | import { join } from "path";
6 |
7 | /**
8 | * Exposes functions
9 | *
10 | * @type {Object}
11 | */
12 | export default {
13 | /**
14 | * get fixture path
15 | * @param {String} name
16 | * @param {String} ext (optional extension, default to ".css")
17 | * @return the fixture filename
18 | */
19 | fixturePath(name, ext) {
20 | ext = ext !== undefined ? ext : ".css";
21 | return join("src", "__tests__", "fixtures", name + ext);
22 | },
23 |
24 | /**
25 | * read a fixture
26 | * @param {String} name
27 | * @param {String} ext (optional extension, default to ".css")
28 | * @return the fixture content
29 | */
30 | readFixture(name, ext) {
31 | return fs.readFileSync(this.fixturePath(name, ext), "utf8");
32 | },
33 |
34 | /**
35 | * read a fixture browsers
36 | * @param {String} name
37 | * @return the fixture browsers string
38 | */
39 | readFixtureBrowsers(name) {
40 | const filePath = this.fixturePath(name, ".browsers");
41 | const exists = fs.existsSync(filePath);
42 | return (
43 | exists &&
44 | fs
45 | .readFileSync(filePath, "utf8")
46 | .split("\n")[0]
47 | .trim()
48 | );
49 | },
50 |
51 | /**
52 | * write a result
53 | * @param {String} name
54 | * @param {String} content
55 | */
56 | write(name, content) {
57 | fs.writeFileSync(name, content);
58 | }
59 | };
60 |
--------------------------------------------------------------------------------
/src/features-activation-map.js:
--------------------------------------------------------------------------------
1 | // Some features might affect others (eg: var() in a calc()
2 | // in order to prevent issue, the map contains a sort of dependencies list
3 | //
4 | // null == always enable (& no caniuse data)
5 | export default {
6 | customProperties: ["css-variables"],
7 | // applyRule: [ null ],
8 | // calc() transformation only make sense with transformed custom properties,
9 | // don't you think ?
10 | // calc: [ null ],
11 | // nesting: [ null ],
12 | // @todo open PR on caniuse repo https://github.com/Fyrd/caniuse
13 | // customMedia: [ null ],
14 | // mediaQueriesRange: [ null ],
15 | // customSelectors: [ null ],
16 | attributeCaseInsensitive: ["css-case-insensitive"],
17 | colorRebeccapurple: ["css-rebeccapurple"],
18 | // colorHsl: [ null ],
19 | // colorHwb: [ null ],
20 | // colorRgb: [ null ],
21 | // colorGray: [ null ],
22 | colorHexAlpha: ["css-rrggbbaa"],
23 | // colorFunction:[ null],
24 | // fontVariant: [ null ],
25 | // @todo can be done using a callback, this is only used for Firefox < 35
26 | filter: ["css-filters"],
27 | initial: ["css-all", "css-initial-value"],
28 | rem: ["rem"],
29 | pseudoElements: ["css-gencontent"],
30 | pseudoClassMatches: ["css-matches-pseudo"],
31 | pseudoClassNot: ["css-not-sel-list"],
32 | // pseudoClassAnyLink: [ null ],
33 | colorRgba: ["css3-colors"],
34 | overflowWrap: ["wordwrap"],
35 | imageSet: ["css-image-set"]
36 | // will always be null since autoprefixer does the same game as we do
37 | // autoprefixer: [ null ]
38 | };
39 |
--------------------------------------------------------------------------------
/src/features.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/max-dependencies */
2 |
3 | export default {
4 | /**
5 | * REMINDER:
6 | * ******************
7 | * order is important
8 | * ******************
9 | */
10 | // https://npmjs.com/package/postcss-custom-properties
11 | customProperties: options => require("postcss-custom-properties")(options),
12 |
13 | // https://npmjs.com/package/postcss-apply
14 | applyRule: options => require("postcss-apply")(options),
15 |
16 | // https://npmjs.com/package/postcss-calc
17 | calc: options => require("postcss-calc")(options),
18 |
19 | // https://www.npmjs.com/package/postcss-image-set-polyfill
20 | imageSet: options => require("postcss-image-set-polyfill")(options),
21 |
22 | // https://npmjs.com/package/postcss-nesting
23 | nesting: options => require("postcss-nesting")(options),
24 |
25 | // https://npmjs.com/package/postcss-custom-media
26 | customMedia: options => require("postcss-custom-media")(options),
27 |
28 | // https://npmjs.com/package/postcss-media-minmax
29 | mediaQueriesRange: options => require("postcss-media-minmax")(options),
30 |
31 | // https://npmjs.com/package/postcss-custom-selectors
32 | customSelectors: options => require("postcss-custom-selectors")(options),
33 |
34 | // https://npmjs.com/package/postcss-attribute-case-insensitive
35 | attributeCaseInsensitive: options =>
36 | require("postcss-attribute-case-insensitive")(options),
37 |
38 | // https://npmjs.com/package/postcss-color-rebeccapurple
39 | colorRebeccapurple: options =>
40 | require("postcss-color-rebeccapurple")(options),
41 |
42 | // https://npmjs.com/package/postcss-color-hwb
43 | colorHwb: options => require("postcss-color-hwb")(options),
44 |
45 | // https://npmjs.com/package/postcss-color-hsl
46 | colorHsl: options => require("postcss-color-hsl")(options),
47 |
48 | // https://npmjs.com/package/postcss-color-rgb
49 | colorRgb: options => require("postcss-color-rgb")(options),
50 |
51 | // https://npmjs.com/package/postcss-color-gray
52 | colorGray: options => require("postcss-color-gray")(options),
53 |
54 | // https://npmjs.com/package/postcss-color-hex-alpha
55 | colorHexAlpha: options => require("postcss-color-hex-alpha")(options),
56 |
57 | // https://npmjs.com/package/postcss-color-function
58 | colorFunction: options => require("postcss-color-function")(options),
59 |
60 | // https://npmjs.com/package/postcss-font-family-system-ui
61 | fontFamilySystemUi: options =>
62 | require("postcss-font-family-system-ui")(options),
63 |
64 | // https://npmjs.com/package/postcss-font-variant
65 | fontVariant: options => require("postcss-font-variant")(options),
66 |
67 | // https://npmjs.com/package/pleeease-filters
68 | filter: options => require("pleeease-filters")(options),
69 |
70 | // https://npmjs.com/package/postcss-initial
71 | initial: options => require("postcss-initial")(options),
72 |
73 | // https://npmjs.com/package/pixrem
74 | rem: options => require("pixrem")(options),
75 |
76 | // https://npmjs.com/package/postcss-pseudoelements
77 | pseudoElements: options => require("postcss-pseudoelements")(options),
78 |
79 | // https://npmjs.com/package/postcss-selector-matches
80 | pseudoClassMatches: options => require("postcss-selector-matches")(options),
81 |
82 | // https://npmjs.com/package/postcss-selector-not
83 | pseudoClassNot: options => require("postcss-selector-not")(options),
84 |
85 | // https://npmjs.com/package/postcss-pseudo-class-any-link
86 | pseudoClassAnyLink: options =>
87 | require("postcss-pseudo-class-any-link")(options),
88 |
89 | // https://npmjs.com/package/postcss-color-rgba-fallback
90 | colorRgba: options => require("postcss-color-rgba-fallback")(options),
91 |
92 | // https://www.npmjs.com/package/postcss-replace-overflow-wrap
93 | overflowWrap: options => require("postcss-replace-overflow-wrap")(options),
94 |
95 | // https://npmjs.com/package/autoprefixer
96 | autoprefixer: options => require("autoprefixer")(options)
97 | };
98 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import postcss from "postcss";
2 | import { isSupported } from "caniuse-api";
3 |
4 | import libraryFeatures from "./features";
5 | import featuresActivationMap from "./features-activation-map";
6 | import warnForDuplicates from "./warn-for-duplicates";
7 | import warnForDeprecations from "./warn-for-deprecations";
8 |
9 | const plugin = postcss.plugin("postcss-cssnext", options => {
10 | options = {
11 | console: console,
12 | warnForDuplicates: true,
13 | warnForDeprecations: true,
14 | features: {},
15 | // options.browsers is deliberately undefined by default to inherit
16 | // browserslist default behavior
17 | ...options
18 | };
19 |
20 | const features = options.features;
21 |
22 | // propagate browsers option to plugins that supports it
23 | const pluginsToPropagateBrowserOption = ["autoprefixer", "rem"];
24 | pluginsToPropagateBrowserOption.forEach(name => {
25 | const feature = features[name];
26 |
27 | if (feature !== false) {
28 | features[name] = {
29 | browsers:
30 | feature && feature.browsers ? feature.browsers : options.browsers,
31 | ...(feature || {})
32 | };
33 | }
34 | });
35 |
36 | // autoprefixer doesn't like an "undefined" value. Related to coffee ?
37 | if (features.autoprefixer && features.autoprefixer.browsers === undefined) {
38 | delete features.autoprefixer.browsers;
39 | }
40 |
41 | const processor = postcss();
42 |
43 | if (options.warnForDeprecations) {
44 | processor.use(
45 | warnForDeprecations({
46 | console: options.console
47 | })
48 | );
49 | }
50 |
51 | // features
52 | Object.keys(libraryFeatures).forEach(key => {
53 | // feature is auto enabled if: not disable && (enabled || no data yet ||
54 | // !supported yet)
55 | if (
56 | // feature is not disabled
57 | features[key] !== false &&
58 | // feature is enabled
59 | (features[key] === true ||
60 | // feature don't have any browsers data (yet)
61 | featuresActivationMap[key] === undefined ||
62 | // feature is not yet supported by the browsers scope
63 | (featuresActivationMap[key] &&
64 | featuresActivationMap[key][0] &&
65 | !isSupported(featuresActivationMap[key][0], options.browsers)))
66 | ) {
67 | const plugin = libraryFeatures[key](
68 | typeof features[key] === "object" ? { ...features[key] } : undefined
69 | );
70 | processor.use(plugin);
71 | }
72 | });
73 |
74 | if (options.warnForDuplicates) {
75 | processor.use(
76 | warnForDuplicates({
77 | keys: Object.keys(libraryFeatures),
78 | console: options.console
79 | })
80 | );
81 | }
82 |
83 | return processor;
84 | });
85 |
86 | // es5/6 support
87 | plugin.features = libraryFeatures;
88 |
89 | module.exports = plugin;
90 |
--------------------------------------------------------------------------------
/src/warn-for-deprecations.js:
--------------------------------------------------------------------------------
1 | import postcss from "postcss";
2 | import color from "chalk";
3 |
4 | let shouldGlobalWarn = true;
5 | export const resetWarning = () => (shouldGlobalWarn = true);
6 |
7 | const warnForDeprecations = postcss.plugin(
8 | "postcss-cssnext-warn-for-deprecations",
9 | ({ console: messenger }) => {
10 | return style => {
11 | // warn for removed @apply
12 | style.walkAtRules("apply", () => {
13 | if (shouldGlobalWarn) {
14 | shouldGlobalWarn = false;
15 | messenger.log(
16 | color.yellow.bold(
17 | "You are using @apply rule and custom property sets. \n" +
18 | "This feature won't be included in the next major release " +
19 | "of postcss-cssnext. \n"
20 | ) +
21 | color.grey(
22 | "This most likely won't get any more support from browser vendors as the " +
23 | "spec is yet considered deprecated and alternative solutions are being " +
24 | "discussed. \n"
25 | ) +
26 | "Read more about the reason here https://github.com/pascalduez/postcss-apply."
27 | );
28 | }
29 | });
30 | };
31 | }
32 | );
33 |
34 | export default warnForDeprecations;
35 |
--------------------------------------------------------------------------------
/src/warn-for-duplicates.js:
--------------------------------------------------------------------------------
1 | import postcss from "postcss";
2 | import color from "chalk";
3 |
4 | const msg = name =>
5 | `Warning: postcss-cssnext found a duplicate plugin ('${name}') ` +
6 | "in your postcss plugins. " +
7 | `This might be inefficient. You should remove '${name}' from your ` +
8 | "postcss plugin list since it's already included by postcss-cssnext.";
9 |
10 | let shouldGlobalWarn = true;
11 | const globalWarning =
12 | "Note: If, for a really specific reason, postcss-cssnext warnings are " +
13 | "irrelevant for your use case, and you really know what you are doing, " +
14 | "you can disable this warnings by setting 'warnForDuplicates' option of " +
15 | "postcss-cssnext to 'false'.";
16 | export const spotted = [];
17 |
18 | const warnForDuplicates = postcss.plugin(
19 | "postcss-cssnext-warn-for-duplicates",
20 | ({ keys, console: messenger }) => {
21 | return (style, result) => {
22 | const pluginNames = [];
23 | result.processor.plugins.forEach(plugin => {
24 | const name = plugin.postcssPlugin;
25 | if (
26 | pluginNames.indexOf(name) > -1 &&
27 | // warn for cssnext plugins only
28 | keys.indexOf(name) > -1 &&
29 | // show warning once
30 | spotted.indexOf(name) === -1
31 | ) {
32 | messenger.log(color.yellow.bold(msg(name)));
33 | spotted.push(name);
34 | } else {
35 | pluginNames.push(name);
36 | }
37 | });
38 |
39 | if (spotted.length > 0 && shouldGlobalWarn) {
40 | shouldGlobalWarn = false;
41 | messenger.log(globalWarning);
42 | }
43 | };
44 | }
45 | );
46 |
47 | export default warnForDuplicates;
48 |
--------------------------------------------------------------------------------
/tea.yaml:
--------------------------------------------------------------------------------
1 | # https://tea.xyz/what-is-this-file
2 | ---
3 | version: 1.0.0
4 | codeOwners:
5 | - '0xaCF57442C0d139baE9Df0f45abF899b8B4CE8547'
6 | quorum: 1
7 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require("webpack");
2 | const ExtractTextPlugin = require("extract-text-webpack-plugin");
3 | const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
4 |
5 | const pkg = require("./package.json");
6 | const buildConfig = require("./build.config");
7 |
8 | module.exports = {
9 | resolve: {
10 | mainFields: ["browser", "main"]
11 | },
12 | module: {
13 | // ! \\ note that loaders are executed from bottom to top !
14 | loaders: [
15 | {
16 | test: /\.js$/,
17 | loader: "babel-loader",
18 | query: {
19 | babelrc: false,
20 | ...pkg.babel.env.browsers
21 | },
22 | exclude: /node_modules/
23 | },
24 | // some plugins that are node4+ in da browsers need uglify compat
25 | {
26 | test: /\.js$/,
27 | loader: "babel-loader",
28 | query: {
29 | babelrc: false,
30 | ...pkg.babel.env.browsers
31 | },
32 | include: /node_modules\/(chalk|ansi-styles|strip-ansi|postcss-.*)/
33 | },
34 | {
35 | test: /\.css$/,
36 | loader: ExtractTextPlugin.extract({
37 | fallback: "style-loader",
38 | use: "css-loader"
39 | })
40 | },
41 | {
42 | test: /\.(ico|jpe?g|png|gif|svg)$/,
43 | loaders: ["file-loader?name=[path][name].[ext]&context=./docs/src"]
44 | }
45 | ]
46 | },
47 |
48 | plugins: [
49 | new webpack.DefinePlugin(buildConfig),
50 | new ExtractTextPlugin({
51 | filename: "[name].css",
52 | disable: !buildConfig.__PROD__
53 | })
54 | ].concat(
55 | buildConfig.__PROD__
56 | ? [
57 | new webpack.optimize.DedupePlugin(),
58 | new UglifyJsPlugin({
59 | uglifyOptions: {
60 | compress: {
61 | warnings: false
62 | }
63 | }
64 | })
65 | ]
66 | : []
67 | ),
68 |
69 | node: {
70 | // https://github.com/webpack/webpack/issues/451
71 | // run tape test with webpack
72 | fs: "empty"
73 | }
74 | };
75 |
--------------------------------------------------------------------------------