diff --git a/lib/less/tree/mixin.js b/lib/less/tree/mixin.js index 8e04e4f6..b0c4b185 100644 --- a/lib/less/tree/mixin.js +++ b/lib/less/tree/mixin.js @@ -73,7 +73,7 @@ tree.mixin.Definition.prototype = { } } } - return new(tree.Ruleset)(null, this.rules).eval({ + return new(tree.Ruleset)(null, this.rules.slice(0)).eval({ frames: [this, frame].concat(this.frames, env.frames) }); }, diff --git a/lib/less/tree/ruleset.js b/lib/less/tree/ruleset.js index 90a5f801..2ab21dee 100644 --- a/lib/less/tree/ruleset.js +++ b/lib/less/tree/ruleset.js @@ -9,18 +9,48 @@ tree.Ruleset.prototype = { eval: function (env) { if (this.evaled) { return this } - var rules = []; + // push the current ruleset to the frames stack + env.frames.unshift(this); - this.rules.forEach(function (rule) { - if (rule instanceof tree.mixin.Call) { - Array.prototype.push.apply(rules, rule.eval(env)); - } else if (! (rule instanceof tree.mixin.Definition)) { - rules.push(rule.eval ? rule.eval(env) : ''); + // Store the frames around mixin definitions, + // so they can be evaluated like closures when the time comes. + for (var i = 0; i < this.rules.length; i++) { + if (this.rules[i] instanceof tree.mixin.Definition) { + this.rules[i].frames = env.frames.slice(0); } - }); - this.rules = rules; + } + + // Evaluate imports + if (this.root) { + for (var i = 0; i < this.rules.length; i++) { + if (this.rules[i] instanceof tree.Import) { + Array.prototype.splice + .apply(this.rules, [i, 1].concat(this.rules[i].eval(env))); + } + } + } + + // Evaluate mixin calls. + for (var i = 0; i < this.rules.length; i++) { + if (this.rules[i] instanceof tree.mixin.Call) { + Array.prototype.splice + .apply(this.rules, [i, 1].concat(this.rules[i].eval(env))); + } + } + + // Evaluate everything else + for (var i = 0, rule; i < this.rules.length; i++) { + rule = this.rules[i]; + + if (! (rule instanceof tree.mixin.Definition)) { + this.rules[i] = rule.eval ? rule.eval(env) : rule; + } + } this.evaled = true; + // Pop the stack + env.frames.shift(); + return this; }, match: function (args) { @@ -92,36 +122,15 @@ tree.Ruleset.prototype = { } } } - } else { - for (var i = 0; i < this.rules.length; i++) { - if (this.rules[i] instanceof tree.Import) { - Array.prototype.splice - .apply(this.rules, [i, 1].concat(this.rules[i].eval(env))); - } - } } - // push the current ruleset to the frames stack - env.frames.unshift(this); + this.eval(env); - // Evaluate mixin calls and store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - for (var i = 0; i < this.rules.length; i++) { - if (this.rules[i] instanceof tree.mixin.Call) { - Array.prototype.splice - .apply(this.rules, [i, 1].concat(this.rules[i].eval(env))); - } else if (this.rules[i] instanceof tree.mixin.Definition) { - this.rules[i].frames = env.frames.slice(0); - } - } - - // Evaluate rules and rulesets + // Compile rules and rulesets for (var i = 0; i < this.rules.length; i++) { rule = this.rules[i]; - if (rule instanceof tree.Directive) { - rulesets.push(rule.eval(env).toCSS(paths, env)); - } else if (rule.rules) { + if (rule.rules || (rule instanceof tree.Directive)) { rulesets.push(rule.toCSS(paths, env)); } else if (rule instanceof tree.Comment) { if (!rule.silent) { @@ -133,7 +142,7 @@ tree.Ruleset.prototype = { } } else { if (rule.toCSS && !rule.variable) { - rules.push(rule.eval(env).toCSS(env)); + rules.push(rule.toCSS(env)); } else if (rule.value && !rule.variable) { rules.push(rule.value.toString()); } @@ -162,9 +171,6 @@ tree.Ruleset.prototype = { } css.push(rulesets); - // Pop the stack - env.frames.shift(); - return css.join('') + (env.compress ? '\n' : ''); } }; diff --git a/test/less/scope.less b/test/less/scope.less index f8f59bfd..36e57e1b 100644 --- a/test/less/scope.less +++ b/test/less/scope.less @@ -7,8 +7,8 @@ } .tiny-scope { - color: @mix; // #989 .mixin; + color: @mix; // #989 } .scope1 { @@ -29,4 +29,4 @@ background-color: @local; // white } } -} \ No newline at end of file +}