Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / options / preferences.js
blobc7ea93d37ea9cc257489a6092805014377743608
1 // Copyright (c) 2012 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 cr.define('options', function() {
7   /////////////////////////////////////////////////////////////////////////////
8   // Preferences class:
10   /**
11    * Preferences class manages access to Chrome profile preferences.
12    * @constructor
13    * @extends {cr.EventTarget}
14    */
15   function Preferences() {
16     // Map of registered preferences.
17     this.registeredPreferences_ = {};
18   }
20   cr.addSingletonGetter(Preferences);
22   /**
23    * Sets a Boolean preference and signals its new value.
24    * @param {string} name Preference name.
25    * @param {boolean} value New preference value.
26    * @param {boolean} commit Whether to commit the change to Chrome.
27    * @param {string=} opt_metric User metrics identifier.
28    */
29   Preferences.setBooleanPref = function(name, value, commit, opt_metric) {
30     if (!commit) {
31       Preferences.getInstance().setPrefNoCommit_(name, 'bool', Boolean(value));
32       return;
33     }
35     var argumentList = [name, Boolean(value)];
36     if (opt_metric != undefined) argumentList.push(opt_metric);
37     chrome.send('setBooleanPref', argumentList);
38   };
40   /**
41    * Sets an integer preference and signals its new value.
42    * @param {string} name Preference name.
43    * @param {number} value New preference value.
44    * @param {boolean} commit Whether to commit the change to Chrome.
45    * @param {string} metric User metrics identifier.
46    */
47   Preferences.setIntegerPref = function(name, value, commit, metric) {
48     if (!commit) {
49       Preferences.getInstance().setPrefNoCommit_(name, 'int', Number(value));
50       return;
51     }
53     var argumentList = [name, Number(value)];
54     if (metric != undefined) argumentList.push(metric);
55     chrome.send('setIntegerPref', argumentList);
56   };
58   /**
59    * Sets a double-valued preference and signals its new value.
60    * @param {string} name Preference name.
61    * @param {number} value New preference value.
62    * @param {boolean} commit Whether to commit the change to Chrome.
63    * @param {string} metric User metrics identifier.
64    */
65   Preferences.setDoublePref = function(name, value, commit, metric) {
66     if (!commit) {
67       Preferences.getInstance().setPrefNoCommit_(name, 'double', Number(value));
68       return;
69     }
71     var argumentList = [name, Number(value)];
72     if (metric != undefined) argumentList.push(metric);
73     chrome.send('setDoublePref', argumentList);
74   };
76   /**
77    * Sets a string preference and signals its new value.
78    * @param {string} name Preference name.
79    * @param {string} value New preference value.
80    * @param {boolean} commit Whether to commit the change to Chrome.
81    * @param {string} metric User metrics identifier.
82    */
83   Preferences.setStringPref = function(name, value, commit, metric) {
84     if (!commit) {
85       Preferences.getInstance().setPrefNoCommit_(name, 'string', String(value));
86       return;
87     }
89     var argumentList = [name, String(value)];
90     if (metric != undefined) argumentList.push(metric);
91     chrome.send('setStringPref', argumentList);
92   };
94   /**
95    * Sets a string preference that represents a URL and signals its new value.
96    * The value will be fixed to be a valid URL when it gets committed to Chrome.
97    * @param {string} name Preference name.
98    * @param {string} value New preference value.
99    * @param {boolean} commit Whether to commit the change to Chrome.
100    * @param {string} metric User metrics identifier.
101    */
102   Preferences.setURLPref = function(name, value, commit, metric) {
103     if (!commit) {
104       Preferences.getInstance().setPrefNoCommit_(name, 'url', String(value));
105       return;
106     }
108     var argumentList = [name, String(value)];
109     if (metric != undefined) argumentList.push(metric);
110     chrome.send('setURLPref', argumentList);
111   };
113   /**
114    * Sets a JSON list preference and signals its new value.
115    * @param {string} name Preference name.
116    * @param {Array} value New preference value.
117    * @param {boolean} commit Whether to commit the change to Chrome.
118    * @param {string} metric User metrics identifier.
119    */
120   Preferences.setListPref = function(name, value, commit, metric) {
121     if (!commit) {
122       Preferences.getInstance().setPrefNoCommit_(name, 'list', value);
123       return;
124     }
126     var argumentList = [name, JSON.stringify(value)];
127     if (metric != undefined) argumentList.push(metric);
128     chrome.send('setListPref', argumentList);
129   };
131   /**
132    * Clears the user setting for a preference and signals its new effective
133    * value.
134    * @param {string} name Preference name.
135    * @param {boolean} commit Whether to commit the change to Chrome.
136    * @param {string=} opt_metric User metrics identifier.
137    */
138   Preferences.clearPref = function(name, commit, opt_metric) {
139     if (!commit) {
140       Preferences.getInstance().clearPrefNoCommit_(name);
141       return;
142     }
144     var argumentList = [name];
145     if (opt_metric != undefined) argumentList.push(opt_metric);
146     chrome.send('clearPref', argumentList);
147   };
149   Preferences.prototype = {
150     __proto__: cr.EventTarget.prototype,
152     /**
153      * Adds an event listener to the target.
154      * @param {string} type The name of the event.
155      * @param {EventListenerType} handler The handler for the event. This is
156      *     called when the event is dispatched.
157      */
158     addEventListener: function(type, handler) {
159       cr.EventTarget.prototype.addEventListener.call(this, type, handler);
160       if (!(type in this.registeredPreferences_))
161         this.registeredPreferences_[type] = {};
162     },
164     /**
165      * Initializes preference reading and change notifications.
166      */
167     initialize: function() {
168       var params1 = ['Preferences.prefsFetchedCallback'];
169       var params2 = ['Preferences.prefsChangedCallback'];
170       for (var prefName in this.registeredPreferences_) {
171         params1.push(prefName);
172         params2.push(prefName);
173       }
174       chrome.send('fetchPrefs', params1);
175       chrome.send('observePrefs', params2);
176     },
178     /**
179      * Helper function for flattening of dictionary passed via fetchPrefs
180      * callback.
181      * @param {string} prefix Preference name prefix.
182      * @param {Object} dict Map with preference values.
183      * @private
184      */
185     flattenMapAndDispatchEvent_: function(prefix, dict) {
186       for (var prefName in dict) {
187         var value = dict[prefName];
188         if (typeof value == 'object' &&
189             !this.registeredPreferences_[prefix + prefName]) {
190           this.flattenMapAndDispatchEvent_(prefix + prefName + '.', value);
191         } else if (value) {
192           var event = new Event(prefix + prefName);
193           this.registeredPreferences_[prefix + prefName].orig = value;
194           event.value = value;
195           this.dispatchEvent(event);
196         }
197       }
198     },
200     /**
201      * Sets a preference and signals its new value. The change is propagated
202      * throughout the UI code but is not committed to Chrome yet. The new value
203      * and its data type are stored so that commitPref() can later be used to
204      * invoke the appropriate set*Pref() method and actually commit the change.
205      * @param {string} name Preference name.
206      * @param {string} type Preference data type.
207      * @param {*} value New preference value.
208      * @private
209      */
210     setPrefNoCommit_: function(name, type, value) {
211       var pref = this.registeredPreferences_[name];
212       pref.action = 'set';
213       pref.type = type;
214       pref.value = value;
216       var event = new Event(name);
217       // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
218       event.value = {value: value, uncommitted: true};
219       if (pref.orig) {
220         event.value.recommendedValue = pref.orig.recommendedValue;
221         event.value.disabled = pref.orig.disabled;
222       }
223       this.dispatchEvent(event);
224     },
226     /**
227      * Clears a preference and signals its new value. The change is propagated
228      * throughout the UI code but is not committed to Chrome yet.
229      * @param {string} name Preference name.
230      * @private
231      */
232     clearPrefNoCommit_: function(name) {
233       var pref = this.registeredPreferences_[name];
234       pref.action = 'clear';
235       delete pref.type;
236       delete pref.value;
238       var event = new Event(name);
239       // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
240       event.value = {controlledBy: 'recommended', uncommitted: true};
241       if (pref.orig) {
242         event.value.value = pref.orig.recommendedValue;
243         event.value.recommendedValue = pref.orig.recommendedValue;
244         event.value.disabled = pref.orig.disabled;
245       }
246       this.dispatchEvent(event);
247     },
249     /**
250      * Commits a preference change to Chrome and signals the new preference
251      * value. Does nothing if there is no uncommitted change.
252      * @param {string} name Preference name.
253      * @param {string} metric User metrics identifier.
254      */
255     commitPref: function(name, metric) {
256       var pref = this.registeredPreferences_[name];
257       switch (pref.action) {
258         case 'set':
259           switch (pref.type) {
260             case 'bool':
261               Preferences.setBooleanPref(name, pref.value, true, metric);
262               break;
263             case 'int':
264               Preferences.setIntegerPref(name, pref.value, true, metric);
265               break;
266             case 'double':
267               Preferences.setDoublePref(name, pref.value, true, metric);
268               break;
269             case 'string':
270               Preferences.setStringPref(name, pref.value, true, metric);
271               break;
272             case 'url':
273               Preferences.setURLPref(name, pref.value, true, metric);
274               break;
275             case 'list':
276               Preferences.setListPref(name, pref.value, true, metric);
277               break;
278           }
279           break;
280         case 'clear':
281           Preferences.clearPref(name, true, metric);
282           break;
283       }
284       delete pref.action;
285       delete pref.type;
286       delete pref.value;
287     },
289     /**
290      * Rolls back a preference change and signals the original preference value.
291      * Does nothing if there is no uncommitted change.
292      * @param {string} name Preference name.
293      */
294     rollbackPref: function(name) {
295       var pref = this.registeredPreferences_[name];
296       if (!pref.action)
297         return;
299       delete pref.action;
300       delete pref.type;
301       delete pref.value;
303       var event = new Event(name);
304       event.value = pref.orig || {};
305       event.value.uncommitted = true;
306       this.dispatchEvent(event);
307     }
308   };
310   /**
311    * Callback for fetchPrefs method.
312    * @param {Object} dict Map of fetched property values.
313    */
314   Preferences.prefsFetchedCallback = function(dict) {
315     Preferences.getInstance().flattenMapAndDispatchEvent_('', dict);
316   };
318   /**
319    * Callback for observePrefs method.
320    * @param {Array} notification An array defining changed preference values.
321    *     notification[0] contains name of the change preference while its new
322    *     value is stored in notification[1].
323    */
324   Preferences.prefsChangedCallback = function(notification) {
325     var event = new Event(notification[0]);
326     event.value = notification[1];
327     var prefs = Preferences.getInstance();
328     prefs.registeredPreferences_[notification[0]] = {orig: notification[1]};
329     if (event.value)
330       prefs.dispatchEvent(event);
331   };
333   // Export
334   return {
335     Preferences: Preferences
336   };