1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/content/widgets/preferences.xml Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1325 @@ 1.4 +<?xml version="1.0"?> 1.5 + 1.6 +<!DOCTYPE bindings [ 1.7 + <!ENTITY % preferencesDTD SYSTEM "chrome://global/locale/preferences.dtd"> 1.8 + %preferencesDTD; 1.9 + <!ENTITY % globalKeysDTD SYSTEM "chrome://global/locale/globalKeys.dtd"> 1.10 + %globalKeysDTD; 1.11 +]> 1.12 + 1.13 +<bindings id="preferencesBindings" 1.14 + xmlns="http://www.mozilla.org/xbl" 1.15 + xmlns:xbl="http://www.mozilla.org/xbl" 1.16 + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 1.17 + 1.18 +# 1.19 +# = Preferences Window Framework 1.20 +# 1.21 +# The syntax for use looks something like: 1.22 +# 1.23 +# <prefwindow> 1.24 +# <prefpane id="prefPaneA"> 1.25 +# <preferences> 1.26 +# <preference id="preference1" name="app.preference1" type="bool" onchange="foo();"/> 1.27 +# <preference id="preference2" name="app.preference2" type="bool" useDefault="true"/> 1.28 +# </preferences> 1.29 +# <checkbox label="Preference" preference="preference1"/> 1.30 +# </prefpane> 1.31 +# </prefwindow> 1.32 +# 1.33 + 1.34 + <binding id="preferences"> 1.35 + <implementation implements="nsIObserver"> 1.36 + <method name="observe"> 1.37 + <parameter name="aSubject"/> 1.38 + <parameter name="aTopic"/> 1.39 + <parameter name="aData"/> 1.40 + <body> 1.41 + <![CDATA[ 1.42 + for (var i = 0; i < this.childNodes.length; ++i) { 1.43 + var preference = this.childNodes[i]; 1.44 + if (preference.name == aData) { 1.45 + preference.value = preference.valueFromPreferences; 1.46 + } 1.47 + } 1.48 + ]]> 1.49 + </body> 1.50 + </method> 1.51 + 1.52 + <method name="fireChangedEvent"> 1.53 + <parameter name="aPreference"/> 1.54 + <body> 1.55 + <![CDATA[ 1.56 + // Value changed, synthesize an event 1.57 + try { 1.58 + var event = document.createEvent("Events"); 1.59 + event.initEvent("change", true, true); 1.60 + aPreference.dispatchEvent(event); 1.61 + } 1.62 + catch (e) { 1.63 + Components.utils.reportError(e); 1.64 + } 1.65 + ]]> 1.66 + </body> 1.67 + </method> 1.68 + 1.69 + <field name="service"> 1.70 + Components.classes["@mozilla.org/preferences-service;1"] 1.71 + .getService(Components.interfaces.nsIPrefService); 1.72 + </field> 1.73 + <field name="rootBranch"> 1.74 + Components.classes["@mozilla.org/preferences-service;1"] 1.75 + .getService(Components.interfaces.nsIPrefBranch); 1.76 + </field> 1.77 + <field name="defaultBranch"> 1.78 + this.service.getDefaultBranch(""); 1.79 + </field> 1.80 + <field name="rootBranchInternal"> 1.81 + Components.classes["@mozilla.org/preferences-service;1"] 1.82 + .getService(Components.interfaces.nsIPrefBranchInternal); 1.83 + </field> 1.84 + <property name="type" readonly="true"> 1.85 + <getter> 1.86 + <![CDATA[ 1.87 + return document.documentElement.type || ""; 1.88 + ]]> 1.89 + </getter> 1.90 + </property> 1.91 + <property name="instantApply" readonly="true"> 1.92 + <getter> 1.93 + <![CDATA[ 1.94 + var doc = document.documentElement; 1.95 + return this.type == "child" ? doc.instantApply 1.96 + : doc.instantApply || this.rootBranch.getBoolPref("browser.preferences.instantApply"); 1.97 + ]]> 1.98 + </getter> 1.99 + </property> 1.100 + </implementation> 1.101 + </binding> 1.102 + 1.103 + <binding id="preference"> 1.104 + <implementation> 1.105 + <constructor> 1.106 + <![CDATA[ 1.107 + // if the element has been inserted without the name attribute set, 1.108 + // we have nothing to do here 1.109 + if (!this.name) 1.110 + return; 1.111 + 1.112 + this.preferences.rootBranchInternal 1.113 + .addObserver(this.name, this.preferences, false); 1.114 + // In non-instant apply mode, we must try and use the last saved state 1.115 + // from any previous opens of a child dialog instead of the value from 1.116 + // preferences, to pick up any edits a user may have made. 1.117 + if (this.preferences.type == "child" && 1.118 + !this.instantApply && window.opener) { 1.119 + var pdoc = window.opener.document; 1.120 + 1.121 + // Try to find a preference element for the same preference. 1.122 + var preference = null; 1.123 + var parentPreferences = pdoc.getElementsByTagName("preferences"); 1.124 + for (var k = 0; (k < parentPreferences.length && !preference); ++k) { 1.125 + var parentPrefs = parentPreferences[k] 1.126 + .getElementsByAttribute("name", this.name); 1.127 + for (var l = 0; (l < parentPrefs.length && !preference); ++l) { 1.128 + if (parentPrefs[l].localName == "preference") 1.129 + preference = parentPrefs[l]; 1.130 + } 1.131 + } 1.132 + this._setValue(preference ? preference.value 1.133 + : this.valueFromPreferences, false); 1.134 + } 1.135 + else 1.136 + this._setValue(this.valueFromPreferences, false); 1.137 + ]]> 1.138 + </constructor> 1.139 + <destructor> 1.140 + this.preferences.rootBranchInternal 1.141 + .removeObserver(this.name, this.preferences); 1.142 + </destructor> 1.143 + 1.144 + <property name="instantApply"> 1.145 + <getter> 1.146 + return this.getAttribute("instantApply") == "true" || this.preferences.instantApply; 1.147 + </getter> 1.148 + </property> 1.149 + 1.150 + <property name="preferences" onget="return this.parentNode"/> 1.151 + <property name="name" onget="return this.getAttribute('name');"> 1.152 + <setter> 1.153 + if (val == this.name) 1.154 + return val; 1.155 + 1.156 + this.preferences.rootBranchInternal 1.157 + .removeObserver(this.name, this.preferences); 1.158 + this.setAttribute('name', val); 1.159 + this.preferences.rootBranchInternal 1.160 + .addObserver(val, this.preferences, false); 1.161 + 1.162 + return val; 1.163 + </setter> 1.164 + </property> 1.165 + <property name="type" onget="return this.getAttribute('type');" 1.166 + onset="this.setAttribute('type', val); return val;"/> 1.167 + <property name="inverted" onget="return this.getAttribute('inverted') == 'true';" 1.168 + onset="this.setAttribute('inverted', val); return val;"/> 1.169 + <property name="readonly" onget="return this.getAttribute('readonly') == 'true';" 1.170 + onset="this.setAttribute('readonly', val); return val;"/> 1.171 + 1.172 + <field name="_value">null</field> 1.173 + <method name="_setValue"> 1.174 + <parameter name="aValue"/> 1.175 + <parameter name="aUpdate"/> 1.176 + <body> 1.177 + <![CDATA[ 1.178 + if (aUpdate && this.value !== aValue) { 1.179 + this._value = aValue; 1.180 + if (this.instantApply) 1.181 + this.valueFromPreferences = aValue; 1.182 + this.preferences.fireChangedEvent(this); 1.183 + } 1.184 + else if (!aUpdate) { 1.185 + this._value = aValue; 1.186 + this.updateElements(); 1.187 + } 1.188 + return aValue; 1.189 + ]]> 1.190 + </body> 1.191 + </method> 1.192 + <property name="value" onget="return this._value" onset="return this._setValue(val, true);"/> 1.193 + 1.194 + <property name="locked"> 1.195 + <getter> 1.196 + return this.preferences.rootBranch.prefIsLocked(this.name); 1.197 + </getter> 1.198 + </property> 1.199 + 1.200 + <property name="disabled"> 1.201 + <getter> 1.202 + return this.getAttribute("disabled") == "true"; 1.203 + </getter> 1.204 + <setter> 1.205 + <![CDATA[ 1.206 + if (val) 1.207 + this.setAttribute("disabled", "true"); 1.208 + else 1.209 + this.removeAttribute("disabled"); 1.210 + 1.211 + if (!this.id) 1.212 + return val; 1.213 + 1.214 + var elements = document.getElementsByAttribute("preference", this.id); 1.215 + for (var i = 0; i < elements.length; ++i) { 1.216 + elements[i].disabled = val; 1.217 + 1.218 + var labels = document.getElementsByAttribute("control", elements[i].id); 1.219 + for (var j = 0; j < labels.length; ++j) 1.220 + labels[j].disabled = val; 1.221 + } 1.222 + 1.223 + return val; 1.224 + ]]> 1.225 + </setter> 1.226 + </property> 1.227 + 1.228 + <property name="tabIndex"> 1.229 + <getter> 1.230 + return parseInt(this.getAttribute("tabindex")); 1.231 + </getter> 1.232 + <setter> 1.233 + <![CDATA[ 1.234 + if (val) 1.235 + this.setAttribute("tabindex", val); 1.236 + else 1.237 + this.removeAttribute("tabindex"); 1.238 + 1.239 + if (!this.id) 1.240 + return val; 1.241 + 1.242 + var elements = document.getElementsByAttribute("preference", this.id); 1.243 + for (var i = 0; i < elements.length; ++i) { 1.244 + elements[i].tabIndex = val; 1.245 + 1.246 + var labels = document.getElementsByAttribute("control", elements[i].id); 1.247 + for (var j = 0; j < labels.length; ++j) 1.248 + labels[j].tabIndex = val; 1.249 + } 1.250 + 1.251 + return val; 1.252 + ]]> 1.253 + </setter> 1.254 + </property> 1.255 + 1.256 + <property name="hasUserValue"> 1.257 + <getter> 1.258 + <![CDATA[ 1.259 + return this.preferences.rootBranch.prefHasUserValue(this.name) && 1.260 + this.value !== undefined; 1.261 + ]]> 1.262 + </getter> 1.263 + </property> 1.264 + 1.265 + <method name="reset"> 1.266 + <body> 1.267 + // defer reset until preference update 1.268 + this.value = undefined; 1.269 + </body> 1.270 + </method> 1.271 + 1.272 + <field name="_useDefault">false</field> 1.273 + <property name="defaultValue"> 1.274 + <getter> 1.275 + <![CDATA[ 1.276 + this._useDefault = true; 1.277 + var val = this.valueFromPreferences; 1.278 + this._useDefault = false; 1.279 + return val; 1.280 + ]]> 1.281 + </getter> 1.282 + </property> 1.283 + 1.284 + <property name="_branch"> 1.285 + <getter> 1.286 + return this._useDefault ? this.preferences.defaultBranch : this.preferences.rootBranch; 1.287 + </getter> 1.288 + </property> 1.289 + 1.290 + <field name="batching">false</field> 1.291 + 1.292 + <method name="_reportUnknownType"> 1.293 + <body> 1.294 + <![CDATA[ 1.295 + var consoleService = Components.classes["@mozilla.org/consoleservice;1"] 1.296 + .getService(Components.interfaces.nsIConsoleService); 1.297 + var msg = "<preference> with id='" + this.id + "' and name='" + 1.298 + this.name + "' has unknown type '" + this.type + "'."; 1.299 + consoleService.logStringMessage(msg); 1.300 + ]]> 1.301 + </body> 1.302 + </method> 1.303 + 1.304 + <property name="valueFromPreferences"> 1.305 + <getter> 1.306 + <![CDATA[ 1.307 + try { 1.308 + // Force a resync of value with preferences. 1.309 + switch (this.type) { 1.310 + case "int": 1.311 + return this._branch.getIntPref(this.name); 1.312 + case "bool": 1.313 + var val = this._branch.getBoolPref(this.name); 1.314 + return this.inverted ? !val : val; 1.315 + case "wstring": 1.316 + return this._branch 1.317 + .getComplexValue(this.name, Components.interfaces.nsIPrefLocalizedString) 1.318 + .data; 1.319 + case "string": 1.320 + case "unichar": 1.321 + return this._branch 1.322 + .getComplexValue(this.name, Components.interfaces.nsISupportsString) 1.323 + .data; 1.324 + case "fontname": 1.325 + var family = this._branch 1.326 + .getComplexValue(this.name, Components.interfaces.nsISupportsString) 1.327 + .data; 1.328 + var fontEnumerator = Components.classes["@mozilla.org/gfx/fontenumerator;1"] 1.329 + .createInstance(Components.interfaces.nsIFontEnumerator); 1.330 + return fontEnumerator.getStandardFamilyName(family); 1.331 + case "file": 1.332 + var f = this._branch 1.333 + .getComplexValue(this.name, Components.interfaces.nsILocalFile); 1.334 + return f; 1.335 + default: 1.336 + this._reportUnknownType(); 1.337 + } 1.338 + } 1.339 + catch (e) { } 1.340 + return null; 1.341 + ]]> 1.342 + </getter> 1.343 + <setter> 1.344 + <![CDATA[ 1.345 + // Exit early if nothing to do. 1.346 + if (this.readonly || this.valueFromPreferences == val) 1.347 + return val; 1.348 + 1.349 + // The special value undefined means 'reset preference to default'. 1.350 + if (val === undefined) { 1.351 + this.preferences.rootBranch.clearUserPref(this.name); 1.352 + return val; 1.353 + } 1.354 + 1.355 + // Force a resync of preferences with value. 1.356 + switch (this.type) { 1.357 + case "int": 1.358 + this.preferences.rootBranch.setIntPref(this.name, val); 1.359 + break; 1.360 + case "bool": 1.361 + this.preferences.rootBranch.setBoolPref(this.name, this.inverted ? !val : val); 1.362 + break; 1.363 + case "wstring": 1.364 + var pls = Components.classes["@mozilla.org/pref-localizedstring;1"] 1.365 + .createInstance(Components.interfaces.nsIPrefLocalizedString); 1.366 + pls.data = val; 1.367 + this.preferences.rootBranch 1.368 + .setComplexValue(this.name, Components.interfaces.nsIPrefLocalizedString, pls); 1.369 + break; 1.370 + case "string": 1.371 + case "unichar": 1.372 + case "fontname": 1.373 + var iss = Components.classes["@mozilla.org/supports-string;1"] 1.374 + .createInstance(Components.interfaces.nsISupportsString); 1.375 + iss.data = val; 1.376 + this.preferences.rootBranch 1.377 + .setComplexValue(this.name, Components.interfaces.nsISupportsString, iss); 1.378 + break; 1.379 + case "file": 1.380 + var lf; 1.381 + if (typeof(val) == "string") { 1.382 + lf = Components.classes["@mozilla.org/file/local;1"] 1.383 + .createInstance(Components.interfaces.nsILocalFile); 1.384 + lf.persistentDescriptor = val; 1.385 + if (!lf.exists()) 1.386 + lf.initWithPath(val); 1.387 + } 1.388 + else 1.389 + lf = val.QueryInterface(Components.interfaces.nsILocalFile); 1.390 + this.preferences.rootBranch 1.391 + .setComplexValue(this.name, Components.interfaces.nsILocalFile, lf); 1.392 + break; 1.393 + default: 1.394 + this._reportUnknownType(); 1.395 + } 1.396 + if (!this.batching) 1.397 + this.preferences.service.savePrefFile(null); 1.398 + return val; 1.399 + ]]> 1.400 + </setter> 1.401 + </property> 1.402 + 1.403 + <method name="setElementValue"> 1.404 + <parameter name="aElement"/> 1.405 + <body> 1.406 + <![CDATA[ 1.407 + if (this.locked) 1.408 + aElement.disabled = true; 1.409 + 1.410 + if (!this.isElementEditable(aElement)) 1.411 + return; 1.412 + 1.413 + var rv = undefined; 1.414 + if (aElement.hasAttribute("onsyncfrompreference")) { 1.415 + // Value changed, synthesize an event 1.416 + try { 1.417 + var event = document.createEvent("Events"); 1.418 + event.initEvent("syncfrompreference", true, true); 1.419 + var f = new Function ("event", 1.420 + aElement.getAttribute("onsyncfrompreference")); 1.421 + rv = f.call(aElement, event); 1.422 + } 1.423 + catch (e) { 1.424 + Components.utils.reportError(e); 1.425 + } 1.426 + } 1.427 + var val = rv !== undefined ? rv : (this.instantApply ? this.valueFromPreferences : this.value); 1.428 + // if the preference is marked for reset, show default value in UI 1.429 + if (val === undefined) 1.430 + val = this.defaultValue; 1.431 + 1.432 + /** 1.433 + * Initialize a UI element property with a value. Handles the case 1.434 + * where an element has not yet had a XBL binding attached for it and 1.435 + * the property setter does not yet exist by setting the same attribute 1.436 + * on the XUL element using DOM apis and assuming the element's 1.437 + * constructor or property getters appropriately handle this state. 1.438 + */ 1.439 + function setValue(element, attribute, value) { 1.440 + if (attribute in element) 1.441 + element[attribute] = value; 1.442 + else 1.443 + element.setAttribute(attribute, value); 1.444 + } 1.445 + if (aElement.localName == "checkbox" || 1.446 + aElement.localName == "listitem") 1.447 + setValue(aElement, "checked", val); 1.448 + else if (aElement.localName == "colorpicker") 1.449 + setValue(aElement, "color", val); 1.450 + else if (aElement.localName == "textbox") { 1.451 + // XXXmano Bug 303998: Avoid a caret placement issue if either the 1.452 + // preference observer or its setter calls updateElements as a result 1.453 + // of the input event handler. 1.454 + if (aElement.value !== val) 1.455 + setValue(aElement, "value", val); 1.456 + } 1.457 + else 1.458 + setValue(aElement, "value", val); 1.459 + ]]> 1.460 + </body> 1.461 + </method> 1.462 + 1.463 + <method name="getElementValue"> 1.464 + <parameter name="aElement"/> 1.465 + <body> 1.466 + <![CDATA[ 1.467 + if (aElement.hasAttribute("onsynctopreference")) { 1.468 + // Value changed, synthesize an event 1.469 + try { 1.470 + var event = document.createEvent("Events"); 1.471 + event.initEvent("synctopreference", true, true); 1.472 + var f = new Function ("event", 1.473 + aElement.getAttribute("onsynctopreference")); 1.474 + var rv = f.call(aElement, event); 1.475 + if (rv !== undefined) 1.476 + return rv; 1.477 + } 1.478 + catch (e) { 1.479 + Components.utils.reportError(e); 1.480 + } 1.481 + } 1.482 + 1.483 + /** 1.484 + * Read the value of an attribute from an element, assuming the 1.485 + * attribute is a property on the element's node API. If the property 1.486 + * is not present in the API, then assume its value is contained in 1.487 + * an attribute, as is the case before a binding has been attached. 1.488 + */ 1.489 + function getValue(element, attribute) { 1.490 + if (attribute in element) 1.491 + return element[attribute]; 1.492 + return element.getAttribute(attribute); 1.493 + } 1.494 + if (aElement.localName == "checkbox" || 1.495 + aElement.localName == "listitem") 1.496 + var value = getValue(aElement, "checked"); 1.497 + else if (aElement.localName == "colorpicker") 1.498 + value = getValue(aElement, "color"); 1.499 + else 1.500 + value = getValue(aElement, "value"); 1.501 + 1.502 + switch (this.type) { 1.503 + case "int": 1.504 + return parseInt(value, 10) || 0; 1.505 + case "bool": 1.506 + return typeof(value) == "boolean" ? value : value == "true"; 1.507 + } 1.508 + return value; 1.509 + ]]> 1.510 + </body> 1.511 + </method> 1.512 + 1.513 + <method name="isElementEditable"> 1.514 + <parameter name="aElement"/> 1.515 + <body> 1.516 + <![CDATA[ 1.517 + switch (aElement.localName) { 1.518 + case "checkbox": 1.519 + case "colorpicker": 1.520 + case "radiogroup": 1.521 + case "textbox": 1.522 + case "listitem": 1.523 + case "listbox": 1.524 + case "menulist": 1.525 + return true; 1.526 + } 1.527 + return aElement.getAttribute("preference-editable") == "true"; 1.528 + ]]> 1.529 + </body> 1.530 + </method> 1.531 + 1.532 + <method name="updateElements"> 1.533 + <body> 1.534 + <![CDATA[ 1.535 + if (!this.id) 1.536 + return; 1.537 + 1.538 + // This "change" event handler tracks changes made to preferences by 1.539 + // sources other than the user in this window. 1.540 + var elements = document.getElementsByAttribute("preference", this.id); 1.541 + for (var i = 0; i < elements.length; ++i) 1.542 + this.setElementValue(elements[i]); 1.543 + ]]> 1.544 + </body> 1.545 + </method> 1.546 + </implementation> 1.547 + 1.548 + <handlers> 1.549 + <handler event="change"> 1.550 + this.updateElements(); 1.551 + </handler> 1.552 + </handlers> 1.553 + </binding> 1.554 + 1.555 + <binding id="prefwindow" 1.556 + extends="chrome://global/content/bindings/dialog.xml#dialog"> 1.557 + <resources> 1.558 + <stylesheet src="chrome://global/skin/preferences.css"/> 1.559 + </resources> 1.560 + <content dlgbuttons="accept,cancel" persist="lastSelected screenX screenY" 1.561 + closebuttonlabel="&preferencesCloseButton.label;" 1.562 + closebuttonaccesskey="&preferencesCloseButton.accesskey;" 1.563 + role="dialog" 1.564 +#ifdef XP_WIN 1.565 + title="&preferencesDefaultTitleWin.title;"> 1.566 +#else 1.567 + title="&preferencesDefaultTitleMac.title;"> 1.568 +#endif 1.569 + <xul:windowdragbox orient="vertical"> 1.570 + <xul:radiogroup anonid="selector" orient="horizontal" class="paneSelector chromeclass-toolbar" 1.571 + role="listbox"/> <!-- Expose to accessibility APIs as a listbox --> 1.572 + </xul:windowdragbox> 1.573 + <xul:hbox flex="1" class="paneDeckContainer"> 1.574 + <xul:deck anonid="paneDeck" flex="1"> 1.575 + <children includes="prefpane"/> 1.576 + </xul:deck> 1.577 + </xul:hbox> 1.578 + <xul:hbox anonid="dlg-buttons" class="prefWindow-dlgbuttons" pack="end"> 1.579 +#ifdef XP_UNIX 1.580 + <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/> 1.581 + <xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/> 1.582 + <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/> 1.583 + <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/> 1.584 + <xul:spacer anonid="spacer" flex="1"/> 1.585 + <xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/> 1.586 + <xul:button dlgtype="accept" class="dialog-button" icon="accept"/> 1.587 +#else 1.588 + <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/> 1.589 + <xul:spacer anonid="spacer" flex="1"/> 1.590 + <xul:button dlgtype="accept" class="dialog-button" icon="accept"/> 1.591 + <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/> 1.592 + <xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/> 1.593 + <xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/> 1.594 + <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/> 1.595 +#endif 1.596 + </xul:hbox> 1.597 + <xul:hbox> 1.598 + <children/> 1.599 + </xul:hbox> 1.600 + </content> 1.601 + <implementation implements="nsITimerCallback"> 1.602 + <constructor> 1.603 + <![CDATA[ 1.604 + if (this.type != "child") { 1.605 + var psvc = Components.classes["@mozilla.org/preferences-service;1"] 1.606 + .getService(Components.interfaces.nsIPrefBranch); 1.607 + this.instantApply = psvc.getBoolPref("browser.preferences.instantApply"); 1.608 + if (this.instantApply) { 1.609 + var docElt = document.documentElement; 1.610 + var acceptButton = docElt.getButton("accept"); 1.611 + acceptButton.hidden = true; 1.612 + var cancelButton = docElt.getButton("cancel"); 1.613 +#ifdef XP_MACOSX 1.614 + // no buttons on Mac except Help 1.615 + cancelButton.hidden = true; 1.616 + // Move Help button to the end 1.617 + document.getAnonymousElementByAttribute(this, "anonid", "spacer").hidden = true; 1.618 + // Also, don't fire onDialogAccept on enter 1.619 + acceptButton.disabled = true; 1.620 +#else 1.621 + // morph the Cancel button into the Close button 1.622 + cancelButton.setAttribute ("icon", "close"); 1.623 + cancelButton.label = docElt.getAttribute("closebuttonlabel"); 1.624 + cancelButton.accesskey = docElt.getAttribute("closebuttonaccesskey"); 1.625 +#endif 1.626 + } 1.627 + } 1.628 + this.setAttribute("animated", this._shouldAnimate ? "true" : "false"); 1.629 + var panes = this.preferencePanes; 1.630 + 1.631 + var lastPane = null; 1.632 + if (this.lastSelected) { 1.633 + lastPane = document.getElementById(this.lastSelected); 1.634 + if (!lastPane) { 1.635 + this.lastSelected = ""; 1.636 + } 1.637 + } 1.638 + 1.639 + var paneToLoad; 1.640 + if ("arguments" in window && window.arguments[0] && document.getElementById(window.arguments[0]) && document.getElementById(window.arguments[0]).nodeName == "prefpane") { 1.641 + paneToLoad = document.getElementById(window.arguments[0]); 1.642 + this.lastSelected = paneToLoad.id; 1.643 + } 1.644 + else if (lastPane) 1.645 + paneToLoad = lastPane; 1.646 + else 1.647 + paneToLoad = panes[0]; 1.648 + 1.649 + for (var i = 0; i < panes.length; ++i) { 1.650 + this._makePaneButton(panes[i]); 1.651 + if (panes[i].loaded) { 1.652 + // Inline pane content, fire load event to force initialization. 1.653 + this._fireEvent("paneload", panes[i]); 1.654 + } 1.655 + } 1.656 + this.showPane(paneToLoad); 1.657 + 1.658 + if (panes.length == 1) 1.659 + this._selector.setAttribute("collapsed", "true"); 1.660 + ]]> 1.661 + </constructor> 1.662 + 1.663 + <destructor> 1.664 + <![CDATA[ 1.665 + // Release timers to avoid reference cycles. 1.666 + if (this._animateTimer) { 1.667 + this._animateTimer.cancel(); 1.668 + this._animateTimer = null; 1.669 + } 1.670 + if (this._fadeTimer) { 1.671 + this._fadeTimer.cancel(); 1.672 + this._fadeTimer = null; 1.673 + } 1.674 + ]]> 1.675 + </destructor> 1.676 + 1.677 + <field name="instantApply">false</field> 1.678 + 1.679 + <property name="preferencePanes" 1.680 + onget="return this.getElementsByTagName('prefpane');"/> 1.681 + 1.682 + <property name="type" onget="return this.getAttribute('type');"/> 1.683 + <property name="_paneDeck" 1.684 + onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'paneDeck');"/> 1.685 + <property name="_paneDeckContainer" 1.686 + onget="return document.getAnonymousElementByAttribute(this, 'class', 'paneDeckContainer');"/> 1.687 + <property name="_selector" 1.688 + onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'selector');"/> 1.689 + <property name="lastSelected" 1.690 + onget="return this.getAttribute('lastSelected');"> 1.691 + <setter> 1.692 + this.setAttribute("lastSelected", val); 1.693 + document.persist(this.id, "lastSelected"); 1.694 + return val; 1.695 + </setter> 1.696 + </property> 1.697 + <property name="currentPane" 1.698 + onset="return this._currentPane = val;"> 1.699 + <getter> 1.700 + if (!this._currentPane) 1.701 + this._currentPane = this.preferencePanes[0]; 1.702 + 1.703 + return this._currentPane; 1.704 + </getter> 1.705 + </property> 1.706 + <field name="_currentPane">null</field> 1.707 + 1.708 + 1.709 + <method name="_makePaneButton"> 1.710 + <parameter name="aPaneElement"/> 1.711 + <body> 1.712 + <![CDATA[ 1.713 + var radio = document.createElement("radio"); 1.714 + radio.setAttribute("pane", aPaneElement.id); 1.715 + radio.setAttribute("label", aPaneElement.label); 1.716 + // Expose preference group choice to accessibility APIs as an unchecked list item 1.717 + // The parent group is exposed to accessibility APIs as a list 1.718 + if (aPaneElement.image) 1.719 + radio.setAttribute("src", aPaneElement.image); 1.720 + radio.style.listStyleImage = aPaneElement.style.listStyleImage; 1.721 + this._selector.appendChild(radio); 1.722 + return radio; 1.723 + ]]> 1.724 + </body> 1.725 + </method> 1.726 + 1.727 + <method name="showPane"> 1.728 + <parameter name="aPaneElement"/> 1.729 + <body> 1.730 + <![CDATA[ 1.731 + if (!aPaneElement) 1.732 + return; 1.733 + 1.734 + this._selector.selectedItem = document.getAnonymousElementByAttribute(this, "pane", aPaneElement.id); 1.735 + if (!aPaneElement.loaded) { 1.736 + let OverlayLoadObserver = function(aPane) 1.737 + { 1.738 + this._pane = aPane; 1.739 + } 1.740 + OverlayLoadObserver.prototype = { 1.741 + _outer: this, 1.742 + observe: function (aSubject, aTopic, aData) 1.743 + { 1.744 + this._pane.loaded = true; 1.745 + this._outer._fireEvent("paneload", this._pane); 1.746 + this._outer._selectPane(this._pane); 1.747 + } 1.748 + }; 1.749 + 1.750 + var obs = new OverlayLoadObserver(aPaneElement); 1.751 + document.loadOverlay(aPaneElement.src, obs); 1.752 + } 1.753 + else 1.754 + this._selectPane(aPaneElement); 1.755 + ]]> 1.756 + </body> 1.757 + </method> 1.758 + 1.759 + <method name="_fireEvent"> 1.760 + <parameter name="aEventName"/> 1.761 + <parameter name="aTarget"/> 1.762 + <body> 1.763 + <![CDATA[ 1.764 + // Panel loaded, synthesize a load event. 1.765 + try { 1.766 + var event = document.createEvent("Events"); 1.767 + event.initEvent(aEventName, true, true); 1.768 + var cancel = !aTarget.dispatchEvent(event); 1.769 + if (aTarget.hasAttribute("on" + aEventName)) { 1.770 + var fn = new Function ("event", aTarget.getAttribute("on" + aEventName)); 1.771 + var rv = fn.call(aTarget, event); 1.772 + if (rv == false) 1.773 + cancel = true; 1.774 + } 1.775 + return !cancel; 1.776 + } 1.777 + catch (e) { 1.778 + Components.utils.reportError(e); 1.779 + } 1.780 + return false; 1.781 + ]]> 1.782 + </body> 1.783 + </method> 1.784 + 1.785 + <field name="_initialized">false</field> 1.786 + <method name="_selectPane"> 1.787 + <parameter name="aPaneElement"/> 1.788 + <body> 1.789 + <![CDATA[ 1.790 +#ifdef XP_MACOSX 1.791 + var paneTitle = aPaneElement.label; 1.792 + if (paneTitle != "") 1.793 + document.title = paneTitle; 1.794 +#endif 1.795 + var helpButton = document.documentElement.getButton("help"); 1.796 + if (aPaneElement.helpTopic) 1.797 + helpButton.hidden = false; 1.798 + else 1.799 + helpButton.hidden = true; 1.800 + 1.801 + // Find this pane's index in the deck and set the deck's 1.802 + // selectedIndex to that value to switch to it. 1.803 + var prefpanes = this.preferencePanes; 1.804 + for (var i = 0; i < prefpanes.length; ++i) { 1.805 + if (prefpanes[i] == aPaneElement) { 1.806 + this._paneDeck.selectedIndex = i; 1.807 + 1.808 + if (this.type != "child") { 1.809 + if (aPaneElement.hasAttribute("flex") && this._shouldAnimate && 1.810 + prefpanes.length > 1) 1.811 + aPaneElement.removeAttribute("flex"); 1.812 + // Calling sizeToContent after the first prefpane is loaded 1.813 + // will size the windows contents so style information is 1.814 + // available to calculate correct sizing. 1.815 + if (!this._initialized && prefpanes.length > 1) { 1.816 + if (this._shouldAnimate) 1.817 + this.style.minHeight = 0; 1.818 + window.sizeToContent(); 1.819 + } 1.820 + 1.821 + var oldPane = this.lastSelected ? document.getElementById(this.lastSelected) : this.preferencePanes[0]; 1.822 + oldPane.selected = !(aPaneElement.selected = true); 1.823 + this.lastSelected = aPaneElement.id; 1.824 + this.currentPane = aPaneElement; 1.825 + this._initialized = true; 1.826 + 1.827 + // Only animate if we've switched between prefpanes 1.828 + if (this._shouldAnimate && oldPane.id != aPaneElement.id) { 1.829 + aPaneElement.style.opacity = 0.0; 1.830 + this.animate(oldPane, aPaneElement); 1.831 + } 1.832 + else if (!this._shouldAnimate && prefpanes.length > 1) { 1.833 + var targetHeight = parseInt(window.getComputedStyle(this._paneDeckContainer, "").height); 1.834 + var verticalPadding = parseInt(window.getComputedStyle(aPaneElement, "").paddingTop); 1.835 + verticalPadding += parseInt(window.getComputedStyle(aPaneElement, "").paddingBottom); 1.836 + if (aPaneElement.contentHeight > targetHeight - verticalPadding) { 1.837 + // To workaround the bottom border of a groupbox from being 1.838 + // cutoff an hbox with a class of bottomBox may enclose it. 1.839 + // This needs to include its padding to resize properly. 1.840 + // See bug 394433 1.841 + var bottomPadding = 0; 1.842 + var bottomBox = aPaneElement.getElementsByAttribute("class", "bottomBox")[0]; 1.843 + if (bottomBox) 1.844 + bottomPadding = parseInt(window.getComputedStyle(bottomBox, "").paddingBottom); 1.845 + window.innerHeight += bottomPadding + verticalPadding + aPaneElement.contentHeight - targetHeight; 1.846 + } 1.847 + 1.848 + // XXX rstrong - extend the contents of the prefpane to 1.849 + // prevent elements from being cutoff (see bug 349098). 1.850 + if (aPaneElement.contentHeight + verticalPadding < targetHeight) 1.851 + aPaneElement._content.style.height = targetHeight - verticalPadding + "px"; 1.852 + } 1.853 + } 1.854 + break; 1.855 + } 1.856 + } 1.857 + ]]> 1.858 + </body> 1.859 + </method> 1.860 + 1.861 + <property name="_shouldAnimate"> 1.862 + <getter> 1.863 + <![CDATA[ 1.864 + var psvc = Components.classes["@mozilla.org/preferences-service;1"] 1.865 + .getService(Components.interfaces.nsIPrefBranch); 1.866 +#ifdef XP_MACOSX 1.867 + var animate = true; 1.868 +#else 1.869 + var animate = false; 1.870 +#endif 1.871 + try { 1.872 + animate = psvc.getBoolPref("browser.preferences.animateFadeIn"); 1.873 + } 1.874 + catch (e) { } 1.875 + return animate; 1.876 + ]]> 1.877 + </getter> 1.878 + </property> 1.879 + 1.880 + <method name="animate"> 1.881 + <parameter name="aOldPane"/> 1.882 + <parameter name="aNewPane"/> 1.883 + <body> 1.884 + <![CDATA[ 1.885 + // if we are already resizing, use currentHeight 1.886 + var oldHeight = this._currentHeight ? this._currentHeight : aOldPane.contentHeight; 1.887 + 1.888 + this._multiplier = aNewPane.contentHeight > oldHeight ? 1 : -1; 1.889 + var sizeDelta = Math.abs(oldHeight - aNewPane.contentHeight); 1.890 + this._animateRemainder = sizeDelta % this._animateIncrement; 1.891 + 1.892 + this._setUpAnimationTimer(oldHeight); 1.893 + ]]> 1.894 + </body> 1.895 + </method> 1.896 + 1.897 + <property name="_sizeIncrement"> 1.898 + <getter> 1.899 + <![CDATA[ 1.900 + var lastSelectedPane = document.getElementById(this.lastSelected); 1.901 + var increment = this._animateIncrement * this._multiplier; 1.902 + var newHeight = this._currentHeight + increment; 1.903 + if ((this._multiplier > 0 && this._currentHeight >= lastSelectedPane.contentHeight) || 1.904 + (this._multiplier < 0 && this._currentHeight <= lastSelectedPane.contentHeight)) 1.905 + return 0; 1.906 + 1.907 + if ((this._multiplier > 0 && newHeight > lastSelectedPane.contentHeight) || 1.908 + (this._multiplier < 0 && newHeight < lastSelectedPane.contentHeight)) 1.909 + increment = this._animateRemainder * this._multiplier; 1.910 + return increment; 1.911 + ]]> 1.912 + </getter> 1.913 + </property> 1.914 + 1.915 + <method name="notify"> 1.916 + <parameter name="aTimer"/> 1.917 + <body> 1.918 + <![CDATA[ 1.919 + if (!document) 1.920 + aTimer.cancel(); 1.921 + 1.922 + if (aTimer == this._animateTimer) { 1.923 + var increment = this._sizeIncrement; 1.924 + if (increment != 0) { 1.925 + window.innerHeight += increment; 1.926 + this._currentHeight += increment; 1.927 + } 1.928 + else { 1.929 + aTimer.cancel(); 1.930 + this._setUpFadeTimer(); 1.931 + } 1.932 + } else if (aTimer == this._fadeTimer) { 1.933 + var elt = document.getElementById(this.lastSelected); 1.934 + var newOpacity = parseFloat(window.getComputedStyle(elt, "").opacity) + this._fadeIncrement; 1.935 + if (newOpacity < 1.0) 1.936 + elt.style.opacity = newOpacity; 1.937 + else { 1.938 + aTimer.cancel(); 1.939 + elt.style.opacity = 1.0; 1.940 + } 1.941 + } 1.942 + ]]> 1.943 + </body> 1.944 + </method> 1.945 + 1.946 + <method name="_setUpAnimationTimer"> 1.947 + <parameter name="aStartHeight"/> 1.948 + <body> 1.949 + <![CDATA[ 1.950 + if (!this._animateTimer) 1.951 + this._animateTimer = Components.classes["@mozilla.org/timer;1"] 1.952 + .createInstance(Components.interfaces.nsITimer); 1.953 + else 1.954 + this._animateTimer.cancel(); 1.955 + this._currentHeight = aStartHeight; 1.956 + 1.957 + this._animateTimer.initWithCallback(this, this._animateDelay, 1.958 + Components.interfaces.nsITimer.TYPE_REPEATING_SLACK); 1.959 + ]]> 1.960 + </body> 1.961 + </method> 1.962 + 1.963 + <method name="_setUpFadeTimer"> 1.964 + <body> 1.965 + <![CDATA[ 1.966 + if (!this._fadeTimer) 1.967 + this._fadeTimer = Components.classes["@mozilla.org/timer;1"] 1.968 + .createInstance(Components.interfaces.nsITimer); 1.969 + else 1.970 + this._fadeTimer.cancel(); 1.971 + 1.972 + this._fadeTimer.initWithCallback(this, this._fadeDelay, 1.973 + Components.interfaces.nsITimer.TYPE_REPEATING_SLACK); 1.974 + ]]> 1.975 + </body> 1.976 + </method> 1.977 + 1.978 + <field name="_animateTimer">null</field> 1.979 + <field name="_fadeTimer">null</field> 1.980 + <field name="_animateDelay">15</field> 1.981 + <field name="_animateIncrement">40</field> 1.982 + <field name="_fadeDelay">5</field> 1.983 + <field name="_fadeIncrement">0.40</field> 1.984 + <field name="_animateRemainder">0</field> 1.985 + <field name="_currentHeight">0</field> 1.986 + <field name="_multiplier">0</field> 1.987 + 1.988 + <method name="addPane"> 1.989 + <parameter name="aPaneElement"/> 1.990 + <body> 1.991 + <![CDATA[ 1.992 + this.appendChild(aPaneElement); 1.993 + 1.994 + // Set up pane button 1.995 + this._makePaneButton(aPaneElement); 1.996 + ]]> 1.997 + </body> 1.998 + </method> 1.999 + 1.1000 + <method name="openSubDialog"> 1.1001 + <parameter name="aURL"/> 1.1002 + <parameter name="aFeatures"/> 1.1003 + <parameter name="aParams"/> 1.1004 + <body> 1.1005 + return openDialog(aURL, "", "modal,centerscreen,resizable=no" + (aFeatures != "" ? ("," + aFeatures) : ""), aParams); 1.1006 + </body> 1.1007 + </method> 1.1008 + 1.1009 + <method name="openWindow"> 1.1010 + <parameter name="aWindowType"/> 1.1011 + <parameter name="aURL"/> 1.1012 + <parameter name="aFeatures"/> 1.1013 + <parameter name="aParams"/> 1.1014 + <body> 1.1015 + <![CDATA[ 1.1016 + var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] 1.1017 + .getService(Components.interfaces.nsIWindowMediator); 1.1018 + var win = aWindowType ? wm.getMostRecentWindow(aWindowType) : null; 1.1019 + if (win) { 1.1020 + if ("initWithParams" in win) 1.1021 + win.initWithParams(aParams); 1.1022 + win.focus(); 1.1023 + } 1.1024 + else { 1.1025 + var features = "resizable,dialog=no,centerscreen" + (aFeatures != "" ? ("," + aFeatures) : ""); 1.1026 + var parentWindow = (this.instantApply || !window.opener || window.opener.closed) ? window : window.opener; 1.1027 + win = parentWindow.openDialog(aURL, "_blank", features, aParams); 1.1028 + } 1.1029 + return win; 1.1030 + ]]> 1.1031 + </body> 1.1032 + </method> 1.1033 + </implementation> 1.1034 + <handlers> 1.1035 + <handler event="dialogaccept"> 1.1036 + <![CDATA[ 1.1037 + if (!this._fireEvent("beforeaccept", this)){ 1.1038 + return false; 1.1039 + } 1.1040 + 1.1041 + if (this.type == "child" && window.opener) { 1.1042 + var psvc = Components.classes["@mozilla.org/preferences-service;1"] 1.1043 + .getService(Components.interfaces.nsIPrefBranch); 1.1044 + var instantApply = psvc.getBoolPref("browser.preferences.instantApply"); 1.1045 + if (instantApply) { 1.1046 + var panes = this.preferencePanes; 1.1047 + for (var i = 0; i < panes.length; ++i) 1.1048 + panes[i].writePreferences(true); 1.1049 + } 1.1050 + else { 1.1051 + // Clone all the preferences elements from the child document and 1.1052 + // insert them into the pane collection of the parent. 1.1053 + var pdoc = window.opener.document; 1.1054 + if (pdoc.documentElement.localName == "prefwindow") { 1.1055 + var currentPane = pdoc.documentElement.currentPane; 1.1056 + var id = window.location.href + "#childprefs"; 1.1057 + var childPrefs = pdoc.getElementById(id); 1.1058 + if (!childPrefs) { 1.1059 + var childPrefs = pdoc.createElement("preferences"); 1.1060 + currentPane.appendChild(childPrefs); 1.1061 + childPrefs.id = id; 1.1062 + } 1.1063 + var panes = this.preferencePanes; 1.1064 + for (var i = 0; i < panes.length; ++i) { 1.1065 + var preferences = panes[i].preferences; 1.1066 + for (var j = 0; j < preferences.length; ++j) { 1.1067 + // Try to find a preference element for the same preference. 1.1068 + var preference = null; 1.1069 + var parentPreferences = pdoc.getElementsByTagName("preferences"); 1.1070 + for (var k = 0; (k < parentPreferences.length && !preference); ++k) { 1.1071 + var parentPrefs = parentPreferences[k] 1.1072 + .getElementsByAttribute("name", preferences[j].name); 1.1073 + for (var l = 0; (l < parentPrefs.length && !preference); ++l) { 1.1074 + if (parentPrefs[l].localName == "preference") 1.1075 + preference = parentPrefs[l]; 1.1076 + } 1.1077 + } 1.1078 + if (!preference) { 1.1079 + // No matching preference in the parent window. 1.1080 + preference = pdoc.createElement("preference"); 1.1081 + childPrefs.appendChild(preference); 1.1082 + preference.name = preferences[j].name; 1.1083 + preference.type = preferences[j].type; 1.1084 + preference.inverted = preferences[j].inverted; 1.1085 + preference.readonly = preferences[j].readonly; 1.1086 + preference.disabled = preferences[j].disabled; 1.1087 + } 1.1088 + preference.value = preferences[j].value; 1.1089 + } 1.1090 + } 1.1091 + } 1.1092 + } 1.1093 + } 1.1094 + else { 1.1095 + var panes = this.preferencePanes; 1.1096 + for (var i = 0; i < panes.length; ++i) 1.1097 + panes[i].writePreferences(false); 1.1098 + 1.1099 + var psvc = Components.classes["@mozilla.org/preferences-service;1"] 1.1100 + .getService(Components.interfaces.nsIPrefService); 1.1101 + psvc.savePrefFile(null); 1.1102 + } 1.1103 + 1.1104 + return true; 1.1105 + ]]> 1.1106 + </handler> 1.1107 + <handler event="command"> 1.1108 + if (event.originalTarget.hasAttribute("pane")) { 1.1109 + var pane = document.getElementById(event.originalTarget.getAttribute("pane")); 1.1110 + this.showPane(pane); 1.1111 + } 1.1112 + </handler> 1.1113 + 1.1114 + <handler event="keypress" key="&windowClose.key;" modifiers="accel" phase="capturing"> 1.1115 + <![CDATA[ 1.1116 + if (this.instantApply) 1.1117 + window.close(); 1.1118 + event.stopPropagation(); 1.1119 + event.preventDefault(); 1.1120 + ]]> 1.1121 + </handler> 1.1122 + 1.1123 + <handler event="keypress" 1.1124 +#ifdef XP_MACOSX 1.1125 + key="&openHelpMac.commandkey;" modifiers="accel" 1.1126 +#else 1.1127 + keycode="&openHelp.commandkey;" 1.1128 +#endif 1.1129 + phase="capturing"> 1.1130 + <![CDATA[ 1.1131 + var helpButton = this.getButton("help"); 1.1132 + if (helpButton.disabled || helpButton.hidden) 1.1133 + return; 1.1134 + this._fireEvent("dialoghelp", this); 1.1135 + event.stopPropagation(); 1.1136 + event.preventDefault(); 1.1137 + ]]> 1.1138 + </handler> 1.1139 + </handlers> 1.1140 + </binding> 1.1141 + 1.1142 + <binding id="prefpane"> 1.1143 + <resources> 1.1144 + <stylesheet src="chrome://global/skin/preferences.css"/> 1.1145 + </resources> 1.1146 + <content> 1.1147 + <xul:vbox class="content-box" xbl:inherits="flex"> 1.1148 + <children/> 1.1149 + </xul:vbox> 1.1150 + </content> 1.1151 + <implementation> 1.1152 + <method name="writePreferences"> 1.1153 + <parameter name="aFlushToDisk"/> 1.1154 + <body> 1.1155 + <![CDATA[ 1.1156 + // Write all values to preferences. 1.1157 + var preferences = this.preferences; 1.1158 + for (var i = 0; i < preferences.length; ++i) { 1.1159 + var preference = preferences[i]; 1.1160 + preference.batching = true; 1.1161 + preference.valueFromPreferences = preference.value; 1.1162 + preference.batching = false; 1.1163 + } 1.1164 + if (aFlushToDisk) { 1.1165 + var psvc = Components.classes["@mozilla.org/preferences-service;1"] 1.1166 + .getService(Components.interfaces.nsIPrefService); 1.1167 + psvc.savePrefFile(null); 1.1168 + } 1.1169 + ]]> 1.1170 + </body> 1.1171 + </method> 1.1172 + 1.1173 + <property name="src" 1.1174 + onget="return this.getAttribute('src');" 1.1175 + onset="this.setAttribute('src', val); return val;"/> 1.1176 + <property name="selected" 1.1177 + onget="return this.getAttribute('selected') == 'true';" 1.1178 + onset="this.setAttribute('selected', val); return val;"/> 1.1179 + <property name="image" 1.1180 + onget="return this.getAttribute('image');" 1.1181 + onset="this.setAttribute('image', val); return val;"/> 1.1182 + <property name="label" 1.1183 + onget="return this.getAttribute('label');" 1.1184 + onset="this.setAttribute('label', val); return val;"/> 1.1185 + 1.1186 + <property name="preferenceElements" 1.1187 + onget="return this.getElementsByAttribute('preference', '*');"/> 1.1188 + <property name="preferences" 1.1189 + onget="return this.getElementsByTagName('preference');"/> 1.1190 + 1.1191 + <property name="helpTopic"> 1.1192 + <getter> 1.1193 + <![CDATA[ 1.1194 + // if there are tabs, and the selected tab provides a helpTopic, return that 1.1195 + var box = this.getElementsByTagName("tabbox"); 1.1196 + if (box[0]) { 1.1197 + var tab = box[0].selectedTab; 1.1198 + if (tab && tab.hasAttribute("helpTopic")) 1.1199 + return tab.getAttribute("helpTopic"); 1.1200 + } 1.1201 + 1.1202 + // otherwise, return the helpTopic of the current panel 1.1203 + return this.getAttribute("helpTopic"); 1.1204 + ]]> 1.1205 + </getter> 1.1206 + </property> 1.1207 + 1.1208 + <field name="_loaded">false</field> 1.1209 + <property name="loaded" 1.1210 + onget="return !this.src ? true : this._loaded;" 1.1211 + onset="this._loaded = val; return val;"/> 1.1212 + 1.1213 + <method name="preferenceForElement"> 1.1214 + <parameter name="aElement"/> 1.1215 + <body> 1.1216 + return document.getElementById(aElement.getAttribute("preference")); 1.1217 + </body> 1.1218 + </method> 1.1219 + 1.1220 + <method name="getPreferenceElement"> 1.1221 + <parameter name="aStartElement"/> 1.1222 + <body> 1.1223 + <![CDATA[ 1.1224 + var temp = aStartElement; 1.1225 + while (temp && temp.nodeType == Node.ELEMENT_NODE && 1.1226 + !temp.hasAttribute("preference")) 1.1227 + temp = temp.parentNode; 1.1228 + return temp.nodeType == Node.ELEMENT_NODE ? temp : aStartElement; 1.1229 + ]]> 1.1230 + </body> 1.1231 + </method> 1.1232 + 1.1233 + <method name="userChangedValue"> 1.1234 + <parameter name="aElement"/> 1.1235 + <body> 1.1236 + <![CDATA[ 1.1237 + var element = this.getPreferenceElement(aElement); 1.1238 + if (element.hasAttribute("preference")) { 1.1239 + var preference = document.getElementById(element.getAttribute("preference")); 1.1240 + var prefVal = preference.getElementValue(element); 1.1241 + preference.value = prefVal; 1.1242 + } 1.1243 + ]]> 1.1244 + </body> 1.1245 + </method> 1.1246 + 1.1247 + <property name="contentHeight"> 1.1248 + <getter> 1.1249 + var targetHeight = parseInt(window.getComputedStyle(this._content, "").height); 1.1250 + targetHeight += parseInt(window.getComputedStyle(this._content, "").marginTop); 1.1251 + targetHeight += parseInt(window.getComputedStyle(this._content, "").marginBottom); 1.1252 + return targetHeight; 1.1253 + </getter> 1.1254 + </property> 1.1255 + <field name="_content"> 1.1256 + document.getAnonymousElementByAttribute(this, "class", "content-box"); 1.1257 + </field> 1.1258 + </implementation> 1.1259 + <handlers> 1.1260 + <handler event="command"> 1.1261 + // This "command" event handler tracks changes made to preferences by 1.1262 + // the user in this window. 1.1263 + if (event.sourceEvent) 1.1264 + event = event.sourceEvent; 1.1265 + this.userChangedValue(event.target); 1.1266 + </handler> 1.1267 + <handler event="select"> 1.1268 + // This "select" event handler tracks changes made to colorpicker 1.1269 + // preferences by the user in this window. 1.1270 + if (event.target.localName == "colorpicker") 1.1271 + this.userChangedValue(event.target); 1.1272 + </handler> 1.1273 + <handler event="change"> 1.1274 + // This "change" event handler tracks changes made to preferences by 1.1275 + // the user in this window. 1.1276 + this.userChangedValue(event.target); 1.1277 + </handler> 1.1278 + <handler event="input"> 1.1279 + // This "input" event handler tracks changes made to preferences by 1.1280 + // the user in this window. 1.1281 + this.userChangedValue(event.target); 1.1282 + </handler> 1.1283 + <handler event="paneload"> 1.1284 + <![CDATA[ 1.1285 + // Initialize all values from preferences. 1.1286 + var elements = this.preferenceElements; 1.1287 + for (var i = 0; i < elements.length; ++i) { 1.1288 + try { 1.1289 + var preference = this.preferenceForElement(elements[i]); 1.1290 + preference.setElementValue(elements[i]); 1.1291 + } 1.1292 + catch (e) { 1.1293 + dump("*** No preference found for " + elements[i].getAttribute("preference") + "\n"); 1.1294 + } 1.1295 + } 1.1296 + ]]> 1.1297 + </handler> 1.1298 + </handlers> 1.1299 + </binding> 1.1300 + 1.1301 + <binding id="panebutton" role="xul:listitem" 1.1302 + extends="chrome://global/content/bindings/radio.xml#radio"> 1.1303 + <resources> 1.1304 + <stylesheet src="chrome://global/skin/preferences.css"/> 1.1305 + </resources> 1.1306 + <content> 1.1307 + <xul:image class="paneButtonIcon" xbl:inherits="src"/> 1.1308 + <xul:label class="paneButtonLabel" xbl:inherits="value=label"/> 1.1309 + </content> 1.1310 + </binding> 1.1311 + 1.1312 +</bindings> 1.1313 + 1.1314 +# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.1315 +# This Source Code Form is subject to the terms of the Mozilla Public 1.1316 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.1317 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.1318 + 1.1319 +# 1.1320 +# This is PrefWindow 6. The Code Could Well Be Ready, Are You? 1.1321 +# 1.1322 +# Historical References: 1.1323 +# PrefWindow V (February 1, 2003) 1.1324 +# PrefWindow IV (April 24, 2000) 1.1325 +# PrefWindow III (January 6, 2000) 1.1326 +# PrefWindow II (???) 1.1327 +# PrefWindow I (June 4, 1999) 1.1328 +#