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.
		
		
		
		
			
				
					255 lines
				
				4.8 KiB
			
		
		
			
		
	
	
					255 lines
				
				4.8 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * 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 || '  ');
							 | 
						||
| 
								 | 
							
								};
							 |