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