Bug 804910 - Part 2. Watch for error notification and display recovery UI. r=jaws
authorFelipe Gomes <felipc@gmail.com>
Tue, 30 Oct 2012 13:10:04 -0700
changeset 111941 08f97e0fa9daef428a8f4109adf905a4c9675160
parent 111940 9104ce0e7396c5843b0f6d1e45a980506a9528fd
child 111942 f9a9450a82afddf0ed3d65f671a13ddfd4e734c5
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersjaws
bugs804910
milestone19.0a1
Bug 804910 - Part 2. Watch for error notification and display recovery UI. r=jaws
browser/base/content/aboutSocialError.xhtml
browser/base/content/browser-social.js
browser/modules/Social.jsm
--- a/browser/base/content/aboutSocialError.xhtml
+++ b/browser/base/content/aboutSocialError.xhtml
@@ -59,16 +59,19 @@
         case "tryAgain":
           let urlMatch = queryString.match(/url=([^&]+)/);
           let encodedURL = urlMatch && urlMatch[1] ? urlMatch[1] : "";
           let url = decodeURIComponent(encodedURL);
 
           config.tryAgainCallback = loadQueryURL;
           config.queryURL = url;
           break;
+        case "workerFailure":
+          config.tryAgainCallback = reloadProvider;
+          break;
         default:
           break;
       }
     }
 
     function setUpStrings() {
       let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
       let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
@@ -98,15 +101,18 @@
       config.tryAgainCallback();
     }
 
     function loadQueryURL() {
       window.location.href = config.queryURL;
     }
 
     function reloadProvider() {
-      Social.provider.reload();
+      Social.enabled = false;
+      Services.tm.mainThread.dispatch(function() {
+        Social.enabled = true;
+      }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
     }
 
     parseQueryString();
     setUpStrings();
   ]]></script>
 </html>
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -7,16 +7,17 @@ const PANEL_MIN_HEIGHT = 100;
 const PANEL_MIN_WIDTH = 330;
 
 let SocialUI = {
   // Called on delayed startup to initialize UI
   init: function SocialUI_init() {
     Services.obs.addObserver(this, "social:pref-changed", false);
     Services.obs.addObserver(this, "social:ambient-notification-changed", false);
     Services.obs.addObserver(this, "social:profile-changed", false);
+    Services.obs.addObserver(this, "social:frameworker-error", false);
 
     Services.prefs.addObserver("social.sidebar.open", this, false);
     Services.prefs.addObserver("social.toast-notifications.enabled", this, false);
 
     gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler, true, true);
 
     // Called when we enter DOM full-screen mode.
     window.addEventListener("mozfullscreenchange", function () SocialSidebar.updateSidebar());
@@ -24,16 +25,17 @@ let SocialUI = {
     Social.init(this._providerReady.bind(this));
   },
 
   // Called on window unload
   uninit: function SocialUI_uninit() {
     Services.obs.removeObserver(this, "social:pref-changed");
     Services.obs.removeObserver(this, "social:ambient-notification-changed");
     Services.obs.removeObserver(this, "social:profile-changed");
+    Services.obs.removeObserver(this, "social:frameworker-error");
 
     Services.prefs.removeObserver("social.sidebar.open", this);
     Services.prefs.removeObserver("social.toast-notifications.enabled", this);
   },
 
   showProfile: function SocialUI_showProfile() {
     if (this.haveLoggedInUser())
       openUILinkIn(Social.provider.profile.profileURL, "tab");
@@ -64,16 +66,22 @@ let SocialUI = {
         SocialToolbar.updateButton();
         SocialMenu.populate();
         break;
       case "social:profile-changed":
         SocialToolbar.updateProfile();
         SocialShareButton.updateProfileInfo();
         SocialChatBar.update();
         break;
+      case "social:frameworker-error":
+        if (Social.provider) {
+          Social.errorState = "frameworker-error";
+          SocialSidebar.setSidebarErrorMessage("frameworker-error");
+        }
+        break;
       case "nsPref:changed":
         SocialSidebar.updateSidebar();
         SocialToolbar.updateButton();
         SocialMenu.populate();
         break;
     }
   },
 
@@ -996,16 +1004,21 @@ var SocialSidebar = {
         this.unloadSidebar();
       } else {
         this._unloadTimeoutId = setTimeout(
           this.unloadSidebar,
           Services.prefs.getIntPref("social.sidebar.unload_timeout_ms")
         );
       }
     } else {
+      if (Social.errorState == "frameworker-error") {
+        SocialSidebar.setSidebarErrorMessage("frameworker-error");
+        return;
+      }
+
       // Make sure the right sidebar URL is loaded
       if (sbrowser.getAttribute("origin") != Social.provider.origin) {
         sbrowser.setAttribute("origin", Social.provider.origin);
         sbrowser.setAttribute("src", Social.provider.sidebarURL);
         sbrowser.addEventListener("load", function sidebarOnShow() {
           sbrowser.removeEventListener("load", sidebarOnShow, true);
           // let load finish, then fire our event
           setTimeout(function () {
@@ -1044,20 +1057,28 @@ var SocialSidebar = {
 
     container.appendChild(sbrowser);
 
     SocialFlyout.unload();
   },
 
   _unloadTimeoutId: 0,
 
-  setSidebarErrorMessage: function() {
+  setSidebarErrorMessage: function(aType) {
     let sbrowser = document.getElementById("social-sidebar-browser");
-    let url = encodeURIComponent(Social.provider.sidebarURL);
-    sbrowser.loadURI("about:socialerror?mode=tryAgain&url=" + url, null, null);
+    switch (aType) {
+      case "sidebar-error":
+        let url = encodeURIComponent(Social.provider.sidebarURL);
+        sbrowser.loadURI("about:socialerror?mode=tryAgain&url=" + url, null, null);
+        break;
+
+      case "frameworker-error":
+        sbrowser.setAttribute("src", "about:socialerror?mode=workerFailure");
+        break;
+    }
   }
 }
 
 // Error handling class used to listen for network errors in the social frames
 // and replace them with a social-specific error page
 function SocialErrorListener(aType) {
   this.type = aType;
 }
@@ -1085,17 +1106,17 @@ SocialErrorListener.prototype = {
     if (failure && aStatus != Components.results.NS_BINDING_ABORTED) {
       aRequest.cancel(Components.results.NS_BINDING_ABORTED);
       this.setErrorMessage(aWebProgress);
     }
   },
 
   onLocationChange: function SPL_onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
     let failure = aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE;
-    if (failure) {
+    if (failure && Social.errorState != "frameworker-error") {
       aRequest.cancel(Components.results.NS_BINDING_ABORTED);
       window.setTimeout(function(self) {
         self.setErrorMessage(aWebProgress);
       }, 0, this);
     }
   },
 
   onProgressChange: function SPL_onProgressChange() {},
@@ -1104,17 +1125,17 @@ SocialErrorListener.prototype = {
 
   setErrorMessage: function(aWebProgress) {
     switch (this.type) {
       case "flyout":
         SocialFlyout.setFlyoutErrorMessage();
         break;
 
       case "sidebar":
-        SocialSidebar.setSidebarErrorMessage();
+        SocialSidebar.setSidebarErrorMessage("sidebar-error");
         break;
 
       case "notification-panel":
         let frame = aWebProgress.QueryInterface(Ci.nsIDocShell)
                                 .chromeEventHandler;
         SocialToolbar.setPanelErrorMessage(frame);
         break;
     }
--- a/browser/modules/Social.jsm
+++ b/browser/modules/Social.jsm
@@ -37,16 +37,19 @@ this.Social = {
     }.bind(this));
   },
 
   get uiVisible() {
     return this.provider && this.provider.enabled;
   },
 
   set enabled(val) {
+    if (!val) {
+      delete this.errorState;
+    }
     SocialService.enabled = val;
   },
   get enabled() {
     return SocialService.enabled;
   },
 
   get active() {
     return Services.prefs.getBoolPref("social.active");