Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(806)

Side by Side Diff: chrome/browser/resources/settings/prefs/prefs.js

Issue 2834433002: MD Settings: ESLint --fix output, WIP. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* Copyright 2015 The Chromium Authors. All rights reserved. 1 /* Copyright 2015 The Chromium Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. */ 3 * found in the LICENSE file. */
4 4
5 /** 5 /**
6 * @fileoverview 6 * @fileoverview
7 * 'settings-prefs' exposes a singleton model of Chrome settings and 7 * 'settings-prefs' exposes a singleton model of Chrome settings and
8 * preferences, which listens to changes to Chrome prefs whitelisted in 8 * preferences, which listens to changes to Chrome prefs whitelisted in
9 * chrome.settingsPrivate. When changing prefs in this element's 'prefs' 9 * chrome.settingsPrivate. When changing prefs in this element's 'prefs'
10 * property via the UI, the singleton model tries to set those preferences in 10 * property via the UI, the singleton model tries to set those preferences in
11 * Chrome. Whether or not the calls to settingsPrivate.setPref succeed, 'prefs' 11 * Chrome. Whether or not the calls to settingsPrivate.setPref succeed, 'prefs'
12 * is eventually consistent with the Chrome pref store. 12 * is eventually consistent with the Chrome pref store.
13 */ 13 */
14 14
15 (function() { 15 (function() {
16 'use strict'; 16 'use strict';
17 17
18 /** 18 /**
19 * Checks whether two values are recursively equal. Only compares serializable 19 * Checks whether two values are recursively equal. Only compares serializable
20 * data (primitives, serializable arrays and serializable objects). 20 * data (primitives, serializable arrays and serializable objects).
21 * @param {*} val1 Value to compare. 21 * @param {*} val1 Value to compare.
22 * @param {*} val2 Value to compare with val1. 22 * @param {*} val2 Value to compare with val1.
23 * @return {boolean} True if the values are recursively equal. 23 * @return {boolean} True if the values are recursively equal.
24 */ 24 */
25 function deepEqual(val1, val2) { 25 function deepEqual(val1, val2) {
26 if (val1 === val2) 26 if (val1 === val2)
27 return true; 27 return true;
28 28
29 if (Array.isArray(val1) || Array.isArray(val2)) { 29 if (Array.isArray(val1) || Array.isArray(val2)) {
30 if (!Array.isArray(val1) || !Array.isArray(val2)) 30 if (!Array.isArray(val1) || !Array.isArray(val2))
31 return false; 31 return false;
32 return arraysEqual(/** @type {!Array} */(val1), 32 return arraysEqual(/** @type {!Array} */(val1),
33 /** @type {!Array} */(val2)); 33 /** @type {!Array} */(val2));
34 } 34 }
35 35
36 if (val1 instanceof Object && val2 instanceof Object) 36 if (val1 instanceof Object && val2 instanceof Object)
37 return objectsEqual(val1, val2); 37 return objectsEqual(val1, val2);
38 38
39 return false; 39 return false;
40 } 40 }
41 41
42 /** 42 /**
43 * @param {!Array} arr1 43 * @param {!Array} arr1
44 * @param {!Array} arr2 44 * @param {!Array} arr2
45 * @return {boolean} True if the arrays are recursively equal. 45 * @return {boolean} True if the arrays are recursively equal.
46 */ 46 */
47 function arraysEqual(arr1, arr2) { 47 function arraysEqual(arr1, arr2) {
48 if (arr1.length != arr2.length) 48 if (arr1.length != arr2.length)
49 return false;
50
51 for (var i = 0; i < arr1.length; i++) {
52 if (!deepEqual(arr1[i], arr2[i]))
49 return false; 53 return false;
54 }
50 55
51 for (var i = 0; i < arr1.length; i++) { 56 return true;
52 if (!deepEqual(arr1[i], arr2[i])) 57 }
53 return false;
54 }
55
56 return true;
57 }
58 58
59 /** 59 /**
60 * @param {!Object} obj1 60 * @param {!Object} obj1
61 * @param {!Object} obj2 61 * @param {!Object} obj2
62 * @return {boolean} True if the objects are recursively equal. 62 * @return {boolean} True if the objects are recursively equal.
63 */ 63 */
64 function objectsEqual(obj1, obj2) { 64 function objectsEqual(obj1, obj2) {
65 var keys1 = Object.keys(obj1); 65 var keys1 = Object.keys(obj1);
66 var keys2 = Object.keys(obj2); 66 var keys2 = Object.keys(obj2);
67 if (keys1.length != keys2.length) 67 if (keys1.length != keys2.length)
68 return false;
69
70 for (var i = 0; i < keys1.length; i++) {
71 var key = keys1[i];
72 if (!deepEqual(obj1[key], obj2[key]))
68 return false; 73 return false;
74 }
69 75
70 for (var i = 0; i < keys1.length; i++) { 76 return true;
71 var key = keys1[i]; 77 }
72 if (!deepEqual(obj1[key], obj2[key]))
73 return false;
74 }
75
76 return true;
77 }
78 78
79 /** 79 /**
80 * Returns a recursive copy of the value. 80 * Returns a recursive copy of the value.
81 * @param {*} val Value to copy. Should be a primitive or only contain 81 * @param {*} val Value to copy. Should be a primitive or only contain
82 * serializable data (primitives, serializable arrays and 82 * serializable data (primitives, serializable arrays and
83 * serializable objects). 83 * serializable objects).
84 * @return {*} A deep copy of the value. 84 * @return {*} A deep copy of the value.
85 */ 85 */
86 function deepCopy(val) { 86 function deepCopy(val) {
87 if (!(val instanceof Object)) 87 if (!(val instanceof Object))
88 return val; 88 return val;
89 return Array.isArray(val) ? deepCopyArray(/** @type {!Array} */(val)) : 89 return Array.isArray(val) ? deepCopyArray(/** @type {!Array} */(val)) :
90 deepCopyObject(val); 90 deepCopyObject(val);
91 }; 91 }
Dan Beam 2017/04/19 19:04:40 did you do this or did eslint --fix do this?
dpapad 2017/04/19 19:19:55 I didn't do any manual text editing in this CL. Th
dpapad 2017/05/05 18:20:46 So this was done because of http://eslint.org/docs
92 92
93 /** 93 /**
94 * @param {!Array} arr 94 * @param {!Array} arr
95 * @return {!Array} Deep copy of the array. 95 * @return {!Array} Deep copy of the array.
96 */ 96 */
97 function deepCopyArray(arr) { 97 function deepCopyArray(arr) {
98 var copy = []; 98 var copy = [];
99 for (var i = 0; i < arr.length; i++) 99 for (var i = 0; i < arr.length; i++)
100 copy.push(deepCopy(arr[i])); 100 copy.push(deepCopy(arr[i]));
101 return copy; 101 return copy;
102 } 102 }
103 103
104 /** 104 /**
105 * @param {!Object} obj 105 * @param {!Object} obj
106 * @return {!Object} Deep copy of the object. 106 * @return {!Object} Deep copy of the object.
107 */ 107 */
108 function deepCopyObject(obj) { 108 function deepCopyObject(obj) {
109 var copy = {}; 109 var copy = {};
110 var keys = Object.keys(obj); 110 var keys = Object.keys(obj);
111 for (var i = 0; i < keys.length; i++) { 111 for (var i = 0; i < keys.length; i++) {
112 var key = keys[i]; 112 var key = keys[i];
113 copy[key] = deepCopy(obj[key]); 113 copy[key] = deepCopy(obj[key]);
114 }
115 return copy;
116 } 114 }
115 return copy;
116 }
117 117
118 Polymer({ 118 Polymer({
119 is: 'settings-prefs', 119 is: 'settings-prefs',
120 120
121 properties: { 121 properties: {
122 /** 122 /**
123 * Object containing all preferences, for use by Polymer controls. 123 * Object containing all preferences, for use by Polymer controls.
124 * @type {Object|undefined} 124 * @type {Object|undefined}
125 */ 125 */
126 prefs: { 126 prefs: {
127 type: Object, 127 type: Object,
128 notify: true, 128 notify: true,
129 }, 129 },
130 130
131 /** 131 /**
132 * Map of pref keys to values representing the state of the Chrome 132 * Map of pref keys to values representing the state of the Chrome
133 * pref store as of the last update from the API. 133 * pref store as of the last update from the API.
134 * @type {Object<*>} 134 * @type {Object<*>}
135 * @private 135 * @private
136 */ 136 */
137 lastPrefValues_: { 137 lastPrefValues_: {
138 type: Object, 138 type: Object,
139 value: function() { return {}; }, 139 value: function() { return {}; },
140 },
141 }, 140 },
141 },
142 142
143 observers: [ 143 observers: [
144 'prefsChanged_(prefs.*)', 144 'prefsChanged_(prefs.*)',
145 ], 145 ],
146 146
147 /** @type {SettingsPrivate} */ 147 /** @type {SettingsPrivate} */
148 settingsApi_: /** @type {SettingsPrivate} */(chrome.settingsPrivate), 148 settingsApi_: /** @type {SettingsPrivate} */(chrome.settingsPrivate),
149 149
150 /** @override */ 150 /** @override */
151 created: function() { 151 created: function() {
152 if (!CrSettingsPrefs.deferInitialization) 152 if (!CrSettingsPrefs.deferInitialization)
153 this.initialize(); 153 this.initialize();
154 }, 154 },
155 155
156 /** @override */ 156 /** @override */
157 detached: function() { 157 detached: function() {
158 CrSettingsPrefs.resetForTesting(); 158 CrSettingsPrefs.resetForTesting();
159 }, 159 },
160 160
161 /** 161 /**
162 * @param {SettingsPrivate=} opt_settingsApi SettingsPrivate implementation 162 * @param {SettingsPrivate=} opt_settingsApi SettingsPrivate implementation
163 * to use (chrome.settingsPrivate by default). 163 * to use (chrome.settingsPrivate by default).
164 */ 164 */
165 initialize: function(opt_settingsApi) { 165 initialize: function(opt_settingsApi) {
166 // Only initialize once (or after resetForTesting() is called). 166 // Only initialize once (or after resetForTesting() is called).
167 if (this.initialized_) 167 if (this.initialized_)
168 return; 168 return;
169 this.initialized_ = true; 169 this.initialized_ = true;
170 170
171 if (opt_settingsApi) 171 if (opt_settingsApi)
172 this.settingsApi_ = opt_settingsApi; 172 this.settingsApi_ = opt_settingsApi;
173 173
174 /** @private {function(!Array<!chrome.settingsPrivate.PrefObject>)} */ 174 /** @private {function(!Array<!chrome.settingsPrivate.PrefObject>)} */
175 this.boundPrefsChanged_ = this.onSettingsPrivatePrefsChanged_.bind(this); 175 this.boundPrefsChanged_ = this.onSettingsPrivatePrefsChanged_.bind(this);
176 this.settingsApi_.onPrefsChanged.addListener(this.boundPrefsChanged_); 176 this.settingsApi_.onPrefsChanged.addListener(this.boundPrefsChanged_);
177 this.settingsApi_.getAllPrefs( 177 this.settingsApi_.getAllPrefs(
178 this.onSettingsPrivatePrefsFetched_.bind(this)); 178 this.onSettingsPrivatePrefsFetched_.bind(this));
179 }, 179 },
180 180
181 /** 181 /**
182 * @param {!{path: string}} e 182 * @param {!{path: string}} e
183 * @private 183 * @private
184 */ 184 */
185 prefsChanged_: function(e) { 185 prefsChanged_: function(e) {
186 // |prefs| can be directly set or unset in tests. 186 // |prefs| can be directly set or unset in tests.
187 if (!CrSettingsPrefs.isInitialized || e.path == 'prefs') 187 if (!CrSettingsPrefs.isInitialized || e.path == 'prefs')
188 return; 188 return;
189 189
190 var key = this.getPrefKeyFromPath_(e.path); 190 var key = this.getPrefKeyFromPath_(e.path);
191 var prefStoreValue = this.lastPrefValues_[key]; 191 var prefStoreValue = this.lastPrefValues_[key];
192 192
193 var prefObj = /** @type {chrome.settingsPrivate.PrefObject} */( 193 var prefObj = /** @type {chrome.settingsPrivate.PrefObject} */(
194 this.get(key, this.prefs)); 194 this.get(key, this.prefs));
195 195
196 // If settingsPrivate already has this value, ignore it. (Otherwise, 196 // If settingsPrivate already has this value, ignore it. (Otherwise,
197 // a change event from settingsPrivate could make us call 197 // a change event from settingsPrivate could make us call
198 // settingsPrivate.setPref and potentially trigger an IPC loop.) 198 // settingsPrivate.setPref and potentially trigger an IPC loop.)
199 if (!deepEqual(prefStoreValue, prefObj.value)) { 199 if (!deepEqual(prefStoreValue, prefObj.value)) {
200 this.settingsApi_.setPref( 200 this.settingsApi_.setPref(
201 key, 201 key,
202 prefObj.value, 202 prefObj.value,
203 /* pageId */ '', 203 /* pageId */ '',
204 /* callback */ this.setPrefCallback_.bind(this, key)); 204 /* callback */ this.setPrefCallback_.bind(this, key));
205 } 205 }
206 }, 206 },
207 207
208 /** 208 /**
209 * Called when prefs in the underlying Chrome pref store are changed. 209 * Called when prefs in the underlying Chrome pref store are changed.
210 * @param {!Array<!chrome.settingsPrivate.PrefObject>} prefs 210 * @param {!Array<!chrome.settingsPrivate.PrefObject>} prefs
211 * The prefs that changed. 211 * The prefs that changed.
212 * @private 212 * @private
213 */ 213 */
214 onSettingsPrivatePrefsChanged_: function(prefs) { 214 onSettingsPrivatePrefsChanged_: function(prefs) {
215 if (CrSettingsPrefs.isInitialized) 215 if (CrSettingsPrefs.isInitialized)
216 this.updatePrefs_(prefs); 216 this.updatePrefs_(prefs);
217 }, 217 },
218 218
219 /** 219 /**
220 * Called when prefs are fetched from settingsPrivate. 220 * Called when prefs are fetched from settingsPrivate.
221 * @param {!Array<!chrome.settingsPrivate.PrefObject>} prefs 221 * @param {!Array<!chrome.settingsPrivate.PrefObject>} prefs
222 * @private 222 * @private
223 */ 223 */
224 onSettingsPrivatePrefsFetched_: function(prefs) { 224 onSettingsPrivatePrefsFetched_: function(prefs) {
225 this.updatePrefs_(prefs); 225 this.updatePrefs_(prefs);
226 CrSettingsPrefs.setInitialized(); 226 CrSettingsPrefs.setInitialized();
227 }, 227 },
228 228
229 /** 229 /**
230 * Checks the result of calling settingsPrivate.setPref. 230 * Checks the result of calling settingsPrivate.setPref.
231 * @param {string} key The key used in the call to setPref. 231 * @param {string} key The key used in the call to setPref.
232 * @param {boolean} success True if setting the pref succeeded. 232 * @param {boolean} success True if setting the pref succeeded.
233 * @private 233 * @private
234 */ 234 */
235 setPrefCallback_: function(key, success) { 235 setPrefCallback_: function(key, success) {
236 if (!success) 236 if (!success)
237 this.refresh(key); 237 this.refresh(key);
238 }, 238 },
239 239
240 /** 240 /**
241 * Get the current pref value from chrome.settingsPrivate to ensure the UI 241 * Get the current pref value from chrome.settingsPrivate to ensure the UI
242 * stays up to date. 242 * stays up to date.
243 * @param {string} key 243 * @param {string} key
244 */ 244 */
245 refresh: function(key) { 245 refresh: function(key) {
246 this.settingsApi_.getPref(key, function(pref) { 246 this.settingsApi_.getPref(key, function(pref) {
247 this.updatePrefs_([pref]); 247 this.updatePrefs_([pref]);
248 }.bind(this)); 248 }.bind(this));
249 }, 249 },
250 250
251 /** 251 /**
252 * Updates the prefs model with the given prefs. 252 * Updates the prefs model with the given prefs.
253 * @param {!Array<!chrome.settingsPrivate.PrefObject>} newPrefs 253 * @param {!Array<!chrome.settingsPrivate.PrefObject>} newPrefs
254 * @private 254 * @private
255 */ 255 */
256 updatePrefs_: function(newPrefs) { 256 updatePrefs_: function(newPrefs) {
257 // Use the existing prefs object or create it. 257 // Use the existing prefs object or create it.
258 var prefs = this.prefs || {}; 258 var prefs = this.prefs || {};
259 newPrefs.forEach(function(newPrefObj) { 259 newPrefs.forEach(function(newPrefObj) {
260 // Use the PrefObject from settingsPrivate to create a copy in 260 // Use the PrefObject from settingsPrivate to create a copy in
261 // lastPrefValues_ at the pref's key. 261 // lastPrefValues_ at the pref's key.
262 this.lastPrefValues_[newPrefObj.key] = deepCopy(newPrefObj.value); 262 this.lastPrefValues_[newPrefObj.key] = deepCopy(newPrefObj.value);
263 263
264 if (!deepEqual(this.get(newPrefObj.key, prefs), newPrefObj)) { 264 if (!deepEqual(this.get(newPrefObj.key, prefs), newPrefObj)) {
265 // Add the pref to |prefs|. 265 // Add the pref to |prefs|.
266 cr.exportPath(newPrefObj.key, newPrefObj, prefs); 266 cr.exportPath(newPrefObj.key, newPrefObj, prefs);
267 // If this.prefs already exists, notify listeners of the change. 267 // If this.prefs already exists, notify listeners of the change.
268 if (prefs == this.prefs) 268 if (prefs == this.prefs)
269 this.notifyPath('prefs.' + newPrefObj.key, newPrefObj); 269 this.notifyPath('prefs.' + newPrefObj.key, newPrefObj);
270 } 270 }
271 }, this); 271 }, this);
272 if (!this.prefs) 272 if (!this.prefs)
273 this.prefs = prefs; 273 this.prefs = prefs;
274 }, 274 },
275 275
276 /** 276 /**
277 * Given a 'property-changed' path, returns the key of the preference the 277 * Given a 'property-changed' path, returns the key of the preference the
278 * path refers to. E.g., if the path of the changed property is 278 * path refers to. E.g., if the path of the changed property is
279 * 'prefs.search.suggest_enabled.value', the key of the pref that changed is 279 * 'prefs.search.suggest_enabled.value', the key of the pref that changed is
280 * 'search.suggest_enabled'. 280 * 'search.suggest_enabled'.
281 * @param {string} path 281 * @param {string} path
282 * @return {string} 282 * @return {string}
283 * @private 283 * @private
284 */ 284 */
285 getPrefKeyFromPath_: function(path) { 285 getPrefKeyFromPath_: function(path) {
286 // Skip the first token, which refers to the member variable (this.prefs). 286 // Skip the first token, which refers to the member variable (this.prefs).
287 var parts = path.split('.'); 287 var parts = path.split('.');
288 assert(parts.shift() == 'prefs', "Path doesn't begin with 'prefs'"); 288 assert(parts.shift() == 'prefs', 'Path doesn\'t begin with \'prefs\'');
dschuyler 2017/04/19 18:58:41 I find it more readable to use double quotes in th
Dan Beam 2017/04/19 19:07:03 +1, not sure what clang-format does here not the
289 289
290 for (var i = 1; i <= parts.length; i++) { 290 for (var i = 1; i <= parts.length; i++) {
291 var key = parts.slice(0, i).join('.'); 291 var key = parts.slice(0, i).join('.');
292 // The lastPrefValues_ keys match the pref keys. 292 // The lastPrefValues_ keys match the pref keys.
293 if (this.lastPrefValues_.hasOwnProperty(key)) 293 if (this.lastPrefValues_.hasOwnProperty(key))
294 return key; 294 return key;
295 } 295 }
296 return ''; 296 return '';
297 }, 297 },
298 298
299 /** 299 /**
300 * Resets the element so it can be re-initialized with a new prefs state. 300 * Resets the element so it can be re-initialized with a new prefs state.
301 */ 301 */
302 resetForTesting: function() { 302 resetForTesting: function() {
303 if (!this.initialized_) 303 if (!this.initialized_)
304 return; 304 return;
305 this.prefs = undefined; 305 this.prefs = undefined;
306 this.lastPrefValues_ = {}; 306 this.lastPrefValues_ = {};
307 this.initialized_ = false; 307 this.initialized_ = false;
308 // Remove the listener added in initialize(). 308 // Remove the listener added in initialize().
309 this.settingsApi_.onPrefsChanged.removeListener(this.boundPrefsChanged_); 309 this.settingsApi_.onPrefsChanged.removeListener(this.boundPrefsChanged_);
310 this.settingsApi_ = 310 this.settingsApi_ =
311 /** @type {SettingsPrivate} */(chrome.settingsPrivate); 311 /** @type {SettingsPrivate} */(chrome.settingsPrivate);
312 }, 312 },
313 }); 313 });
314 })(); 314 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698