diff --git a/lib/less/functions.js b/lib/less/functions.js index 1fb7301a..ef9fa685 100644 --- a/lib/less/functions.js +++ b/lib/less/functions.js @@ -217,22 +217,22 @@ tree.functions = { unit: function (val, unit) { return new(tree.Dimension)(val.value, unit ? unit.toCSS() : ""); }, + convert: function (val, unit) { + return val.convertTo(unit.value); + }, round: function (n, f) { var fraction = typeof(f) === "undefined" ? 0 : f.value; - return this._math(function(num) { return num.toFixed(fraction); }, n); + return this._math(function(num) { return num.toFixed(fraction); }, null, n); }, - ceil: function (n) { - return this._math(Math.ceil, n); + pi: function () { + return new(tree.Dimension)(Math.PI); }, - floor: function (n) { - return this._math(Math.floor, n); + mod: function(a, b) { + return new(tree.Dimension)(a.value % b.value, a.unit); }, - sqrt: function (n) { - return this._math(Math.sqrt, n); - }, - _math: function (fn, n) { + _math: function (fn, unit, n) { if (n instanceof tree.Dimension) { - return new(tree.Dimension)(fn(parseFloat(n.value)), n.unit); + return new(tree.Dimension)(fn(parseFloat(n.value)), unit == null ? n.unit : unit); } else if (typeof(n) === 'number') { return fn(n); } else { @@ -383,6 +383,22 @@ tree.functions = { } }; +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); + }; + }; + +for(var i = 0; i < mathFunctions.length; i++) { + tree.functions[mathFunctions[i].name] = createMathFunction(mathFunctions[i].name, mathFunctions[i].unit); +} + function hsla(color) { return tree.functions.hsla(color.h, color.s, color.l, color.a); } diff --git a/lib/less/tree/dimension.js b/lib/less/tree/dimension.js index f9daa1f6..949433b9 100644 --- a/lib/less/tree/dimension.js +++ b/lib/less/tree/dimension.js @@ -20,7 +20,7 @@ tree.Dimension.prototype = { if (env && env.compress) { // Zero values doesn't need a unit - if (value === 0) { + if (value === 0 && !this.unit.isAngle()) { return strValue; } @@ -89,12 +89,22 @@ tree.Dimension.prototype = { }, unify: function () { - return this.convertTo({ length: 'm', duration: 's' }); + return this.convertTo({ length: 'm', duration: 's', angle: 'rad' }); }, convertTo: function (conversions) { var value = this.value, unit = this.unit.clone(), - i, groupName, group, conversion, targetUnit; + i, groupName, group, conversion, targetUnit, derivedConversions = {}; + + if (typeof conversions === 'string') { + for(i in tree.UnitConversions) { + if (tree.UnitConversions[i].hasOwnProperty(conversions)) { + derivedConversions = {}; + derivedConversions[i] = conversions; + } + } + conversions = derivedConversions; + } for (groupName in conversions) { if (conversions.hasOwnProperty(groupName)) { @@ -134,8 +144,14 @@ tree.UnitConversions = { 'pc': 0.0254 / 72 * 12 }, duration: { - 's': 1, + 's': 1, 'ms': 0.001 + }, + angle: { + 'rad': 1/(2*Math.PI), + 'deg': 1/360, + 'grad': 1/400, + 'turn': 1 } }; @@ -165,6 +181,10 @@ tree.Unit.prototype = { return this.toCSS() === unitString; }, + isAngle: function () { + return tree.UnitConversions.angle.hasOwnProperty(this.toCSS()); + }, + isEmpty: function () { return this.numerator.length == 0 && this.denominator.length == 0; }, diff --git a/test/css/compression/compression.css b/test/css/compression/compression.css index 13fe4de5..ddf95b52 100644 --- a/test/css/compression/compression.css +++ b/test/css/compression/compression.css @@ -1,2 +1,2 @@ #colours{color1:#fea;color2:#fea;color3:rgba(255,238,170,0.1);string:"#ffeeaa"} -dimensions{val:.1px;val:0;val:4cm;val:.2;val:5} +dimensions{val:.1px;val:0;val:4cm;val:.2;val:5;angles-must-have-unit:0deg} diff --git a/test/css/functions.css b/test/css/functions.css index c480a231..d4d3b6e4 100644 --- a/test/css/functions.css +++ b/test/css/functions.css @@ -59,6 +59,15 @@ ceil: 11px; floor: 12px; sqrt: 5px; + pi: 3.141592653589793; + mod: 2m; + abs: 4%; + tan: 0.8390996311772799; + sin: 0.17364817766693033; + cos: 0.8438539587324921; + atan: 0.1rad; + atan: 34.00000000000001deg; + atan: 45.00000000000001deg; percentage: 20%; color: #ff0011; tint: #898989; diff --git a/test/less/compression/compression.less b/test/less/compression/compression.less index bc7b63a7..758a212e 100644 --- a/test/less/compression/compression.less +++ b/test/less/compression/compression.less @@ -11,4 +11,5 @@ dimensions { val: 4cm; val: 0.2; val: 5; + angles-must-have-unit: 0deg; } \ No newline at end of file diff --git a/test/less/functions.less b/test/less/functions.less index 780ef2cb..d8388dee 100644 --- a/test/less/functions.less +++ b/test/less/functions.less @@ -65,6 +65,15 @@ ceil: ceil(10.1px); floor: floor(12.9px); sqrt: sqrt(25px); + pi: pi(); + mod: mod(13m, 11cm); // could take into account units, doesn't at the moment + abs: abs(-4%); + tan: tan(40deg); + sin: sin(10deg); + cos: cos(12); + atan: atan(tan(0.1rad)); + atan: convert(acos(cos(34deg)), deg); + atan: convert(acos(cos(50grad)), deg); percentage: percentage(10px / 50); color: color("#ff0011"); tint: tint(#777777, 13);