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.
Built from https://develop.svn.wordpress.org/trunk@26548


git-svn-id: http://core.svn.wordpress.org/trunk@26440 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Dominik Schilling 2013-12-03 00:08:09 +00:00
parent 492dfca8ab
commit a6cabe9f6d
2 changed files with 73 additions and 2 deletions

View File

@ -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 */
});
/* =====================================================================

File diff suppressed because one or more lines are too long