1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/chrome/content/config.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,658 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +"use strict"; 1.8 + 1.9 +const {classes: Cc, interfaces: Ci, manager: Cm, utils: Cu} = Components; 1.10 +Cu.import("resource://gre/modules/Services.jsm"); 1.11 + 1.12 +const VKB_ENTER_KEY = 13; // User press of VKB enter key 1.13 +const INITIAL_PAGE_DELAY = 500; // Initial pause on program start for scroll alignment 1.14 +const PREFS_BUFFER_MAX = 30; // Max prefs buffer size for getPrefsBuffer() 1.15 +const PAGE_SCROLL_TRIGGER = 200; // Triggers additional getPrefsBuffer() on user scroll-to-bottom 1.16 +const FILTER_CHANGE_TRIGGER = 200; // Delay between responses to filterInput changes 1.17 +const INNERHTML_VALUE_DELAY = 100; // Delay before providing prefs innerHTML value 1.18 + 1.19 +let gStringBundle = Services.strings.createBundle("chrome://browser/locale/config.properties"); 1.20 +let gClipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); 1.21 + 1.22 + 1.23 +/* ============================== NewPrefDialog ============================== 1.24 + * 1.25 + * New Preference Dialog Object and methods 1.26 + * 1.27 + * Implements User Interfaces for creation of a single(new) Preference setting 1.28 + * 1.29 + */ 1.30 +var NewPrefDialog = { 1.31 + 1.32 + _prefsShield: null, 1.33 + 1.34 + _newPrefsDialog: null, 1.35 + _newPrefItem: null, 1.36 + _prefNameInputElt: null, 1.37 + _prefTypeSelectElt: null, 1.38 + 1.39 + _booleanValue: null, 1.40 + _booleanToggle: null, 1.41 + _stringValue: null, 1.42 + _intValue: null, 1.43 + 1.44 + _positiveButton: null, 1.45 + 1.46 + get type() { 1.47 + return this._prefTypeSelectElt.value; 1.48 + }, 1.49 + 1.50 + set type(aType) { 1.51 + this._prefTypeSelectElt.value = aType; 1.52 + switch(this._prefTypeSelectElt.value) { 1.53 + case "boolean": 1.54 + this._prefTypeSelectElt.selectedIndex = 0; 1.55 + break; 1.56 + case "string": 1.57 + this._prefTypeSelectElt.selectedIndex = 1; 1.58 + break; 1.59 + case "int": 1.60 + this._prefTypeSelectElt.selectedIndex = 2; 1.61 + break; 1.62 + } 1.63 + 1.64 + this._newPrefItem.setAttribute("typestyle", aType); 1.65 + }, 1.66 + 1.67 + // Init the NewPrefDialog 1.68 + init: function AC_init() { 1.69 + this._prefsShield = document.getElementById("prefs-shield"); 1.70 + 1.71 + this._newPrefsDialog = document.getElementById("new-pref-container"); 1.72 + this._newPrefItem = document.getElementById("new-pref-item"); 1.73 + this._prefNameInputElt = document.getElementById("new-pref-name"); 1.74 + this._prefTypeSelectElt = document.getElementById("new-pref-type"); 1.75 + 1.76 + this._booleanValue = document.getElementById("new-pref-value-boolean"); 1.77 + this._stringValue = document.getElementById("new-pref-value-string"); 1.78 + this._intValue = document.getElementById("new-pref-value-int"); 1.79 + 1.80 + this._positiveButton = document.getElementById("positive-button"); 1.81 + }, 1.82 + 1.83 + // Called to update positive button to display text ("Create"/"Change), and enabled/disabled status 1.84 + // As new pref name is initially displayed, re-focused, or modifed during user input 1.85 + _updatePositiveButton: function AC_updatePositiveButton(aPrefName) { 1.86 + this._positiveButton.textContent = gStringBundle.GetStringFromName("newPref.createButton"); 1.87 + this._positiveButton.setAttribute("disabled", true); 1.88 + if (aPrefName == "") { 1.89 + return; 1.90 + } 1.91 + 1.92 + // If item already in list, it's being changed, else added 1.93 + let item = document.querySelector(".pref-item[name=" + aPrefName.quote() + "]"); 1.94 + if (item) { 1.95 + this._positiveButton.textContent = gStringBundle.GetStringFromName("newPref.changeButton"); 1.96 + } else { 1.97 + this._positiveButton.removeAttribute("disabled"); 1.98 + } 1.99 + }, 1.100 + 1.101 + // When we want to cancel/hide an existing, or show a new pref dialog 1.102 + toggleShowHide: function AC_toggleShowHide() { 1.103 + if (this._newPrefsDialog.classList.contains("show")) { 1.104 + this.hide(); 1.105 + } else { 1.106 + this._show(); 1.107 + } 1.108 + }, 1.109 + 1.110 + // When we want to show the new pref dialog / shield the prefs list 1.111 + _show: function AC_show() { 1.112 + this._newPrefsDialog.classList.add("show"); 1.113 + this._prefsShield.setAttribute("shown", true); 1.114 + 1.115 + // Initial default field values 1.116 + this._prefNameInputElt.value = ""; 1.117 + this._updatePositiveButton(this._prefNameInputElt.value); 1.118 + 1.119 + this.type = "boolean"; 1.120 + this._booleanValue.value = "false"; 1.121 + this._stringValue.value = ""; 1.122 + this._intValue.value = ""; 1.123 + 1.124 + this._prefNameInputElt.focus(); 1.125 + 1.126 + window.addEventListener("keypress", this.handleKeypress, false); 1.127 + }, 1.128 + 1.129 + // When we want to cancel/hide the new pref dialog / un-shield the prefs list 1.130 + hide: function AC_hide() { 1.131 + this._newPrefsDialog.classList.remove("show"); 1.132 + this._prefsShield.removeAttribute("shown"); 1.133 + 1.134 + window.removeEventListener("keypress", this.handleKeypress, false); 1.135 + }, 1.136 + 1.137 + // Watch user key input so we can provide Enter key action, commit input values 1.138 + handleKeypress: function AC_handleKeypress(aEvent) { 1.139 + // Close our VKB on new pref enter key press 1.140 + if (aEvent.keyCode == VKB_ENTER_KEY) 1.141 + aEvent.target.blur(); 1.142 + }, 1.143 + 1.144 + // New prefs create dialog only allows creating a non-existing preference, doesn't allow for 1.145 + // Changing an existing one on-the-fly, tap existing/displayed line item pref for that 1.146 + create: function AC_create(aEvent) { 1.147 + if (this._positiveButton.getAttribute("disabled") == "true") { 1.148 + return; 1.149 + } 1.150 + 1.151 + switch(this.type) { 1.152 + case "boolean": 1.153 + Services.prefs.setBoolPref(this._prefNameInputElt.value, (this._booleanValue.value == "true") ? true : false); 1.154 + break; 1.155 + case "string": 1.156 + Services.prefs.setCharPref(this._prefNameInputElt.value, this._stringValue.value); 1.157 + break; 1.158 + case "int": 1.159 + Services.prefs.setIntPref(this._prefNameInputElt.value, this._intValue.value); 1.160 + break; 1.161 + } 1.162 + 1.163 + this.hide(); 1.164 + }, 1.165 + 1.166 + // Display proper positive button text/state on new prefs name input focus 1.167 + focusName: function AC_focusName(aEvent) { 1.168 + this._updatePositiveButton(aEvent.target.value); 1.169 + }, 1.170 + 1.171 + // Display proper positive button text/state as user changes new prefs name 1.172 + updateName: function AC_updateName(aEvent) { 1.173 + this._updatePositiveButton(aEvent.target.value); 1.174 + }, 1.175 + 1.176 + // In new prefs dialog, bool prefs are <input type="text">, as they aren't yet tied to an 1.177 + // Actual Services.prefs.*etBoolPref() 1.178 + toggleBoolValue: function AC_toggleBoolValue() { 1.179 + this._booleanValue.value = (this._booleanValue.value == "true" ? "false" : "true"); 1.180 + } 1.181 +} 1.182 + 1.183 + 1.184 +/* ============================== AboutConfig ============================== 1.185 + * 1.186 + * Main AboutConfig object and methods 1.187 + * 1.188 + * Implements User Interfaces for maintenance of a list of Preference settings 1.189 + * 1.190 + */ 1.191 +var AboutConfig = { 1.192 + 1.193 + contextMenuLINode: null, 1.194 + filterInput: null, 1.195 + _filterPrevInput: null, 1.196 + _filterChangeTimer: null, 1.197 + _prefsContainer: null, 1.198 + _loadingContainer: null, 1.199 + _list: null, 1.200 + 1.201 + // Init the main AboutConfig dialog 1.202 + init: function AC_init() { 1.203 + this.filterInput = document.getElementById("filter-input"); 1.204 + this._prefsContainer = document.getElementById("prefs-container"); 1.205 + this._loadingContainer = document.getElementById("loading-container"); 1.206 + 1.207 + let list = Services.prefs.getChildList(""); 1.208 + this._list = list.sort().map( function AC_getMapPref(aPref) { 1.209 + return new Pref(aPref); 1.210 + }, this); 1.211 + 1.212 + // Display the current prefs list (retains searchFilter value) 1.213 + this.bufferFilterInput(); 1.214 + 1.215 + // Setup the prefs observers 1.216 + Services.prefs.addObserver("", this, false); 1.217 + }, 1.218 + 1.219 + // Uninit the main AboutConfig dialog 1.220 + uninit: function AC_uninit() { 1.221 + // Remove the prefs observer 1.222 + Services.prefs.removeObserver("", this); 1.223 + 1.224 + // Ensure pref adds/changes/resets flushed to disk on unload 1.225 + Services.prefs.savePrefFile(null); 1.226 + }, 1.227 + 1.228 + // Clear the filterInput value, to display the entire list 1.229 + clearFilterInput: function AC_clearFilterInput() { 1.230 + this.filterInput.value = ""; 1.231 + this.bufferFilterInput(); 1.232 + }, 1.233 + 1.234 + // Buffer down rapid changes in filterInput value from keyboard 1.235 + bufferFilterInput: function AC_bufferFilterInput() { 1.236 + if (this._filterChangeTimer) { 1.237 + clearTimeout(this._filterChangeTimer); 1.238 + } 1.239 + 1.240 + this._filterChangeTimer = setTimeout((function() { 1.241 + this._filterChangeTimer = null; 1.242 + // Display updated prefs list when filterInput value settles 1.243 + this._displayNewList(); 1.244 + }).bind(this), FILTER_CHANGE_TRIGGER); 1.245 + }, 1.246 + 1.247 + // Update displayed list when filterInput value changes 1.248 + _displayNewList: function AC_displayNewList() { 1.249 + // This survives the search filter value past a page refresh 1.250 + this.filterInput.setAttribute("value", this.filterInput.value); 1.251 + 1.252 + // Don't start new filter search if same as last 1.253 + if (this.filterInput.value == this._filterPrevInput) { 1.254 + return; 1.255 + } 1.256 + this._filterPrevInput = this.filterInput.value; 1.257 + 1.258 + // Clear list item selection / context menu, prefs list, get first buffer, set scrolling on 1.259 + this.selected = ""; 1.260 + this._clearPrefsContainer(); 1.261 + this._addMorePrefsToContainer(); 1.262 + window.onscroll = this.onScroll.bind(this); 1.263 + 1.264 + // Pause for screen to settle, then ensure at top 1.265 + setTimeout((function() { 1.266 + window.scrollTo(0, 0); 1.267 + }).bind(this), INITIAL_PAGE_DELAY); 1.268 + }, 1.269 + 1.270 + // Clear the displayed preferences list 1.271 + _clearPrefsContainer: function AC_clearPrefsContainer() { 1.272 + // Quick clear the prefsContainer list 1.273 + let empty = this._prefsContainer.cloneNode(false); 1.274 + this._prefsContainer.parentNode.replaceChild(empty, this._prefsContainer); 1.275 + this._prefsContainer = empty; 1.276 + 1.277 + // Quick clear the prefs li.HTML list 1.278 + this._list.forEach(function(item) { 1.279 + delete item.li; 1.280 + }); 1.281 + }, 1.282 + 1.283 + // Get a small manageable block of prefs items, and add them to the displayed list 1.284 + _addMorePrefsToContainer: function AC_addMorePrefsToContainer() { 1.285 + // Create filter regex 1.286 + let filterExp = this.filterInput.value ? 1.287 + new RegExp(this.filterInput.value, "i") : null; 1.288 + 1.289 + // Get a new block for the display list 1.290 + let prefsBuffer = []; 1.291 + for (let i = 0; i < this._list.length && prefsBuffer.length < PREFS_BUFFER_MAX; i++) { 1.292 + if (!this._list[i].li && this._list[i].test(filterExp)) { 1.293 + prefsBuffer.push(this._list[i]); 1.294 + } 1.295 + } 1.296 + 1.297 + // Add the new block to the displayed list 1.298 + for (let i = 0; i < prefsBuffer.length; i++) { 1.299 + this._prefsContainer.appendChild(prefsBuffer[i].getOrCreateNewLINode()); 1.300 + } 1.301 + 1.302 + // Determine if anything left to add later by scrolling 1.303 + let anotherPrefsBufferRemains = false; 1.304 + for (let i = 0; i < this._list.length; i++) { 1.305 + if (!this._list[i].li && this._list[i].test(filterExp)) { 1.306 + anotherPrefsBufferRemains = true; 1.307 + break; 1.308 + } 1.309 + } 1.310 + 1.311 + if (anotherPrefsBufferRemains) { 1.312 + // If still more could be displayed, show the throbber 1.313 + this._loadingContainer.style.display = "block"; 1.314 + } else { 1.315 + // If no more could be displayed, hide the throbber, and stop noticing scroll events 1.316 + this._loadingContainer.style.display = "none"; 1.317 + window.onscroll = null; 1.318 + } 1.319 + }, 1.320 + 1.321 + // If scrolling at the bottom, maybe add some more entries 1.322 + onScroll: function AC_onScroll(aEvent) { 1.323 + if (this._prefsContainer.scrollHeight - (window.pageYOffset + window.innerHeight) < PAGE_SCROLL_TRIGGER) { 1.324 + if (!this._filterChangeTimer) { 1.325 + this._addMorePrefsToContainer(); 1.326 + } 1.327 + } 1.328 + }, 1.329 + 1.330 + 1.331 + // Return currently selected list item node 1.332 + get selected() { 1.333 + return document.querySelector(".pref-item.selected"); 1.334 + }, 1.335 + 1.336 + // Set list item node as selected 1.337 + set selected(aSelection) { 1.338 + let currentSelection = this.selected; 1.339 + if (aSelection == currentSelection) { 1.340 + return; 1.341 + } 1.342 + 1.343 + // Clear any previous selection 1.344 + if (currentSelection) { 1.345 + currentSelection.classList.remove("selected"); 1.346 + currentSelection.removeEventListener("keypress", this.handleKeypress, false); 1.347 + } 1.348 + 1.349 + // Set any current selection 1.350 + if (aSelection) { 1.351 + aSelection.classList.add("selected"); 1.352 + aSelection.addEventListener("keypress", this.handleKeypress, false); 1.353 + } 1.354 + }, 1.355 + 1.356 + // Watch user key input so we can provide Enter key action, commit input values 1.357 + handleKeypress: function AC_handleKeypress(aEvent) { 1.358 + if (aEvent.keyCode == VKB_ENTER_KEY) 1.359 + aEvent.target.blur(); 1.360 + }, 1.361 + 1.362 + // Return the target list item node of an action event 1.363 + getLINodeForEvent: function AC_getLINodeForEvent(aEvent) { 1.364 + let node = aEvent.target; 1.365 + while (node && node.nodeName != "li") { 1.366 + node = node.parentNode; 1.367 + } 1.368 + 1.369 + return node; 1.370 + }, 1.371 + 1.372 + // Return a pref of a list item node 1.373 + _getPrefForNode: function AC_getPrefForNode(aNode) { 1.374 + let pref = aNode.getAttribute("name"); 1.375 + 1.376 + return new Pref(pref); 1.377 + }, 1.378 + 1.379 + // When list item name or value are tapped 1.380 + selectOrToggleBoolPref: function AC_selectOrToggleBoolPref(aEvent) { 1.381 + let node = this.getLINodeForEvent(aEvent); 1.382 + 1.383 + // If not already selected, just do so 1.384 + if (this.selected != node) { 1.385 + this.selected = node; 1.386 + return; 1.387 + } 1.388 + 1.389 + // If already selected, and value is boolean, toggle it 1.390 + let pref = this._getPrefForNode(node); 1.391 + if (pref.type != Services.prefs.PREF_BOOL) { 1.392 + return; 1.393 + } 1.394 + 1.395 + this.toggleBoolPref(aEvent); 1.396 + }, 1.397 + 1.398 + // When finalizing list input values due to blur 1.399 + setIntOrStringPref: function AC_setIntOrStringPref(aEvent) { 1.400 + let node = this.getLINodeForEvent(aEvent); 1.401 + 1.402 + // Skip if locked 1.403 + let pref = this._getPrefForNode(node); 1.404 + if (pref.locked) { 1.405 + return; 1.406 + } 1.407 + 1.408 + // Boolean inputs blur to remove focus from "button" 1.409 + if (pref.type == Services.prefs.PREF_BOOL) { 1.410 + return; 1.411 + } 1.412 + 1.413 + // String and Int inputs change / commit on blur 1.414 + pref.value = aEvent.target.value; 1.415 + }, 1.416 + 1.417 + // When we reset a pref to it's default value (note resetting a user created pref will delete it) 1.418 + resetDefaultPref: function AC_resetDefaultPref(aEvent) { 1.419 + let node = this.getLINodeForEvent(aEvent); 1.420 + 1.421 + // If not already selected, do so 1.422 + if (this.selected != node) { 1.423 + this.selected = node; 1.424 + } 1.425 + 1.426 + // Reset will handle any locked condition 1.427 + let pref = this._getPrefForNode(node); 1.428 + pref.reset(); 1.429 + }, 1.430 + 1.431 + // When we want to toggle a bool pref 1.432 + toggleBoolPref: function AC_toggleBoolPref(aEvent) { 1.433 + let node = this.getLINodeForEvent(aEvent); 1.434 + 1.435 + // Skip if locked, or not boolean 1.436 + let pref = this._getPrefForNode(node); 1.437 + if (pref.locked) { 1.438 + return; 1.439 + } 1.440 + 1.441 + // Toggle, and blur to remove field focus 1.442 + pref.value = !pref.value; 1.443 + aEvent.target.blur(); 1.444 + }, 1.445 + 1.446 + // When Int inputs have their Up or Down arrows toggled 1.447 + incrOrDecrIntPref: function AC_incrOrDecrIntPref(aEvent, aInt) { 1.448 + let node = this.getLINodeForEvent(aEvent); 1.449 + 1.450 + // Skip if locked 1.451 + let pref = this._getPrefForNode(node); 1.452 + if (pref.locked) { 1.453 + return; 1.454 + } 1.455 + 1.456 + pref.value += aInt; 1.457 + }, 1.458 + 1.459 + // Observe preference changes 1.460 + observe: function AC_observe(aSubject, aTopic, aPrefName) { 1.461 + let pref = new Pref(aPrefName); 1.462 + 1.463 + // Ignore uninteresting changes, and avoid "private" preferences 1.464 + if (aTopic != "nsPref:changed") { 1.465 + return; 1.466 + } 1.467 + 1.468 + // If pref type invalid, refresh display as user reset/removed an item from the list 1.469 + if (pref.type == Services.prefs.PREF_INVALID) { 1.470 + document.location.reload(); 1.471 + return; 1.472 + } 1.473 + 1.474 + // If pref not already in list, refresh display as it's being added 1.475 + let item = document.querySelector(".pref-item[name=" + pref.name.quote() + "]"); 1.476 + if (!item) { 1.477 + document.location.reload(); 1.478 + return; 1.479 + } 1.480 + 1.481 + // Else we're modifying a pref 1.482 + item.setAttribute("value", pref.value); 1.483 + let input = item.querySelector("input"); 1.484 + input.setAttribute("value", pref.value); 1.485 + input.value = pref.value; 1.486 + 1.487 + pref.default ? 1.488 + item.querySelector(".reset").setAttribute("disabled", "true") : 1.489 + item.querySelector(".reset").removeAttribute("disabled"); 1.490 + }, 1.491 + 1.492 + // Quick context menu helpers for about:config 1.493 + clipboardCopy: function AC_clipboardCopy(aField) { 1.494 + let pref = this._getPrefForNode(this.contextMenuLINode); 1.495 + if (aField == 'name') { 1.496 + gClipboardHelper.copyString(pref.name); 1.497 + } else { 1.498 + gClipboardHelper.copyString(pref.value); 1.499 + } 1.500 + } 1.501 +} 1.502 + 1.503 + 1.504 +/* ============================== Pref ============================== 1.505 + * 1.506 + * Individual Preference object / methods 1.507 + * 1.508 + * Defines a Pref object, a document list item tied to Preferences Services 1.509 + * And the methods by which they interact. 1.510 + * 1.511 + */ 1.512 +function Pref(aName) { 1.513 + this.name = aName; 1.514 +} 1.515 + 1.516 +Pref.prototype = { 1.517 + get type() { 1.518 + return Services.prefs.getPrefType(this.name); 1.519 + }, 1.520 + 1.521 + get value() { 1.522 + switch (this.type) { 1.523 + case Services.prefs.PREF_BOOL: 1.524 + return Services.prefs.getBoolPref(this.name); 1.525 + case Services.prefs.PREF_INT: 1.526 + return Services.prefs.getIntPref(this.name); 1.527 + case Services.prefs.PREF_STRING: 1.528 + default: 1.529 + return Services.prefs.getCharPref(this.name); 1.530 + } 1.531 + 1.532 + }, 1.533 + set value(aPrefValue) { 1.534 + switch (this.type) { 1.535 + case Services.prefs.PREF_BOOL: 1.536 + Services.prefs.setBoolPref(this.name, aPrefValue); 1.537 + break; 1.538 + case Services.prefs.PREF_INT: 1.539 + Services.prefs.setIntPref(this.name, aPrefValue); 1.540 + break; 1.541 + case Services.prefs.PREF_STRING: 1.542 + default: 1.543 + Services.prefs.setCharPref(this.name, aPrefValue); 1.544 + } 1.545 + }, 1.546 + 1.547 + get default() { 1.548 + return !Services.prefs.prefHasUserValue(this.name); 1.549 + }, 1.550 + 1.551 + get locked() { 1.552 + return Services.prefs.prefIsLocked(this.name); 1.553 + }, 1.554 + 1.555 + reset: function AC_reset() { 1.556 + Services.prefs.clearUserPref(this.name); 1.557 + }, 1.558 + 1.559 + test: function AC_test(aValue) { 1.560 + return aValue ? aValue.test(this.name) : true; 1.561 + }, 1.562 + 1.563 + // Get existing or create new LI node for the pref 1.564 + getOrCreateNewLINode: function AC_getOrCreateNewLINode() { 1.565 + if (!this.li) { 1.566 + this.li = document.createElement("li"); 1.567 + 1.568 + this.li.className = "pref-item"; 1.569 + this.li.setAttribute("name", this.name); 1.570 + 1.571 + // Click callback to ensure list item selected even on no-action tap events 1.572 + this.li.addEventListener("click", 1.573 + function(aEvent) { 1.574 + AboutConfig.selected = AboutConfig.getLINodeForEvent(aEvent); 1.575 + }, 1.576 + false 1.577 + ); 1.578 + 1.579 + // Contextmenu callback to identify selected list item 1.580 + this.li.addEventListener("contextmenu", 1.581 + function(aEvent) { 1.582 + AboutConfig.contextMenuLINode = AboutConfig.getLINodeForEvent(aEvent); 1.583 + }, 1.584 + false 1.585 + ); 1.586 + 1.587 + this.li.setAttribute("contextmenu", "prefs-context-menu"); 1.588 + 1.589 + // Create list item outline, bind to object actions 1.590 + this.li.innerHTML = 1.591 + "<div class='pref-name' " + 1.592 + "onclick='AboutConfig.selectOrToggleBoolPref(event);'>" + 1.593 + this.name + 1.594 + "</div>" + 1.595 + "<div class='pref-item-line'>" + 1.596 + "<input class='pref-value' value='' " + 1.597 + "onblur='AboutConfig.setIntOrStringPref(event);' " + 1.598 + "onclick='AboutConfig.selectOrToggleBoolPref(event);'>" + 1.599 + "</input>" + 1.600 + "<div class='pref-button reset' " + 1.601 + "onclick='AboutConfig.resetDefaultPref(event);'>" + 1.602 + gStringBundle.GetStringFromName("pref.resetButton") + 1.603 + "</div>" + 1.604 + "<div class='pref-button toggle' " + 1.605 + "onclick='AboutConfig.toggleBoolPref(event);'>" + 1.606 + gStringBundle.GetStringFromName("pref.toggleButton") + 1.607 + "</div>" + 1.608 + "<div class='pref-button up' " + 1.609 + "onclick='AboutConfig.incrOrDecrIntPref(event, 1);'>" + 1.610 + "</div>" + 1.611 + "<div class='pref-button down' " + 1.612 + "onclick='AboutConfig.incrOrDecrIntPref(event, -1);'>" + 1.613 + "</div>" + 1.614 + "</div>"; 1.615 + 1.616 + // Delay providing the list item values, until the LI is returned and added to the document 1.617 + setTimeout(this._valueSetup.bind(this), INNERHTML_VALUE_DELAY); 1.618 + } 1.619 + 1.620 + return this.li; 1.621 + }, 1.622 + 1.623 + // Initialize list item object values 1.624 + _valueSetup: function AC_valueSetup() { 1.625 + 1.626 + this.li.setAttribute("type", this.type); 1.627 + this.li.setAttribute("value", this.value); 1.628 + 1.629 + let valDiv = this.li.querySelector(".pref-value"); 1.630 + valDiv.value = this.value; 1.631 + 1.632 + switch(this.type) { 1.633 + case Services.prefs.PREF_BOOL: 1.634 + valDiv.setAttribute("type", "button"); 1.635 + this.li.querySelector(".up").setAttribute("disabled", true); 1.636 + this.li.querySelector(".down").setAttribute("disabled", true); 1.637 + break; 1.638 + case Services.prefs.PREF_STRING: 1.639 + valDiv.setAttribute("type", "text"); 1.640 + this.li.querySelector(".up").setAttribute("disabled", true); 1.641 + this.li.querySelector(".down").setAttribute("disabled", true); 1.642 + this.li.querySelector(".toggle").setAttribute("disabled", true); 1.643 + break; 1.644 + case Services.prefs.PREF_INT: 1.645 + valDiv.setAttribute("type", "number"); 1.646 + this.li.querySelector(".toggle").setAttribute("disabled", true); 1.647 + break; 1.648 + } 1.649 + 1.650 + this.li.setAttribute("default", this.default); 1.651 + if (this.default) { 1.652 + this.li.querySelector(".reset").setAttribute("disabled", true); 1.653 + } 1.654 + 1.655 + if (this.locked) { 1.656 + valDiv.setAttribute("disabled", this.locked); 1.657 + this.li.querySelector(".pref-name").setAttribute("locked", true); 1.658 + } 1.659 + } 1.660 +} 1.661 +