Merge fx-team to central, a=merge
authorWes Kocher <wkocher@mozilla.com>
Wed, 20 Apr 2016 14:17:46 -0700
changeset 317843 4feb4dd910a5a2d3061dbdd376a80975206819c6
parent 317829 93090fa3065335c9f830e9c70cbfbbc2f40fd979 (current diff)
parent 317842 6a3291366533e40960df1f859d52734f13f3d7a3 (diff)
child 317844 4e3ad95d689a5beabf3c1f41d958794fe00e3767
child 317859 6d48e6b9edc64b919c1055073406bf991a3f16cd
child 317945 898c9f87a4c48c0cbc5d9afe6ced9eb3c71f9388
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone48.0a1
Merge fx-team to central, a=merge MozReview-Commit-ID: FKKE7Ry6SbZ
toolkit/themes/osx/global/passwordmgr.css
toolkit/themes/windows/global/passwordmgr.css
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -341,58 +341,20 @@ pref("image.mem.surfacecache.max_size_kb
 pref("image.mem.surfacecache.size_factor", 8);  // 1/8 of main memory
 pref("image.mem.surfacecache.discard_factor", 2);  // Discard 1/2 of the surface cache at a time.
 pref("image.mem.surfacecache.min_expiration_ms", 86400000); // 24h, we rely on the out of memory hook
 
 pref("dom.w3c_touch_events.safetyX", 0); // escape borders in units of 1/240"
 pref("dom.w3c_touch_events.safetyY", 120); // escape borders in units of 1/240"
 
 #ifdef MOZ_SAFE_BROWSING
-pref("browser.safebrowsing.enabled", true);
-// Prevent loading of pages identified as malware
-pref("browser.safebrowsing.malware.enabled", true);
 pref("browser.safebrowsing.downloads.enabled", true);
 pref("browser.safebrowsing.downloads.remote.enabled", true);
-pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
-pref("browser.safebrowsing.downloads.remote.url", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
-pref("browser.safebrowsing.downloads.remote.block_dangerous",            true);
-pref("browser.safebrowsing.downloads.remote.block_dangerous_host",       true);
-pref("browser.safebrowsing.downloads.remote.block_potentially_unwanted", false);
-pref("browser.safebrowsing.downloads.remote.block_uncommon",             false);
-pref("browser.safebrowsing.debug", false);
-
-pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-downloadwhite-digest256,goog-phish-shavar,goog-malware-shavar,goog-unwanted-shavar");
-pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
-pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
-pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
-
-pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
-pref("browser.safebrowsing.reportPhishURL", "https://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%&url=");
-pref("browser.safebrowsing.reportMalwareMistakeURL", "https://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%&url=");
 
 pref("browser.safebrowsing.id", "Firefox");
-
-// Tables for application reputation.
-pref("urlclassifier.downloadBlockTable", "goog-badbinurl-shavar");
-
-// The number of random entries to send with a gethash request.
-pref("urlclassifier.gethashnoise", 4);
-
-// Gethash timeout for Safebrowsing.
-pref("urlclassifier.gethash.timeout_ms", 5000);
-
-// If an urlclassifier table has not been updated in this number of seconds,
-// a gethash request will be forced to check that the result is still in
-// the database.
-pref("urlclassifier.max-complete-age", 2700);
-
-// Tracking protection
-pref("privacy.trackingprotection.enabled", false);
-pref("privacy.trackingprotection.pbmode.enabled", true);
-
 #endif
 
 // True if this is the first time we are showing about:firstrun
 pref("browser.firstrun.show.uidiscovery", true);
 pref("browser.firstrun.show.localepicker", true);
 
 // initiated by a user
 pref("content.ime.strict_policy", true);
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -775,59 +775,29 @@ pref("gecko.handlerService.schemes.ircs.
 pref("gecko.handlerService.schemes.ircs.2.uriTemplate", "chrome://browser-region/locale/region.properties");
 pref("gecko.handlerService.schemes.ircs.3.name", "chrome://browser-region/locale/region.properties");
 pref("gecko.handlerService.schemes.ircs.3.uriTemplate", "chrome://browser-region/locale/region.properties");
 
 // By default, we don't want protocol/content handlers to be registered from a different host, see bug 402287
 pref("gecko.handlerService.allowRegisterFromDifferentHost", false);
 
 #ifdef MOZ_SAFE_BROWSING
-pref("browser.safebrowsing.enabled", true);
-pref("browser.safebrowsing.malware.enabled", true);
 pref("browser.safebrowsing.downloads.enabled", true);
 pref("browser.safebrowsing.downloads.remote.enabled", true);
-pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
-pref("browser.safebrowsing.downloads.remote.url", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
-pref("browser.safebrowsing.downloads.remote.block_dangerous",            true);
-pref("browser.safebrowsing.downloads.remote.block_dangerous_host",       true);
-pref("browser.safebrowsing.downloads.remote.block_potentially_unwanted", false);
-pref("browser.safebrowsing.downloads.remote.block_uncommon",             false);
-pref("browser.safebrowsing.debug", false);
-
-pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-downloadwhite-digest256,goog-phish-shavar,goog-malware-shavar,goog-unwanted-shavar");
-pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
-pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
-pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
-
-pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
-pref("browser.safebrowsing.reportPhishURL", "https://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%&url=");
-pref("browser.safebrowsing.reportMalwareMistakeURL", "https://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%&url=");
 
 #ifdef MOZILLA_OFFICIAL
 // Normally the "client ID" sent in updates is appinfo.name, but for
 // official Firefox releases from Mozilla we use a special identifier.
 pref("browser.safebrowsing.id", "navclient-auto-ffox");
 #endif
 
 // Name of the about: page contributed by safebrowsing to handle display of error
 // pages on phishing/malware hits.  (bug 399233)
 pref("urlclassifier.alternate_error_page", "blocked");
 
-// The number of random entries to send with a gethash request.
-pref("urlclassifier.gethashnoise", 4);
-
-// Gethash timeout for Safebrowsing.
-pref("urlclassifier.gethash.timeout_ms", 5000);
-
-// If an urlclassifier table has not been updated in this number of seconds,
-// a gethash request will be forced to check that the result is still in
-// the database.
-pref("urlclassifier.max-complete-age", 2700);
-// Tables for application reputation.
-pref("urlclassifier.downloadBlockTable", "goog-badbinurl-shavar");
 #ifdef XP_WIN
 // Only download the whitelist on Windows, since the whitelist is
 // only useful for suppressing remote lookups for signed binaries which we can
 // only verify on Windows (Bug 974579). Other platforms always do remote lookups.
 pref("urlclassifier.downloadAllowTable", "goog-downloadwhite-digest256");
 #endif
 #endif
 
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -463,23 +463,30 @@
         <menupopup id="bookmarksToolbarFolderPopup"
 #ifndef XP_MACOSX
                    placespopup="true"
 #endif
                    context="placesContext"
                    onpopupshowing="if (!this.parentNode._placesView)
                                      new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
       </menu>
+      <menu id="menu_unsortedBookmarks"
+            class="menu-iconic bookmark-item"
+            label="&otherBookmarksCmd.label;"
+            container="true">
+        <menupopup id="otherBookmarksFolderPopup"
+#ifndef XP_MACOSX
+                   placespopup="true"
+#endif
+                   context="placesContext"
+                   onpopupshowing="if (!this.parentNode._placesView)
+                                     new PlacesMenu(event, 'place:folder=UNFILED_BOOKMARKS');"/>
+      </menu>
       <menuseparator id="bookmarksMenuItemsSeparator"/>
       <!-- Bookmarks menu items -->
-      <menuseparator builder="end"
-                     class="hide-if-empty-places-result"/>
-      <menuitem id="menu_unsortedBookmarks"
-                label="&otherBookmarksCmd.label;"
-                oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"/>
     </menupopup>
   </menu>
 
             <menu id="tools-menu"
                   label="&toolsMenu.label;"
                   accesskey="&toolsMenu.accesskey;"
                   onpopupshowing="mirrorShow(this)">
               <menupopup id="menu_ToolsPopup"
--- a/browser/components/downloads/DownloadsCommon.jsm
+++ b/browser/components/downloads/DownloadsCommon.jsm
@@ -523,39 +523,46 @@ this.DownloadsCommon = {
    *
    * @param aVerdict
    *        The detailed reason why the download was blocked, according to the
    *        "Downloads.Error.BLOCK_VERDICT_" constants. If an unknown reason is
    *        specified, "Downloads.Error.BLOCK_VERDICT_MALWARE" is assumed.
    * @param aOwnerWindow
    *        The window with which this action is associated.
    *
-   * @return True to unblock the file, false to keep the user safe and
-   *         cancel the operation.
+   * @return {Promise}
+   * @resolves String representing the action that should be executed:
+   *            - "unblock" to allow the download without opening the file.
+   *            - "confirmBlock" to delete the blocked data permanently.
+   *            - "cancel" to do nothing and cancel the operation.
    */
   confirmUnblockDownload: Task.async(function* (aVerdict, aOwnerWindow) {
     let s = DownloadsCommon.strings;
     let title = s.unblockHeader;
     let buttonFlags = (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) +
-                      (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1) +
-                      Ci.nsIPrompt.BUTTON_POS_1_DEFAULT;
+                      (Ci.nsIPrompt.BUTTON_TITLE_CANCEL * Ci.nsIPrompt.BUTTON_POS_1);
     let type = "";
     let message = s.unblockTip;
-    let okButton = s.unblockButtonContinue;
-    let cancelButton = s.unblockButtonCancel;
+    let unblockButton = s.unblockButtonContinue;
+    let confirmBlockButton = s.unblockButtonCancel;
 
     switch (aVerdict) {
       case Downloads.Error.BLOCK_VERDICT_UNCOMMON:
         type = s.unblockTypeUncommon;
+        buttonFlags += (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_2) +
+                       Ci.nsIPrompt.BUTTON_POS_0_DEFAULT;
         break;
       case Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED:
         type = s.unblockTypePotentiallyUnwanted;
+        buttonFlags += (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_2) +
+                       Ci.nsIPrompt.BUTTON_POS_2_DEFAULT;
         break;
       default: // Assume Downloads.Error.BLOCK_VERDICT_MALWARE
         type = s.unblockTypeMalware;
+        buttonFlags += Ci.nsIPrompt.BUTTON_POS_1_DEFAULT;
         break;
     }
 
     if (type) {
       message = type + "\n\n" + message;
     }
 
     Services.ww.registerNotification(function onOpen(subj, topic) {
@@ -575,18 +582,19 @@ this.DownloadsCommon = {
           }
         });
       }
     });
 
     // The ordering of the ok/cancel buttons is used this way to allow "cancel"
     // to have the same result as hitting the ESC or Close button (see bug 345067).
     let rv = Services.prompt.confirmEx(aOwnerWindow, title, message, buttonFlags,
-                                       okButton, cancelButton, null, null, {});
-    return (rv == 0);
+                                       unblockButton, null, confirmBlockButton,
+                                       null, {});
+    return ["unblock", "cancel", "confirmBlock"][rv];
   }),
 };
 
 XPCOMUtils.defineLazyGetter(this.DownloadsCommon, "log", () => {
   return DownloadsLogger.log.bind(DownloadsLogger);
 });
 XPCOMUtils.defineLazyGetter(this.DownloadsCommon, "error", () => {
   return DownloadsLogger.error.bind(DownloadsLogger);
--- a/browser/components/downloads/DownloadsViewUI.jsm
+++ b/browser/components/downloads/DownloadsViewUI.jsm
@@ -12,16 +12,18 @@
 this.EXPORTED_SYMBOLS = [
   "DownloadsViewUI",
 ];
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
+                                  "resource://gre/modules/Downloads.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils",
                                   "resource://gre/modules/DownloadUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
                                   "resource:///modules/DownloadsCommon.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm");
 
 this.DownloadsViewUI = {
@@ -107,16 +109,24 @@ this.DownloadsViewUI.DownloadElementShel
    * update in order to improve performance.
    */
   _updateState() {
     this.element.setAttribute("displayName", this.displayName);
     this.element.setAttribute("image", this.image);
     this.element.setAttribute("state",
                               DownloadsCommon.stateOfDownload(this.download));
 
+    if (this.download.error &&
+        this.download.error.becauseBlockedByReputationCheck) {
+      this.element.setAttribute("verdict",
+                                this.download.error.reputationCheckVerdict);
+    } else {
+      this.element.removeAttribute("verdict");
+    }
+
     // Since state changed, reset the time left estimation.
     this.lastEstimatedSecondsLeft = Infinity;
 
     this._updateProgress();
   },
 
   /**
    * Updates the elements that change regularly for in-progress downloads,
@@ -127,16 +137,21 @@ this.DownloadsViewUI.DownloadElementShel
       // We only need to add or remove this attribute for succeeded downloads.
       if (this.download.target.exists) {
         this.element.setAttribute("exists", "true");
       } else {
         this.element.removeAttribute("exists");
       }
     }
 
+    // When a block is confirmed, the removal of blocked data will not trigger a
+    // state change for the download, so this class must be updated here.
+    this.element.classList.toggle("temporary-block",
+                                  !!this.download.hasBlockedData);
+
     // The progress bar is only displayed for in-progress downloads.
     if (this.download.hasProgress) {
       this.element.setAttribute("progressmode", "normal");
       this.element.setAttribute("progress", this.download.progress);
     } else {
       this.element.setAttribute("progressmode", "undetermined");
     }
 
@@ -215,17 +230,27 @@ this.DownloadsViewUI.DownloadElementShel
           // History downloads may not have a size defined.
           stateLabel = s.sizeUnknown;
         }
       } else if (this.download.canceled) {
         stateLabel = s.stateCanceled;
       } else if (this.download.error.becauseBlockedByParentalControls) {
         stateLabel = s.stateBlockedParentalControls;
       } else if (this.download.error.becauseBlockedByReputationCheck) {
-        stateLabel = s.stateDirty;
+        switch (this.download.error.reputationCheckVerdict) {
+          case Downloads.Error.BLOCK_VERDICT_UNCOMMON:
+            stateLabel = s.blockedUncommon;
+            break;
+          case Downloads.Error.BLOCK_VERDICT_POTENTIALLY_UNWANTED:
+            stateLabel = s.blockedPotentiallyUnwanted;
+            break;
+          default: // Assume Downloads.Error.BLOCK_VERDICT_MALWARE
+            stateLabel = s.blockedMalware;
+            break;
+        }
       } else {
         stateLabel = s.stateFailed;
       }
 
       let referrer = this.download.source.referrer || this.download.source.url;
       let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer);
 
       let date = new Date(this.download.endTime);
@@ -235,16 +260,35 @@ this.DownloadsViewUI.DownloadElementShel
       text = s.statusSeparator(firstPart, displayDate);
       tip = s.statusSeparator(fullHost, fullDate);
     }
 
     return { text, tip: tip || text };
   },
 
   /**
+   * Shows the appropriate unblock dialog based on the verdict, and executes the
+   * action selected by the user in the dialog, which may involve unblocking,
+   * opening or removing the file.
+   *
+   * @param window
+   *        The window to which the dialog should be anchored.
+   */
+  confirmUnblock(window) {
+    let verdict = this.download.error.reputationCheckVerdict;
+    DownloadsCommon.confirmUnblockDownload(verdict, window).then(action => {
+      if (action == "unblock") {
+        return this.download.unblock();
+      } else if (action == "confirmBlock") {
+        return this.download.confirmBlock();
+      }
+    }).catch(Cu.reportError);
+  },
+
+  /**
    * Returns the name of the default command to use for the current state of the
    * download, when there is a double click or another default interaction. If
    * there is no default command for the current state, returns an empty string.
    * The commands are implemented as functions on this object or derived ones.
    */
   get currentDefaultCommandName() {
     switch (DownloadsCommon.stateOfDownload(this.download)) {
       case Ci.nsIDownloadManager.DOWNLOAD_NOTSTARTED:
--- a/browser/components/downloads/content/allDownloadsViewOverlay.js
+++ b/browser/components/downloads/content/allDownloadsViewOverlay.js
@@ -293,19 +293,17 @@ HistoryDownloadElementShell.prototype = 
       status.text = status.tip;
     }
     status.tip = "";
 
     return status;
   },
 
   onStateChanged() {
-    this.element.setAttribute("image", this.image);
-    this.element.setAttribute("state",
-                              DownloadsCommon.stateOfDownload(this.download));
+    this._updateState();
 
     if (this.element.selected) {
       goUpdateDownloadCommands();
     } else {
       goUpdateCommand("downloadsCmd_clearDownloads");
     }
   },
 
@@ -374,22 +372,17 @@ HistoryDownloadElementShell.prototype = 
     }
     if (this._historyDownload) {
       let uri = NetUtil.newURI(this.download.source.url);
       PlacesUtils.bhistory.removePage(uri);
     }
   },
 
   downloadsCmd_unblock() {
-    let verdict = this.download.error.reputationCheckVerdict;
-    DownloadsCommon.confirmUnblockDownload(verdict, window).then(confirmed => {
-      if (confirmed) {
-        return this.download.unblock();
-      }
-    }).catch(Cu.reportError);
+    this.confirmUnblock(window);
   },
 
   // Returns whether or not the download handled by this shell should
   // show up in the search results for the given term.  Both the display
   // name for the download and the url are searched.
   matchesSearchTerm(aTerm) {
     if (!aTerm) {
       return true;
--- a/browser/components/downloads/content/download.xml
+++ b/browser/components/downloads/content/download.xml
@@ -42,32 +42,35 @@
                            min="0"
                            max="100"
                            xbl:inherits="mode=progressmode,value=progress"/>
         <xul:description class="downloadDetails"
                          crop="end"
                          xbl:inherits="value=status,tooltiptext=statusTip"/>
       </xul:vbox>
       <xul:stack>
-        <xul:button class="downloadButton downloadCancel"
+        <xul:button class="downloadButton downloadCancel downloadIconCancel"
                     tooltiptext="&cmd.cancel.label;"
                     oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_cancel');"/>
-        <xul:button class="downloadButton downloadRetry"
+        <xul:button class="downloadButton downloadRetry downloadIconRetry"
                     tooltiptext="&cmd.retry.label;"
                     oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_retry');"/>
-        <xul:button class="downloadButton downloadShow"
+        <xul:button class="downloadButton downloadShow downloadIconShow"
 #ifdef XP_MACOSX
                     tooltiptext="&cmd.showMac.label;"
 #else
                     tooltiptext="&cmd.show.label;"
 #endif
                     oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_show');"/>
-        <xul:button class="downloadButton downloadConfirmBlock"
+        <xul:button class="downloadButton downloadConfirmBlock downloadIconCancel"
                     tooltiptext="&cmd.removeFile.label;"
                     oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_confirmBlock');"/>
+        <xul:button class="downloadButton downloadUnblock downloadIconShow"
+                    tooltiptext="&cmd.unblock.label;"
+                    oncommand="DownloadsView.onDownloadCommand(event, 'downloadsCmd_unblock');"/>
       </xul:stack>
     </content>
   </binding>
 
   <binding id="download-toolbarbutton"
            extends="chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton">
     <content>
       <children />
--- a/browser/components/downloads/content/downloads.css
+++ b/browser/components/downloads/content/downloads.css
@@ -113,21 +113,32 @@ richlistitem.download button {
 
 .download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
                               [state="5"], /* Starting (queued)  */
                               [state="0"], /* Downloading        */
                               [state="4"]) /* Paused             */)
                                            .downloadCancel,
 
 /* Blocked (dirty) downloads that have not been confirmed and
-   have temporary data. */
+   have temporary data, for the Malware case. */
 .download-state:not(          [state="8"]  /* Blocked (dirty)    */)
                                            .downloadConfirmBlock,
 .download-state[state="8"]:not(.temporary-block)
                                            .downloadConfirmBlock,
+.download-state[state="8"].temporary-block:not([verdict="Malware"])
+                                           .downloadConfirmBlock,
+
+/* Blocked (dirty) downloads that have not been confirmed and
+   have temporary data, for cases other than Malware. */
+.download-state:not(          [state="8"]  /* Blocked (dirty)    */)
+                                           .downloadUnblock,
+.download-state[state="8"]:not(.temporary-block)
+                                           .downloadUnblock,
+.download-state[state="8"].temporary-block[verdict="Malware"]
+                                           .downloadUnblock,
 
 .download-state:not(:-moz-any([state="2"], /* Failed             */
                               [state="3"]) /* Canceled           */)
                                            .downloadRetry,
 
 .download-state:not(          [state="1"]  /* Finished           */)
                                            .downloadShow
 
--- a/browser/components/downloads/content/downloads.js
+++ b/browser/components/downloads/content/downloads.js
@@ -1030,27 +1030,20 @@ DownloadsViewItem.prototype = {
   __proto__: DownloadsViewUI.DownloadElementShell.prototype,
 
   /**
    * The XUL element corresponding to the associated richlistbox item.
    */
   _element: null,
 
   onStateChanged() {
-    this.element.setAttribute("image", this.image);
-    this.element.setAttribute("state",
-                              DownloadsCommon.stateOfDownload(this.download));
+    this._updateState();
   },
 
   onChanged() {
-    // This cannot be placed within onStateChanged because
-    // when a download goes from hasBlockedData to !hasBlockedData
-    // it will still remain in the same state.
-    this.element.classList.toggle("temporary-block",
-                                  !!this.download.hasBlockedData);
     this._updateProgress();
   },
 
   isCommandEnabled(aCommand) {
     switch (aCommand) {
       case "downloadsCmd_open": {
         if (!this.download.succeeded) {
           return false;
@@ -1094,22 +1087,17 @@ DownloadsViewItem.prototype = {
   cmd_delete() {
     DownloadsCommon.removeAndFinalizeDownload(this.download);
     PlacesUtils.bhistory.removePage(
                            NetUtil.newURI(this.download.source.url));
   },
 
   downloadsCmd_unblock() {
     DownloadsPanel.hidePanel();
-    let verdict = this.download.error.reputationCheckVerdict;
-    DownloadsCommon.confirmUnblockDownload(verdict, window).then(confirmed => {
-      if (confirmed) {
-        return this.download.unblock();
-      }
-    }).catch(Cu.reportError);
+    this.confirmUnblock(window);
   },
 
   downloadsCmd_open() {
     this.download.launch().catch(Cu.reportError);
 
     // We explicitly close the panel here to give the user the feedback that
     // their click has been received, and we're handling the action.
     // Otherwise, we'd have to wait for the file-type handler to execute
--- a/browser/components/downloads/test/browser/browser_confirm_unblock_download.js
+++ b/browser/components/downloads/test/browser/browser_confirm_unblock_download.js
@@ -30,17 +30,17 @@ function addDialogOpenObserver(buttonAct
     }
   });
 }
 
 add_task(function* test_confirm_unblock_dialog_unblock() {
   addDialogOpenObserver("accept");
   let result = yield DownloadsCommon.confirmUnblockDownload(Downloads.Error.BLOCK_VERDICT_MALWARE,
                                                             window);
-  ok(result, "Should return true when the user clicks on `Unblock` button.");
+  is(result, "unblock");
 });
 
 add_task(function* test_confirm_unblock_dialog_keep_safe() {
   addDialogOpenObserver("cancel");
   let result = yield DownloadsCommon.confirmUnblockDownload(Downloads.Error.BLOCK_VERDICT_MALWARE,
                                                             window);
-  ok(!result, "Should return false when the user clicks on `Keep me safe` button.");
+  is(result, "cancel");
 });
--- a/browser/themes/linux/downloads/allDownloadsViewOverlay.css
+++ b/browser/themes/linux/downloads/allDownloadsViewOverlay.css
@@ -6,95 +6,95 @@
 
 /*** List items ***/
 
 :root {
   --downloads-item-height: 5em;
 }
 
 .blockedIcon {
-  list-style-image: url("moz-icon://stock/gtk-dialog-error?size=dialog");
+  list-style-image: url("moz-icon://stock/gtk-dialog-error?size=32");
+}
+
+@item@[verdict="PotentiallyUnwanted"] .blockedIcon {
+  list-style-image: url("moz-icon://stock/gtk-dialog-warning?size=32");
+}
+
+@item@[verdict="Uncommon"] .blockedIcon {
+  list-style-image: url("moz-icon://stock/gtk-dialog-info?size=32");
 }
 
 /*** Button icons ***/
 
-.downloadButton.downloadConfirmBlock,
-.downloadButton.downloadCancel {
+.downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock,
-@item@:hover .downloadButton.downloadCancel {
+@item@:hover .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 32px, 16px, 16px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:hover,
-@item@:hover .downloadButton.downloadCancel:hover {
+@item@:hover .downloadButton.downloadIconCancel:hover {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:active,
-@item@:hover .downloadButton.downloadCancel:active {
+@item@:hover .downloadButton.downloadIconCancel:active {
   -moz-image-region: rect(0px, 64px, 16px, 48px);
 }
-@itemFocused@ .downloadButton.downloadConfirmBlock,
-@itemFocused@ .downloadButton.downloadCancel {
+@itemFocused@ .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 80px, 16px, 64px);
 }
-@itemFocused@:hover .downloadButton.downloadConfirmBlock,
-@itemFocused@:hover .downloadButton.downloadCancel {
+@itemFocused@:hover .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 96px, 16px, 80px);
 }
-@itemFocused@:hover .downloadButton.downloadConfirmBlock:hover,
-@itemFocused@:hover .downloadButton.downloadCancel:hover {
+@itemFocused@:hover .downloadButton.downloadIconCancel:hover {
   -moz-image-region: rect(0px, 112px, 16px, 96px);
 }
-@itemFocused@:hover .downloadButton.downloadConfirmBlock:active,
-@itemFocused@:hover .downloadButton.downloadCancel:active {
+@itemFocused@:hover .downloadButton.downloadIconCancel:active {
   -moz-image-region: rect(0px, 128px, 16px, 112px);
 }
 
-.downloadButton.downloadShow {
+.downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 16px, 32px, 0px);
 }
-@item@:hover .downloadButton.downloadShow {
+@item@:hover .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 32px, 32px, 16px);
 }
-@item@:hover .downloadButton.downloadShow:hover {
+@item@:hover .downloadButton.downloadIconShow:hover {
   -moz-image-region: rect(16px, 48px, 32px, 32px);
 }
-@item@:hover .downloadButton.downloadShow:active {
+@item@:hover .downloadButton.downloadIconShow:active {
   -moz-image-region: rect(16px, 64px, 32px, 48px);
 }
-@itemFocused@ .downloadButton.downloadShow {
+@itemFocused@ .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 80px, 32px, 64px);
 }
-@itemFocused@:hover .downloadButton.downloadShow {
+@itemFocused@:hover .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 96px, 32px, 80px);
 }
-@itemFocused@:hover .downloadButton.downloadShow:hover {
+@itemFocused@:hover .downloadButton.downloadIconShow:hover {
   -moz-image-region: rect(16px, 112px, 32px, 96px);
 }
-@itemFocused@:hover .downloadButton.downloadShow:active {
+@itemFocused@:hover .downloadButton.downloadIconShow:active {
   -moz-image-region: rect(16px, 128px, 32px, 112px);
 }
 
-.downloadButton.downloadRetry {
+.downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 16px, 48px, 0px);
 }
-@item@:hover .downloadButton.downloadRetry {
+@item@:hover .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 32px, 48px, 16px);
 }
-@item@:hover .downloadButton.downloadRetry:hover {
+@item@:hover .downloadButton.downloadIconRetry:hover {
   -moz-image-region: rect(32px, 48px, 48px, 32px);
 }
-@item@:hover .downloadButton.downloadRetry:active {
+@item@:hover .downloadButton.downloadIconRetry:active {
   -moz-image-region: rect(32px, 64px, 48px, 48px);
 }
-@itemFocused@ .downloadButton.downloadRetry {
+@itemFocused@ .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 80px, 48px, 64px);
 }
-@itemFocused@:hover .downloadButton.downloadRetry {
+@itemFocused@:hover .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 96px, 48px, 80px);
 }
-@itemFocused@:hover .downloadButton.downloadRetry:hover {
+@itemFocused@:hover .downloadButton.downloadIconRetry:hover {
   -moz-image-region: rect(32px, 112px, 48px, 96px);
 }
-@itemFocused@:hover .downloadButton.downloadRetry:active {
+@itemFocused@:hover .downloadButton.downloadIconRetry:active {
   -moz-image-region: rect(32px, 128px, 48px, 112px);
 }
--- a/browser/themes/linux/downloads/downloads.css
+++ b/browser/themes/linux/downloads/downloads.css
@@ -32,17 +32,25 @@
   --downloads-item-border-bottom-color: hsla(0,0%,0%,.15);
   --downloads-item-font-size-factor: 0.9;
   --downloads-item-target-margin-bottom: 7px;
   --downloads-item-details-margin-top: 1px;
   --downloads-item-details-opacity: 0.6;
 }
 
 .blockedIcon {
-  list-style-image: url("moz-icon://stock/gtk-dialog-error?size=dialog");
+  list-style-image: url("moz-icon://stock/gtk-dialog-error?size=32");
+}
+
+@item@[verdict="PotentiallyUnwanted"] .blockedIcon {
+  list-style-image: url("moz-icon://stock/gtk-dialog-warning?size=32");
+}
+
+@item@[verdict="Uncommon"] .blockedIcon {
+  list-style-image: url("moz-icon://stock/gtk-dialog-info?size=32");
 }
 
 .downloadButton:focus > .button-box {
   outline: 1px -moz-dialogtext dotted;
 }
 
 /*** Highlighted list items ***/
 
@@ -58,50 +66,55 @@
   background-color: Highlight;
   background-image: linear-gradient(hsla(0,0%,100%,.1), transparent);
   color: HighlightText;
   cursor: pointer;
 }
 
 /*** Button icons ***/
 
-.downloadButton.downloadConfirmBlock,
-.downloadButton.downloadCancel {
+.downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock,
-@item@:hover .downloadButton.downloadCancel {
+@item@:hover .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 32px, 16px, 16px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:hover,
-@item@:hover .downloadButton.downloadCancel:hover {
+@item@:hover .downloadButton.downloadIconCancel:hover {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:active,
-@item@:hover .downloadButton.downloadCancel:active {
+@item@:hover .downloadButton.downloadIconCancel:active {
   -moz-image-region: rect(0px, 64px, 16px, 48px);
 }
 
-.downloadButton.downloadShow {
+.downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 16px, 32px, 0px);
 }
-@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow {
+@itemNotFinished@:hover .downloadButton.downloadIconShow {
+  -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+@itemNotFinished@:hover .downloadButton.downloadIconShow:hover {
+  -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+@itemNotFinished@:hover .downloadButton.downloadIconShow:active {
+  -moz-image-region: rect(16px, 64px, 32px, 48px);
+}
+@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 96px, 32px, 80px);
 }
-@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow:hover {
+@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow:hover {
   -moz-image-region: rect(16px, 112px, 32px, 96px);
 }
-@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow:active {
+@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow:active {
   -moz-image-region: rect(16px, 128px, 32px, 112px);
 }
 
-.downloadButton.downloadRetry {
+.downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 16px, 48px, 0px);
 }
-@item@:hover .downloadButton.downloadRetry {
+@item@:hover .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 32px, 48px, 16px);
 }
-@item@:hover .downloadButton.downloadRetry:hover {
+@item@:hover .downloadButton.downloadIconRetry:hover {
   -moz-image-region: rect(32px, 48px, 48px, 32px);
 }
-@item@:hover .downloadButton.downloadRetry:active {
+@item@:hover .downloadButton.downloadIconRetry:active {
   -moz-image-region: rect(32px, 64px, 48px, 48px);
 }
--- a/browser/themes/osx/downloads/allDownloadsViewOverlay.css
+++ b/browser/themes/osx/downloads/allDownloadsViewOverlay.css
@@ -5,185 +5,177 @@
 %include ../../shared/downloads/allDownloadsViewOverlay.inc.css
 
 /*** List items ***/
 
 :root {
   --downloads-item-height: 6em;
 }
 
+@item@[verdict="PotentiallyUnwanted"] .blockedIcon {
+  list-style-image: url("chrome://global/skin/icons/warning-32.png");
+}
+
+@item@[verdict="Uncommon"] .blockedIcon {
+  list-style-image: url("chrome://global/skin/icons/information-32.png");
+}
+
 /*** Button icons ***/
 
-.downloadButton.downloadConfirmBlock,
-.downloadButton.downloadCancel {
+.downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock,
-@item@:hover .downloadButton.downloadCancel {
+@item@:hover .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 32px, 16px, 16px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:hover,
-@item@:hover .downloadButton.downloadCancel:hover {
+@item@:hover .downloadButton.downloadIconCancel:hover {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:active,
-@item@:hover .downloadButton.downloadCancel:active {
+@item@:hover .downloadButton.downloadIconCancel:active {
   -moz-image-region: rect(0px, 64px, 16px, 48px);
 }
-@itemFocused@ .downloadButton.downloadConfirmBlock,
-@itemFocused@ .downloadButton.downloadCancel {
+@itemFocused@ .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 80px, 16px, 64px);
 }
-@itemFocused@:hover .downloadButton.downloadConfirmBlock,
-@itemFocused@:hover .downloadButton.downloadCancel {
+@itemFocused@:hover .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 96px, 16px, 80px);
 }
-@itemFocused@:hover .downloadButton.downloadConfirmBlock:hover,
-@itemFocused@:hover .downloadButton.downloadCancel:hover {
+@itemFocused@:hover .downloadButton.downloadIconCancel:hover {
   -moz-image-region: rect(0px, 112px, 16px, 96px);
 }
-@itemFocused@:hover .downloadButton.downloadConfirmBlock:active,
-@itemFocused@:hover .downloadButton.downloadCancel:active {
+@itemFocused@:hover .downloadButton.downloadIconCancel:active {
   -moz-image-region: rect(0px, 128px, 16px, 112px);
 }
 
-.downloadButton.downloadShow {
+.downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 16px, 32px, 0px);
 }
-@item@:hover .downloadButton.downloadShow {
+@item@:hover .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 32px, 32px, 16px);
 }
-@item@:hover .downloadButton.downloadShow:hover {
+@item@:hover .downloadButton.downloadIconShow:hover {
   -moz-image-region: rect(16px, 48px, 32px, 32px);
 }
-@item@:hover .downloadButton.downloadShow:active {
+@item@:hover .downloadButton.downloadIconShow:active {
   -moz-image-region: rect(16px, 64px, 32px, 48px);
 }
-@itemFocused@ .downloadButton.downloadShow {
+@itemFocused@ .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 80px, 32px, 64px);
 }
-@itemFocused@:hover .downloadButton.downloadShow {
+@itemFocused@:hover .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 96px, 32px, 80px);
 }
-@itemFocused@:hover .downloadButton.downloadShow:hover {
+@itemFocused@:hover .downloadButton.downloadIconShow:hover {
   -moz-image-region: rect(16px, 112px, 32px, 96px);
 }
-@itemFocused@:hover .downloadButton.downloadShow:active {
+@itemFocused@:hover .downloadButton.downloadIconShow:active {
   -moz-image-region: rect(16px, 128px, 32px, 112px);
 }
 
-.downloadButton.downloadRetry {
+.downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 16px, 48px, 0px);
 }
-@item@:hover .downloadButton.downloadRetry {
+@item@:hover .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 32px, 48px, 16px);
 }
-@item@:hover .downloadButton.downloadRetry:hover {
+@item@:hover .downloadButton.downloadIconRetry:hover {
   -moz-image-region: rect(32px, 48px, 48px, 32px);
 }
-@item@:hover .downloadButton.downloadRetry:active {
+@item@:hover .downloadButton.downloadIconRetry:active {
   -moz-image-region: rect(32px, 64px, 48px, 48px);
 }
-@itemFocused@ .downloadButton.downloadRetry {
+@itemFocused@ .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 80px, 48px, 64px);
 }
-@itemFocused@:hover .downloadButton.downloadRetry {
+@itemFocused@:hover .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 96px, 48px, 80px);
 }
-@itemFocused@:hover .downloadButton.downloadRetry:hover {
+@itemFocused@:hover .downloadButton.downloadIconRetry:hover {
   -moz-image-region: rect(32px, 112px, 48px, 96px);
 }
-@itemFocused@:hover .downloadButton.downloadRetry:active {
+@itemFocused@:hover .downloadButton.downloadIconRetry:active {
   -moz-image-region: rect(32px, 128px, 48px, 112px);
 }
 
 @media (min-resolution: 2dppx) {
   .downloadButton {
     list-style-image: url("chrome://browser/skin/downloads/buttons@2x.png");
   }
   .downloadButton > .button-box > .button-icon {
     width: 16px;
     height: 16px;
   }
 
-  .downloadButton.downloadConfirmBlock,
-  .downloadButton.downloadCancel {
+  .downloadButton.downloadIconCancel {
      -moz-image-region: rect(0px, 32px, 32px, 0px);
   }
-  @item@:hover .downloadButton.downloadConfirmBlock,
-  @item@:hover .downloadButton.downloadCancel {
+  @item@:hover .downloadButton.downloadIconCancel {
     -moz-image-region: rect(0px, 64px, 32px, 32px);
   }
-  @item@:hover .downloadButton.downloadConfirmBlock:hover,
-  @item@:hover .downloadButton.downloadCancel:hover {
+  @item@:hover .downloadButton.downloadIconCancel:hover {
     -moz-image-region: rect(0px, 96px, 32px, 64px);
   }
-  @item@:hover .downloadButton.downloadConfirmBlock:active,
-  @item@:hover .downloadButton.downloadCancel:active {
+  @item@:hover .downloadButton.downloadIconCancel:active {
     -moz-image-region: rect(0px, 128px, 32px, 96px);
   }
-  @itemFocused@ .downloadButton.downloadConfirmBlock,
-  @itemFocused@ .downloadButton.downloadCancel {
+  @itemFocused@ .downloadButton.downloadIconCancel {
     -moz-image-region: rect(0px, 160px, 32px, 128px);
   }
-  @itemFocused@:hover .downloadButton.downloadConfirmBlock,
-  @itemFocused@:hover .downloadButton.downloadCancel {
+  @itemFocused@:hover .downloadButton.downloadIconCancel {
     -moz-image-region: rect(0px, 192px, 32px, 160px);
   }
-  @itemFocused@:hover .downloadButton.downloadConfirmBlock:hover,
-  @itemFocused@:hover .downloadButton.downloadCancel:hover {
+  @itemFocused@:hover .downloadButton.downloadIconCancel:hover {
     -moz-image-region: rect(0px, 224px, 32px, 192px);
   }
-  @itemFocused@:hover .downloadButton.downloadConfirmBlock:active,
-  @itemFocused@:hover .downloadButton.downloadCancel:active {
+  @itemFocused@:hover .downloadButton.downloadIconCancel:active {
     -moz-image-region: rect(0px, 256px, 32px, 224px);
   }
 
-  .downloadButton.downloadShow {
+  .downloadButton.downloadIconShow {
     -moz-image-region: rect(32px, 32px, 64px, 0px);
   }
-  @item@:hover .downloadButton.downloadShow {
+  @item@:hover .downloadButton.downloadIconShow {
     -moz-image-region: rect(32px, 64px, 64px, 32px);
   }
-  @item@:hover .downloadButton.downloadShow:hover {
+  @item@:hover .downloadButton.downloadIconShow:hover {
     -moz-image-region: rect(32px, 96px, 64px, 64px);
   }
-  @item@:hover .downloadButton.downloadShow:active {
+  @item@:hover .downloadButton.downloadIconShow:active {
     -moz-image-region: rect(32px, 128px, 64px, 96px);
   }
-  @itemFocused@ .downloadButton.downloadShow {
+  @itemFocused@ .downloadButton.downloadIconShow {
     -moz-image-region: rect(32px, 160px, 64px, 128px);
   }
-  @itemFocused@:hover .downloadButton.downloadShow {
+  @itemFocused@:hover .downloadButton.downloadIconShow {
     -moz-image-region: rect(32px, 192px, 64px, 160px);
   }
-  @itemFocused@:hover .downloadButton.downloadShow:hover {
+  @itemFocused@:hover .downloadButton.downloadIconShow:hover {
     -moz-image-region: rect(32px, 224px, 64px, 192px);
   }
-  @itemFocused@:hover .downloadButton.downloadShow:active {
+  @itemFocused@:hover .downloadButton.downloadIconShow:active {
     -moz-image-region: rect(32px, 256px, 64px, 224px);
   }
 
-  .downloadButton.downloadRetry {
+  .downloadButton.downloadIconRetry {
     -moz-image-region: rect(64px, 32px, 96px, 0px);
   }
-  @item@:hover .downloadButton.downloadRetry {
+  @item@:hover .downloadButton.downloadIconRetry {
     -moz-image-region: rect(64px, 64px, 96px, 32px);
   }
-  @item@:hover .downloadButton.downloadRetry:hover {
+  @item@:hover .downloadButton.downloadIconRetry:hover {
     -moz-image-region: rect(64px, 96px, 96px, 64px);
   }
-  @item@:hover .downloadButton.downloadRetry:active {
+  @item@:hover .downloadButton.downloadIconRetry:active {
     -moz-image-region: rect(64px, 128px, 96px, 96px);
   }
-  @itemFocused@ .downloadButton.downloadRetry {
+  @itemFocused@ .downloadButton.downloadIconRetry {
     -moz-image-region: rect(64px, 160px, 96px, 128px);
   }
-  @itemFocused@:hover .downloadButton.downloadRetry {
+  @itemFocused@:hover .downloadButton.downloadIconRetry {
     -moz-image-region: rect(64px, 192px, 96px, 160px);
   }
-  @itemFocused@:hover .downloadButton.downloadRetry:hover {
+  @itemFocused@:hover .downloadButton.downloadIconRetry:hover {
     -moz-image-region: rect(64px, 224px, 96px, 192px);
   }
-  @itemFocused@:hover .downloadButton.downloadRetry:active {
+  @itemFocused@:hover .downloadButton.downloadIconRetry:active {
     -moz-image-region: rect(64px, 256px, 96px, 224px);
   }
 }
--- a/browser/themes/osx/downloads/downloads.css
+++ b/browser/themes/osx/downloads/downloads.css
@@ -42,16 +42,24 @@
   --downloads-item-details-opacity: 0.7;
 }
 
 .downloadButton:focus > .button-box {
   outline: 2px -moz-mac-focusring solid;
   outline-offset: -2px;
 }
 
+@item@[verdict="PotentiallyUnwanted"] .blockedIcon {
+  list-style-image: url("chrome://global/skin/icons/warning-32.png");
+}
+
+@item@[verdict="Uncommon"] .blockedIcon {
+  list-style-image: url("chrome://global/skin/icons/information-32.png");
+}
+
 /*** Highlighted list items ***/
 
 @keyfocus@ @itemFocused@,
 @notKeyfocus@ @itemFinished@[exists]:hover {
   border-radius: 3px;
   border-top: 1px solid hsla(0,0%,100%,.2);
   border-bottom: 1px solid hsla(0,0%,0%,.4);
   background-color: Highlight;
@@ -59,189 +67,179 @@
 }
 
 @notKeyfocus@ @itemFinished@[exists]:hover {
   cursor: pointer;
 }
 
 /*** Button icons ***/
 
-.downloadButton.downloadConfirmBlock,
-.downloadButton.downloadCancel {
+.downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock,
-@item@:hover .downloadButton.downloadCancel {
+@item@:hover .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 32px, 16px, 16px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:hover,
-@item@:hover .downloadButton.downloadCancel:hover {
+@item@:hover .downloadButton.downloadIconCancel:hover {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:active,
-@item@:hover .downloadButton.downloadCancel:active {
+@item@:hover .downloadButton.downloadIconCancel:active {
   -moz-image-region: rect(0px, 64px, 16px, 48px);
 }
-@keyfocus@ @itemFocused@ .downloadButton.downloadConfirmBlock,
-@keyfocus@ @itemFocused@ .downloadButton.downloadCancel {
+@keyfocus@ @itemFocused@ .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 80px, 16px, 64px);
 }
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadConfirmBlock,
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadCancel {
+@keyfocus@ @itemFocused@:hover .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 96px, 16px, 80px);
 }
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadConfirmBlock:hover,
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadCancel:hover {
+@keyfocus@ @itemFocused@:hover .downloadButton.downloadIconCancel:hover {
   -moz-image-region: rect(0px, 112px, 16px, 96px);
 }
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadConfirmBlock:active,
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadCancel:active {
+@keyfocus@ @itemFocused@:hover .downloadButton.downloadIconCancel:active {
   -moz-image-region: rect(0px, 128px, 16px, 112px);
 }
 
-.downloadButton.downloadShow {
+.downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 16px, 32px, 0px);
 }
-@keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadShow {
+@notKeyfocus@ @itemNotFinished@:hover .downloadButton.downloadIconShow,
+@keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 32px, 32px, 16px);
 }
-@keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadShow:hover {
+@notKeyfocus@ @itemNotFinished@:hover .downloadButton.downloadIconShow:hover,
+@keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadIconShow:hover {
   -moz-image-region: rect(16px, 48px, 32px, 32px);
 }
-@keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadShow:active {
+@notKeyfocus@ @itemNotFinished@:hover .downloadButton.downloadIconShow:active,
+@keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadIconShow:active {
   -moz-image-region: rect(16px, 64px, 32px, 48px);
 }
-@keyfocus@ @itemFocused@ .downloadButton.downloadShow {
+@keyfocus@ @itemFocused@ .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 80px, 32px, 64px);
 }
-@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow,
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadShow {
+@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow,
+@keyfocus@ @itemFocused@:hover .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 96px, 32px, 80px);
 }
-@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow:hover,
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadShow:hover {
+@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow:hover,
+@keyfocus@ @itemFocused@:hover .downloadButton.downloadIconShow:hover {
   -moz-image-region: rect(16px, 112px, 32px, 96px);
 }
-@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow:active,
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadShow:active {
+@notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow:active,
+@keyfocus@ @itemFocused@:hover .downloadButton.downloadIconShow:active {
   -moz-image-region: rect(16px, 128px, 32px, 112px);
 }
 
-.downloadButton.downloadRetry {
+.downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 16px, 48px, 0px);
 }
-@item@:hover .downloadButton.downloadRetry {
+@item@:hover .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 32px, 48px, 16px);
 }
-@item@:hover .downloadButton.downloadRetry:hover {
+@item@:hover .downloadButton.downloadIconRetry:hover {
   -moz-image-region: rect(32px, 48px, 48px, 32px);
 }
-@item@:hover .downloadButton.downloadRetry:active {
+@item@:hover .downloadButton.downloadIconRetry:active {
   -moz-image-region: rect(32px, 64px, 48px, 48px);
 }
-@keyfocus@ @itemFocused@ .downloadButton.downloadRetry {
+@keyfocus@ @itemFocused@ .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 80px, 48px, 64px);
 }
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadRetry {
+@keyfocus@ @itemFocused@:hover .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 96px, 48px, 80px);
 }
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadRetry:hover {
+@keyfocus@ @itemFocused@:hover .downloadButton.downloadIconRetry:hover {
   -moz-image-region: rect(32px, 112px, 48px, 96px);
 }
-@keyfocus@ @itemFocused@:hover .downloadButton.downloadRetry:active {
+@keyfocus@ @itemFocused@:hover .downloadButton.downloadIconRetry:active {
   -moz-image-region: rect(32px, 128px, 48px, 112px);
 }
 
 @media (min-resolution: 2dppx) {
   .downloadButton {
     list-style-image: url("chrome://browser/skin/downloads/buttons@2x.png");
   }
   .downloadButton > .button-box > .button-icon {
     width: 16px;
     height: 16px;
   }
 
-  .downloadButton.downloadConfirmBlock,
-  .downloadButton.downloadCancel {
+  .downloadButton.downloadIconCancel {
     -moz-image-region: rect(0px, 32px, 32px, 0px);
   }
-  @item@:hover .downloadButton.downloadConfirmBlock,
-  @item@:hover .downloadButton.downloadCancel {
+  @item@:hover .downloadButton.downloadIconCancel {
     -moz-image-region: rect(0px, 64px, 32px, 32px);
   }
-  @item@:hover .downloadButton.downloadConfirmBlock:hover,
-  @item@:hover .downloadButton.downloadCancel:hover {
+  @item@:hover .downloadButton.downloadIconCancel:hover {
     -moz-image-region: rect(0px, 96px, 32px, 64px);
   }
-  @item@:hover .downloadButton.downloadConfirmBlock:active,
-  @item@:hover .downloadButton.downloadCancel:active {
+  @item@:hover .downloadButton.downloadIconCancel:active {
     -moz-image-region: rect(0px, 128px, 32px, 96px);
   }
-  @keyfocus@ @itemFocused@ .downloadButton.downloadConfirmBlock,
-  @keyfocus@ @itemFocused@ .downloadButton.downloadCancel {
+  @keyfocus@ @itemFocused@ .downloadButton.downloadIconCancel {
     -moz-image-region: rect(0px, 160px, 32px, 128px);
   }
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadConfirmBlock,
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadCancel {
+  @keyfocus@ @itemFocused@:hover .downloadButton.downloadIconCancel {
     -moz-image-region: rect(0px, 192px, 32px, 160px);
   }
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadConfirmBlock:hover,
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadCancel:hover {
+  @keyfocus@ @itemFocused@:hover .downloadButton.downloadIconCancel:hover {
     -moz-image-region: rect(0px, 224px, 32px, 192px);
   }
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadConfirmBlock:active,
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadCancel:active {
+  @keyfocus@ @itemFocused@:hover .downloadButton.downloadIconCancel:active {
     -moz-image-region: rect(0px, 256px, 32px, 224px);
   }
 
-  .downloadButton.downloadShow {
+  .downloadButton.downloadIconShow {
     -moz-image-region: rect(32px, 32px, 64px, 0px);
   }
-  @keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadShow {
+  @notKeyfocus@ @itemNotFinished@:hover .downloadButton.downloadIconShow,
+  @keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadIconShow {
     -moz-image-region: rect(32px, 64px, 64px, 32px);
   }
-  @keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadShow:hover {
+  @notKeyfocus@ @itemNotFinished@:hover .downloadButton.downloadIconShow:hover,
+  @keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadIconShow:hover {
     -moz-image-region: rect(32px, 96px, 64px, 64px);
   }
-  @keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadShow:active {
+  @notKeyfocus@ @itemNotFinished@:hover .downloadButton.downloadIconShow:active,
+  @keyfocus@ @itemFinished@:hover:not([selected]) .downloadButton.downloadIconShow:active {
     -moz-image-region: rect(32px, 128px, 64px, 96px);
   }
-  @keyfocus@ @itemFocused@ .downloadButton.downloadShow {
+  @keyfocus@ @itemFocused@ .downloadButton.downloadIconShow {
     -moz-image-region: rect(32px, 160px, 64px, 128px);
   }
-  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow,
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadShow {
+  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow,
+  @keyfocus@ @itemFocused@:hover .downloadButton.downloadIconShow {
     -moz-image-region: rect(32px, 192px, 64px, 160px);
   }
-  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow:hover,
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadShow:hover {
+  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow:hover,
+  @keyfocus@ @itemFocused@:hover .downloadButton.downloadIconShow:hover {
     -moz-image-region: rect(32px, 224px, 64px, 192px);
   }
-  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow:active,
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadShow:active {
+  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow:active,
+  @keyfocus@ @itemFocused@:hover .downloadButton.downloadIconShow:active {
     -moz-image-region: rect(32px, 256px, 64px, 224px);
   }
 
-  .downloadButton.downloadRetry {
+  .downloadButton.downloadIconRetry {
     -moz-image-region: rect(64px, 32px, 96px, 0px);
   }
-  @item@:hover .downloadButton.downloadRetry {
+  @item@:hover .downloadButton.downloadIconRetry {
     -moz-image-region: rect(64px, 64px, 96px, 32px);
   }
-  @item@:hover .downloadButton.downloadRetry:hover {
+  @item@:hover .downloadButton.downloadIconRetry:hover {
     -moz-image-region: rect(64px, 96px, 96px, 64px);
   }
-  @item@:hover .downloadButton.downloadRetry:active {
+  @item@:hover .downloadButton.downloadIconRetry:active {
     -moz-image-region: rect(64px, 128px, 96px, 96px);
   }
-  @keyfocus@ @itemFocused@ .downloadButton.downloadRetry {
+  @keyfocus@ @itemFocused@ .downloadButton.downloadIconRetry {
     -moz-image-region: rect(64px, 160px, 96px, 128px);
   }
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadRetry {
+  @keyfocus@ @itemFocused@:hover .downloadButton.downloadIconRetry {
     -moz-image-region: rect(64px, 192px, 96px, 160px);
   }
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadRetry:hover {
+  @keyfocus@ @itemFocused@:hover .downloadButton.downloadIconRetry:hover {
     -moz-image-region: rect(64px, 224px, 96px, 192px);
   }
-  @keyfocus@ @itemFocused@:hover .downloadButton.downloadRetry:active {
+  @keyfocus@ @itemFocused@:hover .downloadButton.downloadIconRetry:active {
     -moz-image-region: rect(64px, 256px, 96px, 224px);
   }
 }
--- a/browser/themes/shared/downloads/downloads.inc.css
+++ b/browser/themes/shared/downloads/downloads.inc.css
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 %filter substitution
 
 %define keyfocus #downloadsPanel[keyfocus]
 %define notKeyfocus #downloadsPanel:not([keyfocus])
 %define item richlistitem[type="download"]
 %define itemFinished @item@[state="1"]
+%define itemNotFinished @item@:not([state="1"])
 %define itemFocused #downloadsListBox:focus > @item@[selected]
 
 /*** Panel and outer controls ***/
 
 #downloadsPanel > .panel-arrowcontainer > .panel-arrowcontent {
   padding: 0;
 }
 
--- a/browser/themes/windows/downloads/allDownloadsViewOverlay.css
+++ b/browser/themes/windows/downloads/allDownloadsViewOverlay.css
@@ -5,16 +5,24 @@
 %include ../../shared/downloads/allDownloadsViewOverlay.inc.css
 
 /*** List items ***/
 
 :root {
   --downloads-item-height: 6em;
 }
 
+@item@[verdict="PotentiallyUnwanted"] .blockedIcon {
+  list-style-image: url("chrome://global/skin/icons/Warning.png");
+}
+
+@item@[verdict="Uncommon"] .blockedIcon {
+  list-style-image: url("chrome://global/skin/icons/information-32.png");
+}
+
 /*** Highlighted list items ***/
 
 @media not all and (-moz-os-version: windows-xp) {
   @media (-moz-windows-default-theme) {
     /*
     -moz-appearance: menuitem is almost right, but the hover effect is not
     transparent and is lighter than desired.
 
@@ -39,95 +47,87 @@
       -moz-outline-radius: 3px;
       outline-offset: -2px;
     }
   }
 }
 
 /*** Button icons ***/
 
-.downloadButton.downloadConfirmBlock,
-.downloadButton.downloadCancel {
+.downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock,
-@item@:hover .downloadButton.downloadCancel {
+@item@:hover .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 32px, 16px, 16px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:hover,
-@item@:hover .downloadButton.downloadCancel:hover {
+@item@:hover .downloadButton.downloadIconCancel:hover {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:active,
-@item@:hover .downloadButton.downloadCancel:active {
+@item@:hover .downloadButton.downloadIconCancel:active {
   -moz-image-region: rect(0px, 64px, 16px, 48px);
 }
 
-.downloadButton.downloadShow {
+.downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 16px, 32px, 0px);
 }
-@item@:hover .downloadButton.downloadShow {
+@item@:hover .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 32px, 32px, 16px);
 }
-@item@:hover .downloadButton.downloadShow:hover {
+@item@:hover .downloadButton.downloadIconShow:hover {
   -moz-image-region: rect(16px, 48px, 32px, 32px);
 }
-@item@:hover .downloadButton.downloadShow:active {
+@item@:hover .downloadButton.downloadIconShow:active {
   -moz-image-region: rect(16px, 64px, 32px, 48px);
 }
 
-.downloadButton.downloadRetry {
+.downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 16px, 48px, 0px);
 }
-@item@:hover .downloadButton.downloadRetry {
+@item@:hover .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 32px, 48px, 16px);
 }
-@item@:hover .downloadButton.downloadRetry:hover {
+@item@:hover .downloadButton.downloadIconRetry:hover {
   -moz-image-region: rect(32px, 48px, 48px, 32px);
 }
-@item@:hover .downloadButton.downloadRetry:active {
+@item@:hover .downloadButton.downloadIconRetry:active {
   -moz-image-region: rect(32px, 64px, 48px, 48px);
 }
 
 @media (-moz-os-version: windows-xp) {
-  @itemFocused@ .downloadButton.downloadConfirmBlock,
-  @itemFocused@ .downloadButton.downloadCancel {
+  @itemFocused@ .downloadButton.downloadIconCancel {
     -moz-image-region: rect(0px, 80px, 16px, 64px);
   }
-  @itemFocused@:hover .downloadButton.downloadConfirmBlock,
-  @itemFocused@:hover .downloadButton.downloadCancel {
+  @itemFocused@:hover .downloadButton.downloadIconCancel {
     -moz-image-region: rect(0px, 96px, 16px, 80px);
   }
-  @itemFocused@:hover .downloadButton.downloadConfirmBlock:hover,
-  @itemFocused@:hover .downloadButton.downloadCancel:hover {
+  @itemFocused@:hover .downloadButton.downloadIconCancel:hover {
     -moz-image-region: rect(0px, 112px, 16px, 96px);
   }
-  @itemFocused@:hover .downloadButton.downloadConfirmBlock:active,
-  @itemFocused@:hover .downloadButton.downloadCancel:active {
+  @itemFocused@:hover .downloadButton.downloadIconCancel:active {
     -moz-image-region: rect(0px, 128px, 16px, 112px);
   }
 
-  @itemFocused@ .downloadButton.downloadShow {
+  @itemFocused@ .downloadButton.downloadIconShow {
     -moz-image-region: rect(16px, 80px, 32px, 64px);
   }
-  @itemFocused@:hover .downloadButton.downloadShow {
+  @itemFocused@:hover .downloadButton.downloadIconShow {
     -moz-image-region: rect(16px, 96px, 32px, 80px);
   }
-  @itemFocused@:hover .downloadButton.downloadShow:hover {
+  @itemFocused@:hover .downloadButton.downloadIconShow:hover {
     -moz-image-region: rect(16px, 112px, 32px, 96px);
   }
-  @itemFocused@:hover .downloadButton.downloadShow:active {
+  @itemFocused@:hover .downloadButton.downloadIconShow:active {
     -moz-image-region: rect(16px, 128px, 32px, 112px);
   }
 
-  @itemFocused@ .downloadButton.downloadRetry {
+  @itemFocused@ .downloadButton.downloadIconRetry {
     -moz-image-region: rect(32px, 80px, 48px, 64px);
   }
-  @itemFocused@:hover .downloadButton.downloadRetry {
+  @itemFocused@:hover .downloadButton.downloadIconRetry {
     -moz-image-region: rect(32px, 96px, 48px, 80px);
   }
-  @itemFocused@:hover .downloadButton.downloadRetry:hover {
+  @itemFocused@:hover .downloadButton.downloadIconRetry:hover {
     -moz-image-region: rect(32px, 112px, 48px, 96px);
   }
-  @itemFocused@:hover .downloadButton.downloadRetry:active {
+  @itemFocused@:hover .downloadButton.downloadIconRetry:active {
     -moz-image-region: rect(32px, 128px, 48px, 112px);
   }
 }
--- a/browser/themes/windows/downloads/downloads.css
+++ b/browser/themes/windows/downloads/downloads.css
@@ -91,16 +91,24 @@
 .downloadButton > .button-box {
   border: 1px solid transparent;
 }
 
 @keyfocus@ .downloadButton:focus > .button-box {
   border: 1px dotted ThreeDDarkShadow;
 }
 
+@item@[verdict="PotentiallyUnwanted"] .blockedIcon {
+  list-style-image: url("chrome://global/skin/icons/Warning.png");
+}
+
+@item@[verdict="Uncommon"] .blockedIcon {
+  list-style-image: url("chrome://global/skin/icons/information-32.png");
+}
+
 /*** Highlighted list items ***/
 
 @keyfocus@ @itemFocused@ {
   outline: 1px -moz-dialogtext dotted;
   outline-offset: -1px;
 }
 
 @notKeyfocus@ @itemFinished@[exists]:hover {
@@ -143,70 +151,66 @@
                 0 1px 0 hsla(0,0%,100%,.3) inset;
     background-image: linear-gradient(hsl(212,86%,92%), hsl(212,91%,86%));
     color: black;
   }
 }
 
 /*** Button icons ***/
 
-.downloadButton.downloadConfirmBlock,
-.downloadButton.downloadCancel {
+.downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock,
-@item@:hover .downloadButton.downloadCancel {
+@item@:hover .downloadButton.downloadIconCancel {
   -moz-image-region: rect(0px, 32px, 16px, 16px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:hover,
-@item@:hover .downloadButton.downloadCancel:hover {
+@item@:hover .downloadButton.downloadIconCancel:hover {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
-@item@:hover .downloadButton.downloadConfirmBlock:active,
-@item@:hover .downloadButton.downloadCancel:active {
+@item@:hover .downloadButton.downloadIconCancel:active {
   -moz-image-region: rect(0px, 64px, 16px, 48px);
 }
 
-.downloadButton.downloadShow {
+.downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 16px, 32px, 0px);
 }
-@item@:hover .downloadButton.downloadShow {
+@item@:hover .downloadButton.downloadIconShow {
   -moz-image-region: rect(16px, 32px, 32px, 16px);
 }
-@item@:hover .downloadButton.downloadShow:hover {
+@item@:hover .downloadButton.downloadIconShow:hover {
   -moz-image-region: rect(16px, 48px, 32px, 32px);
 }
-@item@:hover .downloadButton.downloadShow:active {
+@item@:hover .downloadButton.downloadIconShow:active {
   -moz-image-region: rect(16px, 64px, 32px, 48px);
 }
 @media (-moz-os-version: windows-xp) {
-  @keyfocus@ @itemFinished@:hover .downloadButton.downloadShow {
+  @keyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow {
     -moz-image-region: rect(16px, 32px, 32px, 16px);
   }
-  @keyfocus@ @itemFinished@:hover .downloadButton.downloadShow:hover {
+  @keyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow:hover {
     -moz-image-region: rect(16px, 48px, 32px, 32px);
   }
-  @keyfocus@ @itemFinished@:hover .downloadButton.downloadShow:active {
+  @keyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow:active {
     -moz-image-region: rect(16px, 64px, 32px, 48px);
   }
-  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow {
+  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow {
     -moz-image-region: rect(16px, 96px, 32px, 80px);
   }
-  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow:hover {
+  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow:hover {
     -moz-image-region: rect(16px, 112px, 32px, 96px);
   }
-  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadShow:active {
+  @notKeyfocus@ @itemFinished@:hover .downloadButton.downloadIconShow:active {
     -moz-image-region: rect(16px, 128px, 32px, 112px);
   }
 }
 
-.downloadButton.downloadRetry {
+.downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 16px, 48px, 0px);
 }
-@item@:hover .downloadButton.downloadRetry {
+@item@:hover .downloadButton.downloadIconRetry {
   -moz-image-region: rect(32px, 32px, 48px, 16px);
 }
-@item@:hover .downloadButton.downloadRetry:hover {
+@item@:hover .downloadButton.downloadIconRetry:hover {
   -moz-image-region: rect(32px, 48px, 48px, 32px);
 }
-@item@:hover .downloadButton.downloadRetry:active {
+@item@:hover .downloadButton.downloadIconRetry:active {
   -moz-image-region: rect(32px, 64px, 48px, 48px);
 }
--- a/devtools/client/shared/widgets/Spectrum.js
+++ b/devtools/client/shared/widgets/Spectrum.js
@@ -9,59 +9,60 @@ const EventEmitter = require("devtools/s
 /**
  * Spectrum creates a color picker widget in any container you give it.
  *
  * Simple usage example:
  *
  * const {Spectrum} = require("devtools/client/shared/widgets/Spectrum");
  * let s = new Spectrum(containerElement, [255, 126, 255, 1]);
  * s.on("changed", (event, rgba, color) => {
- *   console.log("rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ", " + rgba[3] + ")");
+ *   console.log("rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ", " +
+ *     rgba[3] + ")");
  * });
  * s.show();
  * s.destroy();
  *
  * Note that the color picker is hidden by default and you need to call show to
  * make it appear. This 2 stages initialization helps in cases you are creating
  * the color picker in a parent element that hasn't been appended anywhere yet
  * or that is hidden. Calling show() when the parent element is appended and
  * visible will allow spectrum to correctly initialize its various parts.
  *
  * Fires the following events:
  * - changed : When the user changes the current color
  */
 function Spectrum(parentEl, rgb) {
   EventEmitter.decorate(this);
 
-  this.element = parentEl.ownerDocument.createElement('div');
+  this.element = parentEl.ownerDocument.createElement("div");
   this.parentEl = parentEl;
 
   this.element.className = "spectrum-container";
-  this.element.innerHTML = [
-    "<div class='spectrum-top'>",
-      "<div class='spectrum-fill'></div>",
-      "<div class='spectrum-top-inner'>",
-        "<div class='spectrum-color spectrum-box'>",
-          "<div class='spectrum-sat'>",
-            "<div class='spectrum-val'>",
-              "<div class='spectrum-dragger'></div>",
-            "</div>",
-          "</div>",
-        "</div>",
-        "<div class='spectrum-hue spectrum-box'>",
-          "<div class='spectrum-slider spectrum-slider-control'></div>",
-        "</div>",
-      "</div>",
-    "</div>",
-    "<div class='spectrum-alpha spectrum-checker spectrum-box'>",
-      "<div class='spectrum-alpha-inner'>",
-        "<div class='spectrum-alpha-handle spectrum-slider-control'></div>",
-      "</div>",
-    "</div>",
-  ].join("");
+  this.element.innerHTML = `
+    <div class="spectrum-top">
+      <div class="spectrum-fill"></div>
+      <div class="spectrum-top-inner">
+        <div class="spectrum-color spectrum-box">
+          <div class="spectrum-sat">
+            <div class="spectrum-val">
+              <div class="spectrum-dragger"></div>
+            </div>
+          </div>
+        </div>
+        <div class="spectrum-hue spectrum-box">
+          <div class="spectrum-slider spectrum-slider-control"></div>
+        </div>
+      </div>
+    </div>
+    <div class="spectrum-alpha spectrum-checker spectrum-box">
+      <div class="spectrum-alpha-inner">
+        <div class="spectrum-alpha-handle spectrum-slider-control"></div>
+      </div>
+    </div>
+  `;
 
   this.onElementClick = this.onElementClick.bind(this);
   this.element.addEventListener("click", this.onElementClick, false);
 
   this.parentEl.appendChild(this.element);
 
   this.slider = this.element.querySelector(".spectrum-hue");
   this.slideHelper = this.element.querySelector(".spectrum-slider");
@@ -89,42 +90,42 @@ Spectrum.hsvToRgb = function(h, s, v, a)
 
   let i = Math.floor(h * 6);
   let f = h * 6 - i;
   let p = v * (1 - s);
   let q = v * (1 - f * s);
   let t = v * (1 - (1 - f) * s);
 
   switch(i % 6) {
-    case 0: r = v, g = t, b = p; break;
-    case 1: r = q, g = v, b = p; break;
-    case 2: r = p, g = v, b = t; break;
-    case 3: r = p, g = q, b = v; break;
-    case 4: r = t, g = p, b = v; break;
-    case 5: r = v, g = p, b = q; break;
+    case 0: r = v; g = t; b = p; break;
+    case 1: r = q; g = v; b = p; break;
+    case 2: r = p; g = v; b = t; break;
+    case 3: r = p; g = q; b = v; break;
+    case 4: r = t; g = p; b = v; break;
+    case 5: r = v; g = p; b = q; break;
   }
 
   return [r * 255, g * 255, b * 255, a];
 };
 
 Spectrum.rgbToHsv = function(r, g, b, a) {
   r = r / 255;
   g = g / 255;
   b = b / 255;
 
   let max = Math.max(r, g, b), min = Math.min(r, g, b);
   let h, s, v = max;
 
   let d = max - min;
   s = max == 0 ? 0 : d / max;
 
-  if(max == min) {
-    h = 0; // achromatic
-  }
-  else {
+  if (max == min) {
+    // achromatic
+    h = 0;
+  } else {
     switch(max) {
       case r: h = (g - b) / d + (g < b ? 6 : 0); break;
       case g: h = (b - r) / d + 2; break;
       case b: h = (r - g) / d + 4; break;
     }
     h /= 6;
   }
   return [h, s, v, a];
@@ -215,32 +216,35 @@ Spectrum.draggable = function(element, o
 };
 
 Spectrum.prototype = {
   set rgb(color) {
     this.hsv = Spectrum.rgbToHsv(color[0], color[1], color[2], color[3]);
   },
 
   get rgb() {
-    let rgb = Spectrum.hsvToRgb(this.hsv[0], this.hsv[1], this.hsv[2], this.hsv[3]);
-    return [Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2]), Math.round(rgb[3]*100)/100];
+    let rgb = Spectrum.hsvToRgb(this.hsv[0], this.hsv[1], this.hsv[2],
+      this.hsv[3]);
+    return [Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2]),
+      Math.round(rgb[3] * 100) / 100];
   },
 
   get rgbNoSatVal() {
     let rgb = Spectrum.hsvToRgb(this.hsv[0], 1, 1);
     return [Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2]), rgb[3]];
   },
 
   get rgbCssString() {
     let rgb = this.rgb;
-    return "rgba(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ", " + rgb[3] + ")";
+    return "rgba(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ", " +
+      rgb[3] + ")";
   },
 
   show: function() {
-    this.element.classList.add('spectrum-show');
+    this.element.classList.add("spectrum-show");
 
     this.slideHeight = this.slider.offsetHeight;
     this.dragWidth = this.dragger.offsetWidth;
     this.dragHeight = this.dragger.offsetHeight;
     this.dragHelperHeight = this.dragHelper.offsetHeight;
     this.slideHelperHeight = this.slideHelper.offsetHeight;
     this.alphaSliderWidth = this.alphaSliderInner.offsetWidth;
     this.alphaSliderHelperWidth = this.alphaSliderHelper.offsetWidth;
@@ -271,64 +275,68 @@ Spectrum.prototype = {
     this.onChange();
   },
 
   onChange: function() {
     this.emit("changed", this.rgb, this.rgbCssString);
   },
 
   updateHelperLocations: function() {
-    // If the UI hasn't been shown yet then none of the dimensions will be correct
-    if (!this.element.classList.contains('spectrum-show'))
+    // If the UI hasn't been shown yet then none of the dimensions will be
+    // correct
+    if (!this.element.classList.contains("spectrum-show")) {
       return;
+    }
 
     let h = this.hsv[0];
     let s = this.hsv[1];
     let v = this.hsv[2];
 
     // Placing the color dragger
     let dragX = s * this.dragWidth;
     let dragY = this.dragHeight - (v * this.dragHeight);
-    let helperDim = this.dragHelperHeight/2;
+    let helperDim = this.dragHelperHeight / 2;
 
     dragX = Math.max(
       -helperDim,
       Math.min(this.dragWidth - helperDim, dragX - helperDim)
     );
     dragY = Math.max(
       -helperDim,
       Math.min(this.dragHeight - helperDim, dragY - helperDim)
     );
 
     this.dragHelper.style.top = dragY + "px";
     this.dragHelper.style.left = dragX + "px";
 
     // Placing the hue slider
-    let slideY = (h * this.slideHeight) - this.slideHelperHeight/2;
+    let slideY = (h * this.slideHeight) - this.slideHelperHeight / 2;
     this.slideHelper.style.top = slideY + "px";
 
     // Placing the alpha slider
-    let alphaSliderX = (this.hsv[3] * this.alphaSliderWidth) - (this.alphaSliderHelperWidth / 2);
+    let alphaSliderX = (this.hsv[3] * this.alphaSliderWidth) -
+      (this.alphaSliderHelperWidth / 2);
     this.alphaSliderHelper.style.left = alphaSliderX + "px";
   },
 
   updateUI: function() {
     this.updateHelperLocations();
 
     let rgb = this.rgb;
     let rgbNoSatVal = this.rgbNoSatVal;
 
-    let flatColor = "rgb(" + rgbNoSatVal[0] + ", " + rgbNoSatVal[1] + ", " + rgbNoSatVal[2] + ")";
-    let fullColor = "rgba(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ", " + rgb[3] + ")";
+    let flatColor = "rgb(" + rgbNoSatVal[0] + ", " + rgbNoSatVal[1] + ", " +
+      rgbNoSatVal[2] + ")";
 
     this.dragger.style.backgroundColor = flatColor;
 
-    var rgbNoAlpha = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")";
-    var rgbAlpha0 = "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ", 0)";
-    var alphaGradient = "linear-gradient(to right, " + rgbAlpha0 + ", " + rgbNoAlpha + ")";
+    let rgbNoAlpha = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")";
+    let rgbAlpha0 = "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ", 0)";
+    let alphaGradient = "linear-gradient(to right, " + rgbAlpha0 + ", " +
+      rgbNoAlpha + ")";
     this.alphaSliderInner.style.background = alphaGradient;
   },
 
   destroy: function() {
     this.element.removeEventListener("click", this.onElementClick, false);
 
     this.parentEl.removeChild(this.element);
 
--- a/devtools/client/webconsole/net/components/net-info-body.css
+++ b/devtools/client/webconsole/net/components/net-info-body.css
@@ -104,14 +104,13 @@
   border-color: var(--net-border);
 }
 
 .theme-firebug .netInfoBody > .tabs .tabs-menu-item.is-active a,
 .theme-firebug .netInfoBody > .tabs .tabs-menu-item.is-active:hover a,
 .theme-firebug .netInfoBody > .tabs .tabs-menu-item.is-active a:focus {
   border: 1px solid var(--net-border);
   border-bottom-color: transparent;
-  border-color: var(--net-border);
 }
 
 .theme-firebug .netInfoBody > .tabs .tabs-menu-item:hover a {
   border-bottom-color: transparent;
 }
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -300,19 +300,16 @@ pref("browser.search.geoSpecificDefaults
 pref("browser.search.defaultenginename.US", "chrome://browser/locale/region.properties");
 pref("browser.search.order.US.1", "chrome://browser/locale/region.properties");
 pref("browser.search.order.US.2", "chrome://browser/locale/region.properties");
 pref("browser.search.order.US.3", "chrome://browser/locale/region.properties");
 
 // disable updating
 pref("browser.search.update", false);
 
-// enable tracking protection for private browsing
-pref("privacy.trackingprotection.pbmode.enabled", true);
-
 // disable search suggestions by default
 pref("browser.search.suggest.enabled", false);
 pref("browser.search.suggest.prompted", false);
 
 // tell the search service that we don't really expose the "current engine"
 pref("browser.search.noCurrentEngine", true);
 
 // Control media casting & mirroring features
@@ -644,56 +641,24 @@ pref("media.android-media-codec.preferre
 
 // Enable MSE
 pref("media.mediasource.enabled", true);
 
 // optimize images memory usage
 pref("image.downscale-during-decode.enabled", true);
 
 #ifdef MOZ_SAFE_BROWSING
-pref("browser.safebrowsing.enabled", true);
-pref("browser.safebrowsing.malware.enabled", true);
 pref("browser.safebrowsing.downloads.enabled", false);
 pref("browser.safebrowsing.downloads.remote.enabled", false);
-pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
-pref("browser.safebrowsing.downloads.remote.url", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
-pref("browser.safebrowsing.downloads.remote.block_dangerous",            true);
-pref("browser.safebrowsing.downloads.remote.block_dangerous_host",       true);
-pref("browser.safebrowsing.downloads.remote.block_potentially_unwanted", false);
-pref("browser.safebrowsing.downloads.remote.block_uncommon",             false);
-pref("browser.safebrowsing.debug", false);
-
-pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-downloadwhite-digest256,goog-phish-shavar,goog-malware-shavar,goog-unwanted-shavar");
-pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
-pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
-pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
-
-pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
-pref("browser.safebrowsing.reportPhishURL", "https://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%&url=");
-pref("browser.safebrowsing.reportMalwareMistakeURL", "https://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%&url=");
 
 pref("browser.safebrowsing.id", @MOZ_APP_UA_NAME@);
 
 // Name of the about: page contributed by safebrowsing to handle display of error
 // pages on phishing/malware hits.  (bug 399233)
 pref("urlclassifier.alternate_error_page", "blocked");
-
-// The number of random entries to send with a gethash request.
-pref("urlclassifier.gethashnoise", 4);
-
-// Gethash timeout for Safebrowsing.
-pref("urlclassifier.gethash.timeout_ms", 5000);
-
-// If an urlclassifier table has not been updated in this number of seconds,
-// a gethash request will be forced to check that the result is still in
-// the database.
-pref("urlclassifier.max-complete-age", 2700);
-
-// Tables for application reputation.
-pref("urlclassifier.downloadBlockTable", "goog-badbinurl-shavar");
 #endif
 
 // True if this is the first time we are showing about:firstrun
 pref("browser.firstrun.show.uidiscovery", true);
 pref("browser.firstrun.show.localepicker", false);
 
 // True if you always want dump() to work
 //
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testBrowserDatabaseHelperUpgrades.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testBrowserDatabaseHelperUpgrades.java
@@ -42,16 +42,21 @@ import java.util.ArrayList;
  *   * Copy the current version of the database into (robocop-assets)/browser_db_upgrade/v##.db database. You can do
  * this via Margaret's copy profile addon - take browser.db from the profile directory. This db copy should contain a
  * used profile - e.g. history items, bookmarks. A good way to get a used profile is to sign into sync.
  *   * MAKE SURE YOU COPY YOUR DB FIRST. Then make your changes to the DB schema code.
  *   * Test!
  *   * Note: when the application starts for testing, it may need to upgrade the database from your existing version. If
  * this fails, the application will crash and the test may fail to start.
  *
+ * IMPORTANT:
+ * Test DBs must be created on the oldest version of Android that is currently supported. SQLite
+ * is not forwards compatible. E.g. uploading a DB created on a 6.0 device will cause failures
+ * when robocop tests running on 4.3 are unable to load it.
+ *
  * Implementation inspired by:
  *   http://riggaroo.co.za/automated-testing-sqlite-database-upgrades-android/
  */
 public class testBrowserDatabaseHelperUpgrades extends UITest {
     private static final int TEST_FROM_VERSION = 27; // We only started testing on this version.
 
     private ArrayList<File> temporaryDbFiles;
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4952,28 +4952,64 @@ pref("dom.voicemail.enabled", false);
 pref("dom.voicemail.defaultServiceId", 0);
 
 // DOM Inter-App Communication API.
 pref("dom.inter-app-communication-api.enabled", false);
 
 // Disable mapped array buffer by default.
 pref("dom.mapped_arraybuffer.enabled", false);
 
+#ifdef MOZ_SAFE_BROWSING
 // The tables used for Safebrowsing phishing and malware checks.
 pref("urlclassifier.malwareTable", "goog-malware-shavar,goog-unwanted-shavar,test-malware-simple,test-unwanted-simple");
 pref("urlclassifier.phishTable", "goog-phish-shavar,test-phish-simple");
 pref("urlclassifier.downloadBlockTable", "");
 pref("urlclassifier.downloadAllowTable", "");
 pref("urlclassifier.disallow_completions", "test-malware-simple,test-phish-simple,test-unwanted-simple,test-track-simple,test-trackwhite-simple,test-forbid-simple,goog-downloadwhite-digest256,mozstd-track-digest256,mozstd-trackwhite-digest256,mozfull-track-digest256,test-block-simple,mozplugin-block-digest256,mozplugin2-block-digest256");
 
 // The table and update/gethash URLs for Safebrowsing phishing and malware
 // checks.
 pref("urlclassifier.trackingTable", "test-track-simple,mozstd-track-digest256");
 pref("urlclassifier.trackingWhitelistTable", "test-trackwhite-simple,mozstd-trackwhite-digest256");
 
+// Tables for application reputation.
+pref("urlclassifier.downloadBlockTable", "goog-badbinurl-shavar");
+
+// The number of random entries to send with a gethash request.
+pref("urlclassifier.gethashnoise", 4);
+
+// Gethash timeout for Safebrowsing.	
+pref("urlclassifier.gethash.timeout_ms", 5000);
+
+// If an urlclassifier table has not been updated in this number of seconds,
+// a gethash request will be forced to check that the result is still in
+// the database.
+pref("urlclassifier.max-complete-age", 2700);
+
+pref("browser.safebrowsing.enabled", true);
+pref("browser.safebrowsing.malware.enabled", true);
+
+pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
+pref("browser.safebrowsing.downloads.remote.url", "https://sb-ssl.google.com/safebrowsing/clientreport/download?key=%GOOGLE_API_KEY%");
+pref("browser.safebrowsing.downloads.remote.block_dangerous",            true);
+pref("browser.safebrowsing.downloads.remote.block_dangerous_host",       true);
+pref("browser.safebrowsing.downloads.remote.block_potentially_unwanted", false);
+pref("browser.safebrowsing.downloads.remote.block_uncommon",             false);
+pref("browser.safebrowsing.debug", false);
+
+pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-downloadwhite-digest256,goog-phish-shavar,goog-malware-shavar,goog-unwanted-shavar");
+pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
+pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2");
+pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
+
+pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
+pref("browser.safebrowsing.reportPhishURL", "https://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%&url=");
+pref("browser.safebrowsing.reportMalwareMistakeURL", "https://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%&url=");
+
+
 // The table and global pref for blocking access to sites forbidden by policy
 pref("browser.safebrowsing.forbiddenURIs.enabled", false);
 pref("urlclassifier.forbiddenTable", "test-forbid-simple");
 
 // The table and global pref for blocking plugin content
 pref("browser.safebrowsing.blockedURIs.enabled", false);
 pref("urlclassifier.blockedTable", "test-block-simple,mozplugin-block-digest256");
 
@@ -4986,16 +5022,17 @@ pref("browser.safebrowsing.provider.mozi
 // to lookup the localized name in preferences.properties.
 pref("browser.safebrowsing.provider.mozilla.lists.mozstd.name", "mozstdName");
 pref("browser.safebrowsing.provider.mozilla.lists.mozstd.description", "mozstdDesc");
 pref("browser.safebrowsing.provider.mozilla.lists.mozfull.name", "mozfullName");
 pref("browser.safebrowsing.provider.mozilla.lists.mozfull.description", "mozfullDesc");
 
 // Allow users to ignore Safe Browsing warnings.
 pref("browser.safebrowsing.allowOverride", true);
+#endif
 
 // Turn off Spatial navigation by default.
 pref("snav.enabled", false);
 
 // New implementation to unify touch-caret and selection-carets.
 pref("layout.accessiblecaret.enabled", false);
 
 // CSS attributes of the AccessibleCaret in CSS pixels.
--- a/toolkit/components/passwordmgr/content/passwordManager.js
+++ b/toolkit/components/passwordmgr/content/passwordManager.js
@@ -1,15 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*** =================== SAVED SIGNONS CODE =================== ***/
 
 Cu.import("resource://gre/modules/AppConstants.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask",
+                                  "resource://gre/modules/DeferredTask.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
+                                  "resource://gre/modules/PlacesUtils.jsm");
 
 var kSignonBundle;
 var showingPasswords = false;
 var dateFormatter = new Intl.DateTimeFormat(undefined,
                       { day: "numeric", month: "short", year: "numeric" });
 var dateAndTimeFormatter = new Intl.DateTimeFormat(undefined,
                              { day: "numeric", month: "short", year: "numeric",
                                hour: "numeric", minute: "numeric" });
@@ -39,26 +45,56 @@ function SignonsStartup() {
 }
 
 function setFilter(aFilterString) {
   document.getElementById("filter").value = aFilterString;
   _filterPasswords();
 }
 
 var signonsTreeView = {
-  _filterSet : [],
-  _lastSelectedRanges : [],
+  // Keep track of which favicons we've fetched or started fetching.
+  // Maps a login origin to a favicon URL.
+  _faviconMap: new Map(),
+  _filterSet: [],
+  // Coalesce invalidations to avoid repeated flickering.
+  _invalidateTask: new DeferredTask(() => {
+    signonsTree.treeBoxObject.invalidateColumn(signonsTree.columns.siteCol);
+  }, 10),
+  _lastSelectedRanges: [],
   selection: null,
 
-  rowCount : 0,
-  setTree : function(tree) {},
-  getImageSrc : function(row,column) {},
-  getProgressMode : function(row,column) {},
-  getCellValue : function(row,column) {},
-  getCellText : function(row,column) {
+  rowCount: 0,
+  setTree(tree) {},
+  getImageSrc(row, column) {
+    if (column.element.getAttribute("id") !== "siteCol") {
+      return "";
+    }
+
+    const signon = this._filterSet.length ? this._filterSet[row] : signons[row];
+
+    // We already have the favicon URL or we started to fetch (value is null).
+    if (this._faviconMap.has(signon.hostname)) {
+      return this._faviconMap.get(signon.hostname);
+    }
+
+    // Record the fact that we already starting fetching a favicon for this
+    // origin in order to avoid multiple requests for the same origin.
+    this._faviconMap.set(signon.hostname, null);
+
+    PlacesUtils.promiseFaviconLinkUrl(signon.hostname)
+      .then(faviconURI => {
+        this._faviconMap.set(signon.hostname, faviconURI.spec);
+        this._invalidateTask.arm();
+      }).catch(Cu.reportError);
+
+    return "";
+  },
+  getProgressMode(row, column) {},
+  getCellValue(row, column) {},
+  getCellText(row, column) {
     var time;
     var signon = this._filterSet.length ? this._filterSet[row] : signons[row];
     switch (column.id) {
       case "siteCol":
         return signon.httpRealm ?
                (signon.hostname + " (" + signon.httpRealm + ")"):
                signon.hostname;
       case "userCol":
@@ -75,35 +111,35 @@ var signonsTreeView = {
         time = new Date(signon.timePasswordChanged);
         return dateFormatter.format(time);
       case "timesUsedCol":
         return signon.timesUsed;
       default:
         return "";
     }
   },
-  isEditable : function(row, col) {
+  isEditable(row, col) {
     if (col.id == "userCol" || col.id == "passwordCol") {
       return true;
     }
     return false;
   },
-  isSeparator : function(index) { return false; },
-  isSorted : function() { return false; },
-  isContainer : function(index) { return false; },
-  cycleHeader : function(column) {},
-  getRowProperties : function(row) { return ""; },
-  getColumnProperties : function(column) { return ""; },
-  getCellProperties : function(row,column) {
+  isSeparator(index) { return false; },
+  isSorted() { return false; },
+  isContainer(index) { return false; },
+  cycleHeader(column) {},
+  getRowProperties(row) { return ""; },
+  getColumnProperties(column) { return ""; },
+  getCellProperties(row, column) {
     if (column.element.getAttribute("id") == "siteCol")
       return "ltr";
 
     return "";
   },
-  setCellText : function(row, col, value) {
+  setCellText(row, col, value) {
     // If there is a filter, _filterSet needs to be used, otherwise signons is used.
     let table = signonsTreeView._filterSet.length ? signonsTreeView._filterSet : signons;
     function _editLogin(field) {
       if (value == table[row][field]) {
         return;
       }
       let existingLogin = table[row].clone();
       table[row][field] = value;
@@ -219,17 +255,17 @@ function AskUserShowPasswords() {
   // Confirm the user wants to display passwords
   return prompter.confirmEx(window,
           null,
           kSignonBundle.getString("noMasterPasswordPrompt"), prompter.STD_YES_NO_BUTTONS,
           null, null, null, null, dummy) == 0;    // 0=="Yes" button
 }
 
 function FinalizeSignonDeletions(syncNeeded) {
-  for (var s=0; s<deletedSignons.length; s++) {
+  for (var s = 0; s < deletedSignons.length; s++) {
     passwordmanager.removeLogin(deletedSignons[s]);
     Services.telemetry.getHistogramById("PWMGR_MANAGE_DELETED").add(1);
   }
   // If the deletion has been performed in a filtered view, reflect the deletion in the unfiltered table.
   // See bug 405389.
   if (syncNeeded) {
     try {
       signons = passwordmanager.getAllLogins();
@@ -355,18 +391,17 @@ function SignonSaveState() {
   var rangeCount = seln.getRangeCount();
   for (var i = 0; i < rangeCount; ++i) {
     var min = {}; var max = {};
     seln.getRangeAt(i, min, max);
     signonsTreeView._lastSelectedRanges.push({ min: min.value, max: max.value });
   }
 }
 
-function _filterPasswords()
-{
+function _filterPasswords() {
   var filter = document.getElementById("filter").value;
   if (filter == "") {
     SignonClearFilter();
     return;
   }
 
   var newFilterSet = FilterPasswords(filter, signonsTreeView);
   if (!signonsTreeView._filterSet.length) {
--- a/toolkit/themes/osx/global/jar.mn
+++ b/toolkit/themes/osx/global/jar.mn
@@ -24,17 +24,16 @@ toolkit.jar:
   skin/classic/global/groupbox.css
   skin/classic/global/linkTree.css
   skin/classic/global/listbox.css
   skin/classic/global/menu.css
   skin/classic/global/menulist.css
 * skin/classic/global/notification.css
   skin/classic/global/netError.css
   skin/classic/global/numberbox.css
-  skin/classic/global/passwordmgr.css
   skin/classic/global/popup.css
   skin/classic/global/preferences.css
   skin/classic/global/progressmeter.css
   skin/classic/global/radio.css
   skin/classic/global/resizer.css
   skin/classic/global/richlistbox.css
   skin/classic/global/scrollbars.css                                 (nativescrollbars.css)
   skin/classic/global/scale.css
deleted file mode 100644
--- a/toolkit/themes/osx/global/passwordmgr.css
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-.contentPane {
-  margin: 9px 8px 5px 8px;
-}
-
-.actionButtons {
-  margin: 0px 3px 6px 3px !important;
-}
--- a/toolkit/themes/shared/jar.inc.mn
+++ b/toolkit/themes/shared/jar.inc.mn
@@ -41,16 +41,17 @@ toolkit.jar:
   skin/classic/global/menu/shared-menu-check-active.svg    (../../shared/menu-check-active.svg)
   skin/classic/global/menu/shared-menu-check-black.svg     (../../shared/menu-check-black.svg)
   skin/classic/global/menu/shared-menu-check-hover.svg     (../../shared/menu-check-hover.svg)
   skin/classic/global/in-content/check.svg                 (../../shared/in-content/check.svg)
   skin/classic/global/in-content/check-partial.svg         (../../shared/in-content/check-partial.svg)
   skin/classic/global/in-content/dropdown.svg              (../../shared/in-content/dropdown.svg)
   skin/classic/global/in-content/help-glyph.svg            (../../shared/in-content/help-glyph.svg)
   skin/classic/global/in-content/radio.svg                 (../../shared/in-content/radio.svg)
+  skin/classic/global/passwordmgr.css                      (../../shared/passwordmgr.css)
   skin/classic/global/reader/RM-Close-24x24.svg            (../../shared/reader/RM-Close-24x24.svg)
   skin/classic/global/reader/RM-Minus-24x24.svg            (../../shared/reader/RM-Minus-24x24.svg)
   skin/classic/global/reader/RM-Plus-24x24.svg             (../../shared/reader/RM-Plus-24x24.svg)
   skin/classic/global/reader/RM-Type-Controls-24x24.svg    (../../shared/reader/RM-Type-Controls-24x24.svg)
   skin/classic/global/reader/RM-Type-Controls-Arrow.svg    (../../shared/reader/RM-Type-Controls-Arrow.svg)
 #ifdef MOZ_PLACES
   skin/classic/mozapps/places/defaultFavicon.png           (../../shared/places/defaultFavicon.png)
   skin/classic/mozapps/places/defaultFavicon@2x.png        (../../shared/places/defaultFavicon@2x.png)
--- a/toolkit/themes/shared/non-mac.jar.inc.mn
+++ b/toolkit/themes/shared/non-mac.jar.inc.mn
@@ -13,17 +13,16 @@
   skin/classic/global/arrow.css                            (../../windows/global/arrow.css)
   skin/classic/global/customizeToolbar.css                 (../../windows/global/customizeToolbar.css)
   skin/classic/global/datetimepicker.css                   (../../windows/global/datetimepicker.css)
   skin/classic/global/dialog.css                           (../../windows/global/dialog.css)
   skin/classic/global/expander.css                         (../../windows/global/expander.css)
   skin/classic/global/filefield.css                        (../../windows/global/filefield.css)
   skin/classic/global/globalBindings.xml                   (../../windows/global/globalBindings.xml)
   skin/classic/global/linkTree.css                         (../../windows/global/linkTree.css)
-  skin/classic/global/passwordmgr.css                      (../../windows/global/passwordmgr.css)
   skin/classic/global/progressmeter.css                    (../../windows/global/progressmeter.css)
   skin/classic/global/resizer.css                          (../../windows/global/resizer.css)
   skin/classic/global/richlistbox.css                      (../../windows/global/richlistbox.css)
   skin/classic/global/scale.css                            (../../windows/global/scale.css)
 #ifndef MOZ_THEME_FASTSTRIPE
   skin/classic/global/scrollbars.css                       (../../windows/global/xulscrollbars.css)
 #endif
   skin/classic/global/spinbuttons.css                      (../../windows/global/spinbuttons.css)
rename from toolkit/themes/windows/global/passwordmgr.css
rename to toolkit/themes/shared/passwordmgr.css
--- a/toolkit/themes/windows/global/passwordmgr.css
+++ b/toolkit/themes/shared/passwordmgr.css
@@ -6,8 +6,21 @@
 
 .contentPane {
   margin: 9px 8px 5px 8px;
 }
 
 .actionButtons {
   margin: 0px 3px 6px 3px !important;
 }
+
+treechildren::-moz-tree-image(siteCol) {
+  list-style-image: url(chrome://mozapps/skin/places/defaultFavicon.png);
+  width: 16px;
+  height: 16px;
+  -moz-margin-end: 5px;
+}
+
+@media (min-resolution: 1.1dppx) {
+  treechildren::-moz-tree-image(siteCol) {
+    list-style-image: url(chrome://mozapps/skin/places/defaultFavicon@2x.png);
+  }
+}