!import
1 <?xml version="1.0"?>
2
3 <bindings id="dialogBindings"
4 xmlns="http://www.mozilla.org/xbl"
5 xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
6 xmlns:xbl="http://www.mozilla.org/xbl">
7
8 <binding id="dialog-base">
9 <resources>
10 <stylesheet src="chrome://global/skin/dialog.css"/>
11 </resources>
12 </binding>
13
14 <binding id="dialog" extends="chrome://global/content/bindings/dialog.xml#dialog-base">
15 <content>
16 <xul:vbox class="box-inherit dialog-content-box" flex="1">
17 <children/>
18 </xul:vbox>
19
20 <xul:hbox class="dialog-button-box" anonid="buttons"
21 xbl:inherits="pack=buttonpack,align=buttonalign,dir=buttondir,orient=buttonorient"
22 >
23 <xul:button dlgtype="disclosure" class="dialog-button" hidden="true"/>
24 <xul:button dlgtype="help" class="dialog-button" hidden="true"/>
25 <xul:button dlgtype="extra2" class="dialog-button" hidden="true"/>
26 <xul:button dlgtype="extra1" class="dialog-button" hidden="true"/>
27 <xul:spacer anonid="spacer" flex="1"/>
28 <xul:button dlgtype="cancel" class="dialog-button"/>
29 <xul:button dlgtype="accept" class="dialog-button" xbl:inherits="disabled=buttondisabledaccept"/>
30 </xul:hbox>
31 </content>
32
33 <implementation>
field__mStrBundle
34 <field name="_mStrBundle">null</field>
field__closeHandler
anon:35:7
35 <field name="_closeHandler">(function(event) {
36 if (!document.documentElement.cancelDialog())
37 event.preventDefault();
38 })</field>
39
get_buttons
set_buttons
40 <property name="buttons"
41 onget="return this.getAttribute('buttons');"
42 onset="this._configureButtons(val); return val;"/>
43
44 <property name="defaultButton">
get_defaultButton
45 <getter>
46 <![CDATA[
47 if (this.hasAttribute("defaultButton"))
48 return this.getAttribute("defaultButton");
49 else // default to the accept button
50 return "accept";
51 ]]>
52 </getter>
set_defaultButton
53 <setter>
54 <![CDATA[
55 this._setDefaultButton(val);
56 return val;
57 ]]>
58 </setter>
59 </property>
60
61 <method name="acceptDialog">
acceptDialog
62 <body>
63 <![CDATA[
64 return this._doButtonCommand("accept");
65 ]]>
66 </body>
67 </method>
68
69 <method name="cancelDialog">
cancelDialog
70 <body>
71 <![CDATA[
72 return this._doButtonCommand("cancel");
73 ]]>
74 </body>
75 </method>
76
77 <method name="getButton">
78 <parameter name="aDlgType"/>
getButton
79 <body>
80 <![CDATA[
81 return this._buttons[aDlgType];
82 ]]>
83 </body>
84 </method>
85
86 <method name="moveToAlertPosition">
moveToAlertPosition
87 <body>
88 <![CDATA[
89 // hack. we need this so the window has something like its final size
90 if (window.outerWidth == 1) {
91 dump("Trying to position a sizeless window; caller should have called sizeToContent() or sizeTo(). See bug 75649.\n");
92 sizeToContent();
93 }
94
95 var xOffset = (opener.outerWidth - window.outerWidth) / 2;
96 var yOffset = opener.outerHeight / 5;
97
98 var newX = opener.screenX + xOffset;
99 var newY = opener.screenY + yOffset;
100
101 // ensure the window is fully onscreen (if smaller than the screen)
102 if (newX < screen.availLeft)
103 newX = screen.availLeft + 20;
104 if ((newX + window.outerWidth) > (screen.availLeft + screen.availWidth))
105 newX = (screen.availLeft + screen.availWidth) - window.outerWidth - 20;
106
107 if (newY < screen.availTop)
108 newY = screen.availTop + 20;
109 if ((newY + window.outerHeight) > (screen.availTop + screen.availHeight))
110 newY = (screen.availTop + screen.availHeight) - window.outerHeight - 60;
111
112 window.moveTo( newX, newY );
113 ]]>
114 </body>
115 </method>
116
117 <method name="centerWindowOnScreen">
centerWindowOnScreen
118 <body>
119 <![CDATA[
120 var xOffset = screen.availWidth/2 - window.outerWidth/2;
121 var yOffset = screen.availHeight/2 - window.outerHeight/2; //(opener.outerHeight *2)/10;
122
123 xOffset = xOffset > 0 ? xOffset : 0;
124 yOffset = yOffset > 0 ? yOffset : 0;
125 window.moveTo(xOffset, yOffset);
126 ]]>
127 </body>
128 </method>
129
constructor
130 <constructor>
131 <![CDATA[
132 this._configureButtons(this.buttons);
133
134 // listen for when window is closed via native close buttons
135 window.addEventListener("close", this._closeHandler, false);
136
137 // for things that we need to initialize after onload fires
138 window.addEventListener("load", this.postLoadInit, false);
139
140 window.moveToAlertPosition = this.moveToAlertPosition;
141 window.centerWindowOnScreen = this.centerWindowOnScreen;
142 ]]>
143 </constructor>
144
145 <method name="postLoadInit">
146 <parameter name="aEvent"/>
postLoadInit
147 <body>
148 <![CDATA[
focusInit
149 function focusInit() {
150 // give focus to the first focusable element in the dialog
151 if (!document.commandDispatcher.focusedElement) {
152 document.commandDispatcher.advanceFocusIntoSubtree(document.documentElement);
153 var focusedElt = document.commandDispatcher.focusedElement;
154 if (focusedElt) {
155 if (focusedElt.localName == 'tab') {
156 // Move focus into the tab
157 document.commandDispatcher.advanceFocusIntoSubtree(focusedElt);
158 if (document.commandDispatcher.focusedElement.hasAttribute("dlgtype")) {
159 // We don't want to focus on anonymous OK, Cancel, etc. buttons,
160 // so return focus to the tab itself
161 focusedElt.focus();
162 }
163 }
164 }
165 }
166 }
167
168 // Give focus after onload completes, see bug 103197.
169 setTimeout(focusInit, 0);
170 ]]>
171 </body>
172 </method>
173
174 <property name="mStrBundle">
get_mStrBundle
175 <getter>
176 <![CDATA[
177 if (!this._mStrBundle) {
178 // need to create string bundle manually instead of using <xul:stringbundle/>
179 // see bug 63370 for details
180 var localeService = Components.classes["@mozilla.org/intl/nslocaleservice;1"]
181 .getService(Components.interfaces.nsILocaleService);
182 var stringBundleService = Components.classes["@mozilla.org/intl/stringbundle;1"]
183 .getService(Components.interfaces.nsIStringBundleService);
184 var bundleURL = "chrome://global/locale/dialog.properties";
185 this._mStrBundle = stringBundleService.createBundle(bundleURL, localeService.getApplicationLocale());
186 }
187 return this._mStrBundle;
188 ]]></getter>
189 </property>
190
191 <method name="_configureButtons">
192 <parameter name="aButtons"/>
_configureButtons
193 <body>
194 <![CDATA[
195 // by default, get all the anonymous button elements
196 var buttons = {};
197 this._buttons = buttons;
198 buttons.accept = document.getAnonymousElementByAttribute(this, "dlgtype", "accept");
199 buttons.cancel = document.getAnonymousElementByAttribute(this, "dlgtype", "cancel");
200 buttons.extra1 = document.getAnonymousElementByAttribute(this, "dlgtype", "extra1");
201 buttons.extra2 = document.getAnonymousElementByAttribute(this, "dlgtype", "extra2");
202 buttons.help = document.getAnonymousElementByAttribute(this, "dlgtype", "help");
203 buttons.disclosure = document.getAnonymousElementByAttribute(this, "dlgtype", "disclosure");
204
205 // look for any overriding explicit button elements
206 var exBtns = this.getElementsByAttribute("dlgtype", "*");
207 var dlgtype;
208 var i;
209 for (i = 0; i < exBtns.length; ++i) {
210 dlgtype = exBtns[i].getAttribute("dlgtype");
211 buttons[dlgtype].hidden = true; // hide the anonymous button
212 buttons[dlgtype] = exBtns[i];
213 }
214
215 // add the label and oncommand handler to each button
216 for (dlgtype in buttons) {
217 var button = buttons[dlgtype];
218 button.addEventListener("command", this._handleButtonCommand, true);
219
220 // don't override custom labels with pre-defined labels on explicit buttons
221 if (!button.hasAttribute("label")) {
222 // dialog attributes override the default labels in dialog.properties
223 if (this.hasAttribute("buttonlabel"+dlgtype)) {
224 button.setAttribute("label", this.getAttribute("buttonlabel"+dlgtype));
225 if (this.hasAttribute("buttonaccesskey"+dlgtype))
226 button.setAttribute("accesskey", this.getAttribute("buttonaccesskey"+dlgtype));
227 } else if (dlgtype != "extra1" && dlgtype != "extra2") {
228 button.setAttribute("label", this.mStrBundle.GetStringFromName("button-"+dlgtype));
229 var accessKey = this.mStrBundle.GetStringFromName("accesskey-"+dlgtype);
230 if (accessKey)
231 button.setAttribute("accesskey", accessKey);
232 }
233 }
234 // allow specifying alternate icons in the dialog header
235 if (!button.hasAttribute("icon")) {
236 // if there's an icon specified, use that
237 if (this.hasAttribute("buttonicon"+dlgtype))
238 button.setAttribute("icon", this.getAttribute("buttonicon"+dlgtype));
239 // otherwise set defaults
240 else
241 switch (dlgtype) {
242 case "accept":
243 button.setAttribute("icon","accept");
244 break;
245 case "cancel":
246 button.setAttribute("icon","cancel");
247 break;
248 case "disclosue":
249 button.setAttribute("icon","properties");
250 break;
251 case "help":
252 button.setAttribute("icon","help");
253 break;
254 default:
255 break;
256 }
257 }
258 }
259
260 // ensure that hitting enter triggers the default button command
261 this.defaultButton = this.defaultButton;
262
263 // if there is a special button configuration, use it
264 if (aButtons) {
265 // expect a comma delimited list of dlgtype values
266 var list = aButtons.split(",");
267
268 // mark shown dlgtypes as true
269 var shown = { accept: false, cancel: false, help: false,
270 disclosure: false, extra1: false, extra2: false };
271 for (i = 0; i < list.length; ++i)
272 shown[list[i].replace(/ /g, "")] = true;
273
274 // hide/show the buttons we want
275 for (dlgtype in buttons)
276 buttons[dlgtype].hidden = !shown[dlgtype];
277
278
279 }
280 ]]>
281 </body>
282 </method>
283
284 <method name="_setDefaultButton">
285 <parameter name="aNewDefault"/>
_setDefaultButton
286 <body>
287 <![CDATA[
288 // remove the default attribute from the previous default button, if any
289 var oldDefaultButton = this.getButton(this.defaultButton);
290 if (oldDefaultButton)
291 oldDefaultButton.removeAttribute("default");
292
293 var newDefaultButton = this.getButton(aNewDefault);
294 if (newDefaultButton) {
295 this.setAttribute("defaultButton", aNewDefault);
296 newDefaultButton.setAttribute("default", "true");
297 }
298 else {
299 this.setAttribute("defaultButton", "none");
300 if (aNewDefault != "none")
301 dump("invalid new default button: " + aNewDefault + ", assuming: none\n");
302 }
303 ]]>
304 </body>
305 </method>
306
307 <method name="_handleButtonCommand">
308 <parameter name="aEvent"/>
_handleButtonCommand
309 <body>
310 <![CDATA[
311 return document.documentElement._doButtonCommand(
312 aEvent.target.getAttribute("dlgtype"));
313 ]]>
314 </body>
315 </method>
316
317 <method name="_doButtonCommand">
318 <parameter name="aDlgType"/>
_doButtonCommand
319 <body>
320 <![CDATA[
321 var button = this.getButton(aDlgType);
322 if (!button.disabled) {
323 var noCancel = this._fireButtonEvent(aDlgType);
324 if (noCancel) {
325 if (aDlgType == "accept" || aDlgType == "cancel")
326 window.close();
327 }
328 return noCancel;
329 }
330 return true;
331 ]]>
332 </body>
333 </method>
334
335 <method name="_fireButtonEvent">
336 <parameter name="aDlgType"/>
_fireButtonEvent
337 <body>
338 <![CDATA[
339 var event = document.createEvent("Events");
340 event.initEvent("dialog"+aDlgType, true, true);
341
342 // handle dom event handlers
343 var noCancel = this.dispatchEvent(event);
344
345 // handle any xml attribute event handlers
346 var handler = this.getAttribute("ondialog"+aDlgType);
347 if (handler != "") {
anon:348:25
348 var fn = new Function("event", handler);
349 var returned = fn(event);
350 if (returned == false)
351 noCancel = false;
352 }
353
354 return noCancel;
355 ]]>
356 </body>
357 </method>
358
359 <method name="_hitEnter">
360 <parameter name="evt"/>
_hitEnter
361 <body>
362 <![CDATA[
363 if (evt.getPreventDefault())
364 return;
365
366 var btn = this.getButton(this.defaultButton);
367 if (btn)
368 this._doButtonCommand(this.defaultButton);
369 ]]>
370 </body>
371 </method>
372
373 </implementation>
374
375 <handlers>
onkeypress
376 <handler event="keypress" keycode="VK_ENTER"
377 group="system" action="this._hitEnter(event);"/>
onkeypress
378 <handler event="keypress" keycode="VK_RETURN"
379 group="system" action="this._hitEnter(event);"/>
onkeypress
380 <handler event="keypress" keycode="VK_ESCAPE" group="system">
381 if (!event.getPreventDefault())
382 this.cancelDialog();
383 </handler>
onkeypress
384 <handler event="keypress" key="." modifiers="meta" phase="capturing" action="this.cancelDialog();"/>
385 </handlers>
386
387 </binding>
388
389 <binding id="dialogheader" extends="chrome://global/content/bindings/dialog.xml#dialog-base">
390 <content>
391 <xul:label class="dialogheader-title" xbl:inherits="value=title,crop" crop="right" flex="1"/>
392 <xul:label class="dialogheader-description" xbl:inherits="value=description"/>
393 </content>
394 </binding>
395
396 </bindings>