You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
3.3 KiB
153 lines
3.3 KiB
'use strict'; |
|
|
|
const camelCase = require('./camel-case'); |
|
const Stringifier = require('postcss/lib/stringifier'); |
|
|
|
class ObjectStringifier extends Stringifier { |
|
object(node) { |
|
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 || value === undefined) { |
|
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;
|
|
|