mirror of
https://github.com/less/less.js.git
synced 2026-04-09 03:00:20 -04:00
* functions.js: (minor) reworking to clean-up initialization of "externally" defined functions (math, blending, default).
* `default` function "front-end" reworked for a bit higher-level control from its "back-end" code (e.g. tree.mixin.eval).
This commit is contained in:
@@ -232,12 +232,6 @@ tree.functions = {
|
||||
str = str.replace(/%%/g, '%');
|
||||
return new(tree.Quoted)('"' + str + '"', str);
|
||||
},
|
||||
default: function () {
|
||||
if (this.default.enabled) {
|
||||
return this.default.value
|
||||
? tree.True : tree.False;
|
||||
}
|
||||
},
|
||||
unit: function (val, unit) {
|
||||
if(!(val instanceof tree.Dimension)) {
|
||||
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 = {
|
||||
},
|
||||
round: function (n, f) {
|
||||
var fraction = typeof(f) === "undefined" ? 0 : f.value;
|
||||
return this._math(function(num) { return num.toFixed(fraction); }, null, n);
|
||||
return _math(function(num) { return num.toFixed(fraction); }, null, n);
|
||||
},
|
||||
pi: function () {
|
||||
return new(tree.Dimension)(Math.PI);
|
||||
@@ -267,15 +261,6 @@ tree.functions = {
|
||||
|
||||
return new(tree.Dimension)(Math.pow(x.value, y.value), x.unit);
|
||||
},
|
||||
_math: function (fn, unit, n) {
|
||||
if (n instanceof tree.Dimension) {
|
||||
return new(tree.Dimension)(fn(parseFloat(n.value)), unit == null ? n.unit : unit);
|
||||
} else if (typeof(n) === 'number') {
|
||||
return fn(n);
|
||||
} else {
|
||||
throw { type: "Argument", message: "argument must be a number" };
|
||||
}
|
||||
},
|
||||
_minmax: function (isMin, args) {
|
||||
args = Array.prototype.slice.call(args);
|
||||
switch(args.length) {
|
||||
@@ -565,22 +550,36 @@ tree._mime = {
|
||||
}
|
||||
};
|
||||
|
||||
var mathFunctions = [{name:"ceil"}, {name:"floor"}, {name: "sqrt"}, {name:"abs"},
|
||||
{name:"tan", unit: ""}, {name:"sin", unit: ""}, {name:"cos", unit: ""},
|
||||
{name:"atan", unit: "rad"}, {name:"asin", unit: "rad"}, {name:"acos", unit: "rad"}],
|
||||
createMathFunction = function(name, unit) {
|
||||
return function(n) {
|
||||
if (unit != null) {
|
||||
n = n.unify();
|
||||
}
|
||||
return this._math(Math[name], unit, n);
|
||||
};
|
||||
};
|
||||
// Math
|
||||
|
||||
for(var i = 0; i < mathFunctions.length; i++) {
|
||||
tree.functions[mathFunctions[i].name] = createMathFunction(mathFunctions[i].name, mathFunctions[i].unit);
|
||||
var mathFunctions = {
|
||||
// name, unit
|
||||
ceil: null,
|
||||
floor: null,
|
||||
sqrt: null,
|
||||
abs: null,
|
||||
tan: "",
|
||||
sin: "",
|
||||
cos: "",
|
||||
atan: "rad",
|
||||
asin: "rad",
|
||||
acos: "rad"
|
||||
};
|
||||
|
||||
function _math(fn, unit, n) {
|
||||
if (!(n instanceof tree.Dimension)) {
|
||||
throw { type: "Argument", message: "argument must be a number" };
|
||||
}
|
||||
if (unit == null) {
|
||||
unit = n.unit;
|
||||
} else {
|
||||
n = n.unify();
|
||||
}
|
||||
return new(tree.Dimension)(fn(parseFloat(n.value)), unit);
|
||||
}
|
||||
|
||||
// ~ End of Math
|
||||
|
||||
// Color Blending
|
||||
// ref: http://www.w3.org/TR/compositing-1
|
||||
|
||||
@@ -645,14 +644,48 @@ var colorBlendMode = {
|
||||
}
|
||||
};
|
||||
|
||||
function colorBlendInit() {
|
||||
for (var f in colorBlendMode) {
|
||||
tree.functions[f] = colorBlend.bind(null, colorBlendMode[f]);
|
||||
}
|
||||
} colorBlendInit();
|
||||
|
||||
// ~ End of Color Blending
|
||||
|
||||
tree.defaultFunc = {
|
||||
eval: function () {
|
||||
var v = this.value_, e = this.error_;
|
||||
if (e) {
|
||||
throw e;
|
||||
}
|
||||
if (v != null) {
|
||||
return v ? tree.True : tree.False;
|
||||
}
|
||||
},
|
||||
value: function (v) {
|
||||
this.value_ = v;
|
||||
},
|
||||
error: function (e) {
|
||||
this.error_ = e;
|
||||
},
|
||||
reset: function () {
|
||||
this.value_ = this.error_ = null;
|
||||
}
|
||||
};
|
||||
|
||||
function initFunctions() {
|
||||
var f, tf = tree.functions;
|
||||
|
||||
// math
|
||||
for (f in mathFunctions) {
|
||||
tf[f] = _math.bind(null, Math[f], mathFunctions[f]);
|
||||
}
|
||||
|
||||
// color blending
|
||||
for (f in colorBlendMode) {
|
||||
tf[f] = colorBlend.bind(null, colorBlendMode[f]);
|
||||
}
|
||||
|
||||
// default
|
||||
f = tree.defaultFunc;
|
||||
tf.default = f.eval.bind(f);
|
||||
|
||||
} initFunctions();
|
||||
|
||||
function hsla(color) {
|
||||
return tree.functions.hsla(color.h, color.s, color.l, color.a);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ tree.mixin.Call.prototype = {
|
||||
},
|
||||
eval: function (env) {
|
||||
var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule;
|
||||
var candidates = [], candidate, conditionResult = [], defaultFunc = tree.functions.default, defaultUsed = false;
|
||||
var candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc, defaultUsed = false;
|
||||
|
||||
args = this.arguments && this.arguments.map(function (a) {
|
||||
return { name: a.name, value: a.value.eval(env) };
|
||||
@@ -29,7 +29,6 @@ tree.mixin.Call.prototype = {
|
||||
for (i = 0; i < env.frames.length; i++) {
|
||||
if ((mixins = env.frames[i].find(this.selector)).length > 0) {
|
||||
isOneFound = true;
|
||||
defaultFunc.enabled = true;
|
||||
|
||||
// To make `default()` function independent of definition order we have two "subpasses" here.
|
||||
// At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
|
||||
@@ -54,7 +53,7 @@ tree.mixin.Call.prototype = {
|
||||
|
||||
if (mixin.matchCondition) {
|
||||
for (f = 0; f < 2; f++) {
|
||||
defaultFunc.value = f;
|
||||
defaultFunc.value(f);
|
||||
conditionResult[f] = mixin.matchCondition(args, env);
|
||||
}
|
||||
if (conditionResult[0] || conditionResult[1]) {
|
||||
@@ -86,7 +85,7 @@ tree.mixin.Call.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
defaultFunc.enabled = false;
|
||||
defaultFunc.reset();
|
||||
|
||||
for (m in candidates) {
|
||||
candidate = candidates[m];
|
||||
|
||||
Reference in New Issue
Block a user