2017-06-06 00:28:38 +10:00
|
|
|
"use strict";
|
|
|
|
|
|
2017-12-30 21:30:09 +11:00
|
|
|
const clean = require("./clean");
|
2017-12-26 12:23:50 +11:00
|
|
|
const util = require("../common/util");
|
|
|
|
|
const doc = require("../doc");
|
|
|
|
|
const docBuilders = doc.builders;
|
2017-06-06 00:28:38 +10:00
|
|
|
const concat = docBuilders.concat;
|
|
|
|
|
const join = docBuilders.join;
|
|
|
|
|
const line = docBuilders.line;
|
|
|
|
|
const hardline = docBuilders.hardline;
|
|
|
|
|
const softline = docBuilders.softline;
|
|
|
|
|
const group = docBuilders.group;
|
2017-06-21 15:13:51 -07:00
|
|
|
const fill = docBuilders.fill;
|
2017-06-06 00:28:38 +10:00
|
|
|
const indent = docBuilders.indent;
|
2017-12-31 12:34:37 +08:00
|
|
|
const printerOptions = require("./options");
|
2017-06-06 00:28:38 +10:00
|
|
|
|
2017-12-26 12:23:50 +11:00
|
|
|
const removeLines = doc.utils.removeLines;
|
2017-06-19 11:41:10 +02:00
|
|
|
|
2017-06-06 00:28:38 +10:00
|
|
|
function genericPrint(path, options, print) {
|
|
|
|
|
const n = path.getValue();
|
|
|
|
|
|
2017-09-03 22:40:44 +02:00
|
|
|
/* istanbul ignore if */
|
2017-06-06 00:28:38 +10:00
|
|
|
if (!n) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeof n === "string") {
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (n.type) {
|
2018-01-24 19:44:09 +03:00
|
|
|
case "css-comment-yaml":
|
|
|
|
|
return n.value;
|
2017-06-06 00:28:38 +10:00
|
|
|
case "css-root": {
|
2018-01-12 00:05:57 +03:00
|
|
|
const nodes = printNodeSequence(path, options, print);
|
|
|
|
|
|
|
|
|
|
if (nodes.parts.length) {
|
|
|
|
|
return concat([nodes, hardline]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nodes;
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "css-comment": {
|
|
|
|
|
if (n.raws.content) {
|
|
|
|
|
return n.raws.content;
|
|
|
|
|
}
|
|
|
|
|
const text = options.originalText.slice(util.locStart(n), util.locEnd(n));
|
|
|
|
|
const rawText = n.raws.text || n.text;
|
|
|
|
|
// Workaround a bug where the location is off.
|
|
|
|
|
// https://github.com/postcss/postcss-scss/issues/63
|
|
|
|
|
if (text.indexOf(rawText) === -1) {
|
|
|
|
|
if (n.raws.inline) {
|
|
|
|
|
return concat(["// ", rawText]);
|
|
|
|
|
}
|
|
|
|
|
return concat(["/* ", rawText, " */"]);
|
|
|
|
|
}
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
case "css-rule": {
|
2018-01-30 14:16:07 +03:00
|
|
|
// If a Less file ends up being parsed with the SCSS parser, Less
|
|
|
|
|
// variable declarations will be parsed as atrules with names ending
|
|
|
|
|
// with a colon, so keep the original case then.
|
|
|
|
|
const isDetachedRulesetDeclaration =
|
|
|
|
|
n.selector &&
|
|
|
|
|
typeof n.selector === "string" &&
|
|
|
|
|
n.selector.startsWith("@") &&
|
|
|
|
|
n.selector.endsWith(":");
|
2017-06-06 00:28:38 +10:00
|
|
|
return concat([
|
|
|
|
|
path.call(print, "selector"),
|
|
|
|
|
n.important ? " !important" : "",
|
|
|
|
|
n.nodes
|
|
|
|
|
? concat([
|
|
|
|
|
" {",
|
|
|
|
|
n.nodes.length > 0
|
|
|
|
|
? indent(
|
|
|
|
|
concat([hardline, printNodeSequence(path, options, print)])
|
|
|
|
|
)
|
|
|
|
|
: "",
|
|
|
|
|
hardline,
|
2018-01-30 14:16:07 +03:00
|
|
|
"}",
|
|
|
|
|
isDetachedRulesetDeclaration ? ";" : ""
|
2017-06-06 00:28:38 +10:00
|
|
|
])
|
|
|
|
|
: ";"
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
case "css-decl": {
|
2017-06-07 12:40:36 -07:00
|
|
|
// When the following less construct &:extend(.foo); is parsed with scss,
|
|
|
|
|
// it will put a space after `:` and break it. Ideally we should parse
|
|
|
|
|
// less files with less, but we can hardcode this to work with scss as
|
|
|
|
|
// well.
|
|
|
|
|
const isValueExtend =
|
|
|
|
|
n.value.type === "value-root" &&
|
|
|
|
|
n.value.group.type === "value-value" &&
|
|
|
|
|
n.value.group.group.type === "value-func" &&
|
|
|
|
|
n.value.group.group.value === "extend";
|
2017-06-19 11:41:10 +02:00
|
|
|
const isComposed =
|
|
|
|
|
n.value.type === "value-root" &&
|
|
|
|
|
n.value.group.type === "value-value" &&
|
|
|
|
|
n.prop === "composes";
|
2017-06-07 12:40:36 -07:00
|
|
|
|
2017-06-06 00:28:38 +10:00
|
|
|
return concat([
|
|
|
|
|
n.raws.before.replace(/[\s;]/g, ""),
|
2017-09-14 21:55:11 +02:00
|
|
|
maybeToLowerCase(n.prop),
|
2017-06-07 12:40:36 -07:00
|
|
|
":",
|
|
|
|
|
isValueExtend ? "" : " ",
|
2017-06-19 11:41:10 +02:00
|
|
|
isComposed
|
|
|
|
|
? removeLines(path.call(print, "value"))
|
|
|
|
|
: path.call(print, "value"),
|
2017-06-06 00:28:38 +10:00
|
|
|
n.important ? " !important" : "",
|
2018-01-12 14:12:02 +03:00
|
|
|
n.default ? " !default" : "",
|
2018-01-30 17:53:37 +03:00
|
|
|
n.global ? " !global" : "",
|
2017-06-06 00:28:38 +10:00
|
|
|
n.nodes
|
|
|
|
|
? concat([
|
|
|
|
|
" {",
|
|
|
|
|
indent(
|
|
|
|
|
concat([softline, printNodeSequence(path, options, print)])
|
|
|
|
|
),
|
|
|
|
|
softline,
|
|
|
|
|
"}"
|
|
|
|
|
])
|
|
|
|
|
: ";"
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
case "css-atrule": {
|
|
|
|
|
const hasParams =
|
|
|
|
|
n.params &&
|
|
|
|
|
!(n.params.type === "media-query-list" && n.params.value === "");
|
2017-09-03 21:22:28 +02:00
|
|
|
const isDetachedRulesetCall =
|
|
|
|
|
hasParams &&
|
|
|
|
|
n.params.type === "media-query-list" &&
|
|
|
|
|
/^\(\s*\)$/.test(n.params.value);
|
2017-06-06 00:28:38 +10:00
|
|
|
return concat([
|
|
|
|
|
"@",
|
2017-09-15 19:48:16 +02:00
|
|
|
// If a Less file ends up being parsed with the SCSS parser, Less
|
|
|
|
|
// variable declarations will be parsed as atrules with names ending
|
|
|
|
|
// with a colon, so keep the original case then.
|
|
|
|
|
isDetachedRulesetCall || n.name.endsWith(":")
|
|
|
|
|
? n.name
|
|
|
|
|
: maybeToLowerCase(n.name),
|
2017-09-03 21:22:28 +02:00
|
|
|
hasParams
|
|
|
|
|
? concat([
|
|
|
|
|
isDetachedRulesetCall ? "" : " ",
|
|
|
|
|
path.call(print, "params")
|
|
|
|
|
])
|
|
|
|
|
: "",
|
2017-06-06 00:28:38 +10:00
|
|
|
n.nodes
|
|
|
|
|
? concat([
|
|
|
|
|
" {",
|
|
|
|
|
indent(
|
|
|
|
|
concat([
|
|
|
|
|
n.nodes.length > 0 ? softline : "",
|
|
|
|
|
printNodeSequence(path, options, print)
|
|
|
|
|
])
|
|
|
|
|
),
|
|
|
|
|
softline,
|
|
|
|
|
"}"
|
|
|
|
|
])
|
|
|
|
|
: ";"
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
case "css-import": {
|
|
|
|
|
return concat([
|
|
|
|
|
"@",
|
2017-09-03 21:22:28 +02:00
|
|
|
maybeToLowerCase(n.name),
|
2017-06-06 00:28:38 +10:00
|
|
|
" ",
|
|
|
|
|
n.directives ? concat([n.directives, " "]) : "",
|
2017-08-17 08:59:56 +02:00
|
|
|
adjustStrings(n.importPath, options),
|
2017-08-21 21:28:22 +02:00
|
|
|
n.nodes.length > 0
|
|
|
|
|
? concat([
|
|
|
|
|
" {",
|
|
|
|
|
indent(
|
|
|
|
|
concat([softline, printNodeSequence(path, options, print)])
|
|
|
|
|
),
|
|
|
|
|
softline,
|
|
|
|
|
"}"
|
|
|
|
|
])
|
|
|
|
|
: ";"
|
2017-06-06 00:28:38 +10:00
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
// postcss-media-query-parser
|
|
|
|
|
case "media-query-list": {
|
|
|
|
|
const parts = [];
|
|
|
|
|
path.each(childPath => {
|
|
|
|
|
const node = childPath.getValue();
|
|
|
|
|
if (node.type === "media-query" && node.value === "") {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
parts.push(childPath.call(print));
|
|
|
|
|
}, "nodes");
|
2018-01-20 02:56:28 +03:00
|
|
|
|
|
|
|
|
return group(indent(join(line, parts)));
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-query": {
|
2018-01-20 02:56:28 +03:00
|
|
|
const parent = path.getParentNode();
|
|
|
|
|
const isLastNode = parent.nodes.indexOf(n) === parent.nodes.length - 1;
|
|
|
|
|
|
|
|
|
|
return concat([
|
|
|
|
|
join(" ", path.map(print, "nodes")),
|
|
|
|
|
isLastNode ? "" : ","
|
|
|
|
|
]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-type": {
|
2017-08-17 08:59:56 +02:00
|
|
|
const parent = path.getParentNode(2);
|
|
|
|
|
if (
|
|
|
|
|
parent.type === "css-atrule" &&
|
|
|
|
|
parent.name.toLowerCase() === "charset"
|
|
|
|
|
) {
|
|
|
|
|
return n.value;
|
|
|
|
|
}
|
2017-09-03 21:22:28 +02:00
|
|
|
return adjustNumbers(adjustStrings(n.value, options));
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-feature-expression": {
|
|
|
|
|
if (!n.nodes) {
|
|
|
|
|
return n.value;
|
|
|
|
|
}
|
|
|
|
|
return concat(["(", concat(path.map(print, "nodes")), ")"]);
|
|
|
|
|
}
|
|
|
|
|
case "media-feature": {
|
2017-09-03 21:22:28 +02:00
|
|
|
return maybeToLowerCase(
|
|
|
|
|
adjustStrings(n.value.replace(/ +/g, " "), options)
|
|
|
|
|
);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-colon": {
|
|
|
|
|
return concat([n.value, " "]);
|
|
|
|
|
}
|
|
|
|
|
case "media-value": {
|
2017-08-15 17:25:57 +02:00
|
|
|
return adjustNumbers(adjustStrings(n.value, options));
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-keyword": {
|
2017-09-14 14:04:04 +02:00
|
|
|
return adjustStrings(n.value, options);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-url": {
|
2018-01-23 23:33:19 +03:00
|
|
|
return adjustStrings(
|
|
|
|
|
n.value.replace(/^url\(\s+/gi, "url(").replace(/\s+\)$/gi, ")"),
|
|
|
|
|
options
|
|
|
|
|
);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-unknown": {
|
2017-08-17 08:59:56 +02:00
|
|
|
return adjustStrings(n.value, options);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
// postcss-selector-parser
|
2017-09-03 21:22:28 +02:00
|
|
|
case "selector-root-invalid": {
|
|
|
|
|
// This is likely a SCSS nested property: `background: { color: red; }`.
|
|
|
|
|
return adjustNumbers(adjustStrings(maybeToLowerCase(n.value), options));
|
|
|
|
|
}
|
2017-06-06 00:28:38 +10:00
|
|
|
case "selector-root": {
|
2017-06-08 16:46:24 +02:00
|
|
|
return group(join(concat([",", hardline]), path.map(print, "nodes")));
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-comment": {
|
|
|
|
|
return n.value;
|
|
|
|
|
}
|
|
|
|
|
case "selector-string": {
|
2017-08-17 08:59:56 +02:00
|
|
|
return adjustStrings(n.value, options);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-tag": {
|
2017-11-27 13:28:03 +01:00
|
|
|
return adjustNumbers(n.value);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-id": {
|
|
|
|
|
return concat(["#", n.value]);
|
|
|
|
|
}
|
|
|
|
|
case "selector-class": {
|
2017-09-03 21:22:28 +02:00
|
|
|
return concat([".", adjustNumbers(adjustStrings(n.value, options))]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-attribute": {
|
|
|
|
|
return concat([
|
|
|
|
|
"[",
|
2018-01-26 13:00:20 +03:00
|
|
|
n.namespace
|
|
|
|
|
? concat([n.namespace === true ? "" : n.namespace.trim(), "|"])
|
|
|
|
|
: "",
|
2018-01-23 18:30:20 +03:00
|
|
|
n.attribute.trim(),
|
2017-06-06 00:28:38 +10:00
|
|
|
n.operator ? n.operator : "",
|
2017-08-22 18:45:15 +02:00
|
|
|
n.value
|
2018-01-23 18:30:20 +03:00
|
|
|
? quoteAttributeValue(adjustStrings(n.value.trim(), options), options)
|
2017-08-22 18:45:15 +02:00
|
|
|
: "",
|
2017-06-06 00:28:38 +10:00
|
|
|
n.insensitive ? " i" : "",
|
|
|
|
|
"]"
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
case "selector-combinator": {
|
2018-01-24 14:53:22 +03:00
|
|
|
if (
|
|
|
|
|
n.value === "+" ||
|
|
|
|
|
n.value === ">" ||
|
|
|
|
|
n.value === "~" ||
|
|
|
|
|
n.value === ">>>"
|
|
|
|
|
) {
|
2017-06-06 00:28:38 +10:00
|
|
|
const parent = path.getParentNode();
|
2017-07-08 14:07:39 +02:00
|
|
|
const leading =
|
|
|
|
|
parent.type === "selector-selector" && parent.nodes[0] === n
|
|
|
|
|
? ""
|
|
|
|
|
: line;
|
2018-01-13 18:17:29 +03:00
|
|
|
const isLastNode = parent.nodes.length - 1 === parent.nodes.indexOf(n);
|
|
|
|
|
return concat([leading, n.value, isLastNode ? "" : " "]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
2017-09-03 21:22:28 +02:00
|
|
|
const leading = n.value.trim().startsWith("(") ? line : "";
|
|
|
|
|
const value =
|
|
|
|
|
adjustNumbers(adjustStrings(n.value.trim(), options)) || line;
|
|
|
|
|
return concat([leading, value]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-universal": {
|
|
|
|
|
return n.value;
|
|
|
|
|
}
|
|
|
|
|
case "selector-selector": {
|
|
|
|
|
return group(indent(concat(path.map(print, "nodes"))));
|
|
|
|
|
}
|
|
|
|
|
case "selector-pseudo": {
|
|
|
|
|
return concat([
|
2017-09-03 21:22:28 +02:00
|
|
|
maybeToLowerCase(n.value),
|
2017-06-06 00:28:38 +10:00
|
|
|
n.nodes && n.nodes.length > 0
|
|
|
|
|
? concat(["(", join(", ", 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": {
|
2017-11-01 15:21:59 -02:00
|
|
|
const parent = path.getParentNode();
|
|
|
|
|
let declParent;
|
|
|
|
|
let i = 0;
|
|
|
|
|
do {
|
|
|
|
|
declParent = path.getParentNode(i++);
|
|
|
|
|
} while (declParent && declParent.type !== "css-decl");
|
|
|
|
|
|
|
|
|
|
const declParentProp = declParent.prop.toLowerCase();
|
|
|
|
|
const isGridValue =
|
|
|
|
|
parent.type === "value-value" &&
|
|
|
|
|
(declParentProp === "grid" ||
|
|
|
|
|
declParentProp.startsWith("grid-template"));
|
|
|
|
|
|
2017-06-06 00:28:38 +10:00
|
|
|
const printed = path.map(print, "groups");
|
|
|
|
|
const parts = [];
|
2017-11-01 15:21:59 -02:00
|
|
|
let didBreak = false;
|
2017-06-06 00:28:38 +10:00
|
|
|
for (let i = 0; i < n.groups.length; ++i) {
|
|
|
|
|
parts.push(printed[i]);
|
|
|
|
|
if (
|
|
|
|
|
i !== n.groups.length - 1 &&
|
|
|
|
|
n.groups[i + 1].raws &&
|
|
|
|
|
n.groups[i + 1].raws.before !== ""
|
|
|
|
|
) {
|
2017-11-01 15:21:59 -02:00
|
|
|
if (isGridValue) {
|
|
|
|
|
if (
|
|
|
|
|
n.groups[i].source.start.line !==
|
|
|
|
|
n.groups[i + 1].source.start.line
|
|
|
|
|
) {
|
|
|
|
|
parts.push(hardline);
|
|
|
|
|
didBreak = true;
|
|
|
|
|
} else {
|
|
|
|
|
parts.push(" ");
|
|
|
|
|
}
|
|
|
|
|
} else if (
|
2017-06-06 00:28:38 +10:00
|
|
|
n.groups[i + 1].type === "value-operator" &&
|
|
|
|
|
["+", "-", "/", "*", "%"].indexOf(n.groups[i + 1].value) !== -1
|
|
|
|
|
) {
|
|
|
|
|
parts.push(" ");
|
2018-01-24 18:48:54 +03:00
|
|
|
} else if (n.groups[i + 1].value !== ":") {
|
2017-06-06 00:28:38 +10:00
|
|
|
parts.push(line);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-01 15:21:59 -02:00
|
|
|
if (didBreak) {
|
|
|
|
|
parts.unshift(hardline);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-21 15:13:51 -07:00
|
|
|
return group(indent(fill(parts)));
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-paren_group": {
|
|
|
|
|
const parent = path.getParentNode();
|
|
|
|
|
const isURLCall =
|
|
|
|
|
parent && parent.type === "value-func" && parent.value === "url";
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
isURLCall &&
|
|
|
|
|
(n.groups.length === 1 ||
|
|
|
|
|
(n.groups.length > 0 &&
|
|
|
|
|
n.groups[0].type === "value-comma_group" &&
|
|
|
|
|
n.groups[0].groups.length > 0 &&
|
|
|
|
|
n.groups[0].groups[0].type === "value-word" &&
|
|
|
|
|
n.groups[0].groups[0].value === "data"))
|
|
|
|
|
) {
|
|
|
|
|
return concat([
|
|
|
|
|
n.open ? path.call(print, "open") : "",
|
|
|
|
|
join(",", path.map(print, "groups")),
|
|
|
|
|
n.close ? path.call(print, "close") : ""
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!n.open) {
|
2017-06-21 15:13:51 -07:00
|
|
|
const printed = path.map(print, "groups");
|
|
|
|
|
const res = [];
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < printed.length; i++) {
|
|
|
|
|
if (i !== 0) {
|
|
|
|
|
res.push(concat([",", line]));
|
|
|
|
|
}
|
|
|
|
|
res.push(printed[i]);
|
|
|
|
|
}
|
|
|
|
|
return group(indent(fill(res)));
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
|
2017-10-21 21:35:22 -04:00
|
|
|
const declaration = path.getParentNode(2);
|
|
|
|
|
const isMap =
|
|
|
|
|
declaration &&
|
|
|
|
|
declaration.type === "css-decl" &&
|
|
|
|
|
declaration.prop.startsWith("$");
|
|
|
|
|
|
2017-06-06 00:28:38 +10:00
|
|
|
return group(
|
|
|
|
|
concat([
|
|
|
|
|
n.open ? path.call(print, "open") : "",
|
|
|
|
|
indent(
|
|
|
|
|
concat([
|
|
|
|
|
softline,
|
2017-10-21 21:35:22 -04:00
|
|
|
join(
|
|
|
|
|
concat([",", isMap ? hardline : line]),
|
|
|
|
|
path.map(print, "groups")
|
|
|
|
|
)
|
2017-06-06 00:28:38 +10:00
|
|
|
])
|
|
|
|
|
),
|
|
|
|
|
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": {
|
|
|
|
|
if (n.raws.before !== "") {
|
2018-01-24 18:48:54 +03:00
|
|
|
const parent = path.getParentNode(2);
|
|
|
|
|
const isFunction = parent && parent.type === "value-func";
|
|
|
|
|
|
|
|
|
|
return concat([isFunction ? "" : line, n.value]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
return n.value;
|
|
|
|
|
}
|
|
|
|
|
case "value-number": {
|
2017-09-03 21:22:28 +02:00
|
|
|
return concat([printNumber(n.value), maybeToLowerCase(n.unit)]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-operator": {
|
|
|
|
|
return n.value;
|
|
|
|
|
}
|
|
|
|
|
case "value-word": {
|
2018-01-23 18:10:39 +03:00
|
|
|
if ((n.isColor && n.isHex) || isWideKeywords(n.value)) {
|
2017-06-20 23:07:31 +10:00
|
|
|
return n.value.toLowerCase();
|
|
|
|
|
}
|
2017-06-06 00:28:38 +10:00
|
|
|
return n.value;
|
|
|
|
|
}
|
|
|
|
|
case "value-colon": {
|
|
|
|
|
return n.value;
|
|
|
|
|
}
|
|
|
|
|
case "value-comma": {
|
|
|
|
|
return concat([n.value, " "]);
|
|
|
|
|
}
|
|
|
|
|
case "value-string": {
|
2017-08-14 08:57:16 +02:00
|
|
|
return util.printString(n.raws.quote + n.value + n.raws.quote, options);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-atword": {
|
|
|
|
|
return concat(["@", n.value]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
2017-09-03 22:40:44 +02:00
|
|
|
/* istanbul ignore next */
|
2017-06-06 00:28:38 +10:00
|
|
|
throw new Error("unknown postcss type: " + JSON.stringify(n.type));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function printNodeSequence(path, options, print) {
|
|
|
|
|
const node = path.getValue();
|
|
|
|
|
const parts = [];
|
|
|
|
|
let i = 0;
|
|
|
|
|
path.map(pathChild => {
|
2017-06-11 00:45:59 +10:00
|
|
|
const prevNode = node.nodes[i - 1];
|
|
|
|
|
if (
|
|
|
|
|
prevNode &&
|
|
|
|
|
prevNode.type === "css-comment" &&
|
|
|
|
|
prevNode.text.trim() === "prettier-ignore"
|
|
|
|
|
) {
|
|
|
|
|
const childNode = pathChild.getValue();
|
|
|
|
|
parts.push(
|
|
|
|
|
options.originalText.slice(
|
|
|
|
|
util.locStart(childNode),
|
|
|
|
|
util.locEnd(childNode)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
parts.push(pathChild.call(print));
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-06 00:28:38 +10:00
|
|
|
if (i !== node.nodes.length - 1) {
|
|
|
|
|
if (
|
2017-06-11 00:40:05 +10:00
|
|
|
(node.nodes[i + 1].type === "css-comment" &&
|
|
|
|
|
!util.hasNewline(
|
|
|
|
|
options.originalText,
|
|
|
|
|
util.locStart(node.nodes[i + 1]),
|
|
|
|
|
{ backwards: true }
|
|
|
|
|
)) ||
|
|
|
|
|
(node.nodes[i + 1].type === "css-atrule" &&
|
2017-08-08 05:07:47 +03:00
|
|
|
node.nodes[i + 1].name === "else" &&
|
|
|
|
|
node.nodes[i].type !== "css-comment")
|
2017-06-06 00:28:38 +10:00
|
|
|
) {
|
|
|
|
|
parts.push(" ");
|
|
|
|
|
} else {
|
|
|
|
|
parts.push(hardline);
|
|
|
|
|
if (util.isNextLineEmpty(options.originalText, pathChild.getValue())) {
|
|
|
|
|
parts.push(hardline);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
}, "nodes");
|
|
|
|
|
|
|
|
|
|
return concat(parts);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function printValue(value) {
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-14 08:57:16 +02:00
|
|
|
const STRING_REGEX = /(['"])(?:(?!\1)[^\\]|\\[\s\S])*\1/g;
|
2017-08-15 17:25:57 +02:00
|
|
|
const NUMBER_REGEX = /(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g;
|
2017-09-03 21:22:28 +02:00
|
|
|
const STANDARD_UNIT_REGEX = /[a-zA-Z]+/g;
|
|
|
|
|
const WORD_PART_REGEX = /[$@]?[a-zA-Z_\u0080-\uFFFF][\w\-\u0080-\uFFFF]*/g;
|
|
|
|
|
const ADJUST_NUMBERS_REGEX = RegExp(
|
|
|
|
|
STRING_REGEX.source +
|
|
|
|
|
`|` +
|
|
|
|
|
`(${WORD_PART_REGEX.source})?` +
|
|
|
|
|
`(${NUMBER_REGEX.source})` +
|
|
|
|
|
`(${STANDARD_UNIT_REGEX.source})?`,
|
2017-08-15 17:25:57 +02:00
|
|
|
"g"
|
|
|
|
|
);
|
2017-08-14 08:57:16 +02:00
|
|
|
|
|
|
|
|
function adjustStrings(value, options) {
|
|
|
|
|
return value.replace(STRING_REGEX, match => util.printString(match, options));
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-22 18:45:15 +02:00
|
|
|
function quoteAttributeValue(value, options) {
|
|
|
|
|
const quote = options.singleQuote ? "'" : '"';
|
|
|
|
|
return value.includes('"') || value.includes("'")
|
|
|
|
|
? value
|
|
|
|
|
: quote + value + quote;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-15 17:25:57 +02:00
|
|
|
function adjustNumbers(value) {
|
|
|
|
|
return value.replace(
|
2017-09-03 21:22:28 +02:00
|
|
|
ADJUST_NUMBERS_REGEX,
|
|
|
|
|
(match, quote, wordPart, number, unit) =>
|
|
|
|
|
!wordPart && number
|
|
|
|
|
? (wordPart || "") + printNumber(number) + maybeToLowerCase(unit || "")
|
|
|
|
|
: match
|
2017-08-15 17:25:57 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function printNumber(rawNumber) {
|
|
|
|
|
return (
|
|
|
|
|
util
|
|
|
|
|
.printNumber(rawNumber)
|
|
|
|
|
// Remove trailing `.0`.
|
|
|
|
|
.replace(/\.0(?=$|e)/, "")
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-03 21:22:28 +02:00
|
|
|
function maybeToLowerCase(value) {
|
2017-09-14 21:55:11 +02:00
|
|
|
return value.includes("$") ||
|
2017-09-16 20:24:08 +10:00
|
|
|
value.includes("@") ||
|
|
|
|
|
value.includes("#") ||
|
2017-09-21 20:23:22 +02:00
|
|
|
value.startsWith("%") ||
|
2018-01-19 17:39:44 +03:00
|
|
|
value.startsWith("--") ||
|
|
|
|
|
(value.includes("(") && value.includes(")"))
|
2017-09-03 21:22:28 +02:00
|
|
|
? value
|
|
|
|
|
: value.toLowerCase();
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-23 18:10:39 +03:00
|
|
|
function isWideKeywords(value) {
|
|
|
|
|
return (
|
|
|
|
|
["initial", "inherit", "unset", "revert"].indexOf(
|
|
|
|
|
value.replace().toLowerCase()
|
|
|
|
|
) !== -1
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-26 12:23:50 +11:00
|
|
|
module.exports = {
|
2017-12-31 12:34:37 +08:00
|
|
|
options: printerOptions,
|
2017-12-26 12:23:50 +11:00
|
|
|
print: genericPrint,
|
2017-12-30 21:30:09 +11:00
|
|
|
hasPrettierIgnore: util.hasIgnoreComment,
|
|
|
|
|
massageAstNode: clean
|
2017-12-26 12:23:50 +11:00
|
|
|
};
|