diff --git a/package.json b/package.json index d5c4efc8..4b5c2bbb 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "postcss": "^6.0.1", "postcss-less": "^1.0.0", "postcss-media-query-parser": "^0.2.3", + "postcss-scss": "1.0.0", "postcss-selector-parser": "^2.2.3", "postcss-values-parser": "git://github.com/shellscape/postcss-values-parser.git#5e351360479116f3fe309602cdd15b0a233bc29f", "prettier": "^1.3.1", diff --git a/src/clean-ast.js b/src/clean-ast.js index 4ac950db..202eabab 100644 --- a/src/clean-ast.js +++ b/src/clean-ast.js @@ -28,7 +28,9 @@ function massageAST(ast) { const newObj = {}; for (const key in ast) { - newObj[key] = massageAST(ast[key]); + if (typeof ast[key] !== "function") { + newObj[key] = massageAST(ast[key]); + } } [ diff --git a/src/parser.js b/src/parser.js index 5cf4f0c8..75390042 100644 --- a/src/parser.js +++ b/src/parser.js @@ -306,16 +306,22 @@ function parseNestedCSS(node) { parseNestedCSS(node[key]); } if (typeof node.selector === "string") { - try { - node.selector = parseSelector( - node.raws.selector ? node.raws.selector.raw : node.selector - ); - } catch (e) { - throw createError( - e.toString(), - node.source.start.line, - node.source.start.column - 1 - ); + const selector = node.raws.selector + ? node.raws.selector.raw + : node.selector; + + if (selector.trim().endsWith(":")) { + node.selector = selector; + } else { + try { + node.selector = parseSelector(selector); + } catch (e) { + throw createError( + "(postcss-selector-parser) " + e.toString(), + node.source.start.line, + node.source.start.column - 1 + ); + } } } if (node.type && typeof node.value === "string") { @@ -325,7 +331,7 @@ function parseNestedCSS(node) { const line = +(e.toString().match(/line: ([0-9]+)/) || [1, 1])[1]; const column = +(e.toString().match(/column ([0-9]+)/) || [0, 0])[1]; throw createError( - e.toString(), + "(postcss-values-parser) " + e.toString(), node.source.start.line + line - 1, node.source.start.column + column + node.prop.length ); @@ -338,19 +344,38 @@ function parseNestedCSS(node) { return node; } -function parseWithPostCSS(text) { - const r = require; - const parser = r("postcss-less"); +function parseWithPostCSSParser(parser, text) { + let result; try { - const result = parser.parse(text); - const prefixedResult = addTypePrefix(result, "css-"); - const parsedResult = parseNestedCSS(prefixedResult); - return parsedResult; + result = parser.parse(text); } catch (e) { if (typeof e.line !== "number") { throw e; } - throw createError(e.name + " " + e.reason, e.line, e.column); + throw createError("(postcss) " + e.name + " " + e.reason, e.line, e.column); + } + const prefixedResult = addTypePrefix(result, "css-"); + const parsedResult = parseNestedCSS(prefixedResult); + return parsedResult; +} + +function parseWithPostCSS(text) { + const r = require; + const isLikelySCSS = text.match(/(\w\s*: [^}:]+|#){/); + try { + return parseWithPostCSSParser( + r(isLikelySCSS ? "postcss-scss" : "postcss-less"), + text + ); + } catch (e) { + try { + return parseWithPostCSSParser( + r(isLikelySCSS ? "postcss-less" : "postcss-scss"), + text + ); + } catch (e2) { + throw e; + } } } diff --git a/src/printer.js b/src/printer.js index 9fba943b..327e205f 100644 --- a/src/printer.js +++ b/src/printer.js @@ -2532,7 +2532,9 @@ function genericPrintNoParens(path, options, print, args) { return concat([printNodeSequence(path, options, print), hardline]); } case "css-comment": { - return n.raws.content; + return n.raws.content + ? n.raws.content + : options.originalText.slice(util.locStart(n), util.locEnd(n)); } case "css-rule": { return concat([ @@ -2558,7 +2560,16 @@ function genericPrintNoParens(path, options, print, args) { ": ", path.call(print, "value"), n.important ? " !important" : "", - ";" + n.nodes + ? concat([ + " {", + indent( + concat([softline, printNodeSequence(path, options, print)]) + ), + softline, + "}" + ]) + : ";" ]); } case "css-atrule": { diff --git a/tests/css_scss/__snapshots__/jsfmt.spec.js.snap b/tests/css_scss/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 00000000..4f66d2d7 --- /dev/null +++ b/tests/css_scss/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,36 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`scss.css 1`] = ` +@media #{$g-breakpoint-tiny} {} +.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; } +a {height: calc(#{$foo} + 1);} +div { + background: { + size: auto 60%; + position: bottom 2px left; + } +} +a { margin: 0 { left: 10px; } } +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +@media #{$g-breakpoint-tiny} { + +} +.#{$fa-css-prefix}-glass:before { + content: $fa-var-glass; +} +a { + height: calc(#{$foo} + 1); +} +div { + background: { + size: auto 60%; + position: bottom 2px left; + } +} +a { + margin: 0 { + left: 10px; + } +} + +`; diff --git a/tests/css_scss/jsfmt.spec.js b/tests/css_scss/jsfmt.spec.js new file mode 100644 index 00000000..a7d303b6 --- /dev/null +++ b/tests/css_scss/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, { parser: "postcss" }); diff --git a/tests/css_scss/scss.css b/tests/css_scss/scss.css new file mode 100644 index 00000000..c1bfa7f3 --- /dev/null +++ b/tests/css_scss/scss.css @@ -0,0 +1,10 @@ +@media #{$g-breakpoint-tiny} {} +.#{$fa-css-prefix}-glass:before { content: $fa-var-glass; } +a {height: calc(#{$foo} + 1);} +div { + background: { + size: auto 60%; + position: bottom 2px left; + } +} +a { margin: 0 { left: 10px; } } diff --git a/yarn.lock b/yarn.lock index 846faeac..2729fd10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2199,6 +2199,12 @@ postcss-media-query-parser@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" +postcss-scss@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-1.0.0.tgz#4957013097973dfd5bd9b1ad8a6dc13456a5d1ba" + dependencies: + postcss "^6.0.1" + postcss-selector-parser@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" @@ -2815,13 +2821,6 @@ typedarray@^0.0.6: lodash.unescape "4.0.1" semver "5.3.0" -"typescript-eslint-parser@git://github.com/eslint/typescript-eslint-parser.git#a3610632a8bd1ee9ad4179ed01a01b7739143bf5": - version "3.0.0" - resolved "git://github.com/eslint/typescript-eslint-parser.git#a3610632a8bd1ee9ad4179ed01a01b7739143bf5" - dependencies: - lodash.unescape "4.0.1" - semver "5.3.0" - typescript@2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.2.tgz#f0f045e196f69a72f06b25fd3bd39d01c3ce9984"