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
3 * found in the LICENSE file. */
7 * 'cr-settings-prefs' is an element which serves as a model for
8 * interaction with settings which are stored in Chrome's
13 * <cr-settings-prefs id="prefs"></cr-settings-prefs>
14 * <cr-settings-a11y-page prefs="{{this.$.prefs}}"></cr-settings-a11y-page>
16 * @group Chrome Settings Elements
17 * @element cr-settings-a11y-page
23 is: 'cr-settings-prefs',
27 * Object containing all preferences.
31 value: function() { return {}; },
38 CrSettingsPrefs.isInitialized = false;
40 chrome.settingsPrivate.onPrefsChanged.addListener(
41 this.onPrefsChanged_.bind(this));
42 chrome.settingsPrivate.getAllPrefs(this.onPrefsFetched_.bind(this));
46 * Called when prefs in the underlying Chrome pref store are changed.
47 * @param {!Array<!PrefObject>} prefs The prefs that changed.
50 onPrefsChanged_: function(prefs) {
51 this.updatePrefs_(prefs, false);
55 * Called when prefs are fetched from settingsPrivate.
56 * @param {!Array<!PrefObject>} prefs
59 onPrefsFetched_: function(prefs) {
60 this.updatePrefs_(prefs, true);
62 CrSettingsPrefs.isInitialized = true;
63 document.dispatchEvent(new Event(CrSettingsPrefs.INITIALIZED));
68 * Updates the settings model with the given prefs.
69 * @param {!Array<!PrefObject>} prefs
70 * @param {boolean} shouldObserve Whether each of the prefs should be
74 updatePrefs_: function(prefs, shouldObserve) {
75 prefs.forEach(function(prefObj) {
76 let root = this.prefStore;
77 let tokens = prefObj.key.split('.');
79 assert(tokens.length > 0);
81 for (let i = 0; i < tokens.length; i++) {
82 let token = tokens[i];
84 if (!root.hasOwnProperty(token)) {
85 let path = 'prefStore.' + tokens.slice(0, i + 1).join('.');
91 // NOTE: Do this copy rather than just a re-assignment, so that the
93 for (let objKey in prefObj) {
94 let path = 'prefStore.' + prefObj.key + '.' + objKey;
96 // Handle lists specially. We don't want to call this.set()
97 // unconditionally upon updating a list value, since even its contents
98 // are the same as the old list, doing this set() may cause an
99 // infinite update cycle (http://crbug.com/498586).
100 if (objKey == 'value' &&
101 prefObj.type == chrome.settingsPrivate.PrefType.LIST &&
102 !this.shouldUpdateListPrefValue_(root, prefObj['value'])) {
106 this.set(path, prefObj[objKey]);
110 Object.observe(root, this.propertyChangeCallback_, ['update']);
117 * @param {Object} root The root object for a pref that contains a list
119 * @param {!Array} newValue The new list value.
120 * @return {boolean} Whether the new value is different from the one in
121 * root, thus necessitating a pref update.
123 shouldUpdateListPrefValue_: function(root, newValue) {
124 if (root.value == null ||
125 root.value.length != newValue.length) {
129 for (let i = 0; i < newValue.length; i++) {
130 if (root.value != null && root.value[i] != newValue[i]) {
139 * Called when a property of a pref changes.
140 * @param {!Array<!Object>} changes An array of objects describing changes.
141 * @see http://www.html5rocks.com/en/tutorials/es7/observe/
144 propertyChangeCallback_: function(changes) {
145 changes.forEach(function(change) {
146 // UI should only be able to change the value of a setting for now, not
148 assert(change.name == 'value');
150 let newValue = change.object[change.name];
151 assert(newValue !== undefined);
153 chrome.settingsPrivate.setPref(
154 change.object['key'],
157 /* callback */ function() {});