diff --git a/Source/Scene/Expression.js b/Source/Scene/Expression.js index a7a347a22d22..90e893d49874 100644 --- a/Source/Scene/Expression.js +++ b/Source/Scene/Expression.js @@ -18,7 +18,7 @@ define([ "use strict"; var unaryOperators = ['!', '-', '+']; - var binaryOperators = ['+', '-', '*', '/', '%', '==', '!=', '>', '>=', '<', '<=', '&&', '||', '!~', '=~']; + var binaryOperators = ['+', '-', '*', '/', '%', '===', '==', '!==', '!=', '>', '>=', '<', '<=', '&&', '||', '!~', '=~']; var variableRegex = /\${(.*?)}/g; var backslashRegex = /\\/g; @@ -531,8 +531,12 @@ define([ node.evaluate = node._evaluateDivide; } else if (node._value === '%') { node.evaluate = node._evaluateMod; + } else if (node._value === '===') { + node.evaluate = node._evaluateEqualsStrict; } else if (node._value === '==') { node.evaluate = node._evaluateEquals; + } else if (node._value === '!==') { + node.evaluate = node._evaluateNotEqualsStrict; } else if (node._value === '!=') { node.evaluate = node._evaluateNotEquals; } else if (node._value === '<') { @@ -834,6 +838,15 @@ define([ return left % right; }; + Node.prototype._evaluateEqualsStrict = function(feature) { + var left = this._left.evaluate(feature); + var right = this._right.evaluate(feature); + if ((right instanceof Color) && (left instanceof Color)) { + return Color.equals(left, right); + } + return left === right; + }; + Node.prototype._evaluateEquals = function(feature) { var left = this._left.evaluate(feature); var right = this._right.evaluate(feature); @@ -842,11 +855,11 @@ define([ } // Specifically want to do an abstract equality comparison (==) instead of a strict equality comparison (===) - // so that cases like "5 === '5'" return true. Tell jsHint to ignore this line. + // so that cases like "5 == '5'" return true. Tell jsHint to ignore this line. return left == right; // jshint ignore:line }; - Node.prototype._evaluateNotEquals = function(feature) { + Node.prototype._evaluateNotEqualsStrict = function(feature) { var left = this._left.evaluate(feature); var right = this._right.evaluate(feature); if ((right instanceof Color) && (left instanceof Color)) { @@ -855,6 +868,17 @@ define([ return left !== right; }; + Node.prototype._evaluateNotEquals = function(feature) { + var left = this._left.evaluate(feature); + var right = this._right.evaluate(feature); + if ((right instanceof Color) && (left instanceof Color)) { + return !Color.equals(left, right); + } + // Specifically want to do an abstract inequality comparison (!=) instead of a strict inequality comparison (!==) + // so that cases like "5 != '5'" return false. Tell jsHint to ignore this line. + return left != right; // jshint ignore:line + }; + Node.prototype._evaluateConditional = function(feature) { if (this._test.evaluate(feature)) { return this._left.evaluate(feature); @@ -1095,9 +1119,13 @@ define([ //>>includeEnd('debug'); return value + left; case ExpressionNodeType.BINARY: - // Supported types: ||, &&, ==, !=, <, >, <=, >=, +, -, *, /, % + // Supported types: ||, &&, ===, ==, !==, !=, <, >, <=, >=, +, -, *, /, % if (value === '%') { return 'mod(' + left + ', ' + right + ')'; + } else if (value === '===') { + return '(' + left + ' == ' + right + ')'; + } else if (value === '!==') { + return '(' + left + ' != ' + right + ')'; } return '(' + left + ' ' + value + ' ' + right + ')'; case ExpressionNodeType.CONDITIONAL: diff --git a/Specs/Scene/ExpressionSpec.js b/Specs/Scene/ExpressionSpec.js index 806db406cb67..99032f5f915a 100644 --- a/Specs/Scene/ExpressionSpec.js +++ b/Specs/Scene/ExpressionSpec.js @@ -160,14 +160,6 @@ defineSuite([ return new Expression('2 & 3'); }).toThrowDeveloperError(); - expect(function() { - return new Expression('2 === 3'); - }).toThrowDeveloperError(); - - expect(function() { - return new Expression('2 !== 3'); - }).toThrowDeveloperError(); - expect(function() { return new Expression('2 << 3'); }).toThrowDeveloperError(); @@ -543,6 +535,20 @@ defineSuite([ expect(expression.evaluate(undefined)).toEqual(2); }); + it('evaluates binary equals strict', function() { + var expression = new Expression('\'hello\' === \'hello\''); + expect(expression.evaluate(undefined)).toEqual(true); + + expression = new Expression('1 === 2'); + expect(expression.evaluate(undefined)).toEqual(false); + + expression = new Expression('false === true === false'); + expect(expression.evaluate(undefined)).toEqual(true); + + expression = new Expression('1 === "1"'); + expect(expression.evaluate(undefined)).toEqual(false); + }); + it('evaluates binary equals', function() { var expression = new Expression('\'hello\' == \'hello\''); expect(expression.evaluate(undefined)).toEqual(true); @@ -552,6 +558,23 @@ defineSuite([ expression = new Expression('false == true == false'); expect(expression.evaluate(undefined)).toEqual(true); + + expression = new Expression('1 == "1"'); + expect(expression.evaluate(undefined)).toEqual(true); + }); + + it('evaluates binary not equals strict', function() { + var expression = new Expression('\'hello\' !== \'hello\''); + expect(expression.evaluate(undefined)).toEqual(false); + + expression = new Expression('1 !== 2'); + expect(expression.evaluate(undefined)).toEqual(true); + + expression = new Expression('false !== true !== false'); + expect(expression.evaluate(undefined)).toEqual(true); + + expression = new Expression('1 !== "1"'); + expect(expression.evaluate(undefined)).toEqual(true); }); it('evaluates binary not equals', function() { @@ -563,6 +586,9 @@ defineSuite([ expression = new Expression('false != true != false'); expect(expression.evaluate(undefined)).toEqual(true); + + expression = new Expression('1 != "1"'); + expect(expression.evaluate(undefined)).toEqual(false); }); it('evaluates binary less than', function() { @@ -1292,6 +1318,13 @@ defineSuite([ expect(shaderExpression).toEqual(expected); }); + it('gets shader expression for binary equals strict', function() { + var expression = new Expression('1.0 === 2.0'); + var shaderExpression = expression.getShaderExpression('', {}); + var expected = '(1.0 == 2.0)'; + expect(shaderExpression).toEqual(expected); + }); + it('gets shader expression for binary equals', function() { var expression = new Expression('1.0 == 2.0'); var shaderExpression = expression.getShaderExpression('', {}); @@ -1299,6 +1332,13 @@ defineSuite([ expect(shaderExpression).toEqual(expected); }); + it('gets shader expression for binary not equals strict', function() { + var expression = new Expression('1.0 !== 2.0'); + var shaderExpression = expression.getShaderExpression('', {}); + var expected = '(1.0 != 2.0)'; + expect(shaderExpression).toEqual(expected); + }); + it('gets shader expression for binary not equals', function() { var expression = new Expression('1.0 != 2.0'); var shaderExpression = expression.getShaderExpression('', {});