Bug 1043797: extended popup notifications to create a generic doorhanger for all security notifications incl. mixed content r=adw
authorGeorgios Kontaxis <gkontaxis@mozilla.com>
Fri, 22 Aug 2014 15:34:25 -0700
changeset 201234 456567bc1a2b39a01df184f30a5178e2c17adad1
parent 201233 d5cb280f36bfc428c16e406e5203bc78450ac15f
child 201235 cb7e88a77a480bb20eb336d2cfd766185c7d2b9c
push id27365
push userryanvm@gmail.com
push dateMon, 25 Aug 2014 15:24:30 +0000
treeherdermozilla-central@23c70481ed91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw
bugs1043797
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1043797: extended popup notifications to create a generic doorhanger for all security notifications incl. mixed content r=adw
browser/base/content/browser.css
browser/base/content/browser.js
browser/base/content/browser.xul
browser/base/content/popup-notifications.inc
browser/base/content/test/general/browser_bug822367.js
browser/base/content/test/general/browser_bug902156.js
browser/base/content/test/general/browser_bug906190.js
browser/base/content/test/general/browser_mixedcontent_securityflags.js
browser/base/content/urlbarBindings.xml
browser/devtools/webconsole/test/browser_webconsole_block_mixedcontent_securityerrors.js
browser/locales/en-US/chrome/browser/browser.dtd
browser/locales/en-US/chrome/browser/browser.properties
browser/themes/linux/bad-content-blocked-16.png
browser/themes/linux/bad-content-blocked-64.png
browser/themes/linux/browser.css
browser/themes/linux/jar.mn
browser/themes/linux/mixed-content-blocked-16.png
browser/themes/linux/mixed-content-blocked-64.png
browser/themes/osx/bad-content-blocked-16.png
browser/themes/osx/bad-content-blocked-16@2x.png
browser/themes/osx/bad-content-blocked-64.png
browser/themes/osx/bad-content-blocked-64@2x.png
browser/themes/osx/browser.css
browser/themes/osx/jar.mn
browser/themes/osx/mixed-content-blocked-16.png
browser/themes/osx/mixed-content-blocked-16@2x.png
browser/themes/osx/mixed-content-blocked-64.png
browser/themes/osx/mixed-content-blocked-64@2x.png
browser/themes/shared/badcontent-doorhanger.inc.css
browser/themes/windows/bad-content-blocked-16.png
browser/themes/windows/bad-content-blocked-64.png
browser/themes/windows/browser.css
browser/themes/windows/jar.mn
browser/themes/windows/mixed-content-blocked-16.png
browser/themes/windows/mixed-content-blocked-64.png
content/base/test/browser_bug902350.js
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -693,16 +693,20 @@ window[chromehidden~="toolbar"] toolbar:
 #addon-progress-notification {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#addon-progress-notification");
 }
 
 #identity-request-notification {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#identity-request-notification");
 }
 
+#bad-content-notification {
+  -moz-binding: url("chrome://browser/content/urlbarBindings.xml#bad-content-notification");
+}
+
 #click-to-play-plugins-notification {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#click-to-play-plugins-notification");
 }
 
 .plugin-popupnotification-centeritem {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#plugin-popupnotification-center-item");
 }
 
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6482,58 +6482,37 @@ var gIdentityHandler = {
         this.setMode(this.IDENTITY_MODE_MIXED_DISPLAY_LOADED);
       }
     } else {
       this.setMode(this.IDENTITY_MODE_UNKNOWN);
     }
 
     // Ensure the doorhanger is shown when mixed active content is blocked.
     if (state & nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT)
-      this.showMixedContentDoorhanger();
-  },
-
-  /**
-   * Display the Mixed Content Blocker doohanger, providing an option
-   * to the user to override mixed content blocking
-   */
-  showMixedContentDoorhanger : function() {
+      this.showBadContentDoorhanger(state);
+  },
+
+  showBadContentDoorhanger : function(state) {
+    var currentNotification =
+      PopupNotifications.getNotification("bad-content",
+        gBrowser.selectedBrowser);
+
     // If we've already got an active notification, bail out to avoid showing it repeatedly.
-    if (PopupNotifications.getNotification("mixed-content-blocked", gBrowser.selectedBrowser))
+    if (currentNotification && currentNotification.options.state == state)
       return;
 
-    let brandBundle = document.getElementById("bundle_brand");
-    let brandShortName = brandBundle.getString("brandShortName");
-    let messageString = gNavigatorBundle.getFormattedString("mixedContentBlocked.message", [brandShortName]);
-    let action = {
-      label: gNavigatorBundle.getString("mixedContentBlocked.keepBlockingButton.label"),
-      accessKey: gNavigatorBundle.getString("mixedContentBlocked.keepBlockingButton.accesskey"),
-      callback: function() { /* NOP */ }
+    let options = {
+      /* keep doorhanger collapsed */
+      dismissed: true,
+      state: state
     };
-    let secondaryActions = [
-      {
-        label: gNavigatorBundle.getString("mixedContentBlocked.unblock.label"),
-        accessKey: gNavigatorBundle.getString("mixedContentBlocked.unblock.accesskey"),
-        callback: function() {
-          // Use telemetry to measure how often unblocking happens
-          const kMIXED_CONTENT_UNBLOCK_EVENT = 2;
-          let histogram =
-            Services.telemetry.getHistogramById("MIXED_CONTENT_UNBLOCK_COUNTER");
-          histogram.add(kMIXED_CONTENT_UNBLOCK_EVENT);
-          // Reload the page with the content unblocked
-          BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT);
-        }
-      }
-    ];
-    let options = {
-      dismissed: true,
-      learnMoreURL: Services.urlFormatter.formatURLPref("app.support.baseURL") + "mixed-content",
-    };
-    PopupNotifications.show(gBrowser.selectedBrowser, "mixed-content-blocked",
-                            messageString, "mixed-content-blocked-notification-icon",
-                            action, secondaryActions, options);
+
+    PopupNotifications.show(gBrowser.selectedBrowser, "bad-content",
+                            "", "bad-content-blocked-notification-icon",
+                            null, null, options);
   },
 
   /**
    * Return the eTLD+1 version of the current hostname
    */
   getEffectiveHost : function() {
     if (!this._IDNService)
       this._IDNService = Cc["@mozilla.org/network/idn-service;1"]
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -719,17 +719,17 @@
                 <image id="geo-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="addons-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="indexedDB-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="password-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="webapps-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="plugins-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="web-notifications-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="plugin-install-notification-icon" class="notification-anchor-icon" role="button"/>
-                <image id="mixed-content-blocked-notification-icon" class="notification-anchor-icon" role="button"/>
+                <image id="bad-content-blocked-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="webRTC-shareDevices-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="webRTC-sharingDevices-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="webRTC-shareMicrophone-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="webRTC-sharingMicrophone-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="webRTC-shareScreen-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="webRTC-sharingScreen-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="pointerLock-notification-icon" class="notification-anchor-icon" role="button"/>
                 <image id="servicesInstall-notification-icon" class="notification-anchor-icon" role="button"/>
--- a/browser/base/content/popup-notifications.inc
+++ b/browser/base/content/popup-notifications.inc
@@ -55,15 +55,8 @@
     </popupnotification>
 
     <popupnotification id="pointerLock-notification" hidden="true">
       <popupnotificationcontent orient="vertical" align="start">
         <separator class="thin"/>
         <label id="pointerLock-cancel" value="&pointerLock.notification.message;"/>
       </popupnotificationcontent>
     </popupnotification>
-
-    <popupnotification id="mixed-content-blocked-notification" hidden="true">
-      <popupnotificationcontent orient="vertical" align="start">
-        <separator/>
-        <description id="mixed-content-blocked-moreinfo">&mixedContentBlocked.moreinfo;</description>
-      </popupnotificationcontent>
-    </popupnotification>
--- a/browser/base/content/test/general/browser_bug822367.js
+++ b/browser/base/content/test/general/browser_bug822367.js
@@ -45,19 +45,20 @@ function test() {
   var url = gHttpTestRoot + "file_bug822367_1.html";
   gTestBrowser.contentWindow.location = url;
 }
 
 // Mixed Script Test
 function MixedTest1A() {
   gTestBrowser.removeEventListener("load", MixedTest1A, true);
   gTestBrowser.addEventListener("load", MixedTest1B, true);
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
-  ok(notification, "Mixed Content Doorhanger didn't appear");
-  notification.secondaryActions[0].callback();
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
+  ok(notification, "Mixed Content Doorhanger did appear");
+  notification.reshow();
+  PopupNotifications.panel.firstChild.disableMixedContentProtection();
 }
 function MixedTest1B() {
   waitForCondition(function() content.document.getElementById('p1').innerHTML == "hello", MixedTest1C, "Waited too long for mixed script to run in Test 1");
 }
 function MixedTest1C() {
   ok(content.document.getElementById('p1').innerHTML == "hello","Mixed script didn't load in Test 1");
   gTestBrowser.removeEventListener("load", MixedTest1B, true);
   MixedTest2();
@@ -66,34 +67,35 @@ function MixedTest1C() {
 //Mixed Display Test - Doorhanger should not appear
 function MixedTest2() {
   gTestBrowser.addEventListener("load", MixedTest2A, true);
   var url = gHttpTestRoot2 + "file_bug822367_2.html";
   gTestBrowser.contentWindow.location = url;
 }
 
 function MixedTest2A() {
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
-  ok(!notification, "Mixed Content Doorhanger appears for mixed display content!");
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
+  ok(!notification, "Mixed Content Doorhanger did not appear for mixed display content!");
   MixedTest3();
 }
 
 // Mixed Script and Display Test - User Override should cause both the script and the image to load.
 function MixedTest3() {
   gTestBrowser.removeEventListener("load", MixedTest2A, true);
   gTestBrowser.addEventListener("load", MixedTest3A, true);
   var url = gHttpTestRoot + "file_bug822367_3.html";
   gTestBrowser.contentWindow.location = url;
 }
 function MixedTest3A() {
   gTestBrowser.removeEventListener("load", MixedTest3A, true);
   gTestBrowser.addEventListener("load", MixedTest3B, true);
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
-  ok(notification, "Mixed Content Doorhanger doesn't appear for test 3");
-  notification.secondaryActions[0].callback();
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
+  ok(notification, "Mixed Content Doorhanger did appear for test 3");
+  notification.reshow();
+  PopupNotifications.panel.firstChild.disableMixedContentProtection();
 }
 function MixedTest3B() {
   waitForCondition(function() content.document.getElementById('p1').innerHTML == "hello", MixedTest3C, "Waited too long for mixed script to run in Test 3");
 }
 function MixedTest3C() {
   waitForCondition(function() content.document.getElementById('p2').innerHTML == "bye", MixedTest3D, "Waited too long for mixed image to load in Test 3");
 }
 function MixedTest3D() {
@@ -107,27 +109,28 @@ function MixedTest4() {
   gTestBrowser.removeEventListener("load", MixedTest3B, true);
   gTestBrowser.addEventListener("load", MixedTest4A, true);
   var url = gHttpTestRoot2 + "file_bug822367_4.html";
   gTestBrowser.contentWindow.location = url;
 }
 function MixedTest4A() {
   gTestBrowser.removeEventListener("load", MixedTest4A, true);
   gTestBrowser.addEventListener("load", MixedTest4B, true);
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
-  ok(notification, "Mixed Content Doorhanger doesn't appear for Test 4");
-  notification.secondaryActions[0].callback();
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
+  ok(notification, "Mixed Content Doorhanger did appear for Test 4");
+  notification.reshow();
+  PopupNotifications.panel.firstChild.disableMixedContentProtection();
 }
 function MixedTest4B() {
   waitForCondition(function() content.document.location == gHttpTestRoot + "file_bug822367_4B.html", MixedTest4C, "Waited too long for mixed script to run in Test 4");
 }
 function MixedTest4C() {
   ok(content.document.location == gHttpTestRoot + "file_bug822367_4B.html", "Location didn't change in test 4");
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
-  ok(notification, "Mixed Content Doorhanger doesn't appear after location change in Test 4");
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
+  ok(notification, "Mixed Content Doorhanger did appear after location change in Test 4");
   waitForCondition(function() content.document.getElementById('p1').innerHTML == "", MixedTest4D, "Mixed script loaded in test 4 after location change!");
 }
 function MixedTest4D() {
   ok(content.document.getElementById('p1').innerHTML == "","p1.innerHTML changed; mixed script loaded after location change in Test 4");
   MixedTest5();
 }
 
 // Mixed script attempts to load in a document.open()
@@ -135,19 +138,20 @@ function MixedTest5() {
   gTestBrowser.removeEventListener("load", MixedTest4B, true);
   gTestBrowser.addEventListener("load", MixedTest5A, true);
   var url = gHttpTestRoot + "file_bug822367_5.html";
   gTestBrowser.contentWindow.location = url;
 }
 function MixedTest5A() {
   gTestBrowser.removeEventListener("load", MixedTest5A, true);
   gTestBrowser.addEventListener("load", MixedTest5B, true);
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
-  ok(notification, "Mixed Content Doorhanger doesn't appear for Test 5");
-  notification.secondaryActions[0].callback();
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
+  ok(notification, "Mixed Content Doorhanger did appear for Test 5");
+  notification.reshow();
+  PopupNotifications.panel.firstChild.disableMixedContentProtection();
 }
 function MixedTest5B() {
   waitForCondition(function() content.document.getElementById('p1').innerHTML == "hello", MixedTest5C, "Waited too long for mixed script to run in Test 5");
 }
 function MixedTest5C() {
   ok(content.document.getElementById('p1').innerHTML == "hello","Mixed script didn't load in Test 5");
   MixedTest6();
 }
@@ -156,24 +160,25 @@ function MixedTest5C() {
 function MixedTest6() {
   gTestBrowser.removeEventListener("load", MixedTest5B, true);
   gTestBrowser.addEventListener("load", MixedTest6A, true);
   var url = gHttpTestRoot2 + "file_bug822367_6.html";
   gTestBrowser.contentWindow.location = url;
 }
 function MixedTest6A() {
   gTestBrowser.removeEventListener("load", MixedTest6A, true);
-  waitForCondition(function() PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser), MixedTest6B, "waited to long for doorhanger");
+  waitForCondition(function() PopupNotifications.getNotification("bad-content", gTestBrowser), MixedTest6B, "waited too long for doorhanger");
 }
 
 function MixedTest6B() {
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
-  ok(notification, "Mixed Content Doorhanger doesn't appear for Test 6");
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
+  ok(notification, "Mixed Content Doorhanger did appear for Test 6");
   gTestBrowser.addEventListener("load", MixedTest6C, true);
-  notification.secondaryActions[0].callback();
+  notification.reshow();
+  PopupNotifications.panel.firstChild.disableMixedContentProtection();
 }
 
 function MixedTest6C() {
   gTestBrowser.removeEventListener("load", MixedTest6C, true);
   waitForCondition(function() {
     try {
       return content.document.getElementById('f1').contentDocument.getElementById('p1').innerHTML == "hello";
     } catch (e) {
--- a/browser/base/content/test/general/browser_bug902156.js
+++ b/browser/base/content/test/general/browser_bug902156.js
@@ -2,17 +2,17 @@
  * Description of the Tests for
  *  - Bug 902156: Persist "disable protection" option for Mixed Content Blocker
  *
  * 1. Navigate to the same domain via document.location
  *    - Load a html page which has mixed content
  *    - Doorhanger to disable protection appears - we disable it
  *    - Load a new page from the same origin using document.location
  *    - Doorhanger should not appear anymore!
- * 
+ *
  * 2. Navigate to the same domain via simulateclick for a link on the page
  *    - Load a html page which has mixed content
  *    - Doorhanger to disable protection appears - we disable it
  *    - Load a new page from the same origin simulating a click
  *    - Doorhanger should not appear anymore!
  *
  * 3. Navigate to a differnet domain and show the content is still blocked
  *    - Load a different html page which has mixed content
@@ -44,22 +44,23 @@ function cleanUpAfterTests() {
 
 //------------------------ Test 1 ------------------------------
 
 function test1A() {
   // Removing EventListener because we have to register a new
   // one once the page is loaded with mixed content blocker disabled
   gTestBrowser.removeEventListener("load", test1A, true);
   gTestBrowser.addEventListener("load", test1B, true);
-  
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
+
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
   ok(notification, "OK: Mixed Content Doorhanger appeared in Test1A!");
 
-  // Disable Mixed Content Protection for the page 
-  notification.secondaryActions[0].callback();
+  // Disable Mixed Content Protection for the page (and reload)
+  notification.reshow();
+  PopupNotifications.panel.firstChild.disableMixedContentProtection();
 }
 
 function test1B() {
   var expected = "Mixed Content Blocker disabled";
   waitForCondition(
     function() content.document.getElementById('mctestdiv').innerHTML == expected,
     test1C, "Error: Waited too long for mixed script to run in Test 1B");
 }
@@ -77,17 +78,17 @@ function test1C() {
   gTestBrowser.contentWindow.location = url;
 }
 
 function test1D() {
   gTestBrowser.removeEventListener("load", test1D, true);
 
   // The Doorhanger should not appear, because our decision of disabling the
   // mixed content blocker is persistent.
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
   ok(!notification, "OK: Mixed Content Doorhanger did not appear again in Test1D!");
 
   var actual = content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 1D");
 
   // move on to Test 2
   test2();
 }
@@ -100,22 +101,23 @@ function test2() {
   gTestBrowser.contentWindow.location = url;
 }
 
 function test2A() {
   // Removing EventListener because we have to register a new
   // one once the page is loaded with mixed content blocker disabled
   gTestBrowser.removeEventListener("load", test2A, true);
   gTestBrowser.addEventListener("load", test2B, true);
-  
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
+
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
   ok(notification, "OK: Mixed Content Doorhanger appeared in Test 2A!");
 
-  // Disable Mixed Content Protection for the page 
-  notification.secondaryActions[0].callback();
+  // Disable Mixed Content Protection for the page (and reload)
+  notification.reshow();
+  PopupNotifications.panel.firstChild.disableMixedContentProtection();
 }
 
 function test2B() {
   var expected = "Mixed Content Blocker disabled";
   waitForCondition(
     function() content.document.getElementById('mctestdiv').innerHTML == expected,
     test2C, "Error: Waited too long for mixed script to run in Test 2B");
 }
@@ -134,17 +136,17 @@ function test2C() {
   mctestlink.click();
 }
 
 function test2D() {
   gTestBrowser.removeEventListener("load", test2D, true);
 
   // The Doorhanger should not appear, because our decision of disabling the
   // mixed content blocker is persistent.
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
   ok(!notification, "OK: Mixed Content Doorhanger did not appear again in Test2D!");
 
   var actual = content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 2D");
 
   // move on to Test 3
   test3();
 }
@@ -156,18 +158,18 @@ function test3() {
   var url = gHttpTestRoot1 + "file_bug902156_3.html";
   gTestBrowser.contentWindow.location = url;
 }
 
 function test3A() {
   // Removing EventListener because we have to register a new
   // one once the page is loaded with mixed content blocker disabled
   gTestBrowser.removeEventListener("load", test3A, true);
-  
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
+
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
   ok(notification, "OK: Mixed Content Doorhanger appeared in Test 3A!");
 
   // We are done with tests, clean up
   cleanUpAfterTests();
 }
 
 //------------------------------------------------------
 
--- a/browser/base/content/test/general/browser_bug906190.js
+++ b/browser/base/content/test/general/browser_bug906190.js
@@ -126,21 +126,22 @@ function setUpTest(aTestName, aIDForNext
   gTestWin.gBrowser.selectTabAtIndex(1);
   gTestWin.gBrowser.addEventListener("load", checkPopUpNotification, true);
 }
 
 function checkPopUpNotification() {
   gTestWin.gBrowser.removeEventListener("load", checkPopUpNotification, true);
   gTestWin.gBrowser.addEventListener("load", reloadedTabAfterDisablingMCB, true);
 
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(notification, "OK: Mixed Content Doorhanger appeared in " + curTestName + "!");
 
-  // Disable Mixed Content Protection for the page
-  notification.secondaryActions[0].callback();
+  // Disable Mixed Content Protection for the page (and reload page)
+  notification.reshow();
+  gTestWin.PopupNotifications.panel.firstChild.disableMixedContentProtection();
 }
 
 function reloadedTabAfterDisablingMCB() {
   gTestWin.gBrowser.removeEventListener("load", reloadedTabAfterDisablingMCB, true);
 
   var expected = "Mixed Content Blocker disabled";
   waitForCondition(
     function() gTestWin.content.document.getElementById('mctestdiv').innerHTML == expected,
@@ -174,17 +175,17 @@ function test1() {
 }
 
 function test1A() {
   gTestWin.gBrowser.removeEventListener("load", test1A, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger should >> NOT << appear, because our decision of disabling the
   // mixed content blocker is persistent across tabs.
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(!notification, "OK: Mixed Content Doorhanger did not appear again in Test 1A!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 1A");
 
   gTestWin.gBrowser.removeCurrentTab();
   test1B();
 }
@@ -200,17 +201,17 @@ function test1B() {
 }
 
 function test1C() {
   gTestWin.gBrowser.removeEventListener("load", test1C, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger should >> NOT << appear, because our decision of disabling the
   // mixed content blocker is persistent across tabs.
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(!notification, "OK: Mixed Content Doorhanger did not appear again in Test 1C!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 1C");
 
   // remove tabs
   gTestWin.gBrowser.removeTab(gTestWin.gBrowser.tabs[2], {animate: false});
   gTestWin.gBrowser.removeTab(gTestWin.gBrowser.tabs[1], {animate: false});
@@ -232,17 +233,17 @@ function test2() {
 }
 
 function test2A() {
   gTestWin.gBrowser.removeEventListener("load", test2A, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger >> SHOULD << appear, because our decision of disabling the
   // mixed content blocker should only persist if pages are from the same domain.
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(notification, "OK: Mixed Content Doorhanger did appear again in Test 2A!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker enabled", "OK: Blocked mixed script in Test 2A");
 
   gTestWin.gBrowser.removeCurrentTab();
   test2B();
 }
@@ -258,17 +259,17 @@ function test2B() {
 }
 
 function test2C() {
   gTestWin.gBrowser.removeEventListener("load", test2C, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger >> SHOULD << appear, because our decision of disabling the
   // mixed content blocker should only persist if pages are from the same domain.
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(notification, "OK: Mixed Content Doorhanger did appear again in Test 2C!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker enabled", "OK: Blocked mixed script in Test 2C");
 
   // remove tabs
   gTestWin.gBrowser.removeTab(gTestWin.gBrowser.tabs[2], {animate: false});
   gTestWin.gBrowser.removeTab(gTestWin.gBrowser.tabs[1], {animate: false});
@@ -295,17 +296,17 @@ function test3A() {
   gTestWin.gBrowser.addEventListener("load", test3B, true);
 }
 
 function test3B() {
   gTestWin.gBrowser.removeEventListener("load", test3B, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger should >> NOT << appear!
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(!notification, "OK: Mixed Content Doorhanger did appear again in Test 3B!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 3B");
 
   // remove tabs
   gTestWin.gBrowser.removeCurrentTab();
   test3C();
@@ -326,17 +327,17 @@ function test3D() {
   gTestWin.gBrowser.addEventListener("load", test3E, true);
 }
 
 function test3E() {
   gTestWin.gBrowser.removeEventListener("load", test3E, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger should >> NOT << appear!
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(!notification, "OK: Mixed Content Doorhanger did appear again in Test 3E!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 3E");
 
   // remove tabs
   gTestWin.gBrowser.removeTab(gTestWin.gBrowser.tabs[2], {animate: false});
   gTestWin.gBrowser.removeTab(gTestWin.gBrowser.tabs[1], {animate: false});
@@ -363,17 +364,17 @@ function test4A() {
   gTestWin.gBrowser.addEventListener("load", test4B, true);
 }
 
 function test4B() {
   gTestWin.gBrowser.removeEventListener("load", test4B, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger >> SHOULD << appear!
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(notification, "OK: Mixed Content Doorhanger did appear again in Test 4B!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker enabled", "OK: Blocked mixed script in Test 4B");
 
   // remove tabs
   gTestWin.gBrowser.removeCurrentTab();
   test4C();
@@ -394,17 +395,17 @@ function test4D() {
   gTestWin.gBrowser.addEventListener("load", test4E, true);
 }
 
 function test4E() {
   gTestWin.gBrowser.removeEventListener("load", test4E, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger >> SHOULD << appear!
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(notification, "OK: Mixed Content Doorhanger did appear again in Test 4E!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker enabled", "OK: Blocked mixed script in Test 4E");
 
   // remove tabs
   gTestWin.gBrowser.removeTab(gTestWin.gBrowser.tabs[2], {animate: false});
   gTestWin.gBrowser.removeTab(gTestWin.gBrowser.tabs[1], {animate: false});
@@ -427,17 +428,17 @@ function test5() {
 }
 
 function test5A() {
   gTestWin.gBrowser.removeEventListener("load", test5A, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger should >> NOT << appear
   // Currently it >> APPEARS << - see follow up bug 914860
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   todo(!notification, "OK: Mixed Content Doorhanger did not appear again in Test 5A!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   todo_is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 5A!");
 
   // remove tabs
   gTestWin.gBrowser.removeCurrentTab();
   test5B();
@@ -454,17 +455,17 @@ function test5B() {
 
 function test5C() {
   gTestWin.gBrowser.removeEventListener("load", test5C, true);
   // move the tab again
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger should >> NOT << appear
   // Currently it >> APPEARS << - see follow up bug 914860
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   todo(!notification, "OK: Mixed Content Doorhanger did not appear again in Test 5C!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   todo_is(actual, "Mixed Content Blocker disabled", "OK: Executed mixed script in Test 5C!");
 
   // remove tabs
   gTestWin.gBrowser.removeTab(gTestWin.gBrowser.tabs[2], {animate: false});
   gTestWin.gBrowser.removeTab(gTestWin.gBrowser.tabs[1], {animate: false});
@@ -486,17 +487,17 @@ function test6() {
   EventUtils.synthesizeMouseAtCenter(targetElt, { button: 1 }, gTestWin.content);
 }
 
 function test6A() {
   gTestWin.gBrowser.removeEventListener("load", test6A, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger >> SHOULD << appear!
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(notification, "OK: Mixed Content Doorhanger did appear again in Test 6A!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker enabled", "OK: Blocked mixed script in Test 6A");
 
   // done
   gTestWin.gBrowser.removeCurrentTab();
   test6B();
@@ -511,17 +512,17 @@ function test6B() {
   EventUtils.synthesizeMouseAtCenter(targetElt, { type : "contextmenu", button : 2 } , gTestWin.content);
 }
 
 function test6C() {
   gTestWin.gBrowser.removeEventListener("load", test6C, true);
   gTestWin.gBrowser.selectTabAtIndex(2);
 
   // The Doorhanger >> SHOULD << appear!
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestWin.gBrowser.selectedBrowser);
+  var notification = PopupNotifications.getNotification("bad-content", gTestWin.gBrowser.selectedBrowser);
   ok(notification, "OK: Mixed Content Doorhanger did appear again in Test 6C!");
 
   var actual = gTestWin.content.document.getElementById('mctestdiv').innerHTML;
   is(actual, "Mixed Content Blocker enabled", "OK: Blocked mixed script in Test 6C");
 
   gTestWin.close();
   finish();
 }
--- a/browser/base/content/test/general/browser_mixedcontent_securityflags.js
+++ b/browser/base/content/test/general/browser_mixedcontent_securityflags.js
@@ -32,21 +32,23 @@ function blockMixedContentTest()
     is(gTestBrowser.docShell.hasMixedDisplayContentLoaded, false, "hasMixedDisplayContentLoaded flag has been set");
     is(gTestBrowser.docShell.hasMixedActiveContentLoaded, false, "hasMixedActiveContentLoaded flag has been set");
     overrideMCB();
   }, true);
 }
 
 function overrideMCB()
 {
+  // test mixed content flags on load (reload)
   gTestBrowser.addEventListener("load", mixedContentOverrideTest, true);
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
-  ok(notification, "Mixed Content Doorhanger didn't appear");
-  // Click on the doorhanger to allow mixed content.
-  notification.secondaryActions[0].callback(mixedContentOverrideTest);
+  var notification = PopupNotifications.getNotification("bad-content", gTestBrowser);
+  ok(notification, "Mixed Content Doorhanger should appear");
+  // Click on the doorhanger to allow mixed content (and reload page)
+  notification.reshow();
+  PopupNotifications.panel.firstChild.disableMixedContentProtection();
 }
 
 function mixedContentOverrideTest()
 {
   gTestBrowser.removeEventListener("load", mixedContentOverrideTest, true);
 
   is(gTestBrowser.docShell.hasMixedDisplayContentLoaded, true, "hasMixedDisplayContentLoaded flag has not been set");
   is(gTestBrowser.docShell.hasMixedActiveContentLoaded, true, "hasMixedActiveContentLoaded flag has not been set");
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -5,16 +5,18 @@
 # 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/.
 
 <!DOCTYPE bindings [
 <!ENTITY % notificationDTD SYSTEM "chrome://global/locale/notification.dtd">
 %notificationDTD;
 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
 %browserDTD;
+<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+%brandDTD;
 ]>
 
 <bindings id="urlbarBindings" xmlns="http://www.mozilla.org/xbl"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
           xmlns:xbl="http://www.mozilla.org/xbl">
 
   <binding id="urlbar" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete">
@@ -1567,16 +1569,120 @@
         <setter><!-- This should be used only in automated tests -->
           document.getAnonymousElementByAttribute(this, "anonid",
                     "center-item-menulist").value = val;
         </setter>
       </property>
     </implementation>
   </binding>
 
+  <binding id="bad-content-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
+    <content>
+      <xul:hbox align="start">
+        <xul:image class="popup-notification-icon" xbl:inherits="popupid"/>
+        <xul:vbox>
+          <!-- header -->
+          <xul:vbox>
+            <xul:description anonid="badContentBlocked.title"
+              class="popup-notification-item-title" xbl:inherits="popupid">
+            </xul:description>
+            <xul:description class="popup-notification-item-message"
+              xbl:inherits="popupid">
+              &badContentBlocked.moreinfo;
+            </xul:description>
+          </xul:vbox>
+          <!-- mixed content -->
+          <xul:vbox anonid="mixedContent" hidden="true">
+            <xul:separator class="groove"/>
+            <xul:hbox align="start">
+              <xul:vbox>
+                <xul:description class="popup-notification-item-title"
+                  xbl:inherits="popupid">
+                  &mixedContentBlocked2.message;
+                </xul:description>
+                <xul:description class="popup-notification-item-message"
+                  xbl:inherits="popupid">
+                  &mixedContentBlocked2.moreinfo;
+                </xul:description>
+                <xul:label anonid="mixedContent.helplink"
+                  class="text-link plain" href=""
+                  value="&mixedContentBlocked2.learnMore;"/>
+              </xul:vbox>
+              <xul:button
+                type="menu" label="&mixedContentBlocked2.options;"
+                sizetopopup="none">
+                <xul:menupopup>
+                  <xul:menuitem anonid="mixedContentAction.unblock"
+                    hidden="true" label="&mixedContentBlocked2.unblock.label;"
+                    accesskey="&mixedContentBlocked2.unblock.accesskey;"
+                    oncommand="document.getBindingParent(this).disableMixedContentProtection();"/>
+                </xul:menupopup>
+              </xul:button>
+            </xul:hbox>
+          </xul:vbox>
+        </xul:vbox>
+      </xul:hbox>
+    </content>
+    <resources>
+      <stylesheet src="chrome://global/skin/notification.css"/>
+    </resources>
+    <implementation>
+      <field name="_brandShortName">
+        document.getElementById("bundle_brand").getString("brandShortName")
+      </field>
+      <field name="_doorhangerTitle">
+        document.getAnonymousElementByAttribute(this, "anonid",
+          "badContentBlocked.title")
+      </field>
+      <field name="_mixedContent">
+        document.getAnonymousElementByAttribute(this, "anonid",
+            "mixedContent")
+      </field>
+      <field name="_mixedContentUnblock">
+        document.getAnonymousElementByAttribute(this, "anonid",
+          "mixedContentAction.unblock")
+      </field>
+      <field name="_mixedContentHelplink">
+        document.getAnonymousElementByAttribute(this, "anonid",
+          "mixedContent.helplink")
+      </field>
+      <constructor><![CDATA[
+        // default title
+        _doorhangerTitle.value =
+          gNavigatorBundle.getFormattedString(
+            "badContentBlocked.notblocked.message", [this._brandShortName]);
+
+        if (this.notification.options.state &
+          Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT) {
+          _doorhangerTitle.value =
+            gNavigatorBundle.getFormattedString(
+              "badContentBlocked.blocked.message", [this._brandShortName]);
+          _mixedContent.hidden = false;
+          _mixedContentUnblock.hidden = false;
+          _mixedContentHelplink.href =
+            Services.urlFormatter.formatURLPref("app.support.baseURL")
+              + "mixed-content";
+        }
+      ]]></constructor>
+      <method name="disableMixedContentProtection">
+        <body><![CDATA[
+          // Use telemetry to measure how often unblocking happens
+          const kMIXED_CONTENT_UNBLOCK_EVENT = 2;
+          let histogram =
+            Services.telemetry.getHistogramById(
+              "MIXED_CONTENT_UNBLOCK_COUNTER");
+          histogram.add(kMIXED_CONTENT_UNBLOCK_EVENT);
+          // Reload the page with the content unblocked
+          BrowserReloadWithFlags(
+            nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT);
+        ]]></body>
+      </method>
+    </implementation>
+  </binding>
+
   <binding id="click-to-play-plugins-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
     <content align="start" style="width: &pluginNotification.width;;">
       <xul:vbox flex="1" align="stretch" class="popup-notification-main-box"
                 xbl:inherits="popupid">
         <xul:hbox class="click-to-play-plugins-notification-description-box" flex="1" align="start">
           <xul:description class="click-to-play-plugins-outer-description" flex="1">
             <html:span anonid="click-to-play-plugins-notification-description" />
             <xul:label class="text-link click-to-play-plugins-notification-link" anonid="click-to-play-plugins-notification-link" />
--- a/browser/devtools/webconsole/test/browser_webconsole_block_mixedcontent_securityerrors.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_block_mixedcontent_securityerrors.js
@@ -51,20 +51,21 @@ function blockMixedContentTest1()
         mixedContentOverrideTest2(hud);
       });
     });
   }, true);
 }
 
 function mixedContentOverrideTest2(hud)
 {
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", browser);
+  var notification = PopupNotifications.getNotification("bad-content", browser);
   ok(notification, "Mixed Content Doorhanger didn't appear");
   // Click on the doorhanger.
-  notification.secondaryActions[0].callback();
+  notification.reshow();
+  PopupNotifications.panel.firstChild.disableMixedContentProtection();
 
   waitForMessages({
     webconsole: hud,
     messages: [
       {
         name: "Logged blocking mixed active content",
         text: "Loading mixed (insecure) active content on a secure"+
           " page \"http://example.com/\"",
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -719,17 +719,25 @@ just addresses the organization to follo
 <!ENTITY getUserMedia.selectCamera.label "Camera to share:">
 <!ENTITY getUserMedia.selectCamera.accesskey "C">
 <!ENTITY getUserMedia.selectWindowOrScreen.label "Window or screen to share:">
 <!ENTITY getUserMedia.selectWindowOrScreen.accesskey "W">
 <!ENTITY getUserMedia.selectMicrophone.label "Microphone to share:">
 <!ENTITY getUserMedia.selectMicrophone.accesskey "M">
 <!ENTITY getUserMedia.allWindowsShared.message "All visible windows on your screen will be shared.">
 
-<!ENTITY mixedContentBlocked.moreinfo "Most websites will still work properly even when this content is blocked.">
+<!-- Bad Content Blocker Doorhanger Notification -->
+<!ENTITY badContentBlocked.moreinfo "Most websites will work properly even if content is blocked.">
+
+<!ENTITY mixedContentBlocked2.message "Insecure content">
+<!ENTITY mixedContentBlocked2.moreinfo "Some unencrypted elements on this website have been blocked.">
+<!ENTITY mixedContentBlocked2.learnMore "Learn More">
+<!ENTITY mixedContentBlocked2.options "Options">
+<!ENTITY mixedContentBlocked2.unblock.label "Disable protection for now">
+<!ENTITY mixedContentBlocked2.unblock.accesskey "D">
 
 <!ENTITY pointerLock.notification.message "Press ESC at any time to show it again.">
 
 <!ENTITY pluginNotification.showAll.label "Show All">
 <!ENTITY pluginNotification.showAll.accesskey "S">
 
 <!-- LOCALIZATION NOTE (pluginActivateNow.label, pluginActivateAlways.label, pluginBlockNow.label): These should be the same as the matching strings in browser.properties -->
 <!ENTITY pluginActivateNow.label "Allow Now">
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -93,16 +93,21 @@ popupWarningButton.accesskey=O
 popupWarningButtonUnix=Preferences
 popupWarningButtonUnix.accesskey=P
 popupAllow=Allow pop-ups for %S
 popupBlock=Block pop-ups for %S
 popupWarningDontShowFromMessage=Don't show this message when pop-ups are blocked
 popupWarningDontShowFromLocationbar=Don't show info bar when pop-ups are blocked
 popupShowPopupPrefix=Show '%S'
 
+# Bad Content Blocker Doorhanger Notification
+# %S is brandShortName
+badContentBlocked.blocked.message=%S is blocking content on this page.
+badContentBlocked.notblocked.message=%S is not blocking any content on this page.
+
 # missing plugin installer
 installPlugin.message = Would you like to install the plugin needed to display the media on this page?
 installPlugin.button.label=Install %S
 installPlugin.button.accesskey=I
 installPlugin.ignoreButton.label=Don't ask again
 installPlugin.ignoreButton.accesskey=N
 
 crashedpluginsMessage.title=The %S plugin has crashed.
@@ -551,24 +556,16 @@ getUserMedia.sharingMenuCameraMicrophone
 getUserMedia.sharingMenuCameraMicrophoneScreen = %S (camera, microphone and screen)
 getUserMedia.sharingMenuCameraMicrophoneWindow = %S (camera, microphone and window)
 getUserMedia.sharingMenuMicrophoneScreen = %S (microphone and screen)
 getUserMedia.sharingMenuMicrophoneWindow = %S (microphone and window)
 # LOCALIZATION NOTE(getUserMedia.sharingMenuUnknownHost): this is used for the website
 # origin for the sharing menu if no readable origin could be deduced from the URL.
 getUserMedia.sharingMenuUnknownHost = Unknown origin
 
-# Mixed Content Blocker Doorhanger Notification
-# LOCALIZATION NOTE - %S is brandShortName
-mixedContentBlocked.message = %S has blocked content that isn't secure.
-mixedContentBlocked.keepBlockingButton.label = Keep Blocking
-mixedContentBlocked.keepBlockingButton.accesskey = B
-mixedContentBlocked.unblock.label = Disable Protection on This Page
-mixedContentBlocked.unblock.accesskey = D
-
 # LOCALIZATION NOTE - %S is brandShortName
 slowStartup.message = %S seems slow… to… start.
 slowStartup.helpButton.label = Learn How to Speed It Up
 slowStartup.helpButton.accesskey = L
 slowStartup.disableNotificationButton.label = Don't Tell Me Again
 slowStartup.disableNotificationButton.accesskey = A
 
 
rename from browser/themes/linux/mixed-content-blocked-16.png
rename to browser/themes/linux/bad-content-blocked-16.png
rename from browser/themes/linux/mixed-content-blocked-64.png
rename to browser/themes/linux/bad-content-blocked-64.png
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1175,18 +1175,18 @@ toolbarbutton[sdk-button="true"][cui-are
   list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
 }
 
 .popup-notification-icon[popupid="webapps-install-progress"],
 .popup-notification-icon[popupid="webapps-install"] {
   list-style-image: url(chrome://global/skin/icons/webapps-64.png);
 }
 
-.popup-notification-icon[popupid="mixed-content-blocked"] {
-  list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
+.popup-notification-icon[popupid="bad-content"] {
+  list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png);
 }
 
 .popup-notification-icon[popupid="webRTC-sharingDevices"],
 .popup-notification-icon[popupid="webRTC-shareDevices"] {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
 }
 
 .popup-notification-icon[popupid="webRTC-sharingMicrophone"],
@@ -1315,19 +1315,19 @@ toolbarbutton[sdk-button="true"][cui-are
   from {
     opacity: 0;
   }
   to {
     opacity: 1;
   }
 }
 
-.mixed-content-blocked-notification-icon,
-#mixed-content-blocked-notification-icon {
-  list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
+.bad-content-blocked-notification-icon,
+#bad-content-blocked-notification-icon {
+  list-style-image: url(chrome://browser/skin/bad-content-blocked-16.png);
 }
 
 .webRTC-shareDevices-notification-icon,
 #webRTC-shareDevices-notification-icon {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
 }
 
 .webRTC-sharingDevices-notification-icon,
@@ -2029,16 +2029,17 @@ toolbarbutton.chevron > .toolbarbutton-i
 #full-screen-remember-decision {
   font-size: 120%;
 }
 
 %include ../shared/devtools/responsivedesign.inc.css
 %include ../shared/devtools/highlighter.inc.css
 %include ../shared/devtools/commandline.inc.css
 %include ../shared/plugin-doorhanger.inc.css
+%include ../shared/badcontent-doorhanger.inc.css
 
 %include downloads/indicator.css
 
 .gcli-panel {
   padding: 0;
 }
 
 .gclitoolbar-input-node > .textbox-input-box > html|*.textbox-input::-moz-selection {
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -35,18 +35,18 @@ browser.jar:
   skin/classic/browser/identity-icons-https-mixed-active.png
   skin/classic/browser/identity-icons-https-mixed-display.png
   skin/classic/browser/Info.png
   skin/classic/browser/menuPanel.png
   skin/classic/browser/menuPanel-customize.png
   skin/classic/browser/menuPanel-exit.png
   skin/classic/browser/menuPanel-help.png
   skin/classic/browser/menuPanel-small.png
-  skin/classic/browser/mixed-content-blocked-16.png
-  skin/classic/browser/mixed-content-blocked-64.png
+  skin/classic/browser/bad-content-blocked-16.png
+  skin/classic/browser/bad-content-blocked-64.png
   skin/classic/browser/monitor.png
   skin/classic/browser/monitor_16-10.png
   skin/classic/browser/notification-16.png
   skin/classic/browser/notification-64.png
 * skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/pluginInstall-16.png
rename from browser/themes/osx/mixed-content-blocked-16.png
rename to browser/themes/osx/bad-content-blocked-16.png
rename from browser/themes/osx/mixed-content-blocked-16@2x.png
rename to browser/themes/osx/bad-content-blocked-16@2x.png
rename from browser/themes/osx/mixed-content-blocked-64.png
rename to browser/themes/osx/bad-content-blocked-64.png
rename from browser/themes/osx/mixed-content-blocked-64@2x.png
rename to browser/themes/osx/bad-content-blocked-64@2x.png
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -3553,22 +3553,22 @@ toolbarbutton.chevron > .toolbarbutton-m
   from {
     opacity: 0;
   }
   to {
     opacity: 1;
   }
 }
 
-#mixed-content-blocked-notification-icon {
-  list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
+#bad-content-blocked-notification-icon {
+  list-style-image: url(chrome://browser/skin/bad-content-blocked-16.png);
 }
 @media (min-resolution: 2dppx) {
-  #mixed-content-blocked-notification-icon {
-    list-style-image: url(chrome://browser/skin/mixed-content-blocked-16@2x.png);
+  #bad-content-blocked-notification-icon {
+    list-style-image: url(chrome://browser/skin/bad-content-blocked-16@2x.png);
   }
 }
 
 .webRTC-shareDevices-notification-icon,
 #webRTC-shareDevices-notification-icon {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
 }
 @media (min-resolution: 2dppx) {
@@ -3906,22 +3906,22 @@ menulist.translate-infobar-element > .me
   list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
 }
 
 .popup-notification-icon[popupid="webapps-install-progress"],
 .popup-notification-icon[popupid="webapps-install"] {
   list-style-image: url(chrome://global/skin/icons/webapps-64.png);
 }
 
-.popup-notification-icon[popupid="mixed-content-blocked"] {
-  list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
+.popup-notification-icon[popupid="bad-content"] {
+  list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png);
 }
 @media (min-resolution: 2dppx) {
-  .popup-notification-icon[popupid="mixed-content-blocked"] {
-    list-style-image: url(chrome://browser/skin/mixed-content-blocked-64@2x.png);
+  .popup-notification-icon[popupid="bad-content"] {
+    list-style-image: url(chrome://browser/skin/bad-content-blocked-64@2x.png);
   }
 }
 
 .popup-notification-icon[popupid="pointerLock"] {
   list-style-image: url(chrome://browser/skin/pointerLock-64.png);
 }
 @media (min-resolution: 2dppx) {
   .popup-notification-icon[popupid="pointerLock"] {
@@ -4147,16 +4147,17 @@ menulist.translate-infobar-element > .me
 #full-screen-remember-decision {
   font-size: 120%;
 }
 
 %include ../shared/devtools/responsivedesign.inc.css
 %include ../shared/devtools/highlighter.inc.css
 %include ../shared/devtools/commandline.inc.css
 %include ../shared/plugin-doorhanger.inc.css
+%include ../shared/badcontent-doorhanger.inc.css
 
 %include downloads/indicator.css
 
 /* On mac, the popup notification contents are indented by default and so
   the default closebutton margins from notification.css require adjustment */
 
 .click-to-play-plugins-notification-description-box > .popup-notification-closebutton {
   -moz-margin-end: -6px;
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -58,20 +58,20 @@ browser.jar:
   skin/classic/browser/menuPanel-customize.png
   skin/classic/browser/menuPanel-customize@2x.png
   skin/classic/browser/menuPanel-exit.png
   skin/classic/browser/menuPanel-exit@2x.png
   skin/classic/browser/menuPanel-help.png
   skin/classic/browser/menuPanel-help@2x.png
   skin/classic/browser/menuPanel-small.png
   skin/classic/browser/menuPanel-small@2x.png
-  skin/classic/browser/mixed-content-blocked-16.png
-  skin/classic/browser/mixed-content-blocked-16@2x.png
-  skin/classic/browser/mixed-content-blocked-64.png
-  skin/classic/browser/mixed-content-blocked-64@2x.png
+  skin/classic/browser/bad-content-blocked-16.png
+  skin/classic/browser/bad-content-blocked-16@2x.png
+  skin/classic/browser/bad-content-blocked-64.png
+  skin/classic/browser/bad-content-blocked-64@2x.png
   skin/classic/browser/panel-expander-closed.png
   skin/classic/browser/panel-expander-closed@2x.png
   skin/classic/browser/panel-expander-open.png
   skin/classic/browser/panel-expander-open@2x.png
   skin/classic/browser/panel-plus-sign.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/page-livemarks@2x.png
   skin/classic/browser/pageInfo.css
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/badcontent-doorhanger.inc.css
@@ -0,0 +1,7 @@
+.popup-notification-item-title[popupid="bad-content"] {
+  font-weight: bold;
+}
+
+.popup-notification-item-message[popupid="bad-content"] {
+  width: 17em;
+}
rename from browser/themes/windows/mixed-content-blocked-16.png
rename to browser/themes/windows/bad-content-blocked-16.png
rename from browser/themes/windows/mixed-content-blocked-64.png
rename to browser/themes/windows/bad-content-blocked-64.png
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2193,18 +2193,18 @@ toolbarbutton.bookmark-item[dragover="tr
   list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
 }
 
 .popup-notification-icon[popupid="webapps-install-progress"],
 .popup-notification-icon[popupid="webapps-install"] {
   list-style-image: url(chrome://global/skin/icons/webapps-64.png);
 }
 
-.popup-notification-icon[popupid="mixed-content-blocked"] {
-  list-style-image: url(chrome://browser/skin/mixed-content-blocked-64.png);
+.popup-notification-icon[popupid="bad-content"] {
+  list-style-image: url(chrome://browser/skin/bad-content-blocked-64.png);
 }
 
 .popup-notification-icon[popupid="webRTC-sharingDevices"],
 .popup-notification-icon[popupid="webRTC-shareDevices"] {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-64.png);
 }
 
 .popup-notification-icon[popupid="webRTC-sharingMicrophone"],
@@ -2327,19 +2327,19 @@ toolbarbutton.bookmark-item[dragover="tr
   from {
     opacity: 0;
   }
   to {
     opacity: 1;
   }
 }
 
-.mixed-content-blocked-notification-icon,
-#mixed-content-blocked-notification-icon {
-  list-style-image: url(chrome://browser/skin/mixed-content-blocked-16.png);
+.bad-content-blocked-notification-icon,
+#bad-content-blocked-notification-icon {
+  list-style-image: url(chrome://browser/skin/bad-content-blocked-16.png);
 }
 
 .webRTC-shareDevices-notification-icon,
 #webRTC-shareDevices-notification-icon {
   list-style-image: url(chrome://browser/skin/webRTC-shareDevice-16.png);
 }
 
 .webRTC-sharingDevices-notification-icon,
@@ -2641,16 +2641,17 @@ notification[value="translation"] {
 #full-screen-remember-decision {
   font-size: 120%;
 }
 
 %include ../shared/devtools/responsivedesign.inc.css
 %include ../shared/devtools/highlighter.inc.css
 %include ../shared/devtools/commandline.inc.css
 %include ../shared/plugin-doorhanger.inc.css
+%include ../shared/badcontent-doorhanger.inc.css
 
 %include downloads/indicator.css
 
 /* Error counter */
 
 #developer-toolbar-toolbox-button[error-count]:before {
   color: #FDF3DE;
   min-width: 16px;
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -45,18 +45,18 @@ browser.jar:
         skin/classic/browser/menuPanel.png
         skin/classic/browser/menuPanel-customize.png
         skin/classic/browser/menuPanel-exit.png
         skin/classic/browser/menuPanel-help.png
         skin/classic/browser/menuPanel-small.png
         skin/classic/browser/Metro_Glyph.png                        (Metro_Glyph-aero.png)
         skin/classic/browser/Metro_Glyph-inverted.png
         skin/classic/browser/Metro_Glyph-menuPanel.png
-        skin/classic/browser/mixed-content-blocked-16.png
-        skin/classic/browser/mixed-content-blocked-64.png
+        skin/classic/browser/bad-content-blocked-16.png
+        skin/classic/browser/bad-content-blocked-64.png
         skin/classic/browser/monitor.png
         skin/classic/browser/monitor_16-10.png
         skin/classic/browser/notification-16.png
         skin/classic/browser/notification-64.png
         skin/classic/browser/pageInfo.css
         skin/classic/browser/pageInfo.png
         skin/classic/browser/page-livemarks.png                      (feeds/feedIcon16.png)
         skin/classic/browser/pluginInstall-16.png
@@ -454,18 +454,18 @@ browser.jar:
         skin/classic/aero/browser/menuPanel-customize.png
         skin/classic/aero/browser/menuPanel-exit.png
         skin/classic/aero/browser/menuPanel-help.png
         skin/classic/aero/browser/menuPanel-small.png
         skin/classic/aero/browser/menuPanel-small-aero.png
         skin/classic/aero/browser/Metro_Glyph.png                    (Metro_Glyph-aero.png)
         skin/classic/aero/browser/Metro_Glyph-inverted.png
         skin/classic/aero/browser/Metro_Glyph-menuPanel.png
-        skin/classic/aero/browser/mixed-content-blocked-16.png
-        skin/classic/aero/browser/mixed-content-blocked-64.png
+        skin/classic/aero/browser/bad-content-blocked-16.png
+        skin/classic/aero/browser/bad-content-blocked-64.png
         skin/classic/aero/browser/monitor.png
         skin/classic/aero/browser/monitor_16-10.png
         skin/classic/aero/browser/notification-16.png
         skin/classic/aero/browser/notification-64.png
         skin/classic/aero/browser/pageInfo.css
         skin/classic/aero/browser/pageInfo.png                       (pageInfo-aero.png)
         skin/classic/aero/browser/page-livemarks.png                 (feeds/feedIcon16-aero.png)
         skin/classic/aero/browser/pluginInstall-16.png
--- a/content/base/test/browser_bug902350.js
+++ b/content/base/test/browser_bug902350.js
@@ -46,17 +46,17 @@ function MixedTest1A() {
 function MixedTest1B() {
   gTestBrowser.removeEventListener("load", MixedTest1B, true);
   gTestBrowser.addEventListener("load", MixedTest1C, true);
   var frame = content.document.getElementById("testing_frame");
   var topTarget = frame.contentWindow.document.getElementById("topTarget");
   topTarget.click();
 
   // The link click should have caused a load and should not invoke the Mixed Content Blocker
-  var notification = PopupNotifications.getNotification("mixed-content-blocked", gTestBrowser);
+  var notification = PopupNotifications.getNotification("bad-content-blocked", gTestBrowser);
   ok(!notification, "Mixed Content Doorhanger appears when trying to navigate top");
 
 }
 
 function MixedTest1C() {
   gTestBrowser.removeEventListener("load", MixedTest1C, true);
   ok(gTestBrowser.contentWindow.location == "http://example.com/", "Navigating to insecure domain through target='_top' failed.")
   MixedTestsCompleted();