diff --git a/src/clean-ast.js b/src/clean-ast.js index 4e6901adb..17aaa7d3c 100644 --- a/src/clean-ast.js +++ b/src/clean-ast.js @@ -83,14 +83,20 @@ function massageAST(ast) { } if ( - (ast.type === "media-value" || + (ast.type === "media-feature" || + ast.type === "media-type" || + ast.type === "media-unknown" || + ast.type === "media-value" || ast.type === "selector-attribute" || + ast.type === "selector-string" || ast.type === "value-string") && newObj.value ) { - newObj.value = newObj.value - .replace(/'/g, '"') - .replace(/\\([^a-fA-F\d])/g, "$1"); + newObj.value = cleanCSSStrings(newObj.value); + } + + if (ast.type === "css-import" && newObj.importPath) { + newObj.importPath = cleanCSSStrings(newObj.importPath); } // (TypeScript) Ignore `static` in `constructor(static p) {}` @@ -185,4 +191,8 @@ function massageAST(ast) { return ast; } +function cleanCSSStrings(value) { + return value.replace(/'/g, '"').replace(/\\([^a-fA-F\d])/g, "$1"); +} + module.exports = { cleanAST, massageAST }; diff --git a/src/printer-postcss.js b/src/printer-postcss.js index cb7c7c036..ba093eefc 100644 --- a/src/printer-postcss.js +++ b/src/printer-postcss.js @@ -128,7 +128,7 @@ function genericPrint(path, options, print) { n.name, " ", n.directives ? concat([n.directives, " "]) : "", - n.importPath, + adjustStrings(n.importPath, options), ";" ]); } @@ -148,7 +148,14 @@ function genericPrint(path, options, print) { return join(" ", path.map(print, "nodes")); } case "media-type": { - return n.value; + const parent = path.getParentNode(2); + if ( + parent.type === "css-atrule" && + parent.name.toLowerCase() === "charset" + ) { + return n.value; + } + return adjustStrings(n.value, options); } case "media-feature-expression": { if (!n.nodes) { @@ -157,7 +164,7 @@ function genericPrint(path, options, print) { return concat(["(", concat(path.map(print, "nodes")), ")"]); } case "media-feature": { - return n.value.replace(/ +/g, " "); + return adjustStrings(n.value.replace(/ +/g, " "), options); } case "media-colon": { return concat([n.value, " "]); @@ -172,7 +179,7 @@ function genericPrint(path, options, print) { return n.value; } case "media-unknown": { - return n.value; + return adjustStrings(n.value, options); } // postcss-selector-parser case "selector-root": { @@ -182,7 +189,7 @@ function genericPrint(path, options, print) { return n.value; } case "selector-string": { - return n.value; + return adjustStrings(n.value, options); } case "selector-tag": { return n.value; diff --git a/tests/css_quotes/__snapshots__/jsfmt.spec.js.snap b/tests/css_quotes/__snapshots__/jsfmt.spec.js.snap index e5ce5163a..55f554466 100644 --- a/tests/css_quotes/__snapshots__/jsfmt.spec.js.snap +++ b/tests/css_quotes/__snapshots__/jsfmt.spec.js.snap @@ -1,6 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`quotes.css 1`] = ` +@charset "UTF-8"; +/* @charset must always have double quotes: https://www.w3.org/TR/css-syntax-3/#determine-the-fallback-encoding */ +/* Also, it has to be the very first thing in the file, but here are some more tests anyway: */ +@CHARSET "UTF-8"; /* Case insensitive for "consistency". */ +@charset 'UTF-8'; /* Single quotes are invalid here. Keep them since we don't know what the user is doing. */ + @supports (content: one "two" three 'four') { a[href="foo" y], abbr[title^='It\\'s a trap!'], @@ -68,7 +74,25 @@ exports[`quotes.css 1`] = ` content: '\\Abc4 foo \\n' /* 'comment' */ '\\end'; } } + +@import "file.css"; + +@foo "one"; +@foo 'one'; +@foo "one" two 'three'; +@foo ("one"); +@foo ('one'); +@foo ("one" two 'three'); + +one "two" three {} +one 'two' three {} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +@charset "UTF-8"; +/* @charset must always have double quotes: https://www.w3.org/TR/css-syntax-3/#determine-the-fallback-encoding */ +/* Also, it has to be the very first thing in the file, but here are some more tests anyway: */ +@CHARSET "UTF-8"; /* Case insensitive for "consistency". */ +@charset 'UTF-8'; /* Single quotes are invalid here. Keep them since we don't know what the user is doing. */ + @supports (content: one "two" three "four") { a[href="foo" y], abbr[title^="It's a trap!"], @@ -137,9 +161,29 @@ exports[`quotes.css 1`] = ` } } +@import "file.css"; + +@foo "one"; +@foo "one"; +@foo "one" two "three"; +@foo ("one"); +@foo ("one"); +@foo ("one" two "three"); + +one "two" three { +} +one "two" three { +} + `; exports[`quotes.css 2`] = ` +@charset "UTF-8"; +/* @charset must always have double quotes: https://www.w3.org/TR/css-syntax-3/#determine-the-fallback-encoding */ +/* Also, it has to be the very first thing in the file, but here are some more tests anyway: */ +@CHARSET "UTF-8"; /* Case insensitive for "consistency". */ +@charset 'UTF-8'; /* Single quotes are invalid here. Keep them since we don't know what the user is doing. */ + @supports (content: one "two" three 'four') { a[href="foo" y], abbr[title^='It\\'s a trap!'], @@ -207,7 +251,25 @@ exports[`quotes.css 2`] = ` content: '\\Abc4 foo \\n' /* 'comment' */ '\\end'; } } + +@import "file.css"; + +@foo "one"; +@foo 'one'; +@foo "one" two 'three'; +@foo ("one"); +@foo ('one'); +@foo ("one" two 'three'); + +one "two" three {} +one 'two' three {} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +@charset "UTF-8"; +/* @charset must always have double quotes: https://www.w3.org/TR/css-syntax-3/#determine-the-fallback-encoding */ +/* Also, it has to be the very first thing in the file, but here are some more tests anyway: */ +@CHARSET "UTF-8"; /* Case insensitive for "consistency". */ +@charset 'UTF-8'; /* Single quotes are invalid here. Keep them since we don't know what the user is doing. */ + @supports (content: one 'two' three 'four') { a[href='foo' y], abbr[title^="It's a trap!"], @@ -276,4 +338,18 @@ exports[`quotes.css 2`] = ` } } +@import 'file.css'; + +@foo 'one'; +@foo 'one'; +@foo 'one' two 'three'; +@foo ('one'); +@foo ('one'); +@foo ('one' two 'three'); + +one 'two' three { +} +one 'two' three { +} + `; diff --git a/tests/css_quotes/quotes.css b/tests/css_quotes/quotes.css index 6bd51a39f..bef61658c 100644 --- a/tests/css_quotes/quotes.css +++ b/tests/css_quotes/quotes.css @@ -1,3 +1,9 @@ +@charset "UTF-8"; +/* @charset must always have double quotes: https://www.w3.org/TR/css-syntax-3/#determine-the-fallback-encoding */ +/* Also, it has to be the very first thing in the file, but here are some more tests anyway: */ +@CHARSET "UTF-8"; /* Case insensitive for "consistency". */ +@charset 'UTF-8'; /* Single quotes are invalid here. Keep them since we don't know what the user is doing. */ + @supports (content: one "two" three 'four') { a[href="foo" y], abbr[title^='It\'s a trap!'], @@ -65,3 +71,15 @@ content: '\Abc4 foo \n' /* 'comment' */ '\end'; } } + +@import "file.css"; + +@foo "one"; +@foo 'one'; +@foo "one" two 'three'; +@foo ("one"); +@foo ('one'); +@foo ("one" two 'three'); + +one "two" three {} +one 'two' three {}