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.
307 lines
5.6 KiB
307 lines
5.6 KiB
/*! |
|
* Stylus - CSS to Stylus conversion |
|
* Copyright (c) Automattic <developer.wordpress.com> |
|
* MIT Licensed |
|
*/ |
|
|
|
/** |
|
* Convert the given `css` to Stylus source. |
|
* |
|
* @param {String} css |
|
* @return {String} |
|
* @api public |
|
*/ |
|
|
|
module.exports = function(css){ |
|
return new Converter(css).stylus(); |
|
}; |
|
|
|
/** |
|
* Initialize a new `Converter` with the given `css`. |
|
* |
|
* @param {String} css |
|
* @api private |
|
*/ |
|
|
|
function Converter(css) { |
|
var parse = require('css-parse'); |
|
this.css = css; |
|
this.root = parse(css, { position: false }); |
|
this.indents = 0; |
|
} |
|
|
|
/** |
|
* Convert to Stylus. |
|
* |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.stylus = function(){ |
|
return this.visitRules(this.root.stylesheet.rules); |
|
}; |
|
|
|
/** |
|
* Return indent string. |
|
* |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.__defineGetter__('indent', function(){ |
|
return Array(this.indents + 1).join(' '); |
|
}); |
|
|
|
/** |
|
* Visit `node`. |
|
* |
|
* @param {*} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visit = function(node){ |
|
switch (node.type) { |
|
case 'rule': |
|
case 'comment': |
|
case 'charset': |
|
case 'namespace': |
|
case 'media': |
|
case 'import': |
|
case 'document': |
|
case 'keyframes': |
|
case 'page': |
|
case 'host': |
|
case 'supports': |
|
var name = node.type[0].toUpperCase() + node.type.slice(1); |
|
return this['visit' + name](node); |
|
} |
|
}; |
|
|
|
/** |
|
* Visit the rules on `node`. |
|
* |
|
* @param {Array} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitRules = function(node){ |
|
var buf = ''; |
|
for (var i = 0, len = node.length; i < len; ++i) { |
|
buf += this.visit(node[i]); |
|
} |
|
return buf; |
|
}; |
|
|
|
/** |
|
* Visit Media `node`. |
|
* |
|
* @param {Media} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitMedia = function(node){ |
|
var buf = this.indent + '@media ' + node.media; |
|
buf += '\n'; |
|
++this.indents; |
|
buf += this.visitRules(node.rules); |
|
--this.indents; |
|
return buf; |
|
}; |
|
|
|
/** |
|
* Visit Declaration `node`. |
|
* |
|
* @param {Declaration} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitDeclaration = function(node){ |
|
if ('comment' == node.type) { |
|
return this.visitComment(node); |
|
} else { |
|
var buf = this.indent + node.property + ': ' + node.value + '\n'; |
|
return buf; |
|
} |
|
}; |
|
|
|
/** |
|
* Visit Rule `node`.` |
|
* |
|
* @param {Rule} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitRule = function(node){ |
|
var buf = this.indent + node.selectors.join(',\n' + this.indent) + '\n'; |
|
++this.indents; |
|
for (var i = 0, len = node.declarations.length; i < len; ++i) { |
|
buf += this.visitDeclaration(node.declarations[i]); |
|
} |
|
--this.indents; |
|
return buf + '\n'; |
|
}; |
|
|
|
/** |
|
* Visit Comment `node`.` |
|
* |
|
* @param {Comment} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitComment = function(node){ |
|
var buf = this.indent + '/*' + node.comment + '*/'; |
|
return buf + '\n'; |
|
}; |
|
|
|
/** |
|
* Visit Charset `node`.` |
|
* |
|
* @param {Charset} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitCharset = function(node){ |
|
var buf = this.indent + '@charset ' + node.charset; |
|
return buf + '\n'; |
|
}; |
|
|
|
/** |
|
* Visit Namespace `node`.` |
|
* |
|
* @param {Namespace} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitNamespace = function(node){ |
|
var buf = this.indent + '@namespace ' + node.namespace; |
|
return buf + '\n'; |
|
}; |
|
|
|
/** |
|
* Visit Import `node`.` |
|
* |
|
* @param {Import} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitImport = function(node){ |
|
var buf = this.indent + '@import ' + node.import; |
|
return buf + '\n'; |
|
}; |
|
|
|
/** |
|
* Visit Document `node`.` |
|
* |
|
* @param {Document} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitDocument = function(node){ |
|
var buf = this.indent + '@' + node.vendor + 'document ' + node.document; |
|
buf += '\n'; |
|
++this.indents; |
|
buf += this.visitRules(node.rules); |
|
--this.indents; |
|
return buf; |
|
}; |
|
|
|
/** |
|
* Visit Keyframes `node`.` |
|
* |
|
* @param {Keyframes} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitKeyframes = function(node){ |
|
var buf = this.indent + '@keyframes ' + node.name; |
|
buf += '\n'; |
|
++this.indents; |
|
for (var i = 0, len = node.keyframes.length; i < len; ++i) { |
|
buf += this.visitKeyframe(node.keyframes[i]); |
|
} |
|
--this.indents; |
|
return buf; |
|
}; |
|
|
|
/** |
|
* Visit Keyframe `node`.` |
|
* |
|
* @param {Keyframe} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitKeyframe = function(node){ |
|
var buf = this.indent + node.values.join(', '); |
|
buf += '\n'; |
|
++this.indents; |
|
for (var i = 0, len = node.declarations.length; i < len; ++i) { |
|
buf += this.visitDeclaration(node.declarations[i]); |
|
} |
|
--this.indents; |
|
return buf; |
|
}; |
|
|
|
/** |
|
* Visit Page `node`.` |
|
* |
|
* @param {Page} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitPage = function(node){ |
|
var buf = this.indent + '@page' + (node.selectors.length ? ' ' + node.selectors.join(', ') : ''); |
|
buf += '\n'; |
|
++this.indents; |
|
for (var i = 0, len = node.declarations.length; i < len; ++i) { |
|
buf += this.visitDeclaration(node.declarations[i]); |
|
} |
|
--this.indents; |
|
return buf; |
|
}; |
|
|
|
/** |
|
* Visit Supports `node`.` |
|
* |
|
* @param {Supports} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitSupports = function(node){ |
|
var buf = this.indent + '@supports ' + node.supports; |
|
buf += '\n'; |
|
++this.indents; |
|
buf += this.visitRules(node.rules); |
|
--this.indents; |
|
return buf; |
|
}; |
|
|
|
/** |
|
* Visit Host `node`.` |
|
* |
|
* @param {Host} node |
|
* @return {String} |
|
* @api private |
|
*/ |
|
|
|
Converter.prototype.visitHost = function(node){ |
|
var buf = this.indent + '@host'; |
|
buf += '\n'; |
|
++this.indents; |
|
buf += this.visitRules(node.rules); |
|
--this.indents; |
|
return buf; |
|
};
|
|
|