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.
254 lines
4.8 KiB
254 lines
4.8 KiB
|
|
/** |
|
* Module dependencies. |
|
*/ |
|
|
|
var Base = require('./compiler'); |
|
var inherits = require('inherits'); |
|
|
|
/** |
|
* Expose compiler. |
|
*/ |
|
|
|
module.exports = Compiler; |
|
|
|
/** |
|
* Initialize a new `Compiler`. |
|
*/ |
|
|
|
function Compiler(options) { |
|
options = options || {}; |
|
Base.call(this, options); |
|
this.indentation = options.indent; |
|
} |
|
|
|
/** |
|
* Inherit from `Base.prototype`. |
|
*/ |
|
|
|
inherits(Compiler, Base); |
|
|
|
/** |
|
* Compile `node`. |
|
*/ |
|
|
|
Compiler.prototype.compile = function(node){ |
|
return this.stylesheet(node); |
|
}; |
|
|
|
/** |
|
* Visit stylesheet node. |
|
*/ |
|
|
|
Compiler.prototype.stylesheet = function(node){ |
|
return this.mapVisit(node.stylesheet.rules, '\n\n'); |
|
}; |
|
|
|
/** |
|
* Visit comment node. |
|
*/ |
|
|
|
Compiler.prototype.comment = function(node){ |
|
return this.emit(this.indent() + '/*' + node.comment + '*/', node.position); |
|
}; |
|
|
|
/** |
|
* Visit import node. |
|
*/ |
|
|
|
Compiler.prototype.import = function(node){ |
|
return this.emit('@import ' + node.import + ';', node.position); |
|
}; |
|
|
|
/** |
|
* Visit media node. |
|
*/ |
|
|
|
Compiler.prototype.media = function(node){ |
|
return this.emit('@media ' + node.media, node.position) |
|
+ this.emit( |
|
' {\n' |
|
+ this.indent(1)) |
|
+ this.mapVisit(node.rules, '\n\n') |
|
+ this.emit( |
|
this.indent(-1) |
|
+ '\n}'); |
|
}; |
|
|
|
/** |
|
* Visit document node. |
|
*/ |
|
|
|
Compiler.prototype.document = function(node){ |
|
var doc = '@' + (node.vendor || '') + 'document ' + node.document; |
|
|
|
return this.emit(doc, node.position) |
|
+ this.emit( |
|
' ' |
|
+ ' {\n' |
|
+ this.indent(1)) |
|
+ this.mapVisit(node.rules, '\n\n') |
|
+ this.emit( |
|
this.indent(-1) |
|
+ '\n}'); |
|
}; |
|
|
|
/** |
|
* Visit charset node. |
|
*/ |
|
|
|
Compiler.prototype.charset = function(node){ |
|
return this.emit('@charset ' + node.charset + ';', node.position); |
|
}; |
|
|
|
/** |
|
* Visit namespace node. |
|
*/ |
|
|
|
Compiler.prototype.namespace = function(node){ |
|
return this.emit('@namespace ' + node.namespace + ';', node.position); |
|
}; |
|
|
|
/** |
|
* Visit supports node. |
|
*/ |
|
|
|
Compiler.prototype.supports = function(node){ |
|
return this.emit('@supports ' + node.supports, node.position) |
|
+ this.emit( |
|
' {\n' |
|
+ this.indent(1)) |
|
+ this.mapVisit(node.rules, '\n\n') |
|
+ this.emit( |
|
this.indent(-1) |
|
+ '\n}'); |
|
}; |
|
|
|
/** |
|
* Visit keyframes node. |
|
*/ |
|
|
|
Compiler.prototype.keyframes = function(node){ |
|
return this.emit('@' + (node.vendor || '') + 'keyframes ' + node.name, node.position) |
|
+ this.emit( |
|
' {\n' |
|
+ this.indent(1)) |
|
+ this.mapVisit(node.keyframes, '\n') |
|
+ this.emit( |
|
this.indent(-1) |
|
+ '}'); |
|
}; |
|
|
|
/** |
|
* Visit keyframe node. |
|
*/ |
|
|
|
Compiler.prototype.keyframe = function(node){ |
|
var decls = node.declarations; |
|
|
|
return this.emit(this.indent()) |
|
+ this.emit(node.values.join(', '), node.position) |
|
+ this.emit( |
|
' {\n' |
|
+ this.indent(1)) |
|
+ this.mapVisit(decls, '\n') |
|
+ this.emit( |
|
this.indent(-1) |
|
+ '\n' |
|
+ this.indent() + '}\n'); |
|
}; |
|
|
|
/** |
|
* Visit page node. |
|
*/ |
|
|
|
Compiler.prototype.page = function(node){ |
|
var sel = node.selectors.length |
|
? node.selectors.join(', ') + ' ' |
|
: ''; |
|
|
|
return this.emit('@page ' + sel, node.position) |
|
+ this.emit('{\n') |
|
+ this.emit(this.indent(1)) |
|
+ this.mapVisit(node.declarations, '\n') |
|
+ this.emit(this.indent(-1)) |
|
+ this.emit('\n}'); |
|
}; |
|
|
|
/** |
|
* Visit font-face node. |
|
*/ |
|
|
|
Compiler.prototype['font-face'] = function(node){ |
|
return this.emit('@font-face ', node.position) |
|
+ this.emit('{\n') |
|
+ this.emit(this.indent(1)) |
|
+ this.mapVisit(node.declarations, '\n') |
|
+ this.emit(this.indent(-1)) |
|
+ this.emit('\n}'); |
|
}; |
|
|
|
/** |
|
* Visit host node. |
|
*/ |
|
|
|
Compiler.prototype.host = function(node){ |
|
return this.emit('@host', node.position) |
|
+ this.emit( |
|
' {\n' |
|
+ this.indent(1)) |
|
+ this.mapVisit(node.rules, '\n\n') |
|
+ this.emit( |
|
this.indent(-1) |
|
+ '\n}'); |
|
}; |
|
|
|
/** |
|
* Visit custom-media node. |
|
*/ |
|
|
|
Compiler.prototype['custom-media'] = function(node){ |
|
return this.emit('@custom-media ' + node.name + ' ' + node.media + ';', node.position); |
|
}; |
|
|
|
/** |
|
* Visit rule node. |
|
*/ |
|
|
|
Compiler.prototype.rule = function(node){ |
|
var indent = this.indent(); |
|
var decls = node.declarations; |
|
if (!decls.length) return ''; |
|
|
|
return this.emit(node.selectors.map(function(s){ return indent + s }).join(',\n'), node.position) |
|
+ this.emit(' {\n') |
|
+ this.emit(this.indent(1)) |
|
+ this.mapVisit(decls, '\n') |
|
+ this.emit(this.indent(-1)) |
|
+ this.emit('\n' + this.indent() + '}'); |
|
}; |
|
|
|
/** |
|
* Visit declaration node. |
|
*/ |
|
|
|
Compiler.prototype.declaration = function(node){ |
|
return this.emit(this.indent()) |
|
+ this.emit(node.property + ': ' + node.value, node.position) |
|
+ this.emit(';'); |
|
}; |
|
|
|
/** |
|
* Increase, decrease or return current indentation. |
|
*/ |
|
|
|
Compiler.prototype.indent = function(level) { |
|
this.level = this.level || 1; |
|
|
|
if (null != level) { |
|
this.level += level; |
|
return ''; |
|
} |
|
|
|
return Array(this.level).join(this.indentation || ' '); |
|
};
|
|
|