pref_ui.js revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1// Copyright (c) 2010 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. 4 5cr.define('options', function() { 6 7 var Preferences = options.Preferences; 8 ///////////////////////////////////////////////////////////////////////////// 9 // PrefCheckbox class: 10 // TODO(jhawkins): Refactor all this copy-pasted code! 11 12 // Define a constructor that uses an input element as its underlying element. 13 var PrefCheckbox = cr.ui.define('input'); 14 15 PrefCheckbox.prototype = { 16 // Set up the prototype chain 17 __proto__: HTMLInputElement.prototype, 18 19 /** 20 * Initialization function for the cr.ui framework. 21 */ 22 decorate: function() { 23 this.type = 'checkbox'; 24 var self = this; 25 26 self.initializeValueType(self.getAttribute('value-type')); 27 28 // Listen to pref changes. 29 Preferences.getInstance().addEventListener( 30 this.pref, 31 function(event) { 32 var value = event.value && event.value['value'] != undefined ? 33 event.value['value'] : event.value; 34 35 // Invert pref value if inverted_pref == true. 36 if (self.inverted_pref) 37 self.checked = !Boolean(value); 38 else 39 self.checked = Boolean(value); 40 41 self.managed = event.value && event.value['managed'] != undefined ? 42 event.value['managed'] : false; 43 44 // Managed UI elements can only be disabled as a result of being 45 // managed. They cannot be enabled as a result of a pref being 46 // unmanaged. 47 if (self.managed) 48 self.disabled = true; 49 }); 50 51 // Listen to user events. 52 this.addEventListener( 53 'click', 54 function(e) { 55 var value = self.inverted_pref ? !self.checked : self.checked; 56 switch(self.valueType) { 57 case 'number': 58 Preferences.setIntegerPref(self.pref, 59 Number(value), self.metric); 60 break; 61 case 'boolean': 62 Preferences.setBooleanPref(self.pref, 63 value, self.metric); 64 break; 65 } 66 }); 67 }, 68 69 /** 70 * Sets up options in checkbox element. 71 * @param {String} valueType The preference type for this checkbox. 72 */ 73 initializeValueType: function(valueType) { 74 this.valueType = valueType || 'boolean'; 75 } 76 }; 77 78 /** 79 * The preference name. 80 * @type {string} 81 */ 82 cr.defineProperty(PrefCheckbox, 'pref', cr.PropertyKind.ATTR); 83 84 /** 85 * The user metric string. 86 * @type {string} 87 */ 88 cr.defineProperty(PrefCheckbox, 'metric', cr.PropertyKind.ATTR); 89 90 /** 91 * Whether to use inverted pref value. 92 * @type {boolean} 93 */ 94 cr.defineProperty(PrefCheckbox, 'inverted_pref', cr.PropertyKind.BOOL_ATTR); 95 96 ///////////////////////////////////////////////////////////////////////////// 97 // PrefRadio class: 98 99 //Define a constructor that uses an input element as its underlying element. 100 var PrefRadio = cr.ui.define('input'); 101 102 PrefRadio.prototype = { 103 // Set up the prototype chain 104 __proto__: HTMLInputElement.prototype, 105 106 /** 107 * Initialization function for the cr.ui framework. 108 */ 109 decorate: function() { 110 this.type = 'radio'; 111 var self = this; 112 113 // Listen to pref changes. 114 Preferences.getInstance().addEventListener(this.pref, 115 function(event) { 116 var value = event.value && event.value['value'] != undefined ? 117 event.value['value'] : event.value; 118 self.managed = event.value && event.value['managed'] != undefined ? 119 event.value['managed'] : false; 120 self.checked = String(value) == self.value; 121 122 // Managed UI elements can only be disabled as a result of being 123 // managed. They cannot be enabled as a result of a pref being 124 // unmanaged. 125 if (self.managed) 126 self.disabled = true; 127 }); 128 129 // Listen to user events. 130 this.addEventListener('change', 131 function(e) { 132 if(self.value == 'true' || self.value == 'false') { 133 Preferences.setBooleanPref(self.pref, 134 self.value == 'true', self.metric); 135 } else { 136 Preferences.setIntegerPref(self.pref, 137 parseInt(self.value, 10), self.metric); 138 } 139 }); 140 }, 141 142 /** 143 * Getter for preference name attribute. 144 */ 145 get pref() { 146 return this.getAttribute('pref'); 147 }, 148 149 /** 150 * Setter for preference name attribute. 151 */ 152 set pref(name) { 153 this.setAttribute('pref', name); 154 } 155 }; 156 157 /** 158 * The user metric string. 159 * @type {string} 160 */ 161 cr.defineProperty(PrefRadio, 'metric', cr.PropertyKind.ATTR); 162 163 ///////////////////////////////////////////////////////////////////////////// 164 // PrefNumeric class: 165 166 // Define a constructor that uses an input element as its underlying element. 167 var PrefNumeric = function() {}; 168 PrefNumeric.prototype = { 169 // Set up the prototype chain 170 __proto__: HTMLInputElement.prototype, 171 172 /** 173 * Initialization function for the cr.ui framework. 174 */ 175 decorate: function() { 176 var self = this; 177 178 // Listen to pref changes. 179 Preferences.getInstance().addEventListener(this.pref, 180 function(event) { 181 self.value = event.value && event.value['value'] != undefined ? 182 event.value['value'] : event.value; 183 self.managed = event.value && event.value['managed'] != undefined ? 184 event.value['managed'] : false; 185 186 // Managed UI elements can only be disabled as a result of being 187 // managed. They cannot be enabled as a result of a pref being 188 // unmanaged. 189 if (self.managed) 190 self.disabled = true; 191 }); 192 193 // Listen to user events. 194 this.addEventListener('change', 195 function(e) { 196 if (this.validity.valid) { 197 Preferences.setIntegerPref(self.pref, self.value, self.metric); 198 } 199 }); 200 } 201 }; 202 203 /** 204 * The preference name. 205 * @type {string} 206 */ 207 cr.defineProperty(PrefNumeric, 'pref', cr.PropertyKind.ATTR); 208 209 /** 210 * The user metric string. 211 * @type {string} 212 */ 213 cr.defineProperty(PrefNumeric, 'metric', cr.PropertyKind.ATTR); 214 215 ///////////////////////////////////////////////////////////////////////////// 216 // PrefNumber class: 217 218 // Define a constructor that uses an input element as its underlying element. 219 var PrefNumber = cr.ui.define('input'); 220 221 PrefNumber.prototype = { 222 // Set up the prototype chain 223 __proto__: PrefNumeric.prototype, 224 225 /** 226 * Initialization function for the cr.ui framework. 227 */ 228 decorate: function() { 229 this.type = 'number'; 230 PrefNumeric.prototype.decorate.call(this); 231 232 // Listen to user events. 233 this.addEventListener('input', 234 function(e) { 235 if (this.validity.valid) { 236 Preferences.setIntegerPref(self.pref, self.value, self.metric); 237 } 238 }); 239 } 240 }; 241 242 ///////////////////////////////////////////////////////////////////////////// 243 // PrefRange class: 244 245 // Define a constructor that uses an input element as its underlying element. 246 var PrefRange = cr.ui.define('input'); 247 248 PrefRange.prototype = { 249 // Set up the prototype chain 250 __proto__: PrefNumeric.prototype, 251 252 /** 253 * Initialization function for the cr.ui framework. 254 */ 255 decorate: function() { 256 this.type = 'range'; 257 PrefNumeric.prototype.decorate.call(this); 258 var self = this; 259 260 // Additionally change the indicator as well. 261 Preferences.getInstance().addEventListener(this.pref, 262 function(event) { 263 self.updateIndicator(); 264 }); 265 266 // Listen to user events. 267 this.addEventListener('input', 268 function(e) { 269 this.updateIndicator(); 270 }); 271 }, 272 273 updateIndicator: function() { 274 if ($(this.id + '-value')) { 275 $(this.id + '-value').textContent = this.value; 276 } 277 } 278 }; 279 280 ///////////////////////////////////////////////////////////////////////////// 281 // PrefSelect class: 282 283 // Define a constructor that uses an select element as its underlying element. 284 var PrefSelect = cr.ui.define('select'); 285 286 PrefSelect.prototype = { 287 // Set up the prototype chain 288 __proto__: HTMLSelectElement.prototype, 289 290 /** 291 * Initialization function for the cr.ui framework. 292 */ 293 decorate: function() { 294 var self = this; 295 296 var values = self.getAttribute('data-values'); 297 if (values) { 298 self.initializeValues(templateData[values]); 299 } 300 301 // Listen to pref changes. 302 Preferences.getInstance().addEventListener(this.pref, 303 function(event) { 304 var value = event.value && event.value['value'] != undefined ? 305 event.value['value'] : event.value; 306 307 // Make sure |value| is a string, because the value is stored as a 308 // string in the HTMLOptionElement. 309 value = value.toString(); 310 311 self.managed = event.value && event.value['managed'] != undefined ? 312 event.value['managed'] : false; 313 314 // Managed UI elements can only be disabled as a result of being 315 // managed. They cannot be enabled as a result of a pref being 316 // unmanaged. 317 if (self.managed) 318 self.disabled = true; 319 320 var found = false; 321 for (var i = 0; i < self.options.length; i++) { 322 if (self.options[i].value == value) { 323 self.selectedIndex = i; 324 found = true; 325 } 326 } 327 328 // Item not found, select first item. 329 if (!found) 330 self.selectedIndex = 0; 331 332 if (self.onchange != undefined) 333 self.onchange(event); 334 }); 335 336 // Listen to user events. 337 this.addEventListener('change', 338 function(e) { 339 switch(self.dataType) { 340 case 'number': 341 Preferences.setIntegerPref(self.pref, 342 self.options[self.selectedIndex].value, self.metric); 343 break; 344 case 'boolean': 345 var option = self.options[self.selectedIndex]; 346 var value = (option.value == 'true') ? true : false; 347 Preferences.setBooleanPref(self.pref, value, self.metric); 348 break; 349 case 'string': 350 Preferences.setStringPref(self.pref, 351 self.options[self.selectedIndex].value, self.metric); 352 break; 353 } 354 }); 355 }, 356 357 /** 358 * Sets up options in select element. 359 * @param {Array} options List of option and their display text. 360 * Each element in the array is an array of length 2 which contains 361 * options value in the first element and display text in the second 362 * element. May be undefined. 363 * 364 * TODO(zelidrag): move this to that i18n template classes. 365 */ 366 initializeValues: function(options) { 367 options.forEach(function (values) { 368 if (this.dataType == undefined) 369 this.dataType = typeof values[0]; 370 371 this.appendChild(new Option(values[1], values[0])); 372 }, this); 373 } 374 }; 375 376 /** 377 * The preference name. 378 * @type {string} 379 */ 380 cr.defineProperty(PrefSelect, 'pref', cr.PropertyKind.ATTR); 381 382 /** 383 * The user metric string. 384 * @type {string} 385 */ 386 cr.defineProperty(PrefSelect, 'metric', cr.PropertyKind.ATTR); 387 388 ///////////////////////////////////////////////////////////////////////////// 389 // PrefTextField class: 390 391 // Define a constructor that uses an input element as its underlying element. 392 var PrefTextField = cr.ui.define('input'); 393 394 PrefTextField.prototype = { 395 // Set up the prototype chain 396 __proto__: HTMLInputElement.prototype, 397 398 /** 399 * Initialization function for the cr.ui framework. 400 */ 401 decorate: function() { 402 var self = this; 403 404 // Listen to pref changes. 405 Preferences.getInstance().addEventListener(this.pref, 406 function(event) { 407 self.value = event.value && event.value['value'] != undefined ? 408 event.value['value'] : event.value; 409 self.managed = event.value && event.value['managed'] != undefined ? 410 event.value['managed'] : false; 411 412 // Managed UI elements can only be disabled as a result of being 413 // managed. They cannot be enabled as a result of a pref being 414 // unmanaged. 415 if (self.managed) 416 self.disabled = true; 417 }); 418 419 // Listen to user events. 420 this.addEventListener('change', 421 function(e) { 422 Preferences.setStringPref(self.pref, self.value, self.metric); 423 }); 424 425 window.addEventListener('unload', 426 function() { 427 if (document.activeElement == self) 428 self.blur(); 429 }); 430 } 431 }; 432 433 /** 434 * The preference name. 435 * @type {string} 436 */ 437 cr.defineProperty(PrefTextField, 'pref', cr.PropertyKind.ATTR); 438 439 /** 440 * The user metric string. 441 * @type {string} 442 */ 443 cr.defineProperty(PrefTextField, 'metric', cr.PropertyKind.ATTR); 444 445 // Export 446 return { 447 PrefCheckbox: PrefCheckbox, 448 PrefNumber: PrefNumber, 449 PrefNumeric: PrefNumeric, 450 PrefRadio: PrefRadio, 451 PrefRange: PrefRange, 452 PrefSelect: PrefSelect, 453 PrefTextField: PrefTextField 454 }; 455 456}); 457