Index: chrome/browser/resources/settings/prefs/prefs.js |
diff --git a/chrome/browser/resources/settings/prefs/prefs.js b/chrome/browser/resources/settings/prefs/prefs.js |
index 4d1e7062562064b78318f4a5ee21aeaf9ffe4b1d..5930be57c7023ccf3f4e014c3bc884ead2e6c172 100644 |
--- a/chrome/browser/resources/settings/prefs/prefs.js |
+++ b/chrome/browser/resources/settings/prefs/prefs.js |
@@ -51,8 +51,7 @@ PrefWrapper.prototype.equals = function(other) { |
*/ |
function ListPrefWrapper(prefObj) { |
Dan Beam
2015/09/17 06:36:56
Why wouldn't we just make a DictPrefWrapper?
michaelpg
2015/09/17 17:53:47
These wrappers don't make much sense to me so I'm
Dan Beam
2015/09/17 18:13:31
that's not a problem
michaelpg
2015/09/17 22:54:45
I'm happy to separate out the equality methods, bu
|
// Copy the array so changes to prefObj aren't reflected in this.value_. |
- // TODO(michaelpg): Do a deep copy to support nested lists and objects. |
- this.value_ = prefObj.value.slice(); |
+ this.value_ = PrefWrapper.deepCopy(prefObj.value); |
} |
ListPrefWrapper.prototype = { |
@@ -63,21 +62,71 @@ function ListPrefWrapper(prefObj) { |
* @override |
*/ |
equals: function(other) { |
- 'use strict'; |
assert(this.key_ == other.key_); |
- if (this.value_.length != other.value_.length) |
- return false; |
- for (let i = 0; i < this.value_.length; i++) { |
- if (this.value_[i] != other.value_[i]) |
- return false; |
- } |
- return true; |
+ return PrefWrapper.valuesEquivalent(this.value_, other.value_); |
}, |
}; |
(function() { |
'use strict'; |
+ /** |
+ * @param {*} val1 Value to compare. |
+ * @param {*} val2 Value to compare with val1. |
+ * @return {boolean} True if the values are equivalent (equal |
+ * fundamental values, or objects whose elements are equivalent). |
+ */ |
+ PrefWrapper.valuesEquivalent = function(val1, val2) { |
Dan Beam
2015/09/17 06:36:56
var toString = Object.prototype.toString;
if (toSt
michaelpg
2015/09/17 17:53:47
I assume 80% of the time we'll be comparing boolea
|
+ if (val1 == val2) |
Dan Beam
2015/09/17 06:36:56
Eh probably don't do this without type checking fi
michaelpg
2015/09/17 17:53:47
Acknowledged.
michaelpg
2015/09/17 22:54:45
Actually, in my new version I think checking "==="
Dan Beam
2015/09/17 23:07:51
=== is probably OK, yeah
|
+ return true; |
+ |
+ if (Array.isArray(val1)) { |
+ if (!Array.isArray(val2)) |
+ return false; |
+ if (val1.length != val2.length) |
+ return false; |
+ |
+ for (var i = 0; i < val1.length; i++) { |
+ if (!PrefWrapper.valuesEquivalent(val1[i], val2[i])) |
+ return false; |
+ } |
+ return true; |
Dan Beam
2015/09/17 18:13:31
this is the ListPrefWrapper.equals implementation
|
+ } |
+ |
+ if (typeof val1 == 'object') { |
Dan Beam
2015/09/17 06:36:56
What about {}, null?
michaelpg
2015/09/17 17:53:47
{}: "just works", valuesEquivalent({}, {}) == true
Dan Beam
2015/09/17 18:13:31
no, I meant val1 == {}, val2 == null
michaelpg
2015/09/17 22:54:45
New version handles this case.
|
+ var props1 = Object.keys(val1); |
+ var props2 = Object.keys(val2); |
+ if (props1.length != props2.length) |
+ return false; |
+ for (var prop of props1) { |
+ if (!PrefWrapper.valuesEquivalent(val1[prop], val2[prop])) |
+ return false; |
+ } |
+ return true; |
Dan Beam
2015/09/17 18:13:31
this is the DictPrefWrapper.equals implementation
michaelpg
2015/09/17 22:54:45
the problem is I don't want a ListPrefWrapper to b
|
+ } |
+ |
+ return false; |
+ }; |
+ |
+ /** |
+ * @param {*} val Value to copy. |
+ * @return {*} A deep copy of the value. |
+ */ |
+ PrefWrapper.deepCopy = function(val) { |
+ if (Array.isArray(val)) { |
+ var copy = []; |
+ for (let el of val) |
+ copy.push(PrefWrapper.deepCopy(el)); |
+ return copy; |
+ } |
+ if (typeof val == 'object') { |
Dan Beam
2015/09/17 06:36:56
null?
michaelpg
2015/09/17 17:53:47
Done.
|
+ var copy = {}; |
+ for (let prop in val) |
+ copy[prop] = PrefWrapper.deepCopy(val[prop]); |
+ } |
+ return val; |
+ }; |
+ |
Polymer({ |
is: 'cr-settings-prefs', |
@@ -142,7 +191,7 @@ function ListPrefWrapper(prefObj) { |
// If settingsPrivate already has this value, do nothing. (Otherwise, |
// a change event from settingsPrivate could make us call |
// settingsPrivate.setPref and potentially trigger an IPC loop.) |
- if (prefWrapper.equals(this.createPrefWrapper_(prefObj))) |
+ if (PrefWrapper.valuesEquivalent(prefWrapper.value_, prefObj.value)) |
return; |
this.settingsApi_.setPref( |