PageRenderTime 39ms CodeModel.GetById 15ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/toolkit/content/widgets/preferences.xml

http://github.com/zpao/v8monkey
XML | 1364 lines | 1262 code | 102 blank | 0 comment | 0 complexity | a22411b7eb3ff79efbb8843e12a982ad MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?xml version="1.0"?>
   2
   3<!DOCTYPE bindings [
   4  <!ENTITY % preferencesDTD SYSTEM "chrome://global/locale/preferences.dtd">
   5  %preferencesDTD;
   6  <!ENTITY % globalKeysDTD SYSTEM "chrome://global/locale/globalKeys.dtd">
   7  %globalKeysDTD;
   8]>
   9
  10<bindings id="preferencesBindings"
  11          xmlns="http://www.mozilla.org/xbl"
  12          xmlns:xbl="http://www.mozilla.org/xbl"
  13          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  14
  15#
  16# = Preferences Window Framework
  17#
  18#   The syntax for use looks something like:
  19#
  20#   <prefwindow>
  21#     <prefpane id="prefPaneA">
  22#       <preferences>
  23#         <preference id="preference1" name="app.preference1" type="bool" onchange="foo();"/>
  24#         <preference id="preference2" name="app.preference2" type="bool" useDefault="true"/>
  25#       </preferences>
  26#       <checkbox label="Preference" preference="preference1"/>
  27#     </prefpane>
  28#   </prefwindow>
  29#
  30
  31  <binding id="preferences">
  32    <implementation implements="nsIObserver">
  33      <method name="observe">
  34        <parameter name="aSubject"/>
  35        <parameter name="aTopic"/>
  36        <parameter name="aData"/>
  37        <body>
  38        <![CDATA[
  39          for (var i = 0; i < this.childNodes.length; ++i) {
  40            var preference = this.childNodes[i];
  41            if (preference.name == aData) {
  42              preference.value = preference.valueFromPreferences;
  43            }
  44          }
  45        ]]>
  46        </body>
  47      </method>
  48      
  49      <method name="fireChangedEvent">
  50        <parameter name="aPreference"/>
  51        <body>
  52        <![CDATA[
  53          // Value changed, synthesize an event
  54          try {
  55            var event = document.createEvent("Events");
  56            event.initEvent("change", true, true);
  57            aPreference.dispatchEvent(event);
  58          }
  59          catch (e) {
  60            Components.utils.reportError(e);
  61          }
  62        ]]>
  63        </body>
  64      </method>
  65      
  66      <field name="service">
  67        Components.classes["@mozilla.org/preferences-service;1"]
  68                  .getService(Components.interfaces.nsIPrefService);
  69      </field>
  70      <field name="rootBranch">
  71        Components.classes["@mozilla.org/preferences-service;1"]
  72                  .getService(Components.interfaces.nsIPrefBranch);
  73      </field>
  74      <field name="defaultBranch">
  75        this.service.getDefaultBranch("");
  76      </field>
  77      <field name="rootBranchInternal">
  78        Components.classes["@mozilla.org/preferences-service;1"]
  79                  .getService(Components.interfaces.nsIPrefBranchInternal);
  80      </field>
  81      <property name="type" readonly="true">
  82        <getter>
  83          <![CDATA[
  84            return document.documentElement.type || "";
  85          ]]>
  86        </getter>
  87      </property>
  88      <property name="instantApply" readonly="true">
  89        <getter>
  90          <![CDATA[
  91            var doc = document.documentElement;
  92            return this.type == "child" ? doc.instantApply
  93                                        : doc.instantApply || this.rootBranch.getBoolPref("browser.preferences.instantApply");
  94          ]]>
  95        </getter>
  96      </property>
  97    </implementation>
  98  </binding>
  99
 100  <binding id="preference">
 101    <implementation>
 102      <constructor>
 103      <![CDATA[
 104        // if the element has been inserted without the name attribute set,
 105        // we have nothing to do here
 106        if (!this.name)
 107          return;
 108
 109        this.preferences.rootBranchInternal
 110            .addObserver(this.name, this.preferences, false);
 111        // In non-instant apply mode, we must try and use the last saved state
 112        // from any previous opens of a child dialog instead of the value from
 113        // preferences, to pick up any edits a user may have made. 
 114        if (this.preferences.type == "child" && 
 115            !this.instantApply && window.opener) {
 116          var pdoc = window.opener.document;
 117
 118          // Try to find a preference element for the same preference.
 119          var preference = null;
 120          var parentPreferences = pdoc.getElementsByTagName("preferences");
 121          for (var k = 0; (k < parentPreferences.length && !preference); ++k) {
 122            var parentPrefs = parentPreferences[k]
 123                                    .getElementsByAttribute("name", this.name);
 124            for (var l = 0; (l < parentPrefs.length && !preference); ++l) {
 125              if (parentPrefs[l].localName == "preference")
 126                preference = parentPrefs[l];
 127            }
 128          }
 129          this._setValue(preference ? preference.value 
 130                                    : this.valueFromPreferences, false);
 131        }
 132        else
 133          this._setValue(this.valueFromPreferences, false);
 134      ]]>
 135      </constructor>
 136      <destructor>
 137        this.preferences.rootBranchInternal
 138            .removeObserver(this.name, this.preferences);
 139      </destructor>
 140      
 141      <property name="instantApply">
 142        <getter>
 143          return this.getAttribute("instantApply") == "true" || this.preferences.instantApply;
 144        </getter>
 145      </property>
 146
 147      <property name="preferences" onget="return this.parentNode"/>
 148      <property name="name" onget="return this.getAttribute('name');">
 149        <setter>
 150          if (val == this.name)
 151            return val;
 152            
 153          this.preferences.rootBranchInternal
 154              .removeObserver(this.name, this.preferences);
 155          this.setAttribute('name', val);
 156          this.preferences.rootBranchInternal
 157              .addObserver(val, this.preferences, false);
 158              
 159          return val;
 160        </setter>
 161      </property>
 162      <property name="type" onget="return this.getAttribute('type');"
 163                            onset="this.setAttribute('type', val); return val;"/>
 164      <property name="inverted" onget="return this.getAttribute('inverted') == 'true';"
 165                                onset="this.setAttribute('inverted', val); return val;"/>
 166      <property name="readonly" onget="return this.getAttribute('readonly') == 'true';"
 167                                onset="this.setAttribute('readonly', val); return val;"/>
 168
 169      <field name="_value">null</field>
 170      <method name="_setValue">
 171        <parameter name="aValue"/>
 172        <parameter name="aUpdate"/>
 173        <body>
 174        <![CDATA[
 175          if (aUpdate && this.value !== aValue) {
 176            this._value = aValue;
 177            if (this.instantApply)
 178              this.valueFromPreferences = aValue;
 179            this.preferences.fireChangedEvent(this);
 180          }
 181          else if (!aUpdate) {
 182            this._value = aValue;
 183            this.updateElements();
 184          }
 185          return aValue;
 186        ]]>
 187        </body>
 188      </method>
 189      <property name="value" onget="return this._value" onset="return this._setValue(val, true);"/>
 190      
 191      <property name="locked">
 192        <getter>
 193          return this.preferences.rootBranch.prefIsLocked(this.name);
 194        </getter>
 195      </property>
 196      
 197      <property name="disabled">
 198        <getter>
 199          return this.getAttribute("disabled") == "true";
 200        </getter>
 201        <setter>
 202        <![CDATA[
 203          if (val) 
 204            this.setAttribute("disabled", "true");
 205          else
 206            this.removeAttribute("disabled");
 207
 208          if (!this.id)
 209            return val;
 210
 211          var elements = document.getElementsByAttribute("preference", this.id);
 212          for (var i = 0; i < elements.length; ++i) {
 213            elements[i].disabled = val;
 214            
 215            var labels = document.getElementsByAttribute("control", elements[i].id);
 216            for (var j = 0; j < labels.length; ++j)
 217              labels[j].disabled = val;
 218          }
 219            
 220          return val;
 221        ]]>
 222        </setter>
 223      </property>
 224      
 225      <property name="tabIndex">
 226        <getter>
 227          return parseInt(this.getAttribute("tabindex"));
 228        </getter>
 229        <setter>
 230        <![CDATA[
 231          if (val) 
 232            this.setAttribute("tabindex", val);
 233          else
 234            this.removeAttribute("tabindex");
 235
 236          if (!this.id)
 237            return val;
 238
 239          var elements = document.getElementsByAttribute("preference", this.id);
 240          for (var i = 0; i < elements.length; ++i) {
 241            elements[i].tabIndex = val;
 242            
 243            var labels = document.getElementsByAttribute("control", elements[i].id);
 244            for (var j = 0; j < labels.length; ++j)
 245              labels[j].tabIndex = val;
 246          }
 247            
 248          return val;
 249        ]]>
 250        </setter>
 251      </property>
 252
 253      <property name="hasUserValue">
 254        <getter>
 255        <![CDATA[
 256          return this.preferences.rootBranch.prefHasUserValue(this.name) &&
 257                 this.value !== undefined;
 258        ]]>
 259        </getter>
 260      </property>
 261      
 262      <method name="reset">
 263        <body>
 264          // defer reset until preference update
 265          this.value = undefined;
 266        </body>
 267      </method>
 268
 269      <field name="_useDefault">false</field>      
 270      <property name="defaultValue">
 271        <getter>
 272        <![CDATA[
 273          this._useDefault = true;
 274          var val = this.valueFromPreferences;
 275          this._useDefault = false;
 276          return val;
 277        ]]>
 278        </getter>
 279      </property>
 280      
 281      <property name="_branch">
 282        <getter>
 283          return this._useDefault ? this.preferences.defaultBranch : this.preferences.rootBranch;
 284        </getter>
 285      </property>
 286      
 287      <field name="batching">false</field>
 288      
 289      <method name="_reportUnknownType">
 290        <body>
 291        <![CDATA[
 292          var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
 293                                         .getService(Components.interfaces.nsIConsoleService);
 294          var msg = "<preference> with id='" + this.id + "' and name='" + 
 295                    this.name + "' has unknown type '" + this.type + "'.";
 296          consoleService.logStringMessage(msg);
 297        ]]>
 298        </body>
 299      </method>
 300      
 301      <property name="valueFromPreferences">
 302        <getter>
 303        <![CDATA[
 304          try {
 305            // Force a resync of value with preferences.
 306            switch (this.type) {
 307            case "int":
 308              return this._branch.getIntPref(this.name);
 309            case "bool":
 310              var val = this._branch.getBoolPref(this.name);
 311              return this.inverted ? !val : val;
 312            case "wstring":
 313              return this._branch
 314                         .getComplexValue(this.name, Components.interfaces.nsIPrefLocalizedString)
 315                         .data;
 316            case "string":
 317            case "unichar":
 318              return this._branch
 319                         .getComplexValue(this.name, Components.interfaces.nsISupportsString)
 320                         .data;
 321            case "fontname":
 322              var family = this._branch
 323                               .getComplexValue(this.name, Components.interfaces.nsISupportsString)
 324                               .data;
 325              var fontEnumerator = Components.classes["@mozilla.org/gfx/fontenumerator;1"]
 326                                             .createInstance(Components.interfaces.nsIFontEnumerator);
 327              return fontEnumerator.getStandardFamilyName(family);
 328            case "file":
 329              var f = this._branch
 330                          .getComplexValue(this.name, Components.interfaces.nsILocalFile);
 331              return f;
 332            default:
 333              this._reportUnknownType();
 334            }
 335          }
 336          catch (e) { }
 337          return null;
 338        ]]>
 339        </getter>
 340        <setter>
 341        <![CDATA[
 342          // Exit early if nothing to do.
 343          if (this.readonly || this.valueFromPreferences == val)
 344            return val;
 345
 346          // The special value undefined means 'reset preference to default'.
 347          if (val === undefined) {
 348            this.preferences.rootBranch.clearUserPref(this.name);
 349            return val;
 350          }
 351
 352          // Force a resync of preferences with value.
 353          switch (this.type) {
 354          case "int":
 355            this.preferences.rootBranch.setIntPref(this.name, val);
 356            break;
 357          case "bool":
 358            this.preferences.rootBranch.setBoolPref(this.name, this.inverted ? !val : val);
 359            break;
 360          case "wstring":
 361            var pls = Components.classes["@mozilla.org/pref-localizedstring;1"]
 362                                .createInstance(Components.interfaces.nsIPrefLocalizedString);
 363            pls.data = val;
 364            this.preferences.rootBranch
 365                .setComplexValue(this.name, Components.interfaces.nsIPrefLocalizedString, pls);
 366            break;
 367          case "string":
 368          case "unichar":
 369          case "fontname":
 370            var iss = Components.classes["@mozilla.org/supports-string;1"]
 371                                .createInstance(Components.interfaces.nsISupportsString);
 372            iss.data = val;
 373            this.preferences.rootBranch
 374                .setComplexValue(this.name, Components.interfaces.nsISupportsString, iss);
 375            break;
 376          case "file":
 377            var lf;
 378            if (typeof(val) == "string") {
 379              lf = Components.classes["@mozilla.org/file/local;1"]
 380                             .createInstance(Components.interfaces.nsILocalFile);
 381              lf.persistentDescriptor = val;
 382              if (!lf.exists())
 383                lf.initWithPath(val);
 384            }
 385            else 
 386              lf = val.QueryInterface(Components.interfaces.nsILocalFile);
 387            this.preferences.rootBranch
 388                .setComplexValue(this.name, Components.interfaces.nsILocalFile, lf);
 389            break;
 390          default:
 391            this._reportUnknownType();
 392          }
 393          if (!this.batching)
 394            this.preferences.service.savePrefFile(null);
 395          return val;
 396        ]]>
 397        </setter>
 398      </property>
 399      
 400      <method name="setElementValue">
 401        <parameter name="aElement"/>
 402        <body>
 403        <![CDATA[
 404          if (this.locked)
 405            aElement.disabled = true;
 406
 407          if (!this.isElementEditable(aElement))
 408            return;
 409
 410          var rv = undefined;
 411          if (aElement.hasAttribute("onsyncfrompreference")) {
 412            // Value changed, synthesize an event
 413            try {
 414              var event = document.createEvent("Events");
 415              event.initEvent("syncfrompreference", true, true);
 416              var f = new Function ("event", 
 417                                    aElement.getAttribute("onsyncfrompreference"));
 418              rv = f.call(aElement, event);
 419            }
 420            catch (e) {
 421              Components.utils.reportError(e);
 422            }
 423          }
 424          var val = rv !== undefined ? rv : (this.instantApply ? this.valueFromPreferences : this.value);
 425          // if the preference is marked for reset, show default value in UI
 426          if (val === undefined)
 427            val = this.defaultValue;
 428
 429          /**
 430           * Initialize a UI element property with a value. Handles the case 
 431           * where an element has not yet had a XBL binding attached for it and
 432           * the property setter does not yet exist by setting the same attribute
 433           * on the XUL element using DOM apis and assuming the element's 
 434           * constructor or property getters appropriately handle this state. 
 435           */
 436          function setValue(element, attribute, value) {
 437            if (attribute in element) 
 438              element[attribute] = value;
 439            else
 440              element.setAttribute(attribute, value);
 441          }
 442          if (aElement.localName == "checkbox" ||
 443              aElement.localName == "listitem")
 444            setValue(aElement, "checked", val);
 445          else if (aElement.localName == "colorpicker")
 446            setValue(aElement, "color", val);
 447          else if (aElement.localName == "textbox") {
 448            // XXXmano Bug 303998: Avoid a caret placement issue if either the
 449            // preference observer or its setter calls updateElements as a result
 450            // of the input event handler.
 451            if (aElement.value !== val)
 452              setValue(aElement, "value", val);
 453          }
 454          else
 455            setValue(aElement, "value", val);
 456        ]]>
 457        </body>
 458      </method>
 459
 460      <method name="getElementValue">
 461        <parameter name="aElement"/>
 462        <body>
 463        <![CDATA[
 464          if (aElement.hasAttribute("onsynctopreference")) {
 465            // Value changed, synthesize an event
 466            try {
 467              var event = document.createEvent("Events");
 468              event.initEvent("synctopreference", true, true);
 469              var f = new Function ("event", 
 470                                    aElement.getAttribute("onsynctopreference"));
 471              var rv = f.call(aElement, event);
 472              if (rv !== undefined) 
 473                return rv;
 474            }
 475            catch (e) {
 476              Components.utils.reportError(e);
 477            }
 478          }
 479          
 480          /**
 481           * Read the value of an attribute from an element, assuming the 
 482           * attribute is a property on the element's node API. If the property
 483           * is not present in the API, then assume its value is contained in
 484           * an attribute, as is the case before a binding has been attached.
 485           */
 486          function getValue(element, attribute) {
 487            if (attribute in element)
 488              return element[attribute];
 489            return element.getAttribute(attribute);
 490          }
 491          if (aElement.localName == "checkbox" ||
 492              aElement.localName == "listitem")
 493            var value = getValue(aElement, "checked");
 494          else if (aElement.localName == "colorpicker")
 495            value = getValue(aElement, "color");
 496          else
 497            value = getValue(aElement, "value");
 498
 499          switch (this.type) {
 500          case "int":
 501            return parseInt(value, 10) || 0;
 502          case "bool":
 503            return typeof(value) == "boolean" ? value : value == "true";
 504          }
 505          return value;
 506        ]]>
 507        </body>
 508      </method>
 509      
 510      <method name="isElementEditable">
 511        <parameter name="aElement"/>
 512        <body>
 513        <![CDATA[
 514          switch (aElement.localName) {
 515          case "checkbox":
 516          case "colorpicker":
 517          case "radiogroup":
 518          case "textbox":
 519          case "listitem":
 520          case "listbox":
 521          case "menulist":
 522            return true;
 523          }
 524          return aElement.getAttribute("preference-editable") == "true";
 525        ]]> 
 526        </body>
 527      </method>
 528      
 529      <method name="updateElements">
 530        <body>
 531        <![CDATA[
 532          if (!this.id)
 533            return;
 534
 535          // This "change" event handler tracks changes made to preferences by 
 536          // sources other than the user in this window. 
 537          var elements = document.getElementsByAttribute("preference", this.id);
 538          for (var i = 0; i < elements.length; ++i) 
 539            this.setElementValue(elements[i]);
 540        ]]>
 541        </body>
 542      </method>
 543    </implementation>
 544    
 545    <handlers>
 546      <handler event="change">
 547        this.updateElements();
 548      </handler>
 549    </handlers>
 550  </binding>
 551
 552  <binding id="prefwindow"
 553           extends="chrome://global/content/bindings/dialog.xml#dialog">
 554    <resources>
 555      <stylesheet src="chrome://global/skin/preferences.css"/>
 556    </resources>
 557    <content dlgbuttons="accept,cancel" persist="lastSelected screenX screenY"
 558             closebuttonlabel="&preferencesCloseButton.label;"
 559             closebuttonaccesskey="&preferencesCloseButton.accesskey;"
 560             role="dialog"
 561#ifdef XP_WIN
 562             title="&preferencesDefaultTitleWin.title;">
 563#else
 564             title="&preferencesDefaultTitleMac.title;">
 565#endif
 566      <xul:windowdragbox orient="vertical">
 567        <xul:radiogroup anonid="selector" orient="horizontal" class="paneSelector chromeclass-toolbar"
 568                        role="listbox"/> <!-- Expose to accessibility APIs as a listbox -->
 569      </xul:windowdragbox>
 570      <xul:hbox flex="1" class="paneDeckContainer">
 571        <xul:deck anonid="paneDeck" flex="1">
 572          <children includes="prefpane"/>
 573        </xul:deck>
 574      </xul:hbox>
 575      <xul:hbox anonid="dlg-buttons" class="prefWindow-dlgbuttons"
 576#ifdef XP_UNIX
 577                >
 578        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
 579        <xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/>
 580        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
 581        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
 582        <xul:spacer anonid="spacer" flex="1"/>
 583        <xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/>
 584        <xul:button dlgtype="accept" class="dialog-button" icon="accept"/>
 585#else
 586                pack="end">
 587        <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
 588        <xul:spacer anonid="spacer" flex="1"/>
 589        <xul:button dlgtype="accept" class="dialog-button" icon="accept"/>
 590        <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
 591        <xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/>
 592        <xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/>
 593        <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
 594#endif
 595      </xul:hbox>
 596      <xul:hbox>
 597        <children/>
 598      </xul:hbox>
 599    </content>
 600    <implementation implements="nsITimerCallback">
 601      <constructor>
 602      <![CDATA[
 603        if (this.type != "child") {
 604          var psvc = Components.classes["@mozilla.org/preferences-service;1"]
 605                               .getService(Components.interfaces.nsIPrefBranch);
 606          this.instantApply = psvc.getBoolPref("browser.preferences.instantApply");
 607          if (this.instantApply) {
 608            var docElt = document.documentElement;
 609            var acceptButton = docElt.getButton("accept");
 610            acceptButton.hidden = true;
 611            var cancelButton  = docElt.getButton("cancel");
 612#ifdef XP_MACOSX
 613            // no buttons on Mac except Help
 614            cancelButton.hidden = true;
 615            // Also, don't fire onDialogAccept on enter
 616            acceptButton.disabled = true;
 617#else
 618            // morph the Cancel button into the Close button
 619            cancelButton.setAttribute ("icon", "close");
 620            cancelButton.label = docElt.getAttribute("closebuttonlabel");
 621            cancelButton.accesskey = docElt.getAttribute("closebuttonaccesskey");
 622#endif
 623          }
 624        }
 625        this.setAttribute("animated", this._shouldAnimate ? "true" : "false");
 626        var panes = this.preferencePanes;
 627
 628        var lastPane = null;
 629        if (this.lastSelected) {
 630          lastPane = document.getElementById(this.lastSelected);
 631          if (!lastPane) {
 632            this.lastSelected = null;
 633          }
 634        }
 635
 636        var paneToLoad;
 637        if ("arguments" in window && window.arguments[0] && document.getElementById(window.arguments[0]) && document.getElementById(window.arguments[0]).nodeName == "prefpane") {
 638          paneToLoad = document.getElementById(window.arguments[0]);
 639          this.lastSelected = paneToLoad.id;
 640        }
 641        else if (lastPane)
 642          paneToLoad = lastPane;
 643        else
 644          paneToLoad = panes[0];
 645
 646        for (var i = 0; i < panes.length; ++i) {
 647          this._makePaneButton(panes[i]);
 648          if (panes[i].loaded) {
 649            // Inline pane content, fire load event to force initialization.
 650            this._fireEvent("paneload", panes[i]);
 651          }
 652        }
 653        this.showPane(paneToLoad);
 654
 655        if (panes.length == 1)
 656          this._selector.setAttribute("collapsed", "true");
 657      ]]>
 658      </constructor>
 659
 660      <destructor>
 661      <![CDATA[
 662        // Release timers to avoid reference cycles.
 663        if (this._animateTimer) {
 664          this._animateTimer.cancel();
 665          this._animateTimer = null;
 666        }
 667        if (this._fadeTimer) {
 668          this._fadeTimer.cancel();
 669          this._fadeTimer = null;
 670        }
 671      ]]>
 672      </destructor>
 673
 674      <field name="instantApply">false</field>
 675      
 676      <property name="preferencePanes"
 677                onget="return this.getElementsByTagName('prefpane');"/>
 678
 679      <property name="type" onget="return this.getAttribute('type');"/>
 680      <property name="_paneDeck"
 681                onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'paneDeck');"/>
 682      <property name="_paneDeckContainer"
 683                onget="return document.getAnonymousElementByAttribute(this, 'class', 'paneDeckContainer');"/>
 684      <property name="_selector"
 685                onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'selector');"/>
 686      <property name="lastSelected" 
 687                onget="return this.getAttribute('lastSelected');">
 688        <setter>
 689          this.setAttribute("lastSelected", val); 
 690          document.persist(this.id, "lastSelected");
 691          return val;
 692        </setter>          
 693      </property>
 694      <property name="currentPane"
 695                onset="return this._currentPane = val;">
 696        <getter>
 697          if (!this._currentPane)
 698            this._currentPane = this.preferencePanes[0];
 699          
 700          return this._currentPane;
 701        </getter> 
 702      </property>
 703      <field name="_currentPane">null</field>
 704      
 705      
 706      <method name="_makePaneButton">
 707        <parameter name="aPaneElement"/>
 708        <body>
 709        <![CDATA[
 710          var radio = document.createElement("radio");
 711          radio.setAttribute("pane", aPaneElement.id);
 712          radio.setAttribute("label", aPaneElement.label);
 713          // Expose preference group choice to accessibility APIs as an unchecked list item
 714          // The parent group is exposed to accessibility APIs as a list
 715          if (aPaneElement.image)
 716            radio.setAttribute("src", aPaneElement.image);
 717          radio.style.listStyleImage = aPaneElement.style.listStyleImage;
 718          this._selector.appendChild(radio);
 719          return radio;
 720        ]]>
 721        </body>
 722      </method>
 723
 724      <method name="showPane">
 725        <parameter name="aPaneElement"/>
 726        <body>
 727        <![CDATA[
 728          if (!aPaneElement)
 729            return;
 730
 731          this._selector.selectedItem = document.getAnonymousElementByAttribute(this, "pane", aPaneElement.id);
 732          if (!aPaneElement.loaded) {
 733            function OverlayLoadObserver(aPane)
 734            {
 735              this._pane = aPane;
 736            }
 737            OverlayLoadObserver.prototype = { 
 738              _outer: this,
 739              observe: function (aSubject, aTopic, aData) 
 740              {
 741                this._pane.loaded = true;
 742                this._outer._fireEvent("paneload", this._pane);
 743                this._outer._selectPane(this._pane);
 744              }
 745            };
 746            
 747            var obs = new OverlayLoadObserver(aPaneElement);
 748            document.loadOverlay(aPaneElement.src, obs);
 749          }
 750          else
 751            this._selectPane(aPaneElement);
 752        ]]>
 753        </body>
 754      </method>
 755      
 756      <method name="_fireEvent">
 757        <parameter name="aEventName"/>
 758        <parameter name="aTarget"/>
 759        <body>
 760        <![CDATA[
 761          // Panel loaded, synthesize a load event. 
 762          try {
 763            var event = document.createEvent("Events");
 764            event.initEvent(aEventName, true, true);
 765            var cancel = !aTarget.dispatchEvent(event);
 766            if (aTarget.hasAttribute("on" + aEventName)) {
 767              var fn = new Function ("event", aTarget.getAttribute("on" + aEventName));
 768              var rv = fn.call(aTarget, event);
 769              if (rv == false)
 770                cancel = true;
 771            }
 772            return !cancel;  
 773          }
 774          catch (e) { 
 775            Components.utils.reportError(e);
 776          }
 777          return false;
 778        ]]>
 779        </body>
 780      </method>
 781      
 782      <field name="_initialized">false</field>
 783      <method name="_selectPane">
 784        <parameter name="aPaneElement"/>
 785        <body>
 786        <![CDATA[
 787#ifdef XP_MACOSX
 788          var paneTitle = aPaneElement.label;
 789          if (paneTitle != "")
 790            document.title = paneTitle;
 791#endif
 792          var helpButton = document.documentElement.getButton("help");
 793          if (aPaneElement.helpTopic)
 794            helpButton.hidden = false;
 795          else
 796            helpButton.hidden = true;
 797
 798          // Find this pane's index in the deck and set the deck's 
 799          // selectedIndex to that value to switch to it.
 800          var prefpanes = this.preferencePanes;
 801          for (var i = 0; i < prefpanes.length; ++i) {
 802            if (prefpanes[i] == aPaneElement) {
 803              this._paneDeck.selectedIndex = i;
 804              
 805              if (this.type != "child") {
 806                if (aPaneElement.hasAttribute("flex") && this._shouldAnimate &&
 807                    prefpanes.length > 1)
 808                  aPaneElement.removeAttribute("flex");
 809                // Calling sizeToContent after the first prefpane is loaded
 810                // will size the windows contents so style information is
 811                // available to calculate correct sizing.
 812                if (!this._initialized && prefpanes.length > 1) {
 813                  if (this._shouldAnimate)
 814                    this.style.minHeight = 0;
 815                  window.sizeToContent();
 816                }
 817
 818                var oldPane = this.lastSelected ? document.getElementById(this.lastSelected) : this.preferencePanes[0];
 819                oldPane.selected = !(aPaneElement.selected = true);
 820                this.lastSelected = aPaneElement.id;
 821                this.currentPane = aPaneElement;
 822                this._initialized = true;
 823
 824                // Only animate if we've switched between prefpanes
 825                if (this._shouldAnimate && oldPane.id != aPaneElement.id) {
 826                  aPaneElement.style.opacity = 0.0;
 827                  this.animate(oldPane, aPaneElement);
 828                }
 829                else if (!this._shouldAnimate && prefpanes.length > 1) {
 830                  var targetHeight = parseInt(window.getComputedStyle(this._paneDeckContainer, "").height);
 831                  var verticalPadding = parseInt(window.getComputedStyle(aPaneElement, "").paddingTop);
 832                  verticalPadding += parseInt(window.getComputedStyle(aPaneElement, "").paddingBottom);
 833                  if (aPaneElement.contentHeight > targetHeight - verticalPadding) {
 834                    // To workaround the bottom border of a groupbox from being
 835                    // cutoff an hbox with a class of bottomBox may enclose it.
 836                    // This needs to include its padding to resize properly.
 837                    // See bug 394433
 838                    var bottomPadding = 0;
 839                    var bottomBox = aPaneElement.getElementsByAttribute("class", "bottomBox")[0];
 840                    if (bottomBox)
 841                      bottomPadding = parseInt(window.getComputedStyle(bottomBox, "").paddingBottom);
 842                    window.innerHeight += bottomPadding + verticalPadding + aPaneElement.contentHeight - targetHeight;
 843                  }
 844
 845                  // XXX rstrong - extend the contents of the prefpane to
 846                  // prevent elements from being cutoff (see bug 349098).
 847                  if (aPaneElement.contentHeight + verticalPadding < targetHeight)
 848                    aPaneElement._content.style.height = targetHeight - verticalPadding + "px";
 849                }
 850              }
 851              break;
 852            }
 853          }
 854        ]]>
 855        </body>
 856      </method>
 857      
 858      <property name="_shouldAnimate">
 859        <getter>
 860        <![CDATA[
 861          var psvc = Components.classes["@mozilla.org/preferences-service;1"]
 862                               .getService(Components.interfaces.nsIPrefBranch);
 863#ifdef XP_MACOSX
 864          var animate = true;
 865#else
 866          var animate = false;
 867#endif
 868          try {
 869            animate = psvc.getBoolPref("browser.preferences.animateFadeIn");
 870          }
 871          catch (e) { }
 872          return animate;
 873        ]]>
 874        </getter>
 875      </property>
 876      
 877      <method name="animate">
 878        <parameter name="aOldPane"/>
 879        <parameter name="aNewPane"/>
 880        <body>
 881        <![CDATA[
 882          // if we are already resizing, use currentHeight
 883          var oldHeight = this._currentHeight ? this._currentHeight : aOldPane.contentHeight;
 884          
 885          this._multiplier = aNewPane.contentHeight > oldHeight ? 1 : -1;
 886          var sizeDelta = Math.abs(oldHeight - aNewPane.contentHeight);
 887          this._animateRemainder = sizeDelta % this._animateIncrement;
 888
 889          this._setUpAnimationTimer(oldHeight);
 890        ]]>
 891        </body>
 892      </method>
 893      
 894      <property name="_sizeIncrement">
 895        <getter>
 896        <![CDATA[
 897          var lastSelectedPane = document.getElementById(this.lastSelected);
 898          var increment = this._animateIncrement * this._multiplier;
 899          var newHeight = this._currentHeight + increment;
 900          if ((this._multiplier > 0 && this._currentHeight >= lastSelectedPane.contentHeight) ||
 901              (this._multiplier < 0 && this._currentHeight <= lastSelectedPane.contentHeight))
 902            return 0;
 903          
 904          if ((this._multiplier > 0 && newHeight > lastSelectedPane.contentHeight) ||
 905              (this._multiplier < 0 && newHeight < lastSelectedPane.contentHeight))
 906            increment = this._animateRemainder * this._multiplier;
 907          return increment;
 908        ]]>
 909        </getter>
 910      </property>
 911      
 912      <method name="notify">
 913        <parameter name="aTimer"/>
 914        <body>
 915        <![CDATA[
 916          if (!document)
 917            aTimer.cancel();
 918          
 919          if (aTimer == this._animateTimer) {
 920            var increment = this._sizeIncrement;
 921            if (increment != 0) {
 922              window.innerHeight += increment;
 923              this._currentHeight += increment;
 924            }
 925            else {
 926              aTimer.cancel();
 927              this._setUpFadeTimer();
 928            }
 929          } else if (aTimer == this._fadeTimer) {
 930            var elt = document.getElementById(this.lastSelected);
 931            var newOpacity = parseFloat(window.getComputedStyle(elt, "").opacity) + this._fadeIncrement;
 932            if (newOpacity < 1.0)
 933              elt.style.opacity = newOpacity;
 934            else {
 935              aTimer.cancel();
 936              elt.style.opacity = 1.0;
 937            }
 938          }
 939        ]]>
 940        </body>
 941      </method>
 942      
 943      <method name="_setUpAnimationTimer">
 944        <parameter name="aStartHeight"/>
 945        <body>
 946        <![CDATA[
 947          if (!this._animateTimer) 
 948            this._animateTimer = Components.classes["@mozilla.org/timer;1"]
 949                                           .createInstance(Components.interfaces.nsITimer);
 950          else
 951            this._animateTimer.cancel();
 952          this._currentHeight = aStartHeight;
 953          
 954          this._animateTimer.initWithCallback(this, this._animateDelay, 
 955                                              Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
 956        ]]>
 957        </body>
 958      </method>
 959      
 960      <method name="_setUpFadeTimer">
 961        <body>
 962        <![CDATA[
 963          if (!this._fadeTimer) 
 964            this._fadeTimer = Components.classes["@mozilla.org/timer;1"]
 965                                        .createInstance(Components.interfaces.nsITimer);
 966          else
 967            this._fadeTimer.cancel();
 968          
 969          this._fadeTimer.initWithCallback(this, this._fadeDelay, 
 970                                           Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
 971        ]]>
 972        </body>
 973      </method>
 974      
 975      <field name="_animateTimer">null</field>
 976      <field name="_fadeTimer">null</field>
 977      <field name="_animateDelay">15</field>
 978      <field name="_animateIncrement">40</field>
 979      <field name="_fadeDelay">5</field>
 980      <field name="_fadeIncrement">0.40</field>
 981      <field name="_animateRemainder">0</field>
 982      <field name="_currentHeight">0</field>
 983      <field name="_multiplier">0</field>
 984
 985      <method name="addPane">
 986        <parameter name="aPaneElement"/>
 987        <body>
 988        <![CDATA[
 989          this.appendChild(aPaneElement);
 990          
 991          // Set up pane button
 992          this._makePaneButton(aPaneElement);
 993        ]]>
 994        </body>
 995      </method>
 996      
 997      <method name="openSubDialog">
 998        <parameter name="aURL"/>
 999        <parameter name="aFeatures"/>
1000        <parameter name="aParams"/>
1001        <body>
1002          return openDialog(aURL, "", "modal,centerscreen,resizable=no" + (aFeatures != "" ? ("," + aFeatures) : ""), aParams);
1003        </body>
1004      </method>
1005      
1006      <method name="openWindow">
1007        <parameter name="aWindowType"/>
1008        <parameter name="aURL"/>
1009        <parameter name="aFeatures"/>
1010        <parameter name="aParams"/>
1011        <body>
1012        <![CDATA[
1013          var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
1014                             .getService(Components.interfaces.nsIWindowMediator);
1015          var win = aWindowType ? wm.getMostRecentWindow(aWindowType) : null;
1016          if (win) {
1017            if ("initWithParams" in win)
1018              win.initWithParams(aParams);
1019            win.focus();
1020          }
1021          else {
1022            var features = "resizable,dialog=no,centerscreen" + (aFeatures != "" ? ("," + aFeatures) : "");
1023            var parentWindow = (this.instantApply || !window.opener || window.opener.closed) ? window : window.opener;
1024            win = parentWindow.openDialog(aURL, "_blank", features, aParams);
1025          }
1026          return win;
1027        ]]>
1028        </body>
1029      </method>
1030    </implementation>
1031    <handlers>
1032      <handler event="dialogaccept">
1033      <![CDATA[
1034        if (!this._fireEvent("beforeaccept", this)) 
1035          return;
1036        
1037        if (this.type == "child" && window.opener) {
1038          var psvc = Components.classes["@mozilla.org/preferences-service;1"]
1039                               .getService(Components.interfaces.nsIPrefBranch);
1040          var instantApply = psvc.getBoolPref("browser.preferences.instantApply");
1041          if (instantApply) {
1042            var panes = this.preferencePanes;
1043            for (var i = 0; i < panes.length; ++i)
1044              panes[i].writePreferences(true);
1045          }
1046          else {
1047            // Clone all the preferences elements from the child document and
1048            // insert them into the pane collection of the parent. 
1049            var pdoc = window.opener.document;
1050            if (pdoc.documentElement.localName == "prefwindow") {
1051              var currentPane = pdoc.documentElement.currentPane;
1052              var id = window.location.href + "#childprefs";
1053              var childPrefs = pdoc.getElementById(id);
1054              if (!childPrefs) {
1055                var childPrefs = pdoc.createElement("preferences");
1056                currentPane.appendChild(childPrefs);
1057                childPrefs.id = id;
1058              }
1059              var panes = this.preferencePanes;
1060              for (var i = 0; i < panes.length; ++i) {
1061                var preferences = panes[i].preferences;
1062                for (var j = 0; j < preferences.length; ++j) {
1063                  // Try to find a preference element for the same preference.
1064                  var preference = null;
1065                  var parentPreferences = pdoc.getElementsByTagName("preferences");
1066                  for (var k = 0; (k < parentPreferences.length && !preference); ++k) {
1067                    var parentPrefs = parentPreferences[k]
1068                                         .getElementsByAttribute("name", preferences[j].name);
1069                    for (var l = 0; (l < parentPrefs.length && !preference); ++l) {
1070                      if (parentPrefs[l].localName == "preference")
1071                        preference = parentPrefs[l];
1072                    }
1073                  }
1074                  if (!preference) {
1075                    // No matching preference in the parent window.
1076                    preference = pdoc.createElement("preference");
1077                    childPrefs.appendChild(preference);
1078                    preference.name     = preferences[j].name;
1079                    preference.type     = preferences[j].type;
1080                    preference.inverted = preferences[j].inverted;
1081                    preference.readonly = preferences[j].readonly;
1082                    preference.disabled = preferences[j].disabled;
1083                  }
1084                  preference.value = preferences[j].value;
1085                }
1086              }
1087            }
1088          }
1089        }
1090        else {
1091          var panes = this.preferencePanes;
1092          for (var i = 0; i < panes.length; ++i)
1093            panes[i].writePreferences(false);
1094
1095          var psvc = Components.classes["@mozilla.org/preferences-service;1"]
1096                               .getService(Components.interfaces.nsIPrefService);
1097          psvc.savePrefFile(null);
1098        }
1099      ]]>
1100      </handler>
1101      <handler event="command">
1102        if (event.originalTarget.hasAttribute("pane")) {
1103          var pane = document.getElementById(event.originalTarget.getAttribute("pane"));
1104          this.showPane(pane);
1105        }
1106      </handler>
1107
1108      <handler event="keypress" key="&windowClose.key;" modifiers="accel" phase="capturing">
1109      <![CDATA[
1110        if (this.instantApply)
1111          window.close();
1112        event.stopPropagation();
1113        event.preventDefault();
1114      ]]>
1115      </handler>
1116
1117      <handler event="keypress"
1118#ifdef XP_MACOSX
1119               key="&openHelpMac.commandkey;" modifiers="accel"
1120#else
1121               keycode="&openHelp.commandkey;"
1122#endif
1123               phase="capturing">
1124      <![CDATA[
1125        var helpButton = this.getButton("help");
1126        if (helpButton.disabled || helpButton.hidden)
1127          return;
1128        this._fireEvent("dialoghelp", this);
1129        event.stopPropagation();
1130        event.preventDefault();
1131      ]]>
1132      </handler>
1133    </handlers>
1134  </binding>
1135  
1136  <binding id="prefpane">
1137    <resources>
1138      <stylesheet src="chrome://global/skin/preferences.css"/>
1139    </resources>
1140    <content>
1141      <xul:vbox class="content-box" xbl:inherits="flex">
1142        <children/>
1143      </xul:vbox>
1144    </content>
1145    <implementation>
1146      <method name="writePreferences">
1147        <parameter name="aFlushToDisk"/>
1148        <body>
1149        <![CDATA[
1150          // Write all values to preferences.
1151          var preferences = this.preferences;
1152          for (var i = 0; i < preferences.length; ++i) {
1153            var preference = preferences[i];
1154            preference.batching = true;
1155            preference.valueFromPreferences = preference.value;
1156            preference.batching = false;
1157          }
1158          if (aFlushToDisk) {
1159            var psvc = Components.classes["@mozilla.org/preferences-service;1"]
1160                                 .getService(Components.interfaces.nsIPrefService);
1161            psvc.savePrefFile(null);
1162          }
1163        ]]>
1164        </body>
1165      </method>
1166      
1167      <property name="src" 
1168                onget="return this.getAttribute('src');"
1169                onset="this.setAttribute('src', val); return val;"/>
1170      <property name="selected" 
1171                onget="return this.getAttribute('selected') == 'true';"
1172                onset="this.setAttribute('selected', val); return val;"/>
1173      <property name="image" 
1174                onget="return this.getAttribute('image');"
1175                onset="this.setAttribute('image', val); return val;"/>
1176      <property name="label" 
1177                onget="return this.getAttribute('label');"
1178                onset="this.setAttribute('label', val); return val;"/>
1179      
1180      <property name="preferenceElements"
1181                onget="return this.getElementsByAttribute('preference', '*');"/>
1182      <property name="preferences"
1183                onget="return this.getElementsByTagName('preference');"/>
1184
1185      <property name="helpTopic">
1186        <getter>
1187        <![CDATA[
1188          // if there are tabs, and the selected tab provides a helpTopic, return that
1189          var box = this.getElementsByTagName("tabbox");
1190          if (box[0]) {
1191            var tab = box[0].selectedTab;
1192            if (tab && tab.hasAttribute("helpTopic"))
1193              return tab.getAttribute("helpTopic");
1194          }
1195
1196          // otherwise, return the helpTopic of the current panel
1197          return this.getAttribute("helpTopic");
1198        ]]>
1199        </getter>
1200      </property>
1201
1202      <field name="_loaded">false</field>
1203      <property name="loaded" 
1204                onget="return !this.src ? true : this._loaded;"
1205                onset="this._loaded = val; return val;"/>
1206      
1207      <method name="preferenceForElement">
1208        <parameter name="aElement"/>
1209        <body>
1210          return document.getElementById(aElement.getAttribute("preference"));
1211        </body>
1212      </method>
1213      
1214      <method name="getPreferenceElement">
1215        <parameter name="aStartElement"/>
1216        <body>
1217        <![CDATA[
1218          var temp = aStartElement;
1219          while (temp && temp.nodeType == Node.ELEMENT_NODE && 
1220                 !temp.hasAttribute("preference"))
1221            temp = temp.parentNode;
1222          return temp.nodeType == Node.ELEMENT_NODE ? temp : aStartElement;
1223        ]]>
1224        </body>
1225      </method>
1226      
1227      <method name="userChangedValue">
1228        <parameter name="aElement"/>
1229        <body>
1230        <![CDATA[
1231          var element = this.getPreferenceElement(aElement);
1232          if (element.hasAttribute("preference")) {
1233            var preference = document.getElementById(element.getAttribute("preference"));
1234            var prefVal = preference.getElementValue(element);
1235            preference.value = prefVal;
1236          }
1237        ]]>
1238        </body>
1239      </method>
1240      
1241      <property name="contentHeight">
1242        <getter>
1243          var targetHeight = parseInt(window.getComputedStyle(this._content, "").height);
1244          targetHeight += parseInt(window.getComputedStyle(this._content, "").marginTop);
1245          targetHeight += parseInt(window.getComputedStyle(this._content, "").marginBottom);
1246          return targetHeight;
1247        </getter>
1248      </property>
1249      <field name="_content">
1250        document.getAnonymousElementByAttribute(this, "class", "content-box");
1251      </field>
1252    </implementation>
1253    <handlers>
1254      <handler event="command">
1255        // This "command" event handler tracks changes made to preferences by 
1256        // the user in this window.
1257        if (event.sourceEvent)
1258          event = event.sourceEvent;
1259        this.userChangedValue(event.target);
1260      </handler>
1261      <handler event="select">
1262        // This "select" event handler tracks changes made to colorpicker 
1263        // preferences by the user in this window.
1264        if (event.target.localName == "colorpicker") 
1265          this.userChangedValue(event.target);
1266      </handler>
1267      <handler event="change">
1268        // This "change" event handler tracks changes made to preferences by 
1269        // the user in this window. 
1270        this.userChangedValue(event.target);
1271      </handler>
1272      <handler event="input">
1273        // This "input" event handler tracks changes made to preferences by 
1274        // the user in this window.
1275        this.userChangedValue(event.target);
1276      </handler>
1277      <handler event="paneload">
1278      <![CDATA[
1279        // Initialize all values from preferences.
1280        var elements = this.preferenceElements;
1281        for (var i = 0; i < elements.length; ++i) {
1282          try {
1283            var preference = this.preferenceForElement(elements[i]);
1284            preference.setElementValue(elements[i]);
1285          }
1286          catch (e) {
1287            dump("*** No preference found for " + elements[i].getAttribute("preference") + "\n");
1288          }
1289        }
1290      ]]>      
1291      </handler>
1292    </handlers>
1293  </binding>
1294          
1295  <binding id="panebutton" extends="chrome://global/content/bindings/radio.xml#radio">
1296    <resources>
1297      <stylesheet src="chrome://global/skin/preferences.css"/>
1298    </resources>
1299    <content>
1300      <xul:image class="paneButtonIcon" xbl:inherits="src"/>
1301      <xul:label class="paneButtonLabel" xbl:inherits="value=label"/>
1302    </content>
1303    <implementation implements="nsIAccessible">
1304      <property name="accessibleType" readonly="true">
1305        <getter>
1306          <![CDATA[
1307            return Components.interfaces.nsIAccessibleProvider.XULListitem;
1308          ]]>
1309        </getter>
1310      </property>
1311    </implementation>
1312  </binding>
1313
1314</bindings>
1315
1316# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
1317# ***** BEGIN LICENSE BLOCK *****
1318# Version: MPL 1.1/GPL 2.0/LGPL 2.1
1319#
1320# The contents of this file are subject to the Mozilla Public License Version
1321# 1.1 (the "License"); you may not use this file except in compliance with
1322# the License. You may obtain a copy of the License at
1323# http://www.mozilla.org/MPL/
1324#
1325# Software distributed under the License is distributed on an "AS IS" basis,
1326# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1327# for the specific language governing rights and limitations under the
1328# License.
1329#
1330# The Original Code is the Preferences System.
1331#
1332# The Initial Developer of the Original Code is
1333# Ben Goodger.
1334# Portions created by the Initial Developer are Copyright (C) 2005
1335# the Initial Developer. All Rights Reserved.
1336#
1337# Contributor(s):
1338#   Ben Goodger <ben@mozilla.org>
1339#   Josh Aas <josh@mozilla.com>
1340#
1341# Alternatively, the contents of this…

Large files files are truncated, but you can click here to view the full file