Bug 573062 - Add "(restart required)" to tooltip for "Remove," "Disable," "Enable" buttons for add-ons requiring restart; r=dtownsend
authorAsaf Romano <mano@mozilla.com>
Thu, 29 Jul 2010 10:35:34 -0700
changeset 48359 5b4a338e639ad44b2a3e98324cf795019d6525ef
parent 48358 d8b75b9a48dc6d671a73caa7f46a53ad790ccf99
child 48360 9e290d196600332b1731df54ca9142df21127a30
push idunknown
push userunknown
push dateunknown
reviewersdtownsend
bugs573062
milestone2.0b3pre
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 573062 - Add "(restart required)" to tooltip for "Remove," "Disable," "Enable" buttons for add-ons requiring restart; r=dtownsend
toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/content/extensions.xml
toolkit/mozapps/extensions/content/extensions.xul
toolkit/mozapps/extensions/test/browser/browser_bug573062.js
--- a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
+++ b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd
@@ -31,23 +31,20 @@
 <!ENTITY cmd.findUpdates.accesskey            "F">
 <!ENTITY cmd.preferences.label                "Preferences">
 <!ENTITY cmd.preferences.accesskey            "P">
 <!ENTITY cmd.about.label                      "About">
 <!ENTITY cmd.about.accesskey                  "A">
 
 <!ENTITY cmd.enableAddon.label                "Enable">
 <!ENTITY cmd.enableAddon.accesskey            "E">
-<!ENTITY cmd.enableAddon.tooltip              "Enable this add-on">
 <!ENTITY cmd.disableAddon.label               "Disable">
 <!ENTITY cmd.disableAddon.accesskey           "D">
-<!ENTITY cmd.disableAddon.tooltip             "Disable this add-on">
 <!ENTITY cmd.uninstallAddon.label             "Remove">
 <!ENTITY cmd.uninstallAddon.accesskey         "R">
-<!ENTITY cmd.uninstallAddon.tooltip           "Uninstall this add-on">
 <!ENTITY cmd.showPreferences.label            "Preferences">
 <!ENTITY cmd.showPreferences.tooltip          "Change this add-on's preferences">
 <!ENTITY cmd.contribute.label                 "Contribute">
 <!ENTITY cmd.contribute.accesskey             "C">
 <!ENTITY cmd.contribute.tooltip               "Contribute to the development of this add-on">
 
 
 <!-- detail view -->
--- a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
+++ b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
@@ -42,8 +42,15 @@ installDisablePending=Restart to disable
 installFailed=Error installing
 installCancelled=Install cancelled
 
 #LOCALIZATION NOTE: %1$S is the addon name, %2$S is brand name
 restartToEnable=%1$% will be enabled after you restart %2$S
 restartToDisable=%1$S will be disabled after you restart %2$S
 restartToUninstall=%1$S will be removed after you restart %2$S
 restartToUpgrade=%1$S will be updated after you restart %2$S
+
+uninstallAddonTooltip=Uninstall this add-on
+uninstallAddonRestartRequiredTooltip=Uninstall this add-on (restart required)
+enableAddonTooltip=Enable this add-on
+enableAddonRestartRequiredTooltip=Enable this add-on (restart required)
+disableAddonTooltip=Disable this add-on
+disableAddonRestartRequiredTooltip=Disable this add-on (restart required)
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -510,27 +510,41 @@ var gViewController = {
     cmd_enableItem: {
       isEnabled: function(aAddon) {
         if (!aAddon)
           return false;
         return hasPermission(aAddon, "enable");
       },
       doCommand: function(aAddon) {
         aAddon.userDisabled = false;
+      },
+      getTooltip: function(aAddon) {
+        if (!aAddon)
+          return "";
+        if (aAddon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_ENABLE)
+          return gStrings.ext.GetStringFromName("enableAddonRestartRequiredTooltip");
+        return gStrings.ext.GetStringFromName("enableAddonTooltip");
       }
     },
 
     cmd_disableItem: {
       isEnabled: function(aAddon) {
         if (!aAddon)
           return false;
         return hasPermission(aAddon, "disable");
       },
       doCommand: function(aAddon) {
         aAddon.userDisabled = true;
+      },
+      getTooltip: function(aAddon) {
+        if (!aAddon)
+          return "";
+        if (aAddon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_DISABLE)
+          return gStrings.ext.GetStringFromName("disableAddonRestartRequiredTooltip");
+        return gStrings.ext.GetStringFromName("disableAddonTooltip");
       }
     },
 
     cmd_uninstallItem: {
       isEnabled: function(aAddon) {
         if (!aAddon)
           return false;
         return hasPermission(aAddon, "uninstall");
@@ -539,16 +553,23 @@ var gViewController = {
         if (gViewController.currentViewObj != gDetailView) {
           aAddon.uninstall();
           return;
         }
 
         gViewController.loadView(gViewController.previousViewId, function() {
           gViewController.currentViewObj.getListItemForID(aAddon.id).uninstall();
         });
+      },
+      getTooltip: function(aAddon) {
+        if (!aAddon)
+          return "";
+        if (aAddon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_UNINSTALL)
+          return gStrings.ext.GetStringFromName("uninstallAddonRestartRequiredTooltip");
+        return gStrings.ext.GetStringFromName("uninstallAddonTooltip");
       }
     },
 
     cmd_cancelUninstallItem: {
       isEnabled: function(aAddon) {
         if (!aAddon)
           return false;
         return isPending(aAddon, "uninstall");
@@ -571,18 +592,26 @@ var gViewController = {
   },
 
   updateCommands: function() {
     // wait until the view is initialized
     if (!this.currentViewObj)
       return;
     var addon = this.currentViewObj.getSelectedAddon();
     for (let commandId in this.commands) {
-      let cmd = document.getElementById(commandId);
-      cmd.setAttribute("disabled", !this.commands[commandId].isEnabled(addon));
+      let cmd = this.commands[commandId];
+      let cmdElt = document.getElementById(commandId);
+      cmdElt.setAttribute("disabled", !cmd.isEnabled(addon));
+      if ("getTooltip" in cmd) {
+        let tooltip = cmd.getTooltip(addon);        
+        if (tooltip)
+          cmdElt.setAttribute("tooltiptext", tooltip);
+        else
+          cmdElt.removeAttribute("tooltiptext");
+      }
     }
   },
 
   doCommand: function(aCommand, aAddon) {
     if (!this.supportsCommand(aCommand))
       return;
     var cmd = this.commands[aCommand];
     if (!aAddon)
--- a/toolkit/mozapps/extensions/content/extensions.xml
+++ b/toolkit/mozapps/extensions/content/extensions.xml
@@ -785,25 +785,22 @@
         <xul:spacer flex="1"/>
         <xul:hbox anonid="control-container" class="control-container">
           <xul:button anonid="preferences-btn" class="addon-control"
                       label="&cmd.showPreferences.label;"
                       tooltiptext="&cmd.showPreferences.tooltip;"
                       oncommand="document.getBindingParent(this).showPreferences();"/>
           <xul:button anonid="remove-btn" class="addon-control remove"
                       label="&cmd.uninstallAddon.label;"
-                      tooltiptext="&cmd.uninstallAddon.tooltip;"
                       oncommand="document.getBindingParent(this).uninstall();"/>
           <xul:button anonid="enable-btn"  class="addon-control enable"
                       label="&cmd.enableAddon.label;"
-                      tooltiptext="&cmd.enableAddon.tooltip;"
                       oncommand="document.getBindingParent(this).userDisabled = false;"/>
           <xul:button anonid="disable-btn" class="addon-control disable"
                       label="&cmd.disableAddon.label;"
-                      tooltiptext="&cmd.disableAddon.tooltip;"
                       oncommand="document.getBindingParent(this).userDisabled = true;"/>
         </xul:hbox>
         <xul:hbox class="status-container">
           <xul:hbox anonid="checking-update" hidden="true">
             <xul:image class="spinner"/>
             <xul:label value="&addon.checkingForUpdates.label;"/>
           </xul:hbox>
           <xul:hbox anonid="install-status" class="install-status"
@@ -1017,19 +1014,43 @@
       </method>
 
       <method name="_updateState">
         <body><![CDATA[
           this.setAttribute("incompatible", !this.mAddon.isCompatible);
 
           this._preferencesBtn.hidden = !this.mAddon.optionsURL;
 
-          this._enableBtn.hidden = !this.hasPermission("enable");
-          this._disableBtn.hidden = !this.hasPermission("disable");
-          this._removeBtn.hidden = !this.hasPermission("uninstall");
+          if (this.hasPermission("enable")) {
+            this._enableBtn.hidden = false;
+            let tooltip = gViewController.commands["cmd_enableItem"]
+                                         .getTooltip(this.mAddon);
+            this._enableBtn.setAttribute("tooltiptext", tooltip);
+          } else {
+            this._enableBtn.hidden = true;
+          }
+
+          if (this.hasPermission("disable")) {
+            this._disableBtn.hidden = false;
+            let tooltip = gViewController.commands["cmd_disableItem"]
+                                         .getTooltip(this.mAddon);
+            this._disableBtn.setAttribute("tooltiptext", tooltip);
+          } else {
+            this._disableBtn.hidden = true;
+          }
+
+          if (this.hasPermission("uninstall")) {
+            this._removeBtn.hidden = false;
+            let tooltip = gViewController.commands["cmd_uninstallItem"]
+                                         .getTooltip(this.mAddon);
+            this._removeBtn.setAttribute("tooltiptext", tooltip);
+          }
+          else {
+            this._removeBtn.hidden = true;
+          }
 
           var showAsActive = this.mAddon.isActive;
           if (this.isPending("enable"))
             showAsActive = true;
           else if (this.isPending("disable"))
             showAsActive = false;
           this.setAttribute("active", showAsActive);
 
--- a/toolkit/mozapps/extensions/content/extensions.xul
+++ b/toolkit/mozapps/extensions/content/extensions.xul
@@ -265,27 +265,24 @@
                   <button id="detail-contribute" class="contribute"
                           label="&cmd.contribute.label;"
                           accesskey="&cmd.contribute.accesskey;"
                           tooltiptext="&cmd.contribute.tooltip;"/>
                   <spacer flex="1"/>
                   <button id="detail-uninstall" class="addon-control remove"
                           label="&cmd.uninstallAddon.label;"
                           accesskey="&cmd.uninstallAddon.accesskey;"
-                          tooltiptext="&cmd.uninstallAddon.tooltip;"
                           command="cmd_uninstallItem"/>
                   <button id="detail-enable" class="addon-control enable"
                           label="&cmd.enableAddon.label;"
                           accesskey="&cmd.enableAddon.accesskey;"
-                          tooltiptext="&cmd.enableAddon.tooltip;"
                           command="cmd_enableItem"/>
                   <button id="detail-disable" class="addon-control disable"
                           label="&cmd.disableAddon.label;"
                           accesskey="&cmd.disableAddon.accesskey;"
-                          tooltiptext="&cmd.disableAddon.tooltip;"
                           command="cmd_disableItem"/>
                 </hbox>
               </vbox>
             </hbox>
             <hbox class="detail-extra">
                <vbox class="detail-prefs" flex="1">
                   <checkbox id="detail-autoUpdate" checked="true"
                             label="&detail.updateAutomatically.label;"
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/browser/browser_bug573062.js
@@ -0,0 +1,117 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+function test() {
+  waitForExplicitFinish();
+
+  var gProvider = new MockProvider();
+  let perms = AddonManager.PERM_CAN_UNINSTALL |
+              AddonManager.PERM_CAN_ENABLE | AddonManager.PERM_CAN_DISABLE;
+
+  gProvider.createAddons([{
+    id: "restart-enable-disable@tests.mozilla.org",
+    name: "restart-enable-disable",
+    description: "foo",
+    permissions: perms,
+    operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_ENABLE |
+                                AddonManager.OP_NEEDS_RESTART_DISABLE
+  },
+  {
+    id: "restart-uninstall@tests.mozilla.org",
+    name: "restart-uninstall",
+    description: "foo",
+    permissions: perms,
+    operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_UNINSTALL
+  },
+  {
+    id: "no-restart-required@tests.mozilla.org",
+    name: "no-restart-required",
+    description: "bar",
+    permissions: perms,
+    operationsRequiringRestart: AddonManager.OP_NEEDS_RESTART_NONE
+  }]);
+  
+  open_manager(null, function(aWindow) {
+    let addonList = aWindow.document.getElementById("addon-list");
+    let ed_r_Item, un_r_Item, no_r_Item;
+    for (let i = 0; i < addonList.childNodes.length; i++) {
+      let addonItem = addonList.childNodes[i];
+      let name = addonItem.getAttribute("name");
+      switch (name) {
+        case "restart-enable-disable":
+          ed_r_Item = addonItem;
+          break;
+        case "restart-uninstall":
+          un_r_Item = addonItem;
+          break;
+        case "no-restart-required":
+          no_r_Item = addonItem;
+          break;
+      }
+    }
+
+    // Check the buttons in the list view.
+    function checkTooltips(aItem, aEnable, aDisable, aRemove) {
+      ok(aItem._enableBtn.getAttribute("tooltiptext") == aEnable);
+      ok(aItem._disableBtn.getAttribute("tooltiptext") == aDisable);
+      ok(aItem._removeBtn.getAttribute("tooltiptext")  == aRemove);
+    }
+
+    let strs = aWindow.gStrings.ext;
+    addonList.selectedItem = ed_r_Item;
+    let ed_args = [ed_r_Item,
+                   strs.GetStringFromName("enableAddonRestartRequiredTooltip"),
+                   strs.GetStringFromName("disableAddonRestartRequiredTooltip"),
+                   strs.GetStringFromName("uninstallAddonTooltip")];
+    checkTooltips.apply(null, ed_args);
+
+    addonList.selectedItem = un_r_Item;
+    let un_args = [un_r_Item,
+                   strs.GetStringFromName("enableAddonTooltip"),
+                   strs.GetStringFromName("disableAddonTooltip"),
+                   strs.GetStringFromName("uninstallAddonRestartRequiredTooltip")];
+    checkTooltips.apply(null, un_args);
+
+    addonList.selectedItem = no_r_Item;
+    let no_args = [no_r_Item,
+                   strs.GetStringFromName("enableAddonTooltip"),
+                   strs.GetStringFromName("disableAddonTooltip"),
+                   strs.GetStringFromName("uninstallAddonTooltip")];
+    checkTooltips.apply(null, no_args)
+
+    // Check the buttons in the details view.
+    function checkTooltips2(aItem, aEnable, aDisable, aRemove) {
+        let detailEnable = aWindow.document.getElementById("detail-enable");
+    let detailDisable = aWindow.document.getElementById("detail-disable");
+    let detailUninstall = aWindow.document.getElementById("detail-uninstall");
+      ok(detailEnable.getAttribute("tooltiptext") == aEnable);
+      ok(detailDisable.getAttribute("tooltiptext") == aDisable);
+      ok(detailUninstall.getAttribute("tooltiptext")  == aRemove);
+    }
+
+    function showInDetailView(aAddonId) {
+      aWindow.gViewController.loadView("addons://detail/" +
+                                       aWindow.encodeURIComponent(aAddonId));
+    }
+
+    // enable-disable:
+    showInDetailView("restart-enable-disable@tests.mozilla.org");
+    wait_for_view_load(aWindow, function() {
+      checkTooltips2.apply(null, ed_args);
+      // uninstall:
+      showInDetailView("restart-uninstall@tests.mozilla.org");
+      wait_for_view_load(aWindow, function() {
+        checkTooltips2.apply(null, un_args);
+        // no restart:
+        showInDetailView("no-restart-required@tests.mozilla.org");
+        wait_for_view_load(aWindow, function() {
+          checkTooltips2.apply(null, no_args);
+          aWindow.close();
+          finish();
+        });
+      });
+    });
+
+  });
+}