 Chromium Code Reviews
 Chromium Code Reviews Issue 10827141:
  Move handling of dialog preferences to Preferences class  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 10827141:
  Move handling of dialog preferences to Preferences class  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| OLD | NEW | 
|---|---|
| 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 // TODO(jhawkins): Add dialog-pref support to all preference controls. | |
| 6 | |
| 7 cr.define('options', function() { | 5 cr.define('options', function() { | 
| 8 | 6 | 
| 9 var Preferences = options.Preferences; | 7 var Preferences = options.Preferences; | 
| 10 | 8 | 
| 11 /** | 9 /** | 
| 12 * Allows an element to be disabled for several reasons. | 10 * Allows an element to be disabled for several reasons. | 
| 13 * The element is disabled if at least one reason is true, and the reasons | 11 * The element is disabled if at least one reason is true, and the reasons | 
| 14 * can be set separately. | 12 * can be set separately. | 
| 15 * @private | 13 * @private | 
| 16 * @param {!HTMLElement} el The element to update. | 14 * @param {!HTMLElement} el The element to update. | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 41 el.disabled = Object.keys(el.disabledReasons).length > 0; | 39 el.disabled = Object.keys(el.disabledReasons).length > 0; | 
| 42 } | 40 } | 
| 43 | 41 | 
| 44 /** | 42 /** | 
| 45 * Helper function to update element's state from pref change event. | 43 * Helper function to update element's state from pref change event. | 
| 46 * @private | 44 * @private | 
| 47 * @param {!HTMLElement} el The element to update. | 45 * @param {!HTMLElement} el The element to update. | 
| 48 * @param {!Event} event The pref change event. | 46 * @param {!Event} event The pref change event. | 
| 49 */ | 47 */ | 
| 50 function updateElementState_(el, event) { | 48 function updateElementState_(el, event) { | 
| 51 el.controlledBy = null; | |
| 52 | |
| 53 if (!event.value) | |
| 54 return; | |
| 55 | |
| 56 updateDisabledState_(el, 'notUserModifiable', event.value.disabled); | 49 updateDisabledState_(el, 'notUserModifiable', event.value.disabled); | 
| 57 | |
| 58 el.controlledBy = event.value.controlledBy; | 50 el.controlledBy = event.value.controlledBy; | 
| 59 | |
| 60 OptionsPage.updateManagedBannerVisibility(); | 51 OptionsPage.updateManagedBannerVisibility(); | 
| 61 } | 52 } | 
| 62 | 53 | 
| 63 ///////////////////////////////////////////////////////////////////////////// | 54 ///////////////////////////////////////////////////////////////////////////// | 
| 64 // PrefCheckbox class: | 55 // PrefCheckbox class: | 
| 65 // TODO(jhawkins): Refactor all this copy-pasted code! | 56 // TODO(jhawkins): Refactor all this copy-pasted code! | 
| 66 | 57 | 
| 67 // Define a constructor that uses an input element as its underlying element. | 58 // Define a constructor that uses an input element as its underlying element. | 
| 68 var PrefCheckbox = cr.ui.define('input'); | 59 var PrefCheckbox = cr.ui.define('input'); | 
| 69 | 60 | 
| 70 PrefCheckbox.prototype = { | 61 PrefCheckbox.prototype = { | 
| 71 // Set up the prototype chain | 62 // Set up the prototype chain | 
| 72 __proto__: HTMLInputElement.prototype, | 63 __proto__: HTMLInputElement.prototype, | 
| 73 | 64 | 
| 74 /** | 65 /** | 
| 75 * The stored value of the preference that this checkbox controls. | |
| 76 * @type {boolean} | |
| 77 */ | |
| 78 prefValue_: null, | |
| 79 | |
| 80 /** | |
| 81 * Initialization function for the cr.ui framework. | 66 * Initialization function for the cr.ui framework. | 
| 82 */ | 67 */ | 
| 83 decorate: function() { | 68 decorate: function() { | 
| 84 this.type = 'checkbox'; | 69 this.type = 'checkbox'; | 
| 85 var self = this; | 70 var self = this; | 
| 86 | 71 | 
| 87 self.initializeValueType(self.getAttribute('value-type')); | 72 self.initializeValueType(self.getAttribute('value-type')); | 
| 88 | 73 | 
| 89 // Listen to pref changes. | 74 // Listen to pref changes. | 
| 90 Preferences.getInstance().addEventListener(this.pref, function(event) { | 75 Preferences.getInstance().addEventListener(this.pref, function(event) { | 
| 91 self.prefValue_ = Boolean(event.value.value); | 76 var value = event.value.value; | 
| 92 self.resetPrefState(); | 77 self.checked = self.inverted_pref ? !value : value; | 
| 93 | |
| 94 updateElementState_(self, event); | 78 updateElementState_(self, event); | 
| 95 }); | 79 }); | 
| 96 | 80 | 
| 97 // Listen to user events. | 81 // Listen to user events. | 
| 98 this.addEventListener('change', function(e) { | 82 this.addEventListener('change', function(event) { | 
| 99 if (self.customChangeHandler(e)) | 83 if (this.customChangeHandler(event)) | 
| 
James Hawkins
2012/08/02 20:33:32
We have an inconsistency here: we use |self| above
 
bartfab (slow)
2012/08/31 14:14:30
Done.
 | |
| 100 return; | 84 return; | 
| 101 | 85 | 
| 102 if (!this.dialogPref) | 86 var value = this.inverted_pref ? !this.checked : this.checked; | 
| 103 this.updatePreferenceValue_(); | 87 switch (this.valueType) { | 
| 88 case 'number': | |
| 89 Preferences.setIntegerPref(this.pref, Number(value), | |
| 90 !this.dialogPref, this.metric); | |
| 91 break; | |
| 92 case 'boolean': | |
| 93 Preferences.setBooleanPref(this.pref, value, | |
| 94 !this.dialogPref, this.metric); | |
| 95 break; | |
| 96 } | |
| 104 }); | 97 }); | 
| 105 }, | 98 }, | 
| 106 | 99 | 
| 107 /** | 100 /** | 
| 108 * Update the preference value based on the checkbox state. | |
| 109 * @private | |
| 110 */ | |
| 111 updatePreferenceValue_: function() { | |
| 112 var value = this.inverted_pref ? !this.checked : this.checked; | |
| 113 switch (this.valueType) { | |
| 114 case 'number': | |
| 115 Preferences.setIntegerPref(this.pref, Number(value), this.metric); | |
| 116 break; | |
| 117 case 'boolean': | |
| 118 Preferences.setBooleanPref(this.pref, value, this.metric); | |
| 119 break; | |
| 120 } | |
| 121 }, | |
| 122 | |
| 123 /** | |
| 124 * Called by SettingsDialog to save the preference. | |
| 125 */ | |
| 126 savePrefState: function() { | |
| 127 this.updatePreferenceValue_(); | |
| 128 }, | |
| 129 | |
| 130 /** | |
| 131 * Called by SettingsDialog to reset the UI to match the current preference | |
| 132 * value. | |
| 133 */ | |
| 134 resetPrefState: function() { | |
| 135 this.checked = this.inverted_pref ? !this.prefValue_ : this.prefValue_; | |
| 136 }, | |
| 137 | |
| 138 /** | |
| 139 * Sets up options in checkbox element. | 101 * Sets up options in checkbox element. | 
| 140 * @param {String} valueType The preference type for this checkbox. | 102 * @param {String} valueType The preference type for this checkbox. | 
| 141 */ | 103 */ | 
| 142 initializeValueType: function(valueType) { | 104 initializeValueType: function(valueType) { | 
| 143 this.valueType = valueType || 'boolean'; | 105 this.valueType = valueType || 'boolean'; | 
| 144 }, | 106 }, | 
| 145 | 107 | 
| 146 /** | 108 /** | 
| 147 * See |updateDisabledState_| above. | 109 * See |updateDisabledState_| above. | 
| 148 */ | 110 */ | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 162 }, | 124 }, | 
| 163 }; | 125 }; | 
| 164 | 126 | 
| 165 /** | 127 /** | 
| 166 * The preference name. | 128 * The preference name. | 
| 167 * @type {string} | 129 * @type {string} | 
| 168 */ | 130 */ | 
| 169 cr.defineProperty(PrefCheckbox, 'pref', cr.PropertyKind.ATTR); | 131 cr.defineProperty(PrefCheckbox, 'pref', cr.PropertyKind.ATTR); | 
| 170 | 132 | 
| 171 /** | 133 /** | 
| 172 * A special preference type specific to dialogs. These preferences are reset | 134 * A special preference type specific to dialogs. These preferences are reset | 
| 
James Hawkins
2012/08/02 20:33:32
This sentence now doesn't make as much sense.  I'd
 
bartfab (slow)
2012/08/31 14:14:30
Done.
 | |
| 173 * when the dialog is shown and are not saved until the user confirms the | 135 * when the dialog is closed and are not saved until the user confirms the | 
| 174 * dialog. | 136 * dialog. | 
| 175 * @type {boolean} | 137 * @type {boolean} | 
| 176 */ | 138 */ | 
| 177 cr.defineProperty(PrefCheckbox, 'dialogPref', cr.PropertyKind.BOOL_ATTR); | 139 cr.defineProperty(PrefCheckbox, 'dialogPref', cr.PropertyKind.BOOL_ATTR); | 
| 178 | 140 | 
| 179 /** | 141 /** | 
| 180 * Whether the preference is controlled by something else than the user's | 142 * Whether the preference is controlled by something else than the user's | 
| 181 * settings (either 'policy' or 'extension'). | 143 * settings (either 'policy' or 'extension'). | 
| 182 * @type {string} | 144 * @type {string} | 
| 183 */ | 145 */ | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 decorate: function() { | 177 decorate: function() { | 
| 216 this.type = 'radio'; | 178 this.type = 'radio'; | 
| 217 var self = this; | 179 var self = this; | 
| 218 | 180 | 
| 219 // Listen to preference changes. | 181 // Listen to preference changes. | 
| 220 Preferences.getInstance().addEventListener(this.pref, | 182 Preferences.getInstance().addEventListener(this.pref, | 
| 221 function(event) { | 183 function(event) { | 
| 222 if (self.customChangeHandler(event)) | 184 if (self.customChangeHandler(event)) | 
| 223 return; | 185 return; | 
| 224 self.checked = String(event.value.value) == self.value; | 186 self.checked = String(event.value.value) == self.value; | 
| 225 self.storedValue_ = self.checked; | |
| 226 | 187 | 
| 227 updateElementState_(self, event); | 188 updateElementState_(self, event); | 
| 228 }); | 189 }); | 
| 229 | 190 | 
| 230 // Dialog preferences are not saved until savePrefState() is explicitly | 191 // Listen to user events. | 
| 231 // called. | 192 this.addEventListener('change', function(event) { | 
| 232 if (!this.dialogPref) | 193 if (this.customChangeHandler(event)) | 
| 233 this.onchange = this.savePrefState.bind(this); | 194 return; | 
| 195 | |
| 196 if (this.value == 'true' || this.value == 'false') { | |
| 197 var value = String(this.value); | |
| 198 Preferences.setBooleanPref(this.pref, value == String(this.checked), | |
| 199 !this.dialogPref, this.metric); | |
| 200 } else { | |
| 201 Preferences.setIntegerPref(this.pref, parseInt(this.value, 10), | |
| 202 !this.dialogPref, this.metric); | |
| 203 } | |
| 204 }); | |
| 234 }, | 205 }, | 
| 235 | 206 | 
| 236 /** | 207 /** | 
| 237 * Resets the input to the stored value. | |
| 238 */ | |
| 239 resetPrefState: function() { | |
| 240 this.checked = this.storedValue_; | |
| 241 }, | |
| 242 | |
| 243 /** | |
| 244 * Saves the value of the input back into the preference. May be called | |
| 245 * directly to save dialog preferences. | |
| 246 */ | |
| 247 savePrefState: function() { | |
| 248 this.storedValue_ = this.checked; | |
| 249 if (this.value == 'true' || this.value == 'false') { | |
| 250 var value = String(this.value); | |
| 251 Preferences.setBooleanPref(this.pref, value == String(this.checked), | |
| 252 this.metric); | |
| 253 } else { | |
| 254 Preferences.setIntegerPref(this.pref, parseInt(this.value, 10), | |
| 255 this.metric); | |
| 256 } | |
| 257 }, | |
| 258 | |
| 259 /** | |
| 260 * See |updateDisabledState_| above. | 208 * See |updateDisabledState_| above. | 
| 261 */ | 209 */ | 
| 262 setDisabled: function(reason, disabled) { | 210 setDisabled: function(reason, disabled) { | 
| 263 updateDisabledState_(this, reason, disabled); | 211 updateDisabledState_(this, reason, disabled); | 
| 264 }, | 212 }, | 
| 265 | 213 | 
| 266 /** | 214 /** | 
| 267 * This method is called first while processing an onchange event. If it | 215 * This method is called first while processing an onchange event. If it | 
| 268 * returns false, regular onchange processing continues (setting the | 216 * returns false, regular onchange processing continues (setting the | 
| 269 * associated pref, etc). If it returns true, the rest of the onchange is | 217 * associated pref, etc). If it returns true, the rest of the onchange is | 
| 270 * not performed. I.e., this works like stopPropagation or cancelBubble. | 218 * not performed. I.e., this works like stopPropagation or cancelBubble. | 
| 271 * @param {Event} event Change event. | 219 * @param {Event} event Change event. | 
| 272 */ | 220 */ | 
| 273 customChangeHandler: function(event) { | 221 customChangeHandler: function(event) { | 
| 274 return false; | 222 return false; | 
| 275 }, | 223 }, | 
| 276 }; | 224 }; | 
| 277 | 225 | 
| 278 /** | 226 /** | 
| 279 * The preference name. | 227 * The preference name. | 
| 280 * @type {string} | 228 * @type {string} | 
| 281 */ | 229 */ | 
| 282 cr.defineProperty(PrefRadio, 'pref', cr.PropertyKind.ATTR); | 230 cr.defineProperty(PrefRadio, 'pref', cr.PropertyKind.ATTR); | 
| 283 | 231 | 
| 284 /** | 232 /** | 
| 285 * A special preference type specific to dialogs. These preferences are reset | 233 * A special preference type specific to dialogs. These preferences are reset | 
| 286 * when the dialog is shown and are not saved until the user confirms the | 234 * when the dialog is closed and are not saved until the user confirms the | 
| 287 * dialog. | 235 * dialog. | 
| 288 * @type {boolean} | 236 * @type {boolean} | 
| 289 */ | 237 */ | 
| 290 cr.defineProperty(PrefRadio, 'dialogPref', cr.PropertyKind.BOOL_ATTR); | 238 cr.defineProperty(PrefRadio, 'dialogPref', cr.PropertyKind.BOOL_ATTR); | 
| 291 | 239 | 
| 292 /** | 240 /** | 
| 293 * Whether the preference is controlled by something else than the user's | 241 * Whether the preference is controlled by something else than the user's | 
| 294 * settings (either 'policy' or 'extension'). | 242 * settings (either 'policy' or 'extension'). | 
| 295 * @type {string} | 243 * @type {string} | 
| 296 */ | 244 */ | 
| (...skipping 25 matching lines...) Expand all Loading... | |
| 322 function(event) { | 270 function(event) { | 
| 323 self.value = event.value.value; | 271 self.value = event.value.value; | 
| 324 | 272 | 
| 325 updateElementState_(self, event); | 273 updateElementState_(self, event); | 
| 326 }); | 274 }); | 
| 327 | 275 | 
| 328 // Listen to user events. | 276 // Listen to user events. | 
| 329 this.addEventListener('change', | 277 this.addEventListener('change', | 
| 330 function(e) { | 278 function(e) { | 
| 331 if (this.validity.valid) { | 279 if (this.validity.valid) { | 
| 332 Preferences.setIntegerPref(self.pref, self.value, self.metric); | 280 Preferences.setIntegerPref(self.pref, self.value, | 
| 281 !self.dialogPref, self.metric); | |
| 333 } | 282 } | 
| 334 }); | 283 }); | 
| 335 }, | 284 }, | 
| 336 | 285 | 
| 337 /** | 286 /** | 
| 338 * See |updateDisabledState_| above. | 287 * See |updateDisabledState_| above. | 
| 339 */ | 288 */ | 
| 340 setDisabled: function(reason, disabled) { | 289 setDisabled: function(reason, disabled) { | 
| 341 updateDisabledState_(this, reason, disabled); | 290 updateDisabledState_(this, reason, disabled); | 
| 342 }, | 291 }, | 
| 343 }; | 292 }; | 
| 344 | 293 | 
| 345 /** | 294 /** | 
| 346 * The preference name. | 295 * The preference name. | 
| 347 * @type {string} | 296 * @type {string} | 
| 348 */ | 297 */ | 
| 349 cr.defineProperty(PrefNumeric, 'pref', cr.PropertyKind.ATTR); | 298 cr.defineProperty(PrefNumeric, 'pref', cr.PropertyKind.ATTR); | 
| 350 | 299 | 
| 351 /** | 300 /** | 
| 301 * A special preference type specific to dialogs. These preferences are reset | |
| 302 * when the dialog is closed and are not saved until the user confirms the | |
| 303 * dialog. | |
| 304 * @type {boolean} | |
| 305 */ | |
| 306 cr.defineProperty(PrefRadio, 'dialogPref', cr.PropertyKind.BOOL_ATTR); | |
| 307 | |
| 308 /** | |
| 352 * Whether the preference is controlled by something else than the user's | 309 * Whether the preference is controlled by something else than the user's | 
| 353 * settings (either 'policy' or 'extension'). | 310 * settings (either 'policy' or 'extension'). | 
| 354 * @type {string} | 311 * @type {string} | 
| 355 */ | 312 */ | 
| 356 cr.defineProperty(PrefNumeric, 'controlledBy', cr.PropertyKind.ATTR); | 313 cr.defineProperty(PrefNumeric, 'controlledBy', cr.PropertyKind.ATTR); | 
| 357 | 314 | 
| 358 /** | 315 /** | 
| 359 * The user metric string. | 316 * The user metric string. | 
| 360 * @type {string} | 317 * @type {string} | 
| 361 */ | 318 */ | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 375 * Initialization function for the cr.ui framework. | 332 * Initialization function for the cr.ui framework. | 
| 376 */ | 333 */ | 
| 377 decorate: function() { | 334 decorate: function() { | 
| 378 this.type = 'number'; | 335 this.type = 'number'; | 
| 379 PrefNumeric.prototype.decorate.call(this); | 336 PrefNumeric.prototype.decorate.call(this); | 
| 380 | 337 | 
| 381 // Listen to user events. | 338 // Listen to user events. | 
| 382 this.addEventListener('input', | 339 this.addEventListener('input', | 
| 383 function(e) { | 340 function(e) { | 
| 384 if (this.validity.valid) { | 341 if (this.validity.valid) { | 
| 385 Preferences.setIntegerPref(self.pref, self.value, self.metric); | 342 Preferences.setIntegerPref(self.pref, self.value, | 
| 343 !self.dialogPref, self.metric); | |
| 386 } | 344 } | 
| 387 }); | 345 }); | 
| 388 }, | 346 }, | 
| 389 | 347 | 
| 390 /** | 348 /** | 
| 391 * See |updateDisabledState_| above. | 349 * See |updateDisabledState_| above. | 
| 392 */ | 350 */ | 
| 393 setDisabled: function(reason, disabled) { | 351 setDisabled: function(reason, disabled) { | 
| 394 updateDisabledState_(this, reason, disabled); | 352 updateDisabledState_(this, reason, disabled); | 
| 395 }, | 353 }, | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 435 this.onkeyup = this.onmouseup = this.onInputUp_.bind(this); | 393 this.onkeyup = this.onmouseup = this.onInputUp_.bind(this); | 
| 436 }, | 394 }, | 
| 437 | 395 | 
| 438 /** | 396 /** | 
| 439 * Event listener that updates the UI when the underlying pref changes. | 397 * Event listener that updates the UI when the underlying pref changes. | 
| 440 * @param {Event} event The event that details the pref change. | 398 * @param {Event} event The event that details the pref change. | 
| 441 * @private | 399 * @private | 
| 442 */ | 400 */ | 
| 443 onPrefChange_: function(event) { | 401 onPrefChange_: function(event) { | 
| 444 var value = event.value.value; | 402 var value = event.value.value; | 
| 445 if (value != undefined) | 403 this.value = this.valueMap ? this.valueMap.indexOf(value) : value; | 
| 446 this.value = this.valueMap ? this.valueMap.indexOf(value) : value; | |
| 447 }, | 404 }, | 
| 448 | 405 | 
| 449 /** | 406 /** | 
| 450 * onchange handler that sets the pref when the user changes the value of | 407 * onchange handler that sets the pref when the user changes the value of | 
| 451 * the input element. | 408 * the input element. | 
| 452 * @private | 409 * @private | 
| 453 */ | 410 */ | 
| 454 onChange_: function(event) { | 411 onChange_: function(event) { | 
| 455 if (this.continuous) | 412 if (this.continuous) | 
| 456 this.setRangePref_(); | 413 this.setRangePref_(); | 
| 457 | 414 | 
| 458 if (this.notifyChange) | 415 if (this.notifyChange) | 
| 459 this.notifyChange(this, this.mapValueToRange_(this.value)); | 416 this.notifyChange(this, this.mapValueToRange_(this.value)); | 
| 460 }, | 417 }, | 
| 461 | 418 | 
| 462 /** | 419 /** | 
| 463 * Sets the integer value of |pref| to the value of this element. | 420 * Sets the integer value of |pref| to the value of this element. | 
| 464 * @private | 421 * @private | 
| 465 */ | 422 */ | 
| 466 setRangePref_: function() { | 423 setRangePref_: function() { | 
| 467 Preferences.setIntegerPref( | 424 Preferences.setIntegerPref(this.pref, this.mapValueToRange_(this.value), | 
| 468 this.pref, this.mapValueToRange_(this.value), this.metric); | 425 !this.dialogPref, this.metric); | 
| 469 | |
| 470 if (this.notifyPrefChange) | |
| 471 this.notifyPrefChange(this, this.mapValueToRange_(this.value)); | |
| 472 }, | 426 }, | 
| 473 | 427 | 
| 474 /** | 428 /** | 
| 475 * onkeyup/onmouseup handler that modifies the pref if |continuous| is | 429 * onkeyup/onmouseup handler that modifies the pref if |continuous| is | 
| 476 * false. | 430 * false. | 
| 477 * @private | 431 * @private | 
| 478 */ | 432 */ | 
| 479 onInputUp_: function(event) { | 433 onInputUp_: function(event) { | 
| 480 if (!this.continuous) | 434 if (!this.continuous) | 
| 481 this.setRangePref_(); | 435 this.setRangePref_(); | 
| (...skipping 26 matching lines...) Expand all Loading... | |
| 508 }, | 462 }, | 
| 509 }; | 463 }; | 
| 510 | 464 | 
| 511 /** | 465 /** | 
| 512 * The preference name. | 466 * The preference name. | 
| 513 * @type {string} | 467 * @type {string} | 
| 514 */ | 468 */ | 
| 515 cr.defineProperty(PrefRange, 'pref', cr.PropertyKind.ATTR); | 469 cr.defineProperty(PrefRange, 'pref', cr.PropertyKind.ATTR); | 
| 516 | 470 | 
| 517 /** | 471 /** | 
| 472 * A special preference type specific to dialogs. These preferences are reset | |
| 473 * when the dialog is closed and are not saved until the user confirms the | |
| 474 * dialog. | |
| 475 * @type {boolean} | |
| 476 */ | |
| 477 cr.defineProperty(PrefRadio, 'dialogPref', cr.PropertyKind.BOOL_ATTR); | |
| 478 | |
| 479 /** | |
| 518 * Whether the preference is controlled by something else than the user's | 480 * Whether the preference is controlled by something else than the user's | 
| 519 * settings (either 'policy' or 'extension'). | 481 * settings (either 'policy' or 'extension'). | 
| 520 * @type {string} | 482 * @type {string} | 
| 521 */ | 483 */ | 
| 522 cr.defineProperty(PrefRange, 'controlledBy', cr.PropertyKind.ATTR); | 484 cr.defineProperty(PrefRange, 'controlledBy', cr.PropertyKind.ATTR); | 
| 523 | 485 | 
| 524 /** | 486 /** | 
| 525 * The user metric string. | 487 * The user metric string. | 
| 526 * @type {string} | 488 * @type {string} | 
| 527 */ | 489 */ | 
| 528 cr.defineProperty(PrefRange, 'metric', cr.PropertyKind.ATTR); | 490 cr.defineProperty(PrefRange, 'metric', cr.PropertyKind.ATTR); | 
| 529 | 491 | 
| 530 ///////////////////////////////////////////////////////////////////////////// | 492 ///////////////////////////////////////////////////////////////////////////// | 
| 531 // PrefSelect class: | 493 // PrefSelect class: | 
| 532 | 494 | 
| 533 // Define a constructor that uses a select element as its underlying element. | 495 // Define a constructor that uses a select element as its underlying element. | 
| 534 var PrefSelect = cr.ui.define('select'); | 496 var PrefSelect = cr.ui.define('select'); | 
| 535 | 497 | 
| 536 PrefSelect.prototype = { | 498 PrefSelect.prototype = { | 
| 537 // Set up the prototype chain | 499 // Set up the prototype chain | 
| 538 __proto__: HTMLSelectElement.prototype, | 500 __proto__: HTMLSelectElement.prototype, | 
| 539 | 501 | 
| 540 /** | 502 /** | 
| 541 * @type {string} The stored value of the preference that this select | |
| 542 * controls. | |
| 543 */ | |
| 544 prefValue_: null, | |
| 545 | |
| 546 /** | |
| 547 * Initialization function for the cr.ui framework. | 503 * Initialization function for the cr.ui framework. | 
| 548 */ | 504 */ | 
| 549 decorate: function() { | 505 decorate: function() { | 
| 550 var self = this; | 506 var self = this; | 
| 551 | 507 | 
| 552 // Listen to pref changes. | 508 // Listen to pref changes. | 
| 553 Preferences.getInstance().addEventListener(this.pref, function(event) { | 509 Preferences.getInstance().addEventListener(this.pref, function(event) { | 
| 554 // Make sure |value| is a string, because the value is stored as a | 510 // Make sure |value| is a string, because the value is stored as a | 
| 555 // string in the HTMLOptionElement. | 511 // string in the HTMLOptionElement. | 
| 556 value = event.value.value.toString(); | 512 value = event.value.value.toString(); | 
| 557 | 513 | 
| 558 updateElementState_(self, event); | 514 updateElementState_(self, event); | 
| 559 self.prefValue_ = value; | 515 | 
| 560 self.resetPrefState(); | 516 var found = false; | 
| 517 for (var i = 0; i < self.options.length; i++) { | |
| 518 if (self.options[i].value == self.prefValue_) { | |
| 519 self.selectedIndex = i; | |
| 520 found = true; | |
| 521 } | |
| 522 } | |
| 523 | |
| 524 // Item not found, select first item. | |
| 525 if (!found) | |
| 526 self.selectedIndex = 0; | |
| 527 | |
| 528 if (this.onchange) | |
| 529 self.onchange(event); | |
| 561 }); | 530 }); | 
| 562 | 531 | 
| 563 // Listen to user events. | 532 // Listen to user events. | 
| 564 this.addEventListener('change', function(event) { | 533 this.addEventListener('change', function(event) { | 
| 565 if (!self.dialogPref) | 534 if (!this.dataType) { | 
| 566 self.updatePreference_(self.prefValue_); | 535 console.error('undefined data type for <select> pref'); | 
| 536 return; | |
| 537 } | |
| 538 | |
| 539 var prefValue = this.options[this.selectedIndex].value; | |
| 540 switch (this.dataType) { | |
| 541 case 'number': | |
| 542 Preferences.setIntegerPref(this.pref, prefValue, | |
| 543 !this.dialogPref, this.metric); | |
| 544 break; | |
| 545 case 'double': | |
| 546 Preferences.setDoublePref(this.pref, prefValue, | |
| 547 !this.dialogPref, this.metric); | |
| 548 break; | |
| 549 case 'boolean': | |
| 550 var value = (prefValue == 'true'); | |
| 551 Preferences.setBooleanPref(this.pref, value, | |
| 552 !this.dialogPref, this.metric); | |
| 553 break; | |
| 554 case 'string': | |
| 555 Preferences.setStringPref(this.pref, prefValue, | |
| 556 !this.dialogPref, this.metric); | |
| 557 break; | |
| 558 default: | |
| 559 console.error('unknown data type for <select> pref: ' + | |
| 560 this.dataType); | |
| 561 } | |
| 567 }); | 562 }); | 
| 568 }, | 563 }, | 
| 569 | 564 | 
| 570 /** | 565 /** | 
| 571 * Resets the input to the stored value. | |
| 572 */ | |
| 573 resetPrefState: function() { | |
| 574 var found = false; | |
| 575 for (var i = 0; i < this.options.length; i++) { | |
| 576 if (this.options[i].value == this.prefValue_) { | |
| 577 this.selectedIndex = i; | |
| 578 found = true; | |
| 579 } | |
| 580 } | |
| 581 | |
| 582 // Item not found, select first item. | |
| 583 if (!found) | |
| 584 this.selectedIndex = 0; | |
| 585 | |
| 586 if (this.onchange) | |
| 587 this.onchange(event); | |
| 588 }, | |
| 589 | |
| 590 /** | |
| 591 * Updates the preference to the currently selected value. | |
| 592 */ | |
| 593 updatePreference_: function() { | |
| 594 if (!this.dataType) { | |
| 595 console.error('undefined data type for <select> pref'); | |
| 596 return; | |
| 597 } | |
| 598 | |
| 599 var prefValue = this.options[this.selectedIndex].value; | |
| 600 switch (this.dataType) { | |
| 601 case 'number': | |
| 602 Preferences.setIntegerPref(this.pref, prefValue, this.metric); | |
| 603 break; | |
| 604 case 'double': | |
| 605 Preferences.setDoublePref(this.pref, prefValue, this.metric); | |
| 606 break; | |
| 607 case 'boolean': | |
| 608 var value = (prefValue == 'true'); | |
| 609 Preferences.setBooleanPref(this.pref, value, this.metric); | |
| 610 break; | |
| 611 case 'string': | |
| 612 Preferences.setStringPref(this.pref, prefValue, this.metric); | |
| 613 break; | |
| 614 default: | |
| 615 console.error('unknown data type for <select> pref: ' + | |
| 616 this.dataType); | |
| 617 } | |
| 618 }, | |
| 619 | |
| 620 /** | |
| 621 * Called by SettingsDialog to save the stored value to preferences. | |
| 622 */ | |
| 623 savePrefState: function() { | |
| 624 this.updatePreference_(); | |
| 625 }, | |
| 626 | |
| 627 /** | |
| 628 * See |updateDisabledState_| above. | 566 * See |updateDisabledState_| above. | 
| 629 */ | 567 */ | 
| 630 setDisabled: function(reason, disabled) { | 568 setDisabled: function(reason, disabled) { | 
| 631 updateDisabledState_(this, reason, disabled); | 569 updateDisabledState_(this, reason, disabled); | 
| 632 }, | 570 }, | 
| 633 }; | 571 }; | 
| 634 | 572 | 
| 635 /** | 573 /** | 
| 636 * The preference name. | 574 * The preference name. | 
| 637 * @type {string} | 575 * @type {string} | 
| 638 */ | 576 */ | 
| 639 cr.defineProperty(PrefSelect, 'pref', cr.PropertyKind.ATTR); | 577 cr.defineProperty(PrefSelect, 'pref', cr.PropertyKind.ATTR); | 
| 640 | 578 | 
| 641 /** | 579 /** | 
| 642 * Whether the preference is controlled by something else than the user's | 580 * Whether the preference is controlled by something else than the user's | 
| 643 * settings (either 'policy' or 'extension'). | 581 * settings (either 'policy' or 'extension'). | 
| 644 * @type {string} | 582 * @type {string} | 
| 645 */ | 583 */ | 
| 646 cr.defineProperty(PrefSelect, 'controlledBy', cr.PropertyKind.ATTR); | 584 cr.defineProperty(PrefSelect, 'controlledBy', cr.PropertyKind.ATTR); | 
| 647 | 585 | 
| 648 /** | 586 /** | 
| 649 * A special preference type specific to dialogs. These preferences are reset | 587 * A special preference type specific to dialogs. These preferences are reset | 
| 650 * when the dialog is shown and are not saved until the user confirms the | 588 * when the dialog is closed and are not saved until the user confirms the | 
| 651 * dialog. | 589 * dialog. | 
| 652 * @type {boolean} | 590 * @type {boolean} | 
| 653 */ | 591 */ | 
| 654 cr.defineProperty(PrefSelect, 'dialogPref', cr.PropertyKind.BOOL_ATTR); | 592 cr.defineProperty(PrefSelect, 'dialogPref', cr.PropertyKind.BOOL_ATTR); | 
| 655 | 593 | 
| 656 /** | 594 /** | 
| 657 * The user metric string. | 595 * The user metric string. | 
| 658 * @type {string} | 596 * @type {string} | 
| 659 */ | 597 */ | 
| 660 cr.defineProperty(PrefSelect, 'metric', cr.PropertyKind.ATTR); | 598 cr.defineProperty(PrefSelect, 'metric', cr.PropertyKind.ATTR); | 
| 661 | 599 | 
| 662 /** | 600 /** | 
| 663 * The data type for the preference options. | 601 * The data type for the preference options. | 
| 664 * @type {string} | 602 * @type {string} | 
| 665 */ | 603 */ | 
| 666 cr.defineProperty(PrefSelect, 'dataType', cr.PropertyKind.ATTR); | 604 cr.defineProperty(PrefSelect, 'dataType', cr.PropertyKind.ATTR); | 
| 667 | 605 | 
| 668 ///////////////////////////////////////////////////////////////////////////// | 606 ///////////////////////////////////////////////////////////////////////////// | 
| 669 // PrefTextField class: | 607 // PrefTextField class: | 
| 670 | 608 | 
| 671 // Define a constructor that uses an input element as its underlying element. | 609 // Define a constructor that uses an input element as its underlying element. | 
| 672 var PrefTextField = cr.ui.define('input'); | 610 var PrefTextField = cr.ui.define('input'); | 
| 673 | 611 | 
| 674 PrefTextField.prototype = { | 612 PrefTextField.prototype = { | 
| 675 // Set up the prototype chain | 613 // Set up the prototype chain | 
| 676 __proto__: HTMLInputElement.prototype, | 614 __proto__: HTMLInputElement.prototype, | 
| 677 | 615 | 
| 678 /** | 616 /** | 
| 679 * @type {string} The stored value of the preference that this text field | |
| 680 * controls. | |
| 681 */ | |
| 682 prefValue_: null, | |
| 683 | |
| 684 /** | |
| 685 * Saves the value of the input back into the preference. May be called | |
| 686 * directly to save dialog preferences. | |
| 687 */ | |
| 688 savePrefState: function() { | |
| 689 switch (this.dataType) { | |
| 690 case 'number': | |
| 691 Preferences.setIntegerPref(this.pref, this.value, this.metric); | |
| 692 break; | |
| 693 case 'double': | |
| 694 Preferences.setDoublePref(this.pref, this.value, this.metric); | |
| 695 break; | |
| 696 case 'url': | |
| 697 Preferences.setURLPref(this.pref, this.value, this.metric); | |
| 698 break; | |
| 699 default: | |
| 700 Preferences.setStringPref(this.pref, this.value, this.metric); | |
| 701 break; | |
| 702 } | |
| 703 }, | |
| 704 | |
| 705 /** | |
| 706 * Resets the input to the stored value. | |
| 707 */ | |
| 708 resetPrefState: function() { | |
| 709 this.value = this.prefValue_; | |
| 710 }, | |
| 711 | |
| 712 /** | |
| 713 * Initialization function for the cr.ui framework. | 617 * Initialization function for the cr.ui framework. | 
| 714 */ | 618 */ | 
| 715 decorate: function() { | 619 decorate: function() { | 
| 716 var self = this; | 620 var self = this; | 
| 717 | 621 | 
| 718 // Listen to pref changes. | 622 // Listen to pref changes. | 
| 719 Preferences.getInstance().addEventListener(this.pref, | 623 Preferences.getInstance().addEventListener(this.pref, | 
| 720 function(event) { | 624 function(event) { | 
| 721 self.value = event.value.value; | 625 self.value = event.value.value; | 
| 722 | 626 | 
| 723 updateElementState_(self, event); | 627 updateElementState_(self, event); | 
| 724 | |
| 725 self.prefValue_ = self.value; | |
| 726 }); | 628 }); | 
| 727 | 629 | 
| 728 // Listen to user events. | 630 // Listen to user events. | 
| 729 if (!this.dialogPref) | 631 this.addEventListener('change', function(event) { | 
| 730 this.addEventListener('change', this.savePrefState.bind(this)); | 632 switch (this.dataType) { | 
| 
James Hawkins
2012/08/02 20:33:32
I'm not a fan of inlining large functions, so plea
 
bartfab (slow)
2012/08/31 14:14:30
Done.
 | |
| 633 case 'number': | |
| 634 Preferences.setIntegerPref(this.pref, this.value, | |
| 635 !this.dialogPref, this.metric); | |
| 636 break; | |
| 637 case 'double': | |
| 638 Preferences.setDoublePref(this.pref, this.value, | |
| 639 !this.dialogPref, this.metric); | |
| 640 break; | |
| 641 case 'url': | |
| 642 Preferences.setURLPref(this.pref, this.value, | |
| 643 !this.dialogPref, this.metric); | |
| 644 break; | |
| 645 default: | |
| 646 Preferences.setStringPref(this.pref, this.value, | |
| 647 !this.dialogPref, this.metric); | |
| 648 break; | |
| 649 } | |
| 650 }); | |
| 731 | 651 | 
| 732 window.addEventListener('unload', | 652 window.addEventListener('unload', | 
| 733 function() { | 653 function() { | 
| 734 if (document.activeElement == self) | 654 if (document.activeElement == self) | 
| 735 self.blur(); | 655 self.blur(); | 
| 736 }); | 656 }); | 
| 737 }, | 657 }, | 
| 738 | 658 | 
| 739 /** | 659 /** | 
| 740 * See |updateDisabledState_| above. | 660 * See |updateDisabledState_| above. | 
| 741 */ | 661 */ | 
| 742 setDisabled: function(reason, disabled) { | 662 setDisabled: function(reason, disabled) { | 
| 743 updateDisabledState_(this, reason, disabled); | 663 updateDisabledState_(this, reason, disabled); | 
| 744 }, | 664 }, | 
| 745 }; | 665 }; | 
| 746 | 666 | 
| 747 /** | 667 /** | 
| 748 * The preference name. | 668 * The preference name. | 
| 749 * @type {string} | 669 * @type {string} | 
| 750 */ | 670 */ | 
| 751 cr.defineProperty(PrefTextField, 'pref', cr.PropertyKind.ATTR); | 671 cr.defineProperty(PrefTextField, 'pref', cr.PropertyKind.ATTR); | 
| 752 | 672 | 
| 753 /** | 673 /** | 
| 754 * A special preference type specific to dialogs. These preferences are reset | 674 * A special preference type specific to dialogs. These preferences are reset | 
| 755 * when the dialog is shown and are not saved until the user confirms the | 675 * when the dialog is closed and are not saved until the user confirms the | 
| 756 * dialog. | 676 * dialog. | 
| 757 * @type {boolean} | 677 * @type {boolean} | 
| 758 */ | 678 */ | 
| 759 cr.defineProperty(PrefTextField, 'dialogPref', cr.PropertyKind.BOOL_ATTR); | 679 cr.defineProperty(PrefTextField, 'dialogPref', cr.PropertyKind.BOOL_ATTR); | 
| 760 | 680 | 
| 761 /** | 681 /** | 
| 762 * Whether the preference is controlled by something else than the user's | 682 * Whether the preference is controlled by something else than the user's | 
| 763 * settings (either 'policy' or 'extension'). | 683 * settings (either 'policy' or 'extension'). | 
| 764 * @type {string} | 684 * @type {string} | 
| 765 */ | 685 */ | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 837 PrefNumber: PrefNumber, | 757 PrefNumber: PrefNumber, | 
| 838 PrefNumeric: PrefNumeric, | 758 PrefNumeric: PrefNumeric, | 
| 839 PrefRadio: PrefRadio, | 759 PrefRadio: PrefRadio, | 
| 840 PrefRange: PrefRange, | 760 PrefRange: PrefRange, | 
| 841 PrefSelect: PrefSelect, | 761 PrefSelect: PrefSelect, | 
| 842 PrefTextField: PrefTextField, | 762 PrefTextField: PrefTextField, | 
| 843 PrefButton: PrefButton | 763 PrefButton: PrefButton | 
| 844 }; | 764 }; | 
| 845 | 765 | 
| 846 }); | 766 }); | 
| OLD | NEW |