Bug 518054: nsPromptService needs to fire event when opening modal dialogs [r=mark.finkle]
authorFabrice Desré <fabrice.desre@gmail.com>
Mon, 12 Oct 2009 15:05:46 -0400
changeset 65653 848bc8880bad94ecb72ba6adb5bcc4eb7955dbad
parent 65652 201429029e861828f16c8cc830325bbe47b9ee00
child 65654 a65a1742712d1e115539f39c858e319e7e9f82f1
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmark
bugs518054
Bug 518054: nsPromptService needs to fire event when opening modal dialogs [r=mark.finkle]
mobile/chrome/content/bindings/dialog.xml
mobile/chrome/content/browser.js
mobile/components/promptService.js
--- a/mobile/chrome/content/bindings/dialog.xml
+++ b/mobile/chrome/content/bindings/dialog.xml
@@ -12,16 +12,17 @@
         </xul:box>
         <xul:image collapsed="true" top="-10" left="0" anonid="close" class="close-button"
           onclick="document.getBindingParent(this).close()"/>
       </xul:stack>
     </content>
     
     <implementation implements="nsIDOMEventListener">
       <field name="arguments"/>
+      <field name="parent"/>
       
       <constructor><![CDATA[
         if (!this.hasAttribute("orient"))
           this.setAttribute("orient", "vertical");
         if (this.hasAttribute("closebutton") && (this.getAttribute("closebutton") == "true"))
           document.getAnonymousElementByAttribute(this, "anonid", "close").removeAttribute("collapsed");
         this._closed = false;
         if (this.hasAttribute("script")) {
@@ -48,16 +49,22 @@
       <method name="close">
         <body>
           if (this.hasAttribute("onclose")) {
             var f = new Function(this.getAttribute("onclose"));
             f.call(this);
           }
           this.parentNode.parentNode.removeChild(this.parentNode);
           this._closed = true;
+
+          // emit DOMModalDialogClosed event
+          let event = document.createEvent("Events");
+          event.initEvent("DOMModalDialogClosed", true, false);
+          let dispatcher = this.parent || getBrowser();
+          dispatcher.dispatchEvent(event);
         </body>
       </method>
       
       <method name="waitForClose">
         <body>
           let thread = Components.classes["@mozilla.org/thread-manager;1"]
                           .getService(Components.interfaces.nsIThreadManager)
                           .currentThread;
--- a/mobile/chrome/content/browser.js
+++ b/mobile/chrome/content/browser.js
@@ -2065,39 +2065,47 @@ var SoftKeyboardObserver = {
   }
 };
 #endif
 
 function getNotificationBox(aWindow) {
   return Browser.getNotificationBox();
 }
 
-function importDialog(src, arguments) {
+function importDialog(parent, src, arguments) {
   // load the dialog with a synchronous XHR
   let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
   xhr.open("GET", src, false);
   xhr.overrideMimeType("text/xml");
   xhr.send(null);
   if (!xhr.responseXML)
     return null;
+  
   let doc = xhr.responseXML.documentElement;
  
   var dialog  = null;
   
   // we need to insert before select-container if we want it to show correctly
   let selectContainer = document.getElementById("select-container");
   let parent = selectContainer.parentNode;
   
+  // emit DOMWillOpenModalDialog event
+  let event = document.createEvent("Events");
+  event.initEvent("DOMWillOpenModalDialog", true, false);
+  let dispatcher = parent || getBrowser();
+  dispatcher.dispatchEvent(event);
+
   // create a full-screen semi-opaque box as a background 
   let back = document.createElement("box");
   back.setAttribute("class", "modal-block");
   dialog = back.appendChild(document.importNode(doc, true));
   parent.insertBefore(back, selectContainer);
   
   dialog.arguments = arguments;
+  dialog.parent = parent;
   return dialog;
 }
 
 function showDownloadManager(aWindowContext, aID, aReason) {
   BrowserUI.showPanel("downloads-container");
   // TODO: select the download with aID
 }
 
--- a/mobile/components/promptService.js
+++ b/mobile/components/promptService.js
@@ -70,35 +70,35 @@ promptService.prototype = {
     
     let elem = this.getDocument().getElementById(id);
     let height = elem.getBoundingClientRect().height;
     if (height > maxHeight)
       height = maxHeight;
     elem.parentNode.style.height = height + "px";
   },
   
-  openDialog: function(src, params) {
+  openDialog: function(parent, src, params) {
     let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
     let browser = wm.getMostRecentWindow("navigator:browser");
-    return browser.importDialog(src, params);
+    return browser.importDialog(parent, src, params);
   },
   
   alert: function(aParent, aTitle, aText) {
-    let dialog = this.openDialog("chrome://browser/content/prompt/alert.xul", null);
+    let dialog = this.openDialog(aParent, "chrome://browser/content/prompt/alert.xul", null);
     let doc = this.getDocument();
     doc.getElementById("prompt-alert-title").value = aTitle;
     doc.getElementById("prompt-alert-message").appendChild(doc.createTextNode(aText));
     this.sizeElement("prompt-alert-message", 80);
     this.sizeScrollableMsg("prompt-alert-message", 25);
     
     dialog.waitForClose();
   },
   
   alertCheck: function(aParent, aTitle, aText, aCheckMsg, aCheckState) {
-    let dialog = this.openDialog("chrome://browser/content/prompt/alert.xul", aCheckState);
+    let dialog = this.openDialog(aParent, "chrome://browser/content/prompt/alert.xul", aCheckState);
     let doc = this.getDocument();
     doc.getElementById("prompt-alert-title").value = aTitle;
     doc.getElementById("prompt-alert-message").appendChild(doc.createTextNode(aText));
     this.sizeElement("prompt-alert-message", 80);
     this.sizeScrollableMsg("prompt-alert-message", 25);
     
     doc.getElementById("prompt-alert-checkbox").checked = aCheckState.value;
     this.setLabelForNode(doc.getElementById("prompt-alert-checkbox-msg"), aCheckMsg);
@@ -107,32 +107,32 @@ promptService.prototype = {
     
     dialog.waitForClose();
   },
   
   confirm: function(aParent, aTitle, aText) {
     var params = new Object();
     params.result = false;
     let doc = this.getDocument();
-    let dialog = this.openDialog("chrome://browser/content/prompt/confirm.xul", params);
+    let dialog = this.openDialog(aParent, "chrome://browser/content/prompt/confirm.xul", params);
     doc.getElementById("prompt-confirm-title").value = aTitle;
     doc.getElementById("prompt-confirm-message").appendChild(doc.createTextNode(aText));
     this.sizeElement("prompt-confirm-message", 80);
     this.sizeScrollableMsg("prompt-confirm-message", 25);
     
     dialog.waitForClose();
     return params.result;
   },
   
   confirmCheck: function(aParent, aTitle, aText, aCheckMsg, aCheckState) {
     var params = new Object();
     params.result = false;
     params.checkbox = aCheckState;
     let doc = this.getDocument();
-    let dialog = this.openDialog("chrome://browser/content/prompt/confirm.xul", params);
+    let dialog = this.openDialog(aParent, "chrome://browser/content/prompt/confirm.xul", params);
     doc.getElementById("prompt-confirm-title").value = aTitle;
     doc.getElementById("prompt-confirm-message").appendChild(doc.createTextNode(aText));
     this.sizeElement("prompt-confirm-message", 80);
     this.sizeScrollableMsg("prompt-confirm-message", 25);
 
     doc.getElementById("prompt-confirm-checkbox").checked = aCheckState.value;
     this.setLabelForNode(doc.getElementById("prompt-confirm-checkbox-msg"), aCheckMsg);
     this.sizeElement("prompt-confirm-checkbox-msg", 50);
@@ -193,17 +193,17 @@ promptService.prototype = {
             aButton1, aButton2, aCheckMsg, aCheckState) {
     let numButtons = 0;
     let titles = [aButton0, aButton1, aButton2];
     
     var params = new Object();
     params.result = false;
     params.checkbox = aCheckState;
     let doc = this.getDocument();
-    let dialog = this.openDialog("chrome://browser/content/prompt/confirm.xul", params);
+    let dialog = this.openDialog(aParent, "chrome://browser/content/prompt/confirm.xul", params);
     doc.getElementById("prompt-confirm-title").value = aTitle;
     doc.getElementById("prompt-confirm-message").appendChild(doc.createTextNode(aText));
     this.sizeElement("prompt-confirm-message", 80);
     this.sizeScrollableMsg("prompt-confirm-message", 25);
 
     doc.getElementById("prompt-confirm-checkbox").checked = aCheckState.value;
     this.setLabelForNode(doc.getElementById("prompt-confirm-checkbox-msg"), aCheckMsg);
     this.sizeElement("prompt-confirm-checkbox-msg", 50);
@@ -261,17 +261,17 @@ promptService.prototype = {
     return params.result;
   },
   
   commonPrompt : function(aParent, aTitle, aText, aValue, aCheckMsg, aCheckState, isPassword) {
     var params = new Object();
     params.result = false;
     params.checkbox = aCheckState;
     params.value = aValue;
-    let dialog = this.openDialog("chrome://browser/content/prompt/prompt.xul", params);
+    let dialog = this.openDialog(aParent, "chrome://browser/content/prompt/prompt.xul", params);
     let doc = this.getDocument();
     doc.getElementById("prompt-prompt-title").value = aTitle;
     doc.getElementById("prompt-prompt-message").appendChild(doc.createTextNode(aText));
     this.sizeElement("prompt-prompt-message", 80);
     this.sizeScrollableMsg("prompt-prompt-message", 25);
 
     doc.getElementById("prompt-prompt-checkbox").checked = aCheckState.value;
     this.setLabelForNode(doc.getElementById("prompt-prompt-checkbox-msg"), aCheckMsg);
@@ -297,17 +297,17 @@ promptService.prototype = {
   },
   
   promptUsernameAndPassword: function(aParent, aTitle, aText, aUsername, aPassword, aCheckMsg, aCheckState) {
     var params = new Object();
     params.result = false;
     params.checkbox = aCheckState;
     params.user = aUsername;
     params.password = aPassword;
-    let dialog = this.openDialog("chrome://browser/content/prompt/promptPassword.xul", params);
+    let dialog = this.openDialog(aParent, "chrome://browser/content/prompt/promptPassword.xul", params);
     let doc = this.getDocument();
     doc.getElementById("prompt-password-title").value = aTitle;
     doc.getElementById("prompt-password-message").appendChild(doc.createTextNode(aText));
     this.sizeElement("prompt-password-message", 80);
     this.sizeScrollableMsg("prompt-password-message", 25);
     doc.getElementById("prompt-password-checkbox").checked = aCheckState.value;
     
     doc.getElementById("prompt-password-user").value = aUsername.value;
@@ -418,17 +418,17 @@ promptService.prototype = {
     // bug 514196
     throw Cr.NS_ERROR_NOT_IMPLEMENTED;
   },
   
   select: function(aParent, aTitle, aText, aCount, aSelectList, aOutSelection) {
     var params = new Object();
     params.result = false;
     params.selection = aOutSelection;
-    let dialog = this.openDialog("chrome://browser/content/prompt/select.xul", params);
+    let dialog = this.openDialog(aParent, "chrome://browser/content/prompt/select.xul", params);
     let doc = this.getDocument();
     doc.getElementById("prompt-select-title").value = aTitle;
     doc.getElementById("prompt-select-message").appendChild(doc.createTextNode(aText));
     this.sizeElement("prompt-select-message", 80);
     this.sizeScrollableMsg("prompt-select-message", 25);
     
     let list = doc.getElementById("prompt-select-list");
     for (let i = 0; i < aCount; i++)