Skip to content

Commit 8eea798

Browse files
committed
Merge pull request #1757 from seven-phases-max/tree-functions-cleanup
Tree functions cleanup + CSS Guards `default` error.
2 parents c18c9de + bbc15a4 commit 8eea798

7 files changed

+111
-39
lines changed

lib/less/functions.js

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,6 @@ tree.functions = {
232232
str = str.replace(/%%/g, '%');
233233
return new(tree.Quoted)('"' + str + '"', str);
234234
},
235-
default: function () {
236-
if (this.default.enabled) {
237-
return this.default.value
238-
? tree.True : tree.False;
239-
}
240-
},
241235
unit: function (val, unit) {
242236
if(!(val instanceof tree.Dimension)) {
243237
throw { type: "Argument", message: "the first argument to unit must be a number" + (val instanceof tree.Operation ? ". Have you forgotten parenthesis?" : "") };
@@ -249,7 +243,7 @@ tree.functions = {
249243
},
250244
round: function (n, f) {
251245
var fraction = typeof(f) === "undefined" ? 0 : f.value;
252-
return this._math(function(num) { return num.toFixed(fraction); }, null, n);
246+
return _math(function(num) { return num.toFixed(fraction); }, null, n);
253247
},
254248
pi: function () {
255249
return new(tree.Dimension)(Math.PI);
@@ -267,15 +261,6 @@ tree.functions = {
267261

268262
return new(tree.Dimension)(Math.pow(x.value, y.value), x.unit);
269263
},
270-
_math: function (fn, unit, n) {
271-
if (n instanceof tree.Dimension) {
272-
return new(tree.Dimension)(fn(parseFloat(n.value)), unit == null ? n.unit : unit);
273-
} else if (typeof(n) === 'number') {
274-
return fn(n);
275-
} else {
276-
throw { type: "Argument", message: "argument must be a number" };
277-
}
278-
},
279264
_minmax: function (isMin, args) {
280265
args = Array.prototype.slice.call(args);
281266
switch(args.length) {
@@ -565,22 +550,36 @@ tree._mime = {
565550
}
566551
};
567552

568-
var mathFunctions = [{name:"ceil"}, {name:"floor"}, {name: "sqrt"}, {name:"abs"},
569-
{name:"tan", unit: ""}, {name:"sin", unit: ""}, {name:"cos", unit: ""},
570-
{name:"atan", unit: "rad"}, {name:"asin", unit: "rad"}, {name:"acos", unit: "rad"}],
571-
createMathFunction = function(name, unit) {
572-
return function(n) {
573-
if (unit != null) {
574-
n = n.unify();
575-
}
576-
return this._math(Math[name], unit, n);
577-
};
578-
};
553+
// Math
554+
555+
var mathFunctions = {
556+
// name, unit
557+
ceil: null,
558+
floor: null,
559+
sqrt: null,
560+
abs: null,
561+
tan: "",
562+
sin: "",
563+
cos: "",
564+
atan: "rad",
565+
asin: "rad",
566+
acos: "rad"
567+
};
579568

580-
for(var i = 0; i < mathFunctions.length; i++) {
581-
tree.functions[mathFunctions[i].name] = createMathFunction(mathFunctions[i].name, mathFunctions[i].unit);
569+
function _math(fn, unit, n) {
570+
if (!(n instanceof tree.Dimension)) {
571+
throw { type: "Argument", message: "argument must be a number" };
572+
}
573+
if (unit == null) {
574+
unit = n.unit;
575+
} else {
576+
n = n.unify();
577+
}
578+
return new(tree.Dimension)(fn(parseFloat(n.value)), unit);
582579
}
583580

581+
// ~ End of Math
582+
584583
// Color Blending
585584
// ref: http://www.w3.org/TR/compositing-1
586585

@@ -645,13 +644,47 @@ var colorBlendMode = {
645644
}
646645
};
647646

648-
function colorBlendInit() {
649-
for (var f in colorBlendMode) {
650-
tree.functions[f] = colorBlend.bind(null, colorBlendMode[f]);
647+
// ~ End of Color Blending
648+
649+
tree.defaultFunc = {
650+
eval: function () {
651+
var v = this.value_, e = this.error_;
652+
if (e) {
653+
throw e;
654+
}
655+
if (v != null) {
656+
return v ? tree.True : tree.False;
657+
}
658+
},
659+
value: function (v) {
660+
this.value_ = v;
661+
},
662+
error: function (e) {
663+
this.error_ = e;
664+
},
665+
reset: function () {
666+
this.value_ = this.error_ = null;
651667
}
652-
} colorBlendInit();
668+
};
653669

654-
// ~ End of Color Blending
670+
function initFunctions() {
671+
var f, tf = tree.functions;
672+
673+
// math
674+
for (f in mathFunctions) {
675+
tf[f] = _math.bind(null, Math[f], mathFunctions[f]);
676+
}
677+
678+
// color blending
679+
for (f in colorBlendMode) {
680+
tf[f] = colorBlend.bind(null, colorBlendMode[f]);
681+
}
682+
683+
// default
684+
f = tree.defaultFunc;
685+
tf.default = f.eval.bind(f);
686+
687+
} initFunctions();
655688

656689
function hsla(color) {
657690
return tree.functions.hsla(color.h, color.s, color.l, color.a);

lib/less/tree/mixin.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ tree.mixin.Call.prototype = {
2020
},
2121
eval: function (env) {
2222
var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule;
23-
var candidates = [], candidate, conditionResult = [], defaultFunc = tree.functions.default, defaultUsed = false;
23+
var candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc, defaultUsed = false;
2424

2525
args = this.arguments && this.arguments.map(function (a) {
2626
return { name: a.name, value: a.value.eval(env) };
@@ -29,7 +29,6 @@ tree.mixin.Call.prototype = {
2929
for (i = 0; i < env.frames.length; i++) {
3030
if ((mixins = env.frames[i].find(this.selector)).length > 0) {
3131
isOneFound = true;
32-
defaultFunc.enabled = true;
3332

3433
// To make `default()` function independent of definition order we have two "subpasses" here.
3534
// At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
@@ -54,7 +53,7 @@ tree.mixin.Call.prototype = {
5453

5554
if (mixin.matchCondition) {
5655
for (f = 0; f < 2; f++) {
57-
defaultFunc.value = f;
56+
defaultFunc.value(f);
5857
conditionResult[f] = mixin.matchCondition(args, env);
5958
}
6059
if (conditionResult[0] || conditionResult[1]) {
@@ -86,7 +85,7 @@ tree.mixin.Call.prototype = {
8685
}
8786
}
8887

89-
defaultFunc.enabled = false;
88+
defaultFunc.reset();
9089

9190
for (m in candidates) {
9291
candidate = candidates[m];

lib/less/tree/ruleset.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,18 @@ tree.Ruleset.prototype = {
1919
}
2020
},
2121
eval: function (env) {
22-
var thisSelectors = this.selectors, selectors, selCnt, i;
22+
var thisSelectors = this.selectors, selectors,
23+
selCnt, i, defaultFunc = tree.defaultFunc;
2324
if (thisSelectors && (selCnt = thisSelectors.length)) {
2425
selectors = [];
26+
defaultFunc.error({
27+
type: "Syntax",
28+
message: "it is currently only allowed in parametric mixin guards,"
29+
});
2530
for (i = 0; i < selCnt; i++) {
2631
selectors.push(thisSelectors[i].eval(env));
2732
}
33+
defaultFunc.reset();
2834
}
2935

3036
var rules = this.rules ? this.rules.slice(0) : null,

test/css/mixins-guards-default-func.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,9 @@ guard-default-multi-4 {
112112
always: 2;
113113
case: 2;
114114
}
115+
guard-default-scopes-3 {
116+
3: when default;
117+
}
118+
guard-default-scopes-1 {
119+
1: no condition;
120+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
selector when (default()) {
3+
color: red;
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SyntaxError: error evaluating function `default`: it is currently only allowed in parametric mixin guards, in {path}css-guard-default-func.less on line 2, column 16:
2+
1
3+
2 selector when (default()) {
4+
3 color: red;

test/less/mixins-guards-default-func.less

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,23 @@ guard-default-multi-4 {
157157
.m(1);
158158
.m(2);
159159
}
160+
161+
// default & scope
162+
163+
guard-default-scopes {
164+
.s1() {.m(@v) {1: no condition}}
165+
.s2() {.m(@v) when (@v) {2: when true}}
166+
.s3() {.m(@v) when (default()) {3: when default}}
167+
168+
&-3 {
169+
.s2();
170+
.s3();
171+
.m(false);
172+
}
173+
174+
&-1 {
175+
.s1();
176+
.s3();
177+
.m(false);
178+
}
179+
}

0 commit comments

Comments
 (0)