Bug 779360 - Implement mozSocial.isVisible API for social sidebar window, r=felipe
authorJared Wein <jwein@mozilla.com>
Mon, 20 Aug 2012 14:18:50 -0700
changeset 102873 23870683fcc22a20208bf1c7fddcd5f2e9c15acf
parent 102872 cbb72643bbae80d0ebbdcb851942742f7d6ba03b
child 102874 e778a1713d9b3e2b547f61d906fbee2a0f4917ae
push id23312
push useremorley@mozilla.com
push dateTue, 21 Aug 2012 13:23:13 +0000
treeherdermozilla-central@f9a8fdb08193 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe
bugs779360
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 779360 - Implement mozSocial.isVisible API for social sidebar window, r=felipe
browser/base/content/browser-social.js
browser/base/content/test/Makefile.in
browser/base/content/test/browser_social_isVisible.js
browser/base/content/test/browser_social_mozSocial_API.js
browser/base/content/test/social_sidebar.html
browser/base/content/test/social_worker.js
toolkit/components/social/MozSocialAPI.jsm
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -28,20 +28,27 @@ let SocialUI = {
   showProfile: function SocialUI_showProfile() {
     if (Social.provider)
       openUILink(Social.provider.profile.profileURL);
   },
 
   observe: function SocialUI_observe(subject, topic, data) {
     switch (topic) {
       case "social:pref-changed":
-        this.updateToggleCommand();
-        SocialShareButton.updateButtonHiddenState();
-        SocialToolbar.updateButtonHiddenState();
-        SocialSidebar.updateSidebar();
+        // Exceptions here sometimes don't get reported properly, report them
+        // manually :(
+        try {
+          this.updateToggleCommand();
+          SocialShareButton.updateButtonHiddenState();
+          SocialToolbar.updateButtonHiddenState();
+          SocialSidebar.updateSidebar();
+        } catch (e) {
+          Components.utils.reportError(e);
+          throw e;
+        }
         break;
       case "social:ambient-notification-changed":
         SocialToolbar.updateButton();
         break;
       case "social:profile-changed":
         SocialToolbar.updateProfile();
         SocialShareButton.updateProfileInfo();
         break;
@@ -274,17 +281,17 @@ var SocialToolbar = {
   },
 
   get button() {
     return document.getElementById("social-toolbar-button");
   },
 
   updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
     this.button.hidden = !Social.uiVisible;
-    if (!Social.provider.profile || !Social.provider.profile.userName) {
+    if (!Social.provider || !Social.provider.profile || !Social.provider.profile.userName) {
       ["social-notification-box",
        "social-status-iconbox"].forEach(function removeChildren(parentId) {
         let parent = document.getElementById(parentId);
         while(parent.hasChildNodes())
           parent.removeChild(parent.firstChild);
       });
     }
   },
@@ -463,16 +470,17 @@ var SocialSidebar = {
     // Hide the sidebar if it cannot appear, or has been toggled off.
     // Also set the command "checked" state accordingly.
     let hideSidebar = !this.canShow || !this.enabled;
     let broadcaster = document.getElementById("socialSidebarBroadcaster");
     broadcaster.hidden = hideSidebar;
     command.setAttribute("checked", !hideSidebar);
 
     let sbrowser = document.getElementById("social-sidebar-browser");
+    sbrowser.docShell.isActive = !hideSidebar;
     if (hideSidebar) {
       this.dispatchEvent("sidebarhide");
       // If we're disabled, unload the sidebar content
       if (!this.canShow) {
         sbrowser.removeAttribute("origin");
         sbrowser.setAttribute("src", "about:blank");
       }
     } else {
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -258,16 +258,17 @@ endif
                  browser_middleMouse_inherit.js \
                  redirect_bug623155.sjs \
                  browser_tabDrop.js \
                  browser_lastAccessedTab.js \
                  browser_bug734076.js \
                  browser_social_toolbar.js \
                  browser_social_sidebar.js \
                  browser_social_mozSocial_API.js \
+                 browser_social_isVisible.js \
                  social_panel.html \
                  social_sidebar.html \
                  social_window.html \
                  social_worker.js \
                  $(NULL)
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_social_isVisible.js
@@ -0,0 +1,62 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function test() {
+  waitForExplicitFinish();
+
+  let manifest = { // normal provider
+    name: "provider 1",
+    origin: "https://example.com",
+    sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
+    workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+    iconURL: "chrome://branding/content/icon48.png"
+  };
+  runSocialTestWithProvider(manifest, function (finishcb) {
+    runSocialTests(tests, undefined, undefined, finishcb);
+  });
+}
+
+var tests = {
+  testSidebarMessage: function(next) {
+    let port = Social.provider.port;
+    ok(port, "provider has a port");
+    port.postMessage({topic: "test-init"});
+    Social.provider.port.onmessage = function (e) {
+      let topic = e.data.topic;
+      switch (topic) {
+        case "got-sidebar-message":
+          // The sidebar message will always come first, since it loads by default
+          ok(true, "got sidebar message");
+          next();
+          break;
+      }
+    };
+  },
+  testIsVisible: function(next) {
+    let port = Social.provider.port;
+    port.onmessage = function (e) {
+      let topic = e.data.topic;
+      switch (topic) {
+        case "got-isVisible-response":
+          is(e.data.result, true, "Sidebar should be visible by default");
+          Social.toggleSidebar();
+          next();
+      }
+    };
+    port.postMessage({topic: "test-isVisible"});
+  },
+  testIsNotVisible: function(next) {
+    let port = Social.provider.port;
+    port.onmessage = function (e) {
+      let topic = e.data.topic;
+      switch (topic) {
+        case "got-isVisible-response":
+          is(e.data.result, false, "Sidebar should be hidden");
+          Services.prefs.clearUserPref("social.sidebar.open");
+          next();
+      }
+    };
+    port.postMessage({topic: "test-isVisible"});
+  }
+}
--- a/browser/base/content/test/browser_social_mozSocial_API.js
+++ b/browser/base/content/test/browser_social_mozSocial_API.js
@@ -2,19 +2,19 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 function test() {
   waitForExplicitFinish();
 
   let manifest = { // normal provider
     name: "provider 1",
-    origin: "http://example.com",
-    sidebarURL: "http://example.com/browser/browser/base/content/test/social_sidebar.html",
-    workerURL: "http://example.com/browser/browser/base/content/test/social_worker.js",
+    origin: "https://example.com",
+    sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
+    workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
     iconURL: "chrome://branding/content/icon48.png"
   };
   runSocialTestWithProvider(manifest, function (finishcb) {
     runSocialTests(tests, undefined, undefined, finishcb);
   });
 }
 
 var tests = {
--- a/browser/base/content/test/social_sidebar.html
+++ b/browser/base/content/test/social_sidebar.html
@@ -23,16 +23,19 @@
               break;
             case "test-close-service-window":
               win.addEventListener("unload", function watchClose() {
                 win.removeEventListener("unload", watchClose);
                 port.postMessage({topic: "service-window-closed-message", result: "ok"});
               }, false)
               win.close();
               break;
+            case "test-isVisible":
+              port.postMessage({topic: "test-isVisible-response", result: navigator.mozSocial.isVisible});
+              break;
           }
         }
         port.postMessage({topic: "sidebar-message", result: "ok"});
       }
     </script>
   </head>
   <body onload="pingWorker();">
     <p>This is a test social sidebar.</p>
--- a/browser/base/content/test/social_worker.js
+++ b/browser/base/content/test/social_worker.js
@@ -44,16 +44,22 @@ onconnect = function(e) {
         port.postMessage({topic: "social.initialize-response"});
         let profile = {
           userName: "foo"
         };
         port.postMessage({topic: "social.user-profile", data: profile});
         let icon = {
           name: "testIcon",
           iconURL: "chrome://branding/content/icon48.png",
-          contentPanel: "http://example.com/browser/browser/base/content/test/social_panel.html",
+          contentPanel: "https://example.com/browser/browser/base/content/test/social_panel.html",
           counter: 1
         };
         port.postMessage({topic: "social.ambient-notification", data: icon});
         break;
+      case "test-isVisible":
+        sidebarPort.postMessage({topic: "test-isVisible"});
+        break;
+      case "test-isVisible-response":
+        testPort.postMessage({topic: "got-isVisible-response", result: event.data.result});
+        break;
     }
   }
 }
--- a/toolkit/components/social/MozSocialAPI.jsm
+++ b/toolkit/components/social/MozSocialAPI.jsm
@@ -68,52 +68,72 @@ function attachToWindow(provider, target
     throw new Error("MozSocialAPI: cannot attach " + origin + " to " + targetDocURI.spec);
   }
 
   var port = provider._getWorkerPort(targetWindow);
 
   let mozSocialObj = {
     // Use a method for backwards compat with existing providers, but we
     // should deprecate this in favor of a simple .port getter.
-    getWorker: function() {
-      return {
-        port: port,
-        __exposedProps__: {
-          port: "r"
-        }
-      };
+    getWorker: {
+      enumerable: true,
+      configurable: true,
+      writable: true,
+      value: function() {
+        return {
+          port: port,
+          __exposedProps__: {
+            port: "r"
+          }
+        };
+      }
     },
-    hasBeenIdleFor: function () {
-      return false;
+    hasBeenIdleFor: {
+      enumerable: true,
+      configurable: true,
+      writable: true,
+      value: function() {
+        return false;
+      }
     },
-    openServiceWindow: function(toURL, name, options) {
-      return openServiceWindow(provider, targetWindow, toURL, name, options);
+    openServiceWindow: {
+      enumerable: true,
+      configurable: true,
+      writable: true,
+      value: function(toURL, name, options) {
+        return openServiceWindow(provider, targetWindow, toURL, name, options);
+      }
     },
-    getAttention: function() {
-      let mainWindow = targetWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-                         .getInterface(Components.interfaces.nsIWebNavigation)
-                         .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
-                         .rootTreeItem
-                         .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-                         .getInterface(Components.interfaces.nsIDOMWindow);
-      mainWindow.getAttention();
+    getAttention: {
+      enumerable: true,
+      configurable: true,
+      writable: true,
+      value: function() {
+        let mainWindow = targetWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                           .getInterface(Components.interfaces.nsIWebNavigation)
+                           .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
+                           .rootTreeItem
+                           .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                           .getInterface(Components.interfaces.nsIDOMWindow);
+        mainWindow.getAttention();
+      }
+    },
+    isVisible: {
+      enumerable: true,
+      configurable: true,
+      get: function() {
+        return targetWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                           .getInterface(Ci.nsIWebNavigation)
+                           .QueryInterface(Ci.nsIDocShell).isActive;
+      }
     }
   };
 
   let contentObj = Cu.createObjectIn(targetWindow);
-  let propList = {};
-  for (let prop in mozSocialObj) {
-    propList[prop] = {
-      enumerable: true,
-      configurable: true,
-      writable: true,
-      value: mozSocialObj[prop]
-    };
-  }
-  Object.defineProperties(contentObj, propList);
+  Object.defineProperties(contentObj, mozSocialObj);
   Cu.makeObjectPropsNormal(contentObj);
 
   targetWindow.navigator.wrappedJSObject.__defineGetter__("mozSocial", function() {
     // We do this in a getter, so that we create these objects
     // only on demand (this is a potential concern, since
     // otherwise we might add one per iframe, and keep them
     // alive for as long as the window is alive).
     delete targetWindow.navigator.wrappedJSObject.mozSocial;