Add global button and status for checking updates of all addons
authorBlair McBride <bmcbride@mozilla.com>
Fri, 16 Apr 2010 15:54:16 +1200
changeset 40874 496c82e83c58c28c4c7d8df5abff0791775d4494
parent 40873 66cdd5f520efa494f04752457f5e9855d7b62cca
child 40875 aeae9f36e2d2dc84af910e65fe0103b21d8ba143
push id105
push userbmcbride@mozilla.com
push dateFri, 16 Apr 2010 03:54:34 +0000
milestone1.9.3a5pre
Add global button and status for checking updates of all addons
toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/extensions.xml
toolkit/mozapps/extensions/content/extensions.xul
toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
toolkit/themes/pinstripe/mozapps/extensions/extensions.css
toolkit/themes/winstripe/mozapps/extensions/extensions.css
--- a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
+++ b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
@@ -10,16 +10,23 @@
 <!ENTITY view.search.label                    "Search">
 <!ENTITY view.discover.label                  "Get Add-ons">
 <!ENTITY view.languages.label                 "Languages">
 <!ENTITY view.searchengines.label             "Search Engines">
 <!ENTITY view.features.label                  "Extensions">
 <!ENTITY view.appearance.label                "Themes">
 <!ENTITY view.plugins.label                   "Plugins">
 
+<!-- addon updates -->
+<!ENTITY updates.updateNow.label               "Update Add-ons">
+<!ENTITY updates.updating.label                "Updating Add-ons">
+<!ENTITY updates.installed.label               "Add-ons have been updated!">
+<!ENTITY updates.downloaded.label              "Add-on updates have been downloaded!">
+<!ENTITY updates.restart.label                 "Restart">
+<!ENTITY updates.noneFound.label               "No updates found">
 
 <!-- addon actions -->
 <!ENTITY cmd.showDetails.label                "Show More Information">
 <!ENTITY cmd.showDetails.accesskey            "S">
 <!ENTITY cmd.findUpdates.label                "Find Updates">
 <!ENTITY cmd.findUpdates.accesskey            "F">
 <!ENTITY cmd.preferences.label                "Preferences">
 <!ENTITY cmd.preferences.accesskey            "P">
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -282,32 +282,84 @@ var gViewController = {
       doCommand: function(aAddon) {
         gViewController.loadView("addons://detail/" +
                                  encodeURIComponent(aAddon.id));
       }
     },
 
     cmd_findAllUpdates: {
       isEnabled: function() true,
-      doComand: function() {
-        var listener = {
+      doCommand: function() {
+        document.getElementById("updates-checknow").hidden = true;
+        document.getElementById("updates-nonefound").hidden = true;
+        document.getElementById("updates-progress").hidden = false;
+
+        var pendingChecks = 0;
+        var numUpdated = 0;
+        var restartNeeded = false;
+
+        function updateStatus() {
+          if (pendingChecks > 0)
+            return;
+          document.getElementById("updates-progress").hidden = true;
+
+          if (numUpdated == 0) {
+            document.getElementById("updates-checknow").hidden = false;
+            document.getElementById("updates-nonefound").hidden = false;
+            return;
+          }
+
+          if (restartNeeded) {
+            document.getElementById("updates-downloaded").hidden = false;
+            document.getElementById("updates-restart").hidden = false;
+          } else {
+            document.getElementById("updates-installed").hidden = false;
+          }
+        }
+
+        var updateInstallListener = {
+          onDownloadFailed: function() {
+            pendingChecks--;
+            updateStatus();
+          },
+          onInstallFailed: function() {
+            pendingChecks--;
+            updateStatus();
+          },
+          onInstallEnded: function(aInstall, aAddon) {
+            pendingChecks--;
+            numUpdated++;
+            if (isPending(aInstall.existingAddon, "upgrade"))
+              restartNeeded = true;
+            updateStatus();
+          }
+        };
+
+        var updateCheckListener = {
           onUpdateAvailable: function(aAddon, aInstall) {
             gEventManager.delegateAddonEvent("onUpdateAvailable",
                                              [aAddon, aInstall]);
+            aInstall.addListener(updateInstallListener);
             aInstall.install();
           },
+          onNoUpdateAvailable: function(aAddon) {
+            pendingChecks--;
+            updateStatus();
+          },
           onUpdateFinished: function(aAddon, aError) {
             gEventManager.delegateAddonEvent("onUpdateFinished",
                                              [aAddon, aError]);
           }
         };
+
         AddonManager.getAddonsByTypes(null, function(aAddonList) {
           aAddonList.forEach(function(aAddon) {
             if (aAddon.permissions & AddonManager.PERM_CAN_UPGRADE) {
-              aAddon.findUpdates(listener,
+              pendingChecks++;
+              aAddon.findUpdates(updateCheckListener,
                                  AddonManager.UPDATE_WHEN_USER_REQUESTED);
             }
           });
         });
       }
     },
 
     cmd_findItemUpdates: {
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -1016,21 +1016,21 @@
   <!-- Addon - uninstalled - An uninstalled addon that can be re-installed. -->
   <!-- XXXunf this doesn't take into account restart-less uninstalls -->
   <binding id="addon-uninstalled"
            extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
     <content>
       <xul:spacer flex="1"/>
       <xul:hbox class="container">
         <xul:label anonid="notice" class="notice"/>
-        <xul:button anonid="undo-btn"
+        <xul:button anonid="undo-btn" class="button-link"
                     label="&addon.undoUninstall.label;"
                     tooltiptext="&addon.undoUninstall.tooltip;"
                     oncommand="document.getBindingParent(this).cancelUninstall();"/>
-        <xul:button anonid="restart-btn"
+        <xul:button anonid="restart-btn" class="button-link"
                     label="&addon.restartNow.label;"
                     tooltiptext="&addon.restartNow.tooltip;"
                     command="cmd_restartApp"/>
       </xul:hbox>
       <xul:spacer flex="1"/>
     </content>
 
     <implementation>
--- a/toolkit/mozapps/extensions/content/extensions.xul
+++ b/toolkit/mozapps/extensions/content/extensions.xul
@@ -124,16 +124,33 @@
     <!-- right pane -->
     <vbox id="view-container" flex="4">
 
       <!-- main header -->
       <hbox id="header">
         <label id="header-name"/>
         <button id="header-link"/>
         <spacer flex="1"/>
+        <hbox id="updates-container">
+          <image class="spinner"/>
+          <label id="updates-nonefound" hidden="true"
+                 value="&updates.noneFound.label;"/>
+          <button id="updates-checknow" class="button-link"
+                  label="&updates.updateNow.label;"
+                  command="cmd_findAllUpdates"/>
+          <label id="updates-progress" hidden="true"
+                 value="&updates.updating.label;"/>
+          <label id="updates-installed" hidden="true"
+                 value="&updates.installed.label;"/>
+          <label id="updates-downloaded" hidden="true"
+                 value="&updates.downloaded.label;"/>
+          <button id="updates-restart" class="button-link" hidden="true"
+                  label="&updates.restart.label;"
+                  command="cmd_restartApp"/>
+        </hbox>
         <textbox id="header-search" type="search" searchbutton="true"
                  placeholder="&search.placeholder;"/>
       </hbox>
 
       <!-- view port -->
       <deck id="view-port" flex="1">
 
         <!-- discover view -->
--- a/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css
@@ -387,26 +387,16 @@
 .list > richlistitem[status="uninstalled"] > .container {
   -moz-box-align: center;
   padding: 4px 20px;
   background-color: #FDFFA8;
   -moz-border-radius: 8px;
   font-size: 14px;
 }
 
-.list > richlistitem[status="uninstalled"] > .container > button {
-  -moz-appearance: none;
-  background: transparent;
-  border: none;
-  text-decoration: underline;
-  color: blue;
-  cursor: pointer;
-  min-width: 0;
-}
-
 .list > richlistitem[status="uninstalled"][selected] {
   background-color: transparent;
 }
 
 
 
 /*** search view ***/
 
@@ -606,16 +596,28 @@
 
 /*** install status ***/
 
 .install-status {
   -moz-box-align: center;
 }
 
 
+/*** check for updates ***/
+
+#updates-container {
+  -moz-box-align: center;
+}
+
+#updates-installed, #updates-downloaded {
+  color: #00BB00;
+  font-weight: bold;
+}
+
+
 /*** buttons ***/
 
 button.addon-control {
   -moz-appearance: none;
   padding: 0px 5px;
   border: 1px solid #A2A6AD;
   -moz-border-radius: 100%;
   background-image: -moz-linear-gradient(#F9F9F9, #DFDFDF);
@@ -652,8 +654,18 @@ button.contribute {
   -moz-padding-start: 20px;
   -moz-padding-end: 4px;
 }
 
 button.contribute:hover {
   border-color: #4271FF;
   background-image: -moz-linear-gradient(#49CEFF, #4271FF);
 }
+
+button.button-link {
+  -moz-appearance: none;
+  background: transparent;
+  border: none;
+  text-decoration: underline;
+  color: -moz-nativehyperlinktext;
+  cursor: pointer;
+  min-width: 0;
+}
--- a/toolkit/themes/pinstripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/pinstripe/mozapps/extensions/extensions.css
@@ -387,26 +387,16 @@
 .list > richlistitem[status="uninstalled"] > .container {
   -moz-box-align: center;
   padding: 4px 20px;
   background-color: #FDFFA8;
   -moz-border-radius: 8px;
   font-size: 14px;
 }
 
-.list > richlistitem[status="uninstalled"] > .container > button {
-  -moz-appearance: none;
-  background: transparent;
-  border: none;
-  text-decoration: underline;
-  color: blue;
-  cursor: pointer;
-  min-width: 0;
-}
-
 .list > richlistitem[status="uninstalled"][selected] {
   background-color: transparent;
 }
 
 
 
 /*** search view ***/
 
@@ -606,16 +596,28 @@
 
 /*** install status ***/
 
 .install-status {
   -moz-box-align: center;
 }
 
 
+/*** check for updates ***/
+
+#updates-container {
+  -moz-box-align: center;
+}
+
+#updates-installed, #updates-downloaded {
+  color: #00BB00;
+  font-weight: bold;
+}
+
+
 /*** buttons ***/
 
 button.addon-control {
   -moz-appearance: none;
   padding: 0px 5px;
   border: 1px solid #A2A6AD;
   -moz-border-radius: 100%;
   background-image: -moz-linear-gradient(#F9F9F9, #DFDFDF);
@@ -652,8 +654,18 @@ button.contribute {
   -moz-padding-start: 20px;
   -moz-padding-end: 4px;
 }
 
 button.contribute:hover {
   border-color: #4271FF;
   background-image: -moz-linear-gradient(#49CEFF, #4271FF);
 }
+
+button.button-link {
+  -moz-appearance: none;
+  background: transparent;
+  border: none;
+  text-decoration: underline;
+  color: -moz-nativehyperlinktext;
+  cursor: pointer;
+  min-width: 0;
+}
--- a/toolkit/themes/winstripe/mozapps/extensions/extensions.css
+++ b/toolkit/themes/winstripe/mozapps/extensions/extensions.css
@@ -387,26 +387,16 @@
 .list > richlistitem[status="uninstalled"] > .container {
   -moz-box-align: center;
   padding: 4px 20px;
   background-color: #FDFFA8;
   -moz-border-radius: 8px;
   font-size: 14px;
 }
 
-.list > richlistitem[status="uninstalled"] > .container > button {
-  -moz-appearance: none;
-  background: transparent;
-  border: none;
-  text-decoration: underline;
-  color: blue;
-  cursor: pointer;
-  min-width: 0;
-}
-
 .list > richlistitem[status="uninstalled"][selected] {
   background-color: transparent;
 }
 
 
 
 /*** search view ***/
 
@@ -606,16 +596,28 @@
 
 /*** install status ***/
 
 .install-status {
   -moz-box-align: center;
 }
 
 
+/*** check for updates ***/
+
+#updates-container {
+  -moz-box-align: center;
+}
+
+#updates-installed, #updates-downloaded {
+  color: #00BB00;
+  font-weight: bold;
+}
+
+
 /*** buttons ***/
 
 button.addon-control {
   -moz-appearance: none;
   padding: 0px 5px;
   border: 1px solid #A2A6AD;
   -moz-border-radius: 100%;
   background-image: -moz-linear-gradient(#F9F9F9, #DFDFDF);
@@ -652,8 +654,18 @@ button.contribute {
   -moz-padding-start: 20px;
   -moz-padding-end: 4px;
 }
 
 button.contribute:hover {
   border-color: #4271FF;
   background-image: -moz-linear-gradient(#49CEFF, #4271FF);
 }
+
+button.button-link {
+  -moz-appearance: none;
+  background: transparent;
+  border: none;
+  text-decoration: underline;
+  color: -moz-nativehyperlinktext;
+  cursor: pointer;
+  min-width: 0;
+}