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

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

Issue 7003007: Apply content-security-policy to the HTML options page. This is a (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 7 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
OLDNEW
(Empty)
1 // Copyright (c) 2011 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
5 cr.define('options', function() {
6
7 var Preferences = options.Preferences;
8
9 /**
10 * Helper function update element's state from pref change event.
11 * @private
12 * @param {!HTMLElement} el The element to update.
13 * @param {!Event} event The pref change event.
14 */
15 function updateElementState_(el, event) {
16 el.managed = event.value && event.value['managed'] != undefined ?
17 event.value['managed'] : false;
18
19 // Managed UI elements can only be disabled as a result of being
20 // managed. They cannot be enabled as a result of a pref being
21 // unmanaged.
22 if (el.managed)
23 el.disabled = true;
24
25 // Disable UI elements if backend says so.
26 if (!el.disabled && event.value && event.value['disabled'])
27 el.disabled = true;
28 }
29
30 /////////////////////////////////////////////////////////////////////////////
31 // PrefCheckbox class:
32 // TODO(jhawkins): Refactor all this copy-pasted code!
33
34 // Define a constructor that uses an input element as its underlying element.
35 var PrefCheckbox = cr.ui.define('input');
36
37 PrefCheckbox.prototype = {
38 // Set up the prototype chain
39 __proto__: HTMLInputElement.prototype,
40
41 /**
42 * Initialization function for the cr.ui framework.
43 */
44 decorate: function() {
45 this.type = 'checkbox';
46 var self = this;
47
48 self.initializeValueType(self.getAttribute('value-type'));
49
50 // Listen to pref changes.
51 Preferences.getInstance().addEventListener(
52 this.pref,
53 function(event) {
54 var value = event.value && event.value['value'] != undefined ?
55 event.value['value'] : event.value;
56
57 // Invert pref value if inverted_pref == true.
58 if (self.inverted_pref)
59 self.checked = !Boolean(value);
60 else
61 self.checked = Boolean(value);
62
63 updateElementState_(self, event);
64 });
65
66 // Listen to user events.
67 this.addEventListener(
68 'change',
69 function(e) {
70 var value = self.inverted_pref ? !self.checked : self.checked;
71 switch(self.valueType) {
72 case 'number':
73 Preferences.setIntegerPref(self.pref,
74 Number(value), self.metric);
75 break;
76 case 'boolean':
77 Preferences.setBooleanPref(self.pref,
78 value, self.metric);
79 break;
80 }
81 });
82 },
83
84 /**
85 * Sets up options in checkbox element.
86 * @param {String} valueType The preference type for this checkbox.
87 */
88 initializeValueType: function(valueType) {
89 this.valueType = valueType || 'boolean';
90 },
91 };
92
93 /**
94 * The preference name.
95 * @type {string}
96 */
97 cr.defineProperty(PrefCheckbox, 'pref', cr.PropertyKind.ATTR);
98
99 /**
100 * The user metric string.
101 * @type {string}
102 */
103 cr.defineProperty(PrefCheckbox, 'metric', cr.PropertyKind.ATTR);
104
105 /**
106 * Whether to use inverted pref value.
107 * @type {boolean}
108 */
109 cr.defineProperty(PrefCheckbox, 'inverted_pref', cr.PropertyKind.BOOL_ATTR);
110
111 /////////////////////////////////////////////////////////////////////////////
112 // PrefRadio class:
113
114 //Define a constructor that uses an input element as its underlying element.
115 var PrefRadio = cr.ui.define('input');
116
117 PrefRadio.prototype = {
118 // Set up the prototype chain
119 __proto__: HTMLInputElement.prototype,
120
121 /**
122 * Initialization function for the cr.ui framework.
123 */
124 decorate: function() {
125 this.type = 'radio';
126 var self = this;
127
128 // Listen to pref changes.
129 Preferences.getInstance().addEventListener(this.pref,
130 function(event) {
131 var value = event.value && event.value['value'] != undefined ?
132 event.value['value'] : event.value;
133 self.checked = String(value) == self.value;
134
135 updateElementState_(self, event);
136 });
137
138 // Listen to user events.
139 // Use the 'click' event instead of 'change', because of a bug in WebKit
140 // which prevents 'change' from being sent when the user changes selection
141 // using the keyboard.
142 // https://bugs.webkit.org/show_bug.cgi?id=32013
143 this.addEventListener('click',
144 function(e) {
145 if(self.value == 'true' || self.value == 'false') {
146 Preferences.setBooleanPref(self.pref,
147 self.value == 'true', self.metric);
148 } else {
149 Preferences.setIntegerPref(self.pref,
150 parseInt(self.value, 10), self.metric);
151 }
152 });
153 },
154 };
155
156 /**
157 * The preference name.
158 * @type {string}
159 */
160 cr.defineProperty(PrefRadio, 'pref', cr.PropertyKind.ATTR);
161
162 /**
163 * The user metric string.
164 * @type {string}
165 */
166 cr.defineProperty(PrefRadio, 'metric', cr.PropertyKind.ATTR);
167
168 /////////////////////////////////////////////////////////////////////////////
169 // PrefNumeric class:
170
171 // Define a constructor that uses an input element as its underlying element.
172 var PrefNumeric = function() {};
173 PrefNumeric.prototype = {
174 // Set up the prototype chain
175 __proto__: HTMLInputElement.prototype,
176
177 /**
178 * Initialization function for the cr.ui framework.
179 */
180 decorate: function() {
181 var self = this;
182
183 // Listen to pref changes.
184 Preferences.getInstance().addEventListener(this.pref,
185 function(event) {
186 self.value = event.value && event.value['value'] != undefined ?
187 event.value['value'] : event.value;
188
189 updateElementState_(self, event);
190 });
191
192 // Listen to user events.
193 this.addEventListener('change',
194 function(e) {
195 if (this.validity.valid) {
196 Preferences.setIntegerPref(self.pref, self.value, self.metric);
197 }
198 });
199 }
200 };
201
202 /**
203 * The preference name.
204 * @type {string}
205 */
206 cr.defineProperty(PrefNumeric, 'pref', cr.PropertyKind.ATTR);
207
208 /**
209 * The user metric string.
210 * @type {string}
211 */
212 cr.defineProperty(PrefNumeric, 'metric', cr.PropertyKind.ATTR);
213
214 /////////////////////////////////////////////////////////////////////////////
215 // PrefNumber class:
216
217 // Define a constructor that uses an input element as its underlying element.
218 var PrefNumber = cr.ui.define('input');
219
220 PrefNumber.prototype = {
221 // Set up the prototype chain
222 __proto__: PrefNumeric.prototype,
223
224 /**
225 * Initialization function for the cr.ui framework.
226 */
227 decorate: function() {
228 this.type = 'number';
229 PrefNumeric.prototype.decorate.call(this);
230
231 // Listen to user events.
232 this.addEventListener('input',
233 function(e) {
234 if (this.validity.valid) {
235 Preferences.setIntegerPref(self.pref, self.value, self.metric);
236 }
237 });
238 }
239 };
240
241 /////////////////////////////////////////////////////////////////////////////
242 // PrefRange class:
243
244 // Define a constructor that uses an input element as its underlying element.
245 var PrefRange = cr.ui.define('input');
246
247 PrefRange.prototype = {
248 // Set up the prototype chain
249 __proto__: HTMLInputElement.prototype,
250
251 /**
252 * The map from input range value to the corresponding preference value.
253 */
254 valueMap: undefined,
255
256 /**
257 * If true, the associated pref will be modified on each onchange event;
258 * otherwise, the pref will only be modified on the onmouseup event after
259 * the drag.
260 */
261 continuous: true,
262
263 /**
264 * Initialization function for the cr.ui framework.
265 */
266 decorate: function() {
267 this.type = 'range';
268
269 // Update the UI when the pref changes.
270 Preferences.getInstance().addEventListener(
271 this.pref, this.onPrefChange_.bind(this));
272
273 // Listen to user events.
274 // TODO(jhawkins): Add onmousewheel handling once the associated WK bug is
275 // fixed.
276 // https://bugs.webkit.org/show_bug.cgi?id=52256
277 this.onchange = this.onChange_.bind(this);
278 this.onkeyup = this.onmouseup = this.onInputUp_.bind(this);
279 },
280
281 /**
282 * Event listener that updates the UI when the underlying pref changes.
283 * @param {Event} event The event that details the pref change.
284 * @private
285 */
286 onPrefChange_: function(event) {
287 var value = event.value && event.value['value'] != undefined ?
288 event.value['value'] : event.value;
289 if (value != undefined)
290 this.value = this.valueMap ? this.valueMap.indexOf(value) : value;
291 },
292
293 /**
294 * onchange handler that sets the pref when the user changes the value of
295 * the input element.
296 * @private
297 */
298 onChange_: function(event) {
299 if (this.continuous)
300 this.setRangePref_();
301
302 if (this.notifyChange)
303 this.notifyChange(this, this.mapValueToRange_(this.value));
304 },
305
306 /**
307 * Sets the integer value of |pref| to the value of this element.
308 * @private
309 */
310 setRangePref_: function() {
311 Preferences.setIntegerPref(
312 this.pref, this.mapValueToRange_(this.value), this.metric);
313
314 if (this.notifyPrefChange)
315 this.notifyPrefChange(this, this.mapValueToRange_(this.value));
316 },
317
318 /**
319 * onkeyup/onmouseup handler that modifies the pref if |continuous| is
320 * false.
321 * @private
322 */
323 onInputUp_: function(event) {
324 if (!this.continuous)
325 this.setRangePref_();
326 },
327
328 /**
329 * Maps the value of this element into the range provided by the client,
330 * represented by |valueMap|.
331 * @param {number} value The value to map.
332 * @private
333 */
334 mapValueToRange_: function(value) {
335 return this.valueMap ? this.valueMap[value] : value;
336 },
337
338 /**
339 * Called when the client has specified non-continuous mode and the value of
340 * the range control changes.
341 * @param {Element} el This element.
342 * @param {number} value The value of this element.
343 */
344 notifyChange: function(el, value) {
345 },
346 };
347
348 /**
349 * The preference name.
350 * @type {string}
351 */
352 cr.defineProperty(PrefRange, 'pref', cr.PropertyKind.ATTR);
353
354 /**
355 * The user metric string.
356 * @type {string}
357 */
358 cr.defineProperty(PrefRange, 'metric', cr.PropertyKind.ATTR);
359
360 /////////////////////////////////////////////////////////////////////////////
361 // PrefSelect class:
362
363 // Define a constructor that uses a select element as its underlying element.
364 var PrefSelect = cr.ui.define('select');
365
366 PrefSelect.prototype = {
367 // Set up the prototype chain
368 __proto__: HTMLSelectElement.prototype,
369
370 /**
371 * Initialization function for the cr.ui framework.
372 */
373 decorate: function() {
374 var self = this;
375
376 // Listen to pref changes.
377 Preferences.getInstance().addEventListener(this.pref,
378 function(event) {
379 var value = event.value && event.value['value'] != undefined ?
380 event.value['value'] : event.value;
381
382 // Make sure |value| is a string, because the value is stored as a
383 // string in the HTMLOptionElement.
384 value = value.toString();
385
386 updateElementState_(self, event);
387
388 var found = false;
389 for (var i = 0; i < self.options.length; i++) {
390 if (self.options[i].value == value) {
391 self.selectedIndex = i;
392 found = true;
393 }
394 }
395
396 // Item not found, select first item.
397 if (!found)
398 self.selectedIndex = 0;
399
400 if (self.onchange != undefined)
401 self.onchange(event);
402 });
403
404 // Listen to user events.
405 this.addEventListener('change',
406 function(e) {
407 if (!self.dataType) {
408 console.error('undefined data type for <select> pref');
409 return;
410 }
411
412 switch(self.dataType) {
413 case 'number':
414 Preferences.setIntegerPref(self.pref,
415 self.options[self.selectedIndex].value, self.metric);
416 break;
417 case 'double':
418 Preferences.setDoublePref(self.pref,
419 self.options[self.selectedIndex].value, self.metric);
420 break;
421 case 'boolean':
422 var option = self.options[self.selectedIndex];
423 var value = (option.value == 'true') ? true : false;
424 Preferences.setBooleanPref(self.pref, value, self.metric);
425 break;
426 case 'string':
427 Preferences.setStringPref(self.pref,
428 self.options[self.selectedIndex].value, self.metric);
429 break;
430 default:
431 console.error('unknown data type for <select> pref: ' +
432 self.dataType);
433 }
434 });
435 },
436 };
437
438 /**
439 * The preference name.
440 * @type {string}
441 */
442 cr.defineProperty(PrefSelect, 'pref', cr.PropertyKind.ATTR);
443
444 /**
445 * The user metric string.
446 * @type {string}
447 */
448 cr.defineProperty(PrefSelect, 'metric', cr.PropertyKind.ATTR);
449
450 /**
451 * The data type for the preference options.
452 * @type {string}
453 */
454 cr.defineProperty(PrefSelect, 'dataType', cr.PropertyKind.ATTR);
455
456 /////////////////////////////////////////////////////////////////////////////
457 // PrefTextField class:
458
459 // Define a constructor that uses an input element as its underlying element.
460 var PrefTextField = cr.ui.define('input');
461
462 PrefTextField.prototype = {
463 // Set up the prototype chain
464 __proto__: HTMLInputElement.prototype,
465
466 /**
467 * Initialization function for the cr.ui framework.
468 */
469 decorate: function() {
470 var self = this;
471
472 // Listen to pref changes.
473 Preferences.getInstance().addEventListener(this.pref,
474 function(event) {
475 self.value = event.value && event.value['value'] != undefined ?
476 event.value['value'] : event.value;
477
478 updateElementState_(self, event);
479 });
480
481 // Listen to user events.
482 this.addEventListener('change',
483 function(e) {
484 switch(self.dataType) {
485 case 'number':
486 Preferences.setIntegerPref(self.pref, self.value, self.metric);
487 break;
488 case 'double':
489 Preferences.setDoublePref(self.pref, self.value, self.metric);
490 break;
491 default:
492 Preferences.setStringPref(self.pref, self.value, self.metric);
493 break;
494 }
495 });
496
497 window.addEventListener('unload',
498 function() {
499 if (document.activeElement == self)
500 self.blur();
501 });
502 }
503 };
504
505 /**
506 * The preference name.
507 * @type {string}
508 */
509 cr.defineProperty(PrefTextField, 'pref', cr.PropertyKind.ATTR);
510
511 /**
512 * The user metric string.
513 * @type {string}
514 */
515 cr.defineProperty(PrefTextField, 'metric', cr.PropertyKind.ATTR);
516
517 /**
518 * The data type for the preference options.
519 * @type {string}
520 */
521 cr.defineProperty(PrefTextField, 'dataType', cr.PropertyKind.ATTR);
522
523 // Export
524 return {
525 PrefCheckbox: PrefCheckbox,
526 PrefNumber: PrefNumber,
527 PrefNumeric: PrefNumeric,
528 PrefRadio: PrefRadio,
529 PrefRange: PrefRange,
530 PrefSelect: PrefSelect,
531 PrefTextField: PrefTextField
532 };
533
534 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698