bug 481914 - dialogs shouldn't be larger than available screen space. Listen to soft keyboad notifications r=neil
authorBrad Lassey <blassey@mozilla.com>
Mon, 20 Apr 2009 02:17:48 -0400
changeset 28033 cd77eb6f23bffb6acc4471669c9b1b01a64b1217
parent 28032 84f6d4fbaf1539b5ebd808be8db718035d775bf7
child 28034 869fd52a1854048f74dcd65550e0fc5ed2994486
push id6850
push userblassey@mozilla.com
push dateWed, 06 May 2009 14:59:50 +0000
treeherdermozilla-central@cd77eb6f23bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersneil
bugs481914
milestone1.9.2a1pre
bug 481914 - dialogs shouldn't be larger than available screen space. Listen to soft keyboad notifications r=neil
toolkit/content/commonDialog.js
toolkit/content/commonDialog.xul
--- a/toolkit/content/commonDialog.js
+++ b/toolkit/content/commonDialog.js
@@ -1,8 +1,9 @@
+/* -*- Mode: C;  c-basic-offset: 2; tab-width: 2; indent-tabs-mode: nil; -*- */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
@@ -33,19 +34,23 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cc = Components.classes;
+
 // parameters to gCommonDialogParam.Get() are defined in nsPIPromptService.idl
 var gCommonDialogParam = 
-  window.arguments[0].QueryInterface(Components.interfaces.nsIDialogParamBlock);
+  window.arguments[0].QueryInterface(Ci.nsIDialogParamBlock);
   
 function showControls()
 {
   // This is called before onload fires, so we can't be certain that any elements
   // in the document have their bindings ready, so don't call any methods/properties
   // here on xul elements that come from xbl bindings.
   
   // show the required textboxes and set their initial values
@@ -96,28 +101,53 @@ function setLabelForNode(aNode, aLabel, 
   }
 
   // XXXjag bug 325251
   // Need to set this after aNode.setAttribute("value", aLabel);
   if (accessKey)
     aNode.accessKey = accessKey;
 }
 
+var softkbObserver = {
+ QueryInterface: function (aIID) {
+    if (aIID.equals(Ci.nsISupports) ||
+        aIID.equals(Ci.nsIObserver))
+      return this;
+    throw Cr.NS_ERROR_NO_INTERFACE;
+  },
+ observe: function(subject, topic, data) {
+    if (topic === "softkb-change") {
+      var rect = JSON.parse(data);
+      if (rect) {
+        var height = rect.bottom - rect.top;
+        var width = rect.right - rect.left;
+        var top = (rect.top + (height - window.innerHeight) / 2);
+        var left = (rect.left + (width - window.innerWidth) / 2);
+        window.moveTo(left, top);
+      }
+    }
+  }
+};
+
 function commonDialogOnLoad()
 {
   // limit the dialog to the screen width
   document.getElementById("filler").maxWidth = screen.availWidth;
 
   // set the document title
 #ifdef XP_MACOSX
   setElementText("info.title", gCommonDialogParam.GetString(12), true);
 #else
   document.title = gCommonDialogParam.GetString(12);
 #endif
 
+  var observerService = Cc["@mozilla.org/observer-service;1"]
+                          .getService(Ci.nsIObserverService);
+  observerService.addObserver(softkbObserver, "softkb-change", false);
+
   // set the number of command buttons
   var nButtons = gCommonDialogParam.GetInt(2);
   var dialog = document.documentElement;
   switch (nButtons) {
     case 1:
       dialog.getButton("cancel").hidden = true;
       break;
     case 4:
@@ -177,18 +207,18 @@ function commonDialogOnLoad()
     document.documentElement.getButton(dButton).focus();
 #endif
   }
 
   if (gCommonDialogParam.GetInt(6) != 0) // delay button enable
   {
     var delayInterval = 2000;
     try {
-      var prefs = Components.classes["@mozilla.org/preferences-service;1"]
-                  .getService(Components.interfaces.nsIPrefBranch);
+      var prefs = Cc["@mozilla.org/preferences-service;1"]
+                    .getService(Ci.nsIPrefBranch);
       delayInterval = prefs.getIntPref("security.dialog_enable_delay");
     } catch (e) {}
 
     document.documentElement.getButton("accept").disabled = true;
     document.documentElement.getButton("extra1").disabled = true;
     document.documentElement.getButton("extra2").disabled = true;
 
     setTimeout(commonDialogReenableButtons, delayInterval);
@@ -198,23 +228,29 @@ function commonDialogOnLoad()
   }
 
   getAttention();
 
   // play sound
   try {
     var sound = gCommonDialogParam.GetString(13);
     if (sound) {
-      Components.classes["@mozilla.org/sound;1"]
-                .createInstance(Components.interfaces.nsISound)
-                .playSystemSound(sound);
+      Cc["@mozilla.org/sound;1"]
+        .createInstance(Ci.nsISound)
+        .playSystemSound(sound);
     }
   } catch (e) { }
 }
 
+function commonDialogOnUnload(){
+  var observerService = Cc["@mozilla.org/observer-service;1"]
+                          .getService(Ci.nsIObserverService);
+  observerService.removeObserver(softkbObserver, "softkb-change");
+}
+
 var gDelayExpired = false;
 var gBlurred = false;
 
 function commonDialogBlur(aEvent)
 {
   if (aEvent.target != document)
     return;
   gBlurred = true;
--- a/toolkit/content/commonDialog.xul
+++ b/toolkit/content/commonDialog.xul
@@ -5,16 +5,17 @@
 <?xml-stylesheet href="chrome://global/skin/commonDialog.css" type="text/css"?>
 
 <!DOCTYPE dialog SYSTEM "chrome://global/locale/commonDialog.dtd">
 
 <dialog id="commonDialog"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 
         aria-describedby="info.body"
         onload="commonDialogOnLoad();"
+        onunload="commonDialogOnUnload();"
         ondialogaccept="return commonDialogOnAccept();"
         ondialogextra1="return commonDialogOnExtra1();"
         ondialogextra2="return commonDialogOnExtra2();"
         buttonpack="center">
     
   <script type="application/javascript" src="chrome://global/content/commonDialog.js"/>
   <script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"/>