/toolkit/content/widgets/dialog.xml

http://github.com/zpao/v8monkey · XML · 438 lines · 386 code · 52 blank · 0 comment · 0 complexity · b98afbad3707de987e8c597a97cdd1de MD5 · raw file

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