1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/viewconfig/content/config.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,637 @@ 1.4 +// -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +Components.utils.import("resource://gre/modules/Services.jsm"); 1.11 + 1.12 +const nsIPrefLocalizedString = Components.interfaces.nsIPrefLocalizedString; 1.13 +const nsISupportsString = Components.interfaces.nsISupportsString; 1.14 +const nsIPrefBranch = Components.interfaces.nsIPrefBranch; 1.15 +const nsIClipboardHelper = Components.interfaces.nsIClipboardHelper; 1.16 +const nsIAtomService = Components.interfaces.nsIAtomService; 1.17 + 1.18 +const nsSupportsString_CONTRACTID = "@mozilla.org/supports-string;1"; 1.19 +const nsPrompt_CONTRACTID = "@mozilla.org/embedcomp/prompt-service;1"; 1.20 +const nsPrefService_CONTRACTID = "@mozilla.org/preferences-service;1"; 1.21 +const nsClipboardHelper_CONTRACTID = "@mozilla.org/widget/clipboardhelper;1"; 1.22 +const nsAtomService_CONTRACTID = "@mozilla.org/atom-service;1"; 1.23 + 1.24 +const gPrefBranch = Services.prefs; 1.25 +const gClipboardHelper = Components.classes[nsClipboardHelper_CONTRACTID].getService(nsIClipboardHelper); 1.26 +const gAtomService = Components.classes[nsAtomService_CONTRACTID].getService(nsIAtomService); 1.27 + 1.28 +var gLockProps = ["default", "user", "locked"]; 1.29 +// we get these from a string bundle 1.30 +var gLockStrs = []; 1.31 +var gTypeStrs = []; 1.32 + 1.33 +const PREF_IS_DEFAULT_VALUE = 0; 1.34 +const PREF_IS_USER_SET = 1; 1.35 +const PREF_IS_LOCKED = 2; 1.36 + 1.37 +var gPrefHash = {}; 1.38 +var gPrefArray = []; 1.39 +var gPrefView = gPrefArray; // share the JS array 1.40 +var gSortedColumn = "prefCol"; 1.41 +var gSortFunction = null; 1.42 +var gSortDirection = 1; // 1 is ascending; -1 is descending 1.43 +var gConfigBundle = null; 1.44 +var gFilter = null; 1.45 + 1.46 +var view = { 1.47 + get rowCount() { return gPrefView.length; }, 1.48 + getCellText : function(index, col) { 1.49 + if (!(index in gPrefView)) 1.50 + return ""; 1.51 + 1.52 + var value = gPrefView[index][col.id]; 1.53 + 1.54 + switch (col.id) { 1.55 + case "lockCol": 1.56 + return gLockStrs[value]; 1.57 + case "typeCol": 1.58 + return gTypeStrs[value]; 1.59 + default: 1.60 + return value; 1.61 + } 1.62 + }, 1.63 + getRowProperties : function(index) { return ""; }, 1.64 + getCellProperties : function(index, col) { 1.65 + if (index in gPrefView) 1.66 + return gLockProps[gPrefView[index].lockCol]; 1.67 + 1.68 + return ""; 1.69 + }, 1.70 + getColumnProperties : function(col) { return ""; }, 1.71 + treebox : null, 1.72 + selection : null, 1.73 + isContainer : function(index) { return false; }, 1.74 + isContainerOpen : function(index) { return false; }, 1.75 + isContainerEmpty : function(index) { return false; }, 1.76 + isSorted : function() { return true; }, 1.77 + canDrop : function(index, orientation) { return false; }, 1.78 + drop : function(row, orientation) {}, 1.79 + setTree : function(out) { this.treebox = out; }, 1.80 + getParentIndex: function(rowIndex) { return -1; }, 1.81 + hasNextSibling: function(rowIndex, afterIndex) { return false; }, 1.82 + getLevel: function(index) { return 1; }, 1.83 + getImageSrc: function(row, col) { return ""; }, 1.84 + toggleOpenState : function(index) {}, 1.85 + cycleHeader: function(col) { 1.86 + var index = this.selection.currentIndex; 1.87 + if (col.id == gSortedColumn) { 1.88 + gSortDirection = -gSortDirection; 1.89 + gPrefArray.reverse(); 1.90 + if (gPrefView != gPrefArray) 1.91 + gPrefView.reverse(); 1.92 + if (index >= 0) 1.93 + index = gPrefView.length - index - 1; 1.94 + } 1.95 + else { 1.96 + var pref = null; 1.97 + if (index >= 0) 1.98 + pref = gPrefView[index]; 1.99 + 1.100 + var old = document.getElementById(gSortedColumn); 1.101 + old.setAttribute("sortDirection", ""); 1.102 + gPrefArray.sort(gSortFunction = gSortFunctions[col.id]); 1.103 + if (gPrefView != gPrefArray) 1.104 + gPrefView.sort(gSortFunction); 1.105 + gSortedColumn = col.id; 1.106 + if (pref) 1.107 + index = getViewIndexOfPref(pref); 1.108 + } 1.109 + col.element.setAttribute("sortDirection", gSortDirection > 0 ? "ascending" : "descending"); 1.110 + this.treebox.invalidate(); 1.111 + if (index >= 0) { 1.112 + this.selection.select(index); 1.113 + this.treebox.ensureRowIsVisible(index); 1.114 + } 1.115 + }, 1.116 + selectionChanged : function() {}, 1.117 + cycleCell: function(row, col) {}, 1.118 + isEditable: function(row, col) {return false; }, 1.119 + isSelectable: function(row, col) {return false; }, 1.120 + setCellValue: function(row, col, value) {}, 1.121 + setCellText: function(row, col, value) {}, 1.122 + performAction: function(action) {}, 1.123 + performActionOnRow: function(action, row) {}, 1.124 + performActionOnCell: function(action, row, col) {}, 1.125 + isSeparator: function(index) {return false; } 1.126 +}; 1.127 + 1.128 +// find the index in gPrefView of a pref object 1.129 +// or -1 if it does not exist in the filtered view 1.130 +function getViewIndexOfPref(pref) 1.131 +{ 1.132 + var low = -1, high = gPrefView.length; 1.133 + var index = (low + high) >> 1; 1.134 + while (index > low) { 1.135 + var mid = gPrefView[index]; 1.136 + if (mid == pref) 1.137 + return index; 1.138 + if (gSortFunction(mid, pref) < 0) 1.139 + low = index; 1.140 + else 1.141 + high = index; 1.142 + index = (low + high) >> 1; 1.143 + } 1.144 + return -1; 1.145 +} 1.146 + 1.147 +// find the index in gPrefView where a pref object belongs 1.148 +function getNearestViewIndexOfPref(pref) 1.149 +{ 1.150 + var low = -1, high = gPrefView.length; 1.151 + var index = (low + high) >> 1; 1.152 + while (index > low) { 1.153 + if (gSortFunction(gPrefView[index], pref) < 0) 1.154 + low = index; 1.155 + else 1.156 + high = index; 1.157 + index = (low + high) >> 1; 1.158 + } 1.159 + return high; 1.160 +} 1.161 + 1.162 +// find the index in gPrefArray of a pref object 1.163 +function getIndexOfPref(pref) 1.164 +{ 1.165 + var low = -1, high = gPrefArray.length; 1.166 + var index = (low + high) >> 1; 1.167 + while (index > low) { 1.168 + var mid = gPrefArray[index]; 1.169 + if (mid == pref) 1.170 + return index; 1.171 + if (gSortFunction(mid, pref) < 0) 1.172 + low = index; 1.173 + else 1.174 + high = index; 1.175 + index = (low + high) >> 1; 1.176 + } 1.177 + return index; 1.178 +} 1.179 + 1.180 +function getNearestIndexOfPref(pref) 1.181 +{ 1.182 + var low = -1, high = gPrefArray.length; 1.183 + var index = (low + high) >> 1; 1.184 + while (index > low) { 1.185 + if (gSortFunction(gPrefArray[index], pref) < 0) 1.186 + low = index; 1.187 + else 1.188 + high = index; 1.189 + index = (low + high) >> 1; 1.190 + } 1.191 + return high; 1.192 +} 1.193 + 1.194 +var gPrefListener = 1.195 +{ 1.196 + observe: function(subject, topic, prefName) 1.197 + { 1.198 + if (topic != "nsPref:changed") 1.199 + return; 1.200 + 1.201 + var arrayIndex = gPrefArray.length; 1.202 + var viewIndex = arrayIndex; 1.203 + var selectedIndex = view.selection.currentIndex; 1.204 + var pref; 1.205 + var updateView = false; 1.206 + var updateArray = false; 1.207 + var addedRow = false; 1.208 + if (prefName in gPrefHash) { 1.209 + pref = gPrefHash[prefName]; 1.210 + viewIndex = getViewIndexOfPref(pref); 1.211 + arrayIndex = getIndexOfPref(pref); 1.212 + fetchPref(prefName, arrayIndex); 1.213 + // fetchPref replaces the existing pref object 1.214 + pref = gPrefHash[prefName]; 1.215 + if (viewIndex >= 0) { 1.216 + // Might need to update the filtered view 1.217 + gPrefView[viewIndex] = gPrefHash[prefName]; 1.218 + view.treebox.invalidateRow(viewIndex); 1.219 + } 1.220 + if (gSortedColumn == "lockCol" || gSortedColumn == "valueCol") { 1.221 + updateArray = true; 1.222 + gPrefArray.splice(arrayIndex, 1); 1.223 + if (gFilter && gFilter.test(pref.prefCol + ";" + pref.valueCol)) { 1.224 + updateView = true; 1.225 + gPrefView.splice(viewIndex, 1); 1.226 + } 1.227 + } 1.228 + } 1.229 + else { 1.230 + fetchPref(prefName, arrayIndex); 1.231 + pref = gPrefArray.pop(); 1.232 + updateArray = true; 1.233 + addedRow = true; 1.234 + if (gFilter && gFilter.test(pref.prefCol + ";" + pref.valueCol)) { 1.235 + updateView = true; 1.236 + } 1.237 + } 1.238 + if (updateArray) { 1.239 + // Reinsert in the data array 1.240 + var newIndex = getNearestIndexOfPref(pref); 1.241 + gPrefArray.splice(newIndex, 0, pref); 1.242 + 1.243 + if (updateView) { 1.244 + // View is filtered, reinsert in the view separately 1.245 + newIndex = getNearestViewIndexOfPref(pref); 1.246 + gPrefView.splice(newIndex, 0, pref); 1.247 + } 1.248 + else if (gFilter) { 1.249 + // View is filtered, but nothing to update 1.250 + return; 1.251 + } 1.252 + 1.253 + if (addedRow) 1.254 + view.treebox.rowCountChanged(newIndex, 1); 1.255 + 1.256 + // Invalidate the changed range in the view 1.257 + var low = Math.min(viewIndex, newIndex); 1.258 + var high = Math.max(viewIndex, newIndex); 1.259 + view.treebox.invalidateRange(low, high); 1.260 + 1.261 + if (selectedIndex == viewIndex) { 1.262 + selectedIndex = newIndex; 1.263 + } 1.264 + else if (selectedIndex >= low && selectedIndex <= high) { 1.265 + selectedIndex += (newIndex > viewIndex) ? -1 : 1; 1.266 + } 1.267 + if (selectedIndex >= 0) { 1.268 + view.selection.select(selectedIndex); 1.269 + if (selectedIndex == newIndex) 1.270 + view.treebox.ensureRowIsVisible(selectedIndex); 1.271 + } 1.272 + } 1.273 + } 1.274 +}; 1.275 + 1.276 +function prefObject(prefName, prefIndex) 1.277 +{ 1.278 + this.prefCol = prefName; 1.279 +} 1.280 + 1.281 +prefObject.prototype = 1.282 +{ 1.283 + lockCol: PREF_IS_DEFAULT_VALUE, 1.284 + typeCol: nsIPrefBranch.PREF_STRING, 1.285 + valueCol: "" 1.286 +}; 1.287 + 1.288 +function fetchPref(prefName, prefIndex) 1.289 +{ 1.290 + var pref = new prefObject(prefName); 1.291 + 1.292 + gPrefHash[prefName] = pref; 1.293 + gPrefArray[prefIndex] = pref; 1.294 + 1.295 + if (gPrefBranch.prefIsLocked(prefName)) 1.296 + pref.lockCol = PREF_IS_LOCKED; 1.297 + else if (gPrefBranch.prefHasUserValue(prefName)) 1.298 + pref.lockCol = PREF_IS_USER_SET; 1.299 + 1.300 + try { 1.301 + switch (gPrefBranch.getPrefType(prefName)) { 1.302 + case gPrefBranch.PREF_BOOL: 1.303 + pref.typeCol = gPrefBranch.PREF_BOOL; 1.304 + // convert to a string 1.305 + pref.valueCol = gPrefBranch.getBoolPref(prefName).toString(); 1.306 + break; 1.307 + case gPrefBranch.PREF_INT: 1.308 + pref.typeCol = gPrefBranch.PREF_INT; 1.309 + // convert to a string 1.310 + pref.valueCol = gPrefBranch.getIntPref(prefName).toString(); 1.311 + break; 1.312 + default: 1.313 + case gPrefBranch.PREF_STRING: 1.314 + pref.valueCol = gPrefBranch.getComplexValue(prefName, nsISupportsString).data; 1.315 + // Try in case it's a localized string (will throw an exception if not) 1.316 + if (pref.lockCol == PREF_IS_DEFAULT_VALUE && 1.317 + /^chrome:\/\/.+\/locale\/.+\.properties/.test(pref.valueCol)) 1.318 + pref.valueCol = gPrefBranch.getComplexValue(prefName, nsIPrefLocalizedString).data; 1.319 + break; 1.320 + } 1.321 + } catch (e) { 1.322 + // Also catch obscure cases in which you can't tell in advance 1.323 + // that the pref exists but has no user or default value... 1.324 + } 1.325 +} 1.326 + 1.327 +function onConfigLoad() 1.328 +{ 1.329 + // Load strings 1.330 + gConfigBundle = document.getElementById("configBundle"); 1.331 + 1.332 + gLockStrs[PREF_IS_DEFAULT_VALUE] = gConfigBundle.getString("default"); 1.333 + gLockStrs[PREF_IS_USER_SET] = gConfigBundle.getString("user"); 1.334 + gLockStrs[PREF_IS_LOCKED] = gConfigBundle.getString("locked"); 1.335 + 1.336 + gTypeStrs[nsIPrefBranch.PREF_STRING] = gConfigBundle.getString("string"); 1.337 + gTypeStrs[nsIPrefBranch.PREF_INT] = gConfigBundle.getString("int"); 1.338 + gTypeStrs[nsIPrefBranch.PREF_BOOL] = gConfigBundle.getString("bool"); 1.339 + 1.340 + var showWarning = gPrefBranch.getBoolPref("general.warnOnAboutConfig"); 1.341 + 1.342 + if (showWarning) 1.343 + document.getElementById("warningButton").focus(); 1.344 + else 1.345 + ShowPrefs(); 1.346 +} 1.347 + 1.348 +// Unhide the warning message 1.349 +function ShowPrefs() 1.350 +{ 1.351 + gPrefBranch.getChildList("").forEach(fetchPref); 1.352 + 1.353 + var descending = document.getElementsByAttribute("sortDirection", "descending"); 1.354 + if (descending.item(0)) { 1.355 + gSortedColumn = descending[0].id; 1.356 + gSortDirection = -1; 1.357 + } 1.358 + else { 1.359 + var ascending = document.getElementsByAttribute("sortDirection", "ascending"); 1.360 + if (ascending.item(0)) 1.361 + gSortedColumn = ascending[0].id; 1.362 + else 1.363 + document.getElementById(gSortedColumn).setAttribute("sortDirection", "ascending"); 1.364 + } 1.365 + gSortFunction = gSortFunctions[gSortedColumn]; 1.366 + gPrefArray.sort(gSortFunction); 1.367 + 1.368 + gPrefBranch.addObserver("", gPrefListener, false); 1.369 + 1.370 + var configTree = document.getElementById("configTree"); 1.371 + configTree.view = view; 1.372 + configTree.controllers.insertControllerAt(0, configController); 1.373 + 1.374 + document.getElementById("configDeck").setAttribute("selectedIndex", 1); 1.375 + document.getElementById("configTreeKeyset").removeAttribute("disabled"); 1.376 + if (!document.getElementById("showWarningNextTime").checked) 1.377 + gPrefBranch.setBoolPref("general.warnOnAboutConfig", false); 1.378 + 1.379 + // Process about:config?filter=<string> 1.380 + var textbox = document.getElementById("textbox"); 1.381 + // About URIs don't support query params, so do this manually 1.382 + var loc = document.location.href; 1.383 + var matches = /[?&]filter\=([^&]+)/i.exec(loc); 1.384 + if (matches) 1.385 + textbox.value = decodeURIComponent(matches[1]); 1.386 + 1.387 + // Even if we did not set the filter string via the URL query, 1.388 + // textbox might have been set via some other mechanism 1.389 + if (textbox.value) 1.390 + FilterPrefs(); 1.391 + textbox.focus(); 1.392 +} 1.393 + 1.394 +function onConfigUnload() 1.395 +{ 1.396 + if (document.getElementById("configDeck").getAttribute("selectedIndex") == 1) { 1.397 + gPrefBranch.removeObserver("", gPrefListener); 1.398 + var configTree = document.getElementById("configTree"); 1.399 + configTree.view = null; 1.400 + configTree.controllers.removeController(configController); 1.401 + } 1.402 +} 1.403 + 1.404 +function FilterPrefs() 1.405 +{ 1.406 + if (document.getElementById("configDeck").getAttribute("selectedIndex") != 1) { 1.407 + return; 1.408 + } 1.409 + 1.410 + var substring = document.getElementById("textbox").value; 1.411 + // Check for "/regex/[i]" 1.412 + if (substring.charAt(0) == '/') { 1.413 + var r = substring.match(/^\/(.*)\/(i?)$/); 1.414 + try { 1.415 + gFilter = RegExp(r[1], r[2]); 1.416 + } 1.417 + catch (e) { 1.418 + return; // Do nothing on incomplete or bad RegExp 1.419 + } 1.420 + } 1.421 + else if (substring) { 1.422 + gFilter = RegExp(substring.replace(/([^* \w])/g, "\\$1") 1.423 + .replace(/^\*+/, "").replace(/\*+/g, ".*"), "i"); 1.424 + } else { 1.425 + gFilter = null; 1.426 + } 1.427 + 1.428 + var prefCol = (view.selection && view.selection.currentIndex < 0) ? 1.429 + null : gPrefView[view.selection.currentIndex].prefCol; 1.430 + var oldlen = gPrefView.length; 1.431 + gPrefView = gPrefArray; 1.432 + if (gFilter) { 1.433 + gPrefView = []; 1.434 + for (var i = 0; i < gPrefArray.length; ++i) 1.435 + if (gFilter.test(gPrefArray[i].prefCol + ";" + gPrefArray[i].valueCol)) 1.436 + gPrefView.push(gPrefArray[i]); 1.437 + } 1.438 + view.treebox.invalidate(); 1.439 + view.treebox.rowCountChanged(oldlen, gPrefView.length - oldlen); 1.440 + gotoPref(prefCol); 1.441 +} 1.442 + 1.443 +function prefColSortFunction(x, y) 1.444 +{ 1.445 + if (x.prefCol > y.prefCol) 1.446 + return gSortDirection; 1.447 + if (x.prefCol < y.prefCol) 1.448 + return -gSortDirection; 1.449 + return 0; 1.450 +} 1.451 + 1.452 +function lockColSortFunction(x, y) 1.453 +{ 1.454 + if (x.lockCol != y.lockCol) 1.455 + return gSortDirection * (y.lockCol - x.lockCol); 1.456 + return prefColSortFunction(x, y); 1.457 +} 1.458 + 1.459 +function typeColSortFunction(x, y) 1.460 +{ 1.461 + if (x.typeCol != y.typeCol) 1.462 + return gSortDirection * (y.typeCol - x.typeCol); 1.463 + return prefColSortFunction(x, y); 1.464 +} 1.465 + 1.466 +function valueColSortFunction(x, y) 1.467 +{ 1.468 + if (x.valueCol > y.valueCol) 1.469 + return gSortDirection; 1.470 + if (x.valueCol < y.valueCol) 1.471 + return -gSortDirection; 1.472 + return prefColSortFunction(x, y); 1.473 +} 1.474 + 1.475 +const gSortFunctions = 1.476 +{ 1.477 + prefCol: prefColSortFunction, 1.478 + lockCol: lockColSortFunction, 1.479 + typeCol: typeColSortFunction, 1.480 + valueCol: valueColSortFunction 1.481 +}; 1.482 + 1.483 +const configController = { 1.484 + supportsCommand: function supportsCommand(command) { 1.485 + return command == "cmd_copy"; 1.486 + }, 1.487 + isCommandEnabled: function isCommandEnabled(command) { 1.488 + return view.selection && view.selection.currentIndex >= 0; 1.489 + }, 1.490 + doCommand: function doCommand(command) { 1.491 + copyPref(); 1.492 + }, 1.493 + onEvent: function onEvent(event) { 1.494 + } 1.495 +} 1.496 + 1.497 +function updateContextMenu() 1.498 +{ 1.499 + var lockCol = PREF_IS_LOCKED; 1.500 + var typeCol = nsIPrefBranch.PREF_STRING; 1.501 + var valueCol = ""; 1.502 + var copyDisabled = true; 1.503 + var prefSelected = view.selection.currentIndex >= 0; 1.504 + 1.505 + if (prefSelected) { 1.506 + var prefRow = gPrefView[view.selection.currentIndex]; 1.507 + lockCol = prefRow.lockCol; 1.508 + typeCol = prefRow.typeCol; 1.509 + valueCol = prefRow.valueCol; 1.510 + copyDisabled = false; 1.511 + } 1.512 + 1.513 + var copyPref = document.getElementById("copyPref"); 1.514 + copyPref.setAttribute("disabled", copyDisabled); 1.515 + 1.516 + var copyName = document.getElementById("copyName"); 1.517 + copyName.setAttribute("disabled", copyDisabled); 1.518 + 1.519 + var copyValue = document.getElementById("copyValue"); 1.520 + copyValue.setAttribute("disabled", copyDisabled); 1.521 + 1.522 + var resetSelected = document.getElementById("resetSelected"); 1.523 + resetSelected.setAttribute("disabled", lockCol != PREF_IS_USER_SET); 1.524 + 1.525 + var canToggle = typeCol == nsIPrefBranch.PREF_BOOL && valueCol != ""; 1.526 + // indicates that a pref is locked or no pref is selected at all 1.527 + var isLocked = lockCol == PREF_IS_LOCKED; 1.528 + 1.529 + var modifySelected = document.getElementById("modifySelected"); 1.530 + modifySelected.setAttribute("disabled", isLocked); 1.531 + modifySelected.hidden = canToggle; 1.532 + 1.533 + var toggleSelected = document.getElementById("toggleSelected"); 1.534 + toggleSelected.setAttribute("disabled", isLocked); 1.535 + toggleSelected.hidden = !canToggle; 1.536 +} 1.537 + 1.538 +function copyPref() 1.539 +{ 1.540 + var pref = gPrefView[view.selection.currentIndex]; 1.541 + gClipboardHelper.copyString(pref.prefCol + ';' + pref.valueCol, document); 1.542 +} 1.543 + 1.544 +function copyName() 1.545 +{ 1.546 + gClipboardHelper.copyString(gPrefView[view.selection.currentIndex].prefCol, document); 1.547 +} 1.548 + 1.549 +function copyValue() 1.550 +{ 1.551 + gClipboardHelper.copyString(gPrefView[view.selection.currentIndex].valueCol, document); 1.552 +} 1.553 + 1.554 +function ModifySelected() 1.555 +{ 1.556 + if (view.selection.currentIndex >= 0) 1.557 + ModifyPref(gPrefView[view.selection.currentIndex]); 1.558 +} 1.559 + 1.560 +function ResetSelected() 1.561 +{ 1.562 + var entry = gPrefView[view.selection.currentIndex]; 1.563 + gPrefBranch.clearUserPref(entry.prefCol); 1.564 +} 1.565 + 1.566 +function NewPref(type) 1.567 +{ 1.568 + var result = { value: "" }; 1.569 + var dummy = { value: 0 }; 1.570 + if (Services.prompt.prompt(window, 1.571 + gConfigBundle.getFormattedString("new_title", 1.572 + [gTypeStrs[type]]), 1.573 + gConfigBundle.getString("new_prompt"), 1.574 + result, 1.575 + null, 1.576 + dummy)) { 1.577 + result.value = result.value.trim(); 1.578 + if (!result.value) { 1.579 + return; 1.580 + } 1.581 + 1.582 + var pref; 1.583 + if (result.value in gPrefHash) 1.584 + pref = gPrefHash[result.value]; 1.585 + else 1.586 + pref = { prefCol: result.value, lockCol: PREF_IS_DEFAULT_VALUE, typeCol: type, valueCol: "" }; 1.587 + if (ModifyPref(pref)) 1.588 + setTimeout(gotoPref, 0, result.value); 1.589 + } 1.590 +} 1.591 + 1.592 +function gotoPref(pref) 1.593 +{ 1.594 + // make sure the pref exists and is displayed in the current view 1.595 + var index = pref in gPrefHash ? getViewIndexOfPref(gPrefHash[pref]) : -1; 1.596 + if (index >= 0) { 1.597 + view.selection.select(index); 1.598 + view.treebox.ensureRowIsVisible(index); 1.599 + } else { 1.600 + view.selection.clearSelection(); 1.601 + view.selection.currentIndex = -1; 1.602 + } 1.603 +} 1.604 + 1.605 +function ModifyPref(entry) 1.606 +{ 1.607 + if (entry.lockCol == PREF_IS_LOCKED) 1.608 + return false; 1.609 + var title = gConfigBundle.getFormattedString("modify_title", [gTypeStrs[entry.typeCol]]); 1.610 + if (entry.typeCol == nsIPrefBranch.PREF_BOOL) { 1.611 + var check = { value: entry.valueCol == "false" }; 1.612 + if (!entry.valueCol && !Services.prompt.select(window, title, entry.prefCol, 2, [false, true], check)) 1.613 + return false; 1.614 + gPrefBranch.setBoolPref(entry.prefCol, check.value); 1.615 + } else { 1.616 + var result = { value: entry.valueCol }; 1.617 + var dummy = { value: 0 }; 1.618 + if (!Services.prompt.prompt(window, title, entry.prefCol, result, null, dummy)) 1.619 + return false; 1.620 + if (entry.typeCol == nsIPrefBranch.PREF_INT) { 1.621 + // | 0 converts to integer or 0; - 0 to float or NaN. 1.622 + // Thus, this check should catch all cases. 1.623 + var val = result.value | 0; 1.624 + if (val != result.value - 0) { 1.625 + var err_title = gConfigBundle.getString("nan_title"); 1.626 + var err_text = gConfigBundle.getString("nan_text"); 1.627 + Services.prompt.alert(window, err_title, err_text); 1.628 + return false; 1.629 + } 1.630 + gPrefBranch.setIntPref(entry.prefCol, val); 1.631 + } else { 1.632 + var supportsString = Components.classes[nsSupportsString_CONTRACTID].createInstance(nsISupportsString); 1.633 + supportsString.data = result.value; 1.634 + gPrefBranch.setComplexValue(entry.prefCol, nsISupportsString, supportsString); 1.635 + } 1.636 + } 1.637 + 1.638 + Services.prefs.savePrefFile(null); 1.639 + return true; 1.640 +}