Backed out changeset 37bd20ca096a (bug 1139656) for test_blocklistchange.js xpcshell failures.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 24 Mar 2015 15:36:48 -0400
changeset 252908 6dd5b23f5558daf996798b2a3983a7fd9d4359b6
parent 252907 068c46a5ad3fe4f601bec9a672dc58d2d0573ecb
child 252909 cd66c01ef6415128d9db9468beb668ddb0321650
child 252967 cc0950b7a3696f925e2f0c917649aa537f59aa27
push id1223
push usergijskruitbosch@gmail.com
push dateWed, 25 Mar 2015 00:33:29 +0000
bugs1139656
milestone39.0a1
backs out37bd20ca096a57932b1bb093f31e0e15033af38b
Backed out changeset 37bd20ca096a (bug 1139656) for test_blocklistchange.js xpcshell failures. CLOSED TREE
browser/app/profile/firefox.js
browser/base/content/browser-addons.js
browser/base/content/browser.js
browser/base/content/popup-notifications.inc
browser/base/content/test/general/browser_bug553455.js
browser/base/content/urlbarBindings.xml
browser/locales/en-US/chrome/browser/browser.properties
browser/themes/linux/browser.css
browser/themes/osx/browser.css
browser/themes/windows/browser.css
toolkit/content/widgets/notification.xml
toolkit/modules/PopupNotifications.jsm
toolkit/mozapps/extensions/amWebInstallListener.js
toolkit/mozapps/extensions/test/browser/head.js
toolkit/mozapps/extensions/test/xpinstall/head.js
toolkit/themes/linux/global/global.css
toolkit/themes/linux/global/notification.css
toolkit/themes/osx/global/global.css
toolkit/themes/osx/global/notification.css
toolkit/themes/windows/global/global.css
toolkit/themes/windows/global/notification.css
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -32,18 +32,16 @@ pref("extensions.strictCompatibility", f
 
 // Specifies a minimum maxVersion an addon needs to say it's compatible with
 // for it to be compatible by default.
 pref("extensions.minCompatibleAppVersion", "4.0");
 // Temporary preference to forcibly make themes more safe with Australis even if
 // extensions.checkCompatibility=false has been set.
 pref("extensions.checkCompatibility.temporaryThemeOverride_minAppVersion", "29.0a1");
 
-pref("xpinstall.customConfirmationUI", true);
-
 // Preferences for AMO integration
 pref("extensions.getAddons.cache.enabled", true);
 pref("extensions.getAddons.maxResults", 15);
 pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%");
 pref("extensions.getAddons.getWithPerformance.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%");
 pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%&platform=%OS%&appver=%VERSION%");
 pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%/%COMPATIBILITY_MODE%?src=firefox");
 pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/firefox/discovery/pane/%VERSION%/%OS%/%COMPATIBILITY_MODE%");
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -43,25 +43,19 @@ const gXPInstallObserver = {
     var brandShortName = brandBundle.getString("brandShortName");
 
     var notificationID = aTopic;
     // Make notifications persist a minimum of 30 seconds
     var options = {
       timeout: Date.now() + 30000
     };
 
-    try {
-      options.originHost = installInfo.originatingURI.host;
-    } catch (e) {
-      // originatingURI might be missing or 'host' might throw for non-nsStandardURL nsIURIs.
-    }
-
     switch (aTopic) {
-    case "addon-install-disabled": {
-      notificationID = "xpinstall-disabled";
+    case "addon-install-disabled":
+      notificationID = "xpinstall-disabled"
 
       if (gPrefService.prefIsLocked("xpinstall.enabled")) {
         messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
         buttons = [];
       }
       else {
         messageString = gNavigatorBundle.getString("xpinstallDisabledMessage");
 
@@ -71,78 +65,71 @@ const gXPInstallObserver = {
           callback: function editPrefs() {
             gPrefService.setBoolPref("xpinstall.enabled", true);
           }
         };
       }
 
       PopupNotifications.show(browser, notificationID, messageString, anchorID,
                               action, null, options);
-      break; }
-    case "addon-install-blocked": {
-      if (!options.originHost) {
+      break;
+    case "addon-install-blocked":
+      let originatingHost;
+      try {
+        originatingHost = installInfo.originatingURI.host;
+      } catch (ex) {
         // Need to deal with missing originatingURI and with about:/data: URIs more gracefully,
         // see bug 1063418 - but for now, bail:
         return;
       }
-      messageString = gNavigatorBundle.getFormattedString("xpinstallPromptMessage",
-                        [brandShortName]);
+      messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
+                        [brandShortName, originatingHost]);
 
       let secHistogram = Components.classes["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry).getHistogramById("SECURITY_UI");
       action = {
         label: gNavigatorBundle.getString("xpinstallPromptAllowButton"),
         accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"),
         callback: function() {
           secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_ADDON_ASKING_PREVENTED_CLICK_THROUGH);
           installInfo.install();
         }
       };
 
       secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_ADDON_ASKING_PREVENTED);
       PopupNotifications.show(browser, notificationID, messageString, anchorID,
                               action, null, options);
-      break; }
-    case "addon-install-started": {
-      let needsDownload = function needsDownload(aInstall) {
+      break;
+    case "addon-install-started":
+      var needsDownload = function needsDownload(aInstall) {
         return aInstall.state != AddonManager.STATE_DOWNLOADED;
       }
       // If all installs have already been downloaded then there is no need to
       // show the download progress
       if (!installInfo.installs.some(needsDownload))
         return;
       notificationID = "addon-progress";
-      messageString = gNavigatorBundle.getString("addonDownloadingAndVerifying");
+      messageString = gNavigatorBundle.getString("addonDownloading");
       messageString = PluralForm.get(installInfo.installs.length, messageString);
       options.installs = installInfo.installs;
       options.contentWindow = browser.contentWindow;
       options.sourceURI = browser.currentURI;
-      options.eventCallback = (aEvent) => {
-        switch (aEvent) {
-          case "removed":
-            options.contentWindow = null;
-            options.sourceURI = null;
-            break;
-        }
+      options.eventCallback = function(aEvent) {
+        if (aEvent != "removed")
+          return;
+        options.contentWindow = null;
+        options.sourceURI = null;
       };
-      let notification = PopupNotifications.show(browser, notificationID, messageString,
-                                                 anchorID, null, null, options);
-      notification._startTime = Date.now();
-
-      let cancelButton = document.getElementById("addon-progress-cancel");
-      cancelButton.label = gNavigatorBundle.getString("addonInstall.cancelButton.label");
-      cancelButton.accessKey = gNavigatorBundle.getString("addonInstall.cancelButton.accesskey");
-
-      let acceptButton = document.getElementById("addon-progress-accept");
-      acceptButton.label = gNavigatorBundle.getString("addonInstall.acceptButton.label");
-      acceptButton.accessKey = gNavigatorBundle.getString("addonInstall.acceptButton.accesskey");
-      break; }
-    case "addon-install-failed": {
+      PopupNotifications.show(browser, notificationID, messageString, anchorID,
+                              null, null, options);
+      break;
+    case "addon-install-failed":
       // TODO This isn't terribly ideal for the multiple failure case
       for (let install of installInfo.installs) {
-        let host = options.originHost;
+        let host = (installInfo.originatingURI instanceof Ci.nsIStandardURL) &&
+                   installInfo.originatingURI.host;
         if (!host)
           host = (install.sourceURI instanceof Ci.nsIStandardURL) &&
                  install.sourceURI.host;
 
         let error = (host || install.error == 0) ? "addonError" : "addonLocalError";
         if (install.error != 0)
           error += install.error;
         else if (install.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
@@ -155,110 +142,19 @@ const gXPInstallObserver = {
         if (host)
           messageString = messageString.replace("#2", host);
         messageString = messageString.replace("#3", brandShortName);
         messageString = messageString.replace("#4", Services.appinfo.version);
 
         PopupNotifications.show(browser, notificationID, messageString, anchorID,
                                 action, null, options);
       }
-      this._removeProgressNotification(browser);
-      break; }
-    case "addon-install-confirmation": {
-      options.eventCallback = (aEvent) => {
-        switch (aEvent) {
-          case "removed":
-            if (installInfo) {
-              for (let install of installInfo.installs)
-                install.cancel();
-            }
-            this.acceptInstallation = null;
-            break;
-          case "shown":
-            let addonList = document.getElementById("addon-install-confirmation-content");
-            while (addonList.firstChild)
-              addonList.firstChild.remove();
-
-            for (let install of installInfo.installs) {
-              let container = document.createElement("hbox");
-              let name = document.createElement("label");
-              let author = document.createElement("label");
-              name.setAttribute("value", install.addon.name);
-              author.setAttribute("value", !install.addon.creator ? "" :
-                gNavigatorBundle.getFormattedString("addonConfirmInstall.author", [install.addon.creator]));
-              name.setAttribute("class", "addon-install-confirmation-name");
-              author.setAttribute("class", "addon-install-confirmation-author");
-              container.appendChild(name);
-              container.appendChild(author);
-              addonList.appendChild(container);
-            }
-
-            this.acceptInstallation = () => {
-              for (let install of installInfo.installs)
-                install.install();
-              installInfo = null;
-
-              Services.telemetry
-                      .getHistogramById("SECURITY_UI")
-                      .add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL_CLICK_THROUGH);
-            };
-            break;
-        }
-      };
-
-      messageString = gNavigatorBundle.getString("addonConfirmInstall.message");
-      messageString = PluralForm.get(installInfo.installs.length, messageString);
-      messageString = messageString.replace("#1", brandShortName);
-      messageString = messageString.replace("#2", installInfo.installs.length);
-
-      let cancelButton = document.getElementById("addon-install-confirmation-cancel");
-      cancelButton.label = gNavigatorBundle.getString("addonInstall.cancelButton.label");
-      cancelButton.accessKey = gNavigatorBundle.getString("addonInstall.cancelButton.accesskey");
-
-      let acceptButton = document.getElementById("addon-install-confirmation-accept");
-      acceptButton.label = gNavigatorBundle.getString("addonInstall.acceptButton.label");
-      acceptButton.accessKey = gNavigatorBundle.getString("addonInstall.acceptButton.accesskey");
-
-      let showNotification = () => {
-        // The download may have been cancelled during the security delay
-        if (!PopupNotifications.getNotification("addon-progress", browser))
-          return;
-
-        let tab = gBrowser.getTabForBrowser(browser);
-        if (tab)
-          gBrowser.selectedTab = tab;
-
-        if (PopupNotifications.isPanelOpen) {
-          let rect = document.getElementById("addon-progress-notification").getBoundingClientRect();
-          let notification = document.getElementById("addon-install-confirmation-notification");
-          notification.style.minHeight = rect.height + "px";
-        }
-
-        PopupNotifications.show(browser, notificationID, messageString, anchorID,
-                                action, null, options);
-
-        this._removeProgressNotification(browser);
-
-        Services.telemetry
-                .getHistogramById("SECURITY_UI")
-                .add(Ci.nsISecurityUITelemetry.WARNING_CONFIRM_ADDON_INSTALL);
-      };
-
-      let downloadDuration = 0;
-      let progressNotification = PopupNotifications.getNotification("addon-progress", browser);
-      if (progressNotification)
-        downloadDuration = Date.now() - progressNotification._startTime;
-      let securityDelay = Services.prefs.getIntPref("security.dialog_enable_delay") - downloadDuration;
-      if (securityDelay > 0)
-        setTimeout(showNotification, securityDelay);
-      else
-        showNotification();
-      break; }
-    case "addon-install-complete": {
-      let needsRestart = installInfo.installs.some(function(i) {
+      break;
+    case "addon-install-complete":
+      var needsRestart = installInfo.installs.some(function(i) {
         return i.addon.pendingOperations != AddonManager.PENDING_NONE;
       });
 
       if (needsRestart) {
         messageString = gNavigatorBundle.getString("addonsInstalledNeedsRestart");
         action = {
           label: gNavigatorBundle.getString("addonInstallRestartButton"),
           accessKey: gNavigatorBundle.getString("addonInstallRestartButton.accesskey"),
@@ -279,23 +175,18 @@ const gXPInstallObserver = {
 
       // Remove notificaion on dismissal, since it's possible to cancel the
       // install through the addons manager UI, making the "restart" prompt
       // irrelevant.
       options.removeOnDismissal = true;
 
       PopupNotifications.show(browser, notificationID, messageString, anchorID,
                               action, null, options);
-      break; }
+      break;
     }
-  },
-  _removeProgressNotification(aBrowser) {
-    let notification = PopupNotifications.getNotification("addon-progress", aBrowser);
-    if (notification)
-      notification.remove();
   }
 };
 
 var LightWeightThemeWebInstaller = {
   handleEvent: function (event) {
     switch (event.type) {
       case "InstallBrowserTheme":
       case "PreviewBrowserTheme":
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1218,17 +1218,16 @@ var gBrowserInit = {
     setTimeout(function() { SafeBrowsing.init(); }, 2000);
 #endif
 
     Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-started", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
-    Services.obs.addObserver(gXPInstallObserver, "addon-install-confirmation", false);
     Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
     window.messageManager.addMessageListener("Browser:URIFixup", gKeywordURIFixup);
 
     BrowserOffline.init();
     OfflineApps.init();
     IndexedDBPromptHelper.init();
 #ifdef E10S_TESTING_ONLY
     gRemoteTabsUI.init();
@@ -1530,17 +1529,16 @@ var gBrowserInit = {
       LoopUI.uninit();
       FullZoom.destroy();
 
       Services.obs.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
       Services.obs.removeObserver(gXPInstallObserver, "addon-install-disabled");
       Services.obs.removeObserver(gXPInstallObserver, "addon-install-started");
       Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
       Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
-      Services.obs.removeObserver(gXPInstallObserver, "addon-install-confirmation");
       Services.obs.removeObserver(gXPInstallObserver, "addon-install-complete");
       window.messageManager.removeMessageListener("Browser:URIFixup", gKeywordURIFixup);
       window.messageManager.removeMessageListener("Browser:LoadURI", RedirectLoad);
 
       try {
         gPrefService.removeObserver(gHomeButton.prefDomain, gHomeButton);
       } catch (ex) {
         Cu.reportError(ex);
--- a/browser/base/content/popup-notifications.inc
+++ b/browser/base/content/popup-notifications.inc
@@ -5,56 +5,62 @@
            footertype="promobox"
            position="after_start"
            hidden="true"
            orient="vertical"
            role="alert"/>
 
     <popupnotification id="webRTC-shareDevices-notification" hidden="true">
       <popupnotificationcontent id="webRTC-selectCamera" orient="vertical">
+        <separator class="thin"/>
         <label value="&getUserMedia.selectCamera.label;"
                accesskey="&getUserMedia.selectCamera.accesskey;"
                control="webRTC-selectCamera-menulist"/>
         <menulist id="webRTC-selectCamera-menulist">
           <menupopup id="webRTC-selectCamera-menupopup"/>
         </menulist>
       </popupnotificationcontent>
 
       <popupnotificationcontent id="webRTC-selectWindowOrScreen" orient="vertical">
+        <separator class="thin"/>
         <label id="webRTC-selectWindow-label"
                control="webRTC-selectWindow-menulist"/>
         <menulist id="webRTC-selectWindow-menulist"
                   oncommand="gWebRTCUI.updateMainActionLabel(this);">
           <menupopup id="webRTC-selectWindow-menupopup"/>
         </menulist>
         <description id="webRTC-all-windows-shared" hidden="true">&getUserMedia.allWindowsShared.message;</description>
       </popupnotificationcontent>
 
       <popupnotificationcontent id="webRTC-selectMicrophone" orient="vertical">
+        <separator class="thin"/>
         <label value="&getUserMedia.selectMicrophone.label;"
                accesskey="&getUserMedia.selectMicrophone.accesskey;"
                control="webRTC-selectMicrophone-menulist"/>
         <menulist id="webRTC-selectMicrophone-menulist">
           <menupopup id="webRTC-selectMicrophone-menupopup"/>
         </menulist>
       </popupnotificationcontent>
     </popupnotification>
 
     <popupnotification id="webapps-install-progress-notification" hidden="true">
-      <popupnotificationcontent id="webapps-install-progress-content" orient="vertical" align="start"/>
+      <popupnotificationcontent id="webapps-install-progress-content" orient="vertical" align="start">
+        <separator class="thin"/>
+      </popupnotificationcontent>
     </popupnotification>
 
     <popupnotification id="servicesInstall-notification" hidden="true">
       <popupnotificationcontent orient="vertical" align="start">
         <!-- XXX bug 974146, tests are looking for this, can't remove yet. -->
       </popupnotificationcontent>
     </popupnotification>
 
     <popupnotification id="pointerLock-notification" hidden="true">
       <popupnotificationcontent orient="vertical" align="start">
+        <separator class="thin"/>
         <label id="pointerLock-cancel">&pointerLock.notification.message;</label>
       </popupnotificationcontent>
     </popupnotification>
 
     <popupnotification id="password-notification" hidden="true">
       <popupnotificationcontent orient="vertical">
         <textbox id="password-notification-username"/>
         <textbox id="password-notification-password" type="password"
@@ -62,23 +68,8 @@
       </popupnotificationcontent>
     </popupnotification>
 
 #ifdef E10S_TESTING_ONLY
     <popupnotification id="enable-e10s-notification" hidden="true">
       <popupnotificationcontent orient="vertical"/>
     </popupnotification>
 #endif
-
-    <popupnotification id="addon-progress-notification" hidden="true">
-      <button id="addon-progress-cancel"
-              oncommand="this.parentNode.cancel();"/>
-      <button id="addon-progress-accept" disabled="true"/>
-    </popupnotification>
-
-    <popupnotification id="addon-install-confirmation-notification" hidden="true">
-      <popupnotificationcontent id="addon-install-confirmation-content" orient="vertical"/>
-      <button id="addon-install-confirmation-cancel"
-              oncommand="PopupNotifications.getNotification('addon-install-confirmation').remove();"/>
-      <button id="addon-install-confirmation-accept"
-              oncommand="gXPInstallObserver.acceptInstallation();
-                         PopupNotifications.getNotification('addon-install-confirmation').remove();"/>
-    </popupnotification>
--- a/browser/base/content/test/general/browser_bug553455.js
+++ b/browser/base/content/test/general/browser_bug553455.js
@@ -1,96 +1,92 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 const TESTROOT = "http://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/";
 const TESTROOT2 = "http://example.org/browser/toolkit/mozapps/extensions/test/xpinstall/";
 const SECUREROOT = "https://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/";
+const XPINSTALL_URL = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
 const PREF_INSTALL_REQUIREBUILTINCERTS = "extensions.install.requireBuiltInCerts";
-const PROGRESS_NOTIFICATION = "addon-progress";
+const PROGRESS_NOTIFICATION = "addon-progress-notification";
 
 var rootDir = getRootDirectory(gTestPath);
 var path = rootDir.split('/');
 var chromeName = path[0] + '//' + path[2];
 var croot = chromeName + "/content/browser/toolkit/mozapps/extensions/test/xpinstall/";
 var jar = getJar(croot);
 if (jar) {
   var tmpdir = extractJarToTmp(jar);
   croot = 'file://' + tmpdir.path + '/';
 }
 const CHROMEROOT = croot;
 
 var gApp = document.getElementById("bundle_brand").getString("brandShortName");
 var gVersion = Services.appinfo.version;
-
-function get_observer_topic(aNotificationId) {
-  let topic = aNotificationId;
-  if (topic == "xpinstall-disabled")
-    topic = "addon-install-disabled";
-  else if (topic == "addon-progress")
-    topic = "addon-install-started";
-  return topic;
-}
+var check_notification;
 
 function wait_for_progress_notification(aCallback) {
   wait_for_notification(PROGRESS_NOTIFICATION, aCallback, "popupshowing");
 }
 
 function wait_for_notification(aId, aCallback, aEvent = "popupshown") {
   info("Waiting for " + aId + " notification");
-
-  let topic = get_observer_topic(aId);
-  function observer(aSubject, aTopic, aData) {
+  check_notification = function() {
     // Ignore the progress notification unless that is the notification we want
-    if (aId != PROGRESS_NOTIFICATION &&
-        aTopic == get_observer_topic(PROGRESS_NOTIFICATION))
+    if (aId != PROGRESS_NOTIFICATION && PopupNotifications.panel.childNodes[0].id == PROGRESS_NOTIFICATION)
       return;
 
-    Services.obs.removeObserver(observer, topic);
-
-    if (PopupNotifications.isPanelOpen)
-      executeSoon(verify);
-    else
-      PopupNotifications.panel.addEventListener(aEvent, event_listener);
-  }
-
-  function event_listener() {
-    // Ignore the progress notification unless that is the notification we want
-    if (aId != PROGRESS_NOTIFICATION &&
-        PopupNotifications.panel.childNodes[0].id == PROGRESS_NOTIFICATION + "-notification")
-      return;
-
-    PopupNotifications.panel.removeEventListener(aEvent, event_listener);
-
-    verify();
-  }
-
-  function verify() {
+    PopupNotifications.panel.removeEventListener(aEvent, check_notification, false);
     info("Saw a notification");
-    ok(PopupNotifications.isPanelOpen, "Panel should be open");
     is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
-    if (PopupNotifications.panel.childNodes.length) {
-      is(PopupNotifications.panel.childNodes[0].id,
-         aId + "-notification", "Should have seen the right notification");
-    }
+    if (PopupNotifications.panel.childNodes.length)
+      is(PopupNotifications.panel.childNodes[0].id, aId, "Should have seen the right notification");
     aCallback(PopupNotifications.panel);
-  }
-
-  Services.obs.addObserver(observer, topic, false);
+  };
+  PopupNotifications.panel.addEventListener(aEvent, check_notification, false);
 }
 
 function wait_for_notification_close(aCallback) {
   info("Waiting for notification to close");
   PopupNotifications.panel.addEventListener("popuphidden", function() {
     PopupNotifications.panel.removeEventListener("popuphidden", arguments.callee, false);
     aCallback();
   }, false);
 }
 
+function wait_for_install_dialog(aCallback) {
+  info("Waiting for install dialog");
+  Services.wm.addListener({
+    onOpenWindow: function(aXULWindow) {
+      info("Install dialog opened, waiting for focus");
+      Services.wm.removeListener(this);
+
+      var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+                                .getInterface(Ci.nsIDOMWindow);
+      waitForFocus(function() {
+        info("Saw install dialog");
+        is(domwindow.document.location.href, XPINSTALL_URL, "Should have seen the right window open");
+
+        // Override the countdown timer on the accept button
+        var button = domwindow.document.documentElement.getButton("accept");
+        button.disabled = false;
+
+        aCallback(domwindow);
+      }, domwindow);
+    },
+
+    onCloseWindow: function(aXULWindow) {
+    },
+
+    onWindowTitleChange: function(aXULWindow, aNewTitle) {
+    }
+  });
+}
+
 function wait_for_single_notification(aCallback) {
   function inner_waiter() {
     info("Waiting for single notification");
     // Notification should never close while we wait
     ok(PopupNotifications.isPanelOpen, "Notification should still be open");
     if (PopupNotifications.panel.childNodes.length == 2) {
       executeSoon(inner_waiter);
       return;
@@ -113,17 +109,17 @@ function setup_redirect(aSettings) {
   req.send(null);
 }
 
 var TESTS = [
 function test_disabled_install() {
   Services.prefs.setBoolPref("xpinstall.enabled", false);
 
   // Wait for the disabled notification
-  wait_for_notification("xpinstall-disabled", function(aPanel) {
+  wait_for_notification("xpinstall-disabled-notification", function(aPanel) {
     let notification = aPanel.childNodes[0];
     is(notification.button.label, "Enable", "Should have seen the right button");
     is(notification.getAttribute("label"),
        "Software installation is currently disabled. Click Enable and try again.");
 
     wait_for_notification_close(function() {
       try {
         ok(Services.prefs.getBoolPref("xpinstall.enabled"), "Installation should be enabled");
@@ -150,112 +146,105 @@ function test_disabled_install() {
     "XPI": "unsigned.xpi"
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_blocked_install() {
   // Wait for the blocked notification
-  wait_for_notification("addon-install-blocked", function(aPanel) {
+  wait_for_notification("addon-install-blocked-notification", function(aPanel) {
     let notification = aPanel.childNodes[0];
     is(notification.button.label, "Allow", "Should have seen the right button");
-    is(notification.getAttribute("originhost"), "example.com",
-       "Should have seen the right origin host");
     is(notification.getAttribute("label"),
-       gApp + " prevented this site from asking you to install software on your computer.",
+       gApp + " prevented this site (example.com) from asking you to install " +
+       "software on your computer.",
        "Should have seen the right message");
 
     // Wait for the install confirmation dialog
-    wait_for_notification("addon-install-confirmation", function(aPanel) {
+    wait_for_install_dialog(function(aWindow) {
       // Wait for the complete notification
-      wait_for_notification("addon-install-complete", function(aPanel) {
+      wait_for_notification("addon-install-complete-notification", function(aPanel) {
         let notification = aPanel.childNodes[0];
         is(notification.button.label, "Restart Now", "Should have seen the right button");
         is(notification.getAttribute("label"),
            "XPI Test will be installed after you restart " + gApp + ".",
            "Should have seen the right message");
 
         AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
           aInstalls[0].cancel();
 
           wait_for_notification_close(runNextTest);
           gBrowser.removeTab(gBrowser.selectedTab);
         });
       });
 
-      document.getElementById("addon-install-confirmation-accept").click();
+      aWindow.document.documentElement.acceptDialog();
     });
 
     // Click on Allow
     EventUtils.synthesizeMouse(notification.button, 20, 10, {});
 
     // Notification should have changed to progress notification
     ok(PopupNotifications.isPanelOpen, "Notification should still be open");
     notification = aPanel.childNodes[0];
     is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
+
   });
 
   var triggers = encodeURIComponent(JSON.stringify({
     "XPI": "unsigned.xpi"
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_whitelisted_install() {
   // Wait for the progress notification
   wait_for_progress_notification(function(aPanel) {
-    gBrowser.selectedTab = originalTab;
-
     // Wait for the install confirmation dialog
-    wait_for_notification("addon-install-confirmation", function(aPanel) {
-      is(gBrowser.selectedTab, tab,
-         "tab selected in response to the addon-install-confirmation notification");
-
+    wait_for_install_dialog(function(aWindow) {
       // Wait for the complete notification
-      wait_for_notification("addon-install-complete", function(aPanel) {
+      wait_for_notification("addon-install-complete-notification", function(aPanel) {
         let notification = aPanel.childNodes[0];
         is(notification.button.label, "Restart Now", "Should have seen the right button");
         is(notification.getAttribute("label"),
            "XPI Test will be installed after you restart " + gApp + ".",
            "Should have seen the right message");
 
         AddonManager.getAllInstalls(function(aInstalls) {
           is(aInstalls.length, 1, "Should be one pending install");
           aInstalls[0].cancel();
 
           Services.perms.remove("example.com", "install");
           wait_for_notification_close(runNextTest);
           gBrowser.removeTab(gBrowser.selectedTab);
         });
       });
 
-      document.getElementById("addon-install-confirmation-accept").click();
+      aWindow.document.documentElement.acceptDialog();
     });
   });
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   var triggers = encodeURIComponent(JSON.stringify({
     "XPI": "unsigned.xpi"
   }));
-  let originalTab = gBrowser.selectedTab;
-  let tab = gBrowser.addTab();
-  gBrowser.selectedTab = tab;
+  gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_failed_download() {
   // Wait for the progress notification
   wait_for_progress_notification(function(aPanel) {
     // Wait for the failed notification
-    wait_for_notification("addon-install-failed", function(aPanel) {
+    wait_for_notification("addon-install-failed-notification", function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.getAttribute("label"),
          "The add-on could not be downloaded because of a connection failure " +
          "on example.com.",
          "Should have seen the right message");
 
       Services.perms.remove("example.com", "install");
       wait_for_notification_close(runNextTest);
@@ -272,17 +261,17 @@ function test_failed_download() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_corrupt_file() {
   // Wait for the progress notification
   wait_for_progress_notification(function(aPanel) {
     // Wait for the failed notification
-    wait_for_notification("addon-install-failed", function(aPanel) {
+    wait_for_notification("addon-install-failed-notification", function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.getAttribute("label"),
          "The add-on downloaded from example.com could not be installed " +
          "because it appears to be corrupt.",
          "Should have seen the right message");
 
       Services.perms.remove("example.com", "install");
       wait_for_notification_close(runNextTest);
@@ -299,17 +288,17 @@ function test_corrupt_file() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_incompatible() {
   // Wait for the progress notification
   wait_for_progress_notification(function(aPanel) {
     // Wait for the failed notification
-    wait_for_notification("addon-install-failed", function(aPanel) {
+    wait_for_notification("addon-install-failed-notification", function(aPanel) {
       let notification = aPanel.childNodes[0];
       is(notification.getAttribute("label"),
          "XPI Test could not be installed because it is not compatible with " +
          gApp + " " + gVersion + ".",
          "Should have seen the right message");
 
       Services.perms.remove("example.com", "install");
       wait_for_notification_close(runNextTest);
@@ -326,19 +315,19 @@ function test_incompatible() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_restartless() {
   // Wait for the progress notification
   wait_for_progress_notification(function(aPanel) {
     // Wait for the install confirmation dialog
-    wait_for_notification("addon-install-confirmation", function(aPanel) {
+    wait_for_install_dialog(function(aWindow) {
       // Wait for the complete notification
-      wait_for_notification("addon-install-complete", function(aPanel) {
+      wait_for_notification("addon-install-complete-notification", function(aPanel) {
         let notification = aPanel.childNodes[0];
         is(notification.getAttribute("label"),
            "XPI Test has been installed successfully.",
            "Should have seen the right message");
 
         AddonManager.getAllInstalls(function(aInstalls) {
           is(aInstalls.length, 0, "Should be no pending installs");
 
@@ -347,17 +336,17 @@ function test_restartless() {
 
             Services.perms.remove("example.com", "install");
             wait_for_notification_close(runNextTest);
             gBrowser.removeTab(gBrowser.selectedTab);
           });
         });
       });
 
-      document.getElementById("addon-install-confirmation-accept").click();
+      aWindow.document.documentElement.acceptDialog();
     });
   });
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   var triggers = encodeURIComponent(JSON.stringify({
     "XPI": "restartless.xpi"
@@ -365,19 +354,19 @@ function test_restartless() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_multiple() {
   // Wait for the progress notification
   wait_for_progress_notification(function(aPanel) {
     // Wait for the install confirmation dialog
-    wait_for_notification("addon-install-confirmation", function(aPanel) {
+    wait_for_install_dialog(function(aWindow) {
       // Wait for the complete notification
-      wait_for_notification("addon-install-complete", function(aPanel) {
+      wait_for_notification("addon-install-complete-notification", function(aPanel) {
         let notification = aPanel.childNodes[0];
         is(notification.button.label, "Restart Now", "Should have seen the right button");
         is(notification.getAttribute("label"),
            "2 add-ons will be installed after you restart " + gApp + ".",
            "Should have seen the right message");
 
         AddonManager.getAllInstalls(function(aInstalls) {
           is(aInstalls.length, 1, "Should be one pending install");
@@ -388,17 +377,17 @@ function test_multiple() {
 
             Services.perms.remove("example.com", "install");
             wait_for_notification_close(runNextTest);
             gBrowser.removeTab(gBrowser.selectedTab);
           });
         });
       });
 
-      document.getElementById("addon-install-confirmation-accept").click();
+      aWindow.document.documentElement.acceptDialog();
     });
   });
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   var triggers = encodeURIComponent(JSON.stringify({
     "Unsigned XPI": "unsigned.xpi",
@@ -407,35 +396,35 @@ function test_multiple() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_url() {
   // Wait for the progress notification
   wait_for_progress_notification(function(aPanel) {
     // Wait for the install confirmation dialog
-    wait_for_notification("addon-install-confirmation", function(aPanel) {
+    wait_for_install_dialog(function(aWindow) {
       // Wait for the complete notification
-      wait_for_notification("addon-install-complete", function(aPanel) {
+      wait_for_notification("addon-install-complete-notification", function(aPanel) {
         let notification = aPanel.childNodes[0];
         is(notification.button.label, "Restart Now", "Should have seen the right button");
         is(notification.getAttribute("label"),
            "XPI Test will be installed after you restart " + gApp + ".",
            "Should have seen the right message");
 
         AddonManager.getAllInstalls(function(aInstalls) {
           is(aInstalls.length, 1, "Should be one pending install");
           aInstalls[0].cancel();
 
           wait_for_notification_close(runNextTest);
           gBrowser.removeTab(gBrowser.selectedTab);
         });
       });
 
-      document.getElementById("addon-install-confirmation-accept").click();
+      aWindow.document.documentElement.acceptDialog();
     });
   });
 
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "unsigned.xpi");
 },
 
 function test_localfile() {
@@ -473,17 +462,17 @@ function test_wronghost() {
     if (gBrowser.currentURI.spec != TESTROOT2 + "enabled.html")
       return;
 
     gBrowser.removeEventListener("load", arguments.callee, true);
 
     // Wait for the progress notification
     wait_for_progress_notification(function(aPanel) {
       // Wait for the complete notification
-      wait_for_notification("addon-install-failed", function(aPanel) {
+      wait_for_notification("addon-install-failed-notification", function(aPanel) {
         let notification = aPanel.childNodes[0];
         is(notification.getAttribute("label"),
            "The add-on downloaded from example.com could not be installed " +
            "because it appears to be corrupt.",
            "Should have seen the right message");
 
         wait_for_notification_close(runNextTest);
         gBrowser.removeTab(gBrowser.selectedTab);
@@ -494,19 +483,19 @@ function test_wronghost() {
   }, true);
   gBrowser.loadURI(TESTROOT2 + "enabled.html");
 },
 
 function test_reload() {
   // Wait for the progress notification
   wait_for_progress_notification(function(aPanel) {
     // Wait for the install confirmation dialog
-    wait_for_notification("addon-install-confirmation", function(aPanel) {
+    wait_for_install_dialog(function(aWindow) {
       // Wait for the complete notification
-      wait_for_notification("addon-install-complete", function(aPanel) {
+      wait_for_notification("addon-install-complete-notification", function(aPanel) {
         let notification = aPanel.childNodes[0];
         is(notification.button.label, "Restart Now", "Should have seen the right button");
         is(notification.getAttribute("label"),
            "XPI Test will be installed after you restart " + gApp + ".",
            "Should have seen the right message");
 
         function test_fail() {
           ok(false, "Reloading should not have hidden the notification");
@@ -529,17 +518,17 @@ function test_reload() {
             Services.perms.remove("example.com", "install");
             wait_for_notification_close(runNextTest);
             gBrowser.removeTab(gBrowser.selectedTab);
           });
         }, true);
         gBrowser.loadURI(TESTROOT2 + "enabled.html");
       });
 
-      document.getElementById("addon-install-confirmation-accept").click();
+      aWindow.document.documentElement.acceptDialog();
     });
   });
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   var triggers = encodeURIComponent(JSON.stringify({
     "Unsigned XPI": "unsigned.xpi"
@@ -547,19 +536,19 @@ function test_reload() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_theme() {
   // Wait for the progress notification
   wait_for_progress_notification(function(aPanel) {
     // Wait for the install confirmation dialog
-    wait_for_notification("addon-install-confirmation", function(aPanel) {
+    wait_for_install_dialog(function(aWindow) {
       // Wait for the complete notification
-      wait_for_notification("addon-install-complete", function(aPanel) {
+      wait_for_notification("addon-install-complete-notification", function(aPanel) {
         let notification = aPanel.childNodes[0];
         is(notification.button.label, "Restart Now", "Should have seen the right button");
         is(notification.getAttribute("label"),
            "Theme Test will be installed after you restart " + gApp + ".",
            "Should have seen the right message");
 
         AddonManager.getAddonByID("{972ce4c6-7e08-4474-a285-3208198ce6fd}", function(aAddon) {
           ok(aAddon.userDisabled, "Should be switching away from the default theme.");
@@ -572,39 +561,39 @@ function test_theme() {
 
             Services.perms.remove("example.com", "install");
             wait_for_notification_close(runNextTest);
             gBrowser.removeTab(gBrowser.selectedTab);
           });
         });
       });
 
-      document.getElementById("addon-install-confirmation-accept").click();
+      aWindow.document.documentElement.acceptDialog();
     });
   });
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   var triggers = encodeURIComponent(JSON.stringify({
     "Theme XPI": "theme.xpi"
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_renotify_blocked() {
   // Wait for the blocked notification
-  wait_for_notification("addon-install-blocked", function(aPanel) {
+  wait_for_notification("addon-install-blocked-notification", function(aPanel) {
     let notification = aPanel.childNodes[0];
 
     wait_for_notification_close(function () {
       info("Timeouts after this probably mean bug 589954 regressed");
       executeSoon(function () {
-        wait_for_notification("addon-install-blocked", function(aPanel) {
+        wait_for_notification("addon-install-blocked-notification", function(aPanel) {
           AddonManager.getAllInstalls(function(aInstalls) {
           is(aInstalls.length, 2, "Should be two pending installs");
             aInstalls[0].cancel();
             aInstalls[1].cancel();
 
             info("Closing browser tab");
             wait_for_notification_close(runNextTest);
             gBrowser.removeTab(gBrowser.selectedTab);
@@ -625,104 +614,135 @@ function test_renotify_blocked() {
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
 function test_renotify_installed() {
   // Wait for the progress notification
   wait_for_progress_notification(function(aPanel) {
     // Wait for the install confirmation dialog
-    wait_for_notification("addon-install-confirmation", function(aPanel) {
+    wait_for_install_dialog(function(aWindow) {
       // Wait for the complete notification
-      wait_for_notification("addon-install-complete", function(aPanel) {
+      wait_for_notification("addon-install-complete-notification", function(aPanel) {
         // Dismiss the notification
         wait_for_notification_close(function () {
           // Install another
           executeSoon(function () {
             // Wait for the progress notification
             wait_for_progress_notification(function(aPanel) {
               // Wait for the install confirmation dialog
-              wait_for_notification("addon-install-confirmation", function(aPanel) {
+              wait_for_install_dialog(function(aWindow) {
                 info("Timeouts after this probably mean bug 589954 regressed");
 
                 // Wait for the complete notification
-                wait_for_notification("addon-install-complete", function(aPanel) {
+                wait_for_notification("addon-install-complete-notification", function(aPanel) {
                   AddonManager.getAllInstalls(function(aInstalls) {
                   is(aInstalls.length, 1, "Should be one pending installs");
                     aInstalls[0].cancel();
 
                     Services.perms.remove("example.com", "install");
                     wait_for_notification_close(runNextTest);
                     gBrowser.removeTab(gBrowser.selectedTab);
                   });
                 });
 
-                document.getElementById("addon-install-confirmation-accept").click();
+                aWindow.document.documentElement.acceptDialog();
               });
             });
 
             gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
           });
         });
 
         // hide the panel (this simulates the user dismissing it)
         aPanel.hidePopup();
       });
 
-      document.getElementById("addon-install-confirmation-accept").click();
+      aWindow.document.documentElement.acceptDialog();
     });
   });
 
   var pm = Services.perms;
   pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
 
   var triggers = encodeURIComponent(JSON.stringify({
     "XPI": "unsigned.xpi"
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 },
 
-function test_cancel() {
+function test_cancel_restart() {
   function complete_install(callback) {
     let url = TESTROOT + "slowinstall.sjs?continue=true"
     NetUtil.asyncFetch(url, callback || (() => {}));
   }
 
   // Wait for the progress notification
   wait_for_notification(PROGRESS_NOTIFICATION, function(aPanel) {
     let notification = aPanel.childNodes[0];
     // Close the notification
     let anchor = document.getElementById("addons-notification-icon");
     anchor.click();
     // Reopen the notification
     anchor.click();
 
     ok(PopupNotifications.isPanelOpen, "Notification should still be open");
     is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
+    isnot(notification, aPanel.childNodes[0], "Should have reconstructed the notification UI");
     notification = aPanel.childNodes[0];
     is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
-    let button = document.getElementById("addon-progress-cancel");
+    let button = document.getAnonymousElementByAttribute(notification, "anonid", "cancel");
 
     // Wait for the install to fully cancel
     let install = notification.notification.options.installs[0];
     install.addListener({
       onDownloadCancelled: function() {
         install.removeListener(this);
 
         executeSoon(function() {
-          ok(!PopupNotifications.isPanelOpen, "Notification should be closed");
+          ok(PopupNotifications.isPanelOpen, "Notification should still be open");
+          is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
+          isnot(notification, aPanel.childNodes[0], "Should have reconstructed the notification UI");
+          notification = aPanel.childNodes[0];
+          is(notification.id, "addon-install-cancelled-notification", "Should have seen the cancelled notification");
 
-          AddonManager.getAllInstalls(function(aInstalls) {
-            is(aInstalls.length, 0, "Should be no pending install");
+          // Wait for the install confirmation dialog
+          wait_for_install_dialog(function(aWindow) {
+            // Wait for the complete notification
+            wait_for_notification("addon-install-complete-notification", function(aPanel) {
+              let notification = aPanel.childNodes[0];
+              is(notification.button.label, "Restart Now", "Should have seen the right button");
+              is(notification.getAttribute("label"),
+                 "XPI Test will be installed after you restart " + gApp + ".",
+                 "Should have seen the right message");
+
+              AddonManager.getAllInstalls(function(aInstalls) {
+                is(aInstalls.length, 1, "Should be one pending install");
+                aInstalls[0].cancel();
 
-            Services.perms.remove("example.com", "install");
-            gBrowser.removeTab(gBrowser.selectedTab);
-            runNextTest();
+                Services.perms.remove("example.com", "install");
+                wait_for_notification_close(runNextTest);
+                gBrowser.removeTab(gBrowser.selectedTab);
+              });
+            });
+
+            aWindow.document.documentElement.acceptDialog();
           });
+
+          // Restart the download
+          EventUtils.synthesizeMouseAtCenter(notification.button, {});
+
+          // Should be back to a progress notification
+          ok(PopupNotifications.isPanelOpen, "Notification should still be open");
+          is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
+          notification = aPanel.childNodes[0];
+          is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
+
+          complete_install();
         });
       }
     });
 
     // Cancel the download
     EventUtils.synthesizeMouseAtCenter(button, {});
   });
 
@@ -739,17 +759,17 @@ function test_cancel() {
 function test_failed_security() {
   Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false);
 
   setup_redirect({
     "Location": TESTROOT + "unsigned.xpi"
   });
 
   // Wait for the blocked notification
-  wait_for_notification("addon-install-blocked", function(aPanel) {
+  wait_for_notification("addon-install-blocked-notification", function(aPanel) {
     let notification = aPanel.childNodes[0];
 
     // Click on Allow
     EventUtils.synthesizeMouse(notification.button, 20, 10, {});
 
     // Notification should have changed to progress notification
     ok(PopupNotifications.isPanelOpen, "Notification should still be open");
     is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
@@ -816,37 +836,36 @@ var XPInstallObserver = {
 
 function test() {
   requestLongerTimeout(4);
   waitForExplicitFinish();
 
   Services.prefs.setBoolPref("extensions.logging.enabled", true);
   Services.prefs.setBoolPref("extensions.strictCompatibility", true);
   Services.prefs.setBoolPref("extensions.install.requireSecureOrigin", false);
-  Services.prefs.setIntPref("security.dialog_enable_delay", 0);
 
   Services.obs.addObserver(XPInstallObserver, "addon-install-started", false);
   Services.obs.addObserver(XPInstallObserver, "addon-install-blocked", false);
   Services.obs.addObserver(XPInstallObserver, "addon-install-failed", false);
   Services.obs.addObserver(XPInstallObserver, "addon-install-complete", false);
 
   registerCleanupFunction(function() {
     // Make sure no more test parts run in case we were timed out
     TESTS = [];
+    PopupNotifications.panel.removeEventListener("popupshown", check_notification, false);
 
     AddonManager.getAllInstalls(function(aInstalls) {
       aInstalls.forEach(function(aInstall) {
         aInstall.cancel();
       });
     });
 
     Services.prefs.clearUserPref("extensions.logging.enabled");
     Services.prefs.clearUserPref("extensions.strictCompatibility");
     Services.prefs.clearUserPref("extensions.install.requireSecureOrigin");
-    Services.prefs.clearUserPref("security.dialog_enable_delay");
 
     Services.obs.removeObserver(XPInstallObserver, "addon-install-started");
     Services.obs.removeObserver(XPInstallObserver, "addon-install-blocked");
     Services.obs.removeObserver(XPInstallObserver, "addon-install-failed");
     Services.obs.removeObserver(XPInstallObserver, "addon-install-complete");
   });
 
   runNextTest();
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -1568,27 +1568,26 @@
     </implementation>
   </binding>
 
   <binding id="addon-progress-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
     <content align="start">
       <xul:image class="popup-notification-icon"
                  xbl:inherits="popupid,src=icon"/>
       <xul:vbox flex="1">
-        <xul:label class="popup-notification-originHost header"
-                   xbl:inherits="value=originhost"
-                   crop="end"/>
-        <xul:description class="popup-notification-description"
-                         xbl:inherits="xbl:text=label,popupid"/>
-        <xul:progressmeter anonid="progressmeter" flex="1" mode="undetermined" class="popup-progress-meter"/>
-        <xul:label anonid="progresstext" class="popup-progress-label" flex="1" crop="end"/>
+        <xul:description class="popup-notification-description addon-progress-description"
+                         xbl:inherits="xbl:text=label"/>
         <xul:spacer flex="1"/>
+        <xul:hbox align="center">
+          <xul:progressmeter anonid="progressmeter" flex="1" mode="undetermined" class="popup-progress-meter"/>
+          <xul:button anonid="cancel" class="popup-progress-cancel" oncommand="document.getBindingParent(this).cancel()"/>
+        </xul:hbox>
+        <xul:label anonid="progresstext" class="popup-progress-label"/>
         <xul:hbox class="popup-notification-button-container"
                   pack="end" align="center">
-          <children includes="button"/>
           <xul:button anonid="button"
                       class="popup-notification-menubutton"
                       type="menu-button"
                       xbl:inherits="oncommand=buttoncommand,label=buttonlabel,accesskey=buttonaccesskey">
             <xul:menupopup anonid="menupopup"
                            xbl:inherits="oncommand=menucommand">
               <children/>
               <xul:menuitem class="menuitem-iconic popup-notification-closeitem close-icon"
@@ -1602,18 +1601,17 @@
         <xul:toolbarbutton anonid="closebutton"
                            class="messageCloseButton close-icon popup-notification-closebutton tabbable"
                            xbl:inherits="oncommand=closebuttoncommand"
                            tooltiptext="&closeNotification.tooltip;"/>
       </xul:vbox>
     </content>
     <implementation>
       <constructor><![CDATA[
-        if (!this.notification)
-          return;
+        this.cancelbtn.setAttribute("tooltiptext", gNavigatorBundle.getString("addonDownloadCancelTooltip"));
 
         this.notification.options.installs.forEach(function(aInstall) {
           aInstall.addListener(this);
         }, this);
 
         // Calling updateProgress can sometimes cause this notification to be
         // removed in the middle of refreshing the notification panel which
         // makes the panel get refreshed again. Just initialise to the
@@ -1628,27 +1626,27 @@
       ]]></destructor>
 
       <field name="progressmeter" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "progressmeter");
       </field>
       <field name="progresstext" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "progresstext");
       </field>
+      <field name="cancelbtn" readonly="true">
+        document.getAnonymousElementByAttribute(this, "anonid", "cancel");
+      </field>
       <field name="DownloadUtils" readonly="true">
         let utils = {};
         Components.utils.import("resource://gre/modules/DownloadUtils.jsm", utils);
         utils.DownloadUtils;
       </field>
 
       <method name="destroy">
         <body><![CDATA[
-          if (!this.notification)
-            return;
-
           this.notification.options.installs.forEach(function(aInstall) {
             aInstall.removeListener(this);
           }, this);
           clearTimeout(this._updateProgressTimeout);
         ]]></body>
       </method>
 
       <method name="setProgress">
@@ -1683,64 +1681,83 @@
             speed = speed * 0.9 + this.notification.speed * 0.1;
 
           this.notification.lastUpdate = now;
           this.notification.lastProgress = aProgress;
           this.notification.speed = speed;
 
           let status = null;
           [status, this.notification.last] = this.DownloadUtils.getDownloadStatus(aProgress, aMaxProgress, speed, this.notification.last);
-          this.progresstext.value = this.progresstext.tooltipText = status;
+          this.progresstext.value = status;
         ]]></body>
       </method>
 
       <method name="cancel">
         <body><![CDATA[
+          // Cache these as cancelling the installs will remove this
+          // notification which will drop these references
+          let browser = this.notification.browser;
+          let sourceURI = this.notification.options.sourceURI;
+
           let installs = this.notification.options.installs;
           installs.forEach(function(aInstall) {
             try {
               aInstall.cancel();
             }
             catch (e) {
               // Cancel will throw if the download has already failed
             }
           }, this);
 
-          PopupNotifications.remove(this.notification);
+          let anchorID = "addons-notification-icon";
+          let notificationID = "addon-install-cancelled";
+          let messageString = gNavigatorBundle.getString("addonDownloadCancelled");
+          messageString = PluralForm.get(installs.length, messageString);
+          let buttonText = gNavigatorBundle.getString("addonDownloadRestart");
+          buttonText = PluralForm.get(installs.length, buttonText);
+
+          let action = {
+            label: buttonText,
+            accessKey: gNavigatorBundle.getString("addonDownloadRestart.accessKey"),
+            callback: function() {
+              let weblistener = Cc["@mozilla.org/addons/web-install-listener;1"].
+                                getService(Ci.amIWebInstallListener);
+              if (weblistener.onWebInstallRequested(browser, sourceURI,
+                                                    installs, installs.length)) {
+                installs.forEach(function(aInstall) {
+                  aInstall.install();
+                });
+              }
+            }
+          };
+
+          PopupNotifications.show(browser, notificationID, messageString,
+                                  anchorID, action);
         ]]></body>
       </method>
 
       <method name="updateProgress">
         <body><![CDATA[
-          if (!this.notification)
-            return;
-
           let downloadingCount = 0;
           let progress = 0;
           let maxProgress = 0;
 
           this.notification.options.installs.forEach(function(aInstall) {
             if (aInstall.maxProgress == -1)
               maxProgress = -1;
             progress += aInstall.progress;
             if (maxProgress >= 0)
               maxProgress += aInstall.maxProgress;
             if (aInstall.state < AddonManager.STATE_DOWNLOADED)
               downloadingCount++;
           });
 
           if (downloadingCount == 0) {
             this.destroy();
-            if (Preferences.get("xpinstall.customConfirmationUI", false)) {
-              this.progressmeter.mode = "undetermined";
-              this.progresstext.value = this.progresstext.tooltipText =
-                gNavigatorBundle.getString("addonDownloadVerifying");
-            } else {
-              PopupNotifications.remove(this.notification);
-            }
+            PopupNotifications.remove(this.notification);
           }
           else {
             this.setProgress(progress, maxProgress);
           }
         ]]></body>
       </method>
 
       <method name="onDownloadProgress">
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -14,48 +14,36 @@ droponhomemsg=Do you want this document 
 # %2$S is the selection string.
 contextMenuSearch=Search %1$S for "%2$S"
 contextMenuSearch.accesskey=S
 
 # bookmark dialog strings
 
 bookmarkAllTabsDefault=[Folder Name]
 
-xpinstallPromptMessage=%S prevented this site from asking you to install software on your computer.
+xpinstallPromptWarning=%S prevented this site (%S) from asking you to install software on your computer.
 xpinstallPromptAllowButton=Allow
 # Accessibility Note:
 # Be sure you do not choose an accesskey that is used elsewhere in the active context (e.g. main menu bar, submenu of the warning popup button)
 # See http://www.mozilla.org/access/keyboard/accesskey for details
 xpinstallPromptAllowButton.accesskey=A
 xpinstallDisabledMessageLocked=Software installation has been disabled by your system administrator.
 xpinstallDisabledMessage=Software installation is currently disabled. Click Enable and try again.
 xpinstallDisabledButton=Enable
 xpinstallDisabledButton.accesskey=n
 
-# LOCALIZATION NOTE (addonDownloading):
+# LOCALIZATION NOTE (addonDownloading, addonDownloadCancelled, addonDownloadRestart):
 # Semicolon-separated list of plural forms. See:
 # http://developer.mozilla.org/en/docs/Localization_and_Plurals
 # Also see https://bugzilla.mozilla.org/show_bug.cgi?id=570012 for mockups
-addonDownloadingAndVerifying=Downloading and verifying add-on…;Downloading and verifying add-ons…
-addonDownloadVerifying=Verifying
-
-addonInstall.cancelButton.label=Cancel
-addonInstall.cancelButton.accesskey=C
-addonInstall.acceptButton.label=Install
-addonInstall.acceptButton.accesskey=I
-
-# LOCALIZATION NOTE (addonConfirmInstallMessage):
-# Semicolon-separated list of plural forms. See:
-# http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# #1 is brandShortName
-# #2 is the number of add-ons being installed
-addonConfirmInstall.message=This site would like to install an add-on in #1:;This site would like to install #2 add-ons in #1:
-# LOCALIZATION NOTE (addonConfirmInstall.author):
-# %S is the add-on author's name
-addonConfirmInstall.author=by %S
+addonDownloading=Add-on downloading;Add-ons downloading
+addonDownloadCancelled=Add-on download cancelled.;Add-on downloads cancelled.
+addonDownloadRestart=Restart Download;Restart Downloads
+addonDownloadRestart.accessKey=R
+addonDownloadCancelTooltip=Cancel
 
 addonwatch.slow=%1$S might be making %2$S run slowly
 addonwatch.disable.label=Disable %S
 addonwatch.disable.accesskey=D
 addonwatch.ignoreSession.label=Ignore for now
 addonwatch.ignoreSession.accesskey=I
 addonwatch.ignorePerm.label=Ignore permanently
 addonwatch.ignorePerm.accesskey=p
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1127,59 +1127,73 @@ toolbarbutton[sdk-button="true"][cui-are
 }
 
 #identity-popup-button-container {
   background: linear-gradient(to bottom, rgba(0,0,0,0.04) 60%, transparent);
   padding: 10px;
   margin-top: 5px;
 }
 
+/* Notification popup */
+#notification-popup {
+  min-width: 280px;
+}
+
 .popup-notification-icon {
   width: 64px;
   height: 64px;
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
   list-style-image: url(chrome://browser/skin/Geolocation-64.png);
 }
 
 .popup-notification-icon[popupid="xpinstall-disabled"],
 .popup-notification-icon[popupid="addon-progress"],
+.popup-notification-icon[popupid="addon-install-cancelled"],
 .popup-notification-icon[popupid="addon-install-blocked"],
 .popup-notification-icon[popupid="addon-install-failed"],
-.popup-notification-icon[popupid="addon-install-confirmation"],
 .popup-notification-icon[popupid="addon-install-complete"] {
   list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
   width: 32px;
   height: 32px;
 }
 
-.popup-notification-description[popupid="addon-progress"],
-.popup-notification-description[popupid="addon-install-confirmation"] {
-  width: 27em;
-  max-width: 27em;
-}
-
-.popup-progress-meter {
-  margin-top: .5em;
-}
-
-.addon-install-confirmation-name {
-  font-weight: bold;
-}
-
 .popup-notification-icon[popupid="click-to-play-plugins"] {
   list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
 }
 
 .popup-notification-icon[popupid="web-notifications"] {
   list-style-image: url(chrome://browser/skin/notification-64.png);
 }
 
+.addon-progress-description {
+  width: 350px;
+  max-width: 350px;
+}
+
+.popup-progress-label,
+.popup-progress-meter {
+  -moz-margin-start: 0;
+  -moz-margin-end: 0;
+}
+
+.popup-progress-cancel {
+  -moz-appearance: none;
+  background: transparent;
+  border: none;
+  padding: 0;
+  margin: 0;
+  -moz-margin-start: 5px;
+  min-height: 0;
+  min-width: 0;
+  list-style-image: url("moz-icon://stock/gtk-cancel?size=menu");
+}
+
 .popup-notification-icon[popupid="indexedDB-permissions-prompt"],
 .popup-notification-icon[popupid*="offline-app-requested"],
 .popup-notification-icon[popupid="offline-app-usage"] {
   list-style-image: url(chrome://global/skin/icons/question-64.png);
 }
 
 .popup-notification-icon[popupid="password"] {
   list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -4145,49 +4145,58 @@ notification[value="loop-sharing-notific
 @media (min-resolution: 2dppx) {
   .popup-notification-icon[popupid="web-notifications"] {
     list-style-image: url(chrome://browser/skin/notification-64@2x.png);
   }
 }
 
 .popup-notification-icon[popupid="xpinstall-disabled"],
 .popup-notification-icon[popupid="addon-progress"],
+.popup-notification-icon[popupid="addon-install-cancelled"],
 .popup-notification-icon[popupid="addon-install-blocked"],
 .popup-notification-icon[popupid="addon-install-failed"],
-.popup-notification-icon[popupid="addon-install-confirmation"],
 .popup-notification-icon[popupid="addon-install-complete"] {
   list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
   width: 32px;
   height: 32px;
 }
 
-.popup-notification-description[popupid="addon-progress"],
-.popup-notification-description[popupid="addon-install-confirmation"] {
-  width: 27em;
-  max-width: 27em;
+.popup-notification-icon[popupid="click-to-play-plugins"] {
+  list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
+}
+
+.addon-progress-description {
+  width: 350px;
+  max-width: 350px;
 }
 
 .popup-progress-label,
 .popup-progress-meter {
   -moz-margin-start: 0;
   -moz-margin-end: 0;
 }
 
-.popup-progress-meter,
-#addon-install-confirmation-content {
-  margin-top: 1em;
-}
-
-.addon-install-confirmation-name {
-  font-weight: bold;
-  -moz-margin-start: 0 !important; /* override default label margin to match description margin */
-}
-
-.popup-notification-icon[popupid="click-to-play-plugins"] {
-  list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
+.popup-progress-cancel {
+  -moz-appearance: none;
+  min-height: 16px;
+  min-width: 16px;
+  max-height: 16px;
+  max-width: 16px;
+  padding: 0;
+  margin: 0 1px 0 1px;
+  list-style-image: url(chrome://mozapps/skin/downloads/buttons.png);
+  -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+.popup-progress-cancel:hover {
+  -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+.popup-progress-cancel:active {
+  -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
 
 .popup-notification-icon[popupid="indexedDB-permissions-prompt"],
 .popup-notification-icon[popupid*="offline-app-requested"],
 .popup-notification-icon[popupid="offline-app-usage"] {
   list-style-image: url(chrome://global/skin/icons/question-64.png);
 }
 
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2153,48 +2153,64 @@ toolbarbutton.bookmark-item[dragover="tr
 }
 
 .popup-notification-icon[popupid="geolocation"] {
   list-style-image: url(chrome://browser/skin/Geolocation-64.png);
 }
 
 .popup-notification-icon[popupid="xpinstall-disabled"],
 .popup-notification-icon[popupid="addon-progress"],
+.popup-notification-icon[popupid="addon-install-cancelled"],
 .popup-notification-icon[popupid="addon-install-blocked"],
 .popup-notification-icon[popupid="addon-install-failed"],
-.popup-notification-icon[popupid="addon-install-confirmation"],
 .popup-notification-icon[popupid="addon-install-complete"] {
   list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
   width: 32px;
   height: 32px;
 }
 
-.popup-notification-description[popupid="addon-progress"],
-.popup-notification-description[popupid="addon-install-confirmation"] {
-  width: 27em;
-  max-width: 27em;
-}
-
-.popup-progress-meter,
-#addon-install-confirmation-content {
-  margin-top: 1em;
-}
-
-.addon-install-confirmation-name {
-  font-weight: bold;
-}
-
 .popup-notification-icon[popupid="click-to-play-plugins"] {
   list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png);
 }
 
 .popup-notification-icon[popupid="web-notifications"] {
   list-style-image: url(chrome://browser/skin/notification-64.png);
 }
 
+.addon-progress-description {
+  width: 350px;
+  max-width: 350px;
+}
+
+.popup-progress-label,
+.popup-progress-meter {
+  -moz-margin-start: 0;
+  -moz-margin-end: 0;
+}
+
+.popup-progress-cancel {
+  -moz-appearance: none;
+  background: transparent;
+  border: none;
+  padding: 0;
+  margin: 0;
+  min-height: 0;
+  min-width: 0;
+  list-style-image: url(chrome://mozapps/skin/downloads/downloadButtons.png);
+  -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+.popup-progress-cancel:hover {
+  -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+.popup-progress-cancel:active {
+  -moz-image-region: rect(32px, 32px, 48px, 16px);
+}
+
 .popup-notification-icon[popupid="indexedDB-permissions-prompt"],
 .popup-notification-icon[popupid*="offline-app-requested"],
 .popup-notification-icon[popupid="offline-app-usage"] {
   list-style-image: url(chrome://global/skin/icons/question-64.png);
 }
 
 .popup-notification-icon[popupid="password"] {
   list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
--- a/toolkit/content/widgets/notification.xml
+++ b/toolkit/content/widgets/notification.xml
@@ -465,34 +465,28 @@
             }
           ]]>
         </body>
       </method>
     </implementation>
   </binding>
 
   <binding id="popup-notification">
-    <content>
-      <xul:vbox>
-        <xul:image class="popup-notification-icon"
-                   xbl:inherits="popupid,src=icon"/>
-      </xul:vbox>
+    <content align="start">
+      <xul:image class="popup-notification-icon"
+                 xbl:inherits="popupid,src=icon"/>
       <xul:vbox flex="1">
-        <xul:label class="popup-notification-originHost header"
-                   xbl:inherits="value=originhost"
-                   crop="end"/>
         <xul:description class="popup-notification-description"
-                         xbl:inherits="xbl:text=label,popupid"/>
+                         xbl:inherits="xbl:text=label"/>
         <children includes="popupnotificationcontent"/>
         <xul:label class="text-link popup-notification-learnmore-link"
                xbl:inherits="href=learnmoreurl">&learnMore;</xul:label>
         <xul:spacer flex="1"/>
         <xul:hbox class="popup-notification-button-container"
                   pack="end" align="center">
-          <children includes="button"/>
           <xul:button anonid="button"
                       class="popup-notification-menubutton"
                       type="menu-button"
                       xbl:inherits="oncommand=buttoncommand,label=buttonlabel,accesskey=buttonaccesskey">
             <xul:menupopup anonid="menupopup"
                            xbl:inherits="oncommand=menucommand">
               <children/>
               <xul:menuitem class="menuitem-iconic popup-notification-closeitem"
--- a/toolkit/modules/PopupNotifications.jsm
+++ b/toolkit/modules/PopupNotifications.jsm
@@ -265,18 +265,16 @@ PopupNotifications.prototype = {
    *        popupIconURL:
    *                     A string. URL of the image to be displayed in the popup.
    *                     Normally specified in CSS using list-style-image and the
    *                     .popup-notification-icon[popupid=...] selector.
    *        learnMoreURL:
    *                     A string URL. Setting this property will make the
    *                     prompt display a "Learn More" link that, when clicked,
    *                     opens the URL in a new tab.
-   *        originHost:  The host name of the page the notification came from.
-   *                     If present, this will be displayed above the message.
    * @returns the Notification object corresponding to the added notification.
    */
   show: function PopupNotifications_show(browser, id, message, anchorID,
                                          mainAction, secondaryActions, options) {
     function isInvalidAction(a) {
       return !a || !(typeof(a.callback) == "function") || !a.label || !a.accessKey;
     }
 
@@ -496,22 +494,22 @@ PopupNotifications.prototype = {
 
       // If this notification was provided by the chrome document rather than
       // created ad hoc, move it back to where we got it from.
       let originalParent = gNotificationParents.get(popupnotification);
       if (originalParent) {
         popupnotification.notification = null;
 
         // Remove nodes dynamically added to the notification's menu button
-        // in _refreshPanel.
+        // in _refreshPanel. Keep popupnotificationcontent nodes; they are
+        // provided by the chrome document.
         let contentNode = popupnotification.lastChild;
         while (contentNode) {
           let previousSibling = contentNode.previousSibling;
-          if (contentNode.nodeName == "menuitem" ||
-              contentNode.nodeName == "menuseparator")
+          if (contentNode.nodeName != "popupnotificationcontent")
             popupnotification.removeChild(contentNode);
           contentNode = previousSibling;
         }
 
         // Re-hide the notification such that it isn't rendered in the chrome
         // document. _refreshPanel will unhide it again when needed.
         popupnotification.hidden = true;
 
@@ -556,27 +554,21 @@ PopupNotifications.prototype = {
         popupnotification.removeAttribute("buttonaccesskey");
         popupnotification.removeAttribute("buttoncommand");
         popupnotification.removeAttribute("menucommand");
         popupnotification.removeAttribute("closeitemcommand");
       }
 
       if (n.options.popupIconURL)
         popupnotification.setAttribute("icon", n.options.popupIconURL);
-
       if (n.options.learnMoreURL)
         popupnotification.setAttribute("learnmoreurl", n.options.learnMoreURL);
       else
         popupnotification.removeAttribute("learnmoreurl");
 
-      if (n.options.originHost)
-        popupnotification.setAttribute("originhost", n.options.originHost);
-      else
-        popupnotification.removeAttribute("originhost");
-
       popupnotification.notification = n;
 
       if (n.secondaryActions) {
         n.secondaryActions.forEach(function (a) {
           let item = doc.createElementNS(XUL_NS, "menuitem");
           item.setAttribute("label", a.label);
           item.setAttribute("accesskey", a.accessKey);
           item.notification = n;
--- a/toolkit/mozapps/extensions/amWebInstallListener.js
+++ b/toolkit/mozapps/extensions/amWebInstallListener.js
@@ -14,17 +14,16 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/AddonManager.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Preferences.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PromptUtils", "resource://gre/modules/SharedPromptUtils.jsm");
 
 const URI_XPINSTALL_DIALOG = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
 
 // Installation can begin from any of these states
 const READY_STATES = [
   AddonManager.STATE_AVAILABLE,
@@ -150,21 +149,16 @@ Installer.prototype = {
       }, this);
       notifyObservers("addon-install-failed", this.browser, this.url, failed);
     }
 
     // If none of the downloads were successful then exit early
     if (this.downloads.length == 0)
       return;
 
-    if (Preferences.get("xpinstall.customConfirmationUI", false)) {
-      notifyObservers("addon-install-confirmation", this.browser, this.url, this.downloads);
-      return;
-    }
-
     // Check for a custom installation prompt that may be provided by the
     // applicaton
     if ("@mozilla.org/addons/web-install-prompt;1" in Cc) {
       try {
         let prompt = Cc["@mozilla.org/addons/web-install-prompt;1"].
                      getService(Ci.amIWebInstallPrompt);
         prompt.confirm(this.browser, this.url, this.downloads, this.downloads.length);
         return;
--- a/toolkit/mozapps/extensions/test/browser/head.js
+++ b/toolkit/mozapps/extensions/test/browser/head.js
@@ -27,17 +27,16 @@ const RELATIVE_DIR = pathParts.slice(4).
 const TESTROOT = "http://example.com/" + RELATIVE_DIR;
 const TESTROOT2 = "http://example.org/" + RELATIVE_DIR;
 const CHROMEROOT = pathParts.join("/") + "/";
 const PREF_DISCOVERURL = "extensions.webservice.discoverURL";
 const PREF_DISCOVER_ENABLED = "extensions.getAddons.showPane";
 const PREF_XPI_ENABLED = "xpinstall.enabled";
 const PREF_UPDATEURL = "extensions.update.url";
 const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
-const PREF_CUSTOM_XPINSTALL_CONFIRMATION_UI = "xpinstall.customConfirmationUI";
 
 const MANAGER_URI = "about:addons";
 const INSTALL_URI = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
 const PREF_LOGGING_ENABLED = "extensions.logging.enabled";
 const PREF_SEARCH_MAXRESULTS = "extensions.getAddons.maxResults";
 const PREF_STRICT_COMPAT = "extensions.strictCompatibility";
 
 var PREF_CHECK_COMPATIBILITY;
@@ -58,17 +57,16 @@ var PREF_CHECK_COMPATIBILITY;
 
 var gPendingTests = [];
 var gTestsRun = 0;
 var gTestStart = null;
 
 var gUseInContentUI = !gTestInWindow && ("switchToTabHavingURI" in window);
 
 var gRestorePrefs = [{name: PREF_LOGGING_ENABLED},
-                     {name: PREF_CUSTOM_XPINSTALL_CONFIRMATION_UI},
                      {name: "extensions.webservice.discoverURL"},
                      {name: "extensions.update.url"},
                      {name: "extensions.update.background.url"},
                      {name: "extensions.update.enabled"},
                      {name: "extensions.update.autoUpdateDefault"},
                      {name: "extensions.getAddons.get.url"},
                      {name: "extensions.getAddons.getWithPerformance.url"},
                      {name: "extensions.getAddons.search.browseURL"},
@@ -92,18 +90,16 @@ for (let pref of gRestorePrefs) {
     pref.value = Services.prefs.getIntPref(pref.name);
   else if (pref.type == Services.prefs.PREF_STRING)
     pref.value = Services.prefs.getCharPref(pref.name);
 }
 
 // Turn logging on for all tests
 Services.prefs.setBoolPref(PREF_LOGGING_ENABLED, true);
 
-Services.prefs.setBoolPref(PREF_CUSTOM_XPINSTALL_CONFIRMATION_UI, false);
-
 // Helper to register test failures and close windows if any are left open
 function checkOpenWindows(aWindowID) {
   let windows = Services.wm.getEnumerator(aWindowID);
   let found = false;
   while (windows.hasMoreElements()) {
     let win = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
     if (!win.closed) {
       found = true;
--- a/toolkit/mozapps/extensions/test/xpinstall/head.js
+++ b/toolkit/mozapps/extensions/test/xpinstall/head.js
@@ -3,17 +3,16 @@ const RELATIVE_DIR = "toolkit/mozapps/ex
 const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
 const TESTROOT2 = "http://example.org/browser/" + RELATIVE_DIR;
 const XPINSTALL_URL = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
 const PROMPT_URL = "chrome://global/content/commonDialog.xul";
 const ADDONS_URL = "chrome://mozapps/content/extensions/extensions.xul";
 const PREF_LOGGING_ENABLED = "extensions.logging.enabled";
 const PREF_INSTALL_REQUIREBUILTINCERTS = "extensions.install.requireBuiltInCerts";
 const PREF_INSTALL_REQUIRESECUREORIGIN = "extensions.install.requireSecureOrigin";
-const PREF_CUSTOM_CONFIRMATION_UI = "xpinstall.customConfirmationUI";
 const CHROME_NAME = "mochikit";
 
 function getChromeRoot(path) {
   if (path === undefined) {
     return "chrome://" + CHROME_NAME + "/content/browser/" + RELATIVE_DIR
   }
   return getRootDirectory(path);
 }
@@ -23,21 +22,16 @@ function extractChromeRoot(path) {
   var jar = getJar(chromeRootPath);
   if (jar) {
     var tmpdir = extractJarToTmp(jar);
     return "file://" + tmpdir.path + "/";
   }
   return chromeRootPath;
 }
 
-Services.prefs.setBoolPref(PREF_CUSTOM_CONFIRMATION_UI, false);
-registerCleanupFunction(() => {
-  Services.prefs.clearUserPref(PREF_CUSTOM_CONFIRMATION_UI);
-});
-
 /**
  * This is a test harness designed to handle responding to UI during the process
  * of installing an XPI. A test can set callbacks to hear about specific parts
  * of the sequence.
  * Before use setup must be called and finish must be called afterwards.
  */
 var Harness = {
   // If set then the callback is called when an install is attempted and
--- a/toolkit/themes/linux/global/global.css
+++ b/toolkit/themes/linux/global/global.css
@@ -276,20 +276,16 @@ label[disabled="true"] {
   border: 1px dotted -moz-DialogText;
 }
 
 notification > button {
   margin-top: 0;
   margin-bottom: 0;
 }
 
-popupnotificationcontent {
-  margin-top: .5em;
-}
-
 /* :::::: autoscroll popup ::::: */
 
 .autoscroller {
   height: 28px;
   width: 28px;
   border: none;
   margin: -14px;
   padding: 0;
--- a/toolkit/themes/linux/global/notification.css
+++ b/toolkit/themes/linux/global/notification.css
@@ -62,24 +62,19 @@ notification[type="critical"] {
 }
 
 /* Popup notification */
 
 .popup-notification-description {
   max-width: 24em;
 }
 
-.popup-notification-originHost:not([value]),
-.popup-notification-learnmore-link:not([href]) {
-  display: none;
+.popup-notification-learnmore-link {
+  margin-top: 1em !important;
 }
 
-.popup-notification-originHost {
-  margin-bottom: .3em !important;
-}
-
-.popup-notification-learnmore-link {
-  margin-top: .5em !important;
+.popup-notification-learnmore-link:not([href]) {
+  display: none;
 }
 
 .popup-notification-button-container {
   margin-top: 17px;
 }
--- a/toolkit/themes/osx/global/global.css
+++ b/toolkit/themes/osx/global/global.css
@@ -261,20 +261,16 @@ notification > button:-moz-focusring {
 notification > button:active:hover:-moz-focusring {
   box-shadow: @focusRingShadow@, @roundButtonPressedShadow@;
 }
 
 notification > button > .button-box > .button-text {
   margin: 0 !important;
 }
 
-popupnotificationcontent {
-  margin-top: .5em;
-}
-
 /* :::::: autoscroll popup ::::: */
 
 .autoscroller {
   height: 28px;
   width: 28px;
   border: none;
   margin: -14px;
   padding: 0;
--- a/toolkit/themes/osx/global/notification.css
+++ b/toolkit/themes/osx/global/notification.css
@@ -100,29 +100,23 @@ notification[type="info"]:not([value="tr
 }
 
 /* Popup notification */
 
 .popup-notification-description {
   max-width: 24em;
 }
 
-.popup-notification-originHost:not([value]),
-.popup-notification-learnmore-link:not([href]) {
-  display: none;
-}
-
-.popup-notification-originHost {
-  margin-bottom: .3em !important;
+.popup-notification-learnmore-link {
+  margin-top: 1em !important;
   -moz-margin-start: 0 !important; /* override default label margin to match description margin */
 }
 
-.popup-notification-learnmore-link {
-  margin-top: .5em !important;
-  -moz-margin-start: 0 !important; /* override default label margin to match description margin */
+.popup-notification-learnmore-link:not([href]) {
+  display: none;
 }
 
 .popup-notification-button-container {
   margin-top: 17px;
 }
 
 .popup-notification-menubutton {
   -moz-appearance: none;
--- a/toolkit/themes/windows/global/global.css
+++ b/toolkit/themes/windows/global/global.css
@@ -281,20 +281,16 @@ label[disabled="true"]:-moz-system-metri
 .text-link:hover {
   text-decoration: underline;
 }
 
 .text-link:-moz-focusring {
   border: 1px dotted -moz-DialogText;
 }
 
-popupnotificationcontent {
-  margin-top: .5em;
-}
-
 /* :::::: autoscroll popup ::::: */
 
 .autoscroller {
   height: 28px;
   width: 28px;
   border: none;
   margin: -14px;
   padding: 0;
--- a/toolkit/themes/windows/global/notification.css
+++ b/toolkit/themes/windows/global/notification.css
@@ -57,27 +57,22 @@ notification[type="critical"] {
 }
 
 /* Popup notification */
 
 .popup-notification-description {
   max-width: 24em;
 }
 
-.popup-notification-originHost:not([value]),
-.popup-notification-learnmore-link:not([href]) {
-  display: none;
+.popup-notification-learnmore-link {
+  margin-top: 1em !important;
 }
 
-.popup-notification-originHost {
-  margin-bottom: .3em !important;
-}
-
-.popup-notification-learnmore-link {
-  margin-top: .5em !important;
+.popup-notification-learnmore-link:not([href]) {
+  display: none;
 }
 
 .popup-notification-button-container {
   margin-top: 17px;
 }
 
 %ifdef XP_WIN
 /*