OLD | NEW |
---|---|
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 * 'cr-settings-prefs' is an element which serves as a model for | 7 * 'cr-settings-prefs' is an element which serves as a model for |
8 * interaction with settings which are stored in Chrome's | 8 * interaction with settings which are stored in Chrome's |
9 * Preferences. | 9 * Preferences. |
10 * | 10 * |
11 * Example: | 11 * Example: |
12 * | 12 * |
13 * <cr-settings-prefs id="prefs"></cr-settings-prefs> | 13 * <cr-settings-prefs id="prefs"></cr-settings-prefs> |
14 * <cr-settings-a11y-page prefs="{{this.$.prefs}}"></cr-settings-a11y-page> | 14 * <cr-settings-a11y-page prefs="{{this.$.prefs}}"></cr-settings-a11y-page> |
15 * | 15 * |
16 * @group Chrome Settings Elements | 16 * @group Chrome Settings Elements |
17 * @element cr-settings-a11y-page | 17 * @element cr-settings-a11y-page |
18 */ | 18 */ |
19 Polymer('cr-settings-prefs', { | 19 (function() { |
20 publish: { | 20 'use strict'; |
21 /** | 21 |
22 * Accessibility preferences state. | 22 /** |
23 * | 23 * A list of all pref paths used on all platforms in the UI. |
24 * @attribute settings | 24 * TODO(jlklein): This is a temporary workaround that needs to be removed |
25 * @type CrSettingsPrefs.Settings | 25 * once settingsPrivate is implemented with the fetchAll function. We will |
26 * @default null | 26 * not need to tell the settingsPrivate API which prefs to fetch. |
27 */ | 27 * @const {!Array<string>} |
28 settings: null, | 28 */ |
29 }, | 29 var PREFS_TO_FETCH = [ |
30 | 30 'download.default_directory', |
31 /** @override */ | 31 'download.prompt_for_download', |
32 created: function() { | 32 ]; |
33 'use strict'; | 33 |
34 | 34 /** |
35 this.settings = {}; | 35 * A list of all CrOS-only pref paths used in the UI. |
36 this.initializeA11y_(); | 36 * TODO(jlklein): This is a temporary workaround that needs to be removed |
37 this.initializeDownloads_(); | 37 * once settingsPrivate is implemented with the fetchAll function. We will |
38 var observer = new ObjectObserver(this.settings); | 38 * not need to tell the settingsPrivate API which prefs to fetch. |
39 observer.open(this.propertyChangeCallback_.bind(this, 'settings')); | 39 * @const {!Array<string>} |
40 | 40 */ |
41 // For all Object properties of settings, create an ObjectObserver. | 41 var CROS_ONLY_PREFS = [ |
42 for (let key in this.settings) { | 42 'settings.accessibility', |
43 if (typeof this.settings[key] == 'object') { | 43 'settings.a11y.autoclick', |
44 let keyObserver = new ObjectObserver(this.settings[key]); | 44 'settings.a11y.autoclick_delay_ms', |
45 'settings.a11y.enable_menu', | |
46 'settings.a11y.high_contrast_enabled', | |
47 'settings.a11y.large_cursor_enabled', | |
48 'settings.a11y.screen_magnifier', | |
49 'settings.a11y.sticky_keys_enabled', | |
50 'settings.a11y.virtual_keyboard', | |
51 'settings.touchpad.enable_tap_dragging', | |
52 ]; | |
53 | |
54 Polymer('cr-settings-prefs', { | |
55 publish: { | |
56 /** | |
57 * Object containing all preferences. | |
58 * | |
59 * @attribute settings | |
60 * @type CrSettingsPrefs.Settings | |
61 * @default null | |
62 */ | |
63 settings: null, | |
64 }, | |
65 | |
66 /** @override */ | |
67 created: function() { | |
68 this.settings = {}; | |
69 this.fetchSettings_(); | |
70 }, | |
71 | |
72 /** | |
73 * Fetches all settings from settingsPrivate. | |
74 * TODO(jlklein): Implement using settingsPrivate when it's available. | |
75 * @private | |
76 */ | |
77 fetchSettings_: function() { | |
78 // *Sigh* We need to export the function name to global scope. This is | |
79 // needed the CoreOptionsHandler can only call a function in the global | |
80 // scope. | |
81 var callbackName = 'CrSettingsPrefs_onPrefsFetched'; | |
82 window[callbackName] = this.onPrefsFetched_.bind(this); | |
83 var prefsToFetch = PREFS_TO_FETCH; | |
84 if (cr.isChromeOS) | |
85 prefsToFetch.concat(CROS_ONLY_PREFS); | |
86 | |
87 chrome.send('fetchPrefs', [callbackName].concat(prefsToFetch)); | |
88 }, | |
89 | |
90 /** | |
91 * Fetches all settings from settingsPrivate. | |
92 * @param {!Object} dict Map of fetched property values. | |
93 * @private | |
94 */ | |
95 onPrefsFetched_: function(dict) { | |
96 this.parsePrefDict_('', dict); | |
97 }, | |
98 | |
99 /** | |
100 * Helper function for parsing the prefs dict and constructing Preference | |
101 * objects. | |
102 * @param {string} prefix The namespace prefix of the pref. | |
103 * @param {!Object} dict Map with preference values. | |
104 * @private | |
105 */ | |
106 parsePrefDict_: function(prefix, dict) { | |
107 for (let prefName in dict) { | |
Dan Beam
2015/03/20 19:34:05
p.s. Chrome on iOS may not support `let` (arv@ rem
| |
108 let prefObj = dict[prefName]; | |
109 if (!this.isPrefObject_(prefObj)) { | |
110 this.parsePrefDict_(prefix + prefName + '.', prefObj); | |
111 continue; | |
112 } | |
113 | |
114 // prefObj is actually a pref object. Construct the path to pref using | |
115 // prefix, add the pref to this.settings, and observe changes. | |
116 let root = this.settings; | |
117 let pathPieces = prefix.slice(0, -1).split('.'); | |
118 pathPieces.forEach(function(pathPiece) { | |
119 root[pathPiece] = root[pathPiece] || {}; | |
120 root = root[pathPiece]; | |
121 }); | |
122 | |
123 root[prefName] = prefObj; | |
124 let keyObserver = new ObjectObserver(prefObj); | |
45 keyObserver.open( | 125 keyObserver.open( |
46 this.propertyChangeCallback_.bind(this, 'settings.' + key)); | 126 this.propertyChangeCallback_.bind(this, prefix + prefName)); |
47 } | 127 } |
48 } | 128 }, |
49 }, | 129 |
50 | 130 /** |
51 /** | 131 * Determines whether the passed object is a pref object from Chrome. |
52 * Initializes some defaults for the a11y settings. | 132 * @param {*} rawPref The object to check. |
53 * @private | 133 * @return {boolean} True if the passes object is a pref. |
54 */ | 134 * @private |
55 initializeA11y_: function() { | 135 */ |
56 this.settings.a11y = { | 136 isPrefObject_: function(rawPref) { |
57 enableMenu: true, | 137 return rawPref && typeof rawPref == 'object' && |
58 largeCursorEnabled: false, | 138 rawPref.hasOwnProperty('value') && |
59 highContrastEnabled: false, | 139 rawPref.hasOwnProperty('disabled'); |
60 stickyKeysEnabled: false, | 140 }, |
61 screenMagnifier: false, | 141 |
62 enableTapDragging: false, | 142 /** |
63 autoclick: false, | 143 * Called when a property of a pref changes. |
64 autoclickDelayMs: 200, | 144 * @param {string} propertyPath The path before the property names. |
65 virtualKeyboard: false, | 145 * @param {!Array<string>} added An array of keys which were added. |
66 }; | 146 * @param {!Array<string>} removed An array of keys which were removed. |
67 | 147 * @param {!Array<string>} changed An array of keys of properties whose |
68 this.settings.touchpad = { | 148 * values changed. |
69 enableTapDragging: false, | 149 * @param {function(string) : *} getOldValueFn A function which takes a |
70 }; | 150 * property name and returns the old value for that property. |
71 | 151 * @private |
72 // ChromeVox is enbaled/disabled via the 'settings.accessibility' boolean | 152 */ |
73 // pref. | 153 propertyChangeCallback_: function( |
74 this.settings.accessibility = false; | 154 propertyPath, added, removed, changed, getOldValueFn) { |
75 | 155 for (let property in changed) { |
76 // TODO(jlklein): Actually pull the data out of prefs and initialize. | 156 // UI should only be able to change the value of a setting for now, not |
77 }, | 157 // disabled, etc. |
78 | 158 assert(property == 'value'); |
79 /** | 159 |
80 * Initializes some defaults for the downloads settings. | 160 let newValue = changed[property]; |
81 * @private | 161 assert(newValue !== undefined); |
82 */ | 162 |
83 initializeDownloads_: function() { | 163 switch (typeof newValue) { |
84 this.settings.download = { | 164 case 'boolean': |
85 downloadLocation: '', | 165 this.setBooleanPref_( |
86 promptForDownload: false, | 166 propertyPath, /** @type {boolean} */ (newValue)); |
87 }; | 167 break; |
88 }, | 168 case 'number': |
89 | 169 this.setNumberPref_( |
90 /** | 170 propertyPath, /** @type {number} */ (newValue)); |
91 * @param {string} propertyPath The path before the property names. | 171 break; |
92 * @param {!Array<string>} added An array of keys which were added. | 172 case 'string': |
93 * @param {!Array<string>} removed An array of keys which were removed. | 173 this.setStringPref_( |
94 * @param {!Array<string>} changed An array of keys of properties whose | 174 propertyPath, /** @type {string} */ (newValue)); |
95 * values changed. | 175 break; |
96 * @param {function(string) : *} getOldValueFn A function which takes a | 176 case 'object': |
97 * property name and returns the old value for that property. | 177 assertInstanceof(newValue, Array); |
98 * @private | 178 this.setArrayPref_( |
99 */ | 179 propertyPath, /** @type {!Array} */ (newValue)); |
100 propertyChangeCallback_: function( | 180 } |
101 propertyPath, added, removed, changed, getOldValueFn) { | 181 } |
102 Object.keys(changed).forEach(function(property) { | 182 }, |
103 console.log( | 183 |
104 `${propertyPath}.${property}`, | 184 /** |
105 `old : ${getOldValueFn(property)}`, | 185 * @param {string} propertyPath The full path of the pref. |
106 `newValue : ${changed[property]}`); | 186 * @param {boolean} value The new value of the pref. |
107 | 187 * @private |
108 // TODO(jlklein): Actually set the changed property back to prefs. | 188 */ |
109 }); | 189 setBooleanPref_: function(propertyPath, value) { |
110 }, | 190 chrome.send('setBooleanPref', [propertyPath, value]); |
111 }); | 191 }, |
192 | |
193 /** | |
194 * @param {string} propertyPath The full path of the pref. | |
195 * @param {string} value The new value of the pref. | |
196 * @private | |
197 */ | |
198 setStringPref_: function(propertyPath, value) { | |
199 chrome.send('setStringPref', [propertyPath, value]); | |
200 }, | |
201 | |
202 /** | |
203 * @param {string} propertyPath The full path of the pref. | |
204 * @param {number} value The new value of the pref. | |
205 * @private | |
206 */ | |
207 setNumberPref_: function(propertyPath, value) { | |
208 var setFn = value % 1 == 0 ? 'setIntegerPref' : 'setDoublePref'; | |
209 chrome.send(setFn, [propertyPath, value]); | |
210 }, | |
211 | |
212 /** | |
213 * @param {string} propertyPath The full path of the pref. | |
214 * @param {!Array} value The new value of the pref. | |
215 * @private | |
216 */ | |
217 setArrayPref_: function(propertyPath, value) { | |
218 chrome.send('setListPref', [propertyPath, value]); | |
219 }, | |
220 }); | |
221 })(); | |
OLD | NEW |