mirror of
https://github.com/less/less.js.git
synced 2026-05-01 03:00:22 -04:00
Scope fix - default parameters are evaluated in the mixin scope, not the
caller scope. Fixes #973.
This commit is contained in:
@@ -96,7 +96,7 @@ tree.mixin.Definition.prototype = {
|
||||
find: function () { return this.parent.find.apply(this, arguments) },
|
||||
rulesets: function () { return this.parent.rulesets.apply(this) },
|
||||
|
||||
evalParams: function (env, args, evaldArguments) {
|
||||
evalParams: function (env, mixinEnv, args, evaldArguments) {
|
||||
var frame = new(tree.Ruleset)(null, []), varargs, arg, params = this.params.slice(0), i, j, val, name, isNamedFound, argIndex;
|
||||
|
||||
if (args) {
|
||||
@@ -138,12 +138,19 @@ tree.mixin.Definition.prototype = {
|
||||
varargs.push(args[j].value.eval(env));
|
||||
}
|
||||
frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
|
||||
} else if (val = (arg && arg.value) || params[i].value) {
|
||||
frame.rules.unshift(new(tree.Rule)(name, val.eval(env)));
|
||||
evaldArguments[i] = val.eval(env)
|
||||
} else {
|
||||
throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
|
||||
val = arg && arg.value;
|
||||
if (val) {
|
||||
val = val.eval(env);
|
||||
} else if (params[i].value) {
|
||||
val = params[i].value.eval(mixinEnv);
|
||||
} else {
|
||||
throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
|
||||
' (' + args.length + ' for ' + this.arity + ')' };
|
||||
}
|
||||
|
||||
frame.rules.unshift(new(tree.Rule)(name, val));
|
||||
evaldArguments[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +165,10 @@ tree.mixin.Definition.prototype = {
|
||||
return frame;
|
||||
},
|
||||
eval: function (env, args, important) {
|
||||
var _arguments = [], frame = this.evalParams(env, args, _arguments), context, rules, start, ruleset;
|
||||
var _arguments = [],
|
||||
mixinFrames = this.frames.concat(env.frames),
|
||||
frame = this.evalParams(env, {frames: mixinFrames}, args, _arguments),
|
||||
context, rules, start, ruleset;
|
||||
|
||||
frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
|
||||
|
||||
@@ -166,14 +176,14 @@ tree.mixin.Definition.prototype = {
|
||||
this.parent.makeImportant.apply(this).rules : this.rules.slice(0);
|
||||
|
||||
ruleset = new(tree.Ruleset)(null, rules).eval({
|
||||
frames: [this, frame].concat(this.frames, env.frames)
|
||||
frames: [this, frame].concat(mixinFrames)
|
||||
});
|
||||
ruleset.originalRuleset = this;
|
||||
return ruleset;
|
||||
},
|
||||
matchCondition: function (args, env) {
|
||||
if (this.condition && !this.condition.eval({
|
||||
frames: [this.evalParams(env, args, [])].concat(env.frames)
|
||||
frames: [this.evalParams(env, {frames: this.frames.concat(env.frames)}, args, [])].concat(env.frames)
|
||||
})) { return false }
|
||||
return true;
|
||||
},
|
||||
|
||||
@@ -28,3 +28,8 @@
|
||||
.testImported {
|
||||
exists: true;
|
||||
}
|
||||
#allAreUsedHere {
|
||||
default: 'top level';
|
||||
scope: 'top level';
|
||||
sub-scope-only: 'inside';
|
||||
}
|
||||
|
||||
@@ -59,3 +59,21 @@
|
||||
.testImported {
|
||||
.imported;
|
||||
}
|
||||
|
||||
@parameterDefault: 'top level';
|
||||
@anotherVariable: 'top level';
|
||||
//mixin uses top-level variables
|
||||
.mixinNoParam(@parameter: @parameterDefault) when (@parameter = 'top level') {
|
||||
default: @parameter;
|
||||
scope: @anotherVariable;
|
||||
sub-scope-only: @subScopeOnly;
|
||||
}
|
||||
|
||||
#allAreUsedHere {
|
||||
//redefine top-level variables in different scope
|
||||
@parameterDefault: 'inside';
|
||||
@anotherVariable: 'inside';
|
||||
@subScopeOnly: 'inside';
|
||||
//use the mixin
|
||||
.mixinNoParam();
|
||||
}
|
||||
Reference in New Issue
Block a user