From 571d574b094cc081116552209f842e1a69dba343 Mon Sep 17 00:00:00 2001 From: "Dominik Schilling (ocean90)" Date: Tue, 3 Dec 2013 00:07:49 +0000 Subject: [PATCH] Customizer: Don't trigger a change event if two unchanged object values are equal. In JavaScript: `{"title":"Foo"} !== {"title":"Foo"}` Underscore.js provides an isEqual function to compare two values to see if they have the same contents, which can be use instead. Because only one function of Underscore.js is needed we just add a copy of `_.isEqual` to customize-base.js. props westonruter. fixes #26061. git-svn-id: https://develop.svn.wordpress.org/trunk@26548 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/js/customize-base.js | 73 +++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/js/customize-base.js b/src/wp-includes/js/customize-base.js index db573b5fca..ec7ca172be 100644 --- a/src/wp-includes/js/customize-base.js +++ b/src/wp-includes/js/customize-base.js @@ -176,7 +176,7 @@ window.wp = window.wp || {}; to = this.validate( to ); // Bail if the sanitized value is null or unchanged. - if ( null === to || this._value === to ) + if ( null === to || this.isEqual( to ) ) return this; this._value = to; @@ -251,7 +251,78 @@ window.wp = window.wp || {}; this.unlink( that ); }); return this; + }, + + isEqual: function( to ) { + return this._eq( this._value, to, [], [] ); + }, + + /** + * Internal recursive comparison function for `isEqual`. + * Copied from Underscore.js. + */ + /* jshint ignore:start */ + _eq: function(a, b, aStack, bStack) { + if (a === b) return a !== 0 || 1 / a == 1 / b; + if (a == null || b == null) return a === b; + + var className = toString.call(a); + if (className != toString.call(b)) return false; + switch (className) { + case '[object String]': + return a == String(b); + case '[object Number]': + return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + return +a == +b; + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') return false; + var length = aStack.length; + while (length--) { + if (aStack[length] == a) return bStack[length] == b; + } + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !((typeof aCtor === 'function') && (aCtor instanceof aCtor) && + (typeof bCtor === 'function') && (bCtor instanceof bCtor))) { + return false; + } + aStack.push(a); + bStack.push(b); + var size = 0, result = true; + + if (className == '[object Array]') { + size = a.length; + result = size == b.length; + if (result) { + while (size--) { + if (!(result = this._eq(a[size], b[size], aStack, bStack))) break; + } + } + } else { + for (var key in a) { + if (hasOwnProperty.call(a, key)) { + size++; + if (!(result = hasOwnProperty.call(b, key) && this._eq(a[key], b[key], aStack, bStack))) break; + } + } + if (result) { + for (key in b) { + if (hasOwnProperty.call(b, key) && !(size--)) break; + } + result = !size; + } + } + aStack.pop(); + bStack.pop(); + return result; } + /* jshint ignore:end */ }); /* =====================================================================