Comparing version
@@ -32,3 +32,3 @@ | ||
, darkcyan: [0, 139, 139] | ||
, darkgoldenrod: [184, 132, 11] | ||
, darkgoldenrod: [184, 134, 11] | ||
, darkgray: [169, 169, 169] | ||
@@ -56,3 +56,3 @@ , darkgreen: [0, 100, 0] | ||
, firebrick: [178, 34, 34] | ||
, floralwhite: [255, 255, 240] | ||
, floralwhite: [255, 250, 240] | ||
, forestgreen: [34, 139, 34] | ||
@@ -127,3 +127,3 @@ , fuchsia: [255, 0, 255] | ||
, pink: [255, 192, 203] | ||
, plum: [221, 160, 203] | ||
, plum: [221, 160, 221] | ||
, powderblue: [176, 224, 230] | ||
@@ -143,5 +143,5 @@ , purple: [128, 0, 128] | ||
, slateblue: [106, 90, 205] | ||
, slategray: [119, 128, 144] | ||
, slategrey: [119, 128, 144] | ||
, snow: [255, 255, 250] | ||
, slategray: [112, 128, 144] | ||
, slategrey: [112, 128, 144] | ||
, snow: [255, 250, 250] | ||
, springgreen: [0, 255, 127] | ||
@@ -159,3 +159,3 @@ , steelblue: [70, 130, 180] | ||
, yellow: [255, 255, 0] | ||
, yellowgreen: [154, 205, 5] | ||
, yellowgreen: [154, 205, 50] | ||
}; |
@@ -573,2 +573,19 @@ | ||
/** | ||
* Set a variable `name` on current scope. | ||
* | ||
* @param {String} name | ||
* @param {Expression} expr | ||
* @api public | ||
*/ | ||
exports.define = function define(name, expr){ | ||
utils.assertType(name, 'string', 'name'); | ||
expr = utils.unwrap(expr); | ||
var scope = this.currentScope; | ||
var node = new nodes.Ident(name.val, expr); | ||
scope.add(node); | ||
return nodes.null; | ||
}; | ||
/** | ||
* Perform `op` on the `left` and `right` operands. | ||
@@ -968,2 +985,27 @@ * | ||
/** | ||
* Return the tangent of the given `angle`. | ||
* | ||
* @param {Unit} angle | ||
* @return {Unit} | ||
* @api public | ||
*/ | ||
exports.tan = function tan(angle) { | ||
utils.assertType(angle, 'unit', 'angle'); | ||
var radians = angle.val; | ||
if (angle.type === 'deg') { | ||
radians *= Math.PI / 180; | ||
} | ||
var m = Math.pow(10, 9); | ||
var sin = Math.round(Math.sin(radians) * m) / m | ||
, cos = Math.round(Math.cos(radians) * m) / m | ||
, tan = Math.round(m * sin / cos ) / m; | ||
return new nodes.Unit(tan, ''); | ||
} | ||
/** | ||
* Apply Math `fn` to `n`. | ||
@@ -1112,2 +1154,23 @@ * | ||
/** | ||
* Prefix css classes in a block | ||
* | ||
* @param {String} prefix | ||
* @param {Block} block | ||
* @return {Block} | ||
* @api private | ||
*/ | ||
exports['-prefix-classes'] = function prefixClasses(prefix, block){ | ||
utils.assertString(prefix, 'prefix'); | ||
utils.assertType(block, 'block', 'block'); | ||
var _prefix = this.prefix; | ||
this.prefix = prefix.string; | ||
block = this.visit(block); | ||
this.prefix = _prefix; | ||
return block; | ||
}; | ||
/** | ||
* Attempt to parse unit `str`. | ||
@@ -1147,3 +1210,3 @@ * | ||
else if (str.substr(0,3) === 'rgb'){ | ||
var m = str.match(/(\d\.*\d+)/g); | ||
var m = str.match(/([0-9]*\.?[0-9]+)/g); | ||
if (!m) return; | ||
@@ -1150,0 +1213,0 @@ m = m.map(function(s){return parseFloat(s, 10)}); |
@@ -413,2 +413,3 @@ | ||
* | 'and' | ||
* | 'only' | ||
* | 'or' | ||
@@ -425,3 +426,3 @@ * | 'is' | ||
, tok; | ||
if (captures = /^(not|and|or|is a|is defined|isnt|is not|is)(?!-)\b([ \t]*)/.exec(this.str)) { | ||
if (captures = /^(not|and|only|or|is a|is defined|isnt|is not|is)(?!-)\b([ \t]*)/.exec(this.str)) { | ||
var op = captures[1]; | ||
@@ -491,3 +492,3 @@ this.skip(captures); | ||
/** | ||
* '@extends' ([^{\n]+) | ||
* '@extends' | ||
*/ | ||
@@ -497,5 +498,5 @@ | ||
var captures; | ||
if (captures = /^@extends?[ \t]*([^\/{\n;]+)/.exec(this.str)) { | ||
if (captures = /^@extends?[ \t]*/.exec(this.str)) { | ||
this.skip(captures); | ||
return new Token('extend', captures[1].trim()); | ||
return new Token('extend'); | ||
} | ||
@@ -505,3 +506,3 @@ }, | ||
/** | ||
* '@media' ([^{\n]+) | ||
* '@media' | ||
*/ | ||
@@ -511,5 +512,5 @@ | ||
var captures; | ||
if (captures = /^@media[ \t]*(.+?)(?=\/\/|[\n{])/.exec(this.str)) { | ||
if (captures = /^@media[ \t]*/.exec(this.str)) { | ||
this.skip(captures); | ||
return new Token('media', captures[1].trim()); | ||
return new Token('media'); | ||
} | ||
@@ -516,0 +517,0 @@ }, |
@@ -15,11 +15,11 @@ | ||
/** | ||
* Initialize a new `Extend` with the given `selector`. | ||
* Initialize a new `Extend` with the given `selectors` array. | ||
* | ||
* @param {Selector} selector | ||
* @param {Array} selectors array of the selectors | ||
* @api public | ||
*/ | ||
var Extend = module.exports = function Extend(selector){ | ||
var Extend = module.exports = function Extend(selectors){ | ||
Node.call(this); | ||
this.selector = selector; | ||
this.selectors = selectors; | ||
}; | ||
@@ -41,7 +41,7 @@ | ||
Extend.prototype.clone = function(){ | ||
return new Extend(this.selector); | ||
return new Extend(this.selectors); | ||
}; | ||
/** | ||
* Return `@extend selector`. | ||
* Return `@extend selectors`. | ||
* | ||
@@ -53,3 +53,3 @@ * @return {String} | ||
Extend.prototype.toString = function(){ | ||
return '@extend ' + this.selector; | ||
return '@extend ' + this.selectors.join(', '); | ||
}; |
@@ -65,2 +65,13 @@ | ||
/** | ||
* Check if this set has only placeholders. | ||
* | ||
* @return {Boolean} | ||
* @api public | ||
*/ | ||
Group.prototype.__defineGetter__('hasOnlyPlaceholders', function(){ | ||
return this.nodes.every(function(selector) { return selector.isPlaceholder; }); | ||
}); | ||
/** | ||
* Return a clone of this node. | ||
@@ -67,0 +78,0 @@ * |
@@ -35,2 +35,5 @@ | ||
exports.Media = require('./media'); | ||
exports.QueryList = require('./query-list'); | ||
exports.Query = require('./query'); | ||
exports.QueryExpr = require('./query-expression'); | ||
exports.Params = require('./params'); | ||
@@ -37,0 +40,0 @@ exports.Comment = require('./comment'); |
@@ -26,2 +26,3 @@ | ||
this.string = str; | ||
this.prefixed = false; | ||
}; | ||
@@ -28,0 +29,0 @@ |
@@ -41,3 +41,3 @@ | ||
Media.prototype.clone = function(){ | ||
var clone = new Media(this.val); | ||
var clone = new Media(this.val.clone()); | ||
clone.block = this.block.clone(); | ||
@@ -48,2 +48,13 @@ return clone; | ||
/** | ||
* Check if media block has properties. | ||
* | ||
* @return {Boolean} | ||
* @api public | ||
*/ | ||
Media.prototype.__defineGetter__('hasProperties', function(){ | ||
return hasProperties(this.block); | ||
}); | ||
/** | ||
* Return @media "val". | ||
@@ -58,1 +69,17 @@ * | ||
}; | ||
function hasProperties(block) { | ||
for (var i = 0, len = block.nodes.length; i < len; i++) { | ||
var node = block.nodes[i]; | ||
switch (node.nodeName) { | ||
case 'property': | ||
return true; | ||
case 'group': | ||
return !node.hasOnlyPlaceholders && hasProperties(node.block); | ||
case 'block': | ||
return hasProperties(node); | ||
default: | ||
if (node.block) return hasProperties(node.block); | ||
} | ||
} | ||
} |
@@ -12,3 +12,3 @@ | ||
var BinOp = require('./binop'); | ||
var Node = require('./node'); | ||
@@ -24,10 +24,12 @@ /** | ||
var Member = module.exports = function Member(left, right){ | ||
BinOp.call(this, '.', left, right); | ||
Node.call(this); | ||
this.left = left; | ||
this.right = right; | ||
}; | ||
/** | ||
* Inherit from `BinOp.prototype`. | ||
* Inherit from `Node.prototype`. | ||
*/ | ||
Member.prototype.__proto__ = BinOp.prototype; | ||
Member.prototype.__proto__ = Node.prototype; | ||
@@ -42,4 +44,6 @@ /** | ||
Member.prototype.clone = function(){ | ||
var clone = BinOp.prototype.clone.call(this); | ||
clone.constructor = Member; | ||
var clone = new Member(this.left.clone(), this.right.clone()); | ||
clone.lineno = this.lineno; | ||
clone.filename = this.filename; | ||
if (this.val) clone.val = this.val.clone(); | ||
return clone; | ||
@@ -46,0 +50,0 @@ }; |
@@ -46,2 +46,13 @@ | ||
/** | ||
* Check if this is placeholder selector. | ||
* | ||
* @return {Boolean} | ||
* @api public | ||
*/ | ||
Selector.prototype.__defineGetter__('isPlaceholder', function(){ | ||
return this.val && ~this.val.substr(0, 2).indexOf('$'); | ||
}); | ||
/** | ||
* Return a clone of this node. | ||
@@ -48,0 +59,0 @@ * |
@@ -28,2 +28,3 @@ /*! | ||
this.string = val; | ||
this.prefixed = false; | ||
if (typeof quote !== 'string') { | ||
@@ -122,3 +123,5 @@ this.quote = "'"; | ||
case '+': | ||
return new String(this.val + this.coerce(right).val); | ||
var expr = new nodes.Expression; | ||
expr.push(new String(this.val + this.coerce(right).val)); | ||
return expr; | ||
default: | ||
@@ -125,0 +128,0 @@ return Node.prototype.operate.call(this, op, right); |
@@ -26,3 +26,3 @@ | ||
Node.call(this); | ||
this.val = val; | ||
this.val = parseFloat( val.toFixed( 15 ) ); | ||
this.type = type; | ||
@@ -65,3 +65,3 @@ }; | ||
* Return a clone of this node. | ||
* | ||
* | ||
* @return {Node} | ||
@@ -108,7 +108,7 @@ * @api public | ||
return new Unit(this.val - right.val, type); | ||
case '+': | ||
case '+': | ||
return new Unit(this.val + right.val, type); | ||
case '/': | ||
case '/': | ||
return new Unit(this.val / right.val, type); | ||
case '*': | ||
case '*': | ||
return new Unit(this.val * right.val, type); | ||
@@ -149,6 +149,6 @@ case '%': | ||
* in -> mm | cm | ||
* | ||
* | ||
* ms -> s | ||
* s -> ms | ||
* | ||
* | ||
* Hz -> kHz | ||
@@ -176,3 +176,3 @@ * kHz -> Hz | ||
} else if ('string' == other.nodeName) { | ||
var val = parseInt(other.val, 10); | ||
var val = parseFloat(other.val); | ||
if (isNaN(val)) Node.prototype.coerce.call(this, other); | ||
@@ -179,0 +179,0 @@ return new nodes.Unit(val); |
@@ -100,3 +100,2 @@ | ||
, 'placeholder-shown' | ||
, 'default' | ||
, 'checked' | ||
@@ -155,2 +154,3 @@ , 'indeterminate' | ||
this.lexer = new Lexer(str, options); | ||
this.prefix = options.prefix || ''; | ||
this.root = options.root || new nodes.Root; | ||
@@ -416,2 +416,12 @@ this.state = ['root']; | ||
/** | ||
* Consume spaces and comments. | ||
*/ | ||
skipSpacesAndComments: function() { | ||
while ('space' == this.peek().type | ||
|| 'comment' == this.peek().type) | ||
this.next(); | ||
}, | ||
/** | ||
* Check if the following sequence of tokens | ||
@@ -892,17 +902,21 @@ * forms a function definition, ie trailing | ||
extend: function(){ | ||
var val = this.expect('extend').val | ||
, arr = this.selectorParts(); | ||
this.expect('extend'); | ||
var selectors = [] | ||
, arr; | ||
arr.unshift(new nodes.Literal(val)); | ||
do { | ||
arr = this.selectorParts(); | ||
if (arr.length) selectors.push(new nodes.Selector(arr)); | ||
} while(this.accept(',')); | ||
return new nodes.Extend(new nodes.Selector(arr)); | ||
return new nodes.Extend(selectors); | ||
}, | ||
/** | ||
* media | ||
* media queries | ||
*/ | ||
media: function() { | ||
var val = this.expect('media').val | ||
, media = new nodes.Media(val); | ||
this.expect('media'); | ||
var media = new nodes.Media(this.queries()); | ||
this.state.push('media'); | ||
@@ -915,2 +929,63 @@ media.block = this.block(media); | ||
/** | ||
* query (',' query)* | ||
*/ | ||
queries: function() { | ||
var queries = new nodes.QueryList; | ||
do { | ||
queries.push(this.query()); | ||
} while(this.accept(',')); | ||
return queries; | ||
}, | ||
/** | ||
* ('only' | 'not')? ident ('and' queryExpr)* | ||
* | queryExpr ('and' queryExpr)* | ||
*/ | ||
query: function() { | ||
this.skipSpacesAndComments(); | ||
var pred = this.accept('only') || this.accept('not') | ||
, id | ||
, query; | ||
this.skipSpacesAndComments(); | ||
if (id = this.accept('ident')) { | ||
query = new nodes.Query(new nodes.QueryExpr([id.val])); | ||
} else { | ||
query = new nodes.Query(this.queryExpr()); | ||
} | ||
if (pred) query.predicate = new nodes.Literal(pred.val); | ||
this.skipSpacesAndComments(); | ||
if (this.accept('&&')) { | ||
do { | ||
query.push(this.queryExpr()); | ||
} while(this.accept('&&')); | ||
} | ||
return query; | ||
}, | ||
/** | ||
* '(' ident ( ':'? expression )? ')' | ||
*/ | ||
queryExpr: function() { | ||
this.skipSpacesAndComments(); | ||
this.expect('('); | ||
this.skipSpacesAndComments(); | ||
var node = new nodes.QueryExpr(this.interpolate()); | ||
this.skipSpacesAndComments(); | ||
this.accept(':') | ||
this.skipSpacesAndComments(); | ||
node.expr = this.expression(); | ||
this.skipSpacesAndComments(); | ||
this.expect(')'); | ||
this.skipSpacesAndComments(); | ||
return node; | ||
}, | ||
/** | ||
* @-moz-document block | ||
@@ -1306,2 +1381,7 @@ */ | ||
break; | ||
case this.prefix && '.': | ||
var literal = new nodes.Literal(tok.val + this.prefix); | ||
literal.prefixed = true; | ||
arr.push(literal); | ||
break; | ||
case 'comment': | ||
@@ -1308,0 +1388,0 @@ arr.push(new nodes.Literal(tok.val.str)); |
@@ -108,2 +108,33 @@ | ||
/** | ||
* Get dependencies of the compiled file. | ||
* | ||
* @param {String} [filename] | ||
* @return {Array} | ||
* @api public | ||
*/ | ||
Renderer.prototype.deps = function(filename){ | ||
if (filename) this.options.filename = filename; | ||
var DepsResolver = require('./visitor/deps-resolver') | ||
, parser = new Parser(this.str, this.options); | ||
try { | ||
nodes.filename = this.options.filename; | ||
// parse | ||
var ast = parser.parse() | ||
, resolver = new DepsResolver(ast, this.options); | ||
// resolve dependencies | ||
return resolver.resolve(); | ||
} catch (err) { | ||
var options = {}; | ||
options.input = err.input || this.str; | ||
options.filename = err.filename || this.options.filename; | ||
options.lineno = err.lineno || parser.lexer.lineno; | ||
throw utils.formatException(err, options); | ||
} | ||
}; | ||
/** | ||
* Set option `key` to `val`. | ||
@@ -175,3 +206,3 @@ * | ||
Renderer.prototype.define = function(name, fn, raw){ | ||
fn = utils.coerce(fn); | ||
fn = utils.coerce(fn, raw); | ||
@@ -178,0 +209,0 @@ if (fn.nodeName) { |
@@ -13,2 +13,4 @@ | ||
var nodes = require('./nodes') | ||
, basename = require('path').basename | ||
, relative = require('path').relative | ||
, join = require('path').join | ||
@@ -107,2 +109,38 @@ , resolve = require('path').resolve | ||
/** | ||
* Lookup index file inside dir with given `name`. | ||
* | ||
* @param {String} name | ||
* @return {Array} | ||
* @api private | ||
*/ | ||
exports.lookupIndex = function(name, paths, filename){ | ||
// foo/index.styl | ||
var found = exports.find(join(name, 'index.styl'), paths, filename); | ||
if (!found) { | ||
// foo/foo.styl | ||
found = exports.find(join(name, basename(name).replace(/\.styl/i, '') + '.styl'), paths, filename); | ||
} | ||
if (!found && !~name.indexOf('node_modules')) { | ||
// node_modules/foo/.. or node_modules/foo.styl/.. | ||
found = lookupPackage(join('node_modules', name)); | ||
} | ||
return found; | ||
function lookupPackage(dir) { | ||
var package = exports.lookup(join(dir, 'package.json'), paths, filename); | ||
if (!package) { | ||
return /\.styl$/i.test(dir) ? exports.lookupIndex(dir, paths, filename) : lookupPackage(dir + '.styl'); | ||
} | ||
var main = require(relative(__dirname, package)).main; | ||
if (main) { | ||
found = exports.find(join(dir, main), paths, filename); | ||
} else { | ||
found = exports.lookupIndex(dir, paths, filename); | ||
} | ||
return found; | ||
} | ||
}; | ||
/** | ||
* Format the given `err` with the given `options`. | ||
@@ -253,2 +291,3 @@ * | ||
* @param {Mixed} val | ||
* @param {Boolean} [raw] | ||
* @return {Node} | ||
@@ -258,3 +297,3 @@ * @api public | ||
exports.coerce = function(val){ | ||
exports.coerce = function(val, raw){ | ||
switch (typeof val) { | ||
@@ -271,5 +310,5 @@ case 'function': | ||
if (null == val) return nodes.null; | ||
if (Array.isArray(val)) return exports.coerceArray(val); | ||
if (Array.isArray(val)) return exports.coerceArray(val, raw); | ||
if (val.nodeName) return val; | ||
return exports.coerceObject(val); | ||
return exports.coerceObject(val, raw); | ||
} | ||
@@ -282,2 +321,3 @@ }; | ||
* @param {Array} val | ||
* @param {Boolean} [raw] | ||
* @return {Expression} | ||
@@ -287,6 +327,6 @@ * @api private | ||
exports.coerceArray = function(val){ | ||
exports.coerceArray = function(val, raw){ | ||
var expr = new nodes.Expression; | ||
val.forEach(function(val){ | ||
expr.push(exports.coerce(val)); | ||
expr.push(exports.coerce(val, raw)); | ||
}); | ||
@@ -297,23 +337,29 @@ return expr; | ||
/** | ||
* Coerce a javascript object to a Stylus `Expression`. | ||
* Coerce a javascript object to a Stylus `Expression` or `Object`. | ||
* | ||
* For example `{ foo: 'bar', bar: 'baz' }` would become | ||
* the expression `(foo 'bar') (bar 'baz')`. | ||
* the expression `(foo 'bar') (bar 'baz')`. If `raw` is true | ||
* given `obj` would become a Stylus hash object. | ||
* | ||
* @param {Object} obj | ||
* @return {Expression} | ||
* @param {Boolean} [raw] | ||
* @return {Expression|Object} | ||
* @api public | ||
*/ | ||
exports.coerceObject = function(obj){ | ||
var expr = new nodes.Expression | ||
exports.coerceObject = function(obj, raw){ | ||
var node = raw ? new nodes.Object : new nodes.Expression | ||
, val; | ||
for (var key in obj) { | ||
val = exports.coerce(obj[key]); | ||
val = exports.coerce(obj[key], raw); | ||
key = new nodes.Ident(key); | ||
expr.push(exports.coerceArray([key, val])); | ||
if (raw) { | ||
node.set(key, val); | ||
} else { | ||
node.push(exports.coerceArray([key, val])); | ||
} | ||
} | ||
return expr; | ||
return node; | ||
}; | ||
@@ -350,2 +396,23 @@ | ||
/** | ||
* Returns an array with unique values. | ||
* | ||
* @param {Array} arr | ||
* @return {Array} | ||
* @api private | ||
*/ | ||
exports.uniq = function(arr){ | ||
var obj = {} | ||
, ret = []; | ||
for (var i = 0, len = arr.length; i < len; ++i) { | ||
if (arr[i] in obj) continue; | ||
obj[arr[i]] = true; | ||
ret.push(arr[i]); | ||
} | ||
return ret; | ||
}; | ||
/** | ||
* Compile selector strings in `arr` from the bottom-up | ||
@@ -352,0 +419,0 @@ * to produce the selector combinations. For example |
@@ -185,3 +185,6 @@ /*! | ||
Compiler.prototype.visitMedia = function(media){ | ||
this.buf += '@media ' + media.val; | ||
if (!media.hasProperties) return ''; | ||
this.buf += '@media '; | ||
this.visit(media.val); | ||
this.buf += this.compress ? '{' : ' {\n'; | ||
@@ -195,2 +198,39 @@ ++this.indents; | ||
/** | ||
* Visit QueryList. | ||
*/ | ||
Compiler.prototype.visitQueryList = function(queries){ | ||
for (var i = 0, len = queries.nodes.length; i < len; ++i) { | ||
this.visit(queries.nodes[i]); | ||
if (len - 1 != i) this.buf += ',' + (this.compress ? '' : ' '); | ||
} | ||
}; | ||
/** | ||
* Visit Query. | ||
*/ | ||
Compiler.prototype.visitQuery = function(node){ | ||
if (node.predicate) this.buf += node.predicate + ' '; | ||
for (var i = 0, len = node.nodes.length; i < len; ++i) { | ||
this.visit(node.nodes[i]); | ||
if (len - 1 != i) this.buf += ' and '; | ||
} | ||
}; | ||
/** | ||
* Visit QueryExpr. | ||
*/ | ||
Compiler.prototype.visitQueryExpr = function(node){ | ||
if (!node.expr) { | ||
this.buf += node.name; | ||
} else if (node.expr.isEmpty) { | ||
this.buf += '(' + node.name + ')'; | ||
} else { | ||
this.buf += '(' + node.name + ':' + (this.compress ? '' : ' ') + this.visit(node.expr) + ')'; | ||
} | ||
}; | ||
/** | ||
* Visit MozDocument. | ||
@@ -348,6 +388,7 @@ */ | ||
var selectors = utils.compileSelectors.call(this, stack); | ||
if(selectors.length) | ||
if (selectors.length) { | ||
this.buf += (this.selector = selectors.join(this.compress ? ',' : ',\n')); | ||
else | ||
} else { | ||
group.block.lacksRenderedSelectors = true; | ||
} | ||
} | ||
@@ -354,0 +395,0 @@ |
@@ -20,6 +20,3 @@ | ||
, bifs = require('../functions') | ||
, basename = require('path').basename | ||
, dirname = require('path').dirname | ||
, relative = require('path').relative | ||
, join = require('path').join | ||
, colors = require('../colors') | ||
@@ -130,2 +127,3 @@ , debug = require('debug')('stylus:evaluator') | ||
this.paths = options.paths || []; | ||
this.prefix = options.prefix || ''; | ||
this.filename = options.filename; | ||
@@ -240,39 +238,2 @@ this.includeCSS = options['include css']; | ||
/** | ||
* Lookup index file for @import. | ||
* | ||
* @param {String} name | ||
* @return {Array} | ||
* @api private | ||
*/ | ||
Evaluator.prototype.lookupIndex = function(name){ | ||
// foo/index.styl | ||
var found = utils.find(join(name, 'index.styl'), this.paths, this.filename) | ||
, self = this; | ||
if (!found) { | ||
// foo/foo.styl | ||
found = utils.find(join(name, basename(name).replace(/\.styl/i, '') + '.styl'), this.paths, this.filename); | ||
} | ||
if (!found && !~name.indexOf('node_modules')) { | ||
// node_modules/foo/.. or node_modules/foo.styl/.. | ||
found = lookupPackage(join('node_modules', name)); | ||
} | ||
return found; | ||
function lookupPackage(dir) { | ||
var package = utils.lookup(join(dir, 'package.json'), self.paths, self.filename); | ||
if (!package) { | ||
return /\.styl$/i.test(dir) ? self.lookupIndex(dir) : lookupPackage(dir + '.styl'); | ||
} | ||
var main = require(relative(__dirname, package)).main; | ||
if (main) { | ||
found = utils.find(join(dir, main), self.paths, self.filename); | ||
} else { | ||
found = self.lookupIndex(dir); | ||
} | ||
return found; | ||
} | ||
}; | ||
/** | ||
* Visit Group. | ||
@@ -315,4 +276,3 @@ */ | ||
media.block = this.visit(media.block); | ||
var query = this.lookup(media.val); | ||
if (query) media.val = new nodes.Literal(query.first.string); | ||
media.val = this.visit(media.val); | ||
return media; | ||
@@ -322,2 +282,35 @@ }; | ||
/** | ||
* Visit QueryList. | ||
*/ | ||
Evaluator.prototype.visitQueryList = function(queries){ | ||
queries.nodes.forEach(this.visit, this); | ||
return queries; | ||
}; | ||
/** | ||
* Visit Query. | ||
*/ | ||
Evaluator.prototype.visitQuery = function(node){ | ||
node.predicate = this.visit(node.predicate); | ||
node.nodes.forEach(this.visit, this); | ||
return node; | ||
}; | ||
/** | ||
* Visit QueryExpr. | ||
*/ | ||
Evaluator.prototype.visitQueryExpr = function(node){ | ||
var val; | ||
node.name = node.name || this.interpolate(node); | ||
if (node.expr) node.expr = this.visit(node.expr); | ||
if (val = this.lookup(node.name)) { | ||
node.name = new nodes.Literal(val.first.string || val.first.name); | ||
} | ||
return node; | ||
}; | ||
/** | ||
* Visit MozDocument. | ||
@@ -825,8 +818,10 @@ */ | ||
Evaluator.prototype.visitExtend = function(extend){ | ||
// Cloning the selector for when we are in a loop and don't want it to affect | ||
// the selector nodes and cause the values to be different to expected | ||
var selector = this.interpolate(extend.selector.clone()); | ||
var block = this.currentBlock; | ||
if ('group' != block.node.nodeName) block = this.closestGroup; | ||
block.node.extends.push(selector); | ||
extend.selectors.forEach(function(selector){ | ||
// Cloning the selector for when we are in a loop and don't want it to affect | ||
// the selector nodes and cause the values to be different to expected | ||
selector = this.interpolate(selector.clone()).trim(); | ||
block.node.extends.push(selector); | ||
}, this); | ||
return nodes.null; | ||
@@ -883,3 +878,3 @@ }; | ||
if (!found) { | ||
found = this.lookupIndex(name); | ||
found = utils.lookupIndex(name, this.paths, this.filename); | ||
index = true; | ||
@@ -1358,2 +1353,7 @@ } | ||
case 'string': | ||
if (self.prefix && !node.prefixed && !node.val.nodeName) { | ||
node.val = node.val.replace(/\./g, '.' + self.prefix); | ||
node.prefixed = true; | ||
} | ||
return node.val; | ||
case 'unit': | ||
@@ -1363,3 +1363,3 @@ return node.val; | ||
// Prevent cyclic `selector()` calls. | ||
if (~self.calling.indexOf('selector') && self._selector) return self._selector; | ||
if (self.calling && ~self.calling.indexOf('selector') && self._selector) return self._selector; | ||
self.return++; | ||
@@ -1366,0 +1366,0 @@ var ret = toString(self.visit(node).first); |
@@ -201,2 +201,13 @@ | ||
/** | ||
* Visit Keyframes. | ||
*/ | ||
Normalizer.prototype.visitKeyframes = function(node){ | ||
node.frames = node.frames.filter(function(frame){ | ||
return frame.block.hasProperties; | ||
}); | ||
return node.frames.length ? node : nodes.null; | ||
}; | ||
/** | ||
* Apply `group` extensions. | ||
@@ -203,0 +214,0 @@ * |
{ | ||
"name": "stylus", | ||
"description": "Robust, expressive, and feature-rich CSS superset", | ||
"version": "0.42.3", | ||
"version": "0.43.0", | ||
"author": "TJ Holowaychuk <tj@vision-media.ca>", | ||
@@ -6,0 +6,0 @@ "keywords": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
285382
5.82%73
5.8%10801
5.47%15
7.14%