Comparing version 0.9.2 to 0.10.0
0.10.0 / 2011-03-29 | ||
================== | ||
* Added keyword argument support | ||
* Added `Arguments` node, acts like `Expression` | ||
* Added `utils.params()` | ||
* Added `debug` option to stylus middleware | ||
* Added support for `hsl + 15deg` etc to adjust hue | ||
* Added special-case for percentage based `RGBA` operations (`#eee - 20%`) | ||
* Changed; right-hand colors in operations are not clamped (`#eee * 0.2`) | ||
* Added support for `unit * color` (swaps operands) | ||
* Fixed color component requests on the opposite node type (ex red on hsla node) | ||
* Fixed `Expression#clone()` to support `Arguments` | ||
* Fixed issue with middleware where imports are improperly mapped | ||
* Fixed mutation of color when adjusting values | ||
* Fixed; coerce string to literal | ||
* Removed {darken,lighten}-by() BIFs | ||
0.9.2 / 2011-03-21 | ||
@@ -3,0 +21,0 @@ ================== |
@@ -31,6 +31,6 @@ | ||
/** | ||
* Color component type map. | ||
* Color component unit type map. | ||
*/ | ||
var typeMap = { | ||
var unitMap = { | ||
hue: 'deg' | ||
@@ -42,2 +42,16 @@ , saturation: '%' | ||
/** | ||
* Color type map. | ||
*/ | ||
var typeMap = { | ||
red: 'rgba' | ||
, blue: 'rgba' | ||
, green: 'rgba' | ||
, alpha: 'rgba' | ||
, hue: 'hsla' | ||
, saturation: 'hsla' | ||
, lightness: 'hsla' | ||
}; | ||
/** | ||
* Convert the given `color` to an `HSLA` node, | ||
@@ -54,6 +68,6 @@ * or h,s,l,a component values. | ||
* | ||
* @param {RGBA|HSLA|Unit} h | ||
* @param {Unit} s | ||
* @param {Unit} l | ||
* @param {Unit} a | ||
* @param {RGBA|HSLA|Unit} hue | ||
* @param {Unit} saturation | ||
* @param {Unit} lightness | ||
* @param {Unit} alpha | ||
* @return {HSLA} | ||
@@ -63,13 +77,17 @@ * @api public | ||
exports.hsla = function(h,s,l,a){ | ||
exports.hsla = function(hue, saturation, lightness, alpha){ | ||
switch (arguments.length) { | ||
case 1: | ||
utils.assertColor(h); | ||
return h.hsla; | ||
utils.assertColor(hue); | ||
return hue.hsla; | ||
default: | ||
utils.assertType(h, nodes.Unit, 'hue'); | ||
utils.assertType(s, nodes.Unit, 'saturation'); | ||
utils.assertType(l, nodes.Unit, 'lightness'); | ||
utils.assertType(a, nodes.Unit, 'alpha'); | ||
return new nodes.HSLA(h.val,s.val,l.val,a.val); | ||
utils.assertType(hue, nodes.Unit, 'hue'); | ||
utils.assertType(saturation, nodes.Unit, 'saturation'); | ||
utils.assertType(lightness, nodes.Unit, 'lightness'); | ||
utils.assertType(alpha, nodes.Unit, 'alpha'); | ||
return new nodes.HSLA( | ||
hue.val | ||
, saturation.val | ||
, lightness.val | ||
, alpha.val); | ||
} | ||
@@ -90,5 +108,5 @@ }; | ||
* | ||
* @param {Unit|HSLA|RGBA} h | ||
* @param {Unit} s | ||
* @param {Unit} l | ||
* @param {Unit|HSLA|RGBA} hue | ||
* @param {Unit} saturation | ||
* @param {Unit} lightness | ||
* @return {HSLA} | ||
@@ -98,8 +116,13 @@ * @api public | ||
exports.hsl = function(h,s,l){ | ||
if (arguments.length > 1) { | ||
return exports.hsla(h,s,l,new nodes.Unit(1)); | ||
exports.hsl = function(hue, saturation, lightness){ | ||
if (1 == arguments.length) { | ||
utils.assertColor(hue, 'color'); | ||
return hue.hsla; | ||
} else { | ||
return exports.hsla( | ||
hue | ||
, saturation | ||
, lightness | ||
, new nodes.Unit(1)); | ||
} | ||
utils.assertColor(h, 'color'); | ||
return h.hsla; | ||
}; | ||
@@ -152,6 +175,7 @@ | ||
var name = name.string | ||
, unit = unitMap[name] | ||
, type = typeMap[name] | ||
, name = componentMap[name]; | ||
if (!name) throw new Error('invalid color component "' + name + '"'); | ||
return new nodes.Unit(color[name], type); | ||
return new nodes.Unit(color[type][name], unit); | ||
}; | ||
@@ -224,6 +248,6 @@ | ||
* | ||
* @param {Unit|RGBA|HSLA} r | ||
* @param {Unit} g | ||
* @param {Unit} b | ||
* @param {Unit} a | ||
* @param {Unit|RGBA|HSLA} red | ||
* @param {Unit} green | ||
* @param {Unit} blue | ||
* @param {Unit} alpha | ||
* @return {RGBA} | ||
@@ -233,7 +257,7 @@ * @api public | ||
exports.rgba = function(r,g,b,a){ | ||
exports.rgba = function(red, green, blue, alpha){ | ||
switch (arguments.length) { | ||
case 1: | ||
utils.assertColor(r); | ||
var color = r.rgba; | ||
utils.assertColor(red); | ||
var color = red.rgba; | ||
return new nodes.RGBA( | ||
@@ -245,5 +269,5 @@ color.r | ||
case 2: | ||
utils.assertColor(r); | ||
var color = r.rgba; | ||
utils.assertType(g, nodes.Unit); | ||
utils.assertColor(red); | ||
var color = red.rgba; | ||
utils.assertType(green, nodes.Unit); | ||
return new nodes.RGBA( | ||
@@ -253,13 +277,13 @@ color.r | ||
, color.b | ||
, g.val); | ||
, green.val); | ||
default: | ||
utils.assertType(r, nodes.Unit, 'red'); | ||
utils.assertType(g, nodes.Unit, 'green'); | ||
utils.assertType(b, nodes.Unit, 'blue'); | ||
utils.assertType(a, nodes.Unit, 'alpha'); | ||
utils.assertType(red, nodes.Unit, 'red'); | ||
utils.assertType(green, nodes.Unit, 'green'); | ||
utils.assertType(blue, nodes.Unit, 'blue'); | ||
utils.assertType(alpha, nodes.Unit, 'alpha'); | ||
return new nodes.RGBA( | ||
r.val | ||
, g.val | ||
, b.val | ||
, a.val); | ||
red.val | ||
, green.val | ||
, blue.val | ||
, alpha.val); | ||
} | ||
@@ -279,5 +303,5 @@ }; | ||
* | ||
* @param {Unit|RGBA|HSLA} r | ||
* @param {Unit} g | ||
* @param {Unit} b | ||
* @param {Unit|RGBA|HSLA} red | ||
* @param {Unit} green | ||
* @param {Unit} blue | ||
* @return {RGBA} | ||
@@ -287,7 +311,7 @@ * @api public | ||
exports.rgb = function(r,g,b){ | ||
exports.rgb = function(red, green, blue){ | ||
switch (arguments.length) { | ||
case 1: | ||
utils.assertColor(r); | ||
var color = r.rgba; | ||
utils.assertColor(red); | ||
var color = red.rgba; | ||
return new nodes.RGBA( | ||
@@ -299,3 +323,7 @@ color.r | ||
default: | ||
return exports.rgba(r,g,b,new nodes.Unit(1)); | ||
return exports.rgba( | ||
red | ||
, green | ||
, blue | ||
, new nodes.Unit(1)); | ||
} | ||
@@ -315,3 +343,3 @@ }; | ||
* | ||
* @param {String|Ident} val | ||
* @param {String|Ident} string | ||
* @return {Literal} | ||
@@ -321,5 +349,5 @@ * @api public | ||
exports.unquote = function(val){ | ||
utils.assertString(val, 'string'); | ||
return new nodes.Literal(val.string); | ||
exports.unquote = function(string){ | ||
utils.assertString(string, 'string'); | ||
return new nodes.Literal(string.string); | ||
}; | ||
@@ -560,3 +588,3 @@ | ||
* @param {Unit} amount | ||
* @return {HSLA} | ||
* @return {RGBA} | ||
* @api private | ||
@@ -566,7 +594,9 @@ */ | ||
exports['-adjust'] = function(color, prop, amount){ | ||
var hsl = color.hsla; | ||
var hsl = color.hsla.clone(); | ||
prop = { hue: 'h', saturation: 's', lightness: 'l' }[prop.string]; | ||
if (!prop) throw new Error('invalid adjustment property'); | ||
hsl[prop] = hsl[prop] + amount.val; | ||
return hsl.clone(); | ||
}; | ||
var val = amount.val; | ||
if ('%' == amount.type) val = hsl[prop] * (val / 100); | ||
hsl[prop] += val; | ||
return hsl.rgba; | ||
}; |
@@ -38,2 +38,3 @@ /*! | ||
* `force` Always re-compile | ||
* `debug` Output debugging information | ||
* `src` Source directory used to find .styl files | ||
@@ -91,2 +92,5 @@ * `dest` Destination directory used to output .css files | ||
// Debug option | ||
var debug = options.debug; | ||
// Source dir required | ||
@@ -116,2 +120,7 @@ var src = options.src; | ||
if (debug) { | ||
log('source', stylusPath); | ||
log('dest', cssPath); | ||
} | ||
// Ignore ENOENT to fall through as 404 | ||
@@ -129,2 +138,3 @@ function error(err) { | ||
function compile() { | ||
if (debug) log('read', stylusPath); | ||
fs.readFile(stylusPath, 'utf8', function(err, str){ | ||
@@ -135,4 +145,5 @@ if (err) return error(err); | ||
style.render(function(err, css){ | ||
if (err) return next(err); | ||
if (debug) log('render', stylusPath); | ||
imports[stylusPath] = imports[stylusPath] || paths; | ||
if (err) return next(err); | ||
fs.writeFile(cssPath, css, 'utf8', function(err){ | ||
@@ -145,2 +156,6 @@ next(err); | ||
// Re-compile on server restart, disregarding | ||
// mtimes since we need to map imports | ||
if (!imports[stylusPath]) return compile(); | ||
// Compare mtimes | ||
@@ -153,2 +168,3 @@ fs.stat(stylusPath, function(err, stylusStats){ | ||
if (ENOENT == err.errno) { | ||
if (debug) log('not found', cssPath); | ||
compile(); | ||
@@ -161,2 +177,3 @@ } else { | ||
if (stylusStats.mtime > cssStats.mtime) { | ||
if (debug) log('modified', cssPath); | ||
compile(); | ||
@@ -166,2 +183,3 @@ // Already compiled, check imports | ||
checkImports(stylusPath, function(changed){ | ||
if (debug && changed) log('modified import', changed); | ||
changed ? compile() : next(); | ||
@@ -191,18 +209,35 @@ }); | ||
if (!nodes.length) return fn(); | ||
var pending = nodes.length | ||
, changed = false; | ||
nodes.forEach(function(import){ | ||
fs.stat(import.path, function(err, stat){ | ||
// error | ||
if (err) { | ||
--pending || fn(changed); | ||
// compare mtimes | ||
} else if (import.mtime) { | ||
changed = changed || stat.mtime > import.mtime; | ||
if (!changed) changed = stat.mtime > import.mtime | ||
? import.path | ||
: false; | ||
import.mtime = stat.mtime; | ||
--pending || fn(changed); | ||
// first hit, ignore | ||
} else { | ||
import.mtime = stat.mtime; | ||
--pending || fn(changed = true); | ||
--pending || fn(changed); | ||
} | ||
}); | ||
}); | ||
} | ||
/** | ||
* Log a message. | ||
* | ||
* @api private | ||
*/ | ||
function log(key, val) { | ||
console.error(' \033[90m%s :\033[0m \033[36m%s\033[0m', key, val); | ||
} |
@@ -80,3 +80,3 @@ | ||
Expression.prototype.clone = function(){ | ||
var clone = new Expression(this.isList); | ||
var clone = new this.constructor(this.isList); | ||
clone.preserve = this.preserve; | ||
@@ -83,0 +83,0 @@ clone.lineno = this.lineno; |
@@ -105,2 +105,11 @@ | ||
return other.hsla; | ||
} else if (other instanceof nodes.Unit) { | ||
var n = other.val; | ||
// unit type | ||
switch (other.type) { | ||
case 'deg': return new HSLA(n,0,0,1); | ||
} | ||
return new HSLA(n,n,n,1); | ||
} else { | ||
@@ -206,3 +215,5 @@ return Node.prototype.coerce.call(this, other); | ||
function clampDegrees(n) { | ||
return Math.max(0, Math.min(n, 360)); | ||
if (n > 360) return n - 360; | ||
if (n < 0) return clampDegrees(Math.abs(n)); | ||
return n; | ||
} | ||
@@ -209,0 +220,0 @@ |
@@ -41,2 +41,3 @@ | ||
exports.Expression = require('./expression'); | ||
exports.Arguments = require('./arguments'); | ||
@@ -43,0 +44,0 @@ /** |
@@ -65,4 +65,5 @@ | ||
if (other instanceof Literal || | ||
other instanceof nodes.Ident) { | ||
return other; | ||
other instanceof nodes.Ident || | ||
other instanceof nodes.String) { | ||
return new Literal(other.string); | ||
} else { | ||
@@ -69,0 +70,0 @@ return Node.prototype.coerce.call(this, other); |
@@ -42,2 +42,22 @@ | ||
/** | ||
* Return an `RGBA` without clamping values. | ||
* | ||
* @param {Number} r | ||
* @param {Number} g | ||
* @param {Number} b | ||
* @param {Number} a | ||
* @return {RGBA} | ||
* @api public | ||
*/ | ||
RGBA.withoutClamping = function(r,g,b,a){ | ||
var rgba = new RGBA(0,0,0,0); | ||
rgba.r = r; | ||
rgba.g = g; | ||
rgba.b = b; | ||
rgba.a = a; | ||
return rgba; | ||
}; | ||
/** | ||
* Return a clone of this node. | ||
@@ -105,3 +125,13 @@ * | ||
var n = other.val; | ||
return new RGBA(n,n,n,1); | ||
if ('%' == other.type) { | ||
n /= 100; | ||
return new RGBA( | ||
this.r * n | ||
, this.g * n | ||
, this.b * n | ||
, 1 | ||
); | ||
} else { | ||
return RGBA.withoutClamping(n,n,n,1); | ||
} | ||
} else { | ||
@@ -108,0 +138,0 @@ return Node.prototype.coerce.call(this, other); |
@@ -14,2 +14,3 @@ | ||
, nodes = require('./nodes') | ||
, Token = require('./token') | ||
, inspect = require('sys').inspect; | ||
@@ -92,2 +93,3 @@ | ||
this.state = ['root']; | ||
this.stash = []; | ||
this.state.pop = function(){ | ||
@@ -194,3 +196,5 @@ self.prevState = [].pop.call(this); | ||
next: function() { | ||
var tok = this.lexer.next(); | ||
var tok = this.stash.length | ||
? this.stash.pop() | ||
: this.lexer.next(); | ||
nodes.lineno = tok.lineno; | ||
@@ -1063,10 +1067,21 @@ return tok; | ||
/** | ||
* expression (',' expression)* | ||
* (ident ':')? expression (',' (ident ':')? expression)* | ||
*/ | ||
args: function() { | ||
var args = new nodes.Expression; | ||
var args = new nodes.Arguments | ||
, keyword; | ||
do { | ||
args.push(this.expression()); | ||
// keyword | ||
if ('ident' == this.peek().type && ':' == this.lookahead(2).type) { | ||
keyword = this.next().val.string; | ||
this.expect(':'); | ||
args.map[keyword] = this.expression(); | ||
// arg | ||
} else { | ||
args.push(this.expression()); | ||
} | ||
} while (this.accept(',')); | ||
return args; | ||
@@ -1263,6 +1278,5 @@ }, | ||
if ('/' == op && this.inProperty && !this.parens) { | ||
var expr = new nodes.Expression; | ||
expr.push(node); | ||
expr.push(new nodes.Literal('/')); | ||
return expr; | ||
this.stash.push(new Token('literal', new nodes.Literal('/'))); | ||
this.operand = false; | ||
return node; | ||
} else { | ||
@@ -1269,0 +1283,0 @@ if (!node) throw new Error('illegal unary ' + op); |
@@ -26,3 +26,3 @@ | ||
exports.version = '0.9.2'; | ||
exports.version = '0.10.0'; | ||
@@ -29,0 +29,0 @@ /** |
@@ -170,7 +170,22 @@ | ||
exports.unwrap = function(expr){ | ||
// explicitly preserve the expression | ||
if (expr.preserve) return expr; | ||
if ('expression' != expr.nodeName) return expr; | ||
if (!(expr instanceof nodes.Expression)) return expr; | ||
if (1 != expr.nodes.length) return expr; | ||
if ('expression' != expr.nodes[0].nodeName) return expr; | ||
if (!(expr.nodes[0] instanceof nodes.Expression)) return expr; | ||
return exports.unwrap(expr.nodes[0]); | ||
}; | ||
}; | ||
/** | ||
* Return param names for `fn`. | ||
* | ||
* @param {Function} fn | ||
* @return {Array} | ||
* @api private | ||
*/ | ||
exports.params = function(fn){ | ||
return fn | ||
.toString() | ||
.match(/\(([^)]+)\)/)[1].split(/ *, */); | ||
}; |
@@ -359,2 +359,8 @@ | ||
/** | ||
* Visit Arguments. | ||
*/ | ||
Compiler.prototype.visitArguments = Compiler.prototype.visitExpression; | ||
/** | ||
* Visit Property. | ||
@@ -361,0 +367,0 @@ */ |
@@ -241,2 +241,5 @@ | ||
// Resolve keyword args | ||
call.args.nodes = call.args.resolve(fn); | ||
// Massive stack | ||
@@ -305,2 +308,11 @@ if (this.calling.length > 200) { | ||
// Swap <Unit> OP <RGBA|HSLA> | ||
if ('unit' == left.nodeName) { | ||
if ('rgba' == right.nodeName || 'hsla' == right.nodeName) { | ||
var tmp = left; | ||
left = right; | ||
right = tmp; | ||
} | ||
} | ||
// First node in expression | ||
@@ -400,2 +412,8 @@ if (!~['[]', 'in'].indexOf(op)) { | ||
/** | ||
* Visit Arguments. | ||
*/ | ||
Evaluator.prototype.visitArguments = Evaluator.prototype.visitExpression; | ||
/** | ||
* Visit Property. | ||
@@ -413,3 +431,4 @@ */ | ||
this.calling.push(name); | ||
var ret = this.visit(new nodes.Call(name, prop.expr)); | ||
var args = nodes.Arguments.fromExpression(prop.expr); | ||
var ret = this.visit(new nodes.Call(name, args)); | ||
this.calling.pop(); | ||
@@ -416,0 +435,0 @@ return ret; |
{ "name": "stylus" | ||
, "description": "Robust, expressive language which compiles to CSS" | ||
, "version": "0.9.2" | ||
, "version": "0.10.0" | ||
, "author": "TJ Holowaychuk <tj@vision-media.ca>" | ||
, "keywords": ["css", "parser", "style", "stylesheets", "jade", "language"] | ||
, "repository": "git://github.com/learnboost/stylus" | ||
, "main": "./index.js" | ||
, "engines": { "node": ">= 0.2.4" } | ||
, "bin": { | ||
"stylus": "./bin/stylus" | ||
, "stylus-tutorial": "./bin/stylus-tutorial" | ||
} | ||
, "bin": { "stylus": "./bin/stylus" } | ||
, "dependencies": { | ||
@@ -13,0 +11,0 @@ "cssom": "0.2.0" |
@@ -48,2 +48,3 @@ | ||
- [mixins](stylus/blob/master/docs/mixins.md) | ||
- [keyword arguments](stylus/blob/master/docs/kwargs.md) | ||
- [variables](stylus/blob/master/docs/variables.md) | ||
@@ -50,0 +51,0 @@ - [interpolation](stylus/blob/master/docs/interpolation.md) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
6932
119
193962