Bug 790545 - cache provider's toolbar notification icons. r=felipe
authorMark Hammond <mhammond@skippinet.com.au>
Mon, 08 Oct 2012 11:15:02 +1100
changeset 109585 3cf86586da0d439307495f42b14a7449fec19539
parent 109584 9827af2a97cec5805dc0ed88ca34d1a71b8a092a
child 109586 959de7eea1ff4082cd79b69ab2fef4f73f65c175
push id23636
push usergsharp@mozilla.com
push dateMon, 08 Oct 2012 08:08:19 +0000
treeherdermozilla-central@24cf40690042 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe
bugs790545
milestone18.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 790545 - cache provider's toolbar notification icons. r=felipe
browser/base/content/browser-social.js
toolkit/components/social/SocialService.jsm
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -619,31 +619,67 @@ var SocialToolbar = {
       notLoggedInLabel.hidden = false;
       userNameBtn.hidden = true;
     }
   },
 
   updateButton: function SocialToolbar_updateButton() {
     this.updateButtonHiddenState();
     let provider = Social.provider;
-    let iconNames = Object.keys(provider.ambientNotificationIcons);
+    let icons = provider.ambientNotificationIcons;
+    let iconNames = Object.keys(icons);
     let iconBox = document.getElementById("social-toolbar-item");
     let notifBox = document.getElementById("social-notification-box");
     let panel = document.getElementById("social-notification-panel");
     panel.hidden = false;
+
+    let command = document.getElementById("Social:ToggleNotifications");
+    command.setAttribute("checked", Services.prefs.getBoolPref("social.toast-notifications.enabled"));
+
+    const CACHE_PREF_NAME = "social.cached.notificationIcons";
+    // provider.profile == undefined means no response yet from the provider
+    // to tell us whether the user is logged in or not.
+    if (!SocialUI.haveLoggedInUser() && provider.profile !== undefined) {
+      // The provider has responded with a profile and the user isn't logged
+      // in.  The icons etc have already been removed by
+      // updateButtonHiddenState, so we want to nuke any cached icons we
+      // have and get out of here!
+      Services.prefs.clearUserPref(CACHE_PREF_NAME);
+      return;
+    }
+    if (Social.provider.profile === undefined) {
+      // provider has not told us about the login state yet - see if we have
+      // a cached version for this provider.
+      let cached;
+      try {
+        cached = JSON.parse(Services.prefs.getCharPref(CACHE_PREF_NAME));
+      } catch (ex) {}
+      if (cached && cached.provider == Social.provider.origin && cached.data) {
+        icons = cached.data;
+        iconNames = Object.keys(icons);
+        // delete the counter data as it is almost certainly stale.
+        for each(let name in iconNames) {
+          icons[name].counter = '';
+        }
+      }
+    } else {
+      // We have a logged in user - save the current set of icons back to the
+      // "cache" so we can use them next startup.
+      Services.prefs.setCharPref(CACHE_PREF_NAME,
+                                 JSON.stringify({provider: Social.provider.origin,
+                                                 data: icons}));
+    }
+
     let notificationFrames = document.createDocumentFragment();
     let iconContainers = document.createDocumentFragment();
 
     let createdFrames = [];
 
-    let command = document.getElementById("Social:ToggleNotifications");
-    command.setAttribute("checked", Services.prefs.getBoolPref("social.toast-notifications.enabled"));
-
     for each(let name in iconNames) {
-      let icon = provider.ambientNotificationIcons[name];
+      let icon = icons[name];
 
       let notificationFrameId = "social-status-" + icon.name;
       let notificationFrame = document.getElementById(notificationFrameId);
       if (!notificationFrame) {
         notificationFrame = document.createElement("iframe");
         notificationFrame.setAttribute("type", "content");
         notificationFrame.setAttribute("class", "social-panel-frame");
         notificationFrame.setAttribute("id", notificationFrameId);
--- a/toolkit/components/social/SocialService.jsm
+++ b/toolkit/components/social/SocialService.jsm
@@ -201,22 +201,30 @@ SocialProvider.prototype = {
   // no FrameWorker, or is disabled.
   workerAPI: null,
 
   // Contains information related to the user's profile. Populated by the
   // workerAPI via updateUserProfile. Null if the provider has no FrameWorker.
   // Properties:
   //   iconURL, portrait, userName, displayName, profileURL
   // See https://github.com/mozilla/socialapi-dev/blob/develop/docs/socialAPI.md
-  profile: null,
+  // A value of null or an empty object means 'user not logged in'.
+  // A value of undefined means the service has not told us the status of the
+  // profile, but is expected to soon (ie, the service is still loading/initing)
+  // This distinction might be used to cache certain data between runs - eg,
+  // browser-social.js caches the notification icons so they can be displayed
+  // quickly at startup without waiting for the provider to initialize -
+  // 'undefined' means 'ok to use cached values' versus 'null' meaning 'cached
+  // values aren't to be used as the user is logged out'.
+  profile: undefined,
 
   // Map of objects describing the provider's notification icons, whose
   // properties include:
   //   name, iconURL, counter, contentPanel
-  // See https://github.com/mozilla/socialapi-dev/blob/develop/docs/socialAPI.md
+  // See https://developer.mozilla.org/en-US/docs/Social_API
   ambientNotificationIcons: null,
 
   // Called by the workerAPI to update our profile information.
   updateUserProfile: function(profile) {
     this.profile = profile;
 
     // Sanitize the portrait from any potential script-injection.
     if (profile.portrait) {