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 || '  '); | 
						|
};
 | 
						|
 |