mirror of
https://github.com/less/less.js.git
synced 2026-01-22 13:48:03 -05:00
Support for pattern-matching on mixin calls.
This commit is contained in:
@@ -533,15 +533,21 @@ less.Parser = function Parser(env) {
|
||||
if (match = $(/([#.][a-zA-Z0-9_-]+)\s*\(/g)) {
|
||||
name = match[1];
|
||||
|
||||
while (param = $(/@[\w-]+/g)) {
|
||||
if ($(':')) {
|
||||
if (value = $(this.expression)) {
|
||||
params.push({ name: param, value: value });
|
||||
while (param = $(/@[\w-]+/g) || $(this.entities.literal)
|
||||
|| $(this.entities.keyword)) {
|
||||
// Variable
|
||||
if (param[0] === '@') {
|
||||
if ($(':')) {
|
||||
if (value = $(this.expression)) {
|
||||
params.push({ name: param, value: value });
|
||||
} else {
|
||||
throw new(Error)("Expected value");
|
||||
}
|
||||
} else {
|
||||
throw new(Error)("Expected value");
|
||||
params.push({ name: param });
|
||||
}
|
||||
} else {
|
||||
params.push({ name: param });
|
||||
params.push({ value: param });
|
||||
}
|
||||
if (! $(',')) { break }
|
||||
}
|
||||
|
||||
@@ -12,8 +12,10 @@ tree.mixin.Call.prototype = {
|
||||
for (var i = 0; i < env.frames.length; i++) {
|
||||
if ((mixins = env.frames[i].find(this.selector)).length > 0) {
|
||||
for (var m = 0; m < mixins.length; m++) {
|
||||
Array.prototype.push.apply(
|
||||
rules, mixins[m].eval(this.arguments, env).rules);
|
||||
if (mixins[m].match(this.arguments, env)) {
|
||||
Array.prototype.push.apply(
|
||||
rules, mixins[m].eval(this.arguments, env).rules);
|
||||
}
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
@@ -26,8 +28,13 @@ tree.mixin.Definition = function MixinDefinition(name, params, rules) {
|
||||
this.name = name;
|
||||
this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
|
||||
this.params = params;
|
||||
this.arity = params.length;
|
||||
this.rules = rules;
|
||||
this._lookups = {};
|
||||
this.required = params.reduce(function (count, p) {
|
||||
if (p.name && p.value) { return count }
|
||||
else { return count + 1 }
|
||||
}, 0);
|
||||
};
|
||||
tree.mixin.Definition.prototype = {
|
||||
toCSS: function () { return "" },
|
||||
@@ -39,14 +46,32 @@ tree.mixin.Definition.prototype = {
|
||||
var frame = new(tree.Ruleset)(null, []), context;
|
||||
|
||||
for (var i = 0, val; i < this.params.length; i++) {
|
||||
if (val = (args && args[i]) || this.params[i].value) {
|
||||
frame.rules.unshift(new(tree.Rule)(this.params[i].name, val));
|
||||
} else {
|
||||
throw new(Error)("wrong number of arguments for " + this.name);
|
||||
if (this.params[i].name) {
|
||||
if (val = (args && args[i]) || this.params[i].value) {
|
||||
frame.rules.unshift(new(tree.Rule)(this.params[i].name, val));
|
||||
} else {
|
||||
throw new(Error)("wrong number of arguments for " + this.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new(tree.Ruleset)(null, this.rules).evalRules({
|
||||
frames: [this, frame].concat(env.frames)
|
||||
});
|
||||
},
|
||||
match: function (args, env) {
|
||||
var argsLength = (args && args.length) || 0;
|
||||
|
||||
if (argsLength < this.required || argsLength > this.arity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < argsLength; i++) {
|
||||
if (!this.params[i].name) {
|
||||
if (args[i].toCSS(env) != this.params[i].value.toCSS(env)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,7 +27,8 @@ tree.Value = function Value(value) {
|
||||
tree.Value.prototype = {
|
||||
eval: function (env) {
|
||||
if (this.value.length === 1) {
|
||||
return this.value[0].eval(env);
|
||||
return this.value[0].eval ? this.value[0].eval(env)
|
||||
: this.value[0];
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -16,12 +16,15 @@ tree.Ruleset.prototype = {
|
||||
} else if (rule instanceof tree.mixin.Call) {
|
||||
Array.prototype.push.apply(rules, rule.eval(context));
|
||||
} else {
|
||||
rules.push(rule.eval(context));
|
||||
rules.push(rule.eval ? rule.eval(context) : rule);
|
||||
}
|
||||
});
|
||||
this.rules = rules;
|
||||
return this;
|
||||
},
|
||||
match: function (args) {
|
||||
return !args || args.length === 0;
|
||||
},
|
||||
variables: function (name) {
|
||||
if (this._variables) { return this._variables[name] }
|
||||
else {
|
||||
|
||||
33
test/css/mixins-pattern.css
Normal file
33
test/css/mixins-pattern.css
Normal file
@@ -0,0 +1,33 @@
|
||||
.zero {
|
||||
zero: 0;
|
||||
one: 1;
|
||||
two: 2;
|
||||
three: 3;
|
||||
}
|
||||
.one {
|
||||
one: 1;
|
||||
one-req: 1;
|
||||
two: 2;
|
||||
three: 3;
|
||||
}
|
||||
.two {
|
||||
two: 2;
|
||||
three: 3;
|
||||
}
|
||||
.three {
|
||||
three: 3;
|
||||
}
|
||||
.left {
|
||||
left: 1;
|
||||
}
|
||||
.right {
|
||||
right: 1;
|
||||
}
|
||||
.border-right {
|
||||
color: black;
|
||||
border-right: 4px;
|
||||
}
|
||||
.border-left {
|
||||
color: black;
|
||||
border-left: 4px;
|
||||
}
|
||||
73
test/less/mixins-pattern.less
Normal file
73
test/less/mixins-pattern.less
Normal file
@@ -0,0 +1,73 @@
|
||||
.mixin () {
|
||||
zero: 0;
|
||||
}
|
||||
.mixin (@a: 1px) {
|
||||
one: 1;
|
||||
}
|
||||
.mixin (@a) {
|
||||
one-req: 1;
|
||||
}
|
||||
.mixin (@a: 1px, @b: 2px) {
|
||||
two: 2;
|
||||
}
|
||||
|
||||
.mixin (@a: 1px, @b: 2px, @c: 3px) {
|
||||
three: 3;
|
||||
}
|
||||
|
||||
.zero {
|
||||
.mixin();
|
||||
}
|
||||
|
||||
.one {
|
||||
.mixin(1);
|
||||
}
|
||||
|
||||
.two {
|
||||
.mixin(1, 2);
|
||||
}
|
||||
|
||||
.three {
|
||||
.mixin(1, 2, 3);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
.mixout ('left') {
|
||||
left: 1;
|
||||
}
|
||||
|
||||
.mixout ('right') {
|
||||
right: 1;
|
||||
}
|
||||
|
||||
.left {
|
||||
.mixout('left');
|
||||
}
|
||||
.right {
|
||||
.mixout('right');
|
||||
}
|
||||
.none {
|
||||
.mixout('top');
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
.border (@side, @width) {
|
||||
color: black;
|
||||
.border-side(@side, @width);
|
||||
}
|
||||
.border-side (left, @w) {
|
||||
border-left: @w;
|
||||
}
|
||||
.border-side (right, @w) {
|
||||
border-right: @w;
|
||||
}
|
||||
|
||||
.border-right {
|
||||
.border(right, 4px);
|
||||
}
|
||||
.border-left {
|
||||
.border(left, 4px);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user