toolkit/components/viewconfig/content/config.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 Components.utils.import("resource://gre/modules/Services.jsm");
michael@0 8
michael@0 9 const nsIPrefLocalizedString = Components.interfaces.nsIPrefLocalizedString;
michael@0 10 const nsISupportsString = Components.interfaces.nsISupportsString;
michael@0 11 const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
michael@0 12 const nsIClipboardHelper = Components.interfaces.nsIClipboardHelper;
michael@0 13 const nsIAtomService = Components.interfaces.nsIAtomService;
michael@0 14
michael@0 15 const nsSupportsString_CONTRACTID = "@mozilla.org/supports-string;1";
michael@0 16 const nsPrompt_CONTRACTID = "@mozilla.org/embedcomp/prompt-service;1";
michael@0 17 const nsPrefService_CONTRACTID = "@mozilla.org/preferences-service;1";
michael@0 18 const nsClipboardHelper_CONTRACTID = "@mozilla.org/widget/clipboardhelper;1";
michael@0 19 const nsAtomService_CONTRACTID = "@mozilla.org/atom-service;1";
michael@0 20
michael@0 21 const gPrefBranch = Services.prefs;
michael@0 22 const gClipboardHelper = Components.classes[nsClipboardHelper_CONTRACTID].getService(nsIClipboardHelper);
michael@0 23 const gAtomService = Components.classes[nsAtomService_CONTRACTID].getService(nsIAtomService);
michael@0 24
michael@0 25 var gLockProps = ["default", "user", "locked"];
michael@0 26 // we get these from a string bundle
michael@0 27 var gLockStrs = [];
michael@0 28 var gTypeStrs = [];
michael@0 29
michael@0 30 const PREF_IS_DEFAULT_VALUE = 0;
michael@0 31 const PREF_IS_USER_SET = 1;
michael@0 32 const PREF_IS_LOCKED = 2;
michael@0 33
michael@0 34 var gPrefHash = {};
michael@0 35 var gPrefArray = [];
michael@0 36 var gPrefView = gPrefArray; // share the JS array
michael@0 37 var gSortedColumn = "prefCol";
michael@0 38 var gSortFunction = null;
michael@0 39 var gSortDirection = 1; // 1 is ascending; -1 is descending
michael@0 40 var gConfigBundle = null;
michael@0 41 var gFilter = null;
michael@0 42
michael@0 43 var view = {
michael@0 44 get rowCount() { return gPrefView.length; },
michael@0 45 getCellText : function(index, col) {
michael@0 46 if (!(index in gPrefView))
michael@0 47 return "";
michael@0 48
michael@0 49 var value = gPrefView[index][col.id];
michael@0 50
michael@0 51 switch (col.id) {
michael@0 52 case "lockCol":
michael@0 53 return gLockStrs[value];
michael@0 54 case "typeCol":
michael@0 55 return gTypeStrs[value];
michael@0 56 default:
michael@0 57 return value;
michael@0 58 }
michael@0 59 },
michael@0 60 getRowProperties : function(index) { return ""; },
michael@0 61 getCellProperties : function(index, col) {
michael@0 62 if (index in gPrefView)
michael@0 63 return gLockProps[gPrefView[index].lockCol];
michael@0 64
michael@0 65 return "";
michael@0 66 },
michael@0 67 getColumnProperties : function(col) { return ""; },
michael@0 68 treebox : null,
michael@0 69 selection : null,
michael@0 70 isContainer : function(index) { return false; },
michael@0 71 isContainerOpen : function(index) { return false; },
michael@0 72 isContainerEmpty : function(index) { return false; },
michael@0 73 isSorted : function() { return true; },
michael@0 74 canDrop : function(index, orientation) { return false; },
michael@0 75 drop : function(row, orientation) {},
michael@0 76 setTree : function(out) { this.treebox = out; },
michael@0 77 getParentIndex: function(rowIndex) { return -1; },
michael@0 78 hasNextSibling: function(rowIndex, afterIndex) { return false; },
michael@0 79 getLevel: function(index) { return 1; },
michael@0 80 getImageSrc: function(row, col) { return ""; },
michael@0 81 toggleOpenState : function(index) {},
michael@0 82 cycleHeader: function(col) {
michael@0 83 var index = this.selection.currentIndex;
michael@0 84 if (col.id == gSortedColumn) {
michael@0 85 gSortDirection = -gSortDirection;
michael@0 86 gPrefArray.reverse();
michael@0 87 if (gPrefView != gPrefArray)
michael@0 88 gPrefView.reverse();
michael@0 89 if (index >= 0)
michael@0 90 index = gPrefView.length - index - 1;
michael@0 91 }
michael@0 92 else {
michael@0 93 var pref = null;
michael@0 94 if (index >= 0)
michael@0 95 pref = gPrefView[index];
michael@0 96
michael@0 97 var old = document.getElementById(gSortedColumn);
michael@0 98 old.setAttribute("sortDirection", "");
michael@0 99 gPrefArray.sort(gSortFunction = gSortFunctions[col.id]);
michael@0 100 if (gPrefView != gPrefArray)
michael@0 101 gPrefView.sort(gSortFunction);
michael@0 102 gSortedColumn = col.id;
michael@0 103 if (pref)
michael@0 104 index = getViewIndexOfPref(pref);
michael@0 105 }
michael@0 106 col.element.setAttribute("sortDirection", gSortDirection > 0 ? "ascending" : "descending");
michael@0 107 this.treebox.invalidate();
michael@0 108 if (index >= 0) {
michael@0 109 this.selection.select(index);
michael@0 110 this.treebox.ensureRowIsVisible(index);
michael@0 111 }
michael@0 112 },
michael@0 113 selectionChanged : function() {},
michael@0 114 cycleCell: function(row, col) {},
michael@0 115 isEditable: function(row, col) {return false; },
michael@0 116 isSelectable: function(row, col) {return false; },
michael@0 117 setCellValue: function(row, col, value) {},
michael@0 118 setCellText: function(row, col, value) {},
michael@0 119 performAction: function(action) {},
michael@0 120 performActionOnRow: function(action, row) {},
michael@0 121 performActionOnCell: function(action, row, col) {},
michael@0 122 isSeparator: function(index) {return false; }
michael@0 123 };
michael@0 124
michael@0 125 // find the index in gPrefView of a pref object
michael@0 126 // or -1 if it does not exist in the filtered view
michael@0 127 function getViewIndexOfPref(pref)
michael@0 128 {
michael@0 129 var low = -1, high = gPrefView.length;
michael@0 130 var index = (low + high) >> 1;
michael@0 131 while (index > low) {
michael@0 132 var mid = gPrefView[index];
michael@0 133 if (mid == pref)
michael@0 134 return index;
michael@0 135 if (gSortFunction(mid, pref) < 0)
michael@0 136 low = index;
michael@0 137 else
michael@0 138 high = index;
michael@0 139 index = (low + high) >> 1;
michael@0 140 }
michael@0 141 return -1;
michael@0 142 }
michael@0 143
michael@0 144 // find the index in gPrefView where a pref object belongs
michael@0 145 function getNearestViewIndexOfPref(pref)
michael@0 146 {
michael@0 147 var low = -1, high = gPrefView.length;
michael@0 148 var index = (low + high) >> 1;
michael@0 149 while (index > low) {
michael@0 150 if (gSortFunction(gPrefView[index], pref) < 0)
michael@0 151 low = index;
michael@0 152 else
michael@0 153 high = index;
michael@0 154 index = (low + high) >> 1;
michael@0 155 }
michael@0 156 return high;
michael@0 157 }
michael@0 158
michael@0 159 // find the index in gPrefArray of a pref object
michael@0 160 function getIndexOfPref(pref)
michael@0 161 {
michael@0 162 var low = -1, high = gPrefArray.length;
michael@0 163 var index = (low + high) >> 1;
michael@0 164 while (index > low) {
michael@0 165 var mid = gPrefArray[index];
michael@0 166 if (mid == pref)
michael@0 167 return index;
michael@0 168 if (gSortFunction(mid, pref) < 0)
michael@0 169 low = index;
michael@0 170 else
michael@0 171 high = index;
michael@0 172 index = (low + high) >> 1;
michael@0 173 }
michael@0 174 return index;
michael@0 175 }
michael@0 176
michael@0 177 function getNearestIndexOfPref(pref)
michael@0 178 {
michael@0 179 var low = -1, high = gPrefArray.length;
michael@0 180 var index = (low + high) >> 1;
michael@0 181 while (index > low) {
michael@0 182 if (gSortFunction(gPrefArray[index], pref) < 0)
michael@0 183 low = index;
michael@0 184 else
michael@0 185 high = index;
michael@0 186 index = (low + high) >> 1;
michael@0 187 }
michael@0 188 return high;
michael@0 189 }
michael@0 190
michael@0 191 var gPrefListener =
michael@0 192 {
michael@0 193 observe: function(subject, topic, prefName)
michael@0 194 {
michael@0 195 if (topic != "nsPref:changed")
michael@0 196 return;
michael@0 197
michael@0 198 var arrayIndex = gPrefArray.length;
michael@0 199 var viewIndex = arrayIndex;
michael@0 200 var selectedIndex = view.selection.currentIndex;
michael@0 201 var pref;
michael@0 202 var updateView = false;
michael@0 203 var updateArray = false;
michael@0 204 var addedRow = false;
michael@0 205 if (prefName in gPrefHash) {
michael@0 206 pref = gPrefHash[prefName];
michael@0 207 viewIndex = getViewIndexOfPref(pref);
michael@0 208 arrayIndex = getIndexOfPref(pref);
michael@0 209 fetchPref(prefName, arrayIndex);
michael@0 210 // fetchPref replaces the existing pref object
michael@0 211 pref = gPrefHash[prefName];
michael@0 212 if (viewIndex >= 0) {
michael@0 213 // Might need to update the filtered view
michael@0 214 gPrefView[viewIndex] = gPrefHash[prefName];
michael@0 215 view.treebox.invalidateRow(viewIndex);
michael@0 216 }
michael@0 217 if (gSortedColumn == "lockCol" || gSortedColumn == "valueCol") {
michael@0 218 updateArray = true;
michael@0 219 gPrefArray.splice(arrayIndex, 1);
michael@0 220 if (gFilter && gFilter.test(pref.prefCol + ";" + pref.valueCol)) {
michael@0 221 updateView = true;
michael@0 222 gPrefView.splice(viewIndex, 1);
michael@0 223 }
michael@0 224 }
michael@0 225 }
michael@0 226 else {
michael@0 227 fetchPref(prefName, arrayIndex);
michael@0 228 pref = gPrefArray.pop();
michael@0 229 updateArray = true;
michael@0 230 addedRow = true;
michael@0 231 if (gFilter && gFilter.test(pref.prefCol + ";" + pref.valueCol)) {
michael@0 232 updateView = true;
michael@0 233 }
michael@0 234 }
michael@0 235 if (updateArray) {
michael@0 236 // Reinsert in the data array
michael@0 237 var newIndex = getNearestIndexOfPref(pref);
michael@0 238 gPrefArray.splice(newIndex, 0, pref);
michael@0 239
michael@0 240 if (updateView) {
michael@0 241 // View is filtered, reinsert in the view separately
michael@0 242 newIndex = getNearestViewIndexOfPref(pref);
michael@0 243 gPrefView.splice(newIndex, 0, pref);
michael@0 244 }
michael@0 245 else if (gFilter) {
michael@0 246 // View is filtered, but nothing to update
michael@0 247 return;
michael@0 248 }
michael@0 249
michael@0 250 if (addedRow)
michael@0 251 view.treebox.rowCountChanged(newIndex, 1);
michael@0 252
michael@0 253 // Invalidate the changed range in the view
michael@0 254 var low = Math.min(viewIndex, newIndex);
michael@0 255 var high = Math.max(viewIndex, newIndex);
michael@0 256 view.treebox.invalidateRange(low, high);
michael@0 257
michael@0 258 if (selectedIndex == viewIndex) {
michael@0 259 selectedIndex = newIndex;
michael@0 260 }
michael@0 261 else if (selectedIndex >= low && selectedIndex <= high) {
michael@0 262 selectedIndex += (newIndex > viewIndex) ? -1 : 1;
michael@0 263 }
michael@0 264 if (selectedIndex >= 0) {
michael@0 265 view.selection.select(selectedIndex);
michael@0 266 if (selectedIndex == newIndex)
michael@0 267 view.treebox.ensureRowIsVisible(selectedIndex);
michael@0 268 }
michael@0 269 }
michael@0 270 }
michael@0 271 };
michael@0 272
michael@0 273 function prefObject(prefName, prefIndex)
michael@0 274 {
michael@0 275 this.prefCol = prefName;
michael@0 276 }
michael@0 277
michael@0 278 prefObject.prototype =
michael@0 279 {
michael@0 280 lockCol: PREF_IS_DEFAULT_VALUE,
michael@0 281 typeCol: nsIPrefBranch.PREF_STRING,
michael@0 282 valueCol: ""
michael@0 283 };
michael@0 284
michael@0 285 function fetchPref(prefName, prefIndex)
michael@0 286 {
michael@0 287 var pref = new prefObject(prefName);
michael@0 288
michael@0 289 gPrefHash[prefName] = pref;
michael@0 290 gPrefArray[prefIndex] = pref;
michael@0 291
michael@0 292 if (gPrefBranch.prefIsLocked(prefName))
michael@0 293 pref.lockCol = PREF_IS_LOCKED;
michael@0 294 else if (gPrefBranch.prefHasUserValue(prefName))
michael@0 295 pref.lockCol = PREF_IS_USER_SET;
michael@0 296
michael@0 297 try {
michael@0 298 switch (gPrefBranch.getPrefType(prefName)) {
michael@0 299 case gPrefBranch.PREF_BOOL:
michael@0 300 pref.typeCol = gPrefBranch.PREF_BOOL;
michael@0 301 // convert to a string
michael@0 302 pref.valueCol = gPrefBranch.getBoolPref(prefName).toString();
michael@0 303 break;
michael@0 304 case gPrefBranch.PREF_INT:
michael@0 305 pref.typeCol = gPrefBranch.PREF_INT;
michael@0 306 // convert to a string
michael@0 307 pref.valueCol = gPrefBranch.getIntPref(prefName).toString();
michael@0 308 break;
michael@0 309 default:
michael@0 310 case gPrefBranch.PREF_STRING:
michael@0 311 pref.valueCol = gPrefBranch.getComplexValue(prefName, nsISupportsString).data;
michael@0 312 // Try in case it's a localized string (will throw an exception if not)
michael@0 313 if (pref.lockCol == PREF_IS_DEFAULT_VALUE &&
michael@0 314 /^chrome:\/\/.+\/locale\/.+\.properties/.test(pref.valueCol))
michael@0 315 pref.valueCol = gPrefBranch.getComplexValue(prefName, nsIPrefLocalizedString).data;
michael@0 316 break;
michael@0 317 }
michael@0 318 } catch (e) {
michael@0 319 // Also catch obscure cases in which you can't tell in advance
michael@0 320 // that the pref exists but has no user or default value...
michael@0 321 }
michael@0 322 }
michael@0 323
michael@0 324 function onConfigLoad()
michael@0 325 {
michael@0 326 // Load strings
michael@0 327 gConfigBundle = document.getElementById("configBundle");
michael@0 328
michael@0 329 gLockStrs[PREF_IS_DEFAULT_VALUE] = gConfigBundle.getString("default");
michael@0 330 gLockStrs[PREF_IS_USER_SET] = gConfigBundle.getString("user");
michael@0 331 gLockStrs[PREF_IS_LOCKED] = gConfigBundle.getString("locked");
michael@0 332
michael@0 333 gTypeStrs[nsIPrefBranch.PREF_STRING] = gConfigBundle.getString("string");
michael@0 334 gTypeStrs[nsIPrefBranch.PREF_INT] = gConfigBundle.getString("int");
michael@0 335 gTypeStrs[nsIPrefBranch.PREF_BOOL] = gConfigBundle.getString("bool");
michael@0 336
michael@0 337 var showWarning = gPrefBranch.getBoolPref("general.warnOnAboutConfig");
michael@0 338
michael@0 339 if (showWarning)
michael@0 340 document.getElementById("warningButton").focus();
michael@0 341 else
michael@0 342 ShowPrefs();
michael@0 343 }
michael@0 344
michael@0 345 // Unhide the warning message
michael@0 346 function ShowPrefs()
michael@0 347 {
michael@0 348 gPrefBranch.getChildList("").forEach(fetchPref);
michael@0 349
michael@0 350 var descending = document.getElementsByAttribute("sortDirection", "descending");
michael@0 351 if (descending.item(0)) {
michael@0 352 gSortedColumn = descending[0].id;
michael@0 353 gSortDirection = -1;
michael@0 354 }
michael@0 355 else {
michael@0 356 var ascending = document.getElementsByAttribute("sortDirection", "ascending");
michael@0 357 if (ascending.item(0))
michael@0 358 gSortedColumn = ascending[0].id;
michael@0 359 else
michael@0 360 document.getElementById(gSortedColumn).setAttribute("sortDirection", "ascending");
michael@0 361 }
michael@0 362 gSortFunction = gSortFunctions[gSortedColumn];
michael@0 363 gPrefArray.sort(gSortFunction);
michael@0 364
michael@0 365 gPrefBranch.addObserver("", gPrefListener, false);
michael@0 366
michael@0 367 var configTree = document.getElementById("configTree");
michael@0 368 configTree.view = view;
michael@0 369 configTree.controllers.insertControllerAt(0, configController);
michael@0 370
michael@0 371 document.getElementById("configDeck").setAttribute("selectedIndex", 1);
michael@0 372 document.getElementById("configTreeKeyset").removeAttribute("disabled");
michael@0 373 if (!document.getElementById("showWarningNextTime").checked)
michael@0 374 gPrefBranch.setBoolPref("general.warnOnAboutConfig", false);
michael@0 375
michael@0 376 // Process about:config?filter=<string>
michael@0 377 var textbox = document.getElementById("textbox");
michael@0 378 // About URIs don't support query params, so do this manually
michael@0 379 var loc = document.location.href;
michael@0 380 var matches = /[?&]filter\=([^&]+)/i.exec(loc);
michael@0 381 if (matches)
michael@0 382 textbox.value = decodeURIComponent(matches[1]);
michael@0 383
michael@0 384 // Even if we did not set the filter string via the URL query,
michael@0 385 // textbox might have been set via some other mechanism
michael@0 386 if (textbox.value)
michael@0 387 FilterPrefs();
michael@0 388 textbox.focus();
michael@0 389 }
michael@0 390
michael@0 391 function onConfigUnload()
michael@0 392 {
michael@0 393 if (document.getElementById("configDeck").getAttribute("selectedIndex") == 1) {
michael@0 394 gPrefBranch.removeObserver("", gPrefListener);
michael@0 395 var configTree = document.getElementById("configTree");
michael@0 396 configTree.view = null;
michael@0 397 configTree.controllers.removeController(configController);
michael@0 398 }
michael@0 399 }
michael@0 400
michael@0 401 function FilterPrefs()
michael@0 402 {
michael@0 403 if (document.getElementById("configDeck").getAttribute("selectedIndex") != 1) {
michael@0 404 return;
michael@0 405 }
michael@0 406
michael@0 407 var substring = document.getElementById("textbox").value;
michael@0 408 // Check for "/regex/[i]"
michael@0 409 if (substring.charAt(0) == '/') {
michael@0 410 var r = substring.match(/^\/(.*)\/(i?)$/);
michael@0 411 try {
michael@0 412 gFilter = RegExp(r[1], r[2]);
michael@0 413 }
michael@0 414 catch (e) {
michael@0 415 return; // Do nothing on incomplete or bad RegExp
michael@0 416 }
michael@0 417 }
michael@0 418 else if (substring) {
michael@0 419 gFilter = RegExp(substring.replace(/([^* \w])/g, "\\$1")
michael@0 420 .replace(/^\*+/, "").replace(/\*+/g, ".*"), "i");
michael@0 421 } else {
michael@0 422 gFilter = null;
michael@0 423 }
michael@0 424
michael@0 425 var prefCol = (view.selection && view.selection.currentIndex < 0) ?
michael@0 426 null : gPrefView[view.selection.currentIndex].prefCol;
michael@0 427 var oldlen = gPrefView.length;
michael@0 428 gPrefView = gPrefArray;
michael@0 429 if (gFilter) {
michael@0 430 gPrefView = [];
michael@0 431 for (var i = 0; i < gPrefArray.length; ++i)
michael@0 432 if (gFilter.test(gPrefArray[i].prefCol + ";" + gPrefArray[i].valueCol))
michael@0 433 gPrefView.push(gPrefArray[i]);
michael@0 434 }
michael@0 435 view.treebox.invalidate();
michael@0 436 view.treebox.rowCountChanged(oldlen, gPrefView.length - oldlen);
michael@0 437 gotoPref(prefCol);
michael@0 438 }
michael@0 439
michael@0 440 function prefColSortFunction(x, y)
michael@0 441 {
michael@0 442 if (x.prefCol > y.prefCol)
michael@0 443 return gSortDirection;
michael@0 444 if (x.prefCol < y.prefCol)
michael@0 445 return -gSortDirection;
michael@0 446 return 0;
michael@0 447 }
michael@0 448
michael@0 449 function lockColSortFunction(x, y)
michael@0 450 {
michael@0 451 if (x.lockCol != y.lockCol)
michael@0 452 return gSortDirection * (y.lockCol - x.lockCol);
michael@0 453 return prefColSortFunction(x, y);
michael@0 454 }
michael@0 455
michael@0 456 function typeColSortFunction(x, y)
michael@0 457 {
michael@0 458 if (x.typeCol != y.typeCol)
michael@0 459 return gSortDirection * (y.typeCol - x.typeCol);
michael@0 460 return prefColSortFunction(x, y);
michael@0 461 }
michael@0 462
michael@0 463 function valueColSortFunction(x, y)
michael@0 464 {
michael@0 465 if (x.valueCol > y.valueCol)
michael@0 466 return gSortDirection;
michael@0 467 if (x.valueCol < y.valueCol)
michael@0 468 return -gSortDirection;
michael@0 469 return prefColSortFunction(x, y);
michael@0 470 }
michael@0 471
michael@0 472 const gSortFunctions =
michael@0 473 {
michael@0 474 prefCol: prefColSortFunction,
michael@0 475 lockCol: lockColSortFunction,
michael@0 476 typeCol: typeColSortFunction,
michael@0 477 valueCol: valueColSortFunction
michael@0 478 };
michael@0 479
michael@0 480 const configController = {
michael@0 481 supportsCommand: function supportsCommand(command) {
michael@0 482 return command == "cmd_copy";
michael@0 483 },
michael@0 484 isCommandEnabled: function isCommandEnabled(command) {
michael@0 485 return view.selection && view.selection.currentIndex >= 0;
michael@0 486 },
michael@0 487 doCommand: function doCommand(command) {
michael@0 488 copyPref();
michael@0 489 },
michael@0 490 onEvent: function onEvent(event) {
michael@0 491 }
michael@0 492 }
michael@0 493
michael@0 494 function updateContextMenu()
michael@0 495 {
michael@0 496 var lockCol = PREF_IS_LOCKED;
michael@0 497 var typeCol = nsIPrefBranch.PREF_STRING;
michael@0 498 var valueCol = "";
michael@0 499 var copyDisabled = true;
michael@0 500 var prefSelected = view.selection.currentIndex >= 0;
michael@0 501
michael@0 502 if (prefSelected) {
michael@0 503 var prefRow = gPrefView[view.selection.currentIndex];
michael@0 504 lockCol = prefRow.lockCol;
michael@0 505 typeCol = prefRow.typeCol;
michael@0 506 valueCol = prefRow.valueCol;
michael@0 507 copyDisabled = false;
michael@0 508 }
michael@0 509
michael@0 510 var copyPref = document.getElementById("copyPref");
michael@0 511 copyPref.setAttribute("disabled", copyDisabled);
michael@0 512
michael@0 513 var copyName = document.getElementById("copyName");
michael@0 514 copyName.setAttribute("disabled", copyDisabled);
michael@0 515
michael@0 516 var copyValue = document.getElementById("copyValue");
michael@0 517 copyValue.setAttribute("disabled", copyDisabled);
michael@0 518
michael@0 519 var resetSelected = document.getElementById("resetSelected");
michael@0 520 resetSelected.setAttribute("disabled", lockCol != PREF_IS_USER_SET);
michael@0 521
michael@0 522 var canToggle = typeCol == nsIPrefBranch.PREF_BOOL && valueCol != "";
michael@0 523 // indicates that a pref is locked or no pref is selected at all
michael@0 524 var isLocked = lockCol == PREF_IS_LOCKED;
michael@0 525
michael@0 526 var modifySelected = document.getElementById("modifySelected");
michael@0 527 modifySelected.setAttribute("disabled", isLocked);
michael@0 528 modifySelected.hidden = canToggle;
michael@0 529
michael@0 530 var toggleSelected = document.getElementById("toggleSelected");
michael@0 531 toggleSelected.setAttribute("disabled", isLocked);
michael@0 532 toggleSelected.hidden = !canToggle;
michael@0 533 }
michael@0 534
michael@0 535 function copyPref()
michael@0 536 {
michael@0 537 var pref = gPrefView[view.selection.currentIndex];
michael@0 538 gClipboardHelper.copyString(pref.prefCol + ';' + pref.valueCol, document);
michael@0 539 }
michael@0 540
michael@0 541 function copyName()
michael@0 542 {
michael@0 543 gClipboardHelper.copyString(gPrefView[view.selection.currentIndex].prefCol, document);
michael@0 544 }
michael@0 545
michael@0 546 function copyValue()
michael@0 547 {
michael@0 548 gClipboardHelper.copyString(gPrefView[view.selection.currentIndex].valueCol, document);
michael@0 549 }
michael@0 550
michael@0 551 function ModifySelected()
michael@0 552 {
michael@0 553 if (view.selection.currentIndex >= 0)
michael@0 554 ModifyPref(gPrefView[view.selection.currentIndex]);
michael@0 555 }
michael@0 556
michael@0 557 function ResetSelected()
michael@0 558 {
michael@0 559 var entry = gPrefView[view.selection.currentIndex];
michael@0 560 gPrefBranch.clearUserPref(entry.prefCol);
michael@0 561 }
michael@0 562
michael@0 563 function NewPref(type)
michael@0 564 {
michael@0 565 var result = { value: "" };
michael@0 566 var dummy = { value: 0 };
michael@0 567 if (Services.prompt.prompt(window,
michael@0 568 gConfigBundle.getFormattedString("new_title",
michael@0 569 [gTypeStrs[type]]),
michael@0 570 gConfigBundle.getString("new_prompt"),
michael@0 571 result,
michael@0 572 null,
michael@0 573 dummy)) {
michael@0 574 result.value = result.value.trim();
michael@0 575 if (!result.value) {
michael@0 576 return;
michael@0 577 }
michael@0 578
michael@0 579 var pref;
michael@0 580 if (result.value in gPrefHash)
michael@0 581 pref = gPrefHash[result.value];
michael@0 582 else
michael@0 583 pref = { prefCol: result.value, lockCol: PREF_IS_DEFAULT_VALUE, typeCol: type, valueCol: "" };
michael@0 584 if (ModifyPref(pref))
michael@0 585 setTimeout(gotoPref, 0, result.value);
michael@0 586 }
michael@0 587 }
michael@0 588
michael@0 589 function gotoPref(pref)
michael@0 590 {
michael@0 591 // make sure the pref exists and is displayed in the current view
michael@0 592 var index = pref in gPrefHash ? getViewIndexOfPref(gPrefHash[pref]) : -1;
michael@0 593 if (index >= 0) {
michael@0 594 view.selection.select(index);
michael@0 595 view.treebox.ensureRowIsVisible(index);
michael@0 596 } else {
michael@0 597 view.selection.clearSelection();
michael@0 598 view.selection.currentIndex = -1;
michael@0 599 }
michael@0 600 }
michael@0 601
michael@0 602 function ModifyPref(entry)
michael@0 603 {
michael@0 604 if (entry.lockCol == PREF_IS_LOCKED)
michael@0 605 return false;
michael@0 606 var title = gConfigBundle.getFormattedString("modify_title", [gTypeStrs[entry.typeCol]]);
michael@0 607 if (entry.typeCol == nsIPrefBranch.PREF_BOOL) {
michael@0 608 var check = { value: entry.valueCol == "false" };
michael@0 609 if (!entry.valueCol && !Services.prompt.select(window, title, entry.prefCol, 2, [false, true], check))
michael@0 610 return false;
michael@0 611 gPrefBranch.setBoolPref(entry.prefCol, check.value);
michael@0 612 } else {
michael@0 613 var result = { value: entry.valueCol };
michael@0 614 var dummy = { value: 0 };
michael@0 615 if (!Services.prompt.prompt(window, title, entry.prefCol, result, null, dummy))
michael@0 616 return false;
michael@0 617 if (entry.typeCol == nsIPrefBranch.PREF_INT) {
michael@0 618 // | 0 converts to integer or 0; - 0 to float or NaN.
michael@0 619 // Thus, this check should catch all cases.
michael@0 620 var val = result.value | 0;
michael@0 621 if (val != result.value - 0) {
michael@0 622 var err_title = gConfigBundle.getString("nan_title");
michael@0 623 var err_text = gConfigBundle.getString("nan_text");
michael@0 624 Services.prompt.alert(window, err_title, err_text);
michael@0 625 return false;
michael@0 626 }
michael@0 627 gPrefBranch.setIntPref(entry.prefCol, val);
michael@0 628 } else {
michael@0 629 var supportsString = Components.classes[nsSupportsString_CONTRACTID].createInstance(nsISupportsString);
michael@0 630 supportsString.data = result.value;
michael@0 631 gPrefBranch.setComplexValue(entry.prefCol, nsISupportsString, supportsString);
michael@0 632 }
michael@0 633 }
michael@0 634
michael@0 635 Services.prefs.savePrefFile(null);
michael@0 636 return true;
michael@0 637 }

mercurial