UNPKG

4.95 kBJavaScriptView Raw
1
2/**
3 * Module dependencies.
4 */
5
6var Base = require('./compiler');
7var inherits = require('inherits');
8
9/**
10 * Expose compiler.
11 */
12
13module.exports = Compiler;
14
15/**
16 * Initialize a new `Compiler`.
17 */
18
19function Compiler(options) {
20 options = options || {};
21 Base.call(this, options);
22 this.indentation = options.indent;
23}
24
25/**
26 * Inherit from `Base.prototype`.
27 */
28
29inherits(Compiler, Base);
30
31/**
32 * Compile `node`.
33 */
34
35Compiler.prototype.compile = function(node){
36 return this.stylesheet(node);
37};
38
39/**
40 * Visit stylesheet node.
41 */
42
43Compiler.prototype.stylesheet = function(node){
44 return this.mapVisit(node.stylesheet.rules, '\n\n');
45};
46
47/**
48 * Visit comment node.
49 */
50
51Compiler.prototype.comment = function(node){
52 return this.emit(this.indent() + '/*' + node.comment + '*/', node.position);
53};
54
55/**
56 * Visit import node.
57 */
58
59Compiler.prototype.import = function(node){
60 return this.emit('@import ' + node.import + ';', node.position);
61};
62
63/**
64 * Visit media node.
65 */
66
67Compiler.prototype.media = function(node){
68 return this.emit('@media ' + node.media, node.position)
69 + this.emit(
70 ' {\n'
71 + this.indent(1))
72 + this.mapVisit(node.rules, '\n\n')
73 + this.emit(
74 this.indent(-1)
75 + '\n}');
76};
77
78/**
79 * Visit document node.
80 */
81
82Compiler.prototype.document = function(node){
83 var doc = '@' + (node.vendor || '') + 'document ' + node.document;
84
85 return this.emit(doc, node.position)
86 + this.emit(
87 ' '
88 + ' {\n'
89 + this.indent(1))
90 + this.mapVisit(node.rules, '\n\n')
91 + this.emit(
92 this.indent(-1)
93 + '\n}');
94};
95
96/**
97 * Visit charset node.
98 */
99
100Compiler.prototype.charset = function(node){
101 return this.emit('@charset ' + node.charset + ';', node.position);
102};
103
104/**
105 * Visit namespace node.
106 */
107
108Compiler.prototype.namespace = function(node){
109 return this.emit('@namespace ' + node.namespace + ';', node.position);
110};
111
112/**
113 * Visit supports node.
114 */
115
116Compiler.prototype.supports = function(node){
117 return this.emit('@supports ' + node.supports, node.position)
118 + this.emit(
119 ' {\n'
120 + this.indent(1))
121 + this.mapVisit(node.rules, '\n\n')
122 + this.emit(
123 this.indent(-1)
124 + '\n}');
125};
126
127/**
128 * Visit keyframes node.
129 */
130
131Compiler.prototype.keyframes = function(node){
132 return this.emit('@' + (node.vendor || '') + 'keyframes ' + node.name, node.position)
133 + this.emit(
134 ' {\n'
135 + this.indent(1))
136 + this.mapVisit(node.keyframes, '\n')
137 + this.emit(
138 this.indent(-1)
139 + '}');
140};
141
142/**
143 * Visit keyframe node.
144 */
145
146Compiler.prototype.keyframe = function(node){
147 var decls = node.declarations;
148
149 return this.emit(this.indent())
150 + this.emit(node.values.join(', '), node.position)
151 + this.emit(
152 ' {\n'
153 + this.indent(1))
154 + this.mapVisit(decls, '\n')
155 + this.emit(
156 this.indent(-1)
157 + '\n'
158 + this.indent() + '}\n');
159};
160
161/**
162 * Visit page node.
163 */
164
165Compiler.prototype.page = function(node){
166 var sel = node.selectors.length
167 ? node.selectors.join(', ') + ' '
168 : '';
169
170 return this.emit('@page ' + sel, node.position)
171 + this.emit('{\n')
172 + this.emit(this.indent(1))
173 + this.mapVisit(node.declarations, '\n')
174 + this.emit(this.indent(-1))
175 + this.emit('\n}');
176};
177
178/**
179 * Visit font-face node.
180 */
181
182Compiler.prototype['font-face'] = function(node){
183 return this.emit('@font-face ', node.position)
184 + this.emit('{\n')
185 + this.emit(this.indent(1))
186 + this.mapVisit(node.declarations, '\n')
187 + this.emit(this.indent(-1))
188 + this.emit('\n}');
189};
190
191/**
192 * Visit host node.
193 */
194
195Compiler.prototype.host = function(node){
196 return this.emit('@host', node.position)
197 + this.emit(
198 ' {\n'
199 + this.indent(1))
200 + this.mapVisit(node.rules, '\n\n')
201 + this.emit(
202 this.indent(-1)
203 + '\n}');
204};
205
206/**
207 * Visit custom-media node.
208 */
209
210Compiler.prototype['custom-media'] = function(node){
211 return this.emit('@custom-media ' + node.name + ' ' + node.media + ';', node.position);
212};
213
214/**
215 * Visit rule node.
216 */
217
218Compiler.prototype.rule = function(node){
219 var indent = this.indent();
220 var decls = node.declarations;
221 if (!decls.length) return '';
222
223 return this.emit(node.selectors.map(function(s){ return indent + s }).join(',\n'), node.position)
224 + this.emit(' {\n')
225 + this.emit(this.indent(1))
226 + this.mapVisit(decls, '\n')
227 + this.emit(this.indent(-1))
228 + this.emit('\n' + this.indent() + '}');
229};
230
231/**
232 * Visit declaration node.
233 */
234
235Compiler.prototype.declaration = function(node){
236 return this.emit(this.indent())
237 + this.emit(node.property + ': ' + node.value, node.position)
238 + this.emit(';');
239};
240
241/**
242 * Increase, decrease or return current indentation.
243 */
244
245Compiler.prototype.indent = function(level) {
246 this.level = this.level || 1;
247
248 if (null != level) {
249 this.level += level;
250 return '';
251 }
252
253 return Array(this.level).join(this.indentation || ' ');
254};