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

Side by Side Diff: chrome/browser/resources/options/pref_ui.js

Issue 10908061: Clean up copy-and-pasted code in prefs UI classes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Nit addressed. Created 8 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/resources/options/font_settings.js ('k') | chrome/tools/extract_actions.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 cr.define('options', function() { 5 cr.define('options', function() {
6 6
7 var Preferences = options.Preferences; 7 var Preferences = options.Preferences;
8 8
9 /** 9 /**
10 * Allows an element to be disabled for several reasons. 10 * Allows an element to be disabled for several reasons.
(...skipping 21 matching lines...) Expand all
32 console.error('Element is not disabled but should be'); 32 console.error('Element is not disabled but should be');
33 } 33 }
34 if (disabled) { 34 if (disabled) {
35 el.disabledReasons[reason] = true; 35 el.disabledReasons[reason] = true;
36 } else { 36 } else {
37 delete el.disabledReasons[reason]; 37 delete el.disabledReasons[reason];
38 } 38 }
39 el.disabled = Object.keys(el.disabledReasons).length > 0; 39 el.disabled = Object.keys(el.disabledReasons).length > 0;
40 } 40 }
41 41
42 /**
43 * Helper function to update element's state from pref change event.
44 * @private
45 * @param {!HTMLElement} el The element to update.
46 * @param {!Event} event The pref change event.
47 */
48 function updateElementState_(el, event) {
49 updateDisabledState_(el, 'notUserModifiable', event.value.disabled);
50 el.controlledBy = event.value.controlledBy;
51 OptionsPage.updateManagedBannerVisibility();
52 }
53
54 ///////////////////////////////////////////////////////////////////////////// 42 /////////////////////////////////////////////////////////////////////////////
55 // PrefCheckbox class: 43 // PrefInputElement class:
56 // TODO(jhawkins): Refactor all this copy-pasted code!
57 44
58 // Define a constructor that uses an input element as its underlying element. 45 // Define a constructor that uses an input element as its underlying element.
59 var PrefCheckbox = cr.ui.define('input'); 46 var PrefInputElement = function() {};
60 47
61 PrefCheckbox.prototype = { 48 PrefInputElement.prototype = {
62 // Set up the prototype chain 49 // Set up the prototype chain
63 __proto__: HTMLInputElement.prototype, 50 __proto__: HTMLInputElement.prototype,
64 51
65 /** 52 /**
66 * Initialization function for the cr.ui framework. 53 * Initialization function for the cr.ui framework.
67 */ 54 */
68 decorate: function() { 55 decorate: function() {
69 this.type = 'checkbox';
70 var self = this; 56 var self = this;
71 57
72 this.initializeValueType(this.getAttribute('value-type')); 58 // Listen for user events.
59 this.addEventListener('change', this.handleChange_.bind(this));
73 60
74 // Listen to pref changes. 61 // Listen for pref changes.
75 Preferences.getInstance().addEventListener(this.pref, function(event) { 62 Preferences.getInstance().addEventListener(this.pref, function(event) {
76 var value = event.value.value; 63 self.updateStateFromPref_(event);
77 self.checked = self.inverted_pref ? !value : value; 64 updateDisabledState_(self, 'notUserModifiable', event.value.disabled);
78 updateElementState_(self, event); 65 self.controlledBy = event.value.controlledBy;
66 OptionsPage.updateManagedBannerVisibility();
79 }); 67 });
80
81 // Listen to user events.
82 this.addEventListener('change', this.updatePreferenceValue_.bind(this));
83 }, 68 },
84 69
85 /** 70 /**
86 * Handler that updates the associated pref when the user changes the input 71 * Handle changes to the input element's state made by the user. If a custom
87 * element's value. 72 * change handler does not suppress it, a default handler is invoked that
73 * updates the associated pref.
88 * @param {Event} event Change event. 74 * @param {Event} event Change event.
89 * @private 75 * @private
90 */ 76 */
91 updatePreferenceValue_: function(event) { 77 handleChange_: function(event) {
92 if (this.customChangeHandler(event)) 78 if (!this.customChangeHandler(event))
93 return; 79 this.updatePrefFromState_();
94
95 var value = this.inverted_pref ? !this.checked : this.checked;
96 switch (this.valueType) {
97 case 'number':
98 Preferences.setIntegerPref(this.pref, Number(value),
99 !this.dialogPref, this.metric);
100 break;
101 case 'boolean':
102 Preferences.setBooleanPref(this.pref, value,
103 !this.dialogPref, this.metric);
104 break;
105 }
106 }, 80 },
107 81
108 /** 82 /**
109 * Sets up options in checkbox element. 83 * Update the input element's state when the associated pref changes.
110 * @param {String} valueType The preference type for this checkbox. 84 * @param {Event} event Pref change event.
85 * @private
111 */ 86 */
112 initializeValueType: function(valueType) { 87 updateStateFromPref_: function(event) {
113 this.valueType = valueType || 'boolean'; 88 this.value = event.value.value;
114 }, 89 },
115 90
116 /** 91 /**
117 * See |updateDisabledState_| above. 92 * See |updateDisabledState_| above.
118 */ 93 */
119 setDisabled: function(reason, disabled) { 94 setDisabled: function(reason, disabled) {
120 updateDisabledState_(this, reason, disabled); 95 updateDisabledState_(this, reason, disabled);
121 }, 96 },
122 97
123 /** 98 /**
124 * Handler that is called when the user changes the input element's value. 99 * Custom change handler that is invoked first when the user makes changes
125 * If it returns false, the default handler is executed next, updating the 100 * to the input element's state. If it returns false, a default handler is
126 * associated pref to its new value. If it returns true, the default handler 101 * invoked next that updates the associated pref. If it returns true, the
127 * is skipped (i.e., this works like stopPropagation or cancelBubble). 102 * default handler is suppressed (i.e., this works like stopPropagation or
128 * @param {Event} event Change event. 103 * cancelBubble).
104 * @param {Event} event Input element change event.
129 */ 105 */
130 customChangeHandler: function(event) { 106 customChangeHandler: function(event) {
131 return false; 107 return false;
132 }, 108 },
133 }; 109 };
134 110
135 /** 111 /**
136 * The preference name. 112 * The name of the associated preference.
137 * @type {string} 113 * @type {string}
138 */ 114 */
139 cr.defineProperty(PrefCheckbox, 'pref', cr.PropertyKind.ATTR); 115 cr.defineProperty(PrefInputElement, 'pref', cr.PropertyKind.ATTR);
140 116
141 /** 117 /**
142 * A special preference type specific to dialogs. Changes take effect in the 118 * The data type of the associated preference, only relevant for derived
143 * settings UI immediately but are only actually committed when the user 119 * classes that support different data types.
144 * confirms the dialog. If the user cancels the dialog instead, the changes 120 * @type {string}
145 * are rolled back in the settings UI and never committed. 121 */
122 cr.defineProperty(PrefInputElement, 'dataType', cr.PropertyKind.ATTR);
123
124 /**
125 * Whether this input element is part of a dialog. If so, changes take effect
126 * in the settings UI immediately but are only actually committed when the
127 * user confirms the dialog. If the user cancels the dialog instead, the
128 * changes are rolled back in the settings UI and never committed.
146 * @type {boolean} 129 * @type {boolean}
147 */ 130 */
148 cr.defineProperty(PrefCheckbox, 'dialogPref', cr.PropertyKind.BOOL_ATTR); 131 cr.defineProperty(PrefInputElement, 'dialogPref', cr.PropertyKind.BOOL_ATTR);
149 132
150 /** 133 /**
151 * Whether the preference is controlled by something else than the user's 134 * Whether the associated preference is controlled by a source other than the
152 * settings (either 'policy' or 'extension'). 135 * user's setting (can be 'policy', 'extension' or 'recommended').
153 * @type {string} 136 * @type {string}
154 */ 137 */
155 cr.defineProperty(PrefCheckbox, 'controlledBy', cr.PropertyKind.ATTR); 138 cr.defineProperty(PrefInputElement, 'controlledBy', cr.PropertyKind.ATTR);
156 139
157 /** 140 /**
158 * The user metric string. 141 * The user metric string.
159 * @type {string} 142 * @type {string}
160 */ 143 */
161 cr.defineProperty(PrefCheckbox, 'metric', cr.PropertyKind.ATTR); 144 cr.defineProperty(PrefInputElement, 'metric', cr.PropertyKind.ATTR);
145
146 /////////////////////////////////////////////////////////////////////////////
147 // PrefCheckbox class:
148
149 // Define a constructor that uses an input element as its underlying element.
150 var PrefCheckbox = cr.ui.define('input');
151
152 PrefCheckbox.prototype = {
153 // Set up the prototype chain
154 __proto__: PrefInputElement.prototype,
155
156 /**
157 * Initialization function for the cr.ui framework.
158 */
159 decorate: function() {
160 PrefInputElement.prototype.decorate.call(this);
161 this.type = 'checkbox';
162 },
163
164 /**
165 * Update the associated pref when when the user makes changes to the
166 * checkbox state.
167 * @private
168 */
169 updatePrefFromState_: function() {
170 var value = this.inverted_pref ? !this.checked : this.checked;
171 Preferences.setBooleanPref(this.pref, value,
172 !this.dialogPref, this.metric);
173 },
174
175 /**
176 * Update the checkbox state when the associated pref changes.
177 * @param {Event} event Pref change event.
178 * @private
179 */
180 updateStateFromPref_: function(event) {
181 var value = Boolean(event.value.value);
182 this.checked = this.inverted_pref ? !value : value;
183 },
184 };
162 185
163 /** 186 /**
164 * Whether to use inverted pref value. 187 * Whether the mapping between checkbox state and associated pref is inverted.
165 * @type {boolean} 188 * @type {boolean}
166 */ 189 */
167 cr.defineProperty(PrefCheckbox, 'inverted_pref', cr.PropertyKind.BOOL_ATTR); 190 cr.defineProperty(PrefCheckbox, 'inverted_pref', cr.PropertyKind.BOOL_ATTR);
168 191
169 ///////////////////////////////////////////////////////////////////////////// 192 /////////////////////////////////////////////////////////////////////////////
193 // PrefNumber class:
194
195 // Define a constructor that uses an input element as its underlying element.
196 var PrefNumber = cr.ui.define('input');
197
198 PrefNumber.prototype = {
199 // Set up the prototype chain
200 __proto__: PrefInputElement.prototype,
201
202 /**
203 * Initialization function for the cr.ui framework.
204 */
205 decorate: function() {
206 PrefInputElement.prototype.decorate.call(this);
207 this.type = 'number';
208 },
209
210 /**
211 * Update the associated pref when when the user inputs a number.
212 * @private
213 */
214 updatePrefFromState_: function() {
215 if (this.validity.valid) {
216 Preferences.setIntegerPref(this.pref, this.value,
217 !this.dialogPref, this.metric);
218 }
219 },
220 };
221
222 /////////////////////////////////////////////////////////////////////////////
170 // PrefRadio class: 223 // PrefRadio class:
171 224
172 //Define a constructor that uses an input element as its underlying element. 225 //Define a constructor that uses an input element as its underlying element.
173 var PrefRadio = cr.ui.define('input'); 226 var PrefRadio = cr.ui.define('input');
174 227
175 PrefRadio.prototype = { 228 PrefRadio.prototype = {
176 // Set up the prototype chain 229 // Set up the prototype chain
177 __proto__: HTMLInputElement.prototype, 230 __proto__: PrefInputElement.prototype,
178
179 // Stores the initialized value of the preference used to reset the input
180 // in resetPrefState().
181 storedValue_: null,
182 231
183 /** 232 /**
184 * Initialization function for the cr.ui framework. 233 * Initialization function for the cr.ui framework.
185 */ 234 */
186 decorate: function() { 235 decorate: function() {
236 PrefInputElement.prototype.decorate.call(this);
187 this.type = 'radio'; 237 this.type = 'radio';
188 var self = this;
189
190 // Listen to pref changes.
191 Preferences.getInstance().addEventListener(this.pref, function(event) {
192 self.checked = String(event.value.value) == self.value;
193 updateElementState_(self, event);
194 });
195
196 // Listen to user events.
197 this.addEventListener('change', this.updatePreferenceValue_.bind(this));
198 }, 238 },
199 239
200 /** 240 /**
201 * Handler that updates the associated pref when the user changes the input 241 * Update the associated pref when when the user selects the radio button.
202 * element's value.
203 * @param {Event} event Change event.
204 * @private 242 * @private
205 */ 243 */
206 updatePreferenceValue_: function(event) { 244 updatePrefFromState_: function() {
207 if (this.customChangeHandler(event))
208 return;
209
210 if (this.value == 'true' || this.value == 'false') { 245 if (this.value == 'true' || this.value == 'false') {
211 var value = String(this.value); 246 Preferences.setBooleanPref(this.pref,
212 Preferences.setBooleanPref(this.pref, value == String(this.checked), 247 this.value == String(this.checked),
213 !this.dialogPref, this.metric); 248 !this.dialogPref, this.metric);
214 } else { 249 } else {
215 Preferences.setIntegerPref(this.pref, parseInt(this.value, 10), 250 Preferences.setIntegerPref(this.pref, this.value,
216 !this.dialogPref, this.metric); 251 !this.dialogPref, this.metric);
217 } 252 }
218 }, 253 },
219 254
220 /** 255 /**
221 * See |updateDisabledState_| above. 256 * Update the radio button state when the associated pref changes.
257 * @param {Event} event Pref change event.
258 * @private
222 */ 259 */
223 setDisabled: function(reason, disabled) { 260 updateStateFromPref_: function(event) {
224 updateDisabledState_(this, reason, disabled); 261 this.checked = this.value == String(event.value.value);
225 },
226
227 /**
228 * Handler that is called when the user changes the input element's value.
229 * If it returns false, the default handler is executed next, updating the
230 * associated pref to its new value. If it returns true, the default handler
231 * is skipped (i.e., this works like stopPropagation or cancelBubble).
232 * @param {Event} event Change event.
233 */
234 customChangeHandler: function(event) {
235 return false;
236 }, 262 },
237 }; 263 };
238 264
239 /**
240 * The preference name.
241 * @type {string}
242 */
243 cr.defineProperty(PrefRadio, 'pref', cr.PropertyKind.ATTR);
244
245 /**
246 * A special preference type specific to dialogs. Changes take effect in the
247 * settings UI immediately but are only actually committed when the user
248 * confirms the dialog. If the user cancels the dialog instead, the changes
249 * are rolled back in the settings UI and never committed.
250 * @type {boolean}
251 */
252 cr.defineProperty(PrefRadio, 'dialogPref', cr.PropertyKind.BOOL_ATTR);
253
254 /**
255 * Whether the preference is controlled by something else than the user's
256 * settings (either 'policy' or 'extension').
257 * @type {string}
258 */
259 cr.defineProperty(PrefRadio, 'controlledBy', cr.PropertyKind.ATTR);
260
261 /**
262 * The user metric string.
263 * @type {string}
264 */
265 cr.defineProperty(PrefRadio, 'metric', cr.PropertyKind.ATTR);
266
267 /////////////////////////////////////////////////////////////////////////////
268 // PrefNumeric class:
269
270 // Define a constructor that uses an input element as its underlying element.
271 var PrefNumeric = function() {};
272 PrefNumeric.prototype = {
273 // Set up the prototype chain
274 __proto__: HTMLInputElement.prototype,
275
276 /**
277 * Initialization function for the cr.ui framework.
278 */
279 decorate: function() {
280 var self = this;
281
282 // Listen to pref changes.
283 Preferences.getInstance().addEventListener(this.pref, function(event) {
284 self.value = event.value.value;
285 updateElementState_(self, event);
286 });
287
288 // Listen to user events.
289 this.addEventListener('change', function(event) {
290 if (self.validity.valid) {
291 Preferences.setIntegerPref(self.pref, self.value,
292 !self.dialogPref, self.metric);
293 }
294 });
295 },
296
297 /**
298 * See |updateDisabledState_| above.
299 */
300 setDisabled: function(reason, disabled) {
301 updateDisabledState_(this, reason, disabled);
302 },
303 };
304
305 /**
306 * The preference name.
307 * @type {string}
308 */
309 cr.defineProperty(PrefNumeric, 'pref', cr.PropertyKind.ATTR);
310
311 /**
312 * A special preference type specific to dialogs. Changes take effect in the
313 * settings UI immediately but are only actually committed when the user
314 * confirms the dialog. If the user cancels the dialog instead, the changes
315 * are rolled back in the settings UI and never committed.
316 * @type {boolean}
317 */
318 cr.defineProperty(PrefRadio, 'dialogPref', cr.PropertyKind.BOOL_ATTR);
319
320 /**
321 * Whether the preference is controlled by something else than the user's
322 * settings (either 'policy' or 'extension').
323 * @type {string}
324 */
325 cr.defineProperty(PrefNumeric, 'controlledBy', cr.PropertyKind.ATTR);
326
327 /**
328 * The user metric string.
329 * @type {string}
330 */
331 cr.defineProperty(PrefNumeric, 'metric', cr.PropertyKind.ATTR);
332
333 /////////////////////////////////////////////////////////////////////////////
334 // PrefNumber class:
335
336 // Define a constructor that uses an input element as its underlying element.
337 var PrefNumber = cr.ui.define('input');
338
339 PrefNumber.prototype = {
340 // Set up the prototype chain
341 __proto__: PrefNumeric.prototype,
342
343 /**
344 * Initialization function for the cr.ui framework.
345 */
346 decorate: function() {
347 this.type = 'number';
348 PrefNumeric.prototype.decorate.call(this);
349 var self = this;
350
351 // Listen to user events.
352 this.addEventListener('input',
353 function(e) {
354 if (self.validity.valid) {
355 Preferences.setIntegerPref(self.pref, self.value,
356 !self.dialogPref, self.metric);
357 }
358 });
359 },
360
361 /**
362 * See |updateDisabledState_| above.
363 */
364 setDisabled: function(reason, disabled) {
365 updateDisabledState_(this, reason, disabled);
366 },
367 };
368
369 ///////////////////////////////////////////////////////////////////////////// 265 /////////////////////////////////////////////////////////////////////////////
370 // PrefRange class: 266 // PrefRange class:
371 267
372 // Define a constructor that uses an input element as its underlying element. 268 // Define a constructor that uses an input element as its underlying element.
373 var PrefRange = cr.ui.define('input'); 269 var PrefRange = cr.ui.define('input');
374 270
375 PrefRange.prototype = { 271 PrefRange.prototype = {
376 // Set up the prototype chain 272 // Set up the prototype chain
377 __proto__: HTMLInputElement.prototype, 273 __proto__: PrefInputElement.prototype,
378 274
379 /** 275 /**
380 * The map from input range value to the corresponding preference value. 276 * The map from slider position to corresponding pref value.
381 */ 277 */
382 valueMap: undefined, 278 valueMap: undefined,
383 279
384 /** 280 /**
385 * Initialization function for the cr.ui framework. 281 * Initialization function for the cr.ui framework.
386 */ 282 */
387 decorate: function() { 283 decorate: function() {
284 PrefInputElement.prototype.decorate.call(this);
388 this.type = 'range'; 285 this.type = 'range';
389 286
390 // Update the UI when the pref changes. 287 // Listen for user events.
391 Preferences.getInstance().addEventListener(
392 this.pref, this.onPrefChange_.bind(this));
393
394 // Listen to user events.
395 // TODO(jhawkins): Add onmousewheel handling once the associated WK bug is 288 // TODO(jhawkins): Add onmousewheel handling once the associated WK bug is
396 // fixed. 289 // fixed.
397 // https://bugs.webkit.org/show_bug.cgi?id=52256 290 // https://bugs.webkit.org/show_bug.cgi?id=52256
398 this.addEventListener('keyup', this.updatePreferenceValue_.bind(this)); 291 this.addEventListener('keyup', this.handleRelease_.bind(this));
399 this.addEventListener('mouseup', this.updatePreferenceValue_.bind(this)); 292 this.addEventListener('mouseup', this.handleRelease_.bind(this));
400 }, 293 },
401 294
402 /** 295 /**
403 * Event listener that updates the input element when the associated pref 296 * Update the associated pref when when the user releases the slider.
404 * changes.
405 * @param {Event} event The event that details the pref change.
406 * @private 297 * @private
407 */ 298 */
408 onPrefChange_: function(event) { 299 updatePrefFromState_: function() {
300 Preferences.setIntegerPref(this.pref, this.mapPositionToPref(this.value),
301 !this.dialogPref, this.metric);
302 },
303
304 /**
305 * Ignore changes to the slider position made by the user while the slider
306 * has not been released.
307 * @private
308 */
309 handleChange_: function() {
310 },
311
312 /**
313 * Handle changes to the slider position made by the user when the slider is
314 * released. If a custom change handler does not suppress it, a default
315 * handler is invoked that updates the associated pref.
316 * @param {Event} event Change event.
317 * @private
318 */
319 handleRelease_: function(event) {
320 if (!this.customChangeHandler(event))
321 this.updatePrefFromState_();
322 },
323
324 /**
325 * Update the slider position when the associated pref changes.
326 * @param {Event} event Pref change event.
327 * @private
328 */
329 updateStateFromPref_: function(event) {
409 var value = event.value.value; 330 var value = event.value.value;
410 this.value = this.valueMap ? this.valueMap.indexOf(value) : value; 331 this.value = this.valueMap ? this.valueMap.indexOf(value) : value;
411 }, 332 },
412 333
413 /** 334 /**
414 * Handler that updates the associated pref when the user changes the input 335 * Map slider position to the range of values provided by the client,
415 * element's value. 336 * represented by |valueMap|.
416 * This handler is called when the user completes the change by releasing 337 * @param {number} position The slider position to map.
417 * the slider.
418 * @param {Event} event Change event.
419 * @private
420 */ 338 */
421 updatePreferenceValue_: function(event) { 339 mapPositionToPref: function(position) {
422 if (this.customChangeHandler(event)) 340 return this.valueMap ? this.valueMap[position] : position;
423 return;
424
425 Preferences.setIntegerPref(this.pref, this.mapValueToRange(this.value),
426 !this.dialogPref, this.metric);
427 },
428
429 /**
430 * Maps the value of this element into the range provided by the client,
431 * represented by |valueMap|.
432 * @param {number} value The value to map.
433 */
434 mapValueToRange: function(value) {
435 return this.valueMap ? this.valueMap[value] : value;
436 },
437
438 /**
439 * See |updateDisabledState_| above.
440 */
441 setDisabled: function(reason, disabled) {
442 updateDisabledState_(this, reason, disabled);
443 },
444
445 /**
446 * Handler that is called when the user changes the input element's value.
447 * If it returns false, the default handler is executed next, updating the
448 * associated pref to its new value. If it returns true, the default handler
449 * is skipped (i.e., this works like stopPropagation or cancelBubble).
450 * This handler is called when the user completes the change by releasing
451 * the slider.
452 * @param {Event} event Change event.
453 */
454 customChangeHandler: function(event) {
455 return false;
456 }, 341 },
457 }; 342 };
458 343
459 /**
460 * The preference name.
461 * @type {string}
462 */
463 cr.defineProperty(PrefRange, 'pref', cr.PropertyKind.ATTR);
464
465 /**
466 * A special preference type specific to dialogs. Changes take effect in the
467 * settings UI immediately but are only actually committed when the user
468 * confirms the dialog. If the user cancels the dialog instead, the changes
469 * are rolled back in the settings UI and never committed.
470 * @type {boolean}
471 */
472 cr.defineProperty(PrefRadio, 'dialogPref', cr.PropertyKind.BOOL_ATTR);
473
474 /**
475 * Whether the preference is controlled by something else than the user's
476 * settings (either 'policy' or 'extension').
477 * @type {string}
478 */
479 cr.defineProperty(PrefRange, 'controlledBy', cr.PropertyKind.ATTR);
480
481 /**
482 * The user metric string.
483 * @type {string}
484 */
485 cr.defineProperty(PrefRange, 'metric', cr.PropertyKind.ATTR);
486
487 ///////////////////////////////////////////////////////////////////////////// 344 /////////////////////////////////////////////////////////////////////////////
488 // PrefSelect class: 345 // PrefSelect class:
489 346
490 // Define a constructor that uses a select element as its underlying element. 347 // Define a constructor that uses a select element as its underlying element.
491 var PrefSelect = cr.ui.define('select'); 348 var PrefSelect = cr.ui.define('select');
492 349
493 PrefSelect.prototype = { 350 PrefSelect.prototype = {
494 // Set up the prototype chain 351 // Set up the prototype chain
495 __proto__: HTMLSelectElement.prototype, 352 __proto__: PrefInputElement.prototype,
496 353
497 /** 354 /**
498 * Initialization function for the cr.ui framework. 355 * Update the associated pref when when the user selects an item.
499 */ 356 * @private
500 decorate: function() { 357 */
501 // Listen to pref changes. 358 updatePrefFromState_: function() {
502 Preferences.getInstance().addEventListener( 359 var value = this.options[this.selectedIndex].value;
503 this.pref, this.onPrefChange_.bind(this)); 360 switch (this.dataType) {
504 361 case 'number':
505 // Listen to user events. 362 Preferences.setIntegerPref(this.pref, value,
506 this.addEventListener('change', this.updatePreferenceValue_.bind(this)); 363 !this.dialogPref, this.metric);
364 break;
365 case 'double':
366 Preferences.setDoublePref(this.pref, value,
367 !this.dialogPref, this.metric);
368 break;
369 case 'boolean':
370 Preferences.setBooleanPref(this.pref, value == 'true',
371 !this.dialogPref, this.metric);
372 break;
373 case 'string':
374 Preferences.setStringPref(this.pref, value,
375 !this.dialogPref, this.metric);
376 break;
377 default:
378 console.error('Unknown data type for <select> UI element: ' +
379 this.dataType);
380 }
507 }, 381 },
508 382
509 /** 383 /**
510 * Event listener that updates the input element when the associated pref 384 * Update the selected item when the associated pref changes.
511 * changes. 385 * @param {Event} event Pref change event.
512 * @param {Event} event The event that details the pref change.
513 * @private 386 * @private
514 */ 387 */
515 onPrefChange_: function(event) { 388 updateStateFromPref_: function(event) {
516 // Make sure |value| is a string, because the value is stored as a string 389 // Make sure the value is a string, because the value is stored as a
517 // in the HTMLOptionElement. 390 // string in the HTMLOptionElement.
518 var value = event.value.value.toString(); 391 value = String(event.value.value);
519
520 updateElementState_(this, event);
521 392
522 var found = false; 393 var found = false;
523 for (var i = 0; i < this.options.length; i++) { 394 for (var i = 0; i < this.options.length; i++) {
524 if (this.options[i].value == value) { 395 if (this.options[i].value == value) {
525 this.selectedIndex = i; 396 this.selectedIndex = i;
526 found = true; 397 found = true;
527 } 398 }
528 } 399 }
529 400
530 // Item not found, select first item. 401 // Item not found, select first item.
531 if (!found) 402 if (!found)
532 this.selectedIndex = 0; 403 this.selectedIndex = 0;
533 404
405 // The "onchange" event automatically fires when the user makes a manual
406 // change. It should never be fired for a programmatic change. However,
407 // these two lines were here already and it is hard to tell who may be
408 // relying on them.
534 if (this.onchange) 409 if (this.onchange)
535 this.onchange(event); 410 this.onchange(event);
536 }, 411 },
537
538 /**
539 * Handler that updates the associated pref when the user changes the input
540 * element's value.
541 * @param {Event} event Change event.
542 * @private
543 */
544 updatePreferenceValue_: function(event) {
545 if (!this.dataType) {
546 console.error('undefined data type for <select> pref');
547 return;
548 }
549
550 var prefValue = this.options[this.selectedIndex].value;
551 switch (this.dataType) {
552 case 'number':
553 Preferences.setIntegerPref(this.pref, prefValue,
554 !this.dialogPref, this.metric);
555 break;
556 case 'double':
557 Preferences.setDoublePref(this.pref, prefValue,
558 !this.dialogPref, this.metric);
559 break;
560 case 'boolean':
561 var value = (prefValue == 'true');
562 Preferences.setBooleanPref(this.pref, value,
563 !this.dialogPref, this.metric);
564 break;
565 case 'string':
566 Preferences.setStringPref(this.pref, prefValue,
567 !this.dialogPref, this.metric);
568 break;
569 default:
570 console.error('unknown data type for <select> pref: ' +
571 this.dataType);
572 }
573 },
574
575 /**
576 * See |updateDisabledState_| above.
577 */
578 setDisabled: function(reason, disabled) {
579 updateDisabledState_(this, reason, disabled);
580 },
581 }; 412 };
582 413
583 /**
584 * The preference name.
585 * @type {string}
586 */
587 cr.defineProperty(PrefSelect, 'pref', cr.PropertyKind.ATTR);
588
589 /**
590 * Whether the preference is controlled by something else than the user's
591 * settings (either 'policy' or 'extension').
592 * @type {string}
593 */
594 cr.defineProperty(PrefSelect, 'controlledBy', cr.PropertyKind.ATTR);
595
596 /**
597 * A special preference type specific to dialogs. Changes take effect in the
598 * settings UI immediately but are only actually committed when the user
599 * confirms the dialog. If the user cancels the dialog instead, the changes
600 * are rolled back in the settings UI and never committed.
601 * @type {boolean}
602 */
603 cr.defineProperty(PrefSelect, 'dialogPref', cr.PropertyKind.BOOL_ATTR);
604
605 /**
606 * The user metric string.
607 * @type {string}
608 */
609 cr.defineProperty(PrefSelect, 'metric', cr.PropertyKind.ATTR);
610
611 /**
612 * The data type for the preference options.
613 * @type {string}
614 */
615 cr.defineProperty(PrefSelect, 'dataType', cr.PropertyKind.ATTR);
616
617 ///////////////////////////////////////////////////////////////////////////// 414 /////////////////////////////////////////////////////////////////////////////
618 // PrefTextField class: 415 // PrefTextField class:
619 416
620 // Define a constructor that uses an input element as its underlying element. 417 // Define a constructor that uses an input element as its underlying element.
621 var PrefTextField = cr.ui.define('input'); 418 var PrefTextField = cr.ui.define('input');
622 419
623 PrefTextField.prototype = { 420 PrefTextField.prototype = {
624 // Set up the prototype chain 421 // Set up the prototype chain
625 __proto__: HTMLInputElement.prototype, 422 __proto__: PrefInputElement.prototype,
626 423
627 /** 424 /**
628 * Initialization function for the cr.ui framework. 425 * Initialization function for the cr.ui framework.
629 */ 426 */
630 decorate: function() { 427 decorate: function() {
428 PrefInputElement.prototype.decorate.call(this);
631 var self = this; 429 var self = this;
632 430
633 // Listen to pref changes. 431 // Listen for user events.
634 Preferences.getInstance().addEventListener(this.pref, function(event) { 432 window.addEventListener('unload', function() {
635 self.value = event.value.value;
636 updateElementState_(self, event);
637 });
638
639 // Listen to user events.
640 this.addEventListener('change', this.updatePreferenceValue_.bind(this));
641
642 window.addEventListener('unload', function(event) {
643 if (document.activeElement == self) 433 if (document.activeElement == self)
644 self.blur(); 434 self.blur();
645 }); 435 });
646 }, 436 },
647 437
648 /** 438 /**
649 * Handler that updates the associated pref when the user changes the input 439 * Update the associated pref when when the user inputs text.
650 * element's value.
651 * @param {Event} event Change event.
652 * @private 440 * @private
653 */ 441 */
654 updatePreferenceValue_: function(event) { 442 updatePrefFromState_: function(event) {
655 switch (this.dataType) { 443 switch (this.dataType) {
656 case 'number': 444 case 'number':
657 Preferences.setIntegerPref(this.pref, this.value, 445 Preferences.setIntegerPref(this.pref, this.value,
658 !this.dialogPref, this.metric); 446 !this.dialogPref, this.metric);
659 break; 447 break;
660 case 'double': 448 case 'double':
661 Preferences.setDoublePref(this.pref, this.value, 449 Preferences.setDoublePref(this.pref, this.value,
662 !this.dialogPref, this.metric); 450 !this.dialogPref, this.metric);
663 break; 451 break;
664 case 'url': 452 case 'url':
665 Preferences.setURLPref(this.pref, this.value, 453 Preferences.setURLPref(this.pref, this.value,
666 !this.dialogPref, this.metric); 454 !this.dialogPref, this.metric);
667 break; 455 break;
668 default: 456 default:
669 Preferences.setStringPref(this.pref, this.value, 457 Preferences.setStringPref(this.pref, this.value,
670 !this.dialogPref, this.metric); 458 !this.dialogPref, this.metric);
671 break; 459 break;
672 } 460 }
673 }, 461 },
674
675 /**
676 * See |updateDisabledState_| above.
677 */
678 setDisabled: function(reason, disabled) {
679 updateDisabledState_(this, reason, disabled);
680 },
681 }; 462 };
682 463
683 /**
684 * The preference name.
685 * @type {string}
686 */
687 cr.defineProperty(PrefTextField, 'pref', cr.PropertyKind.ATTR);
688
689 /**
690 * A special preference type specific to dialogs. Changes take effect in the
691 * settings UI immediately but are only actually committed when the user
692 * confirms the dialog. If the user cancels the dialog instead, the changes
693 * are rolled back in the settings UI and never committed.
694 * @type {boolean}
695 */
696 cr.defineProperty(PrefTextField, 'dialogPref', cr.PropertyKind.BOOL_ATTR);
697
698 /**
699 * Whether the preference is controlled by something else than the user's
700 * settings (either 'policy' or 'extension').
701 * @type {string}
702 */
703 cr.defineProperty(PrefTextField, 'controlledBy', cr.PropertyKind.ATTR);
704
705 /**
706 * The user metric string.
707 * @type {string}
708 */
709 cr.defineProperty(PrefTextField, 'metric', cr.PropertyKind.ATTR);
710
711 /**
712 * The data type for the preference options.
713 * @type {string}
714 */
715 cr.defineProperty(PrefTextField, 'dataType', cr.PropertyKind.ATTR);
716
717 ///////////////////////////////////////////////////////////////////////////// 464 /////////////////////////////////////////////////////////////////////////////
718 // PrefButton class: 465 // PrefButton class:
719 466
720 // Define a constructor that uses a button element as its underlying element. 467 // Define a constructor that uses a button element as its underlying element.
721 var PrefButton = cr.ui.define('button'); 468 var PrefButton = cr.ui.define('button');
722 469
723 PrefButton.prototype = { 470 PrefButton.prototype = {
724 // Set up the prototype chain 471 // Set up the prototype chain
725 __proto__: HTMLButtonElement.prototype, 472 __proto__: HTMLButtonElement.prototype,
726 473
727 /** 474 /**
728 * Initialization function for the cr.ui framework. 475 * Initialization function for the cr.ui framework.
729 */ 476 */
730 decorate: function() { 477 decorate: function() {
731 var self = this; 478 var self = this;
732 479
733 // Listen to pref changes. This element behaves like a normal button and 480 // Listen for pref changes.
734 // doesn't affect the underlying preference; it just becomes disabled 481 // This element behaves like a normal button and does not affect the
735 // when the preference is managed, and its value is false. 482 // underlying preference; it just becomes disabled when the preference is
736 // This is useful for buttons that should be disabled when the underlying 483 // managed, and its value is false. This is useful for buttons that should
737 // boolean preference is set to false by a policy or extension. 484 // be disabled when the underlying Boolean preference is set to false by a
485 // policy or extension.
738 Preferences.getInstance().addEventListener(this.pref, function(event) { 486 Preferences.getInstance().addEventListener(this.pref, function(event) {
739 var e = { 487 updateDisabledState_(self, 'notUserModifiable',
740 value: { 488 event.value.disabled && !event.value.value);
741 'disabled': event.value.disabled && !event.value.value, 489 self.controlledBy = event.value.controlledBy;
742 'controlledBy': event.value.controlledBy 490 OptionsPage.updateManagedBannerVisibility();
743 }
744 };
745 updateElementState_(self, e);
746 }); 491 });
747 }, 492 },
748 493
749 /** 494 /**
750 * See |updateDisabledState_| above. 495 * See |updateDisabledState_| above.
751 */ 496 */
752 setDisabled: function(reason, disabled) { 497 setDisabled: function(reason, disabled) {
753 updateDisabledState_(this, reason, disabled); 498 updateDisabledState_(this, reason, disabled);
754 }, 499 },
755 }; 500 };
756 501
757 /** 502 /**
758 * The preference name. 503 * The name of the associated preference.
759 * @type {string} 504 * @type {string}
760 */ 505 */
761 cr.defineProperty(PrefButton, 'pref', cr.PropertyKind.ATTR); 506 cr.defineProperty(PrefButton, 'pref', cr.PropertyKind.ATTR);
762 507
763 /** 508 /**
764 * Whether the preference is controlled by something else than the user's 509 * Whether the associated preference is controlled by a source other than the
765 * settings (either 'policy' or 'extension'). 510 * user's setting (can be 'policy', 'extension' or 'recommended').
766 * @type {string} 511 * @type {string}
767 */ 512 */
768 cr.defineProperty(PrefButton, 'controlledBy', cr.PropertyKind.ATTR); 513 cr.defineProperty(PrefButton, 'controlledBy', cr.PropertyKind.ATTR);
769 514
770 // Export 515 // Export
771 return { 516 return {
772 PrefCheckbox: PrefCheckbox, 517 PrefCheckbox: PrefCheckbox,
773 PrefNumber: PrefNumber, 518 PrefNumber: PrefNumber,
774 PrefNumeric: PrefNumeric,
775 PrefRadio: PrefRadio, 519 PrefRadio: PrefRadio,
776 PrefRange: PrefRange, 520 PrefRange: PrefRange,
777 PrefSelect: PrefSelect, 521 PrefSelect: PrefSelect,
778 PrefTextField: PrefTextField, 522 PrefTextField: PrefTextField,
779 PrefButton: PrefButton 523 PrefButton: PrefButton
780 }; 524 };
781 525
782 }); 526 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/options/font_settings.js ('k') | chrome/tools/extract_actions.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698