Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / resources / settings / prefs / prefs.js
blobb68ccea3c5c9b26ee7608800145cf458189e34af
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. */
5 /**
6  * @fileoverview
7  * 'cr-settings-prefs' is an element which serves as a model for
8  * interaction with settings which are stored in Chrome's
9  * Preferences.
10  *
11  * Example:
12  *
13  *    <cr-settings-prefs id="prefs"></cr-settings-prefs>
14  *    <cr-settings-a11y-page prefs="{{this.$.prefs}}"></cr-settings-a11y-page>
15  *
16  * @group Chrome Settings Elements
17  * @element cr-settings-a11y-page
18  */
19 (function() {
20   'use strict';
22   Polymer({
23     is: 'cr-settings-prefs',
25     properties: {
26       /**
27        * Object containing all preferences.
28        */
29       prefStore: {
30         type: Object,
31         value: function() { return {}; },
32         notify: true,
33       },
34     },
36     /** @override */
37     created: function() {
38       CrSettingsPrefs.isInitialized = false;
40       chrome.settingsPrivate.onPrefsChanged.addListener(
41           this.onPrefsChanged_.bind(this));
42       chrome.settingsPrivate.getAllPrefs(this.onPrefsFetched_.bind(this));
43     },
45     /**
46      * Called when prefs in the underlying Chrome pref store are changed.
47      * @param {!Array<!PrefObject>} prefs The prefs that changed.
48      * @private
49      */
50     onPrefsChanged_: function(prefs) {
51       this.updatePrefs_(prefs, false);
52     },
54     /**
55      * Called when prefs are fetched from settingsPrivate.
56      * @param {!Array<!PrefObject>} prefs
57      * @private
58      */
59     onPrefsFetched_: function(prefs) {
60       this.updatePrefs_(prefs, true);
62       CrSettingsPrefs.isInitialized = true;
63       document.dispatchEvent(new Event(CrSettingsPrefs.INITIALIZED));
64     },
67     /**
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
71      *     observed.
72      * @private
73      */
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('.');
86             this.set(path, {});
87           }
88           root = root[token];
89         }
91         // NOTE: Do this copy rather than just a re-assignment, so that the
92         // observer fires.
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'])) {
103             continue;
104           }
106           this.set(path, prefObj[objKey]);
107         }
109         if (shouldObserve) {
110           Object.observe(root, this.propertyChangeCallback_, ['update']);
111         }
112       }, this);
113     },
116     /**
117      * @param {Object} root The root object for a pref that contains a list
118      *     value.
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.
122      */
123     shouldUpdateListPrefValue_: function(root, newValue) {
124       if (root.value == null ||
125           root.value.length != newValue.length) {
126         return true;
127       }
129       for (let i = 0; i < newValue.length; i++) {
130         if (root.value != null && root.value[i] != newValue[i]) {
131           return true;
132         }
133       }
135       return false;
136     },
138     /**
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/
142      * @private
143      */
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
147         // disabled, etc.
148         assert(change.name == 'value');
150         let newValue = change.object[change.name];
151         assert(newValue !== undefined);
153         chrome.settingsPrivate.setPref(
154             change.object['key'],
155             newValue,
156             /* pageId */ '',
157             /* callback */ function() {});
158       });
159     },
160   });
161 })();