Merge inbound to mozilla-central. a=merge
authorBrindusan Cristian <cbrindusan@mozilla.com>
Sat, 15 Dec 2018 23:41:35 +0200
changeset 450853 8f91fb1acea5ed5585a8502599e51adfc1618de2
parent 450852 07c40fd43ee1f3220cc77f2d45de86a4418fc47f (current diff)
parent 450841 8a6afcb74cd9cc711a601fad300be5e6b0493c2a (diff)
child 450854 cb8b52956e53fde9863befb45b17f601bd5e32bf
child 450858 d2f0bdd847e1939edd6edea86a73e7edd15fca7f
child 450861 b7e8997927b9dd441be11adb6544abb7f8387929
push id110550
push usercbrindusan@mozilla.com
push dateSat, 15 Dec 2018 21:45:53 +0000
treeherdermozilla-inbound@cb8b52956e53 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone66.0a1
first release with
nightly linux32
8f91fb1acea5 / 66.0a1 / 20181215214208 / files
nightly linux64
8f91fb1acea5 / 66.0a1 / 20181215214208 / files
nightly mac
8f91fb1acea5 / 66.0a1 / 20181215214208 / files
nightly win32
8f91fb1acea5 / 66.0a1 / 20181215214208 / files
nightly win64
8f91fb1acea5 / 66.0a1 / 20181215214208 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
--- a/browser/modules/test/browser/formValidation/browser_form_validation.js
+++ b/browser/modules/test/browser/formValidation/browser_form_validation.js
@@ -351,37 +351,16 @@ add_task(async function() {
   });
 
   await notifierPromise;
 
   gBrowser.removeTab(gBrowser.getTabForBrowser(browser));
 });
 
 /**
- * In this test, we check that the author defined error message is shown.
- */
-add_task(async function() {
-  incrementTest();
-  let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input x-moz-errormessage='foo' required id='i'><input id='s' type='submit'></form>" + getDocFooter();
-  let browser = await openNewTab(uri);
-
-  let popupShownPromise = BrowserTestUtils.waitForEvent(gInvalidFormPopup, "popupshown");
-  await clickChildElement(browser);
-  await popupShownPromise;
-
-  checkPopupShow();
-  await checkChildFocus(browser, gInvalidFormPopup.firstElementChild.textContent);
-
-  is(gInvalidFormPopup.firstElementChild.textContent, "foo",
-     "The panel should show the author defined error message");
-
-  gBrowser.removeCurrentTab();
-});
-
-/**
  * In this test, we check that the message is correctly updated when it changes.
  */
 add_task(async function() {
   incrementTest();
   let uri = getDocHeader() + "<form target='t' action='data:text/html,'><input type='email' required id='i'><input id='s' type='submit'></form>" + getDocFooter();
   let browser = await openNewTab(uri);
 
   let popupShownPromise = BrowserTestUtils.waitForEvent(gInvalidFormPopup, "popupshown");
--- a/browser/themes/shared/customizableui/customizeMode.inc.css
+++ b/browser/themes/shared/customizableui/customizeMode.inc.css
@@ -426,16 +426,27 @@ toolbarpaletteitem[place=toolbar] > tool
 .customization-lwtheme-menu-footeritem:hover {
   background: linear-gradient(var(--arrowpanel-dimmed) 40%, transparent) padding-box;
 }
 
 .customization-lwtheme-menu-footeritem:first-child {
   border-inline-end: 1px solid var(--panel-separator-color);
 }
 
+.customization-uidensity-menuitem > .menu-iconic-left > .menu-iconic-icon:-moz-locale-dir(rtl),
+.customization-lwtheme-menu-theme > .toolbarbutton-icon:-moz-locale-dir(rtl) {
+  transform: scaleX(-1);
+}
+
+#customization-uidensity-button > .box-inherit > .box-inherit > .button-icon:-moz-locale-dir(rtl),
+#customization-lwtheme-button > .box-inherit > .box-inherit > .button-icon:-moz-locale-dir(rtl) {
+  transform: scaleX(-1);
+}
+
+
 #customization-panelWrapper > .panel-arrowcontent {
   color: var(--arrowpanel-color);
   background: var(--arrowpanel-background);
   background-clip: padding-box;
 %ifdef XP_MACOSX
   /* Native styling adds more 'oompf' to the popup box-shadow, so simulate that
    * as best as we can here: */
   box-shadow: 0 0 1px hsla(0,0%,0%,.3), 0 4px 10px hsla(0,0%,0%,.3);
--- a/dom/html/nsIConstraintValidation.cpp
+++ b/dom/html/nsIConstraintValidation.cpp
@@ -41,30 +41,17 @@ mozilla::dom::ValidityState* nsIConstrai
   return mValidity;
 }
 
 void nsIConstraintValidation::GetValidationMessage(
     nsAString& aValidationMessage, ErrorResult& aError) {
   aValidationMessage.Truncate();
 
   if (IsCandidateForConstraintValidation() && !IsValid()) {
-    nsCOMPtr<Element> element = do_QueryInterface(this);
-    NS_ASSERTION(element,
-                 "This class should be inherited by HTML elements only!");
-
-    nsAutoString authorMessage;
-    element->GetAttr(kNameSpaceID_None, nsGkAtoms::x_moz_errormessage,
-                     authorMessage);
-
-    if (!authorMessage.IsEmpty()) {
-      aValidationMessage.Assign(authorMessage);
-      if (aValidationMessage.Length() > sContentSpecifiedMaxLengthMessage) {
-        aValidationMessage.Truncate(sContentSpecifiedMaxLengthMessage);
-      }
-    } else if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
+    if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
       aValidationMessage.Assign(mCustomValidity);
       if (aValidationMessage.Length() > sContentSpecifiedMaxLengthMessage) {
         aValidationMessage.Truncate(sContentSpecifiedMaxLengthMessage);
       }
     } else if (GetValidityState(VALIDITY_STATE_TOO_LONG)) {
       GetValidationMessage(aValidationMessage, VALIDITY_STATE_TOO_LONG);
     } else if (GetValidityState(VALIDITY_STATE_TOO_SHORT)) {
       GetValidationMessage(aValidationMessage, VALIDITY_STATE_TOO_SHORT);
--- a/dom/html/test/test_bug600155.html
+++ b/dom/html/test/test_bug600155.html
@@ -19,17 +19,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 /** Test for Bug 600155 **/
 
 var subjectForConstraintValidation = [ "input", "select", "textarea" ];
 var content = document.getElementById('content');
 
 for (var eName of subjectForConstraintValidation) {
   var e = document.createElement(eName);
   content.appendChild(e);
-  e.setAttribute("x-moz-errormessage", "foo");
+  e.setCustomValidity("foo");
   if ("required" in e) {
     e.required = true;
   } else {
     e.setCustomValidity("bar");
   }
 
   // At this point, the element is invalid.
   is(e.validationMessage, "foo",
--- a/dom/html/test/test_bug606817.html
+++ b/dom/html/test/test_bug606817.html
@@ -34,23 +34,18 @@ for (var i=0; i<75; ++i) {
   msg += "_42_";
 }
 // msg is now 300 chars long
 
 // Testing with setCustomValidity().
 input.setCustomValidity(msg);
 checkMessage(input, msg, false);
 
-// The input is still invalid but x-moz-errormessage will be used as the message.
-input.setAttribute("x-moz-errormessage", msg);
-checkMessage(input, msg, false);
-
 // Cleaning.
 input.setCustomValidity("");
-input.removeAttribute("x-moz-errormessage");
 
 // Testing with pattern and titl.
 input.pattern = "[0-9]*";
 input.value = "foo";
 input.title = msg;
 checkMessage(input, msg, true);
 
 // Cleaning.
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -1807,16 +1807,23 @@ VARCACHE_PREF(
 )
 
 VARCACHE_PREF(
   "privacy.resistFingerprinting.autoDeclineNoUserInputCanvasPrompts",
    privacy_resistFingerprinting_autoDeclineNoUserInputCanvasPrompts,
   RelaxedAtomicBool, false
 )
 
+// Password protection
+VARCACHE_PREF(
+  "browser.safebrowsing.passwords.enabled",
+   browser_safebrowsing_passwords_enabled,
+  bool, false
+)
+
 //---------------------------------------------------------------------------
 // ChannelClassifier prefs
 //---------------------------------------------------------------------------
 
 VARCACHE_PREF(
   "channelclassifier.allowlist_example",
    channelclassifier_allowlist_example,
   bool, false
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5594,19 +5594,16 @@ pref("browser.safebrowsing.downloads.ena
 pref("browser.safebrowsing.downloads.remote.enabled", true);
 pref("browser.safebrowsing.downloads.remote.timeout_ms", 15000);
 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", true);
 pref("browser.safebrowsing.downloads.remote.block_uncommon",             true);
 
-// Password protection
-pref("browser.safebrowsing.passwords.enabled", false);
-
 // Google Safe Browsing provider (legacy)
 pref("browser.safebrowsing.provider.google.pver", "2.2");
 pref("browser.safebrowsing.provider.google.lists", "goog-badbinurl-shavar,goog-downloadwhite-digest256,goog-phish-shavar,googpub-phish-shavar,goog-malware-shavar,goog-unwanted-shavar");
 pref("browser.safebrowsing.provider.google.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%MAJOR_VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");
 pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%MAJOR_VERSION%&pver=2.2");
 pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
 pref("browser.safebrowsing.provider.google.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
 pref("browser.safebrowsing.provider.google.reportMalwareMistakeURL", "https://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%&url=");
--- a/netwerk/url-classifier/UrlClassifierFeatureFactory.cpp
+++ b/netwerk/url-classifier/UrlClassifierFeatureFactory.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "mozilla/net/UrlClassifierFeatureFactory.h"
 
 // List of Features
+#include "UrlClassifierFeatureLoginReputation.h"
 #include "UrlClassifierFeatureTrackingProtection.h"
 #include "UrlClassifierFeatureTrackingAnnotation.h"
 
 #include "nsAppRunner.h"
 
 namespace mozilla {
 namespace net {
 
@@ -26,16 +27,17 @@ namespace net {
 }
 
 /* static */ void UrlClassifierFeatureFactory::Shutdown() {
   // We want to expose Features only in the parent process.
   if (!XRE_IsParentProcess()) {
     return;
   }
 
+  UrlClassifierFeatureLoginReputation::MaybeShutdown();
   UrlClassifierFeatureTrackingAnnotation::Shutdown();
   UrlClassifierFeatureTrackingProtection::Shutdown();
 }
 
 /* static */ void UrlClassifierFeatureFactory::GetFeaturesFromChannel(
     nsIChannel* aChannel,
     nsTArray<nsCOMPtr<nsIUrlClassifierFeature>>& aFeatures) {
   MOZ_ASSERT(XRE_IsParentProcess());
@@ -56,10 +58,16 @@ namespace net {
 
   // Tracking Annotation
   feature = UrlClassifierFeatureTrackingAnnotation::MaybeCreate(aChannel);
   if (feature) {
     aFeatures.AppendElement(feature);
   }
 }
 
+/* static */
+nsIUrlClassifierFeature*
+UrlClassifierFeatureFactory::GetFeatureLoginReputation() {
+  return UrlClassifierFeatureLoginReputation::MaybeGetOrCreate();
+}
+
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/url-classifier/UrlClassifierFeatureFactory.h
+++ b/netwerk/url-classifier/UrlClassifierFeatureFactory.h
@@ -20,14 +20,16 @@ class UrlClassifierFeatureFactory final 
  public:
   static void Initialize();
 
   static void Shutdown();
 
   static void GetFeaturesFromChannel(
       nsIChannel* aChannel,
       nsTArray<nsCOMPtr<nsIUrlClassifierFeature>>& aFeatures);
+
+  static nsIUrlClassifierFeature* GetFeatureLoginReputation();
 };
 
 }  // namespace net
 }  // namespace mozilla
 
 #endif  // mozilla_net_UrlClassifierFeatureFactory_h
new file mode 100644
--- /dev/null
+++ b/netwerk/url-classifier/UrlClassifierFeatureLoginReputation.cpp
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "UrlClassifierFeatureLoginReputation.h"
+
+#include "mozilla/StaticPrefs.h"
+
+namespace mozilla {
+namespace net {
+
+namespace {
+
+#define PREF_PASSWORD_ALLOW_TABLE "urlclassifier.passwordAllowTable"
+
+StaticRefPtr<UrlClassifierFeatureLoginReputation> gFeatureLoginReputation;
+
+}  // namespace
+
+UrlClassifierFeatureLoginReputation::UrlClassifierFeatureLoginReputation()
+    : UrlClassifierFeatureBase(NS_LITERAL_CSTRING("login-reputation"),
+                               EmptyCString(),  // blacklist tables
+                               NS_LITERAL_CSTRING(PREF_PASSWORD_ALLOW_TABLE),
+                               EmptyCString(),  // blacklist pref
+                               EmptyCString(),  // whitelist pref
+                               EmptyCString(),  // blacklist pref table name
+                               EmptyCString(),  // whitelist pref table name
+                               EmptyCString())  // skip host pref
+{}
+
+/* static */ void UrlClassifierFeatureLoginReputation::MaybeShutdown() {
+  UC_LOG(("UrlClassifierFeatureLoginReputation: MaybeShutdown"));
+
+  if (gFeatureLoginReputation) {
+    gFeatureLoginReputation->ShutdownPreferences();
+    gFeatureLoginReputation = nullptr;
+  }
+}
+
+/* static */ nsIUrlClassifierFeature*
+UrlClassifierFeatureLoginReputation::MaybeGetOrCreate() {
+  if (!StaticPrefs::browser_safebrowsing_passwords_enabled()) {
+    return nullptr;
+  }
+
+  if (!gFeatureLoginReputation) {
+    gFeatureLoginReputation = new UrlClassifierFeatureLoginReputation();
+    gFeatureLoginReputation->InitializePreferences();
+  }
+
+  return gFeatureLoginReputation;
+}
+
+NS_IMETHODIMP
+UrlClassifierFeatureLoginReputation::ProcessChannel(nsIChannel* aChannel,
+                                                    const nsACString& aList,
+                                                    bool* aShouldContinue) {
+  MOZ_CRASH(
+      "UrlClassifierFeatureLoginReputation::ProcessChannel should never be "
+      "called");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+UrlClassifierFeatureLoginReputation::GetTables(
+    nsIUrlClassifierFeature::listType aListType, nsTArray<nsCString>& aTables) {
+  MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist,
+             "UrlClassifierFeatureLoginReputation is meant to be used just to "
+             "whitelist URLs");
+  return UrlClassifierFeatureBase::GetTables(aListType, aTables);
+}
+
+NS_IMETHODIMP
+UrlClassifierFeatureLoginReputation::HasTable(
+    const nsACString& aTable, nsIUrlClassifierFeature::listType aListType,
+    bool* aResult) {
+  MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist,
+             "UrlClassifierFeatureLoginReputation is meant to be used just to "
+             "whitelist URLs");
+  return UrlClassifierFeatureBase::HasTable(aTable, aListType, aResult);
+}
+
+NS_IMETHODIMP
+UrlClassifierFeatureLoginReputation::HasHostInPreferences(
+    const nsACString& aHost, nsIUrlClassifierFeature::listType aListType,
+    nsACString& aPrefTableName, bool* aResult) {
+  MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist,
+             "UrlClassifierFeatureLoginReputation is meant to be used just to "
+             "whitelist URLs");
+  return UrlClassifierFeatureBase::HasHostInPreferences(
+      aHost, aListType, aPrefTableName, aResult);
+}
+
+}  // namespace net
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/netwerk/url-classifier/UrlClassifierFeatureLoginReputation.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_net_UrlClassifierFeatureLoginReputation_h
+#define mozilla_net_UrlClassifierFeatureLoginReputation_h
+
+#include "UrlClassifierFeatureBase.h"
+
+class nsIChannel;
+
+namespace mozilla {
+namespace net {
+
+class UrlClassifierFeatureLoginReputation final
+    : public UrlClassifierFeatureBase {
+ public:
+  static void MaybeShutdown();
+
+  static nsIUrlClassifierFeature* MaybeGetOrCreate();
+
+  NS_IMETHOD
+  GetTables(nsIUrlClassifierFeature::listType aListType,
+            nsTArray<nsCString>& aResult) override;
+
+  NS_IMETHOD
+  HasTable(const nsACString& aTable,
+           nsIUrlClassifierFeature::listType aListType, bool* aResult) override;
+
+  NS_IMETHOD
+  HasHostInPreferences(const nsACString& aHost,
+                       nsIUrlClassifierFeature::listType aListType,
+                       nsACString& aPrefTableName, bool* aResult) override;
+
+  NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
+                            bool* aShouldContinue) override;
+
+ private:
+  UrlClassifierFeatureLoginReputation();
+};
+
+}  // namespace net
+}  // namespace mozilla
+
+#endif  // mozilla_UrlClassifierFeatureLoginReputation_h
--- a/netwerk/url-classifier/moz.build
+++ b/netwerk/url-classifier/moz.build
@@ -18,16 +18,17 @@ DEFINES['GOOGLE_PROTOBUF_NO_RTTI'] = Tru
 DEFINES['GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER'] = True
 
 UNIFIED_SOURCES += [
     'AsyncUrlChannelClassifier.cpp',
     'nsChannelClassifier.cpp',
     'UrlClassifierCommon.cpp',
     'UrlClassifierFeatureBase.cpp',
     'UrlClassifierFeatureFactory.cpp',
+    'UrlClassifierFeatureLoginReputation.cpp',
     'UrlClassifierFeatureResult.cpp',
     'UrlClassifierFeatureTrackingAnnotation.cpp',
     'UrlClassifierFeatureTrackingProtection.cpp',
 ]
 
 EXPORTS.mozilla.net += [
     'AsyncUrlChannelClassifier.h',
     'UrlClassifierCommon.h',
--- a/python/mozbuild/mozbuild/base.py
+++ b/python/mozbuild/mozbuild/base.py
@@ -881,16 +881,23 @@ class MachCommandConditions(object):
     @staticmethod
     def is_firefox(cls):
         """Must have a Firefox build."""
         if hasattr(cls, 'substs'):
             return cls.substs.get('MOZ_BUILD_APP') == 'browser'
         return False
 
     @staticmethod
+    def is_thunderbird(cls):
+        """Must have a Thunderbird build."""
+        if hasattr(cls, 'substs'):
+            return cls.substs.get('MOZ_BUILD_APP') == 'comm/mail'
+        return False
+
+    @staticmethod
     def is_android(cls):
         """Must have an Android build."""
         if hasattr(cls, 'substs'):
             return cls.substs.get('MOZ_WIDGET_TOOLKIT') == 'android'
         return False
 
     @staticmethod
     def is_firefox_or_android(cls):
--- a/testing/mochitest/api.js
+++ b/testing/mochitest/api.js
@@ -53,16 +53,20 @@ function androidStartup() {
     }
 
     windowTracker.init();
   }
 }
 
 // ///// Desktop ///////
 
+// Special case for Thunderbird windows.
+const IS_THUNDERBIRD = Services.appinfo.ID == "{3550f703-e582-4d05-9a08-453d09bdfdc6}";
+const WINDOW_TYPE = IS_THUNDERBIRD ? "mail:3pane" : "navigator:browser";
+
 var WindowListener = {
   // browser-test.js is only loaded into the first window. Setup that
   // needs to happen in all navigator:browser windows should go here.
   setupWindow(win) {
     win.nativeConsole = win.console;
     ChromeUtils.defineModuleGetter(win, "console",
       "resource://gre/modules/Console.jsm");
   },
@@ -73,33 +77,35 @@ var WindowListener = {
       win.nativeConsole = undefined;
     }
   },
 
   onOpenWindow(xulWin) {
     let win = xulWin.docShell.domWindow;
 
     win.addEventListener("load", function() {
-      if (win.document.documentElement.getAttribute("windowtype") == "navigator:browser") {
+      if (win.document.documentElement.getAttribute("windowtype") == WINDOW_TYPE) {
         WindowListener.setupWindow(win);
       }
     }, {once: true});
   },
 };
 
 function loadMochitest(e) {
   let flavor = e.detail[0];
   let url = e.detail[1];
 
-  let win = Services.wm.getMostRecentWindow("navigator:browser");
+  let win = Services.wm.getMostRecentWindow(WINDOW_TYPE);
   win.removeEventListener("mochitest-load", loadMochitest);
 
   // for mochitest-plain, navigating to the url is all we need
-  win.loadURI(url, null, null, null, null, null, null, null,
-    Services.scriptSecurityManager.getSystemPrincipal());
+  if (!IS_THUNDERBIRD) {
+    win.loadURI(url, null, null, null, null, null, null, null,
+      Services.scriptSecurityManager.getSystemPrincipal());
+  }
   if (flavor == "mochitest") {
     return;
   }
 
   WindowListener.setupWindow(win);
   Services.wm.addListener(WindowListener);
 
   loadChromeScripts(win);
@@ -113,26 +119,26 @@ this.mochikit = class extends ExtensionA
     const targetURL = this.extension.rootURI.resolve("content/");
     this.chromeHandle = aomStartup.registerChrome(manifestURI, [
       ["content", "mochikit", targetURL],
     ]);
 
     if (AppConstants.platform == "android") {
       androidStartup();
     } else {
-      let win = Services.wm.getMostRecentWindow("navigator:browser");
+      let win = Services.wm.getMostRecentWindow(WINDOW_TYPE);
       // wait for event fired from start_desktop.js containing the
       // suite and url to load
       win.addEventListener("mochitest-load", loadMochitest);
     }
   }
 
   onShutdown() {
     if (AppConstants.platform != "android") {
-      for (let win of Services.wm.getEnumerator("navigator:browser")) {
+      for (let win of Services.wm.getEnumerator(WINDOW_TYPE)) {
         WindowListener.tearDownWindow(win);
       }
 
       Services.wm.removeListener(WindowListener);
     }
 
     this.chromeHandle.destruct();
     this.chromeHandle = null;
--- a/testing/mochitest/browser-harness.xul
+++ b/testing/mochitest/browser-harness.xul
@@ -227,17 +227,21 @@
 
     function setStatus(aStatusString) {
       document.getElementById("status").value = aStatusString;
     }
 
     function createTester(links) {
       var windowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].
                              getService(Ci.nsIWindowMediator);
-      var winType = gConfig.testRoot == "browser" ? "navigator:browser" : null;
+      var winType = null;
+      if (gConfig.testRoot == "browser") {
+        const IS_THUNDERBIRD = Services.appinfo.ID == "{3550f703-e582-4d05-9a08-453d09bdfdc6}";
+        winType = IS_THUNDERBIRD ? "mail:3pane" : "navigator:browser";
+      }
       if (!winType) {
         throw new Error("Unrecognized gConfig.testRoot: " + gConfig.testRoot);
       }
       var testWin = windowMediator.getMostRecentWindow(winType);
 
       setStatus("Running...");
 
       // It's possible that the test harness window is not yet focused when this
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -498,16 +498,18 @@ Tester.prototype = {
     this.structuredLogger.info("*** Start BrowserChrome Test Results ***");
     Services.console.registerListener(this);
     this._globalProperties = Object.keys(window);
     this._globalPropertyWhitelist = [
       "navigator", "constructor", "top",
       "Application",
       "__SS_tabsToRestore", "__SSi",
       "webConsoleCommandController",
+      // Thunderbird
+      "MailMigrator", "SearchIntegration",
     ];
 
     this.PerTestCoverageUtils.beforeTestSync();
 
     if (this.tests.length) {
       this.waitForWindowsReady().then(() => {
         this.nextTest();
       });
@@ -517,17 +519,17 @@ Tester.prototype = {
   },
 
   async waitForWindowsReady() {
     await new Promise(resolve => this.waitForGraphicsTestWindowToBeGone(resolve));
     await this.promiseMainWindowReady();
   },
 
   async promiseMainWindowReady() {
-    if (!gBrowserInit.idleTasksFinished) {
+    if (window.gBrowserInit && !gBrowserInit.idleTasksFinished) {
       await this.TestUtils.topicObserved("browser-idle-startup-tasks-finished",
                                          subject => subject === window);
     }
   },
 
   waitForGraphicsTestWindowToBeGone(aCallback) {
     for (let win of Services.wm.getEnumerator(null)) {
       if (win != window && !win.closed &&
@@ -579,16 +581,19 @@ Tester.prototype = {
     for (let win of Services.wm.getEnumerator(null)) {
       if (win != window && !win.closed &&
           win.document.documentElement.getAttribute("id") != "browserTestHarness") {
         let type = win.document.documentElement.getAttribute("windowtype");
         switch (type) {
         case "navigator:browser":
           type = "browser window";
           break;
+        case "mail:3pane":
+          type = "mail window";
+          break;
         case null:
           type = "unknown window with document URI: " + win.document.documentURI +
                  " and title: " + win.document.title;
           break;
         }
         let msg = baseMsg.replace("{elt}", type);
         if (this.currentTest) {
           this.currentTest.addResult(new testResult({
@@ -624,17 +629,17 @@ Tester.prototype = {
 
     // In the main process, we print the ShutdownLeaksCollector message here.
     let pid = Services.appinfo.processID;
     dump("Completed ShutdownLeaks collections in process " + pid + "\n");
 
     this.structuredLogger.info("TEST-START | Shutdown");
 
     if (this.tests.length) {
-      let e10sMode = gMultiProcessBrowser ? "e10s" : "non-e10s";
+      let e10sMode = window.gMultiProcessBrowser ? "e10s" : "non-e10s";
       this.structuredLogger.info("Browser Chrome Test Summary");
       this.structuredLogger.info("Passed:  " + passCount);
       this.structuredLogger.info("Failed:  " + failCount);
       this.structuredLogger.info("Todo:    " + todoCount);
       this.structuredLogger.info("Mode:    " + e10sMode);
     } else {
       this.structuredLogger.error("browser-test.js | No tests to run. Did you pass invalid test_paths?");
     }
@@ -902,27 +907,31 @@ Tester.prototype = {
         if (gConfig.testRoot == "browser") {
           // Skip if SeaMonkey
           if (AppConstants.MOZ_APP_NAME != "seamonkey") {
             // Replace the document currently loaded in the browser's sidebar.
             // This will prevent false positives for tests that were the last
             // to touch the sidebar. They will thus not be blamed for leaking
             // a document.
             let sidebar = document.getElementById("sidebar");
-            sidebar.setAttribute("src", "data:text/html;charset=utf-8,");
-            sidebar.docShell.createAboutBlankContentViewer(null);
-            sidebar.setAttribute("src", "about:blank");
+            if (sidebar) {
+              sidebar.setAttribute("src", "data:text/html;charset=utf-8,");
+              sidebar.docShell.createAboutBlankContentViewer(null);
+              sidebar.setAttribute("src", "about:blank");
+            }
           }
 
           // Destroy BackgroundPageThumbs resources.
           let {BackgroundPageThumbs} =
             ChromeUtils.import("resource://gre/modules/BackgroundPageThumbs.jsm", {});
           BackgroundPageThumbs._destroy();
 
-          gBrowser.removePreloadedBrowser();
+          if (window.gBrowser) {
+            gBrowser.removePreloadedBrowser();
+          }
         }
 
         // Schedule GC and CC runs before finishing in order to detect
         // DOM windows leaked by our tests or the tested code. Note that we
         // use a shrinking GC so that the JS engine will discard JIT code and
         // JIT caches more aggressively.
 
         let shutdownCleanup = aCallback => {
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -63,17 +63,17 @@ ROBOCOP_TESTS_NOT_FOUND = '''
 The robocop command could not find any tests under the following
 test path(s):
 
 {}
 
 Please check spelling and make sure the named tests exist.
 '''.lstrip()
 
-SUPPORTED_APPS = ['firefox', 'android']
+SUPPORTED_APPS = ['firefox', 'android', 'thunderbird']
 
 parser = None
 
 
 class MochitestRunner(MozbuildObject):
 
     """Easily run mochitests.
 
--- a/testing/mochitest/mochitest_options.py
+++ b/testing/mochitest/mochitest_options.py
@@ -48,17 +48,17 @@ ALL_FLAVORS = {
         'enabled_apps': ('firefox', 'android'),
         'extra_args': {
             'flavor': 'chrome',
         }
     },
     'browser-chrome': {
         'suite': 'browser',
         'aliases': ('browser', 'browser-chrome', 'mochitest-browser-chrome', 'bc'),
-        'enabled_apps': ('firefox',),
+        'enabled_apps': ('firefox', 'thunderbird'),
         'extra_args': {
             'flavor': 'browser',
         }
     },
     'a11y': {
         'suite': 'a11y',
         'aliases': ('a11y', 'mochitest-a11y', 'accessibility'),
         'enabled_apps': ('firefox',),
--- a/testing/mochitest/start_desktop.js
+++ b/testing/mochitest/start_desktop.js
@@ -6,13 +6,16 @@
 /* global __webDriverArguments */
 const flavor  = __webDriverArguments[0].flavor;
 const url = __webDriverArguments[0].testUrl;
 
 // eslint-disable-next-line mozilla/use-services
 let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
           .getService(Ci.nsIWindowMediator);
 let win = wm.getMostRecentWindow("navigator:browser");
+if (!win) {
+  win = wm.getMostRecentWindow("mail:3pane");
+}
 
 // mochikit's bootstrap.js has set up a listener for this event. It's
 // used so bootstrap.js knows which flavor and url to load.
 let ev = new CustomEvent("mochitest-load", {"detail": [flavor, url]});
 win.dispatchEvent(ev);
--- a/toolkit/components/reputationservice/LoginReputation.cpp
+++ b/toolkit/components/reputationservice/LoginReputation.cpp
@@ -2,44 +2,39 @@
 /* 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/. */
 
 #include "LoginReputation.h"
 #include "nsThreadUtils.h"
 #include "mozilla/ErrorNames.h"
 #include "mozilla/Logging.h"
+#include "mozilla/net/UrlClassifierFeatureFactory.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/StaticPrefs.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/ipc/URIUtils.h"
+#include "nsIUrlClassifierFeature.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #define PREF_PP_ENABLED "browser.safebrowsing.passwords.enabled"
-#define PREF_PASSWORD_ALLOW_TABLE "urlclassifier.passwordAllowTable"
-
-static bool sPasswordProtectionEnabled = false;
 
 // MOZ_LOG=LoginReputation:5
 LazyLogModule gLoginReputationLogModule("LoginReputation");
 #define LR_LOG(args) \
   MOZ_LOG(gLoginReputationLogModule, mozilla::LogLevel::Debug, args)
 #define LR_LOG_ENABLED() \
   MOZ_LOG_TEST(gLoginReputationLogModule, mozilla::LogLevel::Debug)
 
 static Atomic<bool> gShuttingDown(false);
 
-static const char* kObservedPrefs[] = {
-    PREF_PASSWORD_ALLOW_TABLE,
-    nullptr,
-};
-
 // -------------------------------------------------------------------------
 // ReputationQueryParam
 //
 // Concrete class for nsILoginReputationQuery to hold query parameters
 //
 class ReputationQueryParam final : public nsILoginReputationQuery {
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
@@ -62,49 +57,39 @@ ReputationQueryParam::GetFormURI(nsIURI*
 }
 
 // -------------------------------------------------------------------------
 // LoginWhitelist
 //
 // This class is a wrapper that encapsulate asynchronous callback API provided
 // by DBService into a MozPromise callback.
 //
-class LoginWhitelist final : public nsIURIClassifierCallback {
+class LoginWhitelist final : public nsIUrlClassifierFeatureCallback {
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSIURICLASSIFIERCALLBACK
+  NS_DECL_NSIURLCLASSIFIERFEATURECALLBACK
 
   RefPtr<ReputationPromise> QueryLoginWhitelist(
       nsILoginReputationQuery* aParam);
 
   LoginWhitelist() = default;
 
-  nsresult Init();
-  nsresult Uninit();
-
-  void UpdateWhitelistTables();
+  nsresult Shutdown();
 
  private:
   ~LoginWhitelist() = default;
 
-  nsCString mTables;
-
-  // Queries that are waiting for callback from ::AsyncClassifyLocalWithTables.
+  // Queries that are waiting for callback from
+  // ::AsyncClassifyLocalWithFeatures.
   nsTArray<UniquePtr<MozPromiseHolder<ReputationPromise>>> mQueryPromises;
 };
 
-NS_IMPL_ISUPPORTS(LoginWhitelist, nsIURIClassifierCallback)
-
-nsresult LoginWhitelist::Init() {
-  UpdateWhitelistTables();
+NS_IMPL_ISUPPORTS(LoginWhitelist, nsIUrlClassifierFeatureCallback)
 
-  return NS_OK;
-}
-
-nsresult LoginWhitelist::Uninit() {
+nsresult LoginWhitelist::Shutdown() {
   // Reject all query promise before releasing.
   for (uint8_t i = 0; i < mQueryPromises.Length(); i++) {
     mQueryPromises[i]->Reject(NS_ERROR_ABORT, __func__);
   }
   mQueryPromises.Clear();
 
   return NS_OK;
 }
@@ -131,61 +116,62 @@ RefPtr<ReputationPromise> LoginWhitelist
       do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return p;
   }
 
   // AsyncClassifyLocalWithTables API won't trigger a gethash request on
   // a full-length match, so this API call should only include local operation.
   // We don't support prefs overwrite for this classification.
-  rv = uriClassifier->AsyncClassifyLocalWithTables(
-      uri, mTables, nsTArray<nsCString>(), nsTArray<nsCString>(), this);
+
+  nsCOMPtr<nsIUrlClassifierFeature> feature =
+      mozilla::net::UrlClassifierFeatureFactory::GetFeatureLoginReputation();
+  if (NS_WARN_IF(!feature)) {
+    return p;
+  }
+
+  nsTArray<RefPtr<nsIUrlClassifierFeature>> features;
+  features.AppendElement(feature);
+
+  rv = uriClassifier->AsyncClassifyLocalWithFeatures(
+      uri, features, nsIUrlClassifierFeature::whitelist, this);
   if (NS_FAILED(rv)) {
     return p;
   }
 
   fail.release();
   mQueryPromises.AppendElement(std::move(holder));
   return p;
 }
 
-nsresult LoginWhitelist::OnClassifyComplete(nsresult aErrorCode,
-                                            const nsACString& aLists,
-                                            const nsACString& aProvider,
-                                            const nsACString& aFullHash) {
+nsresult LoginWhitelist::OnClassifyComplete(
+    const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aResults) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (gShuttingDown) {
     return NS_OK;
   }
 
-  LR_LOG(("OnClassifyComplete : list = %s", aLists.BeginReading()));
+  LR_LOG(("OnClassifyComplete : %s",
+          aResults.IsEmpty() ? "blacklisted" : "whitelisted"));
 
   UniquePtr<MozPromiseHolder<ReputationPromise>> holder =
       std::move(mQueryPromises.ElementAt(0));
   mQueryPromises.RemoveElementAt(0);
 
-  if (NS_FAILED(aErrorCode)) {
-    // This should not happen
-    MOZ_ASSERT_UNREACHABLE("unexpected error received in OnClassifyComplete");
-    holder->Reject(aErrorCode, __func__);
-  } else if (aLists.IsEmpty()) {
+  if (aResults.IsEmpty()) {
     // Reject if we can not find url in white list.
     holder->Reject(NS_OK, __func__);
   } else {
     holder->Resolve(nsILoginReputationVerdictType::SAFE, __func__);
   }
 
   return NS_OK;
 }
 
-void LoginWhitelist::UpdateWhitelistTables() {
-  Preferences::GetCString(PREF_PASSWORD_ALLOW_TABLE, mTables);
-}
-
 // -------------------------------------------------------------------------
 // LoginReputationService
 //
 NS_IMPL_ISUPPORTS(LoginReputationService, nsILoginReputationService,
                   nsIObserver)
 
 LoginReputationService* LoginReputationService::gLoginReputationService =
     nullptr;
@@ -210,19 +196,16 @@ LoginReputationService::~LoginReputation
 
   gLoginReputationService = nullptr;
 }
 
 NS_IMETHODIMP
 LoginReputationService::Init() {
   MOZ_ASSERT(NS_IsMainThread());
 
-  Preferences::AddBoolVarCache(&sPasswordProtectionEnabled, PREF_PP_ENABLED,
-                               true);
-
   switch (XRE_GetProcessType()) {
     case GeckoProcessType_Default:
       LR_LOG(("Init login reputation service in parent"));
       break;
     case GeckoProcessType_Content:
       LR_LOG(("Init login reputation service in child"));
       // Login reputation service in child process will only forward request to
       // parent, return here to skip unnecessary initialization.
@@ -235,52 +218,42 @@ LoginReputationService::Init() {
   // The initialization below only happens in parent process.
   Preferences::AddStrongObserver(this, PREF_PP_ENABLED);
 
   // Init should only be called once.
   MOZ_ASSERT(!mLoginWhitelist);
 
   mLoginWhitelist = new LoginWhitelist();
 
-  if (sPasswordProtectionEnabled) {
+  if (StaticPrefs::browser_safebrowsing_passwords_enabled()) {
     Enable();
   }
 
   return NS_OK;
 }
 
 nsresult LoginReputationService::Enable() {
   MOZ_ASSERT(XRE_IsParentProcess());
-  MOZ_ASSERT(sPasswordProtectionEnabled);
+  MOZ_ASSERT(StaticPrefs::browser_safebrowsing_passwords_enabled());
 
   LR_LOG(("Enable login reputation service"));
 
-  nsresult rv = mLoginWhitelist->Init();
-  Unused << NS_WARN_IF(NS_FAILED(rv));
-
-  Preferences::AddStrongObservers(this, kObservedPrefs);
-
   return NS_OK;
 }
 
 nsresult LoginReputationService::Disable() {
   MOZ_ASSERT(XRE_IsParentProcess());
 
   LR_LOG(("Disable login reputation service"));
 
-  nsresult rv = mLoginWhitelist->Uninit();
+  nsresult rv = mLoginWhitelist->Shutdown();
   Unused << NS_WARN_IF(NS_FAILED(rv));
 
   mQueryRequests.Clear();
 
-  nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
-  if (prefs) {
-    Preferences::RemoveObservers(this, kObservedPrefs);
-  }
-
   return NS_OK;
 }
 
 nsresult LoginReputationService::Shutdown() {
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(gShuttingDown);
 
@@ -303,17 +276,17 @@ LoginReputationService::ConstructQueryPa
 
 NS_IMETHODIMP
 LoginReputationService::QueryReputationAsync(
     HTMLInputElement* aInput, nsILoginReputationQueryCallback* aCallback) {
   NS_ENSURE_ARG_POINTER(aInput);
 
   LR_LOG(("QueryReputationAsync() [this=%p]", this));
 
-  if (!sPasswordProtectionEnabled) {
+  if (!StaticPrefs::browser_safebrowsing_passwords_enabled()) {
     return NS_ERROR_FAILURE;
   }
 
   nsIURI* documentURI = aInput->OwnerDoc()->GetDocumentURI();
   NS_ENSURE_STATE(documentURI);
 
   if (XRE_IsContentProcess()) {
     using namespace mozilla::ipc;
@@ -346,17 +319,17 @@ LoginReputationService::QueryReputation(
     nsILoginReputationQueryCallback* aCallback) {
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_ARG_POINTER(aQuery);
   NS_ENSURE_ARG_POINTER(aCallback);
 
   LR_LOG(("QueryReputation() [this=%p]", this));
 
-  if (gShuttingDown || !sPasswordProtectionEnabled) {
+  if (gShuttingDown || !StaticPrefs::browser_safebrowsing_passwords_enabled()) {
     LR_LOG(("QueryReputation() abort [this=%p]", this));
     aCallback->OnComplete(NS_ERROR_ABORT,
                           nsILoginReputationVerdictType::UNSPECIFIED);
     return NS_OK;
   }
 
   // mQueryRequests is an array used to maintain the ownership of
   // |QueryRequest|. We ensure that |QueryRequest| is always valid until
@@ -474,20 +447,18 @@ nsresult LoginReputationService::Finish(
 
 NS_IMETHODIMP
 LoginReputationService::Observe(nsISupports* aSubject, const char* aTopic,
                                 const char16_t* aData) {
   if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
     nsDependentString data(aData);
 
     if (data.EqualsLiteral(PREF_PP_ENABLED)) {
-      nsresult rv = sPasswordProtectionEnabled ? Enable() : Disable();
+      nsresult rv = StaticPrefs::browser_safebrowsing_passwords_enabled() ?  Enable() : Disable();
       Unused << NS_WARN_IF(NS_FAILED(rv));
-    } else if (data.EqualsLiteral(PREF_PASSWORD_ALLOW_TABLE)) {
-      mLoginWhitelist->UpdateWhitelistTables();
     }
   } else if (!strcmp(aTopic, "quit-application")) {
     // Prepare to shutdown, won't allow any query request after 'gShuttingDown'
     // is set.
     gShuttingDown = true;
   } else if (!strcmp(aTopic, "profile-before-change")) {
     gShuttingDown = true;
     Shutdown();
--- a/toolkit/components/reputationservice/LoginReputation.h
+++ b/toolkit/components/reputationservice/LoginReputation.h
@@ -1,21 +1,22 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #ifndef LoginReputation_h__
 #define LoginReputation_h__
 
-#include "nsILoginReputation.h"
-#include "nsIURIClassifier.h"
-#include "nsIObserver.h"
 #include "mozilla/Logging.h"
 #include "mozilla/MozPromise.h"
+#include "nsILoginReputation.h"
+#include "nsIObserver.h"
+#include "nsISupportsImpl.h"
+#include "nsIURIClassifier.h"
 
 class LoginWhitelist;
 
 namespace mozilla {
 
 typedef uint32_t VerdictType;
 typedef MozPromise<VerdictType, nsresult, false> ReputationPromise;
 
--- a/toolkit/components/url-classifier/nsCheckSummedOutputStream.h
+++ b/toolkit/components/url-classifier/nsCheckSummedOutputStream.h
@@ -5,16 +5,17 @@
 
 #ifndef nsCheckSummedOutputStream_h__
 #define nsCheckSummedOutputStream_h__
 
 #include "nsIFile.h"
 #include "nsIOutputStream.h"
 #include "nsICryptoHash.h"
 #include "nsNetCID.h"
+#include "nsNetUtil.h"
 #include "nsString.h"
 #include "nsToolkitCompsCID.h"
 #include "../../../netwerk/base/nsBufferedStreams.h"
 #include "prio.h"
 
 class nsCheckSummedOutputStream : public nsBufferedOutputStream {
  public:
   NS_DECL_ISUPPORTS_INHERITED
--- a/toolkit/themes/osx/global/findBar.css
+++ b/toolkit/themes/osx/global/findBar.css
@@ -35,17 +35,17 @@ label.findbar-find-fast:-moz-lwtheme {
 }
 
 .findbar-find-next:not(:-moz-lwtheme),
 .findbar-find-previous:not(:-moz-lwtheme),
 .findbar-button {
   border-style: @roundButtonBorderStyle@;
   border-color: @roundButtonBorderColor@;
   color: @roundButtonColor@;
-  background-image: @roundButtonBackground@;
+  background-image: @roundButtonBackgroundImage@;
 }
 
 .findbar-button {
   -moz-appearance: none;
   border-width: @roundButtonBorderWidth@;
   margin-inline-end: 5px;
   padding: 2px 9px;
   border-radius: 10000px;
@@ -55,17 +55,17 @@ label.findbar-find-fast:-moz-lwtheme {
 .findbar-find-previous:-moz-lwtheme {
   border-color: var(--lwt-toolbar-field-border-color, @roundButtonBorderColor@);
 }
 
 .findbar-find-next:not(:-moz-lwtheme):not([disabled]):hover:active,
 .findbar-find-previous:not(:-moz-lwtheme):not([disabled]):hover:active,
 .findbar-button:not([disabled]):hover:active,
 .findbar-button:not([disabled])[checked="true"] {
-  background-image: @roundButtonPressedBackground@;
+  background-image: @roundButtonPressedBackgroundImage@;
   box-shadow: @roundButtonPressedShadow@;
 }
 
 @media (-moz-mac-yosemite-theme: 0) {
   .findbar-textbox,
   .findbar-find-next {
     border-radius: 10000px;
   }
--- a/toolkit/themes/osx/global/global.css
+++ b/toolkit/themes/osx/global/global.css
@@ -223,23 +223,23 @@ notification > hbox > button {
   padding: 1px 10px;
   min-width: 60px;
   min-height: 16px;
   -moz-appearance: none;
   border-radius: 10000px;
   border: @roundButtonBorderWidth@ @roundButtonBorderStyle@ @roundButtonBorderColor@;
   text-shadow: @loweredShadow@;
   color: @roundButtonColor@;
-  background: @roundButtonBackground@;
+  background: @roundButtonBackgroundImage@;
   box-shadow: @roundButtonShadow@;
 }
 
 notification > hbox > button:active:hover {
   color: @roundButtonColor@;
-  background: @roundButtonPressedBackground@;
+  background: @roundButtonPressedBackgroundImage@;
   box-shadow: @roundButtonPressedShadow@;
 }
 
 notification > hbox > button:-moz-focusring {
   box-shadow: var(--focus-ring-box-shadow), @roundButtonShadow@;
 }
 
 notification > hbox > button:active:hover:-moz-focusring {
--- a/toolkit/themes/osx/global/shared.inc
+++ b/toolkit/themes/osx/global/shared.inc
@@ -2,19 +2,19 @@
 
 %define loweredShadow 0 1px rgba(255, 255, 255, .4)
 %define focusRingShadow 0 0 0 1px -moz-mac-focusring inset, 0 0 0 1px -moz-mac-focusring
 
 %define roundButtonBorderWidth 1px
 %define roundButtonBorderStyle solid
 %define roundButtonBorderColor rgba(0,0,0,.35)
 %define roundButtonColor black
-%define roundButtonBackground linear-gradient(#f6f6f6, #e9e9e9)
+%define roundButtonBackgroundImage linear-gradient(#f6f6f6, #e9e9e9)
 %define roundButtonShadow 0 1px rgba(255,255,255,.5), inset 0 1px 1px rgba(255,255,255,.5)
-%define roundButtonPressedBackground linear-gradient(#dadada, #dadada)
+%define roundButtonPressedBackgroundImage linear-gradient(#dadada, #dadada)
 %define roundButtonPressedShadow 0 1px rgba(255,255,255,.4), inset 0 1px 3px rgba(0,0,0,.2)
 
 %define scopeBarBackground linear-gradient(#E8E8E8, #D0D0D0) repeat-x
 %define scopeBarSeparatorBorder 1px solid #888
 %define scopeBarTitleColor #6D6D6D
 
 %define toolbarbuttonBackground linear-gradient(#FFF, #ADADAD) repeat-x
 %define toolbarbuttonPressedInnerShadow inset rgba(0, 0, 0, 0.3) 0 -6px 10px, inset #000 0 1px 3px, inset rgba(0, 0, 0, 0.2) 0 1px 3px
--- a/xpcom/ds/StaticAtoms.py
+++ b/xpcom/ds/StaticAtoms.py
@@ -666,17 +666,16 @@ STATIC_ATOMS = [
     Atom("mozTableAddColumnAfter", "mozTableAddColumnAfter"),
     Atom("mozTableAddColumnBefore", "mozTableAddColumnBefore"),
     Atom("mozTableAddRowAfter", "mozTableAddRowAfter"),
     Atom("mozTableAddRowBefore", "mozTableAddRowBefore"),
     Atom("mozTableRemoveRow", "mozTableRemoveRow"),
     Atom("mozTableRemoveColumn", "mozTableRemoveColumn"),
     Atom("moz_opaque", "moz-opaque"),
     Atom("moz_action_hint", "mozactionhint"),
-    Atom("x_moz_errormessage", "x-moz-errormessage"),
     Atom("multicol", "multicol"),
     Atom("multiple", "multiple"),
     Atom("muted", "muted"),
     Atom("name", "name"),
     Atom("_namespace", "namespace"),
     Atom("namespaceAlias", "namespace-alias"),
     Atom("namespaceUri", "namespace-uri"),
     Atom("NaN", "NaN"),