Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit a357649

Browse files
bripkensIgorMinar
authored andcommittedJul 14, 2013
fix(angular.equals): add support for regular expressions
Regular expression objects didn't used to be considered to be equal when using 'angular.equals'. Dirty checking therefore failed to recognize a property modification. Closes #2685 Conflicts: test/AngularSpec.js
1 parent 332a3c7 commit a357649

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed
 

‎src/Angular.js

+21-4
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,18 @@ function isArray(value) {
403403
function isFunction(value){return typeof value == 'function';}
404404

405405

406+
/**
407+
* Determines if a value is a regular expression object.
408+
*
409+
* @private
410+
* @param {*} value Reference to check.
411+
* @returns {boolean} True if `value` is a `RegExp`.
412+
*/
413+
function isRegExp(value) {
414+
return toString.apply(value) == '[object RegExp]';
415+
}
416+
417+
406418
/**
407419
* Checks if `obj` is a window object.
408420
*
@@ -622,14 +634,17 @@ function shallowCopy(src, dst) {
622634
* @function
623635
*
624636
* @description
625-
* Determines if two objects or two values are equivalent. Supports value types, arrays and
637+
* Determines if two objects or two values are equivalent. Supports value types, regular expressions, arrays and
626638
* objects.
627639
*
628640
* Two objects or values are considered equivalent if at least one of the following is true:
629641
*
630642
* * Both objects or values pass `===` comparison.
631643
* * Both objects or values are of the same type and all of their properties pass `===` comparison.
632644
* * Both values are NaN. (In JavasScript, NaN == NaN => false. But we consider two NaN as equal)
645+
* * Both values represent the same regular expression (In JavasScript,
646+
* /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
647+
* representation matches).
633648
*
634649
* During a property comparision, properties of `function` type and properties with names
635650
* that begin with `$` are ignored.
@@ -656,6 +671,8 @@ function equals(o1, o2) {
656671
}
657672
} else if (isDate(o1)) {
658673
return isDate(o2) && o1.getTime() == o2.getTime();
674+
} else if (isRegExp(o1) && isRegExp(o2)) {
675+
return o1.toString() == o2.toString();
659676
} else {
660677
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
661678
keySet = {};
@@ -912,9 +929,9 @@ function encodeUriQuery(val, pctEncodeSpaces) {
912929
* one ngApp directive can be used per HTML document. The directive
913930
* designates the root of the application and is typically placed
914931
* at the root of the page.
915-
*
916-
* The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in an
917-
* HTML document you must manually bootstrap them using {@link angular.bootstrap}.
932+
*
933+
* The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in an
934+
* HTML document you must manually bootstrap them using {@link angular.bootstrap}.
918935
* Applications cannot be nested.
919936
*
920937
* In the example below if the `ngApp` directive would not be placed

‎test/AngularSpec.js

+28
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,17 @@ describe('angular', function() {
268268
expect(equals(new Date(0), 0)).toBe(false);
269269
expect(equals(0, new Date(0))).toBe(false);
270270
});
271+
272+
it('should compare regular expressions', function() {
273+
expect(equals(/abc/, /abc/)).toBe(true);
274+
expect(equals(/abc/i, new RegExp('abc', 'i'))).toBe(true);
275+
expect(equals(new RegExp('abc', 'i'), new RegExp('abc', 'i'))).toBe(true);
276+
expect(equals(new RegExp('abc', 'i'), new RegExp('abc'))).toBe(false);
277+
expect(equals(/abc/i, /abc/)).toBe(false);
278+
expect(equals(/abc/, /def/)).toBe(false);
279+
expect(equals(/^abc/, /abc/)).toBe(false);
280+
expect(equals(/^abc/, '/^abc/')).toBe(false);
281+
});
271282
});
272283

273284
describe('size', function() {
@@ -625,6 +636,23 @@ describe('angular', function() {
625636
});
626637
});
627638

639+
640+
describe('isRegExp', function() {
641+
it('should return true for RegExp object', function() {
642+
expect(isRegExp(/^foobar$/)).toBe(true);
643+
expect(isRegExp(new RegExp('^foobar$/'))).toBe(true);
644+
});
645+
646+
it('should return false for non RegExp objects', function() {
647+
expect(isRegExp([])).toBe(false);
648+
expect(isRegExp('')).toBe(false);
649+
expect(isRegExp(23)).toBe(false);
650+
expect(isRegExp({})).toBe(false);
651+
expect(isRegExp(new Date())).toBe(false);
652+
});
653+
});
654+
655+
628656
describe('compile', function() {
629657
it('should link to existing node and create scope', inject(function($rootScope, $compile) {
630658
var template = angular.element('<div>{{greeting = "hello world"}}</div>');

0 commit comments

Comments
 (0)
This repository has been archived.