mirror of
https://github.com/less/less.js.git
synced 2026-01-22 21:58:14 -05:00
Added guards checking to namespaces. Issue #1418.
This commit is contained in:
@@ -19,16 +19,45 @@ tree.mixin.Call.prototype = {
|
||||
}
|
||||
},
|
||||
eval: function (env) {
|
||||
var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule,
|
||||
candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc,
|
||||
defaultResult, defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset;
|
||||
var mixins, mixin, mixinPath, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule,
|
||||
candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc,
|
||||
defaultResult, defFalseEitherCase=-1, defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset, noArgumentsFilter;
|
||||
|
||||
function calcDefGroup(mixin, mixinPath) {
|
||||
var p, namespace;
|
||||
|
||||
for (f = 0; f < 2; f++) {
|
||||
conditionResult[f] = true;
|
||||
defaultFunc.value(f);
|
||||
for(p = 0; p < mixinPath.length && conditionResult[f]; p++) {
|
||||
namespace = mixinPath[p];
|
||||
if (namespace.matchCondition) {
|
||||
conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, env);
|
||||
}
|
||||
}
|
||||
if (mixin.matchCondition) {
|
||||
conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, env);
|
||||
}
|
||||
}
|
||||
if (conditionResult[0] || conditionResult[1]) {
|
||||
if (conditionResult[0] != conditionResult[1]) {
|
||||
return conditionResult[1] ?
|
||||
defTrue : defFalse;
|
||||
}
|
||||
|
||||
return defNone;
|
||||
}
|
||||
return defFalseEitherCase;
|
||||
}
|
||||
|
||||
args = this.arguments && this.arguments.map(function (a) {
|
||||
return { name: a.name, value: a.value.eval(env) };
|
||||
});
|
||||
|
||||
noArgumentsFilter = function(rule) {return rule.matchArgs(null, env);};
|
||||
|
||||
for (i = 0; i < env.frames.length; i++) {
|
||||
if ((mixins = env.frames[i].find(this.selector)).length > 0) {
|
||||
if ((mixins = env.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) {
|
||||
isOneFound = true;
|
||||
|
||||
// To make `default()` function independent of definition order we have two "subpasses" here.
|
||||
@@ -37,7 +66,8 @@ tree.mixin.Call.prototype = {
|
||||
// we make a final decision.
|
||||
|
||||
for (m = 0; m < mixins.length; m++) {
|
||||
mixin = mixins[m];
|
||||
mixin = mixins[m].rule;
|
||||
mixinPath = mixins[m].path;
|
||||
isRecursive = false;
|
||||
for(f = 0; f < env.frames.length; f++) {
|
||||
if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) {
|
||||
@@ -48,28 +78,14 @@ tree.mixin.Call.prototype = {
|
||||
if (isRecursive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mixin.matchArgs(args, env)) {
|
||||
candidate = {mixin: mixin, group: defNone};
|
||||
|
||||
if (mixin.matchCondition) {
|
||||
for (f = 0; f < 2; f++) {
|
||||
defaultFunc.value(f);
|
||||
conditionResult[f] = mixin.matchCondition(args, env);
|
||||
}
|
||||
if (conditionResult[0] || conditionResult[1]) {
|
||||
if (conditionResult[0] != conditionResult[1]) {
|
||||
candidate.group = conditionResult[1] ?
|
||||
defTrue : defFalse;
|
||||
}
|
||||
|
||||
candidates.push(candidate);
|
||||
}
|
||||
if (mixin.matchArgs(args, env)) {
|
||||
candidate = {mixin: mixin, group: calcDefGroup(mixin, mixinPath)};
|
||||
|
||||
if (candidate.group!==defFalseEitherCase) {
|
||||
candidates.push(candidate);
|
||||
}
|
||||
else {
|
||||
candidates.push(candidate);
|
||||
}
|
||||
|
||||
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
@@ -133,6 +149,7 @@ tree.mixin.Call.prototype = {
|
||||
message: this.selector.toCSS().trim() + " is undefined",
|
||||
index: this.index, filename: this.currentFileInfo.filename };
|
||||
}
|
||||
|
||||
},
|
||||
format: function (args) {
|
||||
return this.selector.toCSS().trim() + '(' +
|
||||
|
||||
@@ -238,9 +238,9 @@ tree.Ruleset.prototype = {
|
||||
var rules = this.rules;
|
||||
if (rules) { rules.unshift(rule); } else { this.rules = [ rule ]; }
|
||||
},
|
||||
find: function (selector, self) {
|
||||
find: function (selector, self, filter) {
|
||||
self = self || this;
|
||||
var rules = [], match,
|
||||
var rules = [], match, foundMixins,
|
||||
key = selector.toCSS();
|
||||
|
||||
if (key in this._lookups) { return this._lookups[key]; }
|
||||
@@ -251,10 +251,15 @@ tree.Ruleset.prototype = {
|
||||
match = selector.match(rule.selectors[j]);
|
||||
if (match) {
|
||||
if (selector.elements.length > match) {
|
||||
Array.prototype.push.apply(rules, rule.find(
|
||||
new(tree.Selector)(selector.elements.slice(match)), self));
|
||||
if (!filter || filter(rule)) {
|
||||
foundMixins = rule.find(new(tree.Selector)(selector.elements.slice(match)), self, filter);
|
||||
for (var i = 0; i < foundMixins.length; ++i) {
|
||||
foundMixins[i].path.push(rule);
|
||||
}
|
||||
Array.prototype.push.apply(rules, foundMixins);
|
||||
}
|
||||
} else {
|
||||
rules.push(rule);
|
||||
rules.push({ rule: rule, path: []});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -91,3 +91,11 @@
|
||||
.mixin-generated-class {
|
||||
a: 1;
|
||||
}
|
||||
#guarded-caller {
|
||||
guarded: namespace;
|
||||
silent: namespace;
|
||||
guarded: with default;
|
||||
}
|
||||
#guarded-deeper {
|
||||
should: match 1;
|
||||
}
|
||||
|
||||
@@ -171,3 +171,58 @@
|
||||
}
|
||||
|
||||
#ns > .mixin-for-root-usage(1);
|
||||
|
||||
@namespaceGuard: 1;
|
||||
#guarded when (@namespaceGuard>0) {
|
||||
#deeper {
|
||||
.mixin() {
|
||||
guarded: namespace;
|
||||
}
|
||||
}
|
||||
}
|
||||
#guarded() when (@namespaceGuard>0) {
|
||||
#deeper {
|
||||
.mixin() {
|
||||
silent: namespace;
|
||||
}
|
||||
}
|
||||
}
|
||||
#guarded(@variable) when (@namespaceGuard>0) {
|
||||
#deeper {
|
||||
.mixin() {
|
||||
should: not match because namespace argument;
|
||||
}
|
||||
}
|
||||
}
|
||||
#guarded(@variable: default) when (@namespaceGuard>0) {
|
||||
#deeper {
|
||||
.mixin() {
|
||||
guarded: with default;
|
||||
}
|
||||
}
|
||||
}
|
||||
#guarded when (@namespaceGuard<0) {
|
||||
#deeper {
|
||||
.mixin() {
|
||||
should: not match because namespace guard;
|
||||
}
|
||||
}
|
||||
}
|
||||
#guarded-caller {
|
||||
#guarded > #deeper > .mixin();
|
||||
}
|
||||
#top {
|
||||
#deeper when (@namespaceGuard<0) {
|
||||
.mixin(@a) {
|
||||
should: not match because namespace guard;
|
||||
}
|
||||
}
|
||||
#deeper() when (@namespaceGuard>0) {
|
||||
.mixin(@a) {
|
||||
should: match @a;
|
||||
}
|
||||
}
|
||||
}
|
||||
#guarded-deeper {
|
||||
#top > #deeper > .mixin(1);
|
||||
}
|
||||
Reference in New Issue
Block a user