less
Advanced tools
Comparing version 1.1.6 to 1.2.0
@@ -106,8 +106,8 @@ // | ||
var style = styles[i]; | ||
try { | ||
style.type = 'text/css'; | ||
if (style.styleSheet) { | ||
style.styleSheet.cssText = css; | ||
} else { | ||
style.innerHTML = css; | ||
} catch (_) { | ||
style.styleSheets.cssText = css; | ||
} | ||
style.type = 'text/css'; | ||
}); | ||
@@ -114,0 +114,0 @@ } |
@@ -161,6 +161,3 @@ (function (tree) { | ||
} else { | ||
throw { | ||
error: "RuntimeError", | ||
message: "math functions take numbers as parameters" | ||
}; | ||
throw { type: "Argument", message: "argument must be a number" }; | ||
} | ||
@@ -171,2 +168,39 @@ }, | ||
}, | ||
percentage: function (n) { | ||
return new(tree.Dimension)(n.value * 100, '%'); | ||
}, | ||
color: function (n) { | ||
if (n instanceof tree.Quoted) { | ||
return new(tree.Color)(n.value.slice(1)); | ||
} else { | ||
throw { type: "Argument", message: "argument must be a string" }; | ||
} | ||
}, | ||
iscolor: function (n) { | ||
return this._isa(n, tree.Color); | ||
}, | ||
isnumber: function (n) { | ||
return this._isa(n, tree.Dimension); | ||
}, | ||
isstring: function (n) { | ||
return this._isa(n, tree.Quoted); | ||
}, | ||
iskeyword: function (n) { | ||
return this._isa(n, tree.Keyword); | ||
}, | ||
isurl: function (n) { | ||
return this._isa(n, tree.URL); | ||
}, | ||
ispixel: function (n) { | ||
return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False; | ||
}, | ||
ispercentage: function (n) { | ||
return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False; | ||
}, | ||
isem: function (n) { | ||
return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False; | ||
}, | ||
_isa: function (n, Type) { | ||
return (n instanceof Type) ? tree.True : tree.False; | ||
} | ||
@@ -173,0 +207,0 @@ }; |
@@ -6,3 +6,3 @@ var path = require('path'), | ||
var less = { | ||
version: [1, 1, 6], | ||
version: [1, 2, 0], | ||
Parser: require('./parser').Parser, | ||
@@ -47,3 +47,5 @@ importer: require('./parser').importer, | ||
if (!ctx.index) { | ||
if (ctx.stack) { return sys.error(stylize(ctx.stack, 'red')) } | ||
if (!ctx.hasOwnProperty('index')) { | ||
return sys.error(ctx.stack || ctx.message); | ||
@@ -56,5 +58,7 @@ } | ||
error.push(ctx.line + ' ' + extract[1].slice(0, ctx.column) | ||
+ stylize(stylize(extract[1][ctx.column], 'bold') | ||
+ extract[1].slice(ctx.column + 1), 'yellow')); | ||
if (extract[1]) { | ||
error.push(ctx.line + ' ' + extract[1].slice(0, ctx.column) | ||
+ stylize(stylize(stylize(extract[1][ctx.column], 'bold') | ||
+ extract[1].slice(ctx.column + 1), 'red'), 'inverse')); | ||
} | ||
@@ -66,4 +70,5 @@ if (typeof(extract[2]) === 'string') { | ||
message += stylize(ctx.message, 'red'); | ||
ctx.filename && (message += stylize(' in ', 'red') + ctx.filename); | ||
message += stylize(ctx.type + 'Error: ' + ctx.message, 'red'); | ||
ctx.filename && (message += stylize(' in ', 'red') + ctx.filename + | ||
stylize(':' + ctx.line + ':' + ctx.column, 'grey')); | ||
@@ -76,12 +81,11 @@ sys.error(message, error); | ||
} | ||
if (ctx.stack) { sys.error(stylize(ctx.stack, 'red')) } | ||
} | ||
}; | ||
['color', 'directive', 'operation', 'dimension', | ||
'keyword', 'variable', 'ruleset', 'element', | ||
'selector', 'quoted', 'expression', 'rule', | ||
'call', 'url', 'alpha', 'import', | ||
'mixin', 'comment', 'anonymous', 'value', | ||
'javascript', 'assignment' | ||
['color', 'directive', 'operation', 'dimension', | ||
'keyword', 'variable', 'ruleset', 'element', | ||
'selector', 'quoted', 'expression', 'rule', | ||
'call', 'url', 'alpha', 'import', | ||
'mixin', 'comment', 'anonymous', 'value', | ||
'javascript', 'assignment', 'condition', 'paren' | ||
].forEach(function (n) { | ||
@@ -114,4 +118,3 @@ require('./tree/' + n); | ||
}).parse(data, function (e, root) { | ||
if (e) less.writeError(e); | ||
callback(root); | ||
callback(e, root); | ||
}); | ||
@@ -118,0 +121,0 @@ }); |
@@ -6,3 +6,4 @@ var less, tree; | ||
// Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88 | ||
less = {}; | ||
if (typeof(window) === 'undefined') { less = {} } | ||
else { less = window.less = {} } | ||
tree = less.tree = {}; | ||
@@ -77,2 +78,3 @@ less.mode = 'rhino'; | ||
mime: env && env.mime, // MIME type of .less files | ||
error: null, // Error in parsing/evaluating an import | ||
push: function (path, callback) { | ||
@@ -85,7 +87,8 @@ var that = this; | ||
// | ||
less.Parser.importer(path, this.paths, function (root) { | ||
less.Parser.importer(path, this.paths, function (e, root) { | ||
that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue | ||
that.files[path] = root; // Store the root | ||
callback(root); | ||
if (e && !that.error) { that.error = e } | ||
callback(e, root); | ||
@@ -164,2 +167,16 @@ if (that.queue.length === 0) { finish() } // Call `finish` if we're done importing | ||
function expect(arg, msg) { | ||
var result = $(arg); | ||
if (! result) { | ||
error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'" | ||
: "unexpected token")); | ||
} else { | ||
return result; | ||
} | ||
} | ||
function error(msg, type) { | ||
throw { index: i, type: type || 'Syntax', message: msg }; | ||
} | ||
// Same as $(), but don't change the state of the parser, | ||
@@ -179,2 +196,33 @@ // just return the match. | ||
function getLocation(index) { | ||
for (var n = index, column = -1; | ||
n >= 0 && input.charAt(n) !== '\n'; | ||
n--) { column++ } | ||
return { line: index ? (input.slice(0, index).match(/\n/g) || "").length : null, | ||
column: column }; | ||
} | ||
function LessError(e, env) { | ||
var lines = input.split('\n'), | ||
loc = getLocation(e.index), | ||
line = loc.line, | ||
col = loc.column; | ||
this.type = e.type || 'SyntaxError'; | ||
this.message = e.message; | ||
this.filename = e.filename || env.filename; | ||
this.index = e.index; | ||
this.line = typeof(line) === 'number' ? line + 1 : null; | ||
this.callLine = e.call && (getLocation(e.call) + 1); | ||
this.callExtract = lines[getLocation(e.call)]; | ||
this.stack = e.stack; | ||
this.column = col; | ||
this.extract = [ | ||
lines[line - 1], | ||
lines[line], | ||
lines[line + 1] | ||
]; | ||
} | ||
this.env = env = env || {}; | ||
@@ -279,4 +327,8 @@ | ||
// output. The callback is called when the input is parsed. | ||
root = new(tree.Ruleset)([], $(this.parsers.primary)); | ||
root.root = true; | ||
try { | ||
root = new(tree.Ruleset)([], $(this.parsers.primary)); | ||
root.root = true; | ||
} catch (e) { | ||
return callback(new(LessError)(e, env)); | ||
} | ||
@@ -322,26 +374,7 @@ root.toCSS = (function (evaluate) { | ||
} catch (e) { | ||
lines = input.split('\n'); | ||
line = getLine(e.index); | ||
throw new(LessError)(e, env); | ||
} | ||
for (var n = e.index, column = -1; | ||
n >= 0 && input.charAt(n) !== '\n'; | ||
n--) { column++ } | ||
if (parser.imports.error) { throw parser.imports.error } | ||
throw { | ||
type: e.type, | ||
message: e.message, | ||
filename: env.filename, | ||
index: e.index, | ||
line: typeof(line) === 'number' ? line + 1 : null, | ||
callLine: e.call && (getLine(e.call) + 1), | ||
callExtract: lines[getLine(e.call)], | ||
stack: e.stack, | ||
column: column, | ||
extract: [ | ||
lines[line - 1], | ||
lines[line], | ||
lines[line + 1] | ||
] | ||
}; | ||
} | ||
if (options.yuicompress && less.mode === 'node') { | ||
@@ -354,6 +387,2 @@ return require('./cssmin').compressor.cssmin(css); | ||
} | ||
function getLine(index) { | ||
return index ? (input.slice(0, index).match(/\n/g) || "").length : null; | ||
} | ||
}; | ||
@@ -378,3 +407,3 @@ })(root.eval); | ||
error = { | ||
name: "ParseError", | ||
type: "Parse", | ||
message: "Syntax Error on line " + line, | ||
@@ -506,3 +535,3 @@ index: i, | ||
} else { | ||
return new(tree.Keyword)(k) | ||
return new(tree.Keyword)(k); | ||
} | ||
@@ -583,4 +612,5 @@ } | ||
$(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || ""; | ||
if (! $(')')) throw new(Error)("missing closing ) for url()"); | ||
expect(')'); | ||
return new(tree.URL)((value.value || value.data || value instanceof tree.Variable) | ||
@@ -712,3 +742,3 @@ ? value : new(tree.Anonymous)(value), imports.paths); | ||
call: function () { | ||
var elements = [], e, c, args, index = i, s = input.charAt(i); | ||
var elements = [], e, c, args, index = i, s = input.charAt(i), important = false; | ||
@@ -723,4 +753,8 @@ if (s !== '.' && s !== '#') { return } | ||
if ($(this.important)) { | ||
important = true; | ||
} | ||
if (elements.length > 0 && ($(';') || peek('}'))) { | ||
return new(tree.mixin.Call)(elements, args, index); | ||
return new(tree.mixin.Call)(elements, args, index, important); | ||
} | ||
@@ -749,7 +783,8 @@ }, | ||
definition: function () { | ||
var name, params = [], match, ruleset, param, value; | ||
var name, params = [], match, ruleset, param, value, cond; | ||
if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') || | ||
peek(/^[^{]*(;|})/)) return; | ||
save(); | ||
if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) { | ||
@@ -763,7 +798,4 @@ name = match[1]; | ||
if ($(':')) { | ||
if (value = $(this.expression)) { | ||
params.push({ name: param.name, value: value }); | ||
} else { | ||
throw new(Error)("Expected value"); | ||
} | ||
value = expect(this.expression, 'expected expression'); | ||
params.push({ name: param.name, value: value }); | ||
} else { | ||
@@ -777,8 +809,14 @@ params.push({ name: param.name }); | ||
} | ||
if (! $(')')) throw new(Error)("Expected )"); | ||
expect(')'); | ||
if ($(/^when/)) { // Guard | ||
cond = expect(this.conditions, 'expected condition'); | ||
} | ||
ruleset = $(this.block); | ||
if (ruleset) { | ||
return new(tree.mixin.Definition)(name, params, ruleset); | ||
return new(tree.mixin.Definition)(name, params, ruleset, cond); | ||
} else { | ||
restore(); | ||
} | ||
@@ -818,3 +856,3 @@ } | ||
if (value = $(/^\d+/) || $(this.entities.variable)) { | ||
if (! $(')')) throw new(Error)("missing closing ) for alpha()"); | ||
expect(')'); | ||
return new(tree.Alpha)(value); | ||
@@ -837,3 +875,3 @@ } | ||
element: function () { | ||
var e, t, c; | ||
var e, t, c, v; | ||
@@ -844,2 +882,6 @@ c = $(this.combinator); | ||
if (! e) { | ||
$('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v)); | ||
} | ||
if (e) { return new(tree.Element)(c, e, i) } | ||
@@ -997,10 +1039,59 @@ | ||
"import": function () { | ||
var path; | ||
var path, features; | ||
if ($(/^@import\s+/) && | ||
(path = $(this.entities.quoted) || $(this.entities.url)) && | ||
$(';')) { | ||
return new(tree.Import)(path, imports); | ||
(path = $(this.entities.quoted) || $(this.entities.url))) { | ||
features = $(this.mediaFeatures); | ||
if ($(';')) { | ||
return new(tree.Import)(path, imports, features); | ||
} | ||
} | ||
}, | ||
mediaFeature: function () { | ||
var nodes = []; | ||
do { | ||
if (e = $(this.entities.keyword)) { | ||
nodes.push(e); | ||
} else if ($('(')) { | ||
p = $(this.property); | ||
e = $(this.entity); | ||
if ($(')')) { | ||
if (p && e) { | ||
nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true))); | ||
} else if (e) { | ||
nodes.push(new(tree.Paren)(e)); | ||
} else { | ||
return null; | ||
} | ||
} else { return null } | ||
} | ||
} while (e); | ||
if (nodes.length > 0) { | ||
return new(tree.Expression)(nodes); | ||
} | ||
}, | ||
mediaFeatures: function () { | ||
var f, features = []; | ||
while (f = $(this.mediaFeature)) { | ||
features.push(f); | ||
if (! $(',')) { break } | ||
} | ||
return features.length > 0 ? features : null; | ||
}, | ||
media: function () { | ||
var features; | ||
if ($(/^@media/)) { | ||
features = $(this.mediaFeatures); | ||
if (rules = $(this.block)) { | ||
return new(tree.Directive)('@media', rules, features); | ||
} | ||
} | ||
}, | ||
// | ||
@@ -1012,9 +1103,9 @@ // A CSS Directive | ||
directive: function () { | ||
var name, value, rules, types; | ||
var name, value, rules, types, e, nodes; | ||
if (input.charAt(i) !== '@') return; | ||
if (value = $(this['import'])) { | ||
if (value = $(this['import']) || $(this.media)) { | ||
return value; | ||
} else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/) || $('keyframes')) { | ||
} else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) { | ||
types = ($(/^[^{]+/) || '').trim(); | ||
@@ -1102,3 +1193,32 @@ if (rules = $(this.block)) { | ||
}, | ||
conditions: function () { | ||
var a, b, index = i, condition; | ||
if (a = $(this.condition)) { | ||
while ($(',') && (b = $(this.condition))) { | ||
condition = new(tree.Condition)('or', condition || a, b, index); | ||
} | ||
return condition || a; | ||
} | ||
}, | ||
condition: function () { | ||
var a, b, c, op, index = i, negate = false; | ||
if ($(/^not/)) { negate = true } | ||
expect('('); | ||
if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) { | ||
if (op = $(/^(?:>=|=<|[<=>])/)) { | ||
if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) { | ||
c = new(tree.Condition)(op, a, b, index, negate); | ||
} else { | ||
error('expected expression'); | ||
} | ||
} else { | ||
c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate); | ||
} | ||
expect(')'); | ||
return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c; | ||
} | ||
}, | ||
// | ||
@@ -1105,0 +1225,0 @@ // An operand is anything that can be part of an operation, |
@@ -1,2 +0,4 @@ | ||
require('./tree').find = function (obj, fun) { | ||
(function (tree) { | ||
tree.find = function (obj, fun) { | ||
for (var i = 0, r; i < obj.length; i++) { | ||
@@ -7,3 +9,3 @@ if (r = fun.call(obj, obj[i])) { return r } | ||
}; | ||
require('./tree').jsify = function (obj) { | ||
tree.jsify = function (obj) { | ||
if (Array.isArray(obj.value) && (obj.value.length > 1)) { | ||
@@ -15,1 +17,3 @@ return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']'; | ||
}; | ||
})(require('./tree')); |
@@ -31,3 +31,5 @@ (function (tree) { | ||
} catch (e) { | ||
throw { message: "error evaluating function `" + this.name + "`", | ||
throw { type: e.type || "Runtime", | ||
message: "error evaluating function `" + this.name + "`" + | ||
(e.message ? ': ' + e.message : ''), | ||
index: this.index }; | ||
@@ -34,0 +36,0 @@ } |
@@ -31,2 +31,17 @@ (function (tree) { | ||
this.unit || other.unit); | ||
}, | ||
// TODO: Perform unit conversion before comparing | ||
compare: function (other) { | ||
if (other instanceof tree.Dimension) { | ||
if (other.value > this.value) { | ||
return -1; | ||
} else if (other.value < this.value) { | ||
return 1; | ||
} else { | ||
return 0; | ||
} | ||
} else { | ||
return -1; | ||
} | ||
} | ||
@@ -33,0 +48,0 @@ }; |
(function (tree) { | ||
tree.Directive = function (name, value) { | ||
tree.Directive = function (name, value, features) { | ||
this.name = name; | ||
this.features = features && new(tree.Value)(features); | ||
if (Array.isArray(value)) { | ||
this.ruleset = new(tree.Ruleset)([], value); | ||
this.ruleset.allowImports = true; | ||
} else { | ||
@@ -13,5 +16,7 @@ this.value = value; | ||
toCSS: function (ctx, env) { | ||
var features = this.features ? ' ' + this.features.toCSS(env) : ''; | ||
if (this.ruleset) { | ||
this.ruleset.root = true; | ||
return this.name + (env.compress ? '{' : ' {\n ') + | ||
return this.name + features + (env.compress ? '{' : ' {\n ') + | ||
this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') + | ||
@@ -24,2 +29,3 @@ (env.compress ? '}': '\n}\n'); | ||
eval: function (env) { | ||
this.features = this.features && this.features.eval(env); | ||
env.frames.unshift(this); | ||
@@ -26,0 +32,0 @@ this.ruleset = this.ruleset && this.ruleset.eval(env); |
@@ -6,7 +6,19 @@ (function (tree) { | ||
combinator : new(tree.Combinator)(combinator); | ||
this.value = value ? value.trim() : ""; | ||
if (typeof(value) === 'string') { | ||
this.value = value.trim(); | ||
} else if (value) { | ||
this.value = value; | ||
} else { | ||
this.value = ""; | ||
} | ||
this.index = index; | ||
}; | ||
tree.Element.prototype.eval = function (env) { | ||
return new(tree.Element)(this.combinator, | ||
this.value.eval ? this.value.eval(env) : this.value, | ||
this.index); | ||
}; | ||
tree.Element.prototype.toCSS = function (env) { | ||
return this.combinator.toCSS(env || {}) + this.value; | ||
return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value); | ||
}; | ||
@@ -13,0 +25,0 @@ |
@@ -18,3 +18,3 @@ (function (tree) { | ||
return this.value.map(function (e) { | ||
return e.toCSS(env); | ||
return e.toCSS ? e.toCSS(env) : ''; | ||
}).join(' '); | ||
@@ -21,0 +21,0 @@ } |
@@ -14,6 +14,7 @@ (function (tree) { | ||
// | ||
tree.Import = function (path, imports) { | ||
tree.Import = function (path, imports, features) { | ||
var that = this; | ||
this._path = path; | ||
this.features = features && new(tree.Value)(features); | ||
@@ -31,6 +32,3 @@ // The '.less' extension is optional | ||
if (! this.css) { | ||
imports.push(this.path, function (root) { | ||
if (! root) { | ||
throw new(Error)("Error parsing " + that.path); | ||
} | ||
imports.push(this.path, function (e, root) { | ||
that.root = root; | ||
@@ -51,5 +49,7 @@ }); | ||
tree.Import.prototype = { | ||
toCSS: function () { | ||
toCSS: function (env) { | ||
var features = this.features ? ' ' + this.features.toCSS(env) : ''; | ||
if (this.css) { | ||
return "@import " + this._path.toCSS() + ';\n'; | ||
return "@import " + this._path.toCSS() + features + ';\n'; | ||
} else { | ||
@@ -60,3 +60,3 @@ return ""; | ||
eval: function (env) { | ||
var ruleset; | ||
var ruleset, features = this.features && this.features.eval(env); | ||
@@ -66,3 +66,3 @@ if (this.css) { | ||
} else { | ||
ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0)); | ||
ruleset = new(tree.Ruleset)([], this.root.rules.slice(0)); | ||
@@ -77,3 +77,3 @@ for (var i = 0; i < ruleset.rules.length; i++) { | ||
} | ||
return ruleset.rules; | ||
return this.features ? new(tree.Directive)('@media', ruleset.rules, this.features.value) : ruleset.rules; | ||
} | ||
@@ -80,0 +80,0 @@ } |
@@ -6,5 +6,15 @@ (function (tree) { | ||
eval: function () { return this }, | ||
toCSS: function () { return this.value } | ||
toCSS: function () { return this.value }, | ||
compare: function (other) { | ||
if (other instanceof tree.Keyword) { | ||
return other.value === this.value ? 0 : 1; | ||
} else { | ||
return -1; | ||
} | ||
} | ||
}; | ||
tree.True = new(tree.Keyword)('true'); | ||
tree.False = new(tree.Keyword)('false'); | ||
})(require('../tree')); |
(function (tree) { | ||
tree.mixin = {}; | ||
tree.mixin.Call = function (elements, args, index) { | ||
tree.mixin.Call = function (elements, args, index, important) { | ||
this.selector = new(tree.Selector)(elements); | ||
this.arguments = args; | ||
this.index = index; | ||
this.important = important; | ||
}; | ||
@@ -20,3 +21,3 @@ tree.mixin.Call.prototype = { | ||
Array.prototype.push.apply( | ||
rules, mixins[m].eval(env, this.arguments).rules); | ||
rules, mixins[m].eval(env, this.arguments, this.important).rules); | ||
match = true; | ||
@@ -31,3 +32,4 @@ } catch (e) { | ||
} else { | ||
throw { message: 'No matching definition was found for `' + | ||
throw { type: 'Runtime', | ||
message: 'No matching definition was found for `' + | ||
this.selector.toCSS().trim() + '(' + | ||
@@ -41,3 +43,4 @@ this.arguments.map(function (a) { | ||
} | ||
throw { message: this.selector.toCSS().trim() + " is undefined", | ||
throw { type: 'Name', | ||
message: this.selector.toCSS().trim() + " is undefined", | ||
index: this.index }; | ||
@@ -47,6 +50,7 @@ } | ||
tree.mixin.Definition = function (name, params, rules) { | ||
tree.mixin.Definition = function (name, params, rules, condition) { | ||
this.name = name; | ||
this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])]; | ||
this.params = params; | ||
this.condition = condition; | ||
this.arity = params.length; | ||
@@ -69,4 +73,4 @@ this.rules = rules; | ||
eval: function (env, args) { | ||
var frame = new(tree.Ruleset)(null, []), context, _arguments = []; | ||
evalParams: function (env, args) { | ||
var frame = new(tree.Ruleset)(null, []); | ||
@@ -78,3 +82,3 @@ for (var i = 0, val; i < this.params.length; i++) { | ||
} else { | ||
throw { message: "wrong number of arguments for " + this.name + | ||
throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + | ||
' (' + args.length + ' for ' + this.arity + ')' }; | ||
@@ -84,2 +88,7 @@ } | ||
} | ||
return frame; | ||
}, | ||
eval: function (env, args, important) { | ||
var frame = this.evalParams(env, args), context, _arguments = [], rules; | ||
for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) { | ||
@@ -90,3 +99,8 @@ _arguments.push(args[i] || this.params[i].value); | ||
return new(tree.Ruleset)(null, this.rules.slice(0)).eval({ | ||
rules = important ? | ||
this.rules.map(function (r) { | ||
return new(tree.Rule)(r.name, r.value, '!important', r.index); | ||
}) : this.rules.slice(0); | ||
return new(tree.Ruleset)(null, rules).eval({ | ||
frames: [this, frame].concat(this.frames, env.frames) | ||
@@ -96,6 +110,9 @@ }); | ||
match: function (args, env) { | ||
var argsLength = (args && args.length) || 0, len; | ||
var argsLength = (args && args.length) || 0, len, frame; | ||
if (argsLength < this.required) { return false } | ||
if ((this.required > 0) && (argsLength > this.params.length)) { return false } | ||
if (this.condition && !this.condition.eval({ | ||
frames: [this.evalParams(env, args)].concat(env.frames) | ||
})) { return false } | ||
@@ -102,0 +119,0 @@ len = Math.min(argsLength, this.arity); |
@@ -23,3 +23,3 @@ (function (tree) { | ||
var v = new(tree.Variable)('@' + name, that.index).eval(env); | ||
return v.value || v.toCSS(); | ||
return ('value' in v) ? v.value : v.toCSS(); | ||
}); | ||
@@ -26,0 +26,0 @@ return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index); |
(function (tree) { | ||
tree.Rule = function (name, value, important, index) { | ||
tree.Rule = function (name, value, important, index, inline) { | ||
this.name = name; | ||
@@ -8,2 +8,3 @@ this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]); | ||
this.index = index; | ||
this.inline = inline || false; | ||
@@ -19,3 +20,3 @@ if (name.charAt(0) === '@') { | ||
this.value.toCSS(env) + | ||
this.important + ";"; | ||
this.important + (this.inline ? "" : ";"); | ||
} | ||
@@ -25,3 +26,6 @@ }; | ||
tree.Rule.prototype.eval = function (context) { | ||
return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index); | ||
return new(tree.Rule)(this.name, | ||
this.value.eval(context), | ||
this.important, | ||
this.index, this.inline); | ||
}; | ||
@@ -28,0 +32,0 @@ |
@@ -10,5 +10,7 @@ (function (tree) { | ||
eval: function (env) { | ||
var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0)); | ||
var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) }); | ||
var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0)); | ||
ruleset.root = this.root; | ||
ruleset.allowImports = this.allowImports; | ||
@@ -19,3 +21,3 @@ // push the current ruleset to the frames stack | ||
// Evaluate imports | ||
if (ruleset.root) { | ||
if (ruleset.root || ruleset.allowImports) { | ||
for (var i = 0; i < ruleset.rules.length; i++) { | ||
@@ -125,3 +127,3 @@ if (ruleset.rules[i] instanceof tree.Import) { | ||
} else { | ||
this.joinSelectors( paths, context, this.selectors ); | ||
this.joinSelectors(paths, context, this.selectors); | ||
} | ||
@@ -128,0 +130,0 @@ } |
@@ -25,2 +25,7 @@ (function (tree) { | ||
}; | ||
tree.Selector.prototype.eval = function (env) { | ||
return new(tree.Selector)(this.elements.map(function (e) { | ||
return e.eval(env); | ||
})); | ||
}; | ||
tree.Selector.prototype.toCSS = function (env) { | ||
@@ -27,0 +32,0 @@ if (this._css) { return this._css } |
@@ -8,3 +8,3 @@ { | ||
"contributors" : [], | ||
"version" : "1.1.6", | ||
"version" : "1.2.0", | ||
"bin" : { "lessc": "./bin/lessc" }, | ||
@@ -11,0 +11,0 @@ "main" : "./lib/less/index", |
@@ -13,3 +13,3 @@ var path = require('path'), | ||
} | ||
less.tree.functions.color = function (str) { | ||
less.tree.functions._color = function (str) { | ||
if (str.value === "evil red") { return new(less.tree.Color)("600") } | ||
@@ -16,0 +16,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1498385
120
29946
11