Bug 595810 Part 6e: addon notification doorhanger implementation r=Ian
authorNeil Rashbrook <neil@parkwaycc.co.uk>
Sun, 05 Dec 2010 20:26:42 +0000
changeset 6793 e53cca758048c9b499b9a724031cb5def2f135d1
parent 6792 b78db221b0b14580c9923fc630e24403b34424c6
child 6794 2cf4968b500a2371000feac979adcff2a36bd7cd
push idunknown
push userunknown
push dateunknown
reviewersIan
bugs595810
Bug 595810 Part 6e: addon notification doorhanger implementation r=Ian
suite/browser/navigator.css
suite/browser/navigator.xul
suite/common/bindings/notification.xml
suite/themes/classic/mac/navigator/navigator.css
suite/themes/classic/navigator/navigator.css
suite/themes/modern/navigator/navigator.css
--- a/suite/browser/navigator.css
+++ b/suite/browser/navigator.css
@@ -64,16 +64,17 @@ panel[for="urlbar"] {
 /* notification anchors should only be visible when their associated
    notifications are */
 .notification-anchor-icon {
   display: none;
   -moz-user-focus: normal;
 }
 
 #notification-popup-box[anchorid="geo-notification-icon"] > #geo-notification-icon,
+#notification-popup-box[anchorid="addons-notification-icon"] > #addons-notification-icon,
 #notification-popup-box[anchorid="password-notification-icon"] > #password-notification-icon {
   display: -moz-box;
 }
 
 #toolbar-menubar[autohide="true"][inactive="true"]
 {
   min-height: 0px !important;
   height: 0px !important;
--- a/suite/browser/navigator.xul
+++ b/suite/browser/navigator.xul
@@ -310,16 +310,17 @@
                  oninput="gBrowser.userTypedValue = this.value;"
                  ontextentered="return handleURLBarCommand(eventParam, domEvent);"
                  ontextreverted="return handleURLBarRevert();"
                  onfocus="URLBarFocusHandler(event);"
                  onmousedown="URLBarMouseDownHandler(event);"
                  onclick="URLBarClickHandler(event);">
           <box id="notification-popup-box" hidden="true" align="center">
             <image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
+            <image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
             <image id="password-notification-icon" class="notification-anchor-icon" role="button"/>
           </box>
           <deck id="page-proxy-deck"
                 class="urlbar-icons"
                 onclick="handlePageProxyClick(event);">
             <image id="page-proxy-button"
                    ondraggesture="PageProxyDragGesture(event);"
                    tooltiptext="&proxyIcon.tooltip;"/>
--- a/suite/common/bindings/notification.xml
+++ b/suite/common/bindings/notification.xml
@@ -951,16 +951,191 @@
 
             PopupNotifications.show(this.activeBrowser,
                                     "geolocation", message,
                                     "geo-notification-icon", mainAction,
                                     secondaryActions);
           ]]>
         </body>
       </method>
+
+      <method name="addonInstallBlocked">
+        <parameter name="installInfo"/>
+        <body>
+          <![CDATA[
+            var host;
+            try {
+              // this fails with nsSimpleURIs like data: URIs
+              host = installInfo.originatingURI.host;
+            } catch (ex) {
+              host = this._stringBundle.GetStringFromName("xpinstallHostNotAvailable");
+            }
+            var brandShortName = this._brandStringBundle.GetStringFromName("brandShortName");
+            var messageString = this._stringBundle.formatStringFromName("xpinstallPromptWarning",
+                                                                        [brandShortName, host], 2);
+            var action = {
+              label: this._stringBundle.GetStringFromName("xpinstallPromptInstallButton"),
+              accessKey: this._stringBundle.GetStringFromName("xpinstallPromptInstallButton.accesskey"),
+              callback: function allowInstall() {
+                installInfo.install();
+                return false;
+              }
+            };
+
+            // Make notifications persist a minimum of 30 seconds
+            var options = {
+              timeout: Date.now() + 30000
+            };
+            PopupNotifications.show(this.activeBrowser,
+                                    "addon-install-blocked", messageString,
+                                    "addons-notification-icon", action,
+                                    null, options);
+          ]]>
+        </body>
+      </method>
+
+      <method name="addonInstallComplete">
+        <parameter name="installInfo"/>
+        <body>
+          <![CDATA[
+            var tmp = {};
+            Components.utils.import("resource://gre/modules/AddonManager.jsm", tmp);
+            Components.utils.import("resource://gre/modules/PluralForm.jsm", tmp);
+
+            var messageString;
+            var mainAction = null;
+            var secondaryActions = null;
+
+            if ("toEM" in window) {
+              mainAction = {
+                label: this._stringBundle.GetStringFromName("addonInstallManageButton"),
+                accessKey: this._stringBundle.GetStringFromName("addonInstallManageButton.accesskey"),
+                callback: function() {
+                  window.toEM("addons://list/extension");
+                }
+              };
+            }
+
+            if (installInfo.installs.some(function(install)
+                  install.addon.pendingOperations &
+                  tmp.AddonManager.PENDING_INSTALL)) {
+              messageString = this._stringBundle.GetStringFromName("addonsInstalledNeedsRestart");
+              if (mainAction)
+                secondaryActions = [mainAction];
+              mainAction = {
+                label: this._stringBundle.GetStringFromName("addonInstallRestartButton"),
+                accessKey: this._stringBundle.GetStringFromName("addonInstallRestartButton.accesskey"),
+                callback: function () {
+                  Application.restart();
+                }
+              };
+            } else {
+              messageString = this._stringBundle.GetStringFromName("addonsInstalled");
+            }
+
+            var brandShortName = this._brandStringBundle.GetStringFromName("brandShortName");
+            messageString = tmp.PluralForm.get(installInfo.installs.length, messageString)
+                                          .replace("#1", installInfo.installs[0].name)
+                                          .replace("#2", installInfo.installs.length)
+                                          .replace("#3", brandShortName);
+
+            // Make notifications persist a minimum of 30 seconds
+            var options = {
+              timeout: Date.now() + 30000
+            };
+            PopupNotifications.show(this.activeBrowser,
+                                    "addon-install-complete", messageString,
+                                    "addons-notification-icon", mainAction,
+                                    secondaryActions, options);
+          ]]>
+        </body>
+      </method>
+
+      <method name="addonInstallDisabled">
+        <parameter name="installInfo"/>
+        <body>
+          <![CDATA[
+            var messageString;
+            var action = null;
+            var prefBranch = this._prefs; // used by editPrefs callback
+
+            if (prefBranch.prefIsLocked("xpinstall.enabled"))
+              messageString = this._stringBundle.GetStringFromName("xpinstallDisabledMessageLocked");
+            else {
+              messageString = this._stringBundle.GetStringFromName("xpinstallDisabledMessage");
+              action = {
+                label: this._stringBundle.GetStringFromName("xpinstallDisabledButton"),
+                accessKey: this._stringBundle.GetStringFromName("xpinstallDisabledButton.accesskey"),
+                callback: function editPrefs() {
+                  prefBranch.setBoolPref("xpinstall.enabled", true);
+                }
+              };
+            }
+
+            // Make notifications persist a minimum of 30 seconds
+            var options = {
+              timeout: Date.now() + 30000
+            };
+            PopupNotifications.show(this.activeBrowser,
+                                    "addon-install-disabled", messageString,
+                                    "addons-notification-icon", action,
+                                    null, options);
+          ]]>
+        </body>
+      </method>
+
+      <method name="addonInstallFailed">
+        <parameter name="installInfo"/>
+        <body>
+          <![CDATA[
+            var host;
+            try {
+              // this fails with nsSimpleURIs like data: URIs
+              host = installInfo.originatingURI.host;
+            } catch (ex) {
+              host = this._stringBundle.GetStringFromName("xpinstallHostNotAvailable");
+            }
+
+            var error = "addonErrorIncompatible";
+            var name = installInfo.installs[0].name;
+            installInfo.installs.some(function(install) {
+              if (install.error) {
+                name = install.name;
+                error = "addonError" + install.error;
+                return true;
+              }
+              if (install.addon.blocklistState ==
+                  Components.interfaces.nsIBlocklistService.STATE_BLOCKED) {
+                name = install.name;
+                error = "addonErrorBlocklisted";
+              }
+              return false;
+            });
+
+            var brandShortName = this._brandStringBundle.GetStringFromName("brandShortName");
+            var version = Components.classes["@mozilla.org/xre/app-info;1"]
+                                    .getService(Components.interfaces.nsIXULAppInfo).version;
+            var messageString = this._stringBundle.GetStringFromName(error)
+                                                  .replace("#1", name)
+                                                  .replace("#2", host)
+                                                  .replace("#3", brandShortName)
+                                                  .replace("#4", version);
+
+            // Make notifications persist a minimum of 30 seconds
+            var options = {
+              timeout: Date.now() + 30000
+            };
+            PopupNotifications.show(this.activeBrowser,
+                                    "addon-install-failed", messageString,
+                                    "addons-notification-icon", null,
+                                    null, options);
+          ]]>
+        </body>
+      </method>
+
     </implementation>
   </binding>
 
   <binding id="sidebar-notification"
            extends="chrome://global/content/bindings/notification.xml#notification">
     <content>
       <xul:vbox class="notification-inner outset" flex="1" xbl:inherits="type">
         <xul:hbox align="center">
--- a/suite/themes/classic/mac/navigator/navigator.css
+++ b/suite/themes/classic/mac/navigator/navigator.css
@@ -290,16 +290,25 @@ toolbar[mode="text"] > #window-controls 
   height: 64px;
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
   list-style-image: url("chrome://communicator/skin/icons/geolocation-64.png");
 }
 
+.popup-notification-icon[popupid="addon-install-disabled"],
+.popup-notification-icon[popupid="addon-install-blocked"],
+.popup-notification-icon[popupid="addon-install-failed"],
+.popup-notification-icon[popupid="addon-install-complete"] {
+  list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric.png");
+  width: 32px;
+  height: 32px;
+}
+
 .popup-notification-icon[popupid="password-save"] {
   list-style-image: url("chrome://mozapps/skin/passwordmgr/key-64.png");
 }
 
 /* Notification icon box */
 #notification-popup-box {
   margin: 0 3px;
 }
@@ -310,16 +319,22 @@ toolbar[mode="text"] > #window-controls 
 }
 
 #geo-notification-icon {
   list-style-image: url("chrome://communicator/skin/icons/geolocation-16.png");
   width: 16px;
   height: 16px;
 }
 
+#addons-notification-icon {
+  list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric-16.png");
+  width: 16px;
+  height: 16px;
+}
+
 #password-notification-icon {
   list-style-image: url("chrome://mozapps/skin/passwordmgr/key-16.png");
   width: 16px;
   height: 16px;
 }
 
 /* ::::: page proxy icon ::::: */
 
--- a/suite/themes/classic/navigator/navigator.css
+++ b/suite/themes/classic/navigator/navigator.css
@@ -345,16 +345,25 @@ toolbar[mode="text"] > #window-controls 
   height: 64px;
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
   list-style-image: url("chrome://communicator/skin/icons/geolocation-64.png");
 }
 
+.popup-notification-icon[popupid="addon-install-disabled"],
+.popup-notification-icon[popupid="addon-install-blocked"],
+.popup-notification-icon[popupid="addon-install-failed"],
+.popup-notification-icon[popupid="addon-install-complete"] {
+  list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric.png");
+  width: 32px;
+  height: 32px;
+}
+
 .popup-notification-icon[popupid="password-save"] {
   list-style-image: url("chrome://mozapps/skin/passwordmgr/key-64.png");
 }
 
 /* Notification icon box */
 #notification-popup-box {
   margin: 0 3px;
 }
@@ -364,16 +373,22 @@ toolbar[mode="text"] > #window-controls 
 }
 
 #geo-notification-icon {
   list-style-image: url("chrome://communicator/skin/icons/geolocation-16.png");
   width: 16px;
   height: 16px;
 }
 
+#addons-notification-icon {
+  list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric-16.png");
+  width: 16px;
+  height: 16px;
+}
+
 #password-notification-icon {
   list-style-image: url("chrome://mozapps/skin/passwordmgr/key-16.png");
   width: 16px;
   height: 16px;
 }
 
 /* ::::: page proxy icon ::::: */
 
--- a/suite/themes/modern/navigator/navigator.css
+++ b/suite/themes/modern/navigator/navigator.css
@@ -520,16 +520,25 @@ toolbar[mode="icons"] #search-button > .
   height: 64px;
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
   list-style-image: url("chrome://communicator/skin/icons/geolocation-64.png");
 }
 
+.popup-notification-icon[popupid="addon-install-disabled"],
+.popup-notification-icon[popupid="addon-install-blocked"],
+.popup-notification-icon[popupid="addon-install-failed"],
+.popup-notification-icon[popupid="addon-install-complete"] {
+  list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric.png");
+  width: 32px;
+  height: 32px;
+}
+
 .popup-notification-icon[popupid="password-save"] {
   list-style-image: url("chrome://mozapps/skin/passwordmgr/key-64.png");
 }
 
 /* Notification icon box */
 #notification-popup-box {
   -moz-margin-end: 3px;
 }
@@ -539,16 +548,22 @@ toolbar[mode="icons"] #search-button > .
 }
 
 #geo-notification-icon {
   list-style-image: url("chrome://communicator/skin/icons/geolocation-16.png");
   width: 16px;
   height: 16px;
 }
 
+#addons-notification-icon {
+  list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric-16.png");
+  width: 16px;
+  height: 16px;
+}
+
 #password-notification-icon {
   list-style-image: url("chrome://mozapps/skin/passwordmgr/key-16.png");
   width: 16px;
   height: 16px;
 }
 
 /* ::::: page proxy icon ::::: */