Skip to content

Commit b77da32

Browse files
authored
Update postcss to v8 (prettier#9209)
* Update `postcss` v8 * Parser custom properties * Improve logic * Update lint script * Fix node location * Fix comments inside * Add a test * Test on `less` and `scss` too * Fix empty prop print * Clean * Update `postcss` * Exclude `regenerator` * Test `no-semi` * Add changelog * Typo * Apply review suggestion * Style * Simplify logic * Remove error test, we don't throw on this anymore * Style * Update postcss * Update postcss
1 parent 9068b4a commit b77da32

29 files changed

Lines changed: 650 additions & 11 deletions

File tree

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#### Improve custom properties format (#9209 by @fisker)
2+
3+
Thanks to [`PostCSS 8.0`](https://github.com/postcss/postcss/releases/tag/8.0.0), we can handle these edge cases on custom properties.
4+
5+
<!-- prettier-ignore -->
6+
```css
7+
/* Input */
8+
:root {
9+
--empty: ;
10+
--JSON: [1, "2", {"three": {"a":1}}, [4]];
11+
--javascript: function(rule) { console.log(rule) };
12+
}
13+
14+
@supports (--element(".minwidth", { "minWidth": 300 })) {
15+
[--self] {
16+
background: greenyellow;
17+
}
18+
}
19+
20+
/* Prettier stable */
21+
SyntaxError: (postcss) CssSyntaxError Missed semicolon (3:20)
22+
1 | :root {
23+
2 | --empty: ;
24+
> 3 | --JSON: [1, "2", {"three": {"a":1}}, [4]];
25+
| ^
26+
4 | --javascript: function(rule) { console.log(rule) };
27+
5 | }
28+
6 |
29+
30+
/* Prettier master */
31+
:root {
32+
--empty: ;
33+
--JSON: [1, "2", {"three": {"a": 1}}, [4]];
34+
--javascript: function(rule) {console.log(rule)};
35+
}
36+
37+
@supports (--element(".minwidth", {"minWidth": 300})) {
38+
[--self] {
39+
background: greenyellow;
40+
}
41+
}
42+
```

jest.config.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,15 @@ if (isProduction) {
2323
presets: [
2424
[
2525
"@babel/env",
26-
// Workaround for https://github.com/babel/babel/issues/11994
27-
{ loose: true },
26+
{
27+
targets: { node: "current" },
28+
exclude: [
29+
"transform-async-to-generator",
30+
"transform-classes",
31+
"proposal-async-generator-functions",
32+
"transform-regenerator",
33+
],
34+
},
2835
],
2936
],
3037
},

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
"outdent": "0.7.1",
6565
"parse-srcset": "ikatyang/parse-srcset#54eb9c1cb21db5c62b4d0e275d7249516df6f0ee",
6666
"please-upgrade-node": "3.2.0",
67-
"postcss": "7.0.32",
67+
"postcss": "8.0.7",
6868
"postcss-less": "3.1.4",
6969
"postcss-media-query-parser": "0.2.3",
7070
"postcss-scss": "2.1.1",
@@ -145,7 +145,7 @@
145145
"lint:eslint": "cross-env EFF_NO_LINK_RULES=true eslint . --format friendly",
146146
"lint:changelog": "node ./scripts/lint-changelog.js",
147147
"lint:prettier": "prettier . \"!test*\" --check",
148-
"lint:dist": "eslint --no-eslintrc --no-ignore --env=es6,browser --parser-options=ecmaVersion:2016 \"dist/!(bin-prettier|index|third-party).js\"",
148+
"lint:dist": "eslint --no-eslintrc --no-ignore --env=es6,browser --parser-options=ecmaVersion:2017 \"dist/!(bin-prettier|index|third-party).js\"",
149149
"lint:spellcheck": "cspell \"**/*\" \".github/**/*\"",
150150
"lint:deps": "node ./scripts/check-deps.js",
151151
"fix": "run-s fix:eslint fix:prettier",

src/language-css/parser-postcss.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,57 @@ function parseNestedCSS(node, options) {
300300
node.raws = {};
301301
}
302302

303+
// Custom properties looks like declarations
304+
if (
305+
options.parser === "css" &&
306+
node.type === "css-decl" &&
307+
typeof node.prop === "string" &&
308+
node.prop.startsWith("--") &&
309+
typeof node.value === "string" &&
310+
node.value.startsWith("{")
311+
) {
312+
let rules;
313+
if (node.value.endsWith("}")) {
314+
const textBefore = options.originalText.slice(
315+
0,
316+
node.source.start.offset
317+
);
318+
const nodeText =
319+
"a".repeat(node.prop.length) +
320+
options.originalText.slice(
321+
node.source.start.offset + node.prop.length,
322+
node.source.end.offset + 1
323+
);
324+
const fakeContent = textBefore.replace(/[^\n]/g, " ") + nodeText;
325+
let ast;
326+
try {
327+
ast = parseCss(fakeContent, [], { ...options });
328+
} catch (_) {
329+
// noop
330+
}
331+
if (
332+
ast &&
333+
ast.nodes &&
334+
ast.nodes.length === 1 &&
335+
ast.nodes[0].type === "css-rule"
336+
) {
337+
rules = ast.nodes[0].nodes;
338+
}
339+
}
340+
if (rules) {
341+
node.value = {
342+
type: "css-rule",
343+
nodes: rules,
344+
};
345+
} else {
346+
node.value = {
347+
type: "value-unknown",
348+
value: node.raws.value.raw,
349+
};
350+
}
351+
return node;
352+
}
353+
303354
let selector = "";
304355

305356
if (typeof node.selector === "string") {
@@ -594,6 +645,7 @@ function parseWithParser(parse, text, options) {
594645
throw createError("(postcss) " + e.name + " " + e.reason, { start: e });
595646
}
596647

648+
options.originalText = text;
597649
result = parseNestedCSS(addTypePrefix(result, "css-"), options);
598650

599651
calculateLoc(result, text);

src/language-css/printer-postcss.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ function genericPrint(path, options, print) {
121121
node.selector.type === "selector-unknown" &&
122122
lastLineHasInlineComment(node.selector.value)
123123
? line
124-
: " ",
124+
: node.selector
125+
? " "
126+
: "",
125127
"{",
126128
node.nodes.length > 0
127129
? indent(
@@ -141,6 +143,8 @@ function genericPrint(path, options, print) {
141143
const { between: rawBetween } = node.raws;
142144
const trimmedBetween = rawBetween.trim();
143145
const isColon = trimmedBetween === ":";
146+
const isValueAllSpace =
147+
typeof node.value === "string" && /^ *$/.test(node.value);
144148

145149
let value = hasComposesNode(node)
146150
? removeLines(path.call(print, "value"))
@@ -155,7 +159,7 @@ function genericPrint(path, options, print) {
155159
insideICSSRuleNode(path) ? node.prop : maybeToLowerCase(node.prop),
156160
trimmedBetween.startsWith("//") ? " " : "",
157161
trimmedBetween,
158-
node.extend ? "" : " ",
162+
node.extend || isValueAllSpace ? "" : " ",
159163
options.parser === "less" && node.extend && node.selector
160164
? concat(["extend(", path.call(print, "selector"), ")"])
161165
: "",

tests/css/comments/__snapshots__/jsfmt.spec.js.snap

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,44 @@ printWidth: 80
304304
================================================================================
305305
`;
306306

307+
exports[`custom-properties.css format 1`] = `
308+
====================================options=====================================
309+
parsers: ["css"]
310+
printWidth: 80
311+
| printWidth
312+
=====================================input======================================
313+
/* comment 1 */
314+
:root {
315+
/* comment 2 */
316+
--prop : {
317+
/* comment 3 */
318+
color/* comment 4 */: /* comment 5 */#fff/* comment 6 */;/* comment 7 */
319+
/* comment 8 */
320+
font-size: 12px;
321+
/* comment 9 */
322+
};
323+
/* comment 10 */
324+
}
325+
/* comment 11 */
326+
327+
=====================================output=====================================
328+
/* comment 1 */
329+
:root {
330+
/* comment 2 */
331+
--prop: {
332+
/* comment 3 */
333+
color/* comment 4 */: /* comment 5 */ #fff /* comment 6 */; /* comment 7 */
334+
/* comment 8 */
335+
font-size: 12px;
336+
/* comment 9 */
337+
};
338+
/* comment 10 */
339+
}
340+
/* comment 11 */
341+
342+
================================================================================
343+
`;
344+
307345
exports[`declaration.css format 1`] = `
308346
====================================options=====================================
309347
parsers: ["css"]
@@ -887,11 +925,11 @@ article /* comment 168 */ :--heading /* comment 169 */ + /* comment 170 */ p /*
887925
/* custom properties set & @apply rule */
888926
:root {
889927
/* comments 192 */
890-
--centered /* comments 193 */ : /* comments 194 */ {
928+
--centered/* comments 193 */ : /* comments 194 */ {
891929
display: flex;
892930
align-items: center;
893931
justify-content: center;
894-
}
932+
};
895933
}
896934
897935
================================================================================
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* comment 1 */
2+
:root {
3+
/* comment 2 */
4+
--prop : {
5+
/* comment 3 */
6+
color/* comment 4 */: /* comment 5 */#fff/* comment 6 */;/* comment 7 */
7+
/* comment 8 */
8+
font-size: 12px;
9+
/* comment 9 */
10+
};
11+
/* comment 10 */
12+
}
13+
/* comment 11 */
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`empty-props.css format 1`] = `
4+
====================================options=====================================
5+
parsers: ["css"]
6+
printWidth: 80
7+
| printWidth
8+
=====================================input======================================
9+
:root {
10+
--empty:;
11+
--one-space: ;
12+
--two-space: ;
13+
--many-space: ;
14+
}
15+
16+
=====================================output=====================================
17+
:root {
18+
--empty:;
19+
--one-space: ;
20+
--two-space: ;
21+
--many-space: ;
22+
}
23+
24+
================================================================================
25+
`;
26+
27+
exports[`test.css format 1`] = `
28+
====================================options=====================================
29+
parsers: ["css"]
30+
printWidth: 80
31+
| printWidth
32+
=====================================input======================================
33+
/*
34+
This test is copied from \`postcss@8\` release note
35+
36+
https://github.com/postcss/postcss/releases/tag/8.0.0
37+
*/
38+
39+
:root {
40+
--empty: ;
41+
--JSON: [1, "2", {"three": {"a":1}}, [4]];
42+
--javascript: function(rule) { console.log(rule) };
43+
}
44+
45+
@supports (--element(".minwidth", { "minWidth": 300 })) {
46+
[--self] {
47+
background: greenyellow;
48+
}
49+
}
50+
51+
=====================================output=====================================
52+
/*
53+
This test is copied from \`postcss@8\` release note
54+
55+
https://github.com/postcss/postcss/releases/tag/8.0.0
56+
*/
57+
58+
:root {
59+
--empty: ;
60+
--JSON: [1, "2", {"three": {"a": 1}}, [4]];
61+
--javascript: function(rule) {console.log(rule)};
62+
}
63+
64+
@supports (--element(".minwidth", {"minWidth": 300})) {
65+
[--self] {
66+
background: greenyellow;
67+
}
68+
}
69+
70+
================================================================================
71+
`;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
:root {
2+
--empty:;
3+
--one-space: ;
4+
--two-space: ;
5+
--many-space: ;
6+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
run_spec(__dirname, ["css"]);

0 commit comments

Comments
 (0)