2017-06-06 00:28:38 +10:00
|
|
|
"use strict";
|
|
|
|
|
|
2017-12-30 21:30:09 +11:00
|
|
|
const clean = require("./clean");
|
2018-02-09 13:17:48 +01:00
|
|
|
const privateUtil = require("../common/util");
|
|
|
|
|
const sharedUtil = require("../common/util-shared");
|
2018-04-26 13:53:52 +03:00
|
|
|
|
2017-12-26 12:23:50 +11:00
|
|
|
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;
|
|
|
|
|
|
2018-04-26 13:53:52 +03:00
|
|
|
const docUtils = doc.utils;
|
|
|
|
|
const removeLines = docUtils.removeLines;
|
|
|
|
|
|
2018-04-19 02:10:01 +05:30
|
|
|
const utils = require("./utils");
|
2018-05-15 01:08:04 +03:00
|
|
|
|
2018-04-26 13:53:52 +03:00
|
|
|
const getAncestorNode = utils.getAncestorNode;
|
|
|
|
|
const getPropOfDeclNode = utils.getPropOfDeclNode;
|
2018-05-15 01:08:04 +03:00
|
|
|
const maybeToLowerCase = utils.maybeToLowerCase;
|
2018-04-26 13:53:52 +03:00
|
|
|
const insideValueFunctionNode = utils.insideValueFunctionNode;
|
|
|
|
|
const insideICSSRuleNode = utils.insideICSSRuleNode;
|
|
|
|
|
const insideAtRuleNode = utils.insideAtRuleNode;
|
|
|
|
|
const isKeyframeAtRuleKeywords = utils.isKeyframeAtRuleKeywords;
|
2018-05-15 01:08:04 +03:00
|
|
|
const isHTMLTag = utils.isHTMLTag;
|
2018-04-26 13:53:52 +03:00
|
|
|
const isWideKeywords = utils.isWideKeywords;
|
2018-05-15 01:08:04 +03:00
|
|
|
const isSCSS = utils.isSCSS;
|
|
|
|
|
const isLastNode = utils.isLastNode;
|
|
|
|
|
const isSCSSControlDirectiveNode = utils.isSCSSControlDirectiveNode;
|
|
|
|
|
const isDetachedRulesetDeclarationNode = utils.isDetachedRulesetDeclarationNode;
|
|
|
|
|
const isRelationalOperatorNode = utils.isRelationalOperatorNode;
|
|
|
|
|
const isEqualityOperatorNode = utils.isEqualityOperatorNode;
|
|
|
|
|
const isMathOperatorNode = utils.isMathOperatorNode;
|
|
|
|
|
const isEachKeywordNode = utils.isEachKeywordNode;
|
|
|
|
|
const isParenGroupNode = utils.isParenGroupNode;
|
|
|
|
|
const isForKeywordNode = utils.isForKeywordNode;
|
|
|
|
|
const isURLFunctionNode = utils.isURLFunctionNode;
|
|
|
|
|
const isIfElseKeywordNode = utils.isIfElseKeywordNode;
|
2018-04-26 13:53:52 +03:00
|
|
|
const hasLessExtendValueNode = utils.hasLessExtendValueNode;
|
2018-05-15 01:08:04 +03:00
|
|
|
const hasComposesValueNode = utils.hasComposesValueNode;
|
2018-04-26 13:53:52 +03:00
|
|
|
const hasParensAroundValueNode = utils.hasParensAroundValueNode;
|
2018-05-15 01:08:04 +03:00
|
|
|
const isSCSSMapNode = utils.isSCSSMapNode;
|
|
|
|
|
const isDetachedRulesetCallNode = utils.isDetachedRulesetCallNode;
|
|
|
|
|
const isPostcssSimpleVarNode = utils.isPostcssSimpleVarNode;
|
2017-06-19 11:41:10 +02:00
|
|
|
|
2017-06-06 00:28:38 +10:00
|
|
|
function genericPrint(path, options, print) {
|
2018-02-05 16:42:32 +03:00
|
|
|
const node = path.getValue();
|
2017-06-06 00:28:38 +10:00
|
|
|
|
2017-09-03 22:40:44 +02:00
|
|
|
/* istanbul ignore if */
|
2018-02-05 16:42:32 +03:00
|
|
|
if (!node) {
|
2017-06-06 00:28:38 +10:00
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-05 16:42:32 +03:00
|
|
|
if (typeof node === "string") {
|
|
|
|
|
return node;
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
|
2018-02-05 16:42:32 +03:00
|
|
|
switch (node.type) {
|
2018-05-14 22:17:15 -03:00
|
|
|
case "frontmatter":
|
|
|
|
|
return concat([node.value, hardline]);
|
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": {
|
2018-02-05 16:42:32 +03:00
|
|
|
if (node.raws.content) {
|
|
|
|
|
return node.raws.content;
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
2018-02-05 16:42:32 +03:00
|
|
|
const text = options.originalText.slice(
|
2018-02-09 13:17:48 +01:00
|
|
|
options.locStart(node),
|
|
|
|
|
options.locEnd(node)
|
2018-02-05 16:42:32 +03:00
|
|
|
);
|
|
|
|
|
const rawText = node.raws.text || node.text;
|
2017-06-06 00:28:38 +10:00
|
|
|
// Workaround a bug where the location is off.
|
|
|
|
|
// https://github.com/postcss/postcss-scss/issues/63
|
|
|
|
|
if (text.indexOf(rawText) === -1) {
|
2018-02-05 16:42:32 +03:00
|
|
|
if (node.raws.inline) {
|
2017-06-06 00:28:38 +10:00
|
|
|
return concat(["// ", rawText]);
|
|
|
|
|
}
|
|
|
|
|
return concat(["/* ", rawText, " */"]);
|
|
|
|
|
}
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
case "css-rule": {
|
|
|
|
|
return concat([
|
|
|
|
|
path.call(print, "selector"),
|
2018-02-05 16:42:32 +03:00
|
|
|
node.important ? " !important" : "",
|
|
|
|
|
node.nodes
|
2017-06-06 00:28:38 +10:00
|
|
|
? concat([
|
|
|
|
|
" {",
|
2018-02-05 16:42:32 +03:00
|
|
|
node.nodes.length > 0
|
2017-06-06 00:28:38 +10:00
|
|
|
? indent(
|
|
|
|
|
concat([hardline, printNodeSequence(path, options, print)])
|
|
|
|
|
)
|
|
|
|
|
: "",
|
|
|
|
|
hardline,
|
2018-01-30 14:16:07 +03:00
|
|
|
"}",
|
2018-05-15 01:08:04 +03:00
|
|
|
isDetachedRulesetDeclarationNode(node) ? ";" : ""
|
2017-06-06 00:28:38 +10:00
|
|
|
])
|
|
|
|
|
: ";"
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
case "css-decl": {
|
|
|
|
|
return concat([
|
2018-02-05 16:42:32 +03:00
|
|
|
node.raws.before.replace(/[\s;]/g, ""),
|
2018-04-26 13:53:52 +03:00
|
|
|
insideICSSRuleNode(path) ? node.prop : maybeToLowerCase(node.prop),
|
2018-02-06 18:09:42 +03:00
|
|
|
node.raws.between.trim() === ":" ? ":" : node.raws.between.trim(),
|
2018-04-26 13:53:52 +03: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.
|
|
|
|
|
hasLessExtendValueNode(node) ? "" : " ",
|
|
|
|
|
hasComposesValueNode(node)
|
2017-06-19 11:41:10 +02:00
|
|
|
? removeLines(path.call(print, "value"))
|
|
|
|
|
: path.call(print, "value"),
|
2018-02-06 18:09:42 +03:00
|
|
|
node.raws.important
|
|
|
|
|
? node.raws.important.replace(/\s*!\s*important/i, " !important")
|
2018-04-11 22:39:13 -06:00
|
|
|
: node.important
|
|
|
|
|
? " !important"
|
|
|
|
|
: "",
|
2018-02-06 18:09:42 +03:00
|
|
|
node.raws.scssDefault
|
|
|
|
|
? node.raws.scssDefault.replace(/\s*!default/i, " !default")
|
2018-04-11 22:39:13 -06:00
|
|
|
: node.scssDefault
|
|
|
|
|
? " !default"
|
|
|
|
|
: "",
|
2018-02-06 18:09:42 +03:00
|
|
|
node.raws.scssGlobal
|
|
|
|
|
? node.raws.scssGlobal.replace(/\s*!global/i, " !global")
|
2018-04-11 22:39:13 -06:00
|
|
|
: node.scssGlobal
|
|
|
|
|
? " !global"
|
|
|
|
|
: "",
|
2018-02-05 16:42:32 +03:00
|
|
|
node.nodes
|
2017-06-06 00:28:38 +10:00
|
|
|
? concat([
|
|
|
|
|
" {",
|
|
|
|
|
indent(
|
|
|
|
|
concat([softline, printNodeSequence(path, options, print)])
|
|
|
|
|
),
|
|
|
|
|
softline,
|
|
|
|
|
"}"
|
|
|
|
|
])
|
|
|
|
|
: ";"
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
case "css-atrule": {
|
|
|
|
|
return concat([
|
|
|
|
|
"@",
|
2017-09-15 19:48:16 +02:00
|
|
|
// If a Less file ends up being parsed with the SCSS parser, Less
|
2018-04-26 13:53:52 +03:00
|
|
|
// variable declarations will be parsed as at-rules with names ending
|
2017-09-15 19:48:16 +02:00
|
|
|
// with a colon, so keep the original case then.
|
2018-05-15 01:08:04 +03:00
|
|
|
isDetachedRulesetCallNode(node) || node.name.endsWith(":")
|
2018-02-05 16:42:32 +03:00
|
|
|
? node.name
|
|
|
|
|
: maybeToLowerCase(node.name),
|
2018-04-26 13:53:52 +03:00
|
|
|
node.params
|
2017-09-03 21:22:28 +02:00
|
|
|
? concat([
|
2018-05-15 01:08:04 +03:00
|
|
|
isDetachedRulesetCallNode(node) ? "" : " ",
|
2017-09-03 21:22:28 +02:00
|
|
|
path.call(print, "params")
|
|
|
|
|
])
|
|
|
|
|
: "",
|
2018-02-05 16:42:32 +03:00
|
|
|
node.selector
|
|
|
|
|
? indent(concat([" ", path.call(print, "selector")]))
|
|
|
|
|
: "",
|
|
|
|
|
node.value
|
2018-02-02 18:06:47 +03:00
|
|
|
? group(
|
|
|
|
|
concat([
|
|
|
|
|
" ",
|
|
|
|
|
path.call(print, "value"),
|
2018-04-26 13:53:52 +03:00
|
|
|
isSCSSControlDirectiveNode(node)
|
|
|
|
|
? hasParensAroundValueNode(node)
|
2018-04-11 22:39:13 -06:00
|
|
|
? " "
|
|
|
|
|
: line
|
2018-02-22 12:00:08 +03:00
|
|
|
: ""
|
2018-02-02 18:06:47 +03:00
|
|
|
])
|
|
|
|
|
)
|
2018-04-11 22:39:13 -06:00
|
|
|
: node.name === "else"
|
|
|
|
|
? " "
|
|
|
|
|
: "",
|
2018-02-05 16:42:32 +03:00
|
|
|
node.nodes
|
2017-06-06 00:28:38 +10:00
|
|
|
? concat([
|
2018-04-26 13:53:52 +03:00
|
|
|
isSCSSControlDirectiveNode(node) ? "" : " ",
|
2018-02-02 18:06:47 +03:00
|
|
|
"{",
|
2017-06-06 00:28:38 +10:00
|
|
|
indent(
|
|
|
|
|
concat([
|
2018-02-05 16:42:32 +03:00
|
|
|
node.nodes.length > 0 ? softline : "",
|
2017-06-06 00:28:38 +10:00
|
|
|
printNodeSequence(path, options, print)
|
|
|
|
|
])
|
|
|
|
|
),
|
|
|
|
|
softline,
|
|
|
|
|
"}"
|
|
|
|
|
])
|
|
|
|
|
: ";"
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
// 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
|
|
|
return concat([
|
|
|
|
|
join(" ", path.map(print, "nodes")),
|
2018-02-22 12:00:08 +03:00
|
|
|
isLastNode(path, node) ? "" : ","
|
2018-01-20 02:56:28 +03:00
|
|
|
]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-type": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return adjustNumbers(adjustStrings(node.value, options));
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-feature-expression": {
|
2018-02-05 16:42:32 +03:00
|
|
|
if (!node.nodes) {
|
|
|
|
|
return node.value;
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
return concat(["(", concat(path.map(print, "nodes")), ")"]);
|
|
|
|
|
}
|
|
|
|
|
case "media-feature": {
|
2017-09-03 21:22:28 +02:00
|
|
|
return maybeToLowerCase(
|
2018-02-05 16:42:32 +03:00
|
|
|
adjustStrings(node.value.replace(/ +/g, " "), options)
|
2017-09-03 21:22:28 +02:00
|
|
|
);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-colon": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return concat([node.value, " "]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-value": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return adjustNumbers(adjustStrings(node.value, options));
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-keyword": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return adjustStrings(node.value, options);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-url": {
|
2018-01-23 23:33:19 +03:00
|
|
|
return adjustStrings(
|
2018-02-05 16:42:32 +03:00
|
|
|
node.value.replace(/^url\(\s+/gi, "url(").replace(/\s+\)$/gi, ")"),
|
2018-01-23 23:33:19 +03:00
|
|
|
options
|
|
|
|
|
);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "media-unknown": {
|
2018-05-15 00:00:45 +03:00
|
|
|
return node.value;
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
// postcss-selector-parser
|
|
|
|
|
case "selector-root": {
|
2018-02-05 16:42:32 +03:00
|
|
|
const atRuleAncestorNode = getAncestorNode(path, "css-atrule");
|
2018-02-22 12:00:08 +03:00
|
|
|
const insideAtRuleNode =
|
|
|
|
|
atRuleAncestorNode &&
|
|
|
|
|
["extend", "custom-selector", "nest"].indexOf(
|
|
|
|
|
atRuleAncestorNode.name
|
|
|
|
|
) !== -1;
|
2018-02-02 18:06:47 +03:00
|
|
|
|
|
|
|
|
return group(
|
|
|
|
|
concat([
|
2018-02-22 12:00:08 +03:00
|
|
|
atRuleAncestorNode && atRuleAncestorNode.name === "custom-selector"
|
2018-02-05 16:42:32 +03:00
|
|
|
? concat([atRuleAncestorNode.customSelector, line])
|
2018-02-02 18:06:47 +03:00
|
|
|
: "",
|
|
|
|
|
join(
|
2018-02-22 12:00:08 +03:00
|
|
|
concat([",", insideAtRuleNode ? line : hardline]),
|
2018-02-02 18:06:47 +03:00
|
|
|
path.map(print, "nodes")
|
|
|
|
|
)
|
|
|
|
|
])
|
|
|
|
|
);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-comment": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return node.value;
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-string": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return adjustStrings(node.value, options);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-tag": {
|
2018-02-27 04:13:02 +03:00
|
|
|
const parentNode = path.getParentNode();
|
|
|
|
|
const index = parentNode && parentNode.nodes.indexOf(node);
|
|
|
|
|
const prevNode = index && parentNode.nodes[index - 1];
|
|
|
|
|
|
2018-02-12 18:39:03 +03:00
|
|
|
return concat([
|
|
|
|
|
node.namespace
|
|
|
|
|
? concat([node.namespace === true ? "" : node.namespace.trim(), "|"])
|
|
|
|
|
: "",
|
2018-02-27 04:13:02 +03:00
|
|
|
prevNode.type === "selector-nesting"
|
|
|
|
|
? node.value
|
|
|
|
|
: adjustNumbers(
|
|
|
|
|
isHTMLTag(node.value) ||
|
|
|
|
|
isKeyframeAtRuleKeywords(path, node.value)
|
|
|
|
|
? node.value.toLowerCase()
|
|
|
|
|
: node.value
|
|
|
|
|
)
|
2018-02-12 18:39:03 +03:00
|
|
|
]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-id": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return concat(["#", node.value]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-class": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return concat([".", adjustNumbers(adjustStrings(node.value, options))]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-attribute": {
|
|
|
|
|
return concat([
|
|
|
|
|
"[",
|
2018-02-05 16:42:32 +03:00
|
|
|
node.namespace
|
|
|
|
|
? concat([node.namespace === true ? "" : node.namespace.trim(), "|"])
|
2018-01-26 13:00:20 +03:00
|
|
|
: "",
|
2018-02-05 16:42:32 +03:00
|
|
|
node.attribute.trim(),
|
|
|
|
|
node.operator ? node.operator : "",
|
|
|
|
|
node.value
|
|
|
|
|
? quoteAttributeValue(
|
|
|
|
|
adjustStrings(node.value.trim(), options),
|
|
|
|
|
options
|
|
|
|
|
)
|
2017-08-22 18:45:15 +02:00
|
|
|
: "",
|
2018-02-05 16:42:32 +03:00
|
|
|
node.insensitive ? " i" : "",
|
2017-06-06 00:28:38 +10:00
|
|
|
"]"
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
case "selector-combinator": {
|
2018-01-24 14:53:22 +03:00
|
|
|
if (
|
2018-02-05 16:42:32 +03:00
|
|
|
node.value === "+" ||
|
|
|
|
|
node.value === ">" ||
|
|
|
|
|
node.value === "~" ||
|
|
|
|
|
node.value === ">>>"
|
2018-01-24 14:53:22 +03:00
|
|
|
) {
|
2018-02-05 16:42:32 +03:00
|
|
|
const parentNode = path.getParentNode();
|
2017-07-08 14:07:39 +02:00
|
|
|
const leading =
|
2018-02-05 16:42:32 +03:00
|
|
|
parentNode.type === "selector-selector" &&
|
|
|
|
|
parentNode.nodes[0] === node
|
2017-07-08 14:07:39 +02:00
|
|
|
? ""
|
|
|
|
|
: line;
|
2018-02-22 12:00:08 +03:00
|
|
|
return concat([leading, node.value, isLastNode(path, node) ? "" : " "]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
2018-02-05 16:42:32 +03:00
|
|
|
const leading = node.value.trim().startsWith("(") ? line : "";
|
2017-09-03 21:22:28 +02:00
|
|
|
const value =
|
2018-02-05 16:42:32 +03:00
|
|
|
adjustNumbers(adjustStrings(node.value.trim(), options)) || line;
|
2017-09-03 21:22:28 +02:00
|
|
|
return concat([leading, value]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-universal": {
|
2018-02-12 18:39:03 +03:00
|
|
|
return concat([
|
|
|
|
|
node.namespace
|
|
|
|
|
? concat([node.namespace === true ? "" : node.namespace.trim(), "|"])
|
|
|
|
|
: "",
|
|
|
|
|
adjustNumbers(node.value)
|
|
|
|
|
]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "selector-selector": {
|
|
|
|
|
return group(indent(concat(path.map(print, "nodes"))));
|
|
|
|
|
}
|
|
|
|
|
case "selector-pseudo": {
|
|
|
|
|
return concat([
|
2018-02-05 16:42:32 +03:00
|
|
|
maybeToLowerCase(node.value),
|
|
|
|
|
node.nodes && node.nodes.length > 0
|
2017-06-06 00:28:38 +10:00
|
|
|
? concat(["(", join(", ", path.map(print, "nodes")), ")"])
|
|
|
|
|
: ""
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
case "selector-nesting": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return node.value;
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
2018-05-15 00:00:45 +03:00
|
|
|
case "selector-unknown": {
|
|
|
|
|
const ruleAncestorNode = getAncestorNode(path, "css-rule");
|
|
|
|
|
|
|
|
|
|
// Nested SCSS property
|
|
|
|
|
if (ruleAncestorNode && ruleAncestorNode.isSCSSNesterProperty) {
|
|
|
|
|
return adjustNumbers(
|
|
|
|
|
adjustStrings(maybeToLowerCase(node.value), options)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return node.value;
|
|
|
|
|
}
|
2017-06-06 00:28:38 +10:00
|
|
|
// postcss-values-parser
|
|
|
|
|
case "value-root": {
|
|
|
|
|
return path.call(print, "group");
|
|
|
|
|
}
|
2018-02-06 18:09:42 +03:00
|
|
|
case "value-comment": {
|
2018-03-31 17:18:23 +03:00
|
|
|
return concat([
|
|
|
|
|
node.inline ? "//" : "/*",
|
|
|
|
|
node.value,
|
|
|
|
|
node.inline ? "" : "*/"
|
|
|
|
|
]);
|
2018-02-06 18:09:42 +03:00
|
|
|
}
|
2017-06-06 00:28:38 +10:00
|
|
|
case "value-comma_group": {
|
2018-02-05 16:42:32 +03:00
|
|
|
const parentNode = path.getParentNode();
|
2018-04-26 13:53:52 +03:00
|
|
|
const declAncestorProp = getPropOfDeclNode(path);
|
2017-11-01 15:21:59 -02:00
|
|
|
const isGridValue =
|
2018-02-05 16:42:32 +03:00
|
|
|
declAncestorProp &&
|
|
|
|
|
parentNode.type === "value-value" &&
|
|
|
|
|
(declAncestorProp === "grid" ||
|
|
|
|
|
declAncestorProp.startsWith("grid-template"));
|
|
|
|
|
const atRuleAncestorNode = getAncestorNode(path, "css-atrule");
|
2018-02-02 18:06:47 +03:00
|
|
|
const isControlDirective =
|
2018-04-26 13:53:52 +03:00
|
|
|
atRuleAncestorNode && isSCSSControlDirectiveNode(atRuleAncestorNode);
|
2017-11-01 15:21:59 -02:00
|
|
|
|
2017-06-06 00:28:38 +10:00
|
|
|
const printed = path.map(print, "groups");
|
|
|
|
|
const parts = [];
|
2018-04-26 13:53:52 +03:00
|
|
|
const insideURLFunction = insideValueFunctionNode(path, "url");
|
2018-02-10 20:57:06 +03:00
|
|
|
|
2017-11-01 15:21:59 -02:00
|
|
|
let didBreak = false;
|
2018-02-05 16:42:32 +03:00
|
|
|
for (let i = 0; i < node.groups.length; ++i) {
|
2017-06-06 00:28:38 +10:00
|
|
|
parts.push(printed[i]);
|
2018-02-02 18:06:47 +03:00
|
|
|
|
2018-02-16 21:58:21 +03:00
|
|
|
// Ignore value inside `url()`
|
|
|
|
|
if (insideURLFunction) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const iPrevNode = node.groups[i - 1];
|
|
|
|
|
const iNode = node.groups[i];
|
|
|
|
|
const iNextNode = node.groups[i + 1];
|
|
|
|
|
const iNextNextNode = node.groups[i + 2];
|
|
|
|
|
|
2018-02-09 15:28:55 +03:00
|
|
|
// Ignore after latest node (i.e. before semicolon)
|
2018-02-16 21:58:21 +03:00
|
|
|
if (!iNextNode) {
|
2018-02-09 15:28:55 +03:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ignore colon
|
2018-02-16 21:58:21 +03:00
|
|
|
if (iNode.value === ":") {
|
2018-02-09 15:28:55 +03:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ignore `@` in Less (i.e. `@@var;`)
|
2018-02-16 21:58:21 +03:00
|
|
|
if (iNode.type === "value-atword" && iNode.value === "") {
|
2018-02-09 15:28:55 +03:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ignore `~` in Less (i.e. `content: ~"^//* some horrible but needed css hack";`)
|
2018-02-16 21:58:21 +03:00
|
|
|
if (iNode.value === "~") {
|
2018-02-09 15:28:55 +03:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-14 13:47:46 +03:00
|
|
|
// Ignore `\` (i.e. `$variable: \@small;`)
|
|
|
|
|
if (iNode.value === "\\") {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ignore `$$` (i.e. `background-color: $$(style)Color;`)
|
2018-05-15 01:08:04 +03:00
|
|
|
if (isPostcssSimpleVarNode(iNode, iNextNode)) {
|
2018-05-14 13:47:46 +03:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-31 17:18:23 +03:00
|
|
|
if (
|
|
|
|
|
(iPrevNode &&
|
|
|
|
|
iPrevNode.type === "value-comment" &&
|
|
|
|
|
iPrevNode.inline) ||
|
|
|
|
|
(iNextNode.type === "value-comment" && iNextNode.inline)
|
|
|
|
|
) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-16 21:58:21 +03:00
|
|
|
const isHash = iNode.type === "value-word" && iNode.value === "#";
|
|
|
|
|
const isLeftCurlyBrace =
|
|
|
|
|
iNode.type === "value-word" && iNode.value === "{";
|
|
|
|
|
const isNextLeftCurlyBrace =
|
|
|
|
|
iNextNode.type === "value-word" && iNextNode.value === "{";
|
|
|
|
|
const isRightCurlyBrace =
|
|
|
|
|
iNode.type === "value-word" && iNode.value === "}";
|
|
|
|
|
const isNextRightCurlyBrace =
|
|
|
|
|
iNextNode.type === "value-word" && iNextNode.value === "}";
|
|
|
|
|
|
2018-05-12 22:38:28 +03:00
|
|
|
// Ignore interpolation in SCSS (i.e. `#{variable}`)
|
2018-02-09 15:28:55 +03:00
|
|
|
if (
|
2018-02-16 21:58:21 +03:00
|
|
|
isHash ||
|
|
|
|
|
isLeftCurlyBrace ||
|
|
|
|
|
isNextRightCurlyBrace ||
|
|
|
|
|
(isNextLeftCurlyBrace &&
|
|
|
|
|
iNextNode.raws &&
|
|
|
|
|
iNextNode.raws.before === "") ||
|
|
|
|
|
(isRightCurlyBrace && iNextNode.raws && iNextNode.raws.before === "")
|
2018-02-09 15:28:55 +03:00
|
|
|
) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-12 22:38:28 +03:00
|
|
|
// Ignore css variables and interpolation in SCSS (i.e. `--#{$var}`)
|
|
|
|
|
if (iNode.value === "--" && iNextNode.value === "#") {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-16 21:58:21 +03:00
|
|
|
const isNextHash =
|
|
|
|
|
iNextNode.type === "value-word" && iNextNode.value === "#";
|
|
|
|
|
|
|
|
|
|
const isMathOperator = isMathOperatorNode(iNode);
|
|
|
|
|
const isNextMathOperator = isMathOperatorNode(iNextNode);
|
|
|
|
|
|
|
|
|
|
const isMultiplication =
|
|
|
|
|
!isNextHash && isMathOperator && iNode.value === "*";
|
|
|
|
|
const isNextMultiplication =
|
|
|
|
|
!isRightCurlyBrace && isNextMathOperator && iNextNode.value === "*";
|
|
|
|
|
|
|
|
|
|
const isDivision = !isNextHash && isMathOperator && iNode.value === "/";
|
|
|
|
|
const isNextDivision =
|
|
|
|
|
!isRightCurlyBrace && isNextMathOperator && iNextNode.value === "/";
|
|
|
|
|
|
|
|
|
|
const isAddition = !isNextHash && isMathOperator && iNode.value === "+";
|
|
|
|
|
const isNextAddition =
|
|
|
|
|
!isRightCurlyBrace && isNextMathOperator && iNextNode.value === "+";
|
|
|
|
|
|
|
|
|
|
const isPrevFunction = iPrevNode && iPrevNode.type === "value-func";
|
|
|
|
|
const isFunction = iNode.type === "value-func";
|
|
|
|
|
const isNextFunction = iNextNode.type === "value-func";
|
|
|
|
|
const isNextNextFunction =
|
|
|
|
|
iNextNextNode && iNextNextNode.type === "value-func";
|
|
|
|
|
|
|
|
|
|
const isPrevWord =
|
|
|
|
|
iPrevNode &&
|
|
|
|
|
["value-word", "value-atword"].indexOf(iPrevNode.type) !== -1;
|
|
|
|
|
const isWord =
|
|
|
|
|
["value-word", "value-atword"].indexOf(iNode.type) !== -1;
|
|
|
|
|
const isNextWord =
|
|
|
|
|
["value-word", "value-atword"].indexOf(iNextNode.type) !== -1;
|
|
|
|
|
const isNextNextWord =
|
|
|
|
|
iNextNextNode &&
|
|
|
|
|
["value-word", "value-atword"].indexOf(iNextNextNode.type) !== -1;
|
|
|
|
|
|
|
|
|
|
// Math operators
|
2018-04-26 13:53:52 +03:00
|
|
|
const insideCalcFunction = insideValueFunctionNode(path, "calc");
|
2018-02-16 21:58:21 +03:00
|
|
|
|
|
|
|
|
const hasSpaceBeforeOperator =
|
|
|
|
|
isNextNextFunction || isNextNextWord || isFunction || isWord;
|
|
|
|
|
|
|
|
|
|
const hasSpaceAfterOperator =
|
|
|
|
|
isNextFunction || isNextWord || isPrevFunction || isPrevWord;
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
(isMathOperator || isNextMathOperator) &&
|
|
|
|
|
// Multiplication
|
|
|
|
|
!isMultiplication &&
|
|
|
|
|
!isNextMultiplication &&
|
|
|
|
|
// Division
|
|
|
|
|
!(isNextDivision && (hasSpaceBeforeOperator || insideCalcFunction)) &&
|
|
|
|
|
!(isDivision && (hasSpaceAfterOperator || insideCalcFunction)) &&
|
|
|
|
|
// Addition
|
|
|
|
|
!(isNextAddition && hasSpaceBeforeOperator) &&
|
|
|
|
|
!(isAddition && hasSpaceAfterOperator)
|
|
|
|
|
) {
|
|
|
|
|
const isNextParenGroup = isParenGroupNode(iNextNode);
|
|
|
|
|
const isNextValueNumber = iNextNode.type === "value-number";
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
(iNextNode.raws && iNextNode.raws.before === "") ||
|
|
|
|
|
(isMathOperator &&
|
|
|
|
|
(isNextParenGroup ||
|
|
|
|
|
isNextWord ||
|
|
|
|
|
isNextValueNumber ||
|
|
|
|
|
isMathOperatorNode(iNextNode)) &&
|
|
|
|
|
(!iPrevNode || (iPrevNode && isMathOperatorNode(iPrevNode))))
|
|
|
|
|
) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-09 15:28:55 +03:00
|
|
|
const isEqualityOperator =
|
2018-02-16 21:58:21 +03:00
|
|
|
isControlDirective && isEqualityOperatorNode(iNode);
|
2018-02-09 15:28:55 +03:00
|
|
|
const isRelationalOperator =
|
2018-02-16 21:58:21 +03:00
|
|
|
isControlDirective && isRelationalOperatorNode(iNode);
|
2018-02-09 15:28:55 +03:00
|
|
|
const isNextEqualityOperator =
|
2018-02-16 21:58:21 +03:00
|
|
|
isControlDirective && isEqualityOperatorNode(iNextNode);
|
2018-02-09 15:28:55 +03:00
|
|
|
const isNextRelationalOperator =
|
2018-02-16 21:58:21 +03:00
|
|
|
isControlDirective && isRelationalOperatorNode(iNextNode);
|
2018-02-09 15:28:55 +03:00
|
|
|
const isNextIfElseKeyword =
|
2018-02-16 21:58:21 +03:00
|
|
|
isControlDirective && isIfElseKeywordNode(iNextNode);
|
|
|
|
|
const isEachKeyword = isControlDirective && isEachKeywordNode(iNode);
|
2018-02-09 15:28:55 +03:00
|
|
|
const isNextEachKeyword =
|
2018-02-16 21:58:21 +03:00
|
|
|
isControlDirective && isEachKeywordNode(iNextNode);
|
2018-02-09 15:28:55 +03:00
|
|
|
const isForKeyword =
|
|
|
|
|
atRuleAncestorNode &&
|
|
|
|
|
atRuleAncestorNode.name === "for" &&
|
2018-02-16 21:58:21 +03:00
|
|
|
isForKeywordNode(iNode);
|
2018-02-09 15:28:55 +03:00
|
|
|
const isNextForKeyword =
|
2018-02-16 21:58:21 +03:00
|
|
|
isControlDirective && isForKeywordNode(iNextNode);
|
|
|
|
|
const IsNextColon = iNextNode.value === ":";
|
2018-02-09 15:28:55 +03:00
|
|
|
|
|
|
|
|
if (isGridValue) {
|
2018-02-16 21:58:21 +03:00
|
|
|
if (iNode.source.start.line !== iNextNode.source.start.line) {
|
2018-02-09 15:28:55 +03:00
|
|
|
parts.push(hardline);
|
|
|
|
|
didBreak = true;
|
|
|
|
|
} else {
|
2017-06-06 00:28:38 +10:00
|
|
|
parts.push(" ");
|
|
|
|
|
}
|
2018-03-31 17:18:23 +03:00
|
|
|
} else if (iNode.type === "value-comment" && iNode.inline) {
|
|
|
|
|
parts.push(hardline);
|
2018-02-09 15:28:55 +03:00
|
|
|
} else if (
|
|
|
|
|
isNextMathOperator ||
|
|
|
|
|
isNextEqualityOperator ||
|
|
|
|
|
isNextRelationalOperator ||
|
|
|
|
|
isNextIfElseKeyword ||
|
|
|
|
|
isForKeyword ||
|
2018-04-25 21:27:12 +03:00
|
|
|
isEachKeyword ||
|
2018-04-26 13:53:52 +03:00
|
|
|
(atRuleAncestorNode &&
|
|
|
|
|
atRuleAncestorNode.name.toLowerCase() === "namespace")
|
2018-02-09 15:28:55 +03:00
|
|
|
) {
|
|
|
|
|
parts.push(" ");
|
|
|
|
|
} else if (
|
|
|
|
|
!IsNextColon ||
|
|
|
|
|
isEqualityOperator ||
|
|
|
|
|
isRelationalOperator ||
|
|
|
|
|
isNextForKeyword ||
|
|
|
|
|
isNextEachKeyword
|
|
|
|
|
) {
|
|
|
|
|
parts.push(line);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-01 15:21:59 -02:00
|
|
|
if (didBreak) {
|
|
|
|
|
parts.unshift(hardline);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-02 18:06:47 +03:00
|
|
|
if (isControlDirective) {
|
|
|
|
|
return group(indent(concat(parts)));
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-15 01:24:34 +05:30
|
|
|
// Indent is not needed for import url when url is very long
|
|
|
|
|
// and node has two groups
|
|
|
|
|
// when type is value-comma_group
|
|
|
|
|
// example @import url("verylongurl") projection,tv
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
atRuleAncestorNode &&
|
|
|
|
|
atRuleAncestorNode.name === "import" &&
|
|
|
|
|
node.groups[0].value === "url" &&
|
|
|
|
|
node.groups.length === 2
|
|
|
|
|
) {
|
|
|
|
|
return group(fill(parts));
|
|
|
|
|
}
|
2018-02-26 14:58:38 +03:00
|
|
|
return group(indent(fill(parts)));
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-paren_group": {
|
2018-02-05 16:42:32 +03:00
|
|
|
const parentNode = path.getParentNode();
|
2017-06-06 00:28:38 +10:00
|
|
|
|
|
|
|
|
if (
|
2018-04-26 13:53:52 +03:00
|
|
|
parentNode &&
|
2018-05-15 01:08:04 +03:00
|
|
|
isURLFunctionNode(parentNode) &&
|
2018-02-05 16:42:32 +03:00
|
|
|
(node.groups.length === 1 ||
|
|
|
|
|
(node.groups.length > 0 &&
|
|
|
|
|
node.groups[0].type === "value-comma_group" &&
|
|
|
|
|
node.groups[0].groups.length > 0 &&
|
|
|
|
|
node.groups[0].groups[0].type === "value-word" &&
|
|
|
|
|
node.groups[0].groups[0].value.startsWith("data:")))
|
2017-06-06 00:28:38 +10:00
|
|
|
) {
|
|
|
|
|
return concat([
|
2018-02-05 16:42:32 +03:00
|
|
|
node.open ? path.call(print, "open") : "",
|
2017-06-06 00:28:38 +10:00
|
|
|
join(",", path.map(print, "groups")),
|
2018-02-05 16:42:32 +03:00
|
|
|
node.close ? path.call(print, "close") : ""
|
2017-06-06 00:28:38 +10:00
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-05 16:42:32 +03:00
|
|
|
if (!node.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
|
|
|
}
|
|
|
|
|
|
2018-02-22 12:00:08 +03:00
|
|
|
const declNode = path.getParentNode(2);
|
2017-10-21 21:35:22 -04:00
|
|
|
|
2017-06-06 00:28:38 +10:00
|
|
|
return group(
|
|
|
|
|
concat([
|
2018-02-05 16:42:32 +03:00
|
|
|
node.open ? path.call(print, "open") : "",
|
2017-06-06 00:28:38 +10:00
|
|
|
indent(
|
|
|
|
|
concat([
|
|
|
|
|
softline,
|
2017-10-21 21:35:22 -04:00
|
|
|
join(
|
2018-04-26 13:53:52 +03:00
|
|
|
concat([
|
|
|
|
|
",",
|
2018-05-15 01:08:04 +03:00
|
|
|
declNode && isSCSSMapNode(declNode) ? hardline : line
|
2018-04-26 13:53:52 +03:00
|
|
|
]),
|
2017-10-21 21:35:22 -04:00
|
|
|
path.map(print, "groups")
|
|
|
|
|
)
|
2017-06-06 00:28:38 +10:00
|
|
|
])
|
|
|
|
|
),
|
2018-04-26 13:53:52 +03:00
|
|
|
isSCSS(options.parser, options.originalText) &&
|
2018-04-19 02:10:01 +05:30
|
|
|
node.groups.length > 1 &&
|
|
|
|
|
options.trailingComma !== "none"
|
|
|
|
|
? ","
|
|
|
|
|
: "",
|
2017-06-06 00:28:38 +10:00
|
|
|
softline,
|
2018-02-05 16:42:32 +03:00
|
|
|
node.close ? path.call(print, "close") : ""
|
2017-06-06 00:28:38 +10:00
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
case "value-value": {
|
|
|
|
|
return path.call(print, "group");
|
|
|
|
|
}
|
|
|
|
|
case "value-func": {
|
2018-04-26 13:53:52 +03:00
|
|
|
const insideAtRuleSupportsNode = insideAtRuleNode(path, "supports");
|
2018-04-25 20:41:41 +03:00
|
|
|
const isKeyword =
|
|
|
|
|
["not", "and", "or"].indexOf(node.value.toLowerCase()) !== -1;
|
|
|
|
|
|
|
|
|
|
return concat([
|
|
|
|
|
node.value,
|
2018-04-26 13:53:52 +03:00
|
|
|
insideAtRuleSupportsNode && isKeyword ? " " : "",
|
2018-04-25 20:41:41 +03:00
|
|
|
path.call(print, "group")
|
|
|
|
|
]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-paren": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return node.value;
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-number": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return concat([printNumber(node.value), maybeToLowerCase(node.unit)]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-operator": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return node.value;
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-word": {
|
2018-02-05 16:42:32 +03:00
|
|
|
if ((node.isColor && node.isHex) || isWideKeywords(node.value)) {
|
|
|
|
|
return node.value.toLowerCase();
|
2017-06-20 23:07:31 +10:00
|
|
|
}
|
2018-05-15 01:08:04 +03:00
|
|
|
|
2018-02-05 16:42:32 +03:00
|
|
|
return node.value;
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-colon": {
|
2018-04-26 13:53:52 +03:00
|
|
|
return concat([
|
|
|
|
|
node.value,
|
|
|
|
|
insideValueFunctionNode(path, "url") ? "" : line
|
|
|
|
|
]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-comma": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return concat([node.value, " "]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-string": {
|
2018-02-09 13:17:48 +01:00
|
|
|
return privateUtil.printString(
|
2018-02-05 16:42:32 +03:00
|
|
|
node.raws.quote + node.value + node.raws.quote,
|
|
|
|
|
options
|
|
|
|
|
);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
case "value-atword": {
|
2018-02-05 16:42:32 +03:00
|
|
|
return concat(["@", node.value]);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
2018-03-07 21:15:06 +03:00
|
|
|
case "value-unicode-range": {
|
|
|
|
|
return node.value;
|
|
|
|
|
}
|
2018-05-15 00:00:45 +03:00
|
|
|
case "value-unknown": {
|
|
|
|
|
return node.value;
|
|
|
|
|
}
|
2017-06-06 00:28:38 +10:00
|
|
|
default:
|
2017-09-03 22:40:44 +02:00
|
|
|
/* istanbul ignore next */
|
2018-02-22 12:00:08 +03:00
|
|
|
throw new Error(`Unknown postcss type ${JSON.stringify(node.type)}`);
|
2017-06-06 00:28:38 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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(
|
2018-02-09 13:17:48 +01:00
|
|
|
options.locStart(childNode),
|
|
|
|
|
options.locEnd(childNode)
|
2017-06-11 00:45:59 +10:00
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
} 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" &&
|
2018-02-09 13:17:48 +01:00
|
|
|
!privateUtil.hasNewline(
|
2017-06-11 00:40:05 +10:00
|
|
|
options.originalText,
|
2018-02-09 13:17:48 +01:00
|
|
|
options.locStart(node.nodes[i + 1]),
|
2017-06-11 00:40:05 +10:00
|
|
|
{ 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);
|
2018-02-09 13:17:48 +01:00
|
|
|
if (
|
|
|
|
|
sharedUtil.isNextLineEmpty(
|
|
|
|
|
options.originalText,
|
|
|
|
|
pathChild.getValue(),
|
|
|
|
|
options
|
|
|
|
|
)
|
|
|
|
|
) {
|
2017-06-06 00:28:38 +10:00
|
|
|
parts.push(hardline);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
}, "nodes");
|
|
|
|
|
|
|
|
|
|
return concat(parts);
|
|
|
|
|
}
|
|
|
|
|
|
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) {
|
2018-02-09 13:17:48 +01:00
|
|
|
return value.replace(STRING_REGEX, match =>
|
|
|
|
|
privateUtil.printString(match, options)
|
|
|
|
|
);
|
2017-08-14 08:57:16 +02:00
|
|
|
}
|
|
|
|
|
|
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 (
|
2018-02-09 13:17:48 +01:00
|
|
|
privateUtil
|
2017-08-15 17:25:57 +02:00
|
|
|
.printNumber(rawNumber)
|
|
|
|
|
// Remove trailing `.0`.
|
|
|
|
|
.replace(/\.0(?=$|e)/, "")
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-26 12:23:50 +11:00
|
|
|
module.exports = {
|
|
|
|
|
print: genericPrint,
|
2018-02-09 13:17:48 +01:00
|
|
|
hasPrettierIgnore: privateUtil.hasIgnoreComment,
|
2017-12-30 21:30:09 +11:00
|
|
|
massageAstNode: clean
|
2017-12-26 12:23:50 +11:00
|
|
|
};
|