Initial CSS support (#1636)

I wanted to see how hard it would be to add support for CSS inside of prettier. Turns out, it's not that hard. I spent a few hours printing post-css values and getting all the stylefmt unit tests to not throw.
master
Christopher Chedeau 2017-05-24 10:52:12 -07:00 committed by GitHub
parent 0adeadb16e
commit 78ba808322
146 changed files with 2429 additions and 208 deletions

2
.gitignore vendored
View File

@ -2,4 +2,6 @@
npm-debug.log
/errors
/test.js
/test.ts
/test.css
/.vscode

View File

@ -90,7 +90,12 @@ function getParserOption() {
return "flow";
}
if (value === "flow" || value === "babylon" || value === "typescript") {
if (
value === "flow" ||
value === "babylon" ||
value === "typescript" ||
value === "postcss"
) {
return value;
}

View File

@ -29,6 +29,10 @@ function attachComments(text, ast, opts) {
}
function ensureAllCommentsPrinted(astComments) {
if (!astComments) {
return;
}
for (let i = 0; i < astComments.length; ++i) {
if (astComments[i].value.trim() === "prettier-ignore") {
// If there's a prettier-ignore, we're not printing that sub-tree so we

View File

@ -28,6 +28,11 @@
"eslint-plugin-prettier": "^2.1.1",
"jest": "20.0.0",
"mkdirp": "^0.5.1",
"postcss": "^6.0.1",
"postcss-less": "^1.0.0",
"postcss-media-query-parser": "^0.2.3",
"postcss-selector-parser": "^2.2.3",
"postcss-values-parser": "^1.2.1",
"prettier": "^1.3.1",
"rimraf": "^2.6.1",
"rollup": "0.41.1",

View File

@ -42,11 +42,25 @@ function massageAST(ast) {
"start",
"end",
"tokens",
"flags"
"flags",
"raws",
"sourceIndex",
"id",
"source",
"before",
"after"
].forEach(name => {
delete newObj[name];
});
if (
ast.type === "media-query" ||
ast.type === "media-query-list" ||
ast.type === "media-feature-expression"
) {
delete newObj.value;
}
// We convert <div></div> to <div />
if (ast.type === "JSXOpeningElement") {
delete newObj.selfClosing;

View File

@ -14,6 +14,8 @@ function parse(text, opts) {
parseFunction = parseWithFlow;
} else if (opts.parser === "typescript") {
parseFunction = parseWithTypeScript;
} else if (opts.parser === "postcss") {
parseFunction = parseWithPostCSS;
} else {
parseFunction = parseWithBabylon;
}
@ -138,4 +140,170 @@ function isProbablyJsx(text) {
).test(text);
}
function parseSelector(selector) {
const r = require;
const selectorParser = r("postcss-selector-parser");
let result;
selectorParser(result_ => {
result = result_;
}).process(selector);
return addTypePrefix(result, "selector-");
}
function parseValueNodes(nodes) {
let parenGroup = {
open: null,
close: null,
groups: [],
type: "paren_group"
};
const parenGroupStack = [parenGroup];
const rootParenGroup = parenGroup;
let commaGroup = {
groups: [],
type: "comma_group"
};
const commaGroupStack = [commaGroup];
for (let i = 0; i < nodes.length; ++i) {
if (nodes[i].type === "paren" && nodes[i].value === "(") {
parenGroup = {
open: nodes[i],
close: null,
groups: [],
type: "paren_group"
};
parenGroupStack.push(parenGroup);
commaGroup = {
groups: [],
type: "comma_group"
};
commaGroupStack.push(commaGroup);
} else if (nodes[i].type === "paren" && nodes[i].value === ")") {
if (commaGroup.groups.length) {
parenGroup.groups.push(commaGroup);
}
parenGroup.close = nodes[i];
if (commaGroupStack.length === 1) {
throw new Error("Unbalanced parenthesis");
}
commaGroupStack.pop();
commaGroup = commaGroupStack[commaGroupStack.length - 1];
commaGroup.groups.push(parenGroup);
parenGroupStack.pop();
parenGroup = parenGroupStack[parenGroupStack.length - 1];
} else if (nodes[i].type === "comma") {
parenGroup.groups.push(commaGroup);
commaGroup = {
groups: [],
type: "comma_group"
};
commaGroupStack[commaGroupStack.length - 1] = commaGroup;
} else {
commaGroup.groups.push(nodes[i]);
}
}
if (commaGroup.groups.length > 0) {
parenGroup.groups.push(commaGroup);
}
return rootParenGroup;
}
function addTypePrefix(node, prefix) {
if (node && typeof node === "object") {
delete node.parent;
for (const key in node) {
addTypePrefix(node[key], prefix);
if (key === "type" && typeof node[key] === "string") {
if (!node[key].startsWith(prefix)) {
node[key] = prefix + node[key];
}
}
}
}
return node;
}
function addMissingType(node) {
if (node && typeof node === "object") {
delete node.parent;
for (const key in node) {
addMissingType(node[key]);
}
if (!Array.isArray(node) && node.value && !node.type) {
node.type = "unknown";
}
}
return node;
}
function parseNestedValue(node) {
if (node && typeof node === "object") {
delete node.parent;
for (const key in node) {
parseNestedValue(node[key]);
if (key === "nodes") {
node.group = parseValueNodes(node[key]);
delete node[key];
}
}
}
return node;
}
function parseValue(value) {
const r = require;
const valueParser = r("postcss-values-parser");
const result = valueParser(value).parse();
const parsedResult = parseNestedValue(result);
return addTypePrefix(parsedResult, "value-");
}
function parseMediaQuery(value) {
const r = require;
const mediaParser = r("postcss-media-query-parser").default;
const result = addMissingType(mediaParser(value));
return addTypePrefix(result, "media-");
}
function parseNestedCSS(node) {
if (node && typeof node === "object") {
delete node.parent;
for (const key in node) {
parseNestedCSS(node[key]);
}
if (typeof node.selector === "string") {
node.selector = parseSelector(node.selector);
}
if (typeof node.value === "string") {
node.value = parseValue(node.value);
}
if (node.type === "css-atrule" && typeof node.params === "string") {
node.params = parseMediaQuery(node.params);
}
}
return node;
}
function parseWithPostCSS(text) {
const r = require;
const parser = r("postcss-less");
try {
const result = parser.parse(text);
const prefixedResult = addTypePrefix(result, "css-");
const parsedResult = parseNestedCSS(prefixedResult);
// console.log(JSON.stringify(parsedResult, null, 2));
return parsedResult;
} catch (e) {
if (typeof e.line !== "number") {
throw e;
}
throw createError(e.name + " " + e.reason, e.line, e.column);
}
}
module.exports = { parse };

View File

@ -2411,40 +2411,245 @@ function genericPrintNoParens(path, options, print, args) {
return path.call(bodyPath => {
return printStatementSequence(bodyPath, options, print);
}, "body");
case "ClassHeritage": // TODO
case "ComprehensionBlock": // TODO
case "ComprehensionExpression": // TODO
case "Glob": // TODO
case "GeneratorExpression": // TODO
case "LetStatement": // TODO
case "LetExpression": // TODO
case "GraphExpression": // TODO
// XML types that nobody cares about or needs to print. (fallthrough)
case "GraphIndexExpression":
case "XMLDefaultDeclaration":
case "XMLAnyName":
case "XMLQualifiedIdentifier":
case "XMLFunctionQualifiedIdentifier":
case "XMLAttributeSelector":
case "XMLFilterExpression":
case "XML":
case "XMLElement":
case "XMLList":
case "XMLEscape":
case "XMLText":
case "XMLStartTag":
case "XMLEndTag":
case "XMLPointTag":
case "XMLName":
case "XMLAttribute":
case "XMLCdata":
case "XMLComment":
case "XMLProcessingInstruction":
// postcss
case "css-root": {
return concat([printNodeSequence(path, options, print), hardline]);
}
case "css-comment": {
return n.raws.content;
}
case "css-rule": {
return concat([
path.call(print, "selector"),
n.nodes
? concat([
" {",
n.nodes.length > 0
? indent(
concat([hardline, printNodeSequence(path, options, print)])
)
: "",
hardline,
"}"
])
: ";"
]);
}
case "css-decl": {
return concat([
n.raws.before.trimLeft(),
n.prop,
": ",
path.call(print, "value"),
n.important ? " !important" : "",
";"
]);
}
case "css-atrule": {
return concat([
"@",
n.name,
" ",
path.call(print, "params"),
n.nodes
? concat([
" {",
indent(
concat([softline, printNodeSequence(path, options, print)])
),
softline,
"}"
])
: ";"
]);
}
case "css-import": {
return concat(["@", n.name, " ", n.importPath, ";"]);
}
// postcss-media-query-parser
case "media-query-list": {
return join(", ", path.map(print, "nodes"));
}
case "media-query": {
return join(" ", path.map(print, "nodes"));
}
case "media-type": {
return n.value;
}
case "media-feature-expression": {
if (!n.nodes) {
return n.value;
}
return concat(["(", concat(path.map(print, "nodes")), ")"]);
}
case "media-feature": {
return n.value;
}
case "media-colon": {
return concat([n.value, " "]);
}
case "media-value": {
return n.value;
}
case "media-keyword": {
return concat([" ", n.value, " "]);
}
case "media-unknown": {
return n.value;
}
// postcss-selector-parser
case "selector-root": {
return group(join(concat([",", line]), path.map(print, "nodes")));
}
case "selector-tag": {
return n.value;
}
case "selector-id": {
return concat(["#", n.value]);
}
case "selector-class": {
return concat([".", n.value]);
}
case "selector-attribute": {
return concat([
"[",
n.attribute,
n.operator ? n.operator : "",
n.value ? n.value : "",
"]"
]);
}
case "selector-combinator": {
if (n.value === "+" || n.value === ">") {
return concat([" ", n.value, " "]);
}
return n.value;
}
case "selector-universal": {
return n.value;
}
case "selector-selector": {
return concat(path.map(print, "nodes"));
}
case "selector-pseudo": {
return concat([
n.value,
n.nodes && n.nodes.length > 0
? concat(["(", concat(path.map(print, "nodes")), ")"])
: ""
]);
}
case "selector-nesting": {
return printValue(n.value);
}
// postcss-values-parser
case "value-root": {
return path.call(print, "group");
}
case "value-comma_group": {
const printed = path.map(print, "groups");
const parts = [];
for (let i = 0; i < n.groups.length; ++i) {
parts.push(printed[i]);
if (i === 0 && n.groups[i].type === "value-operator") {
continue;
}
if (i !== n.groups.length - 1) {
parts.push(line);
}
}
return group(concat(parts));
}
case "value-paren_group": {
if (!n.open) {
return join(concat([",", line]), path.map(print, "groups"));
}
return group(
concat([
n.open ? path.call(print, "open") : "",
indent(
concat([
softline,
join(concat([",", line]), path.map(print, "groups"))
])
),
softline,
n.close ? path.call(print, "close") : ""
])
);
}
case "value-value": {
return path.call(print, "group");
}
case "value-func": {
return concat([n.value, path.call(print, "group")]);
}
case "value-paren": {
return n.value;
}
case "value-number": {
return concat([n.value, n.unit]);
}
case "value-operator": {
return n.value;
}
case "value-word": {
return n.value;
}
case "value-comma": {
return concat([n.value, " "]);
}
case "value-string": {
return concat([
n.quoted ? n.raws.quote : "",
n.value,
n.quoted ? n.raws.quote : ""
]);
}
case "value-atword": {
return concat(["@", n.value]);
}
default:
throw new Error("unknown type: " + JSON.stringify(n.type));
}
}
function printValue(value) {
return value;
}
function printNodeSequence(path, options, print) {
const node = path.getValue();
const parts = [];
let i = 0;
path.map(pathChild => {
parts.push(pathChild.call(print));
if (i !== node.nodes.length - 1) {
if (
node.nodes[i + 1].type === "css-comment" &&
!util.hasNewline(
options.originalText,
util.locStart(node.nodes[i + 1]),
{ backwards: true }
)
) {
parts.push(" ");
} else {
parts.push(hardline);
if (util.isNextLineEmpty(options.originalText, pathChild.getValue())) {
parts.push(hardline);
}
}
}
i++;
}, "nodes");
return concat(parts);
}
function printStatementSequence(path, options, print) {
const printed = [];

View File

@ -208,14 +208,36 @@ function locStart(node) {
if (node.range) {
return node.range[0];
}
return node.start;
if (typeof node.start === "number") {
return node.start;
}
if (node.source) {
return lineColumnToIndex(node.source.start, node.source.input.css) - 1;
}
}
function locEnd(node) {
if (node.range) {
return node.range[1];
}
return node.end;
if (typeof node.end === "number") {
return node.end;
}
if (node.source) {
return lineColumnToIndex(node.source.end, node.source.input.css);
}
}
// Super inefficient, needs to be cached.
function lineColumnToIndex(lineColumn, text) {
let index = 0;
for (let i = 0; i < lineColumn.line - 1; ++i) {
index = text.indexOf("\n", index) + 1;
if (index === -1) {
return -1;
}
}
return index + lineColumn.column;
}
function setLocStart(node, index) {

View File

@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`atword.css 1`] = `
.test { @color: red; color: @color; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.test {
@color: red;
color: @color;
}
`;

View File

@ -0,0 +1 @@
.test { @color: red; color: @color; }

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,40 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`block.css 1`] = `
// Animation definitions cannot cross the shadow boundary,
// and thus need to be loaded directly into the atom-text-editor scope.
/* Kikoo */
/**
* Kikoo
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Animation definitions cannot cross the shadow boundary,
// and thus need to be loaded directly into the atom-text-editor scope.
/* Kikoo */
/**
* Kikoo
*/
`;
exports[`places.css 1`] = `
div {
// a
margin-left: -@leftMargin; // b
} // c
// d
div {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
div {
// a
margin-left: -@leftMargin; // b
} // c
// d
div {
}
`;

View File

@ -0,0 +1,6 @@
// Animation definitions cannot cross the shadow boundary,
// and thus need to be loaded directly into the atom-text-editor scope.
/* Kikoo */
/**
* Kikoo
*/

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,8 @@
div {
// a
margin-left: -@leftMargin; // b
} // c
// d
div {}

View File

@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`empty.css 1`] = `
.ui-syntax-color();
details[open] {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ui-syntax-color();
details[open] {
}
`;

View File

@ -0,0 +1,4 @@
.ui-syntax-color();
details[open] {
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`important.css 1`] = `
max-height: none !important;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
max-height: none !important;
`;

View File

@ -0,0 +1 @@
max-height: none !important;

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`long_rule.css 1`] = `
.nuclide-resize-sensitive-container-sensor,
.nuclide-resize-sensitive-container-expand,
.nuclide-resize-sensitive-container-shrink {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.nuclide-resize-sensitive-container-sensor,
.nuclide-resize-sensitive-container-expand,
.nuclide-resize-sensitive-container-shrink {
}
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,4 @@
.nuclide-resize-sensitive-container-sensor,
.nuclide-resize-sensitive-container-expand,
.nuclide-resize-sensitive-container-shrink {
}

View File

@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`prefix.css 1`] = `
div {
margin-left: -@leftMargin;
transform: translateY(-@offset);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
div {
margin-left: -@leftMargin;
transform: translateY(-@offset);
}
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,4 @@
div {
margin-left: -@leftMargin;
transform: translateY(-@offset);
}

View File

@ -0,0 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`pseudo_call.css 1`] = `
div:not(:last-child) {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
div:not(:last-child) {
}
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,2 @@
div:not(:last-child) {
}

View File

@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`at-apply.css 1`] = `
.toolbar{@apply --toolbar-theme ;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.toolbar {
@apply --toolbar-theme;
}
`;

View File

@ -0,0 +1,2 @@
.toolbar{@apply --toolbar-theme ;
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`at-media.css 1`] = `
@media ( max-width:600px ) {}
@media ( min-width:700px) and ( orientation: landscape){}
@media (min-width: 700px), handheld and (orientation: landscape) {}
@media not all and ( monochrome ) {}
@media ( not all ) and ( monochrome ) {}
@media ( not ( screen and ( color ) ) ) , print and ( color ){}
@media screen and ( device-aspect-ratio: 16/9 ), screen and (device-aspect-ratio:16/10 ) {}
@media ( -webkit-min-device-pixel-ratio:2),
(min--moz-device-pixel-ratio: 2 ),
(min-resolution: 2dppx),
(min-resolution: 192dpi ){}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@media (max-width: 600px) {
}
@media (min-width: 700px) and (orientation: landscape) {
}
@media (min-width: 700px), handheld and (orientation: landscape) {
}
@media not all and (monochrome) {
}
@media (not all) and (monochrome) {
}
@media (not ( screen and ( color ) )), print and (color) {
}
@media screen and (device-aspect-ratio: 16/9), screen and (device-aspect-ratio: 16/10) {
}
@media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (min-resolution: 2dppx), (min-resolution: 192dpi) {
}
`;

View File

@ -0,0 +1,12 @@
@media ( max-width:600px ) {}
@media ( min-width:700px) and ( orientation: landscape){}
@media (min-width: 700px), handheld and (orientation: landscape) {}
@media not all and ( monochrome ) {}
@media ( not all ) and ( monochrome ) {}
@media ( not ( screen and ( color ) ) ) , print and ( color ){}
@media screen and ( device-aspect-ratio: 16/9 ), screen and (device-aspect-ratio:16/10 ) {}
@media ( -webkit-min-device-pixel-ratio:2),
(min--moz-device-pixel-ratio: 2 ),
(min-resolution: 2dppx),
(min-resolution: 192dpi ){}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`attr-selector.css 1`] = `
[ data-sizes~="m:0" ] {
color:pink;
}
[ class*="test" ]{
color: silver}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ data-sizes~="m:0" ] {
color: pink;
}
[ class*="test" ] {
color: silver;
}
`;

View File

@ -0,0 +1,6 @@
[ data-sizes~="m:0" ] {
color:pink;
}
[ class*="test" ]{
color: silver}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`charset-2.css 1`] = `
@charset "utf-8" ;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@charset "utf-8";
`;

View File

@ -0,0 +1 @@
@charset "utf-8" ;

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`charset.css 1`] = `
@charset "utf-8";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@charset "utf-8";
`;

View File

@ -0,0 +1 @@
@charset "utf-8";

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`color-hex-lowercase.css 1`] = `
.foo{color:#ABCDEF}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.foo {
color: #ABCDEF;
}
`;

View File

@ -0,0 +1 @@
.foo{color:#ABCDEF}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,33 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`comment-in-rules.css 1`] = `
.class
{display: inline-block;
/* comment */
float: left;}
#id {
font-size: 12px;
/* colors */
color: pink;
background: #fff;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.class {
display: inline-block;
/* comment */
float: left;
}
#id {
font-size: 12px;
/* colors */
color: pink;
background: #fff;
}
`;

View File

@ -0,0 +1,13 @@
.class
{display: inline-block;
/* comment */
float: left;}
#id {
font-size: 12px;
/* colors */
color: pink;
background: #fff;
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,70 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`comment.css 1`] = `
/**
* comment
*/
.class
{
padding:10px; }
/*comment*/
.foo{color:red
}
/*
at rule
*/
@media only screen {
/* inner at rule comment */
.foo { display: none; }
/*
* another comment
*/
/* in a row */
.bar {
color:yellow;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* comment
*/
.class {
padding: 10px;
}
/*comment*/
.foo {
color: red;
}
/*
at rule
*/
@media only screen {
/* inner at rule comment */
.foo {
display: none;
}
/*
* another comment
*/
/* in a row */
.bar {
color: yellow;
}
}
`;

View File

@ -0,0 +1,32 @@
/**
* comment
*/
.class
{
padding:10px; }
/*comment*/
.foo{color:red
}
/*
at rule
*/
@media only screen {
/* inner at rule comment */
.foo { display: none; }
/*
* another comment
*/
/* in a row */
.bar {
color:yellow;
}
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`content.css 1`] = `
div {content: " test 1/2 "; content:' test 1+2';
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
div {
content: " test 1/2 ";
content: ' test 1+2';
}
`;

View File

@ -0,0 +1,2 @@
div {content: " test 1/2 "; content:' test 1+2';
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,106 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`cssnext-example.css 1`] = `
/* custom properties */
:root{--fontSize: 1rem;
--mainColor :#12345678;
--highlightColor:hwb(190, 35%, 20%);
}
/* custom media queries */
@custom-media
--viewport-medium(width<=50rem);
/* some var() & calc() */
body{color:var(--mainColor);
font-size:var(--fontSize);
line-height: calc(var(--fontSize) * 1.5);
padding: calc((var(--fontSize) / 2) + 1px)}
/* custom media query usage */
@media (--viewport-medium) {
body {font-size: calc(var(--fontSize) * 1.2); }
}
/* custom selectors */
@custom-selector :--heading h1,h2,h3, h4,h5,h6;
:--heading { margin-top:0 }
/* colors stuff */
a{
color:var(--highlightColor);
transition:color 1s;
}
a:hover{color :gray(255,50%) }
a:active{color : rebeccapurple }
a:any-link { color:color(var(--highlightColor) blackness(+20%)) }
/* font stuff */
h2 {font-variant-caps:small-caps;
}table{font-variant-numeric: lining-nums;
}
/* filters */
.blur{filter:blur(4px)}.sepia{
filter: sepia(.8);}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* custom properties */
:root {
--fontSize: 1rem;
--mainColor: #12345678;
--highlightColor: hwb(190, 35%, 20%);
}
/* custom media queries */
@custom-media --viewport-medium(width<=50rem);
/* some var() & calc() */
body {
color: var(--mainColor);
font-size: var(--fontSize);
line-height: calc(var(--fontSize) * 1.5);
padding: calc((var(--fontSize) / 2) + 1px);
}
/* custom media query usage */
@media (--viewport-medium) {
body {
font-size: calc(var(--fontSize) * 1.2);
}
}
/* custom selectors */
@custom-selector :--heading h1, h2, h3, h4, h5, h6;
:--heading {
margin-top: 0;
}
/* colors stuff */
a {
color: var(--highlightColor);
transition: color 1s;
}
a:hover {
color: gray(255, 50%);
}
a:active {
color: rebeccapurple;
}
a:any-link {
color: color(var(--highlightColor) blackness(+20%));
}
/* font stuff */
h2 {
font-variant-caps: small-caps;
}
table {
font-variant-numeric: lining-nums;
}
/* filters */
.blur {
filter: blur(4px);
}
.sepia {
filter: sepia(.8);
}
`;

View File

@ -0,0 +1,41 @@
/* custom properties */
:root{--fontSize: 1rem;
--mainColor :#12345678;
--highlightColor:hwb(190, 35%, 20%);
}
/* custom media queries */
@custom-media
--viewport-medium(width<=50rem);
/* some var() & calc() */
body{color:var(--mainColor);
font-size:var(--fontSize);
line-height: calc(var(--fontSize) * 1.5);
padding: calc((var(--fontSize) / 2) + 1px)}
/* custom media query usage */
@media (--viewport-medium) {
body {font-size: calc(var(--fontSize) * 1.2); }
}
/* custom selectors */
@custom-selector :--heading h1,h2,h3, h4,h5,h6;
:--heading { margin-top:0 }
/* colors stuff */
a{
color:var(--highlightColor);
transition:color 1s;
}
a:hover{color :gray(255,50%) }
a:active{color : rebeccapurple }
a:any-link { color:color(var(--highlightColor) blackness(+20%)) }
/* font stuff */
h2 {font-variant-caps:small-caps;
}table{font-variant-numeric: lining-nums;
}
/* filters */
.blur{filter:blur(4px)}.sepia{
filter: sepia(.8);}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`custom-media-queries.css 1`] = `
@custom-media --small-viewport ( max-width:30em )
;
@media ( --small-viewport ){
.rule{color:blue;}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@custom-media --small-viewport (max-width: 30em);
@media (--small-viewport) {
.rule {
color: blue;
}
}
`;

View File

@ -0,0 +1,8 @@
@custom-media --small-viewport ( max-width:30em )
;
@media ( --small-viewport ){
.rule{color:blue;}
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`custom-properties.css 1`] = `
:root{--mainColor:#123456}
a{color:var ( --mainColor ) ; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:root {
--mainColor: #123456;
}
a {
color: var (--mainColor);
}
`;

View File

@ -0,0 +1,2 @@
:root{--mainColor:#123456}
a{color:var ( --mainColor ) ; }

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`custom-selectors.css 1`] = `
@custom-selector :--button button,.button;
@custom-selector :--enter :hover,:focus ;
:--button {display: inline-block;
}:--button:--enter{
text-decoration:underline;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@custom-selector :--button button, .button;
@custom-selector :--enter :hover, :focus;
:--button {
display: inline-block;
}
:--button:--enter {
text-decoration: underline;
}
`;

View File

@ -0,0 +1,7 @@
@custom-selector :--button button,.button;
@custom-selector :--enter :hover,:focus ;
:--button {display: inline-block;
}:--button:--enter{
text-decoration:underline;
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`data-url.css 1`] = `
div {
background-image: url(data:image/png;base64,iVBORw0KGg);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
div {
background-image: url(data:image/png;base64,iVBORw0KGg);
}
`;

View File

@ -0,0 +1,3 @@
div {
background-image: url(data:image/png;base64,iVBORw0KGg);
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`font-face.css 1`] = `
@font-face {font-family:'HelveticaNeueW02-45Ligh';src:url("/fonts/pictos-web.eot");src:local("☺"),url("/fonts/pictos-web.woff") format("woff"),url("/fonts/pictos-web.ttf") format("truetype"),url("/fonts/pictos-web.svg#webfontIyfZbseF") format("svg");font-weight:normal;font-style:normal;}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@font-face {
font-family: 'HelveticaNeueW02-45Ligh';
src: url("/fonts/pictos-web.eot");
src: local("☺"),
url("/fonts/pictos-web.woff") format("woff"),
url("/fonts/pictos-web.ttf") format("truetype"),
url("/fonts/pictos-web.svg#webfontIyfZbseF") format("svg");
font-weight: normal;
font-style: normal;
}
`;

View File

@ -0,0 +1 @@
@font-face {font-family:'HelveticaNeueW02-45Ligh';src:url("/fonts/pictos-web.eot");src:local("☺"),url("/fonts/pictos-web.woff") format("woff"),url("/fonts/pictos-web.ttf") format("truetype"),url("/fonts/pictos-web.svg#webfontIyfZbseF") format("svg");font-weight:normal;font-style:normal;}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`font-shorthand.css 1`] = `
.class {
font: normal normal 24px/1 "myfont";font: normal normal normal 12px/20px myfont;
font:normal 300 0.875em/1.3 "myfont", sans-serif;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.class {
font: normal normal 24px / 1 "myfont";
font: normal normal normal 12px / 20px myfont;
font: normal 300 0.875em / 1.3 "myfont", sans-serif;
}
`;

View File

@ -0,0 +1,4 @@
.class {
font: normal normal 24px/1 "myfont";font: normal normal normal 12px/20px myfont;
font:normal 300 0.875em/1.3 "myfont", sans-serif;
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ie-hacks.css 1`] = `
* html p {font-size: 5em; }
.class {
*zoom: 1;_width: 200px;
+color:red;
*+color:red;
color:red\\9;
color:red\\0;
color:red\\9\\0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* html p {
font-size: 5em;
}
.class {
*zoom: 1;
_width: 200px;
+color: red;
*+color: red;
color: red\\9;
color: red\\0;
color: red\\9\\0;
}
`;

View File

@ -0,0 +1,9 @@
* html p {font-size: 5em; }
.class {
*zoom: 1;_width: 200px;
+color:red;
*+color:red;
color:red\9;
color:red\0;
color:red\9\0;
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`import.css 1`] = `
@import "./settings" ;
@import "./components" ;@import "./themes";
.class{float: left;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@import "./settings";
@import "./components";
@import "./themes";
.class {
float: left;
}
`;

6
tests/stylefmt/import/import.css vendored Normal file
View File

@ -0,0 +1,6 @@
@import "./settings" ;
@import "./components" ;@import "./themes";
.class{float: left;
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`important.css 1`] = `
.class {
color: red ! important;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.class {
color: red !important;
}
`;

View File

@ -0,0 +1,3 @@
.class {
color: red ! important;
}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`inline-comment.css 1`] = `
// inline comments
.class {color: red;}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// inline comments
.class {
color: red;
}
`;

View File

@ -0,0 +1,6 @@
// inline comments
.class {color: red;}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,105 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`lowercase.css 1`] = `
@charset "UTF-8";
$myVar: TRANSLATEX(0);
$myVar2: RGB(255,255,255);
$myVar3: MAROON;
$myVar4: HSLA(120,100%,50%,0.3);
$myVar5: RGBA(0,0,0,0.5);
$myVar6: HSL(120,100%,50%);
$myVar7: linear-gradient(to right, RGBA(0,0,0,0.5), RGB(255,255,255));
.class-1 {
BACKGROUND: HSL(120, 100%, 50%);
BACKGROUND: linear-gradient(to right, $myVar2, RGB(255,255,255));
COLOR: RGB(0, 0, 0);
TRANSFORM: TRANSLATE(0,0) TRANSLATEX(0) TRANSLATEY(0) TRANSLATEZ(0) TRANSLATE3D(0,0,0) MATRIX(1,1,1,1);
TRANSFORM: TRANSLATE(0,0);
TRANSFORM: TRANSLATEX(0);
TRANSFORM: TRANSLATEY(0);
TRANSFORM: TRANSLATE3D(0,0,0);
TRANSFORM: MATRIX(1,1,1,1);
transform: translateY(0) $myVar;
animation: textAnimation 0.1s;
animation: tAnimation 0.1s;
}
.class-2 {
BACKGROUND-COLOR: INDIGO;
BACKGROUND: HSLA(120, 100%, 50%, 0.3);
COLOR: RGBA(0, 0, 0, 0.5);
TRANSFORM: ROTATE(1deg) ROTATEX(1deg) ROTATEY(1deg) ROTATEZ(1deg) ROTATE3D(0,0,1,1deg) SKEW(1deg) SKEWX(1deg) SKEWY(1deg) SCALE(1, 1) SCALEX(1) SCALEY(1);
TRANSFORM: ROTATE(1deg);
TRANSFORM: ROTATEX(1deg);
TRANSFORM: ROTATEY(1deg);
TRANSFORM: ROTATEZ(1deg);
TRANSFORM: ROTATE3D(0,0,1,1deg);
TRANSFORM: SKEW(1deg);
TRANSFORM: SKEWX(1deg);
TRANSFORM: SKEWY(1deg);
TRANSFORM: SCALE(1, 1);
TRANSFORM: SCALEX(1);
TRANSFORM: SCALEY(1);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@charset "UTF-8";
$myVar: TRANSLATEX(0);
$myVar2: RGB(255, 255, 255);
$myVar3: MAROON;
$myVar4: HSLA(120, 100%, 50%, 0.3);
$myVar5: RGBA(0, 0, 0, 0.5);
$myVar6: HSL(120, 100%, 50%);
$myVar7: linear-gradient(to right, RGBA(0, 0, 0, 0.5), RGB(255, 255, 255));
.class-1 {
BACKGROUND: HSL(120, 100%, 50%);
BACKGROUND: linear-gradient(to right, $myVar2, RGB(255, 255, 255));
COLOR: RGB(0, 0, 0);
TRANSFORM: TRANSLATE(0, 0)
TRANSLATEX(0)
TRANSLATEY(0)
TRANSLATEZ(0)
TRANSLATE3D(0, 0, 0)
MATRIX(1, 1, 1, 1);
TRANSFORM: TRANSLATE(0, 0);
TRANSFORM: TRANSLATEX(0);
TRANSFORM: TRANSLATEY(0);
TRANSFORM: TRANSLATE3D(0, 0, 0);
TRANSFORM: MATRIX(1, 1, 1, 1);
transform: translateY(0) $myVar;
animation: textAnimation 0.1s;
animation: tAnimation 0.1s;
}
.class-2 {
BACKGROUND-COLOR: INDIGO;
BACKGROUND: HSLA(120, 100%, 50%, 0.3);
COLOR: RGBA(0, 0, 0, 0.5);
TRANSFORM: ROTATE(1deg)
ROTATEX(1deg)
ROTATEY(1deg)
ROTATEZ(1deg)
ROTATE3D(0, 0, 1, 1deg)
SKEW(1deg)
SKEWX(1deg)
SKEWY(1deg)
SCALE(1, 1)
SCALEX(1)
SCALEY(1);
TRANSFORM: ROTATE(1deg);
TRANSFORM: ROTATEX(1deg);
TRANSFORM: ROTATEY(1deg);
TRANSFORM: ROTATEZ(1deg);
TRANSFORM: ROTATE3D(0, 0, 1, 1deg);
TRANSFORM: SKEW(1deg);
TRANSFORM: SKEWX(1deg);
TRANSFORM: SKEWY(1deg);
TRANSFORM: SCALE(1, 1);
TRANSFORM: SCALEX(1);
TRANSFORM: SCALEY(1);
}
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,42 @@
@charset "UTF-8";
$myVar: TRANSLATEX(0);
$myVar2: RGB(255,255,255);
$myVar3: MAROON;
$myVar4: HSLA(120,100%,50%,0.3);
$myVar5: RGBA(0,0,0,0.5);
$myVar6: HSL(120,100%,50%);
$myVar7: linear-gradient(to right, RGBA(0,0,0,0.5), RGB(255,255,255));
.class-1 {
BACKGROUND: HSL(120, 100%, 50%);
BACKGROUND: linear-gradient(to right, $myVar2, RGB(255,255,255));
COLOR: RGB(0, 0, 0);
TRANSFORM: TRANSLATE(0,0) TRANSLATEX(0) TRANSLATEY(0) TRANSLATEZ(0) TRANSLATE3D(0,0,0) MATRIX(1,1,1,1);
TRANSFORM: TRANSLATE(0,0);
TRANSFORM: TRANSLATEX(0);
TRANSFORM: TRANSLATEY(0);
TRANSFORM: TRANSLATE3D(0,0,0);
TRANSFORM: MATRIX(1,1,1,1);
transform: translateY(0) $myVar;
animation: textAnimation 0.1s;
animation: tAnimation 0.1s;
}
.class-2 {
BACKGROUND-COLOR: INDIGO;
BACKGROUND: HSLA(120, 100%, 50%, 0.3);
COLOR: RGBA(0, 0, 0, 0.5);
TRANSFORM: ROTATE(1deg) ROTATEX(1deg) ROTATEY(1deg) ROTATEZ(1deg) ROTATE3D(0,0,1,1deg) SKEW(1deg) SKEWX(1deg) SKEWY(1deg) SCALE(1, 1) SCALEX(1) SCALEY(1);
TRANSFORM: ROTATE(1deg);
TRANSFORM: ROTATEX(1deg);
TRANSFORM: ROTATEY(1deg);
TRANSFORM: ROTATEZ(1deg);
TRANSFORM: ROTATE3D(0,0,1,1deg);
TRANSFORM: SKEW(1deg);
TRANSFORM: SKEWX(1deg);
TRANSFORM: SKEWY(1deg);
TRANSFORM: SCALE(1, 1);
TRANSFORM: SCALEX(1);
TRANSFORM: SCALEY(1);
}

View File

@ -0,0 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`media-indent-with-import.css 1`] = `
@import "foo";@import "bar";
.wrapper {
@media (min-width: 1025px) {
max-width: 600px;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@import "foo";
@import "bar";
.wrapper {
@media (min-width: 1025px) {
max-width: 600px;
}
}
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,6 @@
@import "foo";@import "bar";
.wrapper {
@media (min-width: 1025px) {
max-width: 600px;
}
}

View File

@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`media-indent.css 1`] = `
.foo {
@media(max-width:1000px)
{
display: none;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.foo {
@media (max-width: 1000px) {
display: none;
}
}
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "postcss" });

View File

@ -0,0 +1,6 @@
.foo {
@media(max-width:1000px)
{
display: none;
}
}

View File

@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`media-queries-ranges.css 1`] = `
@media (width >= 500px) and (width <= 1200px) {
.rule {color:red;}
}
@custom-media --only-medium-screen ( width >=500px ) and (width<= 1200px ) ;
@media ( --only-medium-screen ){
.rule{color:blue;}}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@media (width >= 500px) and (width <= 1200px) {
.rule {
color: red;
}
}
@custom-media --only-medium-screen (width >=500px) and (width<= 1200px);
@media (--only-medium-screen) {
.rule {
color: blue;
}
}
`;

Some files were not shown because too many files have changed in this diff Show More