Bug 801080 - window.close should close social panels. r=felipe
authorMark Hammond <mhammond@skippinet.com.au>
Tue, 16 Oct 2012 13:53:37 +1100
changeset 110500 bf5f5e60f37c428e8ec10a4ad04758eedae7276e
parent 110499 6f970ea66426bacf74f4eec4357358423b0ce4ea
child 110501 9fd563bfcf501899da930cf750546711ecf202f8
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersfelipe
bugs801080
milestone19.0a1
Bug 801080 - window.close should close social panels. r=felipe
browser/base/content/test/browser_social_flyout.js
toolkit/components/social/MozSocialAPI.jsm
--- a/browser/base/content/test/browser_social_flyout.js
+++ b/browser/base/content/test/browser_social_flyout.js
@@ -73,30 +73,40 @@ var tests = {
           SocialFlyout.dispatchPanelEvent("socialTest-MakeWider");
           break;
       }
     }
     port.postMessage({topic: "test-init"});
   },
 
   testCloseSelf: function(next) {
+    // window.close is affected by the pref dom.allow_scripts_to_close_windows,
+    // which defaults to false, but is set to true by the test harness.
+    // so temporarily set it back.
+    const ALLOW_SCRIPTS_TO_CLOSE_PREF = "dom.allow_scripts_to_close_windows";
+    // note clearUserPref doesn't do what we expect, as the test harness itself
+    // changes the pref value - so clearUserPref resets it to false rather than
+    // the true setup by the test harness.
+    let oldAllowScriptsToClose = Services.prefs.getBoolPref(ALLOW_SCRIPTS_TO_CLOSE_PREF);    
+    Services.prefs.setBoolPref(ALLOW_SCRIPTS_TO_CLOSE_PREF, false);
     let panel = document.getElementById("social-flyout-panel");
     let port = Social.provider.getWorkerPort();
     ok(port, "provider has a port");
     port.onmessage = function (e) {
       let topic = e.data.topic;
       switch (topic) {
         case "test-init-done":
           port.postMessage({topic: "test-flyout-open"});
           break;
         case "got-flyout-visibility":
           let iframe = panel.firstChild;
           iframe.contentDocument.addEventListener("SocialTest-DoneCloseSelf", function _doneHandler() {
             iframe.contentDocument.removeEventListener("SocialTest-DoneCloseSelf", _doneHandler, false);
             is(panel.state, "closed", "flyout should have closed itself");
+            Services.prefs.setBoolPref(ALLOW_SCRIPTS_TO_CLOSE_PREF, oldAllowScriptsToClose);
             next();
           }, false);
           is(panel.state, "open", "flyout should be open");
           port.close(); // so we don't get the -visibility message as it hides...
           SocialFlyout.dispatchPanelEvent("socialTest-CloseSelf");
           break;
       }
     }
--- a/toolkit/components/social/MozSocialAPI.jsm
+++ b/toolkit/components/social/MozSocialAPI.jsm
@@ -174,16 +174,25 @@ function attachToWindow(provider, target
   });
 
   targetWindow.addEventListener("unload", function () {
     // We want to close the port, but also want the target window to be
     // able to use the port during an unload event they setup - so we
     // set a timer which will fire after the unload events have all fired.
     schedule(function () { port.close(); });
   });
+  // We allow window.close() to close the panel, so add an event handler for
+  // this, then cancel the event (so the window itself doesn't die) and
+  // close the panel instead.
+  // However, this is typically affected by the dom.allow_scripts_to_close_windows
+  // preference, but we can avoid that check by setting a flag on the window.
+  let dwu = targetWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                        .getInterface(Ci.nsIDOMWindowUtils);
+  dwu.allowScriptsToClose();
+
   targetWindow.addEventListener("DOMWindowClose", function _mozSocialDOMWindowClose(evt) {
     let elt = targetWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                 .getInterface(Ci.nsIWebNavigation)
                 .QueryInterface(Ci.nsIDocShell)
                 .chromeEventHandler;
     while (elt) {
       if (elt.nodeName == "panel") {
         elt.hidePopup();