-
-
Notifications
You must be signed in to change notification settings - Fork 37
/
stringifier.js
114 lines (96 loc) · 2.54 KB
/
stringifier.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
const DEFAULT_RAWS = {
colon: ': ',
commentLeft: ' ',
commentRight: ' ',
indent: ' '
}
module.exports = class Stringifier {
constructor(builder) {
this.builder = builder
}
atrule(node) {
let name = '@' + node.name
let params = node.params ? this.rawValue(node, 'params') : ''
if (this.has(node.raws.afterName)) {
name += node.raws.afterName
} else if (params) {
name += ' '
}
this.block(node, name + params)
}
block(node, start) {
let between = node.raws.sssBetween || ''
this.builder(start + between, node, 'start')
if (this.has(node.nodes)) this.body(node)
}
body(node) {
let indent = node.root().raws.indent || DEFAULT_RAWS.indent
for (let i = 0; i < node.nodes.length; i++) {
let child = node.nodes[i]
let before =
child.raws.before.replace(/[^\n]*$/, '') + this.indent(node, indent)
if (child.type === 'comment' && !child.raws.before.includes('\n')) {
before = child.raws.before
}
if (before) this.builder(before)
this.stringify(child)
}
}
comment(node) {
let left = DEFAULT_RAWS.commentLeft
let right = DEFAULT_RAWS.commentRight
if (this.has(node.raws.left)) left = node.raws.left
if (node.raws.inline) {
if (this.has(node.raws.inlineRight)) {
right = node.raws.inlineRight
} else {
right = ''
}
if (node.raws.extraIndent) {
this.builder(node.raws.extraIndent)
}
this.builder('//' + left + node.text + right, node)
} else {
if (this.has(node.raws.right)) right = node.raws.right
this.builder('/*' + left + node.text + right + '*/', node)
}
}
decl(node) {
let between = node.raws.between || DEFAULT_RAWS.colon
let string = node.prop + between + this.rawValue(node, 'value')
if (node.important) {
string += node.raws.important || ' !important'
}
this.builder(string, node)
}
has(value) {
return typeof value !== 'undefined'
}
indent(node, step) {
let result = ''
while (node.parent) {
result += step
node = node.parent
}
return result
}
rawValue(node, prop) {
let value = node[prop]
let raw = node.raws[prop]
if (raw && raw.value === value) {
return raw.sss || raw.raw
} else {
return value
}
}
root(node) {
this.body(node)
if (node.raws.after) this.builder(node.raws.after)
}
rule(node) {
this.block(node, this.rawValue(node, 'selector'))
}
stringify(node, semicolon) {
this[node.type](node, semicolon)
}
}