125 lines
3.2 KiB
JavaScript
125 lines
3.2 KiB
JavaScript
"use strict";
|
|
const Stringifier = require("postcss/lib/stringifier");
|
|
const camelCase = require("./camel-case");
|
|
|
|
class ObjectStringifier extends Stringifier {
|
|
object (node, semicolon) {
|
|
this.builder("{", node, "start");
|
|
|
|
let after;
|
|
if (node.nodes && node.nodes.length) {
|
|
this.body(node);
|
|
after = this.raw(node, "after");
|
|
} else {
|
|
after = this.raw(node, "after", "emptyBody");
|
|
}
|
|
|
|
if (after) this.builder(after);
|
|
this.builder("}", node, "end");
|
|
}
|
|
literal (node, semicolon) {
|
|
this.builder(node.text + (semicolon ? "," : ""), node);
|
|
}
|
|
decl (node, semicolon) {
|
|
let prop = this.rawValue(node, "prop");
|
|
if (prop === "float") {
|
|
prop = "cssFloat";
|
|
}
|
|
let string = prop;
|
|
|
|
const isObjectShorthand = node.raws.node && node.raws.node.shorthand;
|
|
if (!isObjectShorthand) {
|
|
const between = this.raw(node, "between", "colon");
|
|
const value = this.rawValue(node, "value");
|
|
string += between + value;
|
|
}
|
|
|
|
if (semicolon) string += ",";
|
|
this.builder(string, node);
|
|
}
|
|
rule (node, semicolon) {
|
|
this.block(node, this.rawValue(node, "selector"), semicolon);
|
|
}
|
|
atrule (node, semicolon) {
|
|
const name = this.rawValue(node, "name");
|
|
const params = this.rawValue(node, "params");
|
|
if (node.nodes) {
|
|
let string;
|
|
if (params) {
|
|
const afterName = this.raw(node, "afterName");
|
|
string = name + afterName + params;
|
|
} else {
|
|
string = name;
|
|
}
|
|
this.block(node, string, semicolon);
|
|
} else {
|
|
const between = this.raw(node, "between", "colon");
|
|
let string = name + between + params;
|
|
if (semicolon) string += ",";
|
|
this.builder(string, node);
|
|
}
|
|
}
|
|
block (node, start, semicolon) {
|
|
super.block(node, start);
|
|
if (semicolon) {
|
|
this.builder(",", node);
|
|
}
|
|
}
|
|
comment (node) {
|
|
const left = this.raw(node, "left", "commentLeft");
|
|
const right = this.raw(node, "right", "commentRight");
|
|
|
|
if (node.raws.inline) {
|
|
const text = node.raws.text || node.text;
|
|
this.builder("//" + left + text + right, node);
|
|
} else {
|
|
this.builder("/*" + left + node.text + right + "*/", node);
|
|
}
|
|
}
|
|
raw (node, own, detect) {
|
|
let value = super.raw(node, own, detect);
|
|
if ((own === "between" || (own === "afterName" && node.type === "atrule" && !node.nodes)) && !/:/.test(value)) {
|
|
value = ":" + value;
|
|
} else if (own === "before" && /^(decl|rule)$/.test(node.type)) {
|
|
value = value.replace(/\S+$/, "");
|
|
}
|
|
return value;
|
|
}
|
|
rawValue (node, prop) {
|
|
const raw = node.raws[prop];
|
|
if (raw) {
|
|
const descriptor = Object.getOwnPropertyDescriptor(raw, "raw");
|
|
if (descriptor && descriptor.get) {
|
|
return raw.prefix + raw.raw + raw.suffix;
|
|
}
|
|
}
|
|
|
|
let value = super.rawValue(node, prop);
|
|
if (value == null) {
|
|
return value;
|
|
}
|
|
if (/^(prop|selector)$/i.test(prop)) {
|
|
value = camelCase(value);
|
|
if (node.raws.before && /(\S+)$/.test(node.raws.before)) {
|
|
value = RegExp.$1 + value;
|
|
} else if (value && !/\W/.test(value)) {
|
|
return value;
|
|
}
|
|
} else if (node.type === "atrule") {
|
|
if (prop === "name") {
|
|
value = "@" + value;
|
|
} else if (node.nodes) {
|
|
return;
|
|
}
|
|
if (node.nodes) {
|
|
value += this.raw(node, "afterName");
|
|
value += super.rawValue(node, "params");
|
|
}
|
|
}
|
|
value = JSON.stringify(value);
|
|
return value;
|
|
}
|
|
};
|
|
|
|
module.exports = ObjectStringifier;
|