Merge branch 'reworked-guard-comparison' of github.com:seven-phases-max/less.js into 2_0_0

Conflicts:
	lib/less/tree.js
	lib/less/tree/anonymous.js
	lib/less/tree/color.js
	lib/less/tree/condition.js
	lib/less/tree/dimension.js
	lib/less/tree/keyword.js
	lib/less/tree/quoted.js
This commit is contained in:
Luke Page
2014-09-06 01:52:47 +01:00
10 changed files with 191 additions and 92 deletions

View File

@@ -12,19 +12,8 @@ Anonymous.prototype.type = "Anonymous";
Anonymous.prototype.eval = function () {
return new Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines, this.rulesetLike);
};
Anonymous.prototype.compare = function (x) {
if (!x.toCSS) {
return -1;
}
var left = this.toCSS(),
right = x.toCSS();
if (left === right) {
return 0;
}
return left < right ? -1 : 1;
Anonymous.prototype.compare = function (other) {
return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
};
Anonymous.prototype.isRulesetLike = function() {
return this.rulesetLike;

View File

@@ -162,14 +162,11 @@ Color.prototype.toARGB = function () {
return toHex([this.alpha * 255].concat(this.rgb));
};
Color.prototype.compare = function (x) {
if (!x.rgb) {
return -1;
}
return (x.rgb[0] === this.rgb[0] &&
return (x.rgb &&
x.rgb[0] === this.rgb[0] &&
x.rgb[1] === this.rgb[1] &&
x.rgb[2] === this.rgb[2] &&
x.alpha === this.alpha) ? 0 : -1;
x.alpha === this.alpha) ? 0 : undefined;
};
Color.fromKeyword = function(keyword) {

View File

@@ -14,34 +14,20 @@ Condition.prototype.accept = function (visitor) {
this.rvalue = visitor.visit(this.rvalue);
};
Condition.prototype.eval = function (env) {
var a = this.lvalue.eval(env),
b = this.rvalue.eval(env);
var i = this.index, result;
result = (function (op) {
var result = (function (op, a, b) {
switch (op) {
case 'and':
return a && b;
case 'or':
return a || b;
case 'and': return a && b;
case 'or': return a || b;
default:
if (a.compare) {
result = a.compare(b);
} else if (b.compare) {
result = b.compare(a);
} else {
throw { type: "Type",
message: "Unable to perform comparison",
index: i };
}
switch (result) {
switch (Node.compare(a, b)) {
case -1: return op === '<' || op === '=<' || op === '<=';
case 0: return op === '=' || op === '>=' || op === '=<' || op === '<=';
case 1: return op === '>' || op === '>=';
default: return false;
}
}
})(this.op);
}) (this.op, this.lvalue.eval(env), this.rvalue.eval(env));
return this.negate ? !result : result;
};
module.exports = Condition;

View File

@@ -89,33 +89,24 @@ Dimension.prototype.operate = function (env, op, other) {
return new(Dimension)(value, unit);
};
Dimension.prototype.compare = function (other) {
if (other instanceof Dimension) {
var a, b,
aValue, bValue;
var a, b;
if (this.unit.isEmpty() || other.unit.isEmpty()) {
a = this;
b = other;
} else {
a = this.unify();
b = other.unify();
if (a.unit.compare(b.unit) !== 0) {
return -1;
}
}
aValue = a.value;
bValue = b.value;
if (bValue > aValue) {
return -1;
} else if (bValue < aValue) {
return 1;
} else {
return 0;
}
} else {
return -1;
if (!(other instanceof Dimension)) {
return undefined;
}
if (this.unit.isEmpty() || other.unit.isEmpty()) {
a = this;
b = other;
} else {
a = this.unify();
b = other.unify();
if (a.unit.compare(b.unit) !== 0) {
return undefined;
}
}
return Node.numericCompare(a.value, b.value);
};
Dimension.prototype.unify = function () {
return this.convertTo({ length: 'px', duration: 's', angle: 'rad' });

View File

@@ -7,13 +7,6 @@ Keyword.prototype.genCSS = function (env, output) {
if (this.value === '%') { throw { type: "Syntax", message: "Invalid % without number" }; }
output.add(this.value);
};
Keyword.prototype.compare = function (other) {
if (other instanceof Keyword) {
return other.value === this.value ? 0 : 1;
} else {
return -1;
}
};
Keyword.True = new(Keyword)('true');
Keyword.False = new(Keyword)('false');

View File

@@ -32,4 +32,43 @@ Node.prototype.fround = function(env, value) {
//add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999....) are properly rounded...
return (precision == null) ? value : Number((value + 2e-16).toFixed(precision));
};
Node.compare = function (a, b) {
/* returns:
-1: a < b
0: a = b
1: a > b
and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */
if ((a.compare) &&
// for "symmetric results" force toCSS-based comparison
// of Quoted or Anonymous if either value is one of those
!(b.type === "Quoted" || b.type === "Anonymous")) {
return a.compare(b);
} else if (b.compare) {
return -b.compare(a);
} else if (a.type !== b.type) {
return undefined;
}
a = a.value;
b = b.value;
if (!Array.isArray(a)) {
return a === b ? 0 : undefined;
}
if (a.length !== b.length) {
return undefined;
}
for (var i = 0; i < a.length; i++) {
if (Node.compare(a[i], b[i]) !== 0) {
return undefined;
}
}
return 0;
};
Node.numericCompare = function (a, b) {
return a < b ? -1
: a === b ? 0
: a > b ? 1 : undefined;
};
module.exports = Node;

View File

@@ -1,4 +1,5 @@
var JsEvalNode = require("./js-eval-node.js"),
var Node = require("./node.js"),
JsEvalNode = require("./js-eval-node.js"),
Variable = require("./variable.js");
var Quoted = function (str, content, escaped, index, currentFileInfo) {
@@ -29,26 +30,12 @@ Quoted.prototype.eval = function (env) {
});
return new(Quoted)(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo);
};
Quoted.prototype.compare = function (x) {
if (!x.toCSS) {
return -1;
}
var left, right;
Quoted.prototype.compare = function (other) {
// when comparing quoted strings allow the quote to differ
if (x.type === "Quoted" && !this.escaped && !x.escaped) {
left = x.value;
right = this.value;
if (other.type === "Quoted" && !this.escaped && !other.escaped) {
return Node.numericCompare(this.value, other.value);
} else {
left = this.toCSS();
right = x.toCSS();
return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
}
if (left === right) {
return 0;
}
return left < right ? -1 : 1;
};
module.exports = Quoted;

View File

@@ -31,7 +31,7 @@ Unit.prototype.toString = function () {
return returnStr;
};
Unit.prototype.compare = function (other) {
return this.is(other.toString()) ? 0 : -1;
return this.is(other.toString()) ? 0 : undefined;
};
Unit.prototype.is = function (unitString) {
return this.toString().toUpperCase() === unitString.toUpperCase();

View File

@@ -79,6 +79,80 @@
content: theme1 is not 'theme2';
content: theme1 is theme1;
}
.variouse-types-comparision {
/**/
content: true is not equal to false;
content: false is not equal to true too;
/**/
content: 1 is not equal to true;
content: true is not equal to 1 too;
/**/
content: 2 is equal to 2px;
content: 2px is equal to 2 too;
/**/
content: 3 is equal to 3;
content: 3 is equal to 3 too;
/**/
content: 5 is not equal to 4;
content: 4 is not equal to 5 too;
/**/
content: abc is equal to abc;
content: abc is equal to abc too;
/**/
content: abc is not equal to "abc";
content: "abc" is not equal to abc too;
/**/
content: 'abc' is less than "abd";
content: "abd" is greater than 'abc' too;
content: 'abc' is not equal to "abd";
content: "abd" is not equal to 'abc' too;
/**/
content: 6 is equal to 6;
content: 6 is equal to 6 too;
/**/
content: 8 is less than 9 too;
content: 9 is greater than 8;
content: 9 is not equal to 8;
content: 8 is not equal to 9 too;
/**/
content: a is not equal to b;
content: b is not equal to a too;
/**/
content: 1 2 is not equal to 3;
content: 3 is not equal to 1 2 too;
}
.list-comparision {
/**/
content: a b c is equal to a b c;
content: a b c is equal to a b c too;
/**/
content: a b c is not equal to a b d;
content: a b d is not equal to a b c too;
/**/
content: a, b, c is equal to a, b, c;
content: a, b, c is equal to a, b, c too;
/**/
content: a, b, c is not equal to a, b, d;
content: a, b, d is not equal to a, b, c too;
/**/
content: 1 2px 300ms is equal to 1em 2 0.3s;
content: 1em 2 0.3s is equal to 1 2px 300ms too;
/**/
content: 1 2 3 is not equal to 1, 2, 3;
content: 1, 2, 3 is not equal to 1 2 3 too;
/**/
content: 1, 2, 3 is equal to 1, 2, 3;
content: 1, 2, 3 is equal to 1, 2, 3 too;
/**/
content: 1 2 3 1, 2, 3 is equal to 1 2 3 1, 2, 3;
content: 1 2 3 1, 2, 3 is equal to 1 2 3 1, 2, 3 too;
/**/
content: 1 2 3 1, 2, 3 is not equal to 1, 2, 3 1 2 3;
content: 1, 2, 3 1 2 3 is not equal to 1 2 3 1, 2, 3 too;
/**/
content: 1 2 3 1, 2, 3 4 is equal to 1 2 3 1, 2, 3 4;
content: 1 2 3 1, 2, 3 4 is equal to 1 2 3 1, 2, 3 4 too;
}
#tryNumberPx {
catch: all;
declare: 4;

View File

@@ -130,6 +130,49 @@
.stringguard(theme1);
}
.generic(@a, @b) {/**/}
.generic(@a, @b) when (@a = @b) {content: @a is equal to @b}
.generic(@a, @b) when (@b = @a) {content: @b is equal to @a too}
.generic(@a, @b) when (@a < @b) {content: @a is less than @b}
.generic(@a, @b) when (@b < @a) {content: @b is less than @a too}
.generic(@a, @b) when (@a > @b) {content: @a is greater than @b}
.generic(@a, @b) when (@b > @a) {content: @b is greater than @a too}
.generic(@a, @b) when not(@a = @b) {content: @a is not equal to @b}
.generic(@a, @b) when not(@b = @a) {content: @b is not equal to @a too}
.variouse-types-comparision {
.generic(true, false);
.generic(1, true);
.generic(2, 2px);
.generic(3, ~"3");
.generic(5, ~"4");
.generic(abc, ~"abc");
.generic(abc, "abc");
.generic('abc', "abd");
.generic(6, e("6"));
.generic(`9`, 8);
.generic(a, b);
.generic(1 2, 3);
}
.list-comparision {
.generic(a b c, a b c);
.generic(a b c, a b d);
.generic(a, b, c; a, b, c);
.generic(a, b, c; a, b, d);
.generic(1 2px 300ms, 1em 2 .3s);
@space-list: 1 2 3;
@comma-list: 1, 2, 3;
@compound: @space-list @comma-list;
.generic(@space-list, @comma-list);
.generic(@comma-list, ~"1, 2, 3");
.generic(@compound, @space-list @comma-list);
.generic(@compound, @comma-list @space-list);
.generic(@compound 4, ~"1 2 3 1, 2, 3 4");
}
.mixin(...) {
catch:all;
}