Line 0
Link Here
|
|
|
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_GNOME |
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 |
#elif XP_UNIX |
586 |
pack="end"> |
587 |
<xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/> |
588 |
<xul:button dlgtype="extra2" class="dialog-button" hidden="true"/> |
589 |
<xul:spacer anonid="spacer" flex="1"/> |
590 |
<xul:button dlgtype="accept" class="dialog-button" icon="accept"/> |
591 |
<xul:button dlgtype="extra1" class="dialog-button" hidden="true"/> |
592 |
<xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/> |
593 |
<xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/> |
594 |
#else |
595 |
pack="end"> |
596 |
<xul:button dlgtype="extra2" class="dialog-button" hidden="true"/> |
597 |
<xul:spacer anonid="spacer" flex="1"/> |
598 |
<xul:button dlgtype="accept" class="dialog-button" icon="accept"/> |
599 |
<xul:button dlgtype="extra1" class="dialog-button" hidden="true"/> |
600 |
<xul:button dlgtype="cancel" class="dialog-button" icon="cancel"/> |
601 |
<xul:button dlgtype="help" class="dialog-button" hidden="true" icon="help"/> |
602 |
<xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/> |
603 |
#endif |
604 |
</xul:hbox> |
605 |
<xul:hbox> |
606 |
<children/> |
607 |
</xul:hbox> |
608 |
</content> |
609 |
<implementation implements="nsITimerCallback"> |
610 |
<constructor> |
611 |
<![CDATA[ |
612 |
if (this.type != "child") { |
613 |
var psvc = Components.classes["@mozilla.org/preferences-service;1"] |
614 |
.getService(Components.interfaces.nsIPrefBranch); |
615 |
this.instantApply = psvc.getBoolPref("browser.preferences.instantApply"); |
616 |
if (this.instantApply) { |
617 |
var docElt = document.documentElement; |
618 |
var acceptButton = docElt.getButton("accept"); |
619 |
acceptButton.hidden = true; |
620 |
var cancelButton = docElt.getButton("cancel"); |
621 |
#ifdef XP_MACOSX |
622 |
// no buttons on Mac except Help |
623 |
cancelButton.hidden = true; |
624 |
// Also, don't fire onDialogAccept on enter |
625 |
acceptButton.disabled = true; |
626 |
#else |
627 |
// morph the Cancel button into the Close button |
628 |
cancelButton.setAttribute ("icon", "close"); |
629 |
cancelButton.label = docElt.getAttribute("closebuttonlabel"); |
630 |
cancelButton.accesskey = docElt.getAttribute("closebuttonaccesskey"); |
631 |
#endif |
632 |
} |
633 |
} |
634 |
this.setAttribute("animated", this._shouldAnimate ? "true" : "false"); |
635 |
var panes = this.preferencePanes; |
636 |
|
637 |
var lastPane = null; |
638 |
if (this.lastSelected) { |
639 |
lastPane = document.getElementById(this.lastSelected); |
640 |
if (!lastPane) { |
641 |
this.lastSelected = ""; |
642 |
} |
643 |
} |
644 |
|
645 |
var paneToLoad; |
646 |
if ("arguments" in window && window.arguments[0] && document.getElementById(window.arguments[0]) && document.getElementById(window.arguments[0]).nodeName == "prefpane") { |
647 |
paneToLoad = document.getElementById(window.arguments[0]); |
648 |
this.lastSelected = paneToLoad.id; |
649 |
} |
650 |
else if (lastPane) |
651 |
paneToLoad = lastPane; |
652 |
else |
653 |
paneToLoad = panes[0]; |
654 |
|
655 |
for (var i = 0; i < panes.length; ++i) { |
656 |
this._makePaneButton(panes[i]); |
657 |
if (panes[i].loaded) { |
658 |
// Inline pane content, fire load event to force initialization. |
659 |
this._fireEvent("paneload", panes[i]); |
660 |
} |
661 |
} |
662 |
this.showPane(paneToLoad); |
663 |
|
664 |
if (panes.length == 1) |
665 |
this._selector.setAttribute("collapsed", "true"); |
666 |
]]> |
667 |
</constructor> |
668 |
|
669 |
<destructor> |
670 |
<![CDATA[ |
671 |
// Release timers to avoid reference cycles. |
672 |
if (this._animateTimer) { |
673 |
this._animateTimer.cancel(); |
674 |
this._animateTimer = null; |
675 |
} |
676 |
if (this._fadeTimer) { |
677 |
this._fadeTimer.cancel(); |
678 |
this._fadeTimer = null; |
679 |
} |
680 |
]]> |
681 |
</destructor> |
682 |
|
683 |
<field name="instantApply">false</field> |
684 |
|
685 |
<property name="preferencePanes" |
686 |
onget="return this.getElementsByTagName('prefpane');"/> |
687 |
|
688 |
<property name="type" onget="return this.getAttribute('type');"/> |
689 |
<property name="_paneDeck" |
690 |
onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'paneDeck');"/> |
691 |
<property name="_paneDeckContainer" |
692 |
onget="return document.getAnonymousElementByAttribute(this, 'class', 'paneDeckContainer');"/> |
693 |
<property name="_selector" |
694 |
onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'selector');"/> |
695 |
<property name="lastSelected" |
696 |
onget="return this.getAttribute('lastSelected');"> |
697 |
<setter> |
698 |
this.setAttribute("lastSelected", val); |
699 |
document.persist(this.id, "lastSelected"); |
700 |
return val; |
701 |
</setter> |
702 |
</property> |
703 |
<property name="currentPane" |
704 |
onset="return this._currentPane = val;"> |
705 |
<getter> |
706 |
if (!this._currentPane) |
707 |
this._currentPane = this.preferencePanes[0]; |
708 |
|
709 |
return this._currentPane; |
710 |
</getter> |
711 |
</property> |
712 |
<field name="_currentPane">null</field> |
713 |
|
714 |
|
715 |
<method name="_makePaneButton"> |
716 |
<parameter name="aPaneElement"/> |
717 |
<body> |
718 |
<![CDATA[ |
719 |
var radio = document.createElement("radio"); |
720 |
radio.setAttribute("pane", aPaneElement.id); |
721 |
radio.setAttribute("label", aPaneElement.label); |
722 |
// Expose preference group choice to accessibility APIs as an unchecked list item |
723 |
// The parent group is exposed to accessibility APIs as a list |
724 |
if (aPaneElement.image) |
725 |
radio.setAttribute("src", aPaneElement.image); |
726 |
radio.style.listStyleImage = aPaneElement.style.listStyleImage; |
727 |
this._selector.appendChild(radio); |
728 |
return radio; |
729 |
]]> |
730 |
</body> |
731 |
</method> |
732 |
|
733 |
<method name="showPane"> |
734 |
<parameter name="aPaneElement"/> |
735 |
<body> |
736 |
<![CDATA[ |
737 |
if (!aPaneElement) |
738 |
return; |
739 |
|
740 |
this._selector.selectedItem = document.getAnonymousElementByAttribute(this, "pane", aPaneElement.id); |
741 |
if (!aPaneElement.loaded) { |
742 |
function OverlayLoadObserver(aPane) |
743 |
{ |
744 |
this._pane = aPane; |
745 |
} |
746 |
OverlayLoadObserver.prototype = { |
747 |
_outer: this, |
748 |
observe: function (aSubject, aTopic, aData) |
749 |
{ |
750 |
this._pane.loaded = true; |
751 |
this._outer._fireEvent("paneload", this._pane); |
752 |
this._outer._selectPane(this._pane); |
753 |
} |
754 |
}; |
755 |
|
756 |
var obs = new OverlayLoadObserver(aPaneElement); |
757 |
document.loadOverlay(aPaneElement.src, obs); |
758 |
} |
759 |
else |
760 |
this._selectPane(aPaneElement); |
761 |
]]> |
762 |
</body> |
763 |
</method> |
764 |
|
765 |
<method name="_fireEvent"> |
766 |
<parameter name="aEventName"/> |
767 |
<parameter name="aTarget"/> |
768 |
<body> |
769 |
<![CDATA[ |
770 |
// Panel loaded, synthesize a load event. |
771 |
try { |
772 |
var event = document.createEvent("Events"); |
773 |
event.initEvent(aEventName, true, true); |
774 |
var cancel = !aTarget.dispatchEvent(event); |
775 |
if (aTarget.hasAttribute("on" + aEventName)) { |
776 |
var fn = new Function ("event", aTarget.getAttribute("on" + aEventName)); |
777 |
var rv = fn.call(aTarget, event); |
778 |
if (rv == false) |
779 |
cancel = true; |
780 |
} |
781 |
return !cancel; |
782 |
} |
783 |
catch (e) { |
784 |
Components.utils.reportError(e); |
785 |
} |
786 |
return false; |
787 |
]]> |
788 |
</body> |
789 |
</method> |
790 |
|
791 |
<field name="_initialized">false</field> |
792 |
<method name="_selectPane"> |
793 |
<parameter name="aPaneElement"/> |
794 |
<body> |
795 |
<![CDATA[ |
796 |
#ifdef XP_MACOSX |
797 |
var paneTitle = aPaneElement.label; |
798 |
if (paneTitle != "") |
799 |
document.title = paneTitle; |
800 |
#endif |
801 |
var helpButton = document.documentElement.getButton("help"); |
802 |
if (aPaneElement.helpTopic) |
803 |
helpButton.hidden = false; |
804 |
else |
805 |
helpButton.hidden = true; |
806 |
|
807 |
// Find this pane's index in the deck and set the deck's |
808 |
// selectedIndex to that value to switch to it. |
809 |
var prefpanes = this.preferencePanes; |
810 |
for (var i = 0; i < prefpanes.length; ++i) { |
811 |
if (prefpanes[i] == aPaneElement) { |
812 |
this._paneDeck.selectedIndex = i; |
813 |
|
814 |
if (this.type != "child") { |
815 |
if (aPaneElement.hasAttribute("flex") && this._shouldAnimate && |
816 |
prefpanes.length > 1) |
817 |
aPaneElement.removeAttribute("flex"); |
818 |
// Calling sizeToContent after the first prefpane is loaded |
819 |
// will size the windows contents so style information is |
820 |
// available to calculate correct sizing. |
821 |
if (!this._initialized && prefpanes.length > 1) { |
822 |
if (this._shouldAnimate) |
823 |
this.style.minHeight = 0; |
824 |
window.sizeToContent(); |
825 |
} |
826 |
|
827 |
var oldPane = this.lastSelected ? document.getElementById(this.lastSelected) : this.preferencePanes[0]; |
828 |
oldPane.selected = !(aPaneElement.selected = true); |
829 |
this.lastSelected = aPaneElement.id; |
830 |
this.currentPane = aPaneElement; |
831 |
this._initialized = true; |
832 |
|
833 |
// Only animate if we've switched between prefpanes |
834 |
if (this._shouldAnimate && oldPane.id != aPaneElement.id) { |
835 |
aPaneElement.style.opacity = 0.0; |
836 |
this.animate(oldPane, aPaneElement); |
837 |
} |
838 |
else if (!this._shouldAnimate && prefpanes.length > 1) { |
839 |
var targetHeight = parseInt(window.getComputedStyle(this._paneDeckContainer, "").height); |
840 |
var verticalPadding = parseInt(window.getComputedStyle(aPaneElement, "").paddingTop); |
841 |
verticalPadding += parseInt(window.getComputedStyle(aPaneElement, "").paddingBottom); |
842 |
if (aPaneElement.contentHeight > targetHeight - verticalPadding) { |
843 |
// To workaround the bottom border of a groupbox from being |
844 |
// cutoff an hbox with a class of bottomBox may enclose it. |
845 |
// This needs to include its padding to resize properly. |
846 |
// See bug 394433 |
847 |
var bottomPadding = 0; |
848 |
var bottomBox = aPaneElement.getElementsByAttribute("class", "bottomBox")[0]; |
849 |
if (bottomBox) |
850 |
bottomPadding = parseInt(window.getComputedStyle(bottomBox, "").paddingBottom); |
851 |
window.innerHeight += bottomPadding + verticalPadding + aPaneElement.contentHeight - targetHeight; |
852 |
} |
853 |
|
854 |
// XXX rstrong - extend the contents of the prefpane to |
855 |
// prevent elements from being cutoff (see bug 349098). |
856 |
if (aPaneElement.contentHeight + verticalPadding < targetHeight) |
857 |
aPaneElement._content.style.height = targetHeight - verticalPadding + "px"; |
858 |
} |
859 |
} |
860 |
break; |
861 |
} |
862 |
} |
863 |
]]> |
864 |
</body> |
865 |
</method> |
866 |
|
867 |
<property name="_shouldAnimate"> |
868 |
<getter> |
869 |
<![CDATA[ |
870 |
var psvc = Components.classes["@mozilla.org/preferences-service;1"] |
871 |
.getService(Components.interfaces.nsIPrefBranch); |
872 |
#ifdef XP_MACOSX |
873 |
var animate = true; |
874 |
#else |
875 |
var animate = false; |
876 |
#endif |
877 |
try { |
878 |
animate = psvc.getBoolPref("browser.preferences.animateFadeIn"); |
879 |
} |
880 |
catch (e) { } |
881 |
return animate; |
882 |
]]> |
883 |
</getter> |
884 |
</property> |
885 |
|
886 |
<method name="animate"> |
887 |
<parameter name="aOldPane"/> |
888 |
<parameter name="aNewPane"/> |
889 |
<body> |
890 |
<![CDATA[ |
891 |
// if we are already resizing, use currentHeight |
892 |
var oldHeight = this._currentHeight ? this._currentHeight : aOldPane.contentHeight; |
893 |
|
894 |
this._multiplier = aNewPane.contentHeight > oldHeight ? 1 : -1; |
895 |
var sizeDelta = Math.abs(oldHeight - aNewPane.contentHeight); |
896 |
this._animateRemainder = sizeDelta % this._animateIncrement; |
897 |
|
898 |
this._setUpAnimationTimer(oldHeight); |
899 |
]]> |
900 |
</body> |
901 |
</method> |
902 |
|
903 |
<property name="_sizeIncrement"> |
904 |
<getter> |
905 |
<![CDATA[ |
906 |
var lastSelectedPane = document.getElementById(this.lastSelected); |
907 |
var increment = this._animateIncrement * this._multiplier; |
908 |
var newHeight = this._currentHeight + increment; |
909 |
if ((this._multiplier > 0 && this._currentHeight >= lastSelectedPane.contentHeight) || |
910 |
(this._multiplier < 0 && this._currentHeight <= lastSelectedPane.contentHeight)) |
911 |
return 0; |
912 |
|
913 |
if ((this._multiplier > 0 && newHeight > lastSelectedPane.contentHeight) || |
914 |
(this._multiplier < 0 && newHeight < lastSelectedPane.contentHeight)) |
915 |
increment = this._animateRemainder * this._multiplier; |
916 |
return increment; |
917 |
]]> |
918 |
</getter> |
919 |
</property> |
920 |
|
921 |
<method name="notify"> |
922 |
<parameter name="aTimer"/> |
923 |
<body> |
924 |
<![CDATA[ |
925 |
if (!document) |
926 |
aTimer.cancel(); |
927 |
|
928 |
if (aTimer == this._animateTimer) { |
929 |
var increment = this._sizeIncrement; |
930 |
if (increment != 0) { |
931 |
window.innerHeight += increment; |
932 |
this._currentHeight += increment; |
933 |
} |
934 |
else { |
935 |
aTimer.cancel(); |
936 |
this._setUpFadeTimer(); |
937 |
} |
938 |
} else if (aTimer == this._fadeTimer) { |
939 |
var elt = document.getElementById(this.lastSelected); |
940 |
var newOpacity = parseFloat(window.getComputedStyle(elt, "").opacity) + this._fadeIncrement; |
941 |
if (newOpacity < 1.0) |
942 |
elt.style.opacity = newOpacity; |
943 |
else { |
944 |
aTimer.cancel(); |
945 |
elt.style.opacity = 1.0; |
946 |
} |
947 |
} |
948 |
]]> |
949 |
</body> |
950 |
</method> |
951 |
|
952 |
<method name="_setUpAnimationTimer"> |
953 |
<parameter name="aStartHeight"/> |
954 |
<body> |
955 |
<![CDATA[ |
956 |
if (!this._animateTimer) |
957 |
this._animateTimer = Components.classes["@mozilla.org/timer;1"] |
958 |
.createInstance(Components.interfaces.nsITimer); |
959 |
else |
960 |
this._animateTimer.cancel(); |
961 |
this._currentHeight = aStartHeight; |
962 |
|
963 |
this._animateTimer.initWithCallback(this, this._animateDelay, |
964 |
Components.interfaces.nsITimer.TYPE_REPEATING_SLACK); |
965 |
]]> |
966 |
</body> |
967 |
</method> |
968 |
|
969 |
<method name="_setUpFadeTimer"> |
970 |
<body> |
971 |
<![CDATA[ |
972 |
if (!this._fadeTimer) |
973 |
this._fadeTimer = Components.classes["@mozilla.org/timer;1"] |
974 |
.createInstance(Components.interfaces.nsITimer); |
975 |
else |
976 |
this._fadeTimer.cancel(); |
977 |
|
978 |
this._fadeTimer.initWithCallback(this, this._fadeDelay, |
979 |
Components.interfaces.nsITimer.TYPE_REPEATING_SLACK); |
980 |
]]> |
981 |
</body> |
982 |
</method> |
983 |
|
984 |
<field name="_animateTimer">null</field> |
985 |
<field name="_fadeTimer">null</field> |
986 |
<field name="_animateDelay">15</field> |
987 |
<field name="_animateIncrement">40</field> |
988 |
<field name="_fadeDelay">5</field> |
989 |
<field name="_fadeIncrement">0.40</field> |
990 |
<field name="_animateRemainder">0</field> |
991 |
<field name="_currentHeight">0</field> |
992 |
<field name="_multiplier">0</field> |
993 |
|
994 |
<method name="addPane"> |
995 |
<parameter name="aPaneElement"/> |
996 |
<body> |
997 |
<![CDATA[ |
998 |
this.appendChild(aPaneElement); |
999 |
|
1000 |
// Set up pane button |
1001 |
this._makePaneButton(aPaneElement); |
1002 |
]]> |
1003 |
</body> |
1004 |
</method> |
1005 |
|
1006 |
<method name="openSubDialog"> |
1007 |
<parameter name="aURL"/> |
1008 |
<parameter name="aFeatures"/> |
1009 |
<parameter name="aParams"/> |
1010 |
<body> |
1011 |
return openDialog(aURL, "", "modal,centerscreen,resizable=no" + (aFeatures != "" ? ("," + aFeatures) : ""), aParams); |
1012 |
</body> |
1013 |
</method> |
1014 |
|
1015 |
<method name="openWindow"> |
1016 |
<parameter name="aWindowType"/> |
1017 |
<parameter name="aURL"/> |
1018 |
<parameter name="aFeatures"/> |
1019 |
<parameter name="aParams"/> |
1020 |
<body> |
1021 |
<![CDATA[ |
1022 |
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] |
1023 |
.getService(Components.interfaces.nsIWindowMediator); |
1024 |
var win = aWindowType ? wm.getMostRecentWindow(aWindowType) : null; |
1025 |
if (win) { |
1026 |
if ("initWithParams" in win) |
1027 |
win.initWithParams(aParams); |
1028 |
win.focus(); |
1029 |
} |
1030 |
else { |
1031 |
var features = "resizable,dialog=no,centerscreen" + (aFeatures != "" ? ("," + aFeatures) : ""); |
1032 |
var parentWindow = (this.instantApply || !window.opener || window.opener.closed) ? window : window.opener; |
1033 |
win = parentWindow.openDialog(aURL, "_blank", features, aParams); |
1034 |
} |
1035 |
return win; |
1036 |
]]> |
1037 |
</body> |
1038 |
</method> |
1039 |
</implementation> |
1040 |
<handlers> |
1041 |
<handler event="dialogaccept"> |
1042 |
<![CDATA[ |
1043 |
if (!this._fireEvent("beforeaccept", this)) |
1044 |
return; |
1045 |
|
1046 |
if (this.type == "child" && window.opener) { |
1047 |
var psvc = Components.classes["@mozilla.org/preferences-service;1"] |
1048 |
.getService(Components.interfaces.nsIPrefBranch); |
1049 |
var instantApply = psvc.getBoolPref("browser.preferences.instantApply"); |
1050 |
if (instantApply) { |
1051 |
var panes = this.preferencePanes; |
1052 |
for (var i = 0; i < panes.length; ++i) |
1053 |
panes[i].writePreferences(true); |
1054 |
} |
1055 |
else { |
1056 |
// Clone all the preferences elements from the child document and |
1057 |
// insert them into the pane collection of the parent. |
1058 |
var pdoc = window.opener.document; |
1059 |
if (pdoc.documentElement.localName == "prefwindow") { |
1060 |
var currentPane = pdoc.documentElement.currentPane; |
1061 |
var id = window.location.href + "#childprefs"; |
1062 |
var childPrefs = pdoc.getElementById(id); |
1063 |
if (!childPrefs) { |
1064 |
var childPrefs = pdoc.createElement("preferences"); |
1065 |
currentPane.appendChild(childPrefs); |
1066 |
childPrefs.id = id; |
1067 |
} |
1068 |
var panes = this.preferencePanes; |
1069 |
for (var i = 0; i < panes.length; ++i) { |
1070 |
var preferences = panes[i].preferences; |
1071 |
for (var j = 0; j < preferences.length; ++j) { |
1072 |
// Try to find a preference element for the same preference. |
1073 |
var preference = null; |
1074 |
var parentPreferences = pdoc.getElementsByTagName("preferences"); |
1075 |
for (var k = 0; (k < parentPreferences.length && !preference); ++k) { |
1076 |
var parentPrefs = parentPreferences[k] |
1077 |
.getElementsByAttribute("name", preferences[j].name); |
1078 |
for (var l = 0; (l < parentPrefs.length && !preference); ++l) { |
1079 |
if (parentPrefs[l].localName == "preference") |
1080 |
preference = parentPrefs[l]; |
1081 |
} |
1082 |
} |
1083 |
if (!preference) { |
1084 |
// No matching preference in the parent window. |
1085 |
preference = pdoc.createElement("preference"); |
1086 |
childPrefs.appendChild(preference); |
1087 |
preference.name = preferences[j].name; |
1088 |
preference.type = preferences[j].type; |
1089 |
preference.inverted = preferences[j].inverted; |
1090 |
preference.readonly = preferences[j].readonly; |
1091 |
preference.disabled = preferences[j].disabled; |
1092 |
} |
1093 |
preference.value = preferences[j].value; |
1094 |
} |
1095 |
} |
1096 |
} |
1097 |
} |
1098 |
} |
1099 |
else { |
1100 |
var panes = this.preferencePanes; |
1101 |
for (var i = 0; i < panes.length; ++i) |
1102 |
panes[i].writePreferences(false); |
1103 |
|
1104 |
var psvc = Components.classes["@mozilla.org/preferences-service;1"] |
1105 |
.getService(Components.interfaces.nsIPrefService); |
1106 |
psvc.savePrefFile(null); |
1107 |
} |
1108 |
]]> |
1109 |
</handler> |
1110 |
<handler event="command"> |
1111 |
if (event.originalTarget.hasAttribute("pane")) { |
1112 |
var pane = document.getElementById(event.originalTarget.getAttribute("pane")); |
1113 |
this.showPane(pane); |
1114 |
} |
1115 |
</handler> |
1116 |
|
1117 |
<handler event="keypress" key="&windowClose.key;" modifiers="accel" phase="capturing"> |
1118 |
<![CDATA[ |
1119 |
if (this.instantApply) |
1120 |
window.close(); |
1121 |
event.stopPropagation(); |
1122 |
event.preventDefault(); |
1123 |
]]> |
1124 |
</handler> |
1125 |
|
1126 |
<handler event="keypress" |
1127 |
#ifdef XP_MACOSX |
1128 |
key="&openHelpMac.commandkey;" modifiers="accel" |
1129 |
#else |
1130 |
keycode="&openHelp.commandkey;" |
1131 |
#endif |
1132 |
phase="capturing"> |
1133 |
<![CDATA[ |
1134 |
var helpButton = this.getButton("help"); |
1135 |
if (helpButton.disabled || helpButton.hidden) |
1136 |
return; |
1137 |
this._fireEvent("dialoghelp", this); |
1138 |
event.stopPropagation(); |
1139 |
event.preventDefault(); |
1140 |
]]> |
1141 |
</handler> |
1142 |
</handlers> |
1143 |
</binding> |
1144 |
|
1145 |
<binding id="prefpane"> |
1146 |
<resources> |
1147 |
<stylesheet src="chrome://global/skin/preferences.css"/> |
1148 |
</resources> |
1149 |
<content> |
1150 |
<xul:vbox class="content-box" xbl:inherits="flex"> |
1151 |
<children/> |
1152 |
</xul:vbox> |
1153 |
</content> |
1154 |
<implementation> |
1155 |
<method name="writePreferences"> |
1156 |
<parameter name="aFlushToDisk"/> |
1157 |
<body> |
1158 |
<![CDATA[ |
1159 |
// Write all values to preferences. |
1160 |
var preferences = this.preferences; |
1161 |
for (var i = 0; i < preferences.length; ++i) { |
1162 |
var preference = preferences[i]; |
1163 |
preference.batching = true; |
1164 |
preference.valueFromPreferences = preference.value; |
1165 |
preference.batching = false; |
1166 |
} |
1167 |
if (aFlushToDisk) { |
1168 |
var psvc = Components.classes["@mozilla.org/preferences-service;1"] |
1169 |
.getService(Components.interfaces.nsIPrefService); |
1170 |
psvc.savePrefFile(null); |
1171 |
} |
1172 |
]]> |
1173 |
</body> |
1174 |
</method> |
1175 |
|
1176 |
<property name="src" |
1177 |
onget="return this.getAttribute('src');" |
1178 |
onset="this.setAttribute('src', val); return val;"/> |
1179 |
<property name="selected" |
1180 |
onget="return this.getAttribute('selected') == 'true';" |
1181 |
onset="this.setAttribute('selected', val); return val;"/> |
1182 |
<property name="image" |
1183 |
onget="return this.getAttribute('image');" |
1184 |
onset="this.setAttribute('image', val); return val;"/> |
1185 |
<property name="label" |
1186 |
onget="return this.getAttribute('label');" |
1187 |
onset="this.setAttribute('label', val); return val;"/> |
1188 |
|
1189 |
<property name="preferenceElements" |
1190 |
onget="return this.getElementsByAttribute('preference', '*');"/> |
1191 |
<property name="preferences" |
1192 |
onget="return this.getElementsByTagName('preference');"/> |
1193 |
|
1194 |
<property name="helpTopic"> |
1195 |
<getter> |
1196 |
<![CDATA[ |
1197 |
// if there are tabs, and the selected tab provides a helpTopic, return that |
1198 |
var box = this.getElementsByTagName("tabbox"); |
1199 |
if (box[0]) { |
1200 |
var tab = box[0].selectedTab; |
1201 |
if (tab && tab.hasAttribute("helpTopic")) |
1202 |
return tab.getAttribute("helpTopic"); |
1203 |
} |
1204 |
|
1205 |
// otherwise, return the helpTopic of the current panel |
1206 |
return this.getAttribute("helpTopic"); |
1207 |
]]> |
1208 |
</getter> |
1209 |
</property> |
1210 |
|
1211 |
<field name="_loaded">false</field> |
1212 |
<property name="loaded" |
1213 |
onget="return !this.src ? true : this._loaded;" |
1214 |
onset="this._loaded = val; return val;"/> |
1215 |
|
1216 |
<method name="preferenceForElement"> |
1217 |
<parameter name="aElement"/> |
1218 |
<body> |
1219 |
return document.getElementById(aElement.getAttribute("preference")); |
1220 |
</body> |
1221 |
</method> |
1222 |
|
1223 |
<method name="getPreferenceElement"> |
1224 |
<parameter name="aStartElement"/> |
1225 |
<body> |
1226 |
<![CDATA[ |
1227 |
var temp = aStartElement; |
1228 |
while (temp && temp.nodeType == Node.ELEMENT_NODE && |
1229 |
!temp.hasAttribute("preference")) |
1230 |
temp = temp.parentNode; |
1231 |
return temp.nodeType == Node.ELEMENT_NODE ? temp : aStartElement; |
1232 |
]]> |
1233 |
</body> |
1234 |
</method> |
1235 |
|
1236 |
<method name="userChangedValue"> |
1237 |
<parameter name="aElement"/> |
1238 |
<body> |
1239 |
<![CDATA[ |
1240 |
var element = this.getPreferenceElement(aElement); |
1241 |
if (element.hasAttribute("preference")) { |
1242 |
var preference = document.getElementById(element.getAttribute("preference")); |
1243 |
var prefVal = preference.getElementValue(element); |
1244 |
preference.value = prefVal; |
1245 |
} |
1246 |
]]> |
1247 |
</body> |
1248 |
</method> |
1249 |
|
1250 |
<property name="contentHeight"> |
1251 |
<getter> |
1252 |
var targetHeight = parseInt(window.getComputedStyle(this._content, "").height); |
1253 |
targetHeight += parseInt(window.getComputedStyle(this._content, "").marginTop); |
1254 |
targetHeight += parseInt(window.getComputedStyle(this._content, "").marginBottom); |
1255 |
return targetHeight; |
1256 |
</getter> |
1257 |
</property> |
1258 |
<field name="_content"> |
1259 |
document.getAnonymousElementByAttribute(this, "class", "content-box"); |
1260 |
</field> |
1261 |
</implementation> |
1262 |
<handlers> |
1263 |
<handler event="command"> |
1264 |
// This "command" event handler tracks changes made to preferences by |
1265 |
// the user in this window. |
1266 |
if (event.sourceEvent) |
1267 |
event = event.sourceEvent; |
1268 |
this.userChangedValue(event.target); |
1269 |
</handler> |
1270 |
<handler event="select"> |
1271 |
// This "select" event handler tracks changes made to colorpicker |
1272 |
// preferences by the user in this window. |
1273 |
if (event.target.localName == "colorpicker") |
1274 |
this.userChangedValue(event.target); |
1275 |
</handler> |
1276 |
<handler event="change"> |
1277 |
// This "change" event handler tracks changes made to preferences by |
1278 |
// the user in this window. |
1279 |
this.userChangedValue(event.target); |
1280 |
</handler> |
1281 |
<handler event="input"> |
1282 |
// This "input" event handler tracks changes made to preferences by |
1283 |
// the user in this window. |
1284 |
this.userChangedValue(event.target); |
1285 |
</handler> |
1286 |
<handler event="paneload"> |
1287 |
<![CDATA[ |
1288 |
// Initialize all values from preferences. |
1289 |
var elements = this.preferenceElements; |
1290 |
for (var i = 0; i < elements.length; ++i) { |
1291 |
try { |
1292 |
var preference = this.preferenceForElement(elements[i]); |
1293 |
preference.setElementValue(elements[i]); |
1294 |
} |
1295 |
catch (e) { |
1296 |
dump("*** No preference found for " + elements[i].getAttribute("preference") + "\n"); |
1297 |
} |
1298 |
} |
1299 |
]]> |
1300 |
</handler> |
1301 |
</handlers> |
1302 |
</binding> |
1303 |
|
1304 |
<binding id="panebutton" extends="chrome://global/content/bindings/radio.xml#radio"> |
1305 |
<resources> |
1306 |
<stylesheet src="chrome://global/skin/preferences.css"/> |
1307 |
</resources> |
1308 |
<content> |
1309 |
<xul:image class="paneButtonIcon" xbl:inherits="src"/> |
1310 |
<xul:label class="paneButtonLabel" xbl:inherits="value=label"/> |
1311 |
</content> |
1312 |
<implementation implements="nsIAccessible"> |
1313 |
<property name="accessibleType" readonly="true"> |
1314 |
<getter> |
1315 |
<![CDATA[ |
1316 |
return Components.interfaces.nsIAccessibleProvider.XULListitem; |
1317 |
]]> |
1318 |
</getter> |
1319 |
</property> |
1320 |
</implementation> |
1321 |
</binding> |
1322 |
|
1323 |
</bindings> |
1324 |
|
1325 |
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
1326 |
# This Source Code Form is subject to the terms of the Mozilla Public |
1327 |
# License, v. 2.0. If a copy of the MPL was not distributed with this |
1328 |
# file, You can obtain one at http://mozilla.org/MPL/2.0/. |
1329 |
|
1330 |
# |
1331 |
# This is PrefWindow 6. The Code Could Well Be Ready, Are You? |
1332 |
# |
1333 |
# Historical References: |
1334 |
# PrefWindow V (February 1, 2003) |
1335 |
# PrefWindow IV (April 24, 2000) |
1336 |
# PrefWindow III (January 6, 2000) |
1337 |
# PrefWindow II (???) |
1338 |
# PrefWindow I (June 4, 1999) |
1339 |
# |