Merge inbound to central, a=merge
authorWes Kocher <wkocher@mozilla.com>
Wed, 22 Feb 2017 15:01:04 -0800
changeset 344314 32dcdde1fc64fc39a9065dc4218265dbc727673f
parent 344272 499739e68fada7112afe8e5a9ce4744d1e4f07e6 (current diff)
parent 344313 0115e2684986a113ad8c7eb347e8c6a71801a444 (diff)
child 344339 3f649bdc6e81279547ff1f29d9d55dcd39d78ef2
child 344422 8cc3aeab4bd114af858aaf3d3690e289932153bb
push id31406
push userkwierso@gmail.com
push dateWed, 22 Feb 2017 23:01:18 +0000
treeherdermozilla-central@32dcdde1fc64 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone54.0a1
first release with
nightly linux32
32dcdde1fc64 / 54.0a1 / 20170223110219 / files
nightly linux64
32dcdde1fc64 / 54.0a1 / 20170223110219 / files
nightly mac
32dcdde1fc64 / 54.0a1 / 20170223030204 / files
nightly win32
32dcdde1fc64 / 54.0a1 / 20170223030204 / files
nightly win64
32dcdde1fc64 / 54.0a1 / 20170223030204 / 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 central, a=merge MozReview-Commit-ID: 2R3yE5OIznC
browser/components/sessionstore/SessionStore.jsm
docshell/base/nsDocShell.cpp
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/media/MediaPrefs.h
dom/system/tests/marionette/manifest.ini
dom/system/tests/marionette/test_proximity_change.js
dom/system/tests/marionette/test_proximity_init.js
testing/web-platform/meta/html/semantics/tabular-data/the-caption-element/caption_001.html.ini
testing/web-platform/meta/html/semantics/tabular-data/the-table-element/caption-methods.html.ini
testing/web-platform/meta/html/semantics/tabular-data/the-table-element/tHead.html.ini
testing/web-platform/meta/html/semantics/tabular-data/the-table-element/table-insertRow.html.ini
testing/web-platform/meta/referrer-policy/generic/subresource-test/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/http-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/http-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/http-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/http-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/http-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/http-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/http-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/http-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/meta-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/meta-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/http-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/http-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/http-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/http-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/meta-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/meta-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-only/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/http-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/http-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/http-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/http-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/strict-origin-when-cross-origin/__dir__.ini
testing/web-platform/meta/referrer-policy/strict-origin/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/http-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/http-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/http-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/http-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/meta-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/meta-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/http-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/http-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/http-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/http-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-csp/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-csp/same-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
--- a/caps/moz.build
+++ b/caps/moz.build
@@ -36,16 +36,17 @@ EXPORTS.mozilla = [
 SOURCES += [
     # Compile this separately since nsExceptionHandler.h conflicts
     # with something from nsNullPrincipal.cpp.
     'BasePrincipal.cpp',
 ]
 
 UNIFIED_SOURCES += [
     'DomainPolicy.cpp',
+    'nsExpandedPrincipal.cpp',
     'nsJSPrincipals.cpp',
     'nsNullPrincipal.cpp',
     'nsNullPrincipalURI.cpp',
     'nsPrincipal.cpp',
     'nsScriptSecurityManager.cpp',
     'nsSystemPrincipal.cpp',
 ]
 
copy from caps/nsPrincipal.cpp
copy to caps/nsExpandedPrincipal.cpp
--- a/caps/nsPrincipal.cpp
+++ b/caps/nsExpandedPrincipal.cpp
@@ -1,471 +1,19 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=2 et 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 "nsPrincipal.h"
-
-#include "mozIThirdPartyUtil.h"
-#include "nscore.h"
-#include "nsScriptSecurityManager.h"
-#include "nsString.h"
-#include "nsReadableUtils.h"
-#include "pratom.h"
-#include "nsIURI.h"
-#include "nsIURL.h"
-#include "nsIStandardURL.h"
-#include "nsIURIWithPrincipal.h"
-#include "nsJSPrincipals.h"
-#include "nsIEffectiveTLDService.h"
+#include "nsExpandedPrincipal.h"
 #include "nsIClassInfoImpl.h"
-#include "nsIProtocolHandler.h"
-#include "nsError.h"
-#include "nsIContentSecurityPolicy.h"
-#include "nsNetCID.h"
-#include "jswrapper.h"
-
-#include "mozilla/dom/nsCSPContext.h"
-#include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/HashFunctions.h"
 
 using namespace mozilla;
 
-static bool gCodeBasePrincipalSupport = false;
-
-static bool URIIsImmutable(nsIURI* aURI)
-{
-  nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
-  bool isMutable;
-  return
-    mutableObj &&
-    NS_SUCCEEDED(mutableObj->GetMutable(&isMutable)) &&
-    !isMutable;
-}
-
-NS_IMPL_CLASSINFO(nsPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
-                  NS_PRINCIPAL_CID)
-NS_IMPL_QUERY_INTERFACE_CI(nsPrincipal,
-                           nsIPrincipal,
-                           nsISerializable)
-NS_IMPL_CI_INTERFACE_GETTER(nsPrincipal,
-                            nsIPrincipal,
-                            nsISerializable)
-
-// Called at startup:
-/* static */ void
-nsPrincipal::InitializeStatics()
-{
-  Preferences::AddBoolVarCache(&gCodeBasePrincipalSupport,
-                               "signed.applets.codebase_principal_support",
-                               false);
-}
-
-nsPrincipal::nsPrincipal()
-  : mCodebaseImmutable(false)
-  , mDomainImmutable(false)
-  , mInitialized(false)
-{ }
-
-nsPrincipal::~nsPrincipal()
-{
-  // let's clear the principal within the csp to avoid a tangling pointer
-  if (mCSP) {
-    static_cast<nsCSPContext*>(mCSP.get())->clearLoadingPrincipal();
-  }
-}
-
-nsresult
-nsPrincipal::Init(nsIURI *aCodebase, const OriginAttributes& aOriginAttributes)
-{
-  NS_ENSURE_STATE(!mInitialized);
-  NS_ENSURE_ARG(aCodebase);
-
-  mInitialized = true;
-
-  mCodebase = NS_TryToMakeImmutable(aCodebase);
-  mCodebaseImmutable = URIIsImmutable(mCodebase);
-  mOriginAttributes = aOriginAttributes;
-
-  return NS_OK;
-}
-
-nsresult
-nsPrincipal::GetScriptLocation(nsACString &aStr)
-{
-  return mCodebase->GetSpec(aStr);
-}
-
-nsresult
-nsPrincipal::GetOriginInternal(nsACString& aOrigin)
-{
-  if (!mCodebase) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<nsIURI> origin = NS_GetInnermostURI(mCodebase);
-  if (!origin) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsAutoCString hostPort;
-
-  // chrome: URLs don't have a meaningful origin, so make
-  // sure we just get the full spec for them.
-  // XXX this should be removed in favor of the solution in
-  // bug 160042.
-  bool isChrome;
-  nsresult rv = origin->SchemeIs("chrome", &isChrome);
-  if (NS_SUCCEEDED(rv) && !isChrome) {
-    rv = origin->GetAsciiHostPort(hostPort);
-    // Some implementations return an empty string, treat it as no support
-    // for asciiHost by that implementation.
-    if (hostPort.IsEmpty()) {
-      rv = NS_ERROR_FAILURE;
-    }
-  }
-
-  // We want the invariant that prinA.origin == prinB.origin i.f.f.
-  // prinA.equals(prinB). However, this requires that we impose certain constraints
-  // on the behavior and origin semantics of principals, and in particular, forbid
-  // creating origin strings for principals whose equality constraints are not
-  // expressible as strings (i.e. object equality). Moreover, we want to forbid URIs
-  // containing the magic "^" we use as a separating character for origin
-  // attributes.
-  //
-  // These constraints can generally be achieved by restricting .origin to
-  // nsIStandardURL-based URIs, but there are a few other URI schemes that we need
-  // to handle.
-  bool isBehaved;
-  if ((NS_SUCCEEDED(origin->SchemeIs("about", &isBehaved)) && isBehaved) ||
-      (NS_SUCCEEDED(origin->SchemeIs("moz-safe-about", &isBehaved)) && isBehaved) ||
-      (NS_SUCCEEDED(origin->SchemeIs("indexeddb", &isBehaved)) && isBehaved)) {
-    rv = origin->GetAsciiSpec(aOrigin);
-    NS_ENSURE_SUCCESS(rv, rv);
-    // These URIs could technically contain a '^', but they never should.
-    if (NS_WARN_IF(aOrigin.FindChar('^', 0) != -1)) {
-      aOrigin.Truncate();
-      return NS_ERROR_FAILURE;
-    }
-    return NS_OK;
-  }
-
-  if (NS_SUCCEEDED(rv) && !isChrome) {
-    rv = origin->GetScheme(aOrigin);
-    NS_ENSURE_SUCCESS(rv, rv);
-    aOrigin.AppendLiteral("://");
-    aOrigin.Append(hostPort);
-    return NS_OK;
-  }
-
-  // This URL can be a blobURL. In this case, we should use the 'parent'
-  // principal instead.
-  nsCOMPtr<nsIURIWithPrincipal> uriWithPrincipal = do_QueryInterface(origin);
-  if (uriWithPrincipal) {
-    nsCOMPtr<nsIPrincipal> uriPrincipal;
-    rv = uriWithPrincipal->GetPrincipal(getter_AddRefs(uriPrincipal));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (uriPrincipal) {
-      return uriPrincipal->GetOriginNoSuffix(aOrigin);
-    }
-  }
-
-  // If we reached this branch, we can only create an origin if we have a
-  // nsIStandardURL.  So, we query to a nsIStandardURL, and fail if we aren't
-  // an instance of an nsIStandardURL nsIStandardURLs have the good property
-  // of escaping the '^' character in their specs, which means that we can be
-  // sure that the caret character (which is reserved for delimiting the end
-  // of the spec, and the beginning of the origin attributes) is not present
-  // in the origin string
-  nsCOMPtr<nsIStandardURL> standardURL = do_QueryInterface(origin);
-  NS_ENSURE_TRUE(standardURL, NS_ERROR_FAILURE);
-
-  rv = origin->GetAsciiSpec(aOrigin);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // The origin, when taken from the spec, should not contain the ref part of
-  // the URL.
-
-  int32_t pos = aOrigin.FindChar('?');
-  int32_t hashPos = aOrigin.FindChar('#');
-
-  if (hashPos != kNotFound && (pos == kNotFound || hashPos < pos)) {
-    pos = hashPos;
-  }
-
-  if (pos != kNotFound) {
-    aOrigin.Truncate(pos);
-  }
-
-  return NS_OK;
-}
-
-bool
-nsPrincipal::SubsumesInternal(nsIPrincipal* aOther,
-                              BasePrincipal::DocumentDomainConsideration aConsideration)
-{
-  MOZ_ASSERT(aOther);
-
-  // For nsPrincipal, Subsumes is equivalent to Equals.
-  if (aOther == this) {
-    return true;
-  }
-
-  // If either the subject or the object has changed its principal by
-  // explicitly setting document.domain then the other must also have
-  // done so in order to be considered the same origin. This prevents
-  // DNS spoofing based on document.domain (154930)
-  nsresult rv;
-  if (aConsideration == ConsiderDocumentDomain) {
-    // Get .domain on each principal.
-    nsCOMPtr<nsIURI> thisDomain, otherDomain;
-    GetDomain(getter_AddRefs(thisDomain));
-    aOther->GetDomain(getter_AddRefs(otherDomain));
-
-    // If either has .domain set, we have equality i.f.f. the domains match.
-    // Otherwise, we fall through to the non-document-domain-considering case.
-    if (thisDomain || otherDomain) {
-      return nsScriptSecurityManager::SecurityCompareURIs(thisDomain, otherDomain);
-    }
-  }
-
-  nsCOMPtr<nsIURI> otherURI;
-  rv = aOther->GetURI(getter_AddRefs(otherURI));
-  NS_ENSURE_SUCCESS(rv, false);
-
-  // Compare codebases.
-  return nsScriptSecurityManager::SecurityCompareURIs(mCodebase, otherURI);
-}
-
-NS_IMETHODIMP
-nsPrincipal::GetURI(nsIURI** aURI)
-{
-  if (mCodebaseImmutable) {
-    NS_ADDREF(*aURI = mCodebase);
-    return NS_OK;
-  }
-
-  if (!mCodebase) {
-    *aURI = nullptr;
-    return NS_OK;
-  }
-
-  return NS_EnsureSafeToReturn(mCodebase, aURI);
-}
-
-bool
-nsPrincipal::MayLoadInternal(nsIURI* aURI)
-{
-  // See if aURI is something like a Blob URI that is actually associated with
-  // a principal.
-  nsCOMPtr<nsIURIWithPrincipal> uriWithPrin = do_QueryInterface(aURI);
-  nsCOMPtr<nsIPrincipal> uriPrin;
-  if (uriWithPrin) {
-    uriWithPrin->GetPrincipal(getter_AddRefs(uriPrin));
-  }
-  if (uriPrin) {
-    return nsIPrincipal::Subsumes(uriPrin);
-  }
-
-  // If this principal is associated with an addon, check whether that addon
-  // has been given permission to load from this domain.
-  if (AddonAllowsLoad(aURI)) {
-    return true;
-  }
-
-  if (nsScriptSecurityManager::SecurityCompareURIs(mCodebase, aURI)) {
-    return true;
-  }
-
-  // If strict file origin policy is in effect, local files will always fail
-  // SecurityCompareURIs unless they are identical. Explicitly check file origin
-  // policy, in that case.
-  if (nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
-      NS_URIIsLocalFile(aURI) &&
-      NS_RelaxStrictFileOriginPolicy(aURI, mCodebase)) {
-    return true;
-  }
-
-  return false;
-}
-
-void
-nsPrincipal::SetURI(nsIURI* aURI)
-{
-  mCodebase = NS_TryToMakeImmutable(aURI);
-  mCodebaseImmutable = URIIsImmutable(mCodebase);
-}
-
-NS_IMETHODIMP
-nsPrincipal::GetHashValue(uint32_t* aValue)
-{
-  NS_PRECONDITION(mCodebase, "Need a codebase");
-
-  *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPrincipal::GetDomain(nsIURI** aDomain)
-{
-  if (!mDomain) {
-    *aDomain = nullptr;
-    return NS_OK;
-  }
-
-  if (mDomainImmutable) {
-    NS_ADDREF(*aDomain = mDomain);
-    return NS_OK;
-  }
-
-  return NS_EnsureSafeToReturn(mDomain, aDomain);
-}
-
-NS_IMETHODIMP
-nsPrincipal::SetDomain(nsIURI* aDomain)
-{
-  mDomain = NS_TryToMakeImmutable(aDomain);
-  mDomainImmutable = URIIsImmutable(mDomain);
-
-  // Recompute all wrappers between compartments using this principal and other
-  // non-chrome compartments.
-  AutoSafeJSContext cx;
-  JSPrincipals *principals = nsJSPrincipals::get(static_cast<nsIPrincipal*>(this));
-  bool success = js::RecomputeWrappers(cx, js::ContentCompartmentsOnly(),
-                                       js::CompartmentsWithPrincipals(principals));
-  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
-  success = js::RecomputeWrappers(cx, js::CompartmentsWithPrincipals(principals),
-                                  js::ContentCompartmentsOnly());
-  NS_ENSURE_TRUE(success, NS_ERROR_FAILURE);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPrincipal::GetBaseDomain(nsACString& aBaseDomain)
-{
-  // For a file URI, we return the file path.
-  if (NS_URIIsLocalFile(mCodebase)) {
-    nsCOMPtr<nsIURL> url = do_QueryInterface(mCodebase);
-
-    if (url) {
-      return url->GetFilePath(aBaseDomain);
-    }
-  }
-
-  bool hasNoRelativeFlag;
-  nsresult rv = NS_URIChainHasFlags(mCodebase,
-                                    nsIProtocolHandler::URI_NORELATIVE,
-                                    &hasNoRelativeFlag);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (hasNoRelativeFlag) {
-    return mCodebase->GetSpec(aBaseDomain);
-  }
-
-  // For everything else, we ask the TLD service via
-  // the ThirdPartyUtil.
-  nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
-    do_GetService(THIRDPARTYUTIL_CONTRACTID);
-  if (thirdPartyUtil) {
-    return thirdPartyUtil->GetBaseDomain(mCodebase, aBaseDomain);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPrincipal::Read(nsIObjectInputStream* aStream)
-{
-  nsCOMPtr<nsISupports> supports;
-  nsCOMPtr<nsIURI> codebase;
-  nsresult rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  codebase = do_QueryInterface(supports);
-
-  nsCOMPtr<nsIURI> domain;
-  rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  domain = do_QueryInterface(supports);
-
-  nsAutoCString suffix;
-  rv = aStream->ReadCString(suffix);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  OriginAttributes attrs;
-  bool ok = attrs.PopulateFromSuffix(suffix);
-  NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
-
-  rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = Init(codebase, attrs);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mCSP = do_QueryInterface(supports, &rv);
-  // make sure setRequestContext is called after Init(),
-  // to make sure  the principals URI been initalized.
-  if (mCSP) {
-    mCSP->SetRequestContext(nullptr, this);
-  }
-
-  SetDomain(domain);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPrincipal::Write(nsIObjectOutputStream* aStream)
-{
-  NS_ENSURE_STATE(mCodebase);
-  nsresult rv = NS_WriteOptionalCompoundObject(aStream, mCodebase, NS_GET_IID(nsIURI),
-                                               true);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  rv = NS_WriteOptionalCompoundObject(aStream, mDomain, NS_GET_IID(nsIURI),
-                                      true);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  nsAutoCString suffix;
-  OriginAttributesRef().CreateSuffix(suffix);
-
-  rv = aStream->WriteStringZ(suffix.get());
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = NS_WriteOptionalCompoundObject(aStream, mCSP,
-                                      NS_GET_IID(nsIContentSecurityPolicy),
-                                      true);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  // mCodebaseImmutable and mDomainImmutable will be recomputed based
-  // on the deserialized URIs in Read().
-
-  return NS_OK;
-}
-
-/************************************************************************************************************************/
-
 NS_IMPL_CLASSINFO(nsExpandedPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
                   NS_EXPANDEDPRINCIPAL_CID)
 NS_IMPL_QUERY_INTERFACE_CI(nsExpandedPrincipal,
                            nsIPrincipal,
                            nsIExpandedPrincipal)
 NS_IMPL_CI_INTERFACE_GETTER(nsExpandedPrincipal,
                              nsIPrincipal,
                              nsIExpandedPrincipal)
copy from caps/nsPrincipal.h
copy to caps/nsExpandedPrincipal.h
--- a/caps/nsPrincipal.h
+++ b/caps/nsExpandedPrincipal.h
@@ -1,69 +1,24 @@
 /* -*- Mode: C++; tab-width: 2; 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 nsPrincipal_h__
-#define nsPrincipal_h__
+#ifndef nsExpandedPrincipal_h
+#define nsExpandedPrincipal_h
 
 #include "nsCOMPtr.h"
 #include "nsJSPrincipals.h"
 #include "nsTArray.h"
-#include "nsIContentSecurityPolicy.h"
-#include "nsIProtocolHandler.h"
 #include "nsNetUtil.h"
-#include "nsScriptSecurityManager.h"
 #include "mozilla/BasePrincipal.h"
 
-class nsPrincipal final : public mozilla::BasePrincipal
-{
-public:
-  NS_DECL_NSISERIALIZABLE
-  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
-  NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
-  NS_IMETHOD GetURI(nsIURI** aURI) override;
-  NS_IMETHOD GetDomain(nsIURI** aDomain) override;
-  NS_IMETHOD SetDomain(nsIURI* aDomain) override;
-  NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
-  bool IsCodebasePrincipal() const override { return true; }
-  nsresult GetOriginInternal(nsACString& aOrigin) override;
-
-  nsPrincipal();
-
-  // Init() must be called before the principal is in a usable state.
-  nsresult Init(nsIURI* aCodebase,
-                const mozilla::OriginAttributes& aOriginAttributes);
-
-  virtual nsresult GetScriptLocation(nsACString& aStr) override;
-  void SetURI(nsIURI* aURI);
-
-  /**
-   * Called at startup to setup static data, e.g. about:config pref-observers.
-   */
-  static void InitializeStatics();
-
-  PrincipalKind Kind() override { return eCodebasePrincipal; }
-
-  nsCOMPtr<nsIURI> mDomain;
-  nsCOMPtr<nsIURI> mCodebase;
-  // If mCodebaseImmutable is true, mCodebase is non-null and immutable
-  bool mCodebaseImmutable;
-  bool mDomainImmutable;
-  bool mInitialized;
-
-protected:
-  virtual ~nsPrincipal();
-
-  bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
-  bool MayLoadInternal(nsIURI* aURI) override;
-};
-
-class nsExpandedPrincipal : public nsIExpandedPrincipal, public mozilla::BasePrincipal
+class nsExpandedPrincipal : public nsIExpandedPrincipal
+                          , public mozilla::BasePrincipal
 {
 public:
   nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
                       const mozilla::OriginAttributes& aAttrs);
 
   NS_DECL_NSIEXPANDEDPRINCIPAL
   NS_DECL_NSISERIALIZABLE
   NS_IMETHOD_(MozExternalRefCountType) AddRef() override { return nsJSPrincipals::AddRef(); };
@@ -85,19 +40,14 @@ protected:
 
   bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
   bool MayLoadInternal(nsIURI* aURI) override;
 
 private:
   nsTArray< nsCOMPtr<nsIPrincipal> > mPrincipals;
 };
 
-#define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"
-#define NS_PRINCIPAL_CID \
-{ 0x653e0e4d, 0x3ee4, 0x45fa, \
-  { 0xb2, 0x72, 0x97, 0xc2, 0x0b, 0xc0, 0x1e, 0xb8 } }
-
 #define NS_EXPANDEDPRINCIPAL_CONTRACTID "@mozilla.org/expandedprincipal;1"
 #define NS_EXPANDEDPRINCIPAL_CID \
 { 0xe8ee88b0, 0x5571, 0x4086, \
   { 0xa4, 0x5b, 0x39, 0xa7, 0x16, 0x90, 0x6b, 0xdb } }
 
-#endif // nsPrincipal_h__
+#endif // nsExpandedPrincipal_h
--- a/caps/nsIPrincipal.idl
+++ b/caps/nsIPrincipal.idl
@@ -6,19 +6,39 @@
 /* Defines the abstract interface for a principal. */
 
 #include "nsISerializable.idl"
 
 %{C++
 struct JSPrincipals;
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
+#include "mozilla/DebugOnly.h"
 namespace mozilla {
 class OriginAttributes;
 }
+
+/**
+ * Some methods have a fast path for the case when we're comparing a principal
+ * to itself. The situation may happen for example with about:blank documents.
+ */
+
+#define DECL_FAST_INLINE_HELPER(method_)                       \
+  inline bool method_(nsIPrincipal* aOther)                    \
+  {                                                            \
+    mozilla::DebugOnly<bool> val = false;                      \
+    MOZ_ASSERT_IF(this == aOther,                              \
+                  NS_SUCCEEDED(method_(aOther, &val)) && val); \
+                                                               \
+    bool retVal = false;                                       \
+    return                                                     \
+      this == aOther ||                                        \
+      (NS_SUCCEEDED(method_(aOther, &retVal)) && retVal);      \
+  }
+
 %}
 
 interface nsIURI;
 interface nsIContentSecurityPolicy;
 interface nsIDOMDocument;
 
 [ptr] native JSContext(JSContext);
 [ptr] native JSPrincipals(JSPrincipals);
@@ -36,25 +56,18 @@ interface nsIPrincipal : nsISerializable
     boolean equals(in nsIPrincipal other);
 
     /**
      * Like equals, but takes document.domain changes into account.
      */
     boolean equalsConsideringDomain(in nsIPrincipal other);
 
     %{C++
-    inline bool Equals(nsIPrincipal* aOther) {
-      bool equal = false;
-      return NS_SUCCEEDED(Equals(aOther, &equal)) && equal;
-    }
-
-    inline bool EqualsConsideringDomain(nsIPrincipal* aOther) {
-      bool equal = false;
-      return NS_SUCCEEDED(EqualsConsideringDomain(aOther, &equal)) && equal;
-    }
+      DECL_FAST_INLINE_HELPER(Equals)
+      DECL_FAST_INLINE_HELPER(EqualsConsideringDomain)
     %}
 
     /**
      * Returns a hash value for the principal.
      */
     [noscript] readonly attribute unsigned long hashValue;
 
     /**
@@ -96,30 +109,20 @@ interface nsIPrincipal : nsISerializable
 
     /**
      * Same as the subsumesConsideringDomain(), but ignores the first party
      * domain in its originAttributes.
      */
     boolean subsumesConsideringDomainIgnoringFPD(in nsIPrincipal other);
 
     %{C++
-    inline bool Subsumes(nsIPrincipal* aOther) {
-      bool subsumes = false;
-      return NS_SUCCEEDED(Subsumes(aOther, &subsumes)) && subsumes;
-    }
-
-    inline bool SubsumesConsideringDomain(nsIPrincipal* aOther) {
-      bool subsumes = false;
-      return NS_SUCCEEDED(SubsumesConsideringDomain(aOther, &subsumes)) && subsumes;
-    }
-
-    inline bool SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther) {
-      bool subsumes = false;
-      return NS_SUCCEEDED(SubsumesConsideringDomainIgnoringFPD(aOther, &subsumes)) && subsumes;
-    }
+      DECL_FAST_INLINE_HELPER(Subsumes)
+      DECL_FAST_INLINE_HELPER(SubsumesConsideringDomain)
+      DECL_FAST_INLINE_HELPER(SubsumesConsideringDomainIgnoringFPD)
+#undef DECL_FAST_INLINE_HELPER
     %}
 
     /**
      * Checks whether this principal is allowed to load the network resource
      * located at the given URI under the same-origin policy. This means that
      * codebase principals are only allowed to load resources from the same
      * domain, the system principal is allowed to load anything, and null
      * principals can only load URIs where they are the principal. This is
--- a/caps/nsPrincipal.cpp
+++ b/caps/nsPrincipal.cpp
@@ -453,208 +453,8 @@ nsPrincipal::Write(nsIObjectOutputStream
     return rv;
   }
 
   // mCodebaseImmutable and mDomainImmutable will be recomputed based
   // on the deserialized URIs in Read().
 
   return NS_OK;
 }
-
-/************************************************************************************************************************/
-
-NS_IMPL_CLASSINFO(nsExpandedPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
-                  NS_EXPANDEDPRINCIPAL_CID)
-NS_IMPL_QUERY_INTERFACE_CI(nsExpandedPrincipal,
-                           nsIPrincipal,
-                           nsIExpandedPrincipal)
-NS_IMPL_CI_INTERFACE_GETTER(nsExpandedPrincipal,
-                             nsIPrincipal,
-                             nsIExpandedPrincipal)
-
-struct OriginComparator
-{
-  bool LessThan(nsIPrincipal* a, nsIPrincipal* b) const
-  {
-    nsAutoCString originA;
-    nsresult rv = a->GetOrigin(originA);
-    NS_ENSURE_SUCCESS(rv, false);
-    nsAutoCString originB;
-    rv = b->GetOrigin(originB);
-    NS_ENSURE_SUCCESS(rv, false);
-    return originA < originB;
-  }
-
-  bool Equals(nsIPrincipal* a, nsIPrincipal* b) const
-  {
-    nsAutoCString originA;
-    nsresult rv = a->GetOrigin(originA);
-    NS_ENSURE_SUCCESS(rv, false);
-    nsAutoCString originB;
-    rv = b->GetOrigin(originB);
-    NS_ENSURE_SUCCESS(rv, false);
-    return a == b;
-  }
-};
-
-nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
-                                         const OriginAttributes& aAttrs)
-{
-  // We force the principals to be sorted by origin so that nsExpandedPrincipal
-  // origins can have a canonical form.
-  OriginComparator c;
-  for (size_t i = 0; i < aWhiteList.Length(); ++i) {
-    mPrincipals.InsertElementSorted(aWhiteList[i], c);
-  }
-  mOriginAttributes = aAttrs;
-}
-
-nsExpandedPrincipal::~nsExpandedPrincipal()
-{ }
-
-NS_IMETHODIMP
-nsExpandedPrincipal::GetDomain(nsIURI** aDomain)
-{
-  *aDomain = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsExpandedPrincipal::SetDomain(nsIURI* aDomain)
-{
-  return NS_OK;
-}
-
-nsresult
-nsExpandedPrincipal::GetOriginInternal(nsACString& aOrigin)
-{
-  aOrigin.AssignLiteral("[Expanded Principal [");
-  for (size_t i = 0; i < mPrincipals.Length(); ++i) {
-    if (i != 0) {
-      aOrigin.AppendLiteral(", ");
-    }
-
-    nsAutoCString subOrigin;
-    nsresult rv = mPrincipals.ElementAt(i)->GetOrigin(subOrigin);
-    NS_ENSURE_SUCCESS(rv, rv);
-    aOrigin.Append(subOrigin);
-  }
-
-  aOrigin.Append("]]");
-  return NS_OK;
-}
-
-bool
-nsExpandedPrincipal::SubsumesInternal(nsIPrincipal* aOther,
-                                      BasePrincipal::DocumentDomainConsideration aConsideration)
-{
-  // If aOther is an ExpandedPrincipal too, we break it down into its component
-  // nsIPrincipals, and check subsumes on each one.
-  nsCOMPtr<nsIExpandedPrincipal> expanded = do_QueryInterface(aOther);
-  if (expanded) {
-    nsTArray< nsCOMPtr<nsIPrincipal> >* otherList;
-    expanded->GetWhiteList(&otherList);
-    for (uint32_t i = 0; i < otherList->Length(); ++i){
-      // Use SubsumesInternal rather than Subsumes here, since OriginAttribute
-      // checks are only done between non-expanded sub-principals, and we don't
-      // need to incur the extra virtual call overhead.
-      if (!SubsumesInternal((*otherList)[i], aConsideration)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  // We're dealing with a regular principal. One of our principals must subsume
-  // it.
-  for (uint32_t i = 0; i < mPrincipals.Length(); ++i) {
-    if (Cast(mPrincipals[i])->Subsumes(aOther, aConsideration)) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-bool
-nsExpandedPrincipal::MayLoadInternal(nsIURI* uri)
-{
-  for (uint32_t i = 0; i < mPrincipals.Length(); ++i){
-    if (BasePrincipal::Cast(mPrincipals[i])->MayLoadInternal(uri)) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-NS_IMETHODIMP
-nsExpandedPrincipal::GetHashValue(uint32_t* result)
-{
-  MOZ_CRASH("extended principal should never be used as key in a hash map");
-}
-
-NS_IMETHODIMP
-nsExpandedPrincipal::GetURI(nsIURI** aURI)
-{
-  *aURI = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList)
-{
-  *aWhiteList = &mPrincipals;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsExpandedPrincipal::GetBaseDomain(nsACString& aBaseDomain)
-{
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
-bool
-nsExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
-{
-  for (size_t i = 0; i < mPrincipals.Length(); ++i) {
-    if (BasePrincipal::Cast(mPrincipals[i])->AddonHasPermission(aPerm)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-nsresult
-nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
-{
-  aStr.Assign("[Expanded Principal [");
-  for (size_t i = 0; i < mPrincipals.Length(); ++i) {
-    if (i != 0) {
-      aStr.AppendLiteral(", ");
-    }
-
-    nsAutoCString spec;
-    nsresult rv =
-      nsJSPrincipals::get(mPrincipals.ElementAt(i))->GetScriptLocation(spec);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    aStr.Append(spec);
-  }
-  aStr.Append("]]");
-  return NS_OK;
-}
-
-//////////////////////////////////////////
-// Methods implementing nsISerializable //
-//////////////////////////////////////////
-
-NS_IMETHODIMP
-nsExpandedPrincipal::Read(nsIObjectInputStream* aStream)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsExpandedPrincipal::Write(nsIObjectOutputStream* aStream)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
--- a/caps/nsPrincipal.h
+++ b/caps/nsPrincipal.h
@@ -53,51 +53,14 @@ public:
 
 protected:
   virtual ~nsPrincipal();
 
   bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
   bool MayLoadInternal(nsIURI* aURI) override;
 };
 
-class nsExpandedPrincipal : public nsIExpandedPrincipal, public mozilla::BasePrincipal
-{
-public:
-  nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
-                      const mozilla::OriginAttributes& aAttrs);
-
-  NS_DECL_NSIEXPANDEDPRINCIPAL
-  NS_DECL_NSISERIALIZABLE
-  NS_IMETHOD_(MozExternalRefCountType) AddRef() override { return nsJSPrincipals::AddRef(); };
-  NS_IMETHOD_(MozExternalRefCountType) Release() override { return nsJSPrincipals::Release(); };
-  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
-  NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
-  NS_IMETHOD GetURI(nsIURI** aURI) override;
-  NS_IMETHOD GetDomain(nsIURI** aDomain) override;
-  NS_IMETHOD SetDomain(nsIURI* aDomain) override;
-  NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
-  virtual bool AddonHasPermission(const nsAString& aPerm) override;
-  virtual nsresult GetScriptLocation(nsACString &aStr) override;
-  nsresult GetOriginInternal(nsACString& aOrigin) override;
-
-  PrincipalKind Kind() override { return eExpandedPrincipal; }
-
-protected:
-  virtual ~nsExpandedPrincipal();
-
-  bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
-  bool MayLoadInternal(nsIURI* aURI) override;
-
-private:
-  nsTArray< nsCOMPtr<nsIPrincipal> > mPrincipals;
-};
-
 #define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"
 #define NS_PRINCIPAL_CID \
 { 0x653e0e4d, 0x3ee4, 0x45fa, \
   { 0xb2, 0x72, 0x97, 0xc2, 0x0b, 0xc0, 0x1e, 0xb8 } }
 
-#define NS_EXPANDEDPRINCIPAL_CONTRACTID "@mozilla.org/expandedprincipal;1"
-#define NS_EXPANDEDPRINCIPAL_CID \
-{ 0xe8ee88b0, 0x5571, 0x4086, \
-  { 0xa4, 0x5b, 0x39, 0xa7, 0x16, 0x90, 0x6b, 0xdb } }
-
 #endif // nsPrincipal_h__
--- a/devtools/client/framework/test/shared-head.js
+++ b/devtools/client/framework/test/shared-head.js
@@ -107,26 +107,28 @@ registerCleanupFunction(function* cleanu
 
 /**
  * Add a new test tab in the browser and load the given url.
  * @param {String} url The url to be loaded in the new tab
  * @param {Object} options Object with various optional fields:
  *   - {Boolean} background If true, open the tab in background
  *   - {ChromeWindow} window Firefox top level window we should use to open the tab
  *   - {Number} userContextId The userContextId of the tab.
+ *   - {String} preferredRemoteType
  * @return a promise that resolves to the tab object when the url is loaded
  */
 var addTab = Task.async(function* (url, options = { background: false, window: window }) {
   info("Adding a new tab with URL: " + url);
 
   let { background } = options;
   let { gBrowser } = options.window ? options.window : window;
   let { userContextId } = options;
 
-  let tab = gBrowser.addTab(url, {userContextId});
+  let tab = gBrowser.addTab(url,
+    {userContextId, preferredRemoteType: options.preferredRemoteType});
   if (!background) {
     gBrowser.selectedTab = tab;
   }
   yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 
   info("Tab added and finished loading");
 
   return tab;
--- a/devtools/client/webconsole/test/head.js
+++ b/devtools/client/webconsole/test/head.js
@@ -42,44 +42,27 @@ var WCUL10n = new WebConsoleUtils.L10n(W
 
 const DOCS_GA_PARAMS = "?utm_source=mozilla" +
                        "&utm_medium=firefox-console-errors" +
                        "&utm_campaign=default";
 
 flags.testing = true;
 
 function loadTab(url, preferredRemoteType) {
-  let deferred = promise.defer();
-
-  let tab = gBrowser.selectedTab = gBrowser.addTab(url, { preferredRemoteType });
-  let browser = gBrowser.getBrowserForTab(tab);
-
-  browser.addEventListener("load", function () {
-    deferred.resolve({tab: tab, browser: browser});
-  }, {capture: true, once: true});
-
-  return deferred.promise;
+  return addTab(url, { preferredRemoteType }).then( tab => {
+    return { tab, browser: tab.linkedBrowser };
+  });
 }
 
 function loadBrowser(browser) {
   return BrowserTestUtils.browserLoaded(browser);
 }
 
 function closeTab(tab) {
-  let deferred = promise.defer();
-
-  let container = gBrowser.tabContainer;
-
-  container.addEventListener("TabClose", function () {
-    deferred.resolve(null);
-  }, {capture: true, once: true});
-
-  gBrowser.removeTab(tab);
-
-  return deferred.promise;
+  return removeTab(tab);
 }
 
 /**
  * Load the page and return the associated HUD.
  *
  * @param string uri
  *   The URI of the page to load.
  * @param string consoleType [optional]
--- a/docshell/base/LoadContext.cpp
+++ b/docshell/base/LoadContext.cpp
@@ -41,27 +41,29 @@ namespace mozilla {
 NS_IMPL_ISUPPORTS(LoadContext, nsILoadContext, nsIInterfaceRequestor)
 
 LoadContext::LoadContext(nsIPrincipal* aPrincipal,
                          nsILoadContext* aOptionalBase)
   : mTopFrameElement(nullptr)
   , mNestedFrameId(0)
   , mIsContent(true)
   , mUseRemoteTabs(false)
+  , mUseTrackingProtection(false)
 #ifdef DEBUG
   , mIsNotNull(true)
 #endif
 {
   mOriginAttributes.Inherit(aPrincipal->OriginAttributesRef());
   if (!aOptionalBase) {
     return;
   }
 
   MOZ_ALWAYS_SUCCEEDS(aOptionalBase->GetIsContent(&mIsContent));
   MOZ_ALWAYS_SUCCEEDS(aOptionalBase->GetUseRemoteTabs(&mUseRemoteTabs));
+  MOZ_ALWAYS_SUCCEEDS(aOptionalBase->GetUseTrackingProtection(&mUseTrackingProtection));
 }
 
 //-----------------------------------------------------------------------------
 // LoadContext::nsILoadContext
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 LoadContext::GetAssociatedWindow(mozIDOMWindowProxy**)
@@ -175,30 +177,32 @@ LoadContext::GetOriginAttributes(JS::Mut
   MOZ_ASSERT(cx);
 
   bool ok = ToJSValue(cx, mOriginAttributes, aAttrs);
   NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-LoadContext::IsTrackingProtectionOn(bool* aIsTrackingProtectionOn)
+LoadContext::GetUseTrackingProtection(bool* aUseTrackingProtection)
 {
   MOZ_ASSERT(mIsNotNull);
 
-  if (Preferences::GetBool("privacy.trackingprotection.enabled", false)) {
-    *aIsTrackingProtectionOn = true;
-  } else if ((mOriginAttributes.mPrivateBrowsingId > 0) &&
-             Preferences::GetBool("privacy.trackingprotection.pbmode.enabled", false)) {
-    *aIsTrackingProtectionOn = true;
-  } else {
-    *aIsTrackingProtectionOn = false;
-  }
+  NS_ENSURE_ARG_POINTER(aUseTrackingProtection);
+
+  *aUseTrackingProtection = mUseTrackingProtection;
+  return NS_OK;
+}
 
-  return NS_OK;
+NS_IMETHODIMP
+LoadContext::SetUseTrackingProtection(bool aUseTrackingProtection)
+{
+  MOZ_ASSERT_UNREACHABLE("Should only be set through nsDocShell");
+
+  return NS_ERROR_UNEXPECTED;
 }
 
 //-----------------------------------------------------------------------------
 // LoadContext::nsIInterfaceRequestor
 //-----------------------------------------------------------------------------
 NS_IMETHODIMP
 LoadContext::GetInterface(const nsIID& aIID, void** aResult)
 {
--- a/docshell/base/LoadContext.h
+++ b/docshell/base/LoadContext.h
@@ -40,62 +40,67 @@ public:
   // provided by child process.
   LoadContext(const IPC::SerializedLoadContext& aToCopy,
               dom::Element* aTopFrameElement,
               OriginAttributes& aAttrs)
     : mTopFrameElement(do_GetWeakReference(aTopFrameElement))
     , mNestedFrameId(0)
     , mIsContent(aToCopy.mIsContent)
     , mUseRemoteTabs(aToCopy.mUseRemoteTabs)
+    , mUseTrackingProtection(aToCopy.mUseTrackingProtection)
     , mOriginAttributes(aAttrs)
 #ifdef DEBUG
     , mIsNotNull(aToCopy.mIsNotNull)
 #endif
   {
   }
 
   // appId/inIsolatedMozBrowser arguments override those in SerializedLoadContext
   // provided by child process.
   LoadContext(const IPC::SerializedLoadContext& aToCopy,
               uint64_t aNestedFrameId,
               OriginAttributes& aAttrs)
     : mTopFrameElement(nullptr)
     , mNestedFrameId(aNestedFrameId)
     , mIsContent(aToCopy.mIsContent)
     , mUseRemoteTabs(aToCopy.mUseRemoteTabs)
+    , mUseTrackingProtection(aToCopy.mUseTrackingProtection)
     , mOriginAttributes(aAttrs)
 #ifdef DEBUG
     , mIsNotNull(aToCopy.mIsNotNull)
 #endif
   {
   }
 
   LoadContext(dom::Element* aTopFrameElement,
               bool aIsContent,
               bool aUsePrivateBrowsing,
               bool aUseRemoteTabs,
+              bool aUseTrackingProtection,
               const OriginAttributes& aAttrs)
     : mTopFrameElement(do_GetWeakReference(aTopFrameElement))
     , mNestedFrameId(0)
     , mIsContent(aIsContent)
     , mUseRemoteTabs(aUseRemoteTabs)
+    , mUseTrackingProtection(aUseTrackingProtection)
     , mOriginAttributes(aAttrs)
 #ifdef DEBUG
     , mIsNotNull(true)
 #endif
   {
     MOZ_DIAGNOSTIC_ASSERT(aUsePrivateBrowsing == (aAttrs.mPrivateBrowsingId > 0));
   }
 
   // Constructor taking reserved origin attributes.
   explicit LoadContext(OriginAttributes& aAttrs)
     : mTopFrameElement(nullptr)
     , mNestedFrameId(0)
     , mIsContent(false)
     , mUseRemoteTabs(false)
+    , mUseTrackingProtection(false)
     , mOriginAttributes(aAttrs)
 #ifdef DEBUG
     , mIsNotNull(true)
 #endif
   {
   }
 
   // Constructor for creating a LoadContext with a given principal's appId and
@@ -105,16 +110,17 @@ public:
 
 private:
   ~LoadContext() {}
 
   nsWeakPtr mTopFrameElement;
   uint64_t mNestedFrameId;
   bool mIsContent;
   bool mUseRemoteTabs;
+  bool mUseTrackingProtection;
   OriginAttributes mOriginAttributes;
 #ifdef DEBUG
   bool mIsNotNull;
 #endif
 };
 
 } // namespace mozilla
 
--- a/docshell/base/SerializedLoadContext.cpp
+++ b/docshell/base/SerializedLoadContext.cpp
@@ -56,22 +56,24 @@ SerializedLoadContext::SerializedLoadCon
 void
 SerializedLoadContext::Init(nsILoadContext* aLoadContext)
 {
   if (aLoadContext) {
     mIsNotNull = true;
     mIsPrivateBitValid = true;
     aLoadContext->GetIsContent(&mIsContent);
     aLoadContext->GetUseRemoteTabs(&mUseRemoteTabs);
+    aLoadContext->GetUseTrackingProtection(&mUseTrackingProtection);
     if (!aLoadContext->GetOriginAttributes(mOriginAttributes)) {
       NS_WARNING("GetOriginAttributes failed");
     }
   } else {
     mIsNotNull = false;
     mIsPrivateBitValid = false;
     // none of below values really matter when mIsNotNull == false:
     // we won't be GetInterfaced to nsILoadContext
     mIsContent = true;
     mUseRemoteTabs = false;
+    mUseTrackingProtection = false;
   }
 }
 
 } // namespace IPC
--- a/docshell/base/SerializedLoadContext.h
+++ b/docshell/base/SerializedLoadContext.h
@@ -27,16 +27,17 @@ namespace IPC {
 class SerializedLoadContext
 {
 public:
   SerializedLoadContext()
     : mIsNotNull(false)
     , mIsPrivateBitValid(false)
     , mIsContent(false)
     , mUseRemoteTabs(false)
+    , mUseTrackingProtection(false)
   {
     Init(nullptr);
   }
 
   explicit SerializedLoadContext(nsILoadContext* aLoadContext);
   explicit SerializedLoadContext(nsIChannel* aChannel);
   explicit SerializedLoadContext(nsIWebSocketChannel* aChannel);
 
@@ -47,16 +48,17 @@ public:
 
   // used to indicate if child-side LoadContext * was null.
   bool mIsNotNull;
   // used to indicate if child-side mUsePrivateBrowsing flag is valid, even if
   // mIsNotNull is false, i.e., child LoadContext was null.
   bool mIsPrivateBitValid;
   bool mIsContent;
   bool mUseRemoteTabs;
+  bool mUseTrackingProtection;
   mozilla::OriginAttributes mOriginAttributes;
 };
 
 // Function to serialize over IPDL
 template<>
 struct ParamTraits<SerializedLoadContext>
 {
   typedef SerializedLoadContext paramType;
@@ -65,26 +67,28 @@ struct ParamTraits<SerializedLoadContext
   {
     nsAutoCString suffix;
     aParam.mOriginAttributes.CreateSuffix(suffix);
 
     WriteParam(aMsg, aParam.mIsNotNull);
     WriteParam(aMsg, aParam.mIsContent);
     WriteParam(aMsg, aParam.mIsPrivateBitValid);
     WriteParam(aMsg, aParam.mUseRemoteTabs);
+    WriteParam(aMsg, aParam.mUseTrackingProtection);
     WriteParam(aMsg, suffix);
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     nsAutoCString suffix;
     if (!ReadParam(aMsg, aIter, &aResult->mIsNotNull) ||
         !ReadParam(aMsg, aIter, &aResult->mIsContent) ||
         !ReadParam(aMsg, aIter, &aResult->mIsPrivateBitValid) ||
         !ReadParam(aMsg, aIter, &aResult->mUseRemoteTabs) ||
+        !ReadParam(aMsg, aIter, &aResult->mUseTrackingProtection) ||
         !ReadParam(aMsg, aIter, &suffix)) {
       return false;
     }
     return aResult->mOriginAttributes.PopulateFromSuffix(suffix);
   }
 };
 
 } // namespace IPC
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -790,16 +790,17 @@ nsDocShell::nsDocShell()
   , mAllowKeywordFixup(false)
   , mIsOffScreenBrowser(false)
   , mIsActive(true)
   , mDisableMetaRefreshWhenInactive(false)
   , mIsPrerendered(false)
   , mIsAppTab(false)
   , mUseGlobalHistory(false)
   , mUseRemoteTabs(false)
+  , mUseTrackingProtection(false)
   , mDeviceSizeIsPageSize(false)
   , mWindowDraggingAllowed(false)
   , mInFrameSwap(false)
   , mInheritPrivateBrowsingId(true)
   , mCanExecuteScripts(false)
   , mFiredUnloadEvent(false)
   , mEODForCurrentDocument(false)
   , mURIResultedInDocument(false)
@@ -8847,24 +8848,17 @@ nsDocShell::RestoreFromHistory()
 
   nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
   if (document) {
     RefPtr<nsDocShell> parent = GetParentDocshell();
     if (parent) {
       nsCOMPtr<nsIDocument> d = parent->GetDocument();
       if (d) {
         if (d->EventHandlingSuppressed()) {
-          document->SuppressEventHandling(nsIDocument::eEvents,
-                                          d->EventHandlingSuppressed());
-        }
-
-        // Ick, it'd be nicer to not rewalk all of the subdocs here.
-        if (d->AnimationsPaused()) {
-          document->SuppressEventHandling(nsIDocument::eAnimationsOnly,
-                                          d->AnimationsPaused());
+          document->SuppressEventHandling(d->EventHandlingSuppressed());
         }
       }
     }
 
     // Use the uri from the mLSHE we had when we entered this function
     // (which need not match the document's URI if anchors are involved),
     // since that's the history entry we're loading.  Note that if we use
     // origLSHE we don't have to worry about whether the entry in question
@@ -13681,27 +13675,50 @@ nsDocShell::GetTopFrameElement(nsIDOMEle
 NS_IMETHODIMP
 nsDocShell::GetNestedFrameId(uint64_t* aId)
 {
   *aId = 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDocShell::IsTrackingProtectionOn(bool* aIsTrackingProtectionOn)
-{
-  if (Preferences::GetBool("privacy.trackingprotection.enabled", false)) {
-    *aIsTrackingProtectionOn = true;
-  } else if (UsePrivateBrowsing() &&
-             Preferences::GetBool("privacy.trackingprotection.pbmode.enabled", false)) {
-    *aIsTrackingProtectionOn = true;
-  } else {
-    *aIsTrackingProtectionOn = false;
-  }
-
+nsDocShell::GetUseTrackingProtection(bool* aUseTrackingProtection)
+{
+  *aUseTrackingProtection  = false;
+
+  static bool sTPEnabled = false;
+  static bool sTPInPBEnabled = false;
+  static bool sPrefsInit = false;
+
+  if (!sPrefsInit) {
+    sPrefsInit = true;
+    Preferences::AddBoolVarCache(&sTPEnabled,
+      "privacy.trackingprotection.enabled", false);
+    Preferences::AddBoolVarCache(&sTPInPBEnabled,
+      "privacy.trackingprotection.pbmode.enabled", false);
+  }
+
+  if (mUseTrackingProtection || sTPEnabled ||
+      (UsePrivateBrowsing() && sTPInPBEnabled)) {
+    *aUseTrackingProtection = true;
+    return NS_OK;
+  }
+
+  RefPtr<nsDocShell> parent = GetParentDocshell();
+  if (parent) {
+    return parent->GetUseTrackingProtection(aUseTrackingProtection);
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShell::SetUseTrackingProtection(bool aUseTrackingProtection)
+{
+  mUseTrackingProtection = aUseTrackingProtection;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetIsContent(bool* aIsContent)
 {
   *aIsContent = (mItemType == typeContent);
   return NS_OK;
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -229,17 +229,16 @@ public:
   NS_IMETHOD GetNestedFrameId(uint64_t*) override;
   NS_IMETHOD GetIsContent(bool*) override;
   NS_IMETHOD GetUsePrivateBrowsing(bool*) override;
   NS_IMETHOD SetUsePrivateBrowsing(bool) override;
   NS_IMETHOD SetPrivateBrowsing(bool) override;
   NS_IMETHOD GetUseRemoteTabs(bool*) override;
   NS_IMETHOD SetRemoteTabs(bool) override;
   NS_IMETHOD GetOriginAttributes(JS::MutableHandle<JS::Value>) override;
-  NS_IMETHOD IsTrackingProtectionOn(bool*) override;
 
   // Restores a cached presentation from history (mLSHE).
   // This method swaps out the content viewer and simulates loads for
   // subframes. It then simulates the completion of the toplevel load.
   nsresult RestoreFromHistory();
 
   // Perform a URI load from a refresh timer. This is just like the
   // ForceRefreshURI method on nsIRefreshURI, but makes sure to take
@@ -956,16 +955,17 @@ protected:
   bool mAllowKeywordFixup : 1;
   bool mIsOffScreenBrowser : 1;
   bool mIsActive : 1;
   bool mDisableMetaRefreshWhenInactive : 1;
   bool mIsPrerendered : 1;
   bool mIsAppTab : 1;
   bool mUseGlobalHistory : 1;
   bool mUseRemoteTabs : 1;
+  bool mUseTrackingProtection : 1;
   bool mDeviceSizeIsPageSize : 1;
   bool mWindowDraggingAllowed : 1;
   bool mInFrameSwap : 1;
   bool mInheritPrivateBrowsingId : 1;
 
   // Because scriptability depends on the mAllowJavascript values of our
   // ancestors, we cache the effective scriptability and recompute it when
   // it might have changed;
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -1126,9 +1126,14 @@ interface nsIDocShell : nsIDocShellTreeI
    */
   [infallible] readonly attribute boolean isOnlyToplevelInTabGroup;
 
   /**
    * Returns `true` if this docshell was created due to a Large-Allocation
    * header, and has not seen the initiating load yet.
    */
   [infallible] readonly attribute boolean awaitingLargeAlloc;
+
+  /**
+   * Attribute that determines whether tracking protection is enabled.
+   */
+  attribute boolean useTrackingProtection;
 };
--- a/docshell/base/nsILoadContext.idl
+++ b/docshell/base/nsILoadContext.idl
@@ -73,31 +73,46 @@ interface nsILoadContext : nsISupports
    */
   attribute boolean usePrivateBrowsing;
 
   /**
    * Attribute that determines if remote (out-of-process) tabs should be used.
    */
   readonly attribute boolean useRemoteTabs;
 
+  /*
+   * Attribute that determines if tracking protection should be used. May not be
+   * changed after a document has been loaded in this context.
+   */
+  attribute boolean useTrackingProtection;
+
 %{C++
   /**
    * De-XPCOMed getter to make call-sites cleaner.
    */
-  bool UsePrivateBrowsing() {
-    bool usingPB;
+  bool UsePrivateBrowsing()
+  {
+    bool usingPB = false;
     GetUsePrivateBrowsing(&usingPB);
     return usingPB;
   }
 
-  bool UseRemoteTabs() {
-    bool usingRT;
+  bool UseRemoteTabs()
+  {
+    bool usingRT = false;
     GetUseRemoteTabs(&usingRT);
     return usingRT;
   }
+
+  bool UseTrackingProtection()
+  {
+    bool usingTP = false;
+    GetUseTrackingProtection(&usingTP);
+    return usingTP;
+  }
 %}
 
   /**
    * Set the private browsing state of the load context, meant to be used internally.
    */
   [noscript] void SetPrivateBrowsing(in boolean aInPrivateBrowsing);
 
   /**
@@ -125,25 +140,9 @@ interface nsILoadContext : nsISupports
   /**
    * The C++ getter for origin attributes.
    *
    * Defined in LoadContext.cpp
    */
   bool GetOriginAttributes(mozilla::OriginAttributes& aAttrs);
 #endif
 %}
-
-  /**
-   * Returns true if tracking protection is enabled for the load context.
-   */
-  boolean IsTrackingProtectionOn();
-
-%{C++
-  /**
-   * De-XPCOMed getter to make call-sites cleaner.
-   */
-  bool UseTrackingProtection() {
-    bool usingTP;
-    IsTrackingProtectionOn(&usingTP);
-    return usingTP;
-  }
-%}
 };
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3439,22 +3439,22 @@ nsContentUtils::IsDraggableImage(nsICont
 bool
 nsContentUtils::IsDraggableLink(const nsIContent* aContent) {
   nsCOMPtr<nsIURI> absURI;
   return aContent->IsLink(getter_AddRefs(absURI));
 }
 
 // static
 nsresult
-nsContentUtils::NameChanged(mozilla::dom::NodeInfo* aNodeInfo, nsIAtom* aName,
-                            mozilla::dom::NodeInfo** aResult)
+nsContentUtils::QNameChanged(mozilla::dom::NodeInfo* aNodeInfo, nsIAtom* aName,
+                             mozilla::dom::NodeInfo** aResult)
 {
   nsNodeInfoManager *niMgr = aNodeInfo->NodeInfoManager();
 
-  *aResult = niMgr->GetNodeInfo(aName, aNodeInfo->GetPrefixAtom(),
+  *aResult = niMgr->GetNodeInfo(aName, nullptr,
                                 aNodeInfo->NamespaceID(),
                                 aNodeInfo->NodeType(),
                                 aNodeInfo->GetExtraName()).take();
   return NS_OK;
 }
 
 
 static bool
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -791,21 +791,23 @@ public:
    * Method that decides whether a content node is a draggable link
    *
    * @param aContent The content node to test.
    * @return whether it's a draggable link
    */
   static bool IsDraggableLink(const nsIContent* aContent);
 
   /**
-   * Convenience method to create a new nodeinfo that differs only by name
-   * from aNodeInfo.
+   * Convenience method to create a new nodeinfo that differs only by prefix and
+   * name from aNodeInfo. The new nodeinfo's name is set to aName, and prefix is
+   * set to null.
    */
-  static nsresult NameChanged(mozilla::dom::NodeInfo* aNodeInfo, nsIAtom* aName,
-                              mozilla::dom::NodeInfo** aResult);
+  static nsresult QNameChanged(mozilla::dom::NodeInfo* aNodeInfo,
+                               nsIAtom* aName,
+                               mozilla::dom::NodeInfo** aResult);
 
   /**
    * Returns the appropriate event argument names for the specified
    * namespace and event name.  Added because we need to switch between
    * SVG's "evt" and the rest of the world's "event", and because onerror
    * on window takes 5 args.
    */
   static void GetEventArgNames(int32_t aNameSpaceID, nsIAtom *aEventName,
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -750,18 +750,23 @@ nsCopySupport::FireClipboardEvent(EventM
                                   nsIPresShell* aPresShell,
                                   nsISelection* aSelection,
                                   bool* aActionTaken)
 {
   if (aActionTaken) {
     *aActionTaken = false;
   }
 
-  NS_ASSERTION(aEventMessage == eCut || aEventMessage == eCopy ||
-               aEventMessage == ePaste,
+  EventMessage originalEventMessage = aEventMessage;
+  if (originalEventMessage == ePasteNoFormatting) {
+    originalEventMessage = ePaste;
+  }
+
+  NS_ASSERTION(originalEventMessage == eCut || originalEventMessage == eCopy ||
+               originalEventMessage == ePaste,
                "Invalid clipboard event type");
 
   nsCOMPtr<nsIPresShell> presShell = aPresShell;
   if (!presShell)
     return false;
 
   nsCOMPtr<nsIDocument> doc = presShell->GetDocument();
   if (!doc)
@@ -808,31 +813,31 @@ nsCopySupport::FireClipboardEvent(EventM
     docShell && docShell->ItemType() == nsIDocShellTreeItem::typeChrome;
 
   // next, fire the cut, copy or paste event
   bool doDefault = true;
   RefPtr<DataTransfer> clipboardData;
   if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
     clipboardData =
       new DataTransfer(doc->GetScopeObject(), aEventMessage,
-                       aEventMessage == ePaste, aClipboardType);
+                       originalEventMessage == ePaste, aClipboardType);
 
     nsEventStatus status = nsEventStatus_eIgnore;
-    InternalClipboardEvent evt(true, aEventMessage);
+    InternalClipboardEvent evt(true, originalEventMessage);
     evt.mClipboardData = clipboardData;
     EventDispatcher::Dispatch(content, presShell->GetPresContext(), &evt,
                               nullptr, &status);
     // If the event was cancelled, don't do the clipboard operation
     doDefault = (status != nsEventStatus_eConsumeNoDefault);
   }
 
   // No need to do anything special during a paste. Either an event listener
   // took care of it and cancelled the event, or the caller will handle it.
   // Return true to indicate that the event wasn't cancelled.
-  if (aEventMessage == ePaste) {
+  if (originalEventMessage == ePaste) {
     // Clear and mark the clipboardData as readonly. This prevents someone
     // from reading the clipboard contents after the paste event has fired.
     if (clipboardData) {
       clipboardData->ClearAll();
       clipboardData->SetReadOnly();
     }
 
     if (aActionTaken) {
@@ -862,17 +867,17 @@ nsCopySupport::FireClipboardEvent(EventM
     if (formControl) {
       if (formControl->GetType() == NS_FORM_INPUT_PASSWORD) {
         return false;
       }
     }
 
     // when cutting non-editable content, do nothing
     // XXX this is probably the wrong editable flag to check
-    if (aEventMessage != eCut || content->IsEditable()) {
+    if (originalEventMessage != eCut || content->IsEditable()) {
       // get the data from the selection if any
       bool isCollapsed;
       sel->GetIsCollapsed(&isCollapsed);
       if (isCollapsed) {
         if (aActionTaken) {
           *aActionTaken = true;
         }
         return false;
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1645,19 +1645,19 @@ nsDOMWindowUtils::DisableNonTestMouseEve
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
 {
   nsCOMPtr<nsIDocument> doc = GetDocument();
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   if (aSuppress) {
-    doc->SuppressEventHandling(nsIDocument::eEvents);
+    doc->SuppressEventHandling();
   } else {
-    doc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, true);
+    doc->UnsuppressEventHandlingAndFireEvents(true);
   }
 
   return NS_OK;
 }
 
 static nsresult
 getScrollXYAppUnits(const nsWeakPtr& aWindow, bool aFlushLayout, nsPoint& aScrollPos) {
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(aWindow);
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1353,17 +1353,16 @@ nsIDocument::nsIDocument()
 #endif
     mBidiOptions(IBMBIDI_DEFAULT_BIDI_OPTIONS),
     mSandboxFlags(0),
     mPartID(0),
     mMarkedCCGeneration(0),
     mPresShell(nullptr),
     mSubtreeModifiedDepth(0),
     mEventsSuppressed(0),
-    mAnimationsPaused(0),
     mExternalScriptsBeingEvaluated(0),
     mFrameRequestCallbackCounter(0),
     mStaticCloneCount(0),
     mWindow(nullptr),
     mBFCacheEntry(nullptr),
     mInSyncOperationCount(0),
     mBlockDOMContentLoaded(0),
     mDidFireDOMContentLoaded(true),
@@ -3806,17 +3805,17 @@ nsDocument::CreateShell(nsPresContext* a
   RebuildUserFontSet();
 
   return shell.forget();
 }
 
 void
 nsDocument::MaybeRescheduleAnimationFrameNotifications()
 {
-  if (!mPresShell || !IsEventHandlingEnabled() || AnimationsPaused()) {
+  if (!mPresShell || !IsEventHandlingEnabled()) {
     // bail out for now, until one of those conditions changes
     return;
   }
 
   nsRefreshDriver* rd = mPresShell->GetPresContext()->RefreshDriver();
   if (!mFrameRequestCallbacks.IsEmpty()) {
     rd->ScheduleFrameRequestCallbacks(this);
   }
@@ -3869,17 +3868,17 @@ nsIDocument::ShouldThrottleFrameRequests
   // We got painted during the last paint, so run at full speed.
   return false;
 }
 
 void
 nsDocument::DeleteShell()
 {
   mExternalResourceMap.HideViewers();
-  if (IsEventHandlingEnabled() && !AnimationsPaused()) {
+  if (IsEventHandlingEnabled()) {
     RevokeAnimationFrameNotifications();
   }
   if (nsPresContext* presContext = mPresShell->GetPresContext()) {
     presContext->RefreshDriver()->CancelPendingEvents(this);
   }
 
   // When our shell goes away, request that all our images be immediately
   // discarded, so we don't carry around decoded image data for a document we
@@ -4651,17 +4650,17 @@ nsDocument::SetScriptGlobalObject(nsIScr
                nsSMILTimeContainer::PAUSE_BEGIN),
              "Clearing window pointer while animations are unpaused");
 
   if (mScriptGlobalObject && !aScriptGlobalObject) {
     // We're detaching from the window.  We need to grab a pointer to
     // our layout history state now.
     mLayoutHistoryState = GetLayoutHistoryState();
 
-    if (mPresShell && !EventHandlingSuppressed() && !AnimationsPaused()) {
+    if (mPresShell && !EventHandlingSuppressed()) {
       RevokeAnimationFrameNotifications();
     }
 
     // Also make sure to remove our onload blocker now if we haven't done it yet
     if (mOnloadBlockCount != 0) {
       nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
       if (loadGroup) {
         loadGroup->RemoveRequest(mOnloadBlocker, nullptr, NS_OK);
@@ -9320,54 +9319,38 @@ nsIDocument::GetReadyState(nsAString& aR
   case READYSTATE_COMPLETE :
     aReadyState.AssignLiteral(u"complete");
     break;
   default:
     aReadyState.AssignLiteral(u"uninitialized");
   }
 }
 
-namespace {
-
-struct SuppressArgs
-{
-  nsIDocument::SuppressionType mWhat;
-  uint32_t mIncrease;
-};
-
-} // namespace
-
 static bool
 SuppressEventHandlingInDocument(nsIDocument* aDocument, void* aData)
 {
-  SuppressArgs* args = static_cast<SuppressArgs*>(aData);
-  aDocument->SuppressEventHandling(args->mWhat, args->mIncrease);
+  aDocument->SuppressEventHandling(*static_cast<uint32_t*>(aData));
+
   return true;
 }
 
 void
-nsDocument::SuppressEventHandling(nsIDocument::SuppressionType aWhat,
-                                  uint32_t aIncrease)
-{
-  if (mEventsSuppressed == 0 && mAnimationsPaused == 0 &&
-      aIncrease != 0 && mPresShell && mScriptGlobalObject) {
+nsDocument::SuppressEventHandling(uint32_t aIncrease)
+{
+  if (mEventsSuppressed == 0 && aIncrease != 0 && mPresShell &&
+      mScriptGlobalObject) {
     RevokeAnimationFrameNotifications();
   }
 
-  if (aWhat == eAnimationsOnly) {
-    mAnimationsPaused += aIncrease;
-  } else {
-    mEventsSuppressed += aIncrease;
-    for (uint32_t i = 0; i < aIncrease; ++i) {
-      ScriptLoader()->AddExecuteBlocker();
-    }
-  }
-
-  SuppressArgs args = { aWhat, aIncrease };
-  EnumerateSubDocuments(SuppressEventHandlingInDocument, &args);
+  mEventsSuppressed += aIncrease;
+  for (uint32_t i = 0; i < aIncrease; ++i) {
+    ScriptLoader()->AddExecuteBlocker();
+  }
+
+  EnumerateSubDocuments(SuppressEventHandlingInDocument, &aIncrease);
 }
 
 static void
 FireOrClearDelayedEvents(nsTArray<nsCOMPtr<nsIDocument> >& aDocuments,
                          bool aFireEvents)
 {
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (!fm)
@@ -9659,72 +9642,45 @@ public:
     FireOrClearDelayedEvents(mDocuments, true);
     return NS_OK;
   }
 
 private:
   nsTArray<nsCOMPtr<nsIDocument> > mDocuments;
 };
 
-namespace {
-
-struct UnsuppressArgs
-{
-  explicit UnsuppressArgs(nsIDocument::SuppressionType aWhat)
-    : mWhat(aWhat)
-  {
-  }
-
-  nsIDocument::SuppressionType mWhat;
-  nsTArray<nsCOMPtr<nsIDocument>> mDocs;
-};
-
-} // namespace
-
 static bool
 GetAndUnsuppressSubDocuments(nsIDocument* aDocument,
                              void* aData)
 {
-  UnsuppressArgs* args = static_cast<UnsuppressArgs*>(aData);
-  if (args->mWhat != nsIDocument::eAnimationsOnly &&
-      aDocument->EventHandlingSuppressed() > 0) {
+  if (aDocument->EventHandlingSuppressed() > 0) {
     static_cast<nsDocument*>(aDocument)->DecreaseEventSuppression();
     aDocument->ScriptLoader()->RemoveExecuteBlocker();
-  } else if (args->mWhat == nsIDocument::eAnimationsOnly &&
-             aDocument->AnimationsPaused()) {
-    static_cast<nsDocument*>(aDocument)->ResumeAnimations();
-  }
-
-  if (args->mWhat != nsIDocument::eAnimationsOnly) {
-    // No need to remember documents if we only care about animation frames.
-    args->mDocs.AppendElement(aDocument);
-  }
-
+  }
+
+  nsTArray<nsCOMPtr<nsIDocument> >* docs =
+    static_cast<nsTArray<nsCOMPtr<nsIDocument> >* >(aData);
+
+  docs->AppendElement(aDocument);
   aDocument->EnumerateSubDocuments(GetAndUnsuppressSubDocuments, aData);
   return true;
 }
 
 void
-nsDocument::UnsuppressEventHandlingAndFireEvents(nsIDocument::SuppressionType aWhat,
-                                                 bool aFireEvents)
-{
-  UnsuppressArgs args(aWhat);
-  GetAndUnsuppressSubDocuments(this, &args);
-
-  if (aWhat == nsIDocument::eAnimationsOnly) {
-    // No need to fire events if we only care about animations here.
-    return;
-  }
+nsDocument::UnsuppressEventHandlingAndFireEvents(bool aFireEvents)
+{
+  nsTArray<nsCOMPtr<nsIDocument>> documents;
+  GetAndUnsuppressSubDocuments(this, &documents);
 
   if (aFireEvents) {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
-    nsCOMPtr<nsIRunnable> ded = new nsDelayedEventDispatcher(args.mDocs);
+    nsCOMPtr<nsIRunnable> ded = new nsDelayedEventDispatcher(documents);
     Dispatch("nsDelayedEventDispatcher", TaskCategory::Other, ded.forget());
   } else {
-    FireOrClearDelayedEvents(args.mDocs, false);
+    FireOrClearDelayedEvents(documents, false);
   }
 }
 
 nsISupports*
 nsDocument::GetCurrentContentSink()
 {
   return mParser ? mParser->GetContentSink() : nullptr;
 }
@@ -10039,33 +9995,32 @@ nsIDocument::ScheduleFrameRequestCallbac
     return NS_ERROR_NOT_AVAILABLE;
   }
   int32_t newHandle = ++mFrameRequestCallbackCounter;
 
   bool alreadyRegistered = !mFrameRequestCallbacks.IsEmpty();
   DebugOnly<FrameRequest*> request =
     mFrameRequestCallbacks.AppendElement(FrameRequest(aCallback, newHandle));
   NS_ASSERTION(request, "This is supposed to be infallible!");
-  if (!alreadyRegistered && mPresShell && IsEventHandlingEnabled() &&
-      !AnimationsPaused()) {
+  if (!alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
     mPresShell->GetPresContext()->RefreshDriver()->
       ScheduleFrameRequestCallbacks(this);
   }
 
   *aHandle = newHandle;
   return NS_OK;
 }
 
 void
 nsIDocument::CancelFrameRequestCallback(int32_t aHandle)
 {
   // mFrameRequestCallbacks is stored sorted by handle
   if (mFrameRequestCallbacks.RemoveElementSorted(aHandle) &&
       mFrameRequestCallbacks.IsEmpty() &&
-      mPresShell && IsEventHandlingEnabled() && !AnimationsPaused()) {
+      mPresShell && IsEventHandlingEnabled()) {
     mPresShell->GetPresContext()->RefreshDriver()->
       RevokeFrameRequestCallbacks(this);
   }
 }
 
 nsresult
 nsDocument::GetStateObject(nsIVariant** aState)
 {
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -902,34 +902,26 @@ public:
   GetPendingAnimationTracker() final override
   {
     return mPendingAnimationTracker;
   }
 
   virtual mozilla::PendingAnimationTracker*
   GetOrCreatePendingAnimationTracker() override;
 
-  virtual void SuppressEventHandling(SuppressionType aWhat,
-                                     uint32_t aIncrease) override;
+  virtual void SuppressEventHandling(uint32_t aIncrease) override;
 
-  virtual void UnsuppressEventHandlingAndFireEvents(SuppressionType aWhat,
-                                                    bool aFireEvents) override;
+  virtual void UnsuppressEventHandlingAndFireEvents(bool aFireEvents) override;
 
   void DecreaseEventSuppression() {
     MOZ_ASSERT(mEventsSuppressed);
     --mEventsSuppressed;
     MaybeRescheduleAnimationFrameNotifications();
   }
 
-  void ResumeAnimations() {
-    MOZ_ASSERT(mAnimationsPaused);
-    --mAnimationsPaused;
-    MaybeRescheduleAnimationFrameNotifications();
-  }
-
   virtual nsIDocument* GetTemplateContentsOwner() override;
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument,
                                                                    nsIDocument)
 
   void DoNotifyPossibleTitleChange();
 
   nsExternalResourceMap& ExternalResourceMap()
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1999,21 +1999,18 @@ nsGlobalWindow::FreeInnerObjects()
 
   if (mDoc) {
     // Remember the document's principal and URI.
     mDocumentPrincipal = mDoc->NodePrincipal();
     mDocumentURI = mDoc->GetDocumentURI();
     mDocBaseURI = mDoc->GetDocBaseURI();
 
     while (mDoc->EventHandlingSuppressed()) {
-      mDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, false);
-    }
-
-    // Note: we don't have to worry about eAnimationsOnly suppressions because
-    // they won't leak.
+      mDoc->UnsuppressEventHandlingAndFireEvents(false);
+    }
   }
 
   // Remove our reference to the document and the document principal.
   mFocusedNode = nullptr;
 
   if (mApplicationCache) {
     static_cast<nsDOMOfflineResourceList*>(mApplicationCache.get())->Disconnect();
     mApplicationCache = nullptr;
@@ -9261,17 +9258,17 @@ nsGlobalWindow::EnterModalState()
     nsIPresShell::SetCapturingContent(nullptr, 0);
   }
 
   if (topWin->mModalStateDepth == 0) {
     NS_ASSERTION(!topWin->mSuspendedDoc, "Shouldn't have mSuspendedDoc here!");
 
     topWin->mSuspendedDoc = topDoc;
     if (topDoc) {
-      topDoc->SuppressEventHandling(nsIDocument::eEvents);
+      topDoc->SuppressEventHandling();
     }
 
     nsGlobalWindow* inner = topWin->GetCurrentInnerWindowInternal();
     if (inner) {
       topWin->GetCurrentInnerWindowInternal()->Suspend();
     }
   }
   topWin->mModalStateDepth++;
@@ -9298,18 +9295,17 @@ nsGlobalWindow::LeaveModalState()
 
   if (topWin->mModalStateDepth == 0) {
     if (inner) {
       inner->Resume();
     }
 
     if (topWin->mSuspendedDoc) {
       nsCOMPtr<nsIDocument> currentDoc = topWin->GetExtantDoc();
-      topWin->mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents,
-                                                                  currentDoc == topWin->mSuspendedDoc);
+      topWin->mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(currentDoc == topWin->mSuspendedDoc);
       topWin->mSuspendedDoc = nullptr;
     }
   }
 
   // Remember the time of the last dialog quit.
   if (inner) {
     inner->mLastDialogQuitTime = TimeStamp::Now();
   }
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2153,41 +2153,30 @@ public:
   virtual mozilla::PendingAnimationTracker* GetPendingAnimationTracker() = 0;
 
   // Gets the tracker for animations that are waiting to start and
   // creates it if it doesn't already exist. As a result, the return value
   // will never be nullptr.
   virtual mozilla::PendingAnimationTracker*
   GetOrCreatePendingAnimationTracker() = 0;
 
-  enum SuppressionType {
-    eAnimationsOnly = 0x1,
-
-    // Note that suppressing events also suppresses animation frames, so
-    // there's no need to split out events in its own bitmask.
-    eEvents = 0x3,
-  };
-
   /**
    * Prevents user initiated events from being dispatched to the document and
    * subdocuments.
    */
-  virtual void SuppressEventHandling(SuppressionType aWhat,
-                                     uint32_t aIncrease = 1) = 0;
+  virtual void SuppressEventHandling(uint32_t aIncrease = 1) = 0;
 
   /**
    * Unsuppress event handling.
    * @param aFireEvents If true, delayed events (focus/blur) will be fired
    *                    asynchronously.
    */
-  virtual void UnsuppressEventHandlingAndFireEvents(SuppressionType aWhat,
-                                                    bool aFireEvents) = 0;
+  virtual void UnsuppressEventHandlingAndFireEvents(bool aFireEvents) = 0;
 
   uint32_t EventHandlingSuppressed() const { return mEventsSuppressed; }
-  uint32_t AnimationsPaused() const { return mAnimationsPaused; }
 
   bool IsEventHandlingEnabled() {
     return !EventHandlingSuppressed() && mScriptGlobalObject;
   }
 
   /**
    * Increment the number of external scripts being evaluated.
    */
@@ -3277,18 +3266,16 @@ protected:
 
   // If we're an external resource document, this will be non-null and will
   // point to our "display document": the one that all resource lookups should
   // go to.
   nsCOMPtr<nsIDocument> mDisplayDocument;
 
   uint32_t mEventsSuppressed;
 
-  uint32_t mAnimationsPaused;
-
   /**
    * The number number of external scripts (ones with the src attribute) that
    * have this document as their owner and that are being evaluated right now.
    */
   uint32_t mExternalScriptsBeingEvaluated;
 
   /**
    * The current frame request callback handle
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -2782,17 +2782,17 @@ void
 HandlePrerenderingViolation(nsPIDOMWindowInner* aWindow)
 {
   // Freeze the window and its workers, and its children too.
   aWindow->Freeze();
 
   // Suspend event handling on the document
   nsCOMPtr<nsIDocument> doc = aWindow->GetExtantDoc();
   if (doc) {
-    doc->SuppressEventHandling(nsIDocument::eEvents);
+    doc->SuppressEventHandling();
   }
 }
 
 bool
 EnforceNotInPrerendering(JSContext* aCx, JSObject* aObj)
 {
   JS::Rooted<JSObject*> thisObj(aCx, js::CheckedUnwrap(aObj));
   if (!thisObj) {
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -100,18 +100,21 @@ DataTransfer::DataTransfer(nsISupports* 
   // For these events, we want to be able to add data to the data transfer, so
   // clear the readonly state. Otherwise, the data is already present. For
   // external usage, cache the data from the native clipboard or drag.
   if (aEventMessage == eCut ||
       aEventMessage == eCopy ||
       aEventMessage == eDragStart) {
     mReadOnly = false;
   } else if (mIsExternal) {
-    if (aEventMessage == ePaste) {
-      CacheExternalClipboardFormats();
+    if (aEventMessage == ePasteNoFormatting) {
+      mEventMessage = ePaste;
+      CacheExternalClipboardFormats(true);
+    } else if (aEventMessage == ePaste) {
+      CacheExternalClipboardFormats(false);
     } else if (aEventMessage >= eDragDropEventFirst &&
                aEventMessage <= eDragDropEventLast) {
       CacheExternalDragFormats();
     }
   }
 }
 
 DataTransfer::DataTransfer(nsISupports* aParent,
@@ -1351,17 +1354,17 @@ DataTransfer::CacheExternalDragFormats()
       if (supported) {
         CacheExternalData(formats[f], c, sysPrincipal, /* hidden = */ f && hasFileData);
       }
     }
   }
 }
 
 void
-DataTransfer::CacheExternalClipboardFormats()
+DataTransfer::CacheExternalClipboardFormats(bool aPlainTextOnly)
 {
   NS_ASSERTION(mEventMessage == ePaste,
                "caching clipboard data for invalid event");
 
   // Called during the constructor for paste events to cache the formats
   // available on the clipboard. As with CacheExternalDragFormats, the
   // data will only be retrieved when needed.
 
@@ -1370,16 +1373,27 @@ DataTransfer::CacheExternalClipboardForm
   if (!clipboard || mClipboardType < 0) {
     return;
   }
 
   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
   nsCOMPtr<nsIPrincipal> sysPrincipal;
   ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal));
 
+  if (aPlainTextOnly) {
+    bool supported;
+    const char* unicodeMime[] = { kUnicodeMime };
+    clipboard->HasDataMatchingFlavors(unicodeMime, 1, mClipboardType,
+                                      &supported);
+    if (supported) {
+      CacheExternalData(kUnicodeMime, 0, sysPrincipal, false);
+    }
+    return;
+  }
+
   // Check if the clipboard has any files
   bool hasFileData = false;
   const char *fileMime[] = { kFileMime };
   clipboard->HasDataMatchingFlavors(fileMime, 1, mClipboardType, &hasFileData);
 
   // We will be ignoring any application/x-moz-file files found in the paste
   // datatransfer within e10s, as they will fail to be sent over IPC. Because of
   // that, we will unset hasFileData, whether or not it would have been set.
--- a/dom/events/DataTransfer.h
+++ b/dom/events/DataTransfer.h
@@ -302,17 +302,17 @@ protected:
   nsresult CacheExternalData(const char* aFormat, uint32_t aIndex,
                              nsIPrincipal* aPrincipal, bool aHidden);
 
   // caches the formats that exist in the drag service that were added by an
   // external drag
   void CacheExternalDragFormats();
 
   // caches the formats that exist in the clipboard
-  void CacheExternalClipboardFormats();
+  void CacheExternalClipboardFormats(bool aPlainTextOnly);
 
   FileList* GetFilesInternal(ErrorResult& aRv, nsIPrincipal* aSubjectPrincipal);
   nsresult GetDataAtInternal(const nsAString& aFormat, uint32_t aIndex,
                              nsIPrincipal* aSubjectPrincipal,
                              nsIVariant** aData);
 
   nsresult SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
                              uint32_t aIndex, nsIPrincipal* aSubjectPrincipal);
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -134,16 +134,18 @@ support-files = bug1017086_inner.html
 [test_bug1017086_enable.html]
 support-files = bug1017086_inner.html
 [test_bug1079236.html]
 [test_bug1145910.html]
 [test_bug1150308.html]
 [test_bug1248459.html]
 [test_bug1264380.html]
 run-if = (e10s && os != "win") # Bug 1270043, crash at windows platforms; Bug1264380 comment 20, nsDragService::InvokeDragSessionImpl behaves differently among platform implementations in non-e10s mode which prevents us to check the validity of nsIDragService::getCurrentSession() consistently via synthesize mouse clicks in non-e10s mode.
+[test_bug1327798.html]
+subsuite = clipboard
 [test_clickevent_on_input.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_continuous_wheel_events.html]
 [test_dblclick_explicit_original_target.html]
 [test_dom_activate_event.html]
 [test_dom_keyboard_event.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_dom_mouse_event.html]
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_bug1327798.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Test for bug 1327798</title>
+<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?=id=1327798">Mozilla Bug 1327798</a>
+<p id="display"></p>
+<div id="content" style="display: none;"></div>
+
+<div contenteditable="true" id="editable1"><b>Formatted Text</b><br></div>
+<pre>
+<script class="testbody" type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(() => {
+  var editable = document.getElementById("editable1");
+  editable.focus();
+
+  window.getSelection().selectAllChildren(editable1);
+
+  SpecialPowers.doCommand(window, "cmd_copy");
+
+  //--------- now check the content of the clipboard
+  var clipboard = SpecialPowers.Cc["@mozilla.org/widget/clipboard;1"]
+                               .getService(SpecialPowers.Ci.nsIClipboard);
+  // does the clipboard contain text/unicode data ?
+  ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1, clipboard.kGlobalClipboard),
+     "clipboard contains unicode text");
+  // does the clipboard contain text/html data ?
+  ok(clipboard.hasDataMatchingFlavors(["text/html"], 1, clipboard.kGlobalClipboard),
+     "clipboard contains html text");
+
+  window.addEventListener("paste", (e) => {
+    ok(e.clipboardData.types.indexOf('text/html'), -1, "clipboardData shouldn't have text/html");
+    ok(e.clipboardData.getData('text/plain'), "Formatted Text",  "getData(text/plain) should return plain text");
+    SimpleTest.finish();
+  });
+
+  SpecialPowers.doCommand(window, "cmd_pasteNoFormatting");
+});
+</script>
+</pre>
+</body>
+</html>
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -712,18 +712,18 @@ HTMLSelectElement::SetLength(uint32_t aL
   } else if (aLength > curlen) {
     if (aLength > MAX_DYNAMIC_SELECT_LENGTH) {
       aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
       return;
     }
 
     RefPtr<mozilla::dom::NodeInfo> nodeInfo;
 
-    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::option,
-                                getter_AddRefs(nodeInfo));
+    nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::option,
+                                 getter_AddRefs(nodeInfo));
 
     nsCOMPtr<nsINode> node = NS_NewHTMLOptionElement(nodeInfo.forget());
 
     RefPtr<nsTextNode> text = new nsTextNode(mNodeInfo->NodeInfoManager());
 
     aRv = node->AppendChildTo(text, false);
     if (aRv.Failed()) {
       return;
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -398,26 +398,37 @@ HTMLTableElement::TBodies()
 
 already_AddRefed<nsGenericHTMLElement>
 HTMLTableElement::CreateTHead()
 {
   RefPtr<nsGenericHTMLElement> head = GetTHead();
   if (!head) {
     // Create a new head rowgroup.
     RefPtr<mozilla::dom::NodeInfo> nodeInfo;
-    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::thead,
-                                getter_AddRefs(nodeInfo));
+    nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::thead,
+                                 getter_AddRefs(nodeInfo));
 
     head = NS_NewHTMLTableSectionElement(nodeInfo.forget());
     if (!head) {
       return nullptr;
     }
 
-    ErrorResult rv;
-    nsCOMPtr<nsINode> refNode = nsINode::GetFirstChild();
+    nsCOMPtr<nsIContent> refNode = nullptr;
+    for (refNode = nsINode::GetFirstChild();
+         refNode;
+         refNode = refNode->GetNextSibling()) {
+
+      if (refNode->IsHTMLElement() &&
+          !refNode->IsHTMLElement(nsGkAtoms::caption) &&
+          !refNode->IsHTMLElement(nsGkAtoms::colgroup)) {
+        break;
+      }
+    }
+
+    IgnoredErrorResult rv;
     nsINode::InsertBefore(*head, refNode, rv);
   }
   return head.forget();
 }
 
 void
 HTMLTableElement::DeleteTHead()
 {
@@ -431,18 +442,18 @@ HTMLTableElement::DeleteTHead()
 
 already_AddRefed<nsGenericHTMLElement>
 HTMLTableElement::CreateTFoot()
 {
   RefPtr<nsGenericHTMLElement> foot = GetTFoot();
   if (!foot) {
     // create a new foot rowgroup
     RefPtr<mozilla::dom::NodeInfo> nodeInfo;
-    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tfoot,
-                                getter_AddRefs(nodeInfo));
+    nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tfoot,
+                                 getter_AddRefs(nodeInfo));
 
     foot = NS_NewHTMLTableSectionElement(nodeInfo.forget());
     if (!foot) {
       return nullptr;
     }
     AppendChildTo(foot, true);
   }
 
@@ -462,25 +473,27 @@ HTMLTableElement::DeleteTFoot()
 
 already_AddRefed<nsGenericHTMLElement>
 HTMLTableElement::CreateCaption()
 {
   RefPtr<nsGenericHTMLElement> caption = GetCaption();
   if (!caption) {
     // Create a new caption.
     RefPtr<mozilla::dom::NodeInfo> nodeInfo;
-    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::caption,
-                                getter_AddRefs(nodeInfo));
+    nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::caption,
+                                 getter_AddRefs(nodeInfo));
 
     caption = NS_NewHTMLTableCaptionElement(nodeInfo.forget());
     if (!caption) {
       return nullptr;
     }
 
-    AppendChildTo(caption, true);
+    IgnoredErrorResult rv;
+    nsCOMPtr<nsINode> firsChild = nsINode::GetFirstChild();
+    nsINode::InsertBefore(*caption, firsChild, rv);
   }
   return caption.forget();
 }
 
 void
 HTMLTableElement::DeleteCaption()
 {
   HTMLTableCaptionElement* caption = GetCaption();
@@ -509,17 +522,17 @@ HTMLTableElement::CreateTBody()
        child;
        child = child->GetPreviousSibling()) {
     if (child->IsHTMLElement(nsGkAtoms::tbody)) {
       referenceNode = child->GetNextSibling();
       break;
     }
   }
 
-  ErrorResult rv;
+  IgnoredErrorResult rv;
   nsINode::InsertBefore(*newBody, referenceNode, rv);
 
   return newBody.forget();
 }
 
 already_AddRefed<nsGenericHTMLElement>
 HTMLTableElement::InsertRow(int32_t aIndex, ErrorResult& aError)
 {
@@ -555,18 +568,18 @@ HTMLTableElement::InsertRow(int32_t aInd
       refIndex = rowCount - 1;
     }
 
     RefPtr<Element> refRow = rows->Item(refIndex);
     nsCOMPtr<nsINode> parent = refRow->GetParentNode();
 
     // create the row
     RefPtr<mozilla::dom::NodeInfo> nodeInfo;
-    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tr,
-                                getter_AddRefs(nodeInfo));
+    nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tr,
+                                 getter_AddRefs(nodeInfo));
 
     newRow = NS_NewHTMLTableRowElement(nodeInfo.forget());
 
     if (newRow) {
       // If aIndex is -1 or equal to the number of rows, the new row
       // is appended.
       if (aIndex == -1 || uint32_t(aIndex) == rowCount) {
         parent->AppendChild(*newRow, aError);
@@ -589,32 +602,32 @@ HTMLTableElement::InsertRow(int32_t aInd
       if (child->IsHTMLElement(nsGkAtoms::tbody)) {
         rowGroup = child;
         break;
       }
     }
 
     if (!rowGroup) { // need to create a TBODY
       RefPtr<mozilla::dom::NodeInfo> nodeInfo;
-      nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tbody,
-                                  getter_AddRefs(nodeInfo));
+      nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tbody,
+                                   getter_AddRefs(nodeInfo));
 
       rowGroup = NS_NewHTMLTableSectionElement(nodeInfo.forget());
       if (rowGroup) {
         aError = AppendChildTo(rowGroup, true);
         if (aError.Failed()) {
           return nullptr;
         }
       }
     }
 
     if (rowGroup) {
       RefPtr<mozilla::dom::NodeInfo> nodeInfo;
-      nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tr,
-                                  getter_AddRefs(nodeInfo));
+      nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tr,
+                                   getter_AddRefs(nodeInfo));
 
       newRow = NS_NewHTMLTableRowElement(nodeInfo.forget());
       if (newRow) {
         HTMLTableSectionElement* section =
           static_cast<HTMLTableSectionElement*>(rowGroup.get());
         nsIHTMLCollection* rows = section->Rows();
         nsCOMPtr<nsINode> refNode = rows->Item(0);
         rowGroup->InsertBefore(*newRow, refNode, aError);
--- a/dom/html/HTMLTableElement.h
+++ b/dom/html/HTMLTableElement.h
@@ -31,17 +31,18 @@ public:
   HTMLTableCaptionElement* GetCaption() const
   {
     return static_cast<HTMLTableCaptionElement*>(GetChild(nsGkAtoms::caption));
   }
   void SetCaption(HTMLTableCaptionElement* aCaption, ErrorResult& aError)
   {
     DeleteCaption();
     if (aCaption) {
-      nsINode::AppendChild(*aCaption, aError);
+      nsCOMPtr<nsINode> firstChild = nsINode::GetFirstChild();
+      nsINode::InsertBefore(*aCaption, firstChild, aError);
     }
   }
 
   void DeleteTFoot();
 
   already_AddRefed<nsGenericHTMLElement> CreateCaption();
 
   void DeleteCaption();
@@ -54,17 +55,28 @@ public:
   {
     if (aTHead && !aTHead->IsHTMLElement(nsGkAtoms::thead)) {
       aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR);
       return;
     }
 
     DeleteTHead();
     if (aTHead) {
-      nsCOMPtr<nsINode> refNode = nsINode::GetFirstChild();
+
+      nsCOMPtr<nsIContent> refNode = nullptr;
+      for (refNode = nsINode::GetFirstChild();
+           refNode;
+           refNode = refNode->GetNextSibling()) {
+        if (refNode->IsHTMLElement() &&
+            !refNode->IsHTMLElement(nsGkAtoms::caption) &&
+            !refNode->IsHTMLElement(nsGkAtoms::colgroup)) {
+          break;
+        }
+      }
+
       nsINode::InsertBefore(*aTHead, refNode, aError);
     }
   }
   already_AddRefed<nsGenericHTMLElement> CreateTHead();
 
   void DeleteTHead();
 
   HTMLTableSectionElement* GetTFoot() const
--- a/dom/html/HTMLTableRowElement.cpp
+++ b/dom/html/HTMLTableRowElement.cpp
@@ -170,18 +170,18 @@ HTMLTableRowElement::InsertCell(int32_t 
         aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
         return nullptr;
       }
     }
   }
 
   // create the cell
   RefPtr<mozilla::dom::NodeInfo> nodeInfo;
-  nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::td,
-                              getter_AddRefs(nodeInfo));
+  nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::td,
+                               getter_AddRefs(nodeInfo));
 
   RefPtr<nsGenericHTMLElement> cell =
     NS_NewHTMLTableCellElement(nodeInfo.forget());
   if (!cell) {
     aError.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
 
--- a/dom/html/HTMLTableSectionElement.cpp
+++ b/dom/html/HTMLTableSectionElement.cpp
@@ -75,18 +75,18 @@ HTMLTableSectionElement::InsertRow(int32
     aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
     return nullptr;
   }
 
   bool doInsert = (aIndex < int32_t(rowCount)) && (aIndex != -1);
 
   // create the row
   RefPtr<mozilla::dom::NodeInfo> nodeInfo;
-  nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tr,
-                              getter_AddRefs(nodeInfo));
+  nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tr,
+                               getter_AddRefs(nodeInfo));
 
   RefPtr<nsGenericHTMLElement> rowContent =
     NS_NewHTMLTableRowElement(nodeInfo.forget());
   if (!rowContent) {
     aError.Throw(NS_ERROR_OUT_OF_MEMORY);
     return nullptr;
   }
 
--- a/dom/ipc/ContentPrefs.cpp
+++ b/dom/ipc/ContentPrefs.cpp
@@ -1,278 +1,279 @@
-/* -*- 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 "ContentPrefs.h"
-
-const char* mozilla::dom::ContentPrefs::gInitPrefs[] = {
-  "accessibility.monoaudio.enable",
-  "accessibility.mouse_focuses_formcontrol",
-  "accessibility.tabfocus_applies_to_xul",
-  "app.update.channel",
-  "browser.dom.window.dump.enabled",
-  "browser.sessionhistory.max_entries",
-  "browser.sessionhistory.max_total_viewers",
-  "content.cors.disable",
-  "content.cors.no_private_data",
-  "content.notify.backoffcount",
-  "content.notify.interval",
-  "content.notify.ontimer",
-  "content.sink.enable_perf_mode",
-  "content.sink.event_probe_rate",
-  "content.sink.initial_perf_time",
-  "content.sink.interactive_deflect_count",
-  "content.sink.interactive_parse_time",
-  "content.sink.interactive_time",
-  "content.sink.pending_event_mode",
-  "content.sink.perf_deflect_count",
-  "content.sink.perf_parse_time",
-  "device.storage.prompt.testing",
-  "device.storage.writable.name",
-  "dom.allow_XUL_XBL_for_file",
-  "dom.allow_cut_copy",
-  "dom.enable_frame_timing",
-  "dom.enable_performance",
-  "dom.enable_resource_timing",
-  "dom.event.handling-user-input-time-limit",
-  "dom.event.touch.coalescing.enabled",
-  "dom.forms.autocomplete.experimental",
-  "dom.ipc.processPriorityManager.backgroundGracePeriodMS",
-  "dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS",
-  "dom.max_chrome_script_run_time",
-  "dom.max_script_run_time",
-  "dom.mozBrowserFramesEnabled",
-  "dom.performance.enable_notify_performance_timing",
-  "dom.performance.enable_user_timing_logging",
-  "dom.storage.testing",
-  "dom.url.encode_decode_hash",
-  "dom.url.getters_decode_hash",
-  "dom.use_watchdog",
-  "dom.vibrator.enabled",
-  "dom.vibrator.max_vibrate_list_len",
-  "dom.vibrator.max_vibrate_ms",
-  "focusmanager.testmode",
-  "font.size.inflation.disabledInMasterProcess",
-  "font.size.inflation.emPerLine",
-  "font.size.inflation.forceEnabled",
-  "font.size.inflation.lineThreshold",
-  "font.size.inflation.mappingIntercept",
-  "font.size.inflation.maxRatio",
-  "font.size.inflation.minTwips",
-  "full-screen-api.allow-trusted-requests-only",
-  "full-screen-api.enabled",
-  "full-screen-api.unprefix.enabled",
-  "gfx.font_rendering.opentype_svg.enabled",
-  "hangmonitor.timeout",
-  "html5.flushtimer.initialdelay",
-  "html5.flushtimer.subsequentdelay",
-  "html5.offmainthread",
-  "intl.charset.fallback.tld",
-  "intl.ime.hack.on_ime_unaware_apps.fire_key_events_for_composition",
-  "javascript.enabled",
-  "javascript.options.asmjs",
-  "javascript.options.asyncstack",
-  "javascript.options.baselinejit",
-  "javascript.options.baselinejit.threshold",
-  "javascript.options.baselinejit.unsafe_eager_compilation",
-  "javascript.options.discardSystemSource",
-  "javascript.options.dump_stack_on_debuggee_would_run",
-  "javascript.options.gczeal",
-  "javascript.options.gczeal.frequency",
-  "javascript.options.ion",
-  "javascript.options.ion.offthread_compilation",
-  "javascript.options.ion.threshold",
-  "javascript.options.ion.unsafe_eager_compilation",
-  "javascript.options.jit.full_debug_checks",
-  "javascript.options.native_regexp",
-  "javascript.options.parallel_parsing",
-  "javascript.options.shared_memory",
-  "javascript.options.strict",
-  "javascript.options.strict.debug",
-  "javascript.options.throw_on_asmjs_validation_failure",
-  "javascript.options.throw_on_debuggee_would_run",
-  "javascript.options.wasm",
-  "javascript.options.wasm_baselinejit",
-  "javascript.options.werror",
-  "javascript.use_us_english_locale",
-  "jsloader.reuseGlobal",
-  "layout.css.all-shorthand.enabled",
-  "layout.css.background-blend-mode.enabled",
-  "layout.css.background-clip-text.enabled",
-  "layout.css.box-decoration-break.enabled",
-  "layout.css.color-adjust.enabled",
-  "layout.css.contain.enabled",
-  "layout.css.control-characters.visible",
-  "layout.css.display-flow-root.enabled",
-  "layout.css.expensive-style-struct-assertions.enabled",
-  "layout.css.float-logical-values.enabled",
-  "layout.css.font-variations.enabled",
-  "layout.css.grid.enabled",
-  "layout.css.image-orientation.enabled",
-  "layout.css.initial-letter.enabled",
-  "layout.css.isolation.enabled",
-  "layout.css.mix-blend-mode.enabled",
-  "layout.css.object-fit-and-position.enabled",
-  "layout.css.osx-font-smoothing.enabled",
-  "layout.css.overflow-clip-box.enabled",
-  "layout.css.prefixes.animations",
-  "layout.css.prefixes.border-image",
-  "layout.css.prefixes.box-sizing",
-  "layout.css.prefixes.device-pixel-ratio-webkit",
-  "layout.css.prefixes.font-features",
-  "layout.css.prefixes.gradients",
-  "layout.css.prefixes.transforms",
-  "layout.css.prefixes.transitions",
-  "layout.css.prefixes.webkit",
-  "layout.css.scope-pseudo.enabled",
-  "layout.css.scroll-behavior.property-enabled",
-  "layout.css.scroll-snap.enabled",
-  "layout.css.servo.enabled",
-  "layout.css.shape-outside.enabled",
-  "layout.css.text-align-unsafe-value.enabled",
-  "layout.css.text-combine-upright-digits.enabled",
-  "layout.css.text-combine-upright.enabled",
-  "layout.css.touch_action.enabled",
-  "layout.css.unprefixing-service.enabled",
-  "layout.css.unprefixing-service.globally-whitelisted",
-  "layout.css.unprefixing-service.include-test-domains",
-  "layout.css.variables.enabled",
-  "layout.css.visited_links_enabled",
-  "layout.idle_period.required_quiescent_frames",
-  "layout.idle_period.time_limit",
-  "layout.interruptible-reflow.enabled",
-  "mathml.disabled",
-  "media.apple.forcevda",
-  "media.clearkey.persistent-license.enabled",
-  "media.cubeb_latency_msg_frames",
-  "media.cubeb_latency_playback_ms",
-  "media.decoder-doctor.wmf-disabled-is-failure",
-  "media.decoder.fuzzing.dont-delay-inputexhausted",
-  "media.decoder.fuzzing.enabled",
-  "media.decoder.fuzzing.video-output-minimum-interval-ms",
-  "media.decoder.limit",
-  "media.decoder.recycle.enabled",
-  "media.dormant-on-pause-timeout-ms",
-  "media.eme.audio.blank",
-  "media.eme.enabled",
-  "media.eme.video.blank",
-  "media.ffmpeg.enabled",
-  "media.ffvpx.enabled",
-  "media.flac.enabled",
-  "media.forcestereo.enabled",
-  "media.gmp.async-shutdown-timeout",
-  "media.gmp.decoder.aac",
-  "media.gmp.decoder.enabled",
-  "media.gmp.decoder.h264",
-  "media.gmp.insecure.allow",
-  "media.gpu-process-decoder",
-  "media.libavcodec.allow-obsolete",
-  "media.num-decode-threads",
-  "media.ogg.enabled",
-  "media.ogg.flac.enabled",
-  "media.resampling.enabled",
-  "media.resampling.rate",
-  "media.ruin-av-sync.enabled",
-  "media.rust.test_mode",
-  "media.suspend-bkgnd-video.delay-ms",
-  "media.suspend-bkgnd-video.enabled",
-  "media.use-blank-decoder",
-  "media.video_stats.enabled",
-  "media.volume_scale",
-  "media.webspeech.recognition.enable",
-  "media.webspeech.recognition.force_enable",
-  "media.webspeech.synth.force_global_queue",
-  "media.webspeech.test.enable",
-  "media.webspeech.test.fake_fsm_events",
-  "media.webspeech.test.fake_recognition_service",
-  "media.wmf.allow-unsupported-resolutions",
-  "media.wmf.decoder.thread-count",
-  "media.wmf.enabled",
-  "media.wmf.skip-blacklist",
-  "media.wmf.vp9.enabled",
-  "memory.free_dirty_pages",
-  "memory.low_commit_space_threshold_mb",
-  "memory.low_memory_notification_interval_ms",
-  "memory.low_physical_memory_threshold_mb",
-  "memory.low_virtual_mem_threshold_mb",
-  "network.IDN.blacklist_chars",
-  "network.IDN.restriction_profile",
-  "network.IDN.use_whitelist",
-  "network.IDN_show_punycode",
-  "network.buffer.cache.count",
-  "network.buffer.cache.size",
-  "network.captive-portal-service.enabled",
-  "network.cookie.cookieBehavior",
-  "network.cookie.lifetimePolicy",
-  "network.dns.disablePrefetch",
-  "network.dns.disablePrefetchFromHTTPS",
-  "network.jar.block-remote-files",
-  "network.loadinfo.skip_type_assertion",
-  "network.notify.changed",
-  "network.offline-mirrors-connectivity",
-  "network.protocol-handler.external.jar",
-  "network.proxy.type",
-  "network.security.ports.banned",
-  "network.security.ports.banned.override",
-  "network.standard-url.enable-rust",
-  "network.standard-url.max-length",
-  "network.sts.max_time_for_events_between_two_polls",
-  "network.sts.max_time_for_pr_close_during_shutdown",
-  "network.tcp.keepalive.enabled",
-  "network.tcp.keepalive.idle_time",
-  "network.tcp.keepalive.probe_count",
-  "network.tcp.keepalive.retry_interval",
-  "network.tcp.sendbuffer",
-  "nglayout.debug.invalidation",
-  "privacy.donottrackheader.enabled",
-  "privacy.firstparty.isolate",
-  "privacy.firstparty.isolate.restrict_opener_access",
-  "privacy.resistFingerprinting",
-  "security.data_uri.inherit_security_context",
-  "security.fileuri.strict_origin_policy",
-  "security.sandbox.content.level",
-  "security.sandbox.content.tempDirSuffix",
-  "security.sandbox.logging.enabled",
-  "security.sandbox.mac.track.violations",
-  "security.sandbox.windows.log",
-  "security.sandbox.windows.log.stackTraceDepth",
-  "shutdown.watchdog.timeoutSecs",
-  "signed.applets.codebase_principal_support",
-  "svg.disabled",
-  "svg.display-lists.hit-testing.enabled",
-  "svg.display-lists.painting.enabled",
-  "svg.new-getBBox.enabled",
-  "svg.paint-order.enabled",
-  "svg.path-caching.enabled",
-  "svg.transform-box.enabled",
-  "toolkit.asyncshutdown.crash_timeout",
-  "toolkit.asyncshutdown.log",
-  "toolkit.osfile.log",
-  "toolkit.osfile.log.redirect",
-  "toolkit.telemetry.enabled",
-  "toolkit.telemetry.idleTimeout",
-  "toolkit.telemetry.initDelay",
-  "toolkit.telemetry.log.dump",
-  "toolkit.telemetry.log.level",
-  "toolkit.telemetry.minSubsessionLength",
-  "toolkit.telemetry.scheduler.idleTickInterval",
-  "toolkit.telemetry.scheduler.tickInterval",
-  "toolkit.telemetry.unified",
-  "ui.key.menuAccessKeyFocuses",
-  "ui.popup.disable_autohide",
-  "ui.use_activity_cursor",
-  "view_source.editor.external"};
-
-const char** mozilla::dom::ContentPrefs::GetContentPrefs(size_t* aCount)
-{
-  *aCount = ArrayLength(ContentPrefs::gInitPrefs);
-  return gInitPrefs;
-}
-
-const char*  mozilla::dom::ContentPrefs::GetContentPref(size_t aIndex)
-{
-  MOZ_ASSERT(aIndex < ArrayLength(ContentPrefs::gInitPrefs));
-  return gInitPrefs[aIndex];
-}
-
+/* -*- 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 "ContentPrefs.h"
+
+const char* mozilla::dom::ContentPrefs::gInitPrefs[] = {
+  "accessibility.monoaudio.enable",
+  "accessibility.mouse_focuses_formcontrol",
+  "accessibility.tabfocus_applies_to_xul",
+  "app.update.channel",
+  "browser.dom.window.dump.enabled",
+  "browser.sessionhistory.max_entries",
+  "browser.sessionhistory.max_total_viewers",
+  "content.cors.disable",
+  "content.cors.no_private_data",
+  "content.notify.backoffcount",
+  "content.notify.interval",
+  "content.notify.ontimer",
+  "content.sink.enable_perf_mode",
+  "content.sink.event_probe_rate",
+  "content.sink.initial_perf_time",
+  "content.sink.interactive_deflect_count",
+  "content.sink.interactive_parse_time",
+  "content.sink.interactive_time",
+  "content.sink.pending_event_mode",
+  "content.sink.perf_deflect_count",
+  "content.sink.perf_parse_time",
+  "device.storage.prompt.testing",
+  "device.storage.writable.name",
+  "dom.allow_XUL_XBL_for_file",
+  "dom.allow_cut_copy",
+  "dom.enable_frame_timing",
+  "dom.enable_performance",
+  "dom.enable_resource_timing",
+  "dom.event.handling-user-input-time-limit",
+  "dom.event.touch.coalescing.enabled",
+  "dom.forms.autocomplete.experimental",
+  "dom.ipc.processPriorityManager.backgroundGracePeriodMS",
+  "dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS",
+  "dom.max_chrome_script_run_time",
+  "dom.max_script_run_time",
+  "dom.mozBrowserFramesEnabled",
+  "dom.performance.enable_notify_performance_timing",
+  "dom.performance.enable_user_timing_logging",
+  "dom.storage.testing",
+  "dom.url.encode_decode_hash",
+  "dom.url.getters_decode_hash",
+  "dom.use_watchdog",
+  "dom.vibrator.enabled",
+  "dom.vibrator.max_vibrate_list_len",
+  "dom.vibrator.max_vibrate_ms",
+  "focusmanager.testmode",
+  "font.size.inflation.disabledInMasterProcess",
+  "font.size.inflation.emPerLine",
+  "font.size.inflation.forceEnabled",
+  "font.size.inflation.lineThreshold",
+  "font.size.inflation.mappingIntercept",
+  "font.size.inflation.maxRatio",
+  "font.size.inflation.minTwips",
+  "full-screen-api.allow-trusted-requests-only",
+  "full-screen-api.enabled",
+  "full-screen-api.unprefix.enabled",
+  "gfx.font_rendering.opentype_svg.enabled",
+  "hangmonitor.timeout",
+  "html5.flushtimer.initialdelay",
+  "html5.flushtimer.subsequentdelay",
+  "html5.offmainthread",
+  "intl.charset.fallback.tld",
+  "intl.ime.hack.on_ime_unaware_apps.fire_key_events_for_composition",
+  "javascript.enabled",
+  "javascript.options.asmjs",
+  "javascript.options.asyncstack",
+  "javascript.options.baselinejit",
+  "javascript.options.baselinejit.threshold",
+  "javascript.options.baselinejit.unsafe_eager_compilation",
+  "javascript.options.discardSystemSource",
+  "javascript.options.dump_stack_on_debuggee_would_run",
+  "javascript.options.gczeal",
+  "javascript.options.gczeal.frequency",
+  "javascript.options.ion",
+  "javascript.options.ion.offthread_compilation",
+  "javascript.options.ion.threshold",
+  "javascript.options.ion.unsafe_eager_compilation",
+  "javascript.options.jit.full_debug_checks",
+  "javascript.options.native_regexp",
+  "javascript.options.parallel_parsing",
+  "javascript.options.shared_memory",
+  "javascript.options.strict",
+  "javascript.options.strict.debug",
+  "javascript.options.throw_on_asmjs_validation_failure",
+  "javascript.options.throw_on_debuggee_would_run",
+  "javascript.options.wasm",
+  "javascript.options.wasm_baselinejit",
+  "javascript.options.werror",
+  "javascript.use_us_english_locale",
+  "jsloader.reuseGlobal",
+  "layout.css.all-shorthand.enabled",
+  "layout.css.background-blend-mode.enabled",
+  "layout.css.background-clip-text.enabled",
+  "layout.css.box-decoration-break.enabled",
+  "layout.css.color-adjust.enabled",
+  "layout.css.contain.enabled",
+  "layout.css.control-characters.visible",
+  "layout.css.display-flow-root.enabled",
+  "layout.css.expensive-style-struct-assertions.enabled",
+  "layout.css.float-logical-values.enabled",
+  "layout.css.font-variations.enabled",
+  "layout.css.grid.enabled",
+  "layout.css.image-orientation.enabled",
+  "layout.css.initial-letter.enabled",
+  "layout.css.isolation.enabled",
+  "layout.css.mix-blend-mode.enabled",
+  "layout.css.object-fit-and-position.enabled",
+  "layout.css.osx-font-smoothing.enabled",
+  "layout.css.overflow-clip-box.enabled",
+  "layout.css.prefixes.animations",
+  "layout.css.prefixes.border-image",
+  "layout.css.prefixes.box-sizing",
+  "layout.css.prefixes.device-pixel-ratio-webkit",
+  "layout.css.prefixes.font-features",
+  "layout.css.prefixes.gradients",
+  "layout.css.prefixes.transforms",
+  "layout.css.prefixes.transitions",
+  "layout.css.prefixes.webkit",
+  "layout.css.scope-pseudo.enabled",
+  "layout.css.scroll-behavior.property-enabled",
+  "layout.css.scroll-snap.enabled",
+  "layout.css.servo.enabled",
+  "layout.css.shape-outside.enabled",
+  "layout.css.text-align-unsafe-value.enabled",
+  "layout.css.text-combine-upright-digits.enabled",
+  "layout.css.text-combine-upright.enabled",
+  "layout.css.touch_action.enabled",
+  "layout.css.unprefixing-service.enabled",
+  "layout.css.unprefixing-service.globally-whitelisted",
+  "layout.css.unprefixing-service.include-test-domains",
+  "layout.css.variables.enabled",
+  "layout.css.visited_links_enabled",
+  "layout.idle_period.required_quiescent_frames",
+  "layout.idle_period.time_limit",
+  "layout.interruptible-reflow.enabled",
+  "mathml.disabled",
+  "media.apple.forcevda",
+  "media.clearkey.persistent-license.enabled",
+  "media.cubeb_latency_msg_frames",
+  "media.cubeb_latency_playback_ms",
+  "media.decoder-doctor.wmf-disabled-is-failure",
+  "media.decoder.fuzzing.dont-delay-inputexhausted",
+  "media.decoder.fuzzing.enabled",
+  "media.decoder.fuzzing.video-output-minimum-interval-ms",
+  "media.decoder.limit",
+  "media.decoder.recycle.enabled",
+  "media.dormant-on-pause-timeout-ms",
+  "media.eme.audio.blank",
+  "media.eme.enabled",
+  "media.eme.video.blank",
+  "media.ffmpeg.enabled",
+  "media.ffvpx.enabled",
+  "media.ffvpx.low-latency.enabled",
+  "media.flac.enabled",
+  "media.forcestereo.enabled",
+  "media.gmp.async-shutdown-timeout",
+  "media.gmp.decoder.aac",
+  "media.gmp.decoder.enabled",
+  "media.gmp.decoder.h264",
+  "media.gmp.insecure.allow",
+  "media.gpu-process-decoder",
+  "media.libavcodec.allow-obsolete",
+  "media.num-decode-threads",
+  "media.ogg.enabled",
+  "media.ogg.flac.enabled",
+  "media.resampling.enabled",
+  "media.resampling.rate",
+  "media.ruin-av-sync.enabled",
+  "media.rust.test_mode",
+  "media.suspend-bkgnd-video.delay-ms",
+  "media.suspend-bkgnd-video.enabled",
+  "media.use-blank-decoder",
+  "media.video_stats.enabled",
+  "media.volume_scale",
+  "media.webspeech.recognition.enable",
+  "media.webspeech.recognition.force_enable",
+  "media.webspeech.synth.force_global_queue",
+  "media.webspeech.test.enable",
+  "media.webspeech.test.fake_fsm_events",
+  "media.webspeech.test.fake_recognition_service",
+  "media.wmf.allow-unsupported-resolutions",
+  "media.wmf.decoder.thread-count",
+  "media.wmf.enabled",
+  "media.wmf.skip-blacklist",
+  "media.wmf.vp9.enabled",
+  "memory.free_dirty_pages",
+  "memory.low_commit_space_threshold_mb",
+  "memory.low_memory_notification_interval_ms",
+  "memory.low_physical_memory_threshold_mb",
+  "memory.low_virtual_mem_threshold_mb",
+  "network.IDN.blacklist_chars",
+  "network.IDN.restriction_profile",
+  "network.IDN.use_whitelist",
+  "network.IDN_show_punycode",
+  "network.buffer.cache.count",
+  "network.buffer.cache.size",
+  "network.captive-portal-service.enabled",
+  "network.cookie.cookieBehavior",
+  "network.cookie.lifetimePolicy",
+  "network.dns.disablePrefetch",
+  "network.dns.disablePrefetchFromHTTPS",
+  "network.jar.block-remote-files",
+  "network.loadinfo.skip_type_assertion",
+  "network.notify.changed",
+  "network.offline-mirrors-connectivity",
+  "network.protocol-handler.external.jar",
+  "network.proxy.type",
+  "network.security.ports.banned",
+  "network.security.ports.banned.override",
+  "network.standard-url.enable-rust",
+  "network.standard-url.max-length",
+  "network.sts.max_time_for_events_between_two_polls",
+  "network.sts.max_time_for_pr_close_during_shutdown",
+  "network.tcp.keepalive.enabled",
+  "network.tcp.keepalive.idle_time",
+  "network.tcp.keepalive.probe_count",
+  "network.tcp.keepalive.retry_interval",
+  "network.tcp.sendbuffer",
+  "nglayout.debug.invalidation",
+  "privacy.donottrackheader.enabled",
+  "privacy.firstparty.isolate",
+  "privacy.firstparty.isolate.restrict_opener_access",
+  "privacy.resistFingerprinting",
+  "security.data_uri.inherit_security_context",
+  "security.fileuri.strict_origin_policy",
+  "security.sandbox.content.level",
+  "security.sandbox.content.tempDirSuffix",
+  "security.sandbox.logging.enabled",
+  "security.sandbox.mac.track.violations",
+  "security.sandbox.windows.log",
+  "security.sandbox.windows.log.stackTraceDepth",
+  "shutdown.watchdog.timeoutSecs",
+  "signed.applets.codebase_principal_support",
+  "svg.disabled",
+  "svg.display-lists.hit-testing.enabled",
+  "svg.display-lists.painting.enabled",
+  "svg.new-getBBox.enabled",
+  "svg.paint-order.enabled",
+  "svg.path-caching.enabled",
+  "svg.transform-box.enabled",
+  "toolkit.asyncshutdown.crash_timeout",
+  "toolkit.asyncshutdown.log",
+  "toolkit.osfile.log",
+  "toolkit.osfile.log.redirect",
+  "toolkit.telemetry.enabled",
+  "toolkit.telemetry.idleTimeout",
+  "toolkit.telemetry.initDelay",
+  "toolkit.telemetry.log.dump",
+  "toolkit.telemetry.log.level",
+  "toolkit.telemetry.minSubsessionLength",
+  "toolkit.telemetry.scheduler.idleTickInterval",
+  "toolkit.telemetry.scheduler.tickInterval",
+  "toolkit.telemetry.unified",
+  "ui.key.menuAccessKeyFocuses",
+  "ui.popup.disable_autohide",
+  "ui.use_activity_cursor",
+  "view_source.editor.external"};
+
+const char** mozilla::dom::ContentPrefs::GetContentPrefs(size_t* aCount)
+{
+  *aCount = ArrayLength(ContentPrefs::gInitPrefs);
+  return gInitPrefs;
+}
+
+const char*  mozilla::dom::ContentPrefs::GetContentPref(size_t aIndex)
+{
+  MOZ_ASSERT(aIndex < ArrayLength(ContentPrefs::gInitPrefs));
+  return gInitPrefs[aIndex];
+}
+
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2676,20 +2676,26 @@ already_AddRefed<nsILoadContext>
 TabParent::GetLoadContext()
 {
   nsCOMPtr<nsILoadContext> loadContext;
   if (mLoadContext) {
     loadContext = mLoadContext;
   } else {
     bool isPrivate = mChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
     SetPrivateBrowsingAttributes(isPrivate);
+    bool useTrackingProtection = false;
+    nsCOMPtr<nsIDocShell> docShell = mFrameElement->OwnerDoc()->GetDocShell();
+    if (docShell) {
+      docShell->GetUseTrackingProtection(&useTrackingProtection);
+    }
     loadContext = new LoadContext(GetOwnerElement(),
                                   true /* aIsContent */,
                                   isPrivate,
                                   mChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW,
+                                  useTrackingProtection,
                                   OriginAttributesRef());
     mLoadContext = loadContext;
   }
   return loadContext.forget();
 }
 
 NS_IMETHODIMP
 TabParent::GetUseAsyncPanZoom(bool* useAsyncPanZoom)
@@ -2989,17 +2995,18 @@ public:
   NS_IMETHOD GetIsContent(bool*) NO_IMPL
   NS_IMETHOD GetUsePrivateBrowsing(bool*) NO_IMPL
   NS_IMETHOD SetUsePrivateBrowsing(bool) NO_IMPL
   NS_IMETHOD SetPrivateBrowsing(bool) NO_IMPL
   NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool*) NO_IMPL
   NS_IMETHOD GetOriginAttributes(JS::MutableHandleValue) NO_IMPL
   NS_IMETHOD GetUseRemoteTabs(bool*) NO_IMPL
   NS_IMETHOD SetRemoteTabs(bool) NO_IMPL
-  NS_IMETHOD IsTrackingProtectionOn(bool*) NO_IMPL
+  NS_IMETHOD GetUseTrackingProtection(bool*) NO_IMPL
+  NS_IMETHOD SetUseTrackingProtection(bool) NO_IMPL
 #undef NO_IMPL
 
 protected:
   ~FakeChannel() {}
 
   nsCOMPtr<nsIURI> mUri;
   uint64_t mCallbackId;
   nsCOMPtr<Element> mElement;
--- a/dom/media/MediaPrefs.h
+++ b/dom/media/MediaPrefs.h
@@ -116,16 +116,17 @@ private:
   DECL_MEDIA_PREF("media.android-media-codec.preferred",      PDMAndroidMediaCodecPreferred, bool, false);
 #endif
 #ifdef MOZ_FFMPEG
   DECL_MEDIA_PREF("media.ffmpeg.enabled",                     PDMFFmpegEnabled, bool, true);
   DECL_MEDIA_PREF("media.libavcodec.allow-obsolete",          LibavcodecAllowObsolete, bool, false);
 #endif
 #ifdef MOZ_FFVPX
   DECL_MEDIA_PREF("media.ffvpx.enabled",                      PDMFFVPXEnabled, bool, true);
+  DECL_MEDIA_PREF("media.ffvpx.low-latency.enabled",          PDMFFVPXLowLatencyEnabled, bool, false);
 #endif
 #ifdef XP_WIN
   DECL_MEDIA_PREF("media.wmf.enabled",                        PDMWMFEnabled, bool, true);
   DECL_MEDIA_PREF("media.wmf.skip-blacklist",                 PDMWMFSkipBlacklist, bool, false);
   DECL_MEDIA_PREF("media.decoder-doctor.wmf-disabled-is-failure", DecoderDoctorWMFDisabledIsFailure, bool, false);
   DECL_MEDIA_PREF("media.wmf.vp9.enabled",                    PDMWMFVP9DecoderEnabled, bool, true);
   DECL_MEDIA_PREF("media.wmf.decoder.thread-count",           PDMWMFThreadCount, int32_t, -1);
   DECL_MEDIA_PREF("media.wmf.allow-unsupported-resolutions",  PDMWMFAllowUnsupportedResolutions, bool, false);
--- a/dom/media/gmp/GMPCrashHelper.h
+++ b/dom/media/gmp/GMPCrashHelper.h
@@ -2,18 +2,19 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
 #if !defined(GMPCrashHelper_h_)
 #define GMPCrashHelper_h_
 
+#include "MainThreadUtils.h"
+#include "nsISupportsImpl.h"
 #include "nsPIDOMWindow.h"
-#include "nsISupportsImpl.h"
 
 namespace mozilla {
 
 // For every GMP actor requested, the caller can specify a crash helper,
 // which is an object which supplies the nsPIDOMWindowInner to which we'll
 // dispatch the PluginCrashed event if the GMP crashes.
 // GMPCrashHelper has threadsafe refcounting. Its release method ensures
 // that instances are destroyed on the main thread.
--- a/dom/media/ipc/PVideoDecoder.ipdl
+++ b/dom/media/ipc/PVideoDecoder.ipdl
@@ -21,16 +21,17 @@ struct MediaDataIPDL
   uint32_t frames;
   bool keyframe;
 };
 
 struct VideoDataIPDL
 {
   MediaDataIPDL base;
   IntSize display;
+  IntSize frameSize;
   SurfaceDescriptorGPUVideo sd;
   int32_t frameID;
 };
 
 struct MediaRawDataIPDL
 {
   MediaDataIPDL base;
   Shmem buffer;
--- a/dom/media/ipc/VideoDecoderChild.cpp
+++ b/dom/media/ipc/VideoDecoderChild.cpp
@@ -39,17 +39,17 @@ mozilla::ipc::IPCResult
 VideoDecoderChild::RecvOutput(const VideoDataIPDL& aData)
 {
   AssertOnManagerThread();
   VideoInfo info(aData.display().width, aData.display().height);
 
   // The Image here creates a TextureData object that takes ownership
   // of the SurfaceDescriptor, and is responsible for making sure that
   // it gets deallocated.
-  RefPtr<Image> image = new GPUVideoImage(GetManager(), aData.sd(), aData.display());
+  RefPtr<Image> image = new GPUVideoImage(GetManager(), aData.sd(), aData.frameSize());
 
   RefPtr<VideoData> video = VideoData::CreateFromImage(info,
                                                        aData.base().offset(),
                                                        aData.base().time(),
                                                        aData.base().duration(),
                                                        image,
                                                        aData.base().keyframe(),
                                                        aData.base().timecode(),
--- a/dom/media/ipc/VideoDecoderParent.cpp
+++ b/dom/media/ipc/VideoDecoderParent.cpp
@@ -184,16 +184,17 @@ VideoDecoderParent::ProcessDecodedData(
       texture->InitIPDLActor(mKnowsCompositor);
       texture->SetAddedToCompositableClient();
     }
 
     VideoDataIPDL output(
       MediaDataIPDL(data->mOffset, data->mTime, data->mTimecode,
                     data->mDuration, data->mFrames, data->mKeyframe),
       video->mDisplay,
+      texture ? texture->GetSize() : IntSize(),
       texture ? mParent->StoreImage(video->mImage, texture)
               : SurfaceDescriptorGPUVideo(0),
       video->mFrameID);
     Unused << SendOutput(output);
   }
 }
 
 mozilla::ipc::IPCResult
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -110,16 +110,18 @@ MediaSource::IsTypeSupported(const nsASt
       mimeType == MEDIAMIMETYPE("audio/mp4")) {
     if (!Preferences::GetBool("media.mediasource.mp4.enabled", false)) {
       return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
     }
     return NS_OK;
   }
   if (mimeType == MEDIAMIMETYPE("video/webm")) {
     if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
+          containerType->ExtendedType().Codecs().Contains(
+            NS_LITERAL_STRING("vp8")) ||
           IsWebMForced(aDiagnostics))) {
       return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
     }
     return NS_OK;
   }
   if (mimeType == MEDIAMIMETYPE("audio/webm")) {
     if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
           Preferences::GetBool("media.mediasource.webm.audio.enabled", true))) {
--- a/dom/media/mediasource/test/test_MediaSource.html
+++ b/dom/media/mediasource/test/test_MediaSource.html
@@ -35,16 +35,19 @@ runWithMSE(function () {
   v.src = o;
   document.body.appendChild(v);
 
   var loadedmetadataCount = 0;
   var updatestartCount = 0;
   var updateendCount = 0;
   var updateCount = 0;
 
+  ok(MediaSource.isTypeSupported("video/webm; codecs=vp8"), "VP8 MSE is always supported");
+  ok(MediaSource.isTypeSupported("audio/webm", "Audio MSE is always supported"));
+
   ms.addEventListener("sourceopen", function () {
     ok(true, "Receive a sourceopen event");
     is(ms.readyState, "open", "MediaSource must be in open state after sourceopen");
     var sb = ms.addSourceBuffer("video/webm");
     ok(sb, "Create a SourceBuffer");
     is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length");
     is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer");
     is(ms.activeSourceBuffers.length, 0, "MediaSource.activeSourceBuffers is expected length");
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -2,26 +2,27 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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/. */
 
 #if !defined(PlatformDecoderModule_h_)
 #define PlatformDecoderModule_h_
 
+#include "GMPCrashHelper.h"
 #include "MediaDecoderReader.h"
 #include "MediaInfo.h"
+#include "MediaResult.h"
+#include "mozilla/EnumSet.h"
 #include "mozilla/MozPromise.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/layers/KnowsCompositor.h"
 #include "mozilla/layers/LayersTypes.h"
-#include "mozilla/layers/KnowsCompositor.h"
 #include "nsTArray.h"
-#include "mozilla/RefPtr.h"
-#include "GMPCrashHelper.h"
 #include <queue>
-#include "MediaResult.h"
 
 namespace mozilla {
 class TrackInfo;
 class AudioInfo;
 class VideoInfo;
 class MediaRawData;
 class DecoderDoctorDiagnostics;
 
@@ -36,20 +37,24 @@ class RemoteDecoderModule;
 class MediaDataDecoder;
 class TaskQueue;
 class CDMProxy;
 
 static LazyLogModule sPDMLog("PlatformDecoderModule");
 
 struct MOZ_STACK_CLASS CreateDecoderParams final
 {
-  explicit CreateDecoderParams(const TrackInfo& aConfig)
-    : mConfig(aConfig)
+  explicit CreateDecoderParams(const TrackInfo& aConfig) : mConfig(aConfig) { }
+
+  enum class Option
   {
-  }
+    Default,
+    LowLatency,
+  };
+  using OptionSet = EnumSet<Option>;
 
   template <typename T1, typename... Ts>
   CreateDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args)
     : mConfig(aConfig)
   {
     Set(mozilla::Forward<T1>(a1), mozilla::Forward<Ts>(args)...);
   }
 
@@ -78,30 +83,32 @@ struct MOZ_STACK_CLASS CreateDecoderPara
   DecoderDoctorDiagnostics* mDiagnostics = nullptr;
   layers::ImageContainer* mImageContainer = nullptr;
   MediaResult* mError = nullptr;
   RefPtr<layers::KnowsCompositor> mKnowsCompositor;
   RefPtr<GMPCrashHelper> mCrashHelper;
   bool mUseBlankDecoder = false;
   TrackInfo::TrackType mType = TrackInfo::kUndefinedTrack;
   MediaEventProducer<TrackInfo::TrackType>* mOnWaitingForKeyEvent = nullptr;
+  OptionSet mOptions = OptionSet(Option::Default);
 
 private:
   void Set(TaskQueue* aTaskQueue) { mTaskQueue = aTaskQueue; }
   void Set(DecoderDoctorDiagnostics* aDiagnostics)
   {
     mDiagnostics = aDiagnostics;
   }
   void Set(layers::ImageContainer* aImageContainer)
   {
     mImageContainer = aImageContainer;
   }
   void Set(MediaResult* aError) { mError = aError; }
   void Set(GMPCrashHelper* aCrashHelper) { mCrashHelper = aCrashHelper; }
   void Set(bool aUseBlankDecoder) { mUseBlankDecoder = aUseBlankDecoder; }
+  void Set(OptionSet aOptions) { mOptions = aOptions; }
   void Set(layers::KnowsCompositor* aKnowsCompositor)
   {
     mKnowsCompositor = aKnowsCompositor;
   }
   void Set(TrackInfo::TrackType aType)
   {
     mType = aType;
   }
@@ -133,24 +140,25 @@ private:
 
 class PlatformDecoderModule
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PlatformDecoderModule)
 
   // Perform any per-instance initialization.
   // This is called on the decode task queue.
-  virtual nsresult Startup() { return NS_OK; };
+  virtual nsresult Startup() { return NS_OK; }
 
   // Indicates if the PlatformDecoderModule supports decoding of aMimeType.
-  virtual bool SupportsMimeType(
-    const nsACString& aMimeType,
-    DecoderDoctorDiagnostics* aDiagnostics) const = 0;
-  virtual bool Supports(const TrackInfo& aTrackInfo,
-                        DecoderDoctorDiagnostics* aDiagnostics) const
+  virtual bool
+  SupportsMimeType(const nsACString& aMimeType,
+                   DecoderDoctorDiagnostics* aDiagnostics) const = 0;
+  virtual bool
+  Supports(const TrackInfo& aTrackInfo,
+           DecoderDoctorDiagnostics* aDiagnostics) const
   {
     // By default, fall back to SupportsMimeType with just the MIME string.
     // (So PDMs do not need to override this method -- yet.)
     return SupportsMimeType(aTrackInfo.mMimeType, aDiagnostics);
   }
 
 protected:
   PlatformDecoderModule() { }
@@ -202,17 +210,17 @@ protected:
 //
 // Decoding is done asynchronously. Any async work can be done on the
 // TaskQueue passed into the PlatformDecoderModules's Create*Decoder()
 // function. This may not be necessary for platforms with async APIs
 // for decoding.
 class MediaDataDecoder
 {
 protected:
-  virtual ~MediaDataDecoder() {};
+  virtual ~MediaDataDecoder() { }
 
 public:
   typedef TrackInfo::TrackType TrackType;
   typedef nsTArray<RefPtr<MediaData>> DecodedData;
   typedef MozPromise<TrackType, MediaResult, /* IsExclusive = */ true>
     InitPromise;
   typedef MozPromise<DecodedData, MediaResult, /* IsExclusive = */ true>
     DecodePromise;
@@ -276,17 +284,17 @@ public:
   virtual const char* GetDescriptionName() const = 0;
 
   // Set a hint of seek target time to decoder. Decoder will drop any decoded
   // data which pts is smaller than this value. This threshold needs to be clear
   // after reset decoder.
   // Decoder may not honor this value. However, it'd be better that
   // video decoder implements this API to improve seek performance.
   // Note: it should be called before Input() or after Flush().
-  virtual void SetSeekThreshold(const media::TimeUnit& aTime) {}
+  virtual void SetSeekThreshold(const media::TimeUnit& aTime) { }
 
   // When playing adaptive playback, recreating an Android video decoder will
   // cause the transition not smooth during resolution change.
   // Reuse the decoder if the decoder support recycling.
   // Currently, only Android video decoder will return true.
   virtual bool SupportDecoderRecycling() const { return false; }
 
   // ConfigurationChanged will be called to inform the video or audio decoder
--- a/dom/media/platforms/agnostic/OpusDecoder.cpp
+++ b/dom/media/platforms/agnostic/OpusDecoder.cpp
@@ -169,38 +169,47 @@ OpusDataDecoder::ProcessDecode(MediaRawD
 
   if (!mLastFrameTime || mLastFrameTime.ref() != aSample->mTime) {
     // We are starting a new block.
     mFrames = 0;
     mLastFrameTime = Some(aSample->mTime);
   }
 
   // Maximum value is 63*2880, so there's no chance of overflow.
-  uint32_t frames_number = opus_packet_get_nb_frames(aSample->Data(),
-                                                    aSample->Size());
+  int frames_number =
+    opus_packet_get_nb_frames(aSample->Data(), aSample->Size());
   if (frames_number <= 0) {
-    OPUS_DEBUG("Invalid packet header: r=%" PRIu32 " length=%" PRIuSIZE, frames_number,
+    OPUS_DEBUG("Invalid packet header: r=%d length=%" PRIuSIZE, frames_number,
                aSample->Size());
     return DecodePromise::CreateAndReject(
       MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
                   RESULT_DETAIL("Invalid packet header: r=%d length=%u",
                                 frames_number, uint32_t(aSample->Size()))),
       __func__);
   }
 
-  uint32_t samples = opus_packet_get_samples_per_frame(
+  int samples = opus_packet_get_samples_per_frame(
     aSample->Data(), opus_int32(mOpusParser->mRate));
 
   // A valid Opus packet must be between 2.5 and 120 ms long (48kHz).
-  uint32_t frames = frames_number*samples;
-  if (frames < 120 || frames > 5760) {
-    OPUS_DEBUG("Invalid packet frames: %u", frames);
+  CheckedInt32 totalFrames =
+    CheckedInt32(frames_number) * CheckedInt32(samples);
+  if (!totalFrames.isValid()) {
     return DecodePromise::CreateAndReject(
       MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
-                  RESULT_DETAIL("Invalid packet frames:%u", frames)),
+                  RESULT_DETAIL("Frames count overflow")),
+      __func__);
+  }
+
+  int frames = totalFrames.value();
+  if (frames < 120 || frames > 5760) {
+    OPUS_DEBUG("Invalid packet frames: %d", frames);
+    return DecodePromise::CreateAndReject(
+      MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+                  RESULT_DETAIL("Invalid packet frames:%d", frames)),
       __func__);
   }
 
   AlignedAudioBuffer buffer(frames * channels);
   if (!buffer) {
     return DecodePromise::CreateAndReject(
       MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__), __func__);
   }
@@ -216,39 +225,40 @@ OpusDataDecoder::ProcessDecode(MediaRawD
                                     buffer.get(), frames, false);
 #endif
   if (ret < 0) {
     return DecodePromise::CreateAndReject(
       MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
                   RESULT_DETAIL("Opus decoding error:%d", ret)),
       __func__);
   }
-  NS_ASSERTION(uint32_t(ret) == frames, "Opus decoded too few audio samples");
+  NS_ASSERTION(ret == frames, "Opus decoded too few audio samples");
   CheckedInt64 startTime = aSample->mTime;
 
   // Trim the initial frames while the decoder is settling.
   if (mSkip > 0) {
     int32_t skipFrames = std::min<int32_t>(mSkip, frames);
     int32_t keepFrames = frames - skipFrames;
-    OPUS_DEBUG("Opus decoder skipping %d of %d frames", skipFrames, frames);
+    OPUS_DEBUG(
+      "Opus decoder skipping %d of %d frames", skipFrames, frames);
     PodMove(buffer.get(),
             buffer.get() + skipFrames * channels,
             keepFrames * channels);
     startTime = startTime + FramesToUsecs(skipFrames, mOpusParser->mRate);
     frames = keepFrames;
     mSkip -= skipFrames;
   }
 
   if (aSample->mDiscardPadding > 0) {
-    OPUS_DEBUG("Opus decoder discarding %u of %u frames",
+    OPUS_DEBUG("Opus decoder discarding %u of %d frames",
                aSample->mDiscardPadding, frames);
     // Padding discard is only supposed to happen on the final packet.
     // Record the discard so we can return an error if another packet is
     // decoded.
-    if (aSample->mDiscardPadding > frames) {
+    if (aSample->mDiscardPadding > uint32_t(frames)) {
       // Discarding more than the entire packet is invalid.
       OPUS_DEBUG("Opus error, discard padding larger than packet");
       return DecodePromise::CreateAndReject(
         MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                     RESULT_DETAIL("Discard padding larger than packet")),
         __func__);
     }
 
--- a/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
+++ b/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h
@@ -6,16 +6,17 @@
 
 #ifndef __FFmpegDecoderModule_h__
 #define __FFmpegDecoderModule_h__
 
 #include "PlatformDecoderModule.h"
 #include "FFmpegLibWrapper.h"
 #include "FFmpegAudioDecoder.h"
 #include "FFmpegVideoDecoder.h"
+#include "MediaPrefs.h"
 
 namespace mozilla {
 
 template <int V>
 class FFmpegDecoderModule : public PlatformDecoderModule
 {
 public:
   static already_AddRefed<PlatformDecoderModule>
@@ -34,21 +35,27 @@ public:
   {
     // Temporary - forces use of VPXDecoder when alpha is present.
     // Bug 1263836 will handle alpha scenario once implemented. It will shift
     // the check for alpha to PDMFactory but not itself remove the need for a
     // check.
     if (aParams.VideoConfig().HasAlpha()) {
       return nullptr;
     }
-    RefPtr<MediaDataDecoder> decoder =
-      new FFmpegVideoDecoder<V>(mLib,
-                                aParams.mTaskQueue,
-                                aParams.VideoConfig(),
-                                aParams.mImageContainer);
+    if (aParams.mOptions.contains(
+          CreateDecoderParams::Option::LowLatency) &&
+        !MediaPrefs::PDMFFVPXLowLatencyEnabled()) {
+      return nullptr;
+    }
+    RefPtr<MediaDataDecoder> decoder = new FFmpegVideoDecoder<V>(
+      mLib,
+      aParams.mTaskQueue,
+      aParams.VideoConfig(),
+      aParams.mImageContainer,
+      aParams.mOptions.contains(CreateDecoderParams::Option::LowLatency));
     return decoder.forget();
   }
 
   already_AddRefed<MediaDataDecoder>
   CreateAudioDecoder(const CreateDecoderParams& aParams) override
   {
     RefPtr<MediaDataDecoder> decoder =
       new FFmpegAudioDecoder<V>(mLib,
--- a/dom/media/platforms/ffmpeg/FFmpegLibs.h
+++ b/dom/media/platforms/ffmpeg/FFmpegLibs.h
@@ -22,16 +22,17 @@ extern "C" {
 #if LIBAVCODEC_VERSION_MAJOR < 55
 #define AV_CODEC_ID_VP6F CODEC_ID_VP6F
 #define AV_CODEC_ID_H264 CODEC_ID_H264
 #define AV_CODEC_ID_AAC CODEC_ID_AAC
 #define AV_CODEC_ID_MP3 CODEC_ID_MP3
 #define AV_CODEC_ID_VP8 CODEC_ID_VP8
 #define AV_CODEC_ID_NONE CODEC_ID_NONE
 #define AV_CODEC_ID_FLAC CODEC_ID_FLAC
+#define AV_CODEC_FLAG_LOW_DELAY CODEC_FLAG_LOW_DELAY
 typedef CodecID AVCodecID;
 #endif
 
 #ifdef FFVPX_VERSION
 enum { LIBAV_VER = FFVPX_VERSION };
 #else
 enum { LIBAV_VER = LIBAVCODEC_VERSION_MAJOR };
 #endif
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -96,22 +96,23 @@ FFmpegVideoDecoder<LIBAV_VER>::PtsCorrec
   mNumFaultyPts = 0;
   mNumFaultyDts = 0;
   mLastPts = INT64_MIN;
   mLastDts = INT64_MIN;
 }
 
 FFmpegVideoDecoder<LIBAV_VER>::FFmpegVideoDecoder(
   FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue, const VideoInfo& aConfig,
-  ImageContainer* aImageContainer)
+  ImageContainer* aImageContainer, bool aLowLatency)
   : FFmpegDataDecoder(aLib, aTaskQueue, GetCodecId(aConfig.mMimeType))
   , mImageContainer(aImageContainer)
   , mInfo(aConfig)
   , mCodecParser(nullptr)
   , mLastInputDts(INT64_MIN)
+  , mLowLatency(aLowLatency)
 {
   MOZ_COUNT_CTOR(FFmpegVideoDecoder);
   // Use a new MediaByteBuffer as the object will be modified during
   // initialization.
   mExtraData = new MediaByteBuffer;
   mExtraData->AppendElements(*aConfig.mExtraData);
 }
 
@@ -138,21 +139,28 @@ FFmpegVideoDecoder<LIBAV_VER>::InitCodec
   if (mInfo.mDisplay.width >= 2048) {
     decode_threads = 8;
   } else if (mInfo.mDisplay.width >= 1024) {
     decode_threads = 4;
   } else if (mInfo.mDisplay.width >= 320) {
     decode_threads = 2;
   }
 
-  decode_threads = std::min(decode_threads, PR_GetNumberOfProcessors() - 1);
-  decode_threads = std::max(decode_threads, 1);
-  mCodecContext->thread_count = decode_threads;
-  if (decode_threads > 1) {
-    mCodecContext->thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME;
+  if (mLowLatency) {
+    mCodecContext->flags |= CODEC_FLAG_LOW_DELAY;
+    // ffvp9 and ffvp8 at this stage do not support slice threading, but it may
+    // help with the h264 decoder if there's ever one.
+    mCodecContext->thread_type = FF_THREAD_SLICE;
+  } else {
+    decode_threads = std::min(decode_threads, PR_GetNumberOfProcessors() - 1);
+    decode_threads = std::max(decode_threads, 1);
+    mCodecContext->thread_count = decode_threads;
+    if (decode_threads > 1) {
+      mCodecContext->thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME;
+    }
   }
 
   // FFmpeg will call back to this to negotiate a video pixel format.
   mCodecContext->get_format = ChoosePixelFormat;
 
   mCodecParser = mLib->av_parser_init(mCodecID);
   if (mCodecParser) {
     mCodecParser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
@@ -23,17 +23,18 @@ template <>
 class FFmpegVideoDecoder<LIBAV_VER> : public FFmpegDataDecoder<LIBAV_VER>
 {
   typedef mozilla::layers::Image Image;
   typedef mozilla::layers::ImageContainer ImageContainer;
 
 public:
   FFmpegVideoDecoder(FFmpegLibWrapper* aLib, TaskQueue* aTaskQueue,
                      const VideoInfo& aConfig,
-                     ImageContainer* aImageContainer);
+                     ImageContainer* aImageContainer,
+                     bool aLowLatency);
   virtual ~FFmpegVideoDecoder();
 
   RefPtr<InitPromise> Init() override;
   void InitCodecContext() override;
   const char* GetDescriptionName() const override
   {
 #ifdef USING_MOZFFVPX
     return "ffvpx video decoder";
@@ -87,13 +88,14 @@ private:
     int64_t mLastPts;      /// PTS of the last frame
     int64_t mLastDts;      /// DTS of the last frame
   };
 
   PtsCorrectionContext mPtsContext;
   int64_t mLastInputDts;
 
   DurationMap mDurationMap;
+  const bool mLowLatency;
 };
 
 } // namespace mozilla
 
 #endif // __FFmpegVideoDecoder_h__
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -74,16 +74,22 @@ WMFDecoderModule::Startup()
 {
   mWMFInitialized = SUCCEEDED(wmf::MFStartup());
   return mWMFInitialized ? NS_OK : NS_ERROR_FAILURE;
 }
 
 already_AddRefed<MediaDataDecoder>
 WMFDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
 {
+  if (aParams.mOptions.contains(CreateDecoderParams::Option::LowLatency)) {
+    // Latency on Windows is bad. Let's not attempt to decode with WMF decoders
+    // when low latency is required.
+    return nullptr;
+  }
+
   nsAutoPtr<WMFVideoMFTManager> manager(
     new WMFVideoMFTManager(aParams.VideoConfig(),
                            aParams.mKnowsCompositor,
                            aParams.mImageContainer,
                            sDXVAEnabled));
 
   if (!manager->Init()) {
     return nullptr;
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -24,16 +24,17 @@ H264Converter::H264Converter(PlatformDec
   , mKnowsCompositor(aParams.mKnowsCompositor)
   , mImageContainer(aParams.mImageContainer)
   , mTaskQueue(aParams.mTaskQueue)
   , mDecoder(nullptr)
   , mGMPCrashHelper(aParams.mCrashHelper)
   , mLastError(NS_OK)
   , mType(aParams.mType)
   , mOnWaitingForKeyEvent(aParams.mOnWaitingForKeyEvent)
+  , mDecoderOptions(aParams.mOptions)
 {
   CreateDecoder(aParams.mDiagnostics);
 }
 
 H264Converter::~H264Converter()
 {
 }
 
@@ -205,17 +206,18 @@ H264Converter::CreateDecoder(DecoderDoct
   mDecoder = mPDM->CreateVideoDecoder({
     mUseOriginalConfig ? mOriginalConfig : mCurrentConfig,
     mTaskQueue,
     aDiagnostics,
     mImageContainer,
     mKnowsCompositor,
     mGMPCrashHelper,
     mType,
-    mOnWaitingForKeyEvent
+    mOnWaitingForKeyEvent,
+    mDecoderOptions
   });
 
   if (!mDecoder) {
     mLastError = NS_ERROR_FAILURE;
     return NS_ERROR_FAILURE;
   }
 
   mUseOriginalConfig = false;
--- a/dom/media/platforms/wrappers/H264Converter.h
+++ b/dom/media/platforms/wrappers/H264Converter.h
@@ -103,13 +103,14 @@ private:
   RefPtr<GMPCrashHelper> mGMPCrashHelper;
   Maybe<bool> mNeedAVCC;
   nsresult mLastError;
   bool mNeedKeyframe = true;
   // Set to true once a decoder has been created.
   bool mUseOriginalConfig = true;
   const TrackInfo::TrackType mType;
   MediaEventProducer<TrackInfo::TrackType>* const mOnWaitingForKeyEvent;
+  const CreateDecoderParams::OptionSet mDecoderOptions;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_H264Converter_h
deleted file mode 100644
--- a/dom/system/tests/marionette/manifest.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[DEFAULT]
-run-if = buildapp == 'b2g'
-
-[test_proximity_init.js]
-[test_proximity_change.js]
deleted file mode 100644
--- a/dom/system/tests/marionette/test_proximity_change.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-MARIONETTE_TIMEOUT = 10000;
-
-var receivedEvent = false;
-var expectedEvent;
-
-function enableProximityListener() {
-  // Setup device proximity event listener, expect defaults
-  log("Enabling 'deviceproximity' event listener.");
-
-  // Bug 814043: Device proximity event 'min' and 'max' attributes incorrect
-  // Until that is fixed, expect 1:0:1 instead of 1:0:0
-  // expectedEvent = new DeviceProximityEvent("deviceproximity",
-  //     {value:1, min:0, max:0});
-  expectedEvent = new DeviceProximityEvent("deviceproximity",
-      {value:1, min:0, max:1});
-
-  window.addEventListener('deviceproximity', listener);
-  log("Waiting for device proximity event.");
-  waitFor(changeProximity, function() {
-    return(receivedEvent);
-  });
-}
-
-function listener(event) {
-  // Received proximity update
-  log("Received 'deviceproximity' event via listener (value:"
-      + event.value + " min:" + event.min + " max:" + event.max + ").");
-  // Verify event values are as expected
-  is(event.value, expectedEvent.value, "value");
-  is(event.min, expectedEvent.min, "min");
-  is(event.max, expectedEvent.max, "max");
-  receivedEvent = true;
-}
-
-function changeProximity() {
-  // Change emulator's proximity and verify event attributes
-  let newValue = "7:3:15";
-
-  // Bug 814043: Device proximity event 'min' and 'max' attributes won't change
-  // Until fixed, expect proximity event min to be '0' and max to be '1' always
-  // expectedEvent = new DeviceProximityEvent("deviceproximity",
-  //     {value: 7, min: 3, max: 15});
-  expectedEvent = new DeviceProximityEvent("deviceproximity",
-       {value:7, min:0, max:1});
-
-  // Setup handler and verify 'ondeviceproximity' event
-  window.ondeviceproximity = function(event) {
-    log("Received 'ondeviceproximity' event via handler (value:"
-        + event.value + " min:" + event.min + " max:"
-        + event.max + ").");
-    is(event.value, expectedEvent.value, "value");
-    is(event.min, expectedEvent.min, "min");
-    is(event.max, expectedEvent.max, "max");
-    // Turn off event handler and listener
-    window.ondeviceproximity = null;
-    window.removeEventListener('deviceproximity', listener);
-    restoreProximity();
-  };
-
-  log("Sending emulator command to fake proximity change (" + newValue + ").");
-  runEmulatorCmd("sensor set proximity " + newValue, function(result) {
-    log("Emulator callback.");
-  });
-}
-
-function restoreProximity() {
-  // Set the emulator's proximity value back to original
-  newValue = "1:0:0";
-  log("Sending emulator command to restore proximity (" + newValue + ").");
-  runEmulatorCmd("sensor set proximity " + newValue, function(result) {
-    cleanUp();
-  });
-}
-
-function cleanUp() {
-  finish();
-}
-
-// Start the test
-enableProximityListener();
deleted file mode 100644
--- a/dom/system/tests/marionette/test_proximity_init.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-MARIONETTE_TIMEOUT = 10000;
-
-function testEventInit() {
-  let initValue = 7;
-  let initMin = 1;
-  let initMax = 30;
-
-  // Test DeviceProximityEvent initialization
-  log("Verifying DeviceProximityEvent constructor.");
-  let event = new DeviceProximityEvent("deviceproximity",
-      {value: initValue, min: initMin, max: initMax});
-  is(event.type, "deviceproximity", "event type");
-  is(event.value, initValue, "value");
-  is(event.min, initMin, "min");
-  is(event.max, initMax, "max");
-  if (event.value !== initValue ||
-      event.min !== initMin ||
-      event.max !== initMax) {
-    log("DeviceProximityEvent not initialized correctly.");
-  }
-
-  // Test UserProximityEvent initialization
-  log("Verifying UserProximityEvent constructor.");
-  event = new UserProximityEvent("userproximity", {near: true});
-  is(event.type, "userproximity", "event type");
-  ok(event.near, "Initialization of UserProximityEvent");
-  verifyDefaultStatus();
-}
-
-function verifyDefaultStatus() {
-  let emulatorDone = false;
-
-  // Ensure that device proximity is enabled by default
-  log("Getting sensor status from emulator.");
-
-  runEmulatorCmd("sensor status", function(result) {
-    log("Received sensor status (" + result[4] + ").");
-    is(result[4], "proximity: enabled.", "Proximity sensor enabled by default");
-    emulatorDone = true;
-  });
-
-  // Have this here so test doesn't drop out if emulator callback is slow
-  waitFor(getDefaultProximity, function() {
-    return(emulatorDone);
-  });
-}
-
-function getDefaultProximity() {
-  let expected = "1:0:0";
-
-  // Get and verify the default emulator proximity value
-  log("Getting device proximity from emulator.");
-
-  runEmulatorCmd("sensor get proximity", function(result) {
-    let values = result[0].split(" ")[2];
-    log("Received emulator proximity (" + values + ").");
-    is(values, "1:0:0", "Default proximity values");
-    cleanUp();
-  });
-}
-
-function cleanUp() {
-  finish();
-}
-
-// Start the test
-testEventInit();
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -2823,18 +2823,17 @@ XMLHttpRequestMainThread::Send(nsIVarian
 }
 
 void
 XMLHttpRequestMainThread::UnsuppressEventHandlingAndResume()
 {
   MOZ_ASSERT(mFlagSynchronous);
 
   if (mSuspendedDoc) {
-    mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents,
-                                                         true);
+    mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(true);
     mSuspendedDoc = nullptr;
   }
 
   if (mResumeTimeoutRunnable) {
     NS_DispatchToCurrentThread(mResumeTimeoutRunnable);
     mResumeTimeoutRunnable = nullptr;
   }
 }
@@ -2958,17 +2957,17 @@ XMLHttpRequestMainThread::SendInternal(c
   if (mFlagSynchronous) {
     mFlagSyncLooping = true;
 
     if (GetOwner()) {
       if (nsCOMPtr<nsPIDOMWindowOuter> topWindow = GetOwner()->GetOuterWindow()->GetTop()) {
         if (nsCOMPtr<nsPIDOMWindowInner> topInner = topWindow->GetCurrentInnerWindow()) {
           mSuspendedDoc = topWindow->GetExtantDoc();
           if (mSuspendedDoc) {
-            mSuspendedDoc->SuppressEventHandling(nsIDocument::eEvents);
+            mSuspendedDoc->SuppressEventHandling();
           }
           topInner->Suspend();
           mResumeTimeoutRunnable = new nsResumeTimeoutsEvent(topInner);
         }
       }
     }
 
     StopProgressEventTimer();
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -1490,17 +1490,17 @@ HTMLEditor::PasteTransferable(nsITransfe
 }
 
 /**
  * HTML PasteNoFormatting. Ignore any HTML styles and formating in paste source.
  */
 NS_IMETHODIMP
 HTMLEditor::PasteNoFormatting(int32_t aSelectionType)
 {
-  if (!FireClipboardEvent(ePaste, aSelectionType)) {
+  if (!FireClipboardEvent(ePasteNoFormatting, aSelectionType)) {
     return NS_OK;
   }
 
   ForceCompositionEnd();
 
   // Get Clipboard Service
   nsresult rv;
   nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
--- a/gfx/gl/SkiaGLGlue.cpp
+++ b/gfx/gl/SkiaGLGlue.cpp
@@ -17,17 +17,16 @@
 #endif
 
 #include "GLContext.h"
 #include "SkiaGLGlue.h"
 
 using mozilla::gl::GLContext;
 using mozilla::gl::GLFeature;
 using mozilla::gl::SkiaGLGlue;
-using mozilla::gfx::DrawTarget;
 
 template<typename R, typename... A>
 static inline GrGLFunction<R (*)(A...)>
 WrapGL(RefPtr<GLContext> aContext, R (GLContext::*aFunc)(A...))
 {
   return [aContext, aFunc] (A... args) -> R
   {
     aContext->MakeCurrent();
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -6,16 +6,17 @@
 
 #include "BackgroundUtils.h"
 
 #include "MainThreadUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/net/NeckoChannelParams.h"
+#include "nsExpandedPrincipal.h"
 #include "nsPrincipal.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "mozilla/LoadInfo.h"
 #include "nsNullPrincipal.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -938,16 +938,41 @@ class ScopedICUObject
         ptr_ = nullptr;
         return tmp;
     }
 };
 
 // The inline capacity we use for the char16_t Vectors.
 static const size_t INITIAL_CHAR_BUFFER_SIZE = 32;
 
+template <typename ICUStringFunction>
+static JSString*
+Call(JSContext* cx, const ICUStringFunction& strFn)
+{
+    Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
+    MOZ_ALWAYS_TRUE(chars.resize(INITIAL_CHAR_BUFFER_SIZE));
+
+    UErrorCode status = U_ZERO_ERROR;
+    int32_t size = strFn(Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE, &status);
+    if (status == U_BUFFER_OVERFLOW_ERROR) {
+        MOZ_ASSERT(size >= 0);
+        if (!chars.resize(size_t(size)))
+            return nullptr;
+        status = U_ZERO_ERROR;
+        strFn(Char16ToUChar(chars.begin()), size, &status);
+    }
+    if (U_FAILURE(status)) {
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
+        return nullptr;
+    }
+
+    MOZ_ASSERT(size >= 0);
+    return NewStringCopyN<CanGC>(cx, chars.begin(), size_t(size));
+}
+
 
 /******************** Collator ********************/
 
 const ClassOps CollatorObject::classOps_ = {
     nullptr, /* addProperty */
     nullptr, /* delProperty */
     nullptr, /* getProperty */
     nullptr, /* setProperty */
@@ -1802,85 +1827,45 @@ NewUNumberFormat(JSContext* cx, Handle<N
         unum_setAttribute(nf, UNUM_MAX_FRACTION_DIGITS, uMaximumFractionDigits);
     }
     unum_setAttribute(nf, UNUM_GROUPING_USED, uUseGrouping);
     unum_setAttribute(nf, UNUM_ROUNDING_MODE, UNUM_ROUND_HALFUP);
 
     return toClose.forget();
 }
 
-using FormattedNumberChars = Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE>;
-
-static bool
+static JSString*
 PartitionNumberPattern(JSContext* cx, UNumberFormat* nf, double* x,
-                       UFieldPositionIterator* fpositer, FormattedNumberChars& formattedChars)
+                       UFieldPositionIterator* fpositer)
 {
     // PartitionNumberPattern doesn't consider -0.0 to be negative.
     if (IsNegativeZero(*x))
         *x = 0.0;
 
-    MOZ_ASSERT(formattedChars.length() == 0,
-               "formattedChars must initially be empty");
-    MOZ_ALWAYS_TRUE(formattedChars.resize(INITIAL_CHAR_BUFFER_SIZE));
-
-    UErrorCode status = U_ZERO_ERROR;
-
 #if !defined(ICU_UNUM_HAS_FORMATDOUBLEFORFIELDS)
     MOZ_ASSERT(fpositer == nullptr,
                "shouldn't be requesting field information from an ICU that "
                "can't provide it");
 #endif
 
-    int32_t resultSize;
+    return Call(cx, [nf, x, fpositer](UChar* chars, int32_t size, UErrorCode* status) {
 #if defined(ICU_UNUM_HAS_FORMATDOUBLEFORFIELDS)
-    resultSize =
-        unum_formatDoubleForFields(nf, *x,
-                                   Char16ToUChar(formattedChars.begin()), INITIAL_CHAR_BUFFER_SIZE,
-                                   fpositer, &status);
+        return unum_formatDoubleForFields(nf, *x, chars, size, fpositer, status);
 #else
-    resultSize =
-        unum_formatDouble(nf, *x, Char16ToUChar(formattedChars.begin()), INITIAL_CHAR_BUFFER_SIZE,
-                          nullptr, &status);
-#endif // defined(ICU_UNUM_HAS_FORMATDOUBLEFORFIELDS)
-    if (status == U_BUFFER_OVERFLOW_ERROR) {
-        MOZ_ASSERT(resultSize >= 0);
-        if (!formattedChars.resize(size_t(resultSize)))
-            return false;
-        status = U_ZERO_ERROR;
-#ifdef DEBUG
-        int32_t size =
+        return unum_formatDouble(nf, *x, chars, size, nullptr, status);
 #endif
-#if defined(ICU_UNUM_HAS_FORMATDOUBLEFORFIELDS)
-            unum_formatDoubleForFields(nf, *x, Char16ToUChar(formattedChars.begin()), resultSize,
-                                       fpositer, &status);
-#else
-            unum_formatDouble(nf, *x, Char16ToUChar(formattedChars.begin()), resultSize,
-                              nullptr, &status);
-#endif // defined(ICU_UNUM_HAS_FORMATDOUBLEFORFIELDS)
-        MOZ_ASSERT(size == resultSize);
-    }
-    if (U_FAILURE(status)) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
-        return false;
-    }
-
-    MOZ_ASSERT(resultSize >= 0);
-    return formattedChars.resize(size_t(resultSize));
+    });
 }
 
 static bool
 intl_FormatNumber(JSContext* cx, UNumberFormat* nf, double x, MutableHandleValue result)
 {
     // Passing null for |fpositer| will just not compute partition information,
     // letting us common up all ICU number-formatting code.
-    FormattedNumberChars chars(cx);
-    if (!PartitionNumberPattern(cx, nf, &x, nullptr, chars))
-        return false;
-
-    JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), chars.length());
+    JSString* str = PartitionNumberPattern(cx, nf, &x, nullptr);
     if (!str)
         return false;
 
     result.setString(str);
     return true;
 }
 
 using FieldType = ImmutablePropertyNamePtr JSAtomState::*;
@@ -1962,28 +1947,24 @@ intl_FormatNumberToParts(JSContext* cx, 
     if (U_FAILURE(status)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
 
     MOZ_ASSERT(fpositer);
     ScopedICUObject<UFieldPositionIterator, ufieldpositer_close> toClose(fpositer);
 
-    FormattedNumberChars chars(cx);
-    if (!PartitionNumberPattern(cx, nf, &x, fpositer, chars))
+    RootedString overallResult(cx, PartitionNumberPattern(cx, nf, &x, fpositer));
+    if (!overallResult)
         return false;
 
     RootedArrayObject partsArray(cx, NewDenseEmptyArray(cx));
     if (!partsArray)
         return false;
 
-    RootedString overallResult(cx, NewStringCopyN<CanGC>(cx, chars.begin(), chars.length()));
-    if (!overallResult)
-        return false;
-
     // First, vacuum up fields in the overall formatted string.
 
     struct Field
     {
         uint32_t begin;
         uint32_t end;
         FieldType type;
 
@@ -2229,17 +2210,17 @@ intl_FormatNumberToParts(JSContext* cx, 
     };
 
     // Finally, generate the result array.
     size_t lastEndIndex = 0;
     uint32_t partIndex = 0;
     RootedObject singlePart(cx);
     RootedValue propVal(cx);
 
-    PartGenerator gen(cx, fields, chars.length());
+    PartGenerator gen(cx, fields, overallResult->length());
     do {
         bool hasPart;
         Part part;
         if (!gen.nextPart(&hasPart, &part))
             return false;
 
         if (!hasPart)
             break;
@@ -2269,17 +2250,17 @@ intl_FormatNumberToParts(JSContext* cx, 
         propVal.setObject(*singlePart);
         if (!DefineElement(cx, partsArray, partIndex, propVal))
             return false;
 
         lastEndIndex = endIndex;
         partIndex++;
     } while (true);
 
-    MOZ_ASSERT(lastEndIndex == chars.length(),
+    MOZ_ASSERT(lastEndIndex == overallResult->length(),
                "result array must partition the entire string");
 
     result.setObject(*partsArray);
     return true;
 }
 
 #endif // defined(ICU_UNUM_HAS_FORMATDOUBLEFORFIELDS)
 
@@ -2895,80 +2876,42 @@ js::intl_canonicalizeTimeZone(JSContext*
     }
 
     AutoStableStringChars stableChars(cx);
     if (!stableChars.initTwoByte(cx, timeZone))
         return false;
 
     mozilla::Range<const char16_t> tzchars = stableChars.twoByteRange();
 
-    Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
-    if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
-        return false;
-
-    UBool* isSystemID = nullptr;
-    UErrorCode status = U_ZERO_ERROR;
-    int32_t size = ucal_getCanonicalTimeZoneID(Char16ToUChar(tzchars.begin().get()),
-                                               tzchars.length(), Char16ToUChar(chars.begin()),
-                                               INITIAL_CHAR_BUFFER_SIZE, isSystemID, &status);
-    if (status == U_BUFFER_OVERFLOW_ERROR) {
-        MOZ_ASSERT(size >= 0);
-        if (!chars.resize(size_t(size)))
-            return false;
-        status = U_ZERO_ERROR;
-        ucal_getCanonicalTimeZoneID(Char16ToUChar(tzchars.begin().get()), tzchars.length(),
-                                    Char16ToUChar(chars.begin()), size, isSystemID, &status);
-    }
-    if (U_FAILURE(status)) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
-        return false;
-    }
-
-    MOZ_ASSERT(size >= 0);
-    JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size_t(size));
+    JSString* str = Call(cx, [&tzchars](UChar* chars, uint32_t size, UErrorCode* status) {
+        return ucal_getCanonicalTimeZoneID(Char16ToUChar(tzchars.begin().get()), tzchars.length(),
+                                           chars, size, nullptr, status);
+    });
     if (!str)
         return false;
+
     args.rval().setString(str);
     return true;
 }
 
 bool
 js::intl_defaultTimeZone(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 0);
 
     // The current default might be stale, because JS::ResetTimeZone() doesn't
     // immediately update ICU's default time zone. So perform an update if
     // needed.
     js::ResyncICUDefaultTimeZone();
 
-    Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
-    if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
-        return false;
-
-    UErrorCode status = U_ZERO_ERROR;
-    int32_t size = ucal_getDefaultTimeZone(Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
-                                           &status);
-    if (status == U_BUFFER_OVERFLOW_ERROR) {
-        MOZ_ASSERT(size >= 0);
-        if (!chars.resize(size_t(size)))
-            return false;
-        status = U_ZERO_ERROR;
-        ucal_getDefaultTimeZone(Char16ToUChar(chars.begin()), size, &status);
-    }
-    if (U_FAILURE(status)) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
-        return false;
-    }
-
-    MOZ_ASSERT(size >= 0);
-    JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size_t(size));
+    JSString* str = Call(cx, ucal_getDefaultTimeZone);
     if (!str)
         return false;
+
     args.rval().setString(str);
     return true;
 }
 
 bool
 js::intl_defaultTimeZoneOffset(JSContext* cx, unsigned argc, Value* vp) {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 0);
@@ -3005,50 +2948,33 @@ js::intl_patternForSkeleton(JSContext* c
     JSAutoByteString locale(cx, args[0].toString());
     if (!locale)
         return false;
 
     AutoStableStringChars skeleton(cx);
     if (!skeleton.initTwoByte(cx, args[1].toString()))
         return false;
 
-    mozilla::Range<const char16_t> skeletonChars = skeleton.twoByteRange();
+    mozilla::Range<const char16_t> skelChars = skeleton.twoByteRange();
 
     UErrorCode status = U_ZERO_ERROR;
     UDateTimePatternGenerator* gen = udatpg_open(icuLocale(locale.ptr()), &status);
     if (U_FAILURE(status)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
     ScopedICUObject<UDateTimePatternGenerator, udatpg_close> toClose(gen);
 
-    Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
-    if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
-        return false;
-
-    int32_t size = udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.begin().get()),
-                                         skeletonChars.length(), Char16ToUChar(chars.begin()),
-                                         INITIAL_CHAR_BUFFER_SIZE, &status);
-    if (status == U_BUFFER_OVERFLOW_ERROR) {
-        MOZ_ASSERT(size >= 0);
-        if (!chars.resize(size))
-            return false;
-        status = U_ZERO_ERROR;
-        udatpg_getBestPattern(gen, Char16ToUChar(skeletonChars.begin().get()),
-                              skeletonChars.length(), Char16ToUChar(chars.begin()), size, &status);
-    }
-    if (U_FAILURE(status)) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
-        return false;
-    }
-
-    MOZ_ASSERT(size >= 0);
-    JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size);
+    JSString* str = Call(cx, [gen, &skelChars](UChar* chars, uint32_t size, UErrorCode* status) {
+        return udatpg_getBestPattern(gen, Char16ToUChar(skelChars.begin().get()),
+                                     skelChars.length(), chars, size, status);
+    });
     if (!str)
         return false;
+
     args.rval().setString(str);
     return true;
 }
 
 /**
  * Returns a new UDateFormat with the locale and date-time formatting options
  * of the given DateTimeFormat.
  */
@@ -3112,41 +3038,23 @@ NewUDateFormat(JSContext* cx, Handle<Dat
 static bool
 intl_FormatDateTime(JSContext* cx, UDateFormat* df, double x, MutableHandleValue result)
 {
     if (!IsFinite(x)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DATE_NOT_FINITE);
         return false;
     }
 
-    Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
-    if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
-        return false;
-    UErrorCode status = U_ZERO_ERROR;
-    int32_t size = udat_format(df, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
-                               nullptr, &status);
-    if (status == U_BUFFER_OVERFLOW_ERROR) {
-        MOZ_ASSERT(size >= 0);
-        if (!chars.resize(size))
-            return false;
-        status = U_ZERO_ERROR;
-        udat_format(df, x, Char16ToUChar(chars.begin()), size, nullptr, &status);
-    }
-    if (U_FAILURE(status)) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
-        return false;
-    }
-
-    MOZ_ASSERT(size >= 0);
-    JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size);
+    JSString* str = Call(cx, [df, x](UChar* chars, int32_t size, UErrorCode* status) {
+        return udat_format(df, x, chars, size, nullptr, status);
+    });
     if (!str)
         return false;
 
     result.setString(str);
-
     return true;
 }
 
 static FieldType
 GetFieldTypeForFormatField(UDateFormatField fieldName)
 {
     // See intl/icu/source/i18n/unicode/udat.h for a detailed field list.  This
     // switch is deliberately exhaustive: cases might have to be added/removed
@@ -3234,58 +3142,41 @@ GetFieldTypeForFormatField(UDateFormatFi
 static bool
 intl_FormatToPartsDateTime(JSContext* cx, UDateFormat* df, double x, MutableHandleValue result)
 {
     if (!IsFinite(x)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DATE_NOT_FINITE);
         return false;
     }
 
-    Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
-    if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
-        return false;
-
     UErrorCode status = U_ZERO_ERROR;
     UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
     if (U_FAILURE(status)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
     ScopedICUObject<UFieldPositionIterator, ufieldpositer_close> toClose(fpositer);
 
-    int32_t resultSize =
-        udat_formatForFields(df, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
-                             fpositer, &status);
-    if (status == U_BUFFER_OVERFLOW_ERROR) {
-        MOZ_ASSERT(resultSize >= 0);
-        if (!chars.resize(resultSize))
-            return false;
-        status = U_ZERO_ERROR;
-        udat_formatForFields(df, x, Char16ToUChar(chars.begin()), resultSize, fpositer, &status);
-    }
-    if (U_FAILURE(status)) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
+    RootedString overallResult(cx);
+    overallResult = Call(cx, [df, x, fpositer](UChar* chars, int32_t size, UErrorCode* status) {
+        return udat_formatForFields(df, x, chars, size, fpositer, status);
+    });
+    if (!overallResult)
         return false;
-    }
 
     RootedArrayObject partsArray(cx, NewDenseEmptyArray(cx));
     if (!partsArray)
         return false;
 
-    MOZ_ASSERT(resultSize >= 0);
-    if (resultSize == 0) {
+    if (overallResult->length() == 0) {
         // An empty string contains no parts, so avoid extra work below.
         result.setObject(*partsArray);
         return true;
     }
 
-    RootedString overallResult(cx, NewStringCopyN<CanGC>(cx, chars.begin(), resultSize));
-    if (!overallResult)
-        return false;
-
     size_t lastEndIndex = 0;
 
     uint32_t partIndex = 0;
     RootedObject singlePart(cx);
     RootedValue partType(cx);
     RootedValue val(cx);
 
     auto AppendPart = [&](FieldType type, size_t beginIndex, size_t endIndex) {
@@ -3632,36 +3523,19 @@ js::intl_SelectPluralRule(JSContext* cx,
     UPluralRules* pr = uplrules_openForType(icuLocale(locale.ptr()), category, &status);
     if (U_FAILURE(status)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
 
     ScopedICUObject<UPluralRules, uplrules_close> closePluralRules(pr);
 
-    Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
-    if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
-        return false;
-
-    int32_t size = uplrules_select(pr, y, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
-                                   &status);
-    if (status == U_BUFFER_OVERFLOW_ERROR) {
-        MOZ_ASSERT(size >= 0);
-        if (!chars.resize(size))
-            return false;
-        status = U_ZERO_ERROR;
-        uplrules_select(pr, y, Char16ToUChar(chars.begin()), size, &status);
-    }
-    if (U_FAILURE(status)) {
-        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
-        return false;
-    }
-
-    MOZ_ASSERT(size >= 0);
-    JSString* str = NewStringCopyN<CanGC>(cx, chars.begin(), size);
+    JSString* str = Call(cx, [pr, y](UChar* chars, int32_t size, UErrorCode* status) {
+        return uplrules_select(pr, y, chars, size, status);
+    });
     if (!str)
         return false;
 
     args.rval().setString(str);
     return true;
 }
 
 bool
@@ -4052,35 +3926,19 @@ ComputeSingleDisplayName(JSContext* cx, 
         }
 
         // This part must be the final part with no trailing data.
         if (iter != end) {
             ReportBadKey(cx, pattern);
             return nullptr;
         }
 
-        UErrorCode status = U_ZERO_ERROR;
-        int32_t resultSize =
-            udat_getSymbols(fmt, symbolType, index, Char16ToUChar(chars.begin()),
-                            INITIAL_CHAR_BUFFER_SIZE, &status);
-        if (status == U_BUFFER_OVERFLOW_ERROR) {
-            MOZ_ASSERT(resultSize >= 0);
-            if (!chars.resize(resultSize))
-                return nullptr;
-            status = U_ZERO_ERROR;
-            udat_getSymbols(fmt, symbolType, index, Char16ToUChar(chars.begin()),
-                            resultSize, &status);
-        }
-        if (U_FAILURE(status)) {
-            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
-            return nullptr;
-        }
-
-        MOZ_ASSERT(resultSize >= 0);
-        return NewStringCopyN<CanGC>(cx, chars.begin(), resultSize);
+        return Call(cx, [fmt, symbolType, index](UChar* chars, int32_t size, UErrorCode* status) {
+            return udat_getSymbols(fmt, symbolType, index, chars, size, status);
+        });
     }
 
     ReportBadKey(cx, pattern);
     return nullptr;
 }
 
 bool
 js::intl_ComputeDisplayNames(JSContext* cx, unsigned argc, Value* vp)
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -174,18 +174,23 @@ NextNode(VerifyNode* node)
 }
 
 void
 gc::GCRuntime::startVerifyPreBarriers()
 {
     if (verifyPreData || isIncrementalGCInProgress())
         return;
 
-    if (IsIncrementalGCUnsafe(rt) != AbortReason::None || TlsContext.get()->keepAtoms || rt->hasHelperThreadZones())
+    if (IsIncrementalGCUnsafe(rt) != AbortReason::None ||
+        TlsContext.get()->keepAtoms ||
+        rt->hasHelperThreadZones() ||
+        rt->cooperatingContexts().length() != 1)
+    {
         return;
+    }
 
     number++;
 
     VerifyPreTracer* trc = js_new<VerifyPreTracer>(rt);
     if (!trc)
         return;
 
     AutoPrepareForTracing prep(TlsContext.get(), WithAtoms);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug1341326.js
@@ -0,0 +1,15 @@
+if (helperThreadCount() == 0)
+    quit();
+function eval(source) {
+    offThreadCompileModule(source);
+}
+var N = 10000;
+var left = repeat_str('(1&', N);
+var right = repeat_str(')', N);
+var str = 'actual = '.concat(left, '1', right, ';');
+eval(str);
+function repeat_str(str, repeat_count) {
+    var arr = new Array(--repeat_count);
+    while (repeat_count != 0) arr[--repeat_count] = str;
+    return str.concat.apply(str, arr);
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug1341358.js
@@ -0,0 +1,8 @@
+if (helperThreadCount() == 0)
+    quit();
+evalInCooperativeThread("var x = 3");
+let PromiseCtor = Promise;
+let promises = [];
+let p = new PromiseCtor(function(res_, rej_) {});
+promises.push(p);
+let allPromise = getWaitForAllPromise(promises);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1541,17 +1541,18 @@ JS_SetNativeStackQuota(JSContext* cx, si
         untrustedScriptStackSize = trustedScriptStackSize;
     else
         MOZ_ASSERT(untrustedScriptStackSize < trustedScriptStackSize);
 
     SetNativeStackQuotaAndLimit(cx, JS::StackForSystemCode, systemCodeStackSize);
     SetNativeStackQuotaAndLimit(cx, JS::StackForTrustedScript, trustedScriptStackSize);
     SetNativeStackQuotaAndLimit(cx, JS::StackForUntrustedScript, untrustedScriptStackSize);
 
-    cx->initJitStackLimit();
+    if (cx->isCooperativelyScheduled())
+        cx->initJitStackLimit();
 }
 
 /************************************************************************/
 
 JS_PUBLIC_API(bool)
 JS_ValueToId(JSContext* cx, HandleValue value, MutableHandleId idp)
 {
     AssertHeapIsIdle();
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -3465,40 +3465,42 @@ static void SetWorkerContextOptions(JSCo
 
 static void
 WorkerMain(void* arg)
 {
     WorkerInput* input = (WorkerInput*) arg;
     MOZ_ASSERT(!!input->parentRuntime != !!input->siblingContext);
 
     JSContext* cx = nullptr;
+    ShellContext* sc = nullptr;
 
     auto guard = mozilla::MakeScopeExit([&] {
             if (cx)
                 JS_DestroyContext(cx);
             if (input->siblingContext) {
                 cooperationState->numThreads--;
                 CooperativeYield();
             }
             js_delete(input);
+            js_delete(sc);
         });
 
     cx = input->parentRuntime
          ? JS_NewContext(8L * 1024L * 1024L, 2L * 1024L * 1024L, input->parentRuntime)
          : JS_NewCooperativeContext(input->siblingContext);
     if (!cx)
         return;
 
-    UniquePtr<ShellContext> sc = MakeUnique<ShellContext>(cx);
+    sc = js_new<ShellContext>(cx);
     if (!sc)
         return;
 
     if (input->parentRuntime)
         sc->isWorker = true;
-    JS_SetContextPrivate(cx, sc.get());
+    JS_SetContextPrivate(cx, sc);
     SetWorkerContextOptions(cx);
     sc->jobQueue.init(cx, JobQueue(SystemAllocPolicy()));
 
     Maybe<EnvironmentPreparer> environmentPreparer;
     if (input->parentRuntime) {
         JS_SetFutexCanWait(cx);
         JS::SetWarningReporter(cx, WarningReporter);
         js::SetPreserveWrapperCallback(cx, DummyPreserveWrapperCallback);
@@ -3539,20 +3541,23 @@ WorkerMain(void* arg)
         AutoReportException are(cx);
         RootedScript script(cx);
         if (!JS::Compile(cx, options, input->chars, input->length, &script))
             break;
         RootedValue result(cx);
         JS_ExecuteScript(cx, script, &result);
     } while (0);
 
-    JS::SetLargeAllocationFailureCallback(cx, nullptr, nullptr);
-
-    JS::SetGetIncumbentGlobalCallback(cx, nullptr);
-    JS::SetEnqueuePromiseJobCallback(cx, nullptr);
+    if (input->parentRuntime) {
+        JS::SetLargeAllocationFailureCallback(cx, nullptr, nullptr);
+
+        JS::SetGetIncumbentGlobalCallback(cx, nullptr);
+        JS::SetEnqueuePromiseJobCallback(cx, nullptr);
+    }
+
     sc->jobQueue.reset();
 
     KillWatchdog(cx);
 }
 
 // Workers can spawn other workers, so we need a lock to access workerThreads.
 static Mutex* workerThreadsLock = nullptr;
 static Vector<js::Thread*, 0, SystemAllocPolicy> workerThreads;
@@ -3593,16 +3598,21 @@ EvalInThread(JSContext* cx, unsigned arg
         // Disallowing cooperative multithreading in worker runtimes allows
         // yield state to be process wide, and some other simplifications.
         // When we have a better idea of how cooperative multithreading will be
         // used in the browser this restriction might be relaxed.
         JS_ReportErrorASCII(cx, "Cooperative multithreading in worker runtimes is not supported");
         return false;
     }
 
+    if (cooperative && !cx->runtime()->gc.canChangeActiveContext(cx)) {
+        JS_ReportErrorASCII(cx, "Cooperating multithreading context switches are not currently allowed");
+        return false;
+    }
+
     if (!args[0].toString()->ensureLinear(cx))
         return false;
 
     if (!workerThreadsLock) {
         workerThreadsLock = js_new<Mutex>(mutexid::ShellWorkerThreads);
         if (!workerThreadsLock) {
             ReportOutOfMemory(cx);
             return false;
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -158,21 +158,16 @@ skip script test262/built-ins/global/glo
 skip script test262/built-ins/TypedArray/prototype/every/callbackfn-detachbuffer.js
 skip script test262/built-ins/TypedArray/prototype/filter/callbackfn-detachbuffer.js
 skip script test262/built-ins/TypedArray/prototype/find/predicate-may-detach-buffer.js
 skip script test262/built-ins/TypedArray/prototype/findIndex/predicate-may-detach-buffer.js
 skip script test262/built-ins/TypedArray/prototype/forEach/callbackfn-detachbuffer.js
 skip script test262/built-ins/TypedArray/prototype/map/callbackfn-detachbuffer.js
 skip script test262/built-ins/TypedArray/prototype/reduceRight/callbackfn-detachbuffer.js
 skip script test262/built-ins/TypedArray/prototype/reduce/callbackfn-detachbuffer.js
-skip script test262/built-ins/TypedArray/prototype/set/array-arg-targetbuffer-detached-on-get-src-value-throws.js
-skip script test262/built-ins/TypedArray/prototype/set/array-arg-targetbuffer-detached-on-tointeger-offset-throws.js
-skip script test262/built-ins/TypedArray/prototype/set/array-arg-targetbuffer-detached-throws.js
-skip script test262/built-ins/TypedArray/prototype/set/typedarray-arg-srcbuffer-detached-during-tointeger-offset-throws.js
-skip script test262/built-ins/TypedArray/prototype/set/typedarray-arg-targetbuffer-detached-during-tointeger-offset-throws.js
 skip script test262/built-ins/TypedArray/prototype/slice/detached-buffer-custom-ctor-same-targettype.js
 skip script test262/built-ins/TypedArray/prototype/slice/detached-buffer-custom-ctor-other-targettype.js
 skip script test262/built-ins/TypedArray/prototype/slice/detached-buffer-get-ctor.js
 skip script test262/built-ins/TypedArray/prototype/some/callbackfn-detachbuffer.js
 skip script test262/built-ins/TypedArrays/internals/DefineOwnProperty/detached-buffer-realm.js
 skip script test262/built-ins/TypedArrays/internals/DefineOwnProperty/detached-buffer.js
 skip script test262/built-ins/TypedArrays/internals/Get/detached-buffer-realm.js
 skip script test262/built-ins/TypedArrays/internals/Get/detached-buffer.js
@@ -198,21 +193,16 @@ skip script test262/built-ins/TypedArray
 skip script test262/built-ins/TypedArrays/internals/Set/key-is-not-canonical-index.js
 skip script test262/built-ins/TypedArrays/internals/Set/key-is-not-integer.js
 skip script test262/built-ins/TypedArrays/internals/Set/key-is-out-of-bounds.js
 skip script test262/built-ins/TypedArrays/internals/Set/tonumber-value-throws.js
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1140152
 skip script test262/built-ins/TypedArray/prototype/slice/bit-precision.js
 
-# https://bugzilla.mozilla.org/show_bug.cgi?id=1317384
-skip script test262/built-ins/TypedArray/prototype/set/array-arg-negative-integer-offset-throws.js
-skip script test262/built-ins/TypedArray/prototype/set/typedarray-arg-negative-integer-offset-throws.js
-skip script test262/built-ins/TypedArray/prototype/set/typedarray-arg-src-range-greather-than-target-throws-rangeerror.js
-
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1317383
 skip script test262/built-ins/TypedArrays/buffer-arg-byteoffset-is-negative-throws.js
 skip script test262/built-ins/TypedArrays/buffer-arg-defined-negative-length.js
 skip script test262/built-ins/TypedArrays/length-arg-is-infinity-throws-rangeerror.js
 skip script test262/built-ins/TypedArrays/length-arg-is-negative-integer-throws-rangeerror.js
 skip script test262/built-ins/TypedArrays/length-arg-toindex-length.js
 skip script test262/built-ins/TypedArrays/object-arg-length-excessive-throws.js
 
--- a/js/src/threading/posix/Thread.cpp
+++ b/js/src/threading/posix/Thread.cpp
@@ -73,24 +73,26 @@ js::Thread::Id::operator==(const Id& aOt
          (self.hasThread == other.hasThread &&
           pthread_equal(self.ptThread, other.ptThread));
 }
 
 js::Thread::Thread(Thread&& aOther)
 {
   id_ = aOther.id_;
   aOther.id_ = Id();
+  options_ = aOther.options_;
 }
 
 js::Thread&
 js::Thread::operator=(Thread&& aOther)
 {
   MOZ_RELEASE_ASSERT(!joinable());
   id_ = aOther.id_;
   aOther.id_ = Id();
+  options_ = aOther.options_;
   return *this;
 }
 
 bool
 js::Thread::create(void* (*aMain)(void*), void* aArg)
 {
   pthread_attr_t attrs;
   int r = pthread_attr_init(&attrs);
--- a/js/src/threading/windows/Thread.cpp
+++ b/js/src/threading/windows/Thread.cpp
@@ -54,24 +54,26 @@ js::Thread::Id::operator==(const Id& aOt
 {
   return platformData()->id == aOther.platformData()->id;
 }
 
 js::Thread::Thread(Thread&& aOther)
 {
   id_ = aOther.id_;
   aOther.id_ = Id();
+  options_ = aOther.options_;
 }
 
 js::Thread&
 js::Thread::operator=(Thread&& aOther)
 {
   MOZ_RELEASE_ASSERT(!joinable());
   id_ = aOther.id_;
   aOther.id_ = Id();
+  options_ = aOther.options_;
   return *this;
 }
 
 bool
 js::Thread::create(unsigned int (__stdcall* aMain)(void*), void* aArg)
 {
   // Use _beginthreadex and not CreateThread, because threads that are
   // created with the latter leak a small amount of memory when they use
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -1658,17 +1658,17 @@ void
 JSContext::addPendingOutOfMemory()
 {
     // Keep in sync with recoverFromOutOfMemory.
     if (helperThread()->parseTask())
         helperThread()->parseTask()->outOfMemory = true;
 }
 
 void
-HelperThread::handleParseWorkload(AutoLockHelperThreadState& locked, uintptr_t stackLimit)
+HelperThread::handleParseWorkload(AutoLockHelperThreadState& locked)
 {
     MOZ_ASSERT(HelperThreadState().canStartParseTask(locked));
     MOZ_ASSERT(idle());
 
     currentTask.emplace(HelperThreadState().parseWorklist(locked).popCopy());
     ParseTask* task = parseTask();
 
     {
@@ -1898,24 +1898,17 @@ HelperThread::threadLoop()
 
     JSContext cx(nullptr, JS::ContextOptions());
     {
         AutoEnterOOMUnsafeRegion oomUnsafe;
         if (!cx.init(ContextKind::Background))
             oomUnsafe.crash("HelperThread cx.init()");
     }
     cx.setHelperThread(this);
-
-    // Compute the thread's stack limit, for over-recursed checks.
-    uintptr_t stackLimit = GetNativeStackBase();
-#if JS_STACK_GROWTH_DIRECTION > 0
-    stackLimit += HELPER_STACK_QUOTA;
-#else
-    stackLimit -= HELPER_STACK_QUOTA;
-#endif
+    JS_SetNativeStackQuota(&cx, HELPER_STACK_QUOTA);
 
     while (true) {
         MOZ_ASSERT(idle());
 
         // Block until a task is available. Save the value of whether we are
         // going to do an Ion compile, in case the value returned by the method
         // changes.
         bool ionCompile = false;
@@ -1941,17 +1934,17 @@ HelperThread::threadLoop()
         } else if (HelperThreadState().canStartWasmCompile(lock)) {
             js::oom::SetThreadType(js::oom::THREAD_TYPE_WASM);
             handleWasmWorkload(lock);
         } else if (HelperThreadState().canStartPromiseTask(lock)) {
             js::oom::SetThreadType(js::oom::THREAD_TYPE_PROMISE_TASK);
             handlePromiseTaskWorkload(lock);
         } else if (HelperThreadState().canStartParseTask(lock)) {
             js::oom::SetThreadType(js::oom::THREAD_TYPE_PARSE);
-            handleParseWorkload(lock, stackLimit);
+            handleParseWorkload(lock);
         } else if (HelperThreadState().canStartCompressionTask(lock)) {
             js::oom::SetThreadType(js::oom::THREAD_TYPE_COMPRESS);
             handleCompressionWorkload(lock);
         } else if (HelperThreadState().canStartGCHelperTask(lock)) {
             js::oom::SetThreadType(js::oom::THREAD_TYPE_GCHELPER);
             handleGCHelperWorkload(lock);
         } else if (HelperThreadState().canStartGCParallelTask(lock)) {
             js::oom::SetThreadType(js::oom::THREAD_TYPE_GCPARALLEL);
--- a/js/src/vm/HelperThreads.h
+++ b/js/src/vm/HelperThreads.h
@@ -379,17 +379,17 @@ struct HelperThread
             return currentTask->as<T>();
 
         return nullptr;
     }
 
     void handleWasmWorkload(AutoLockHelperThreadState& locked);
     void handlePromiseTaskWorkload(AutoLockHelperThreadState& locked);
     void handleIonWorkload(AutoLockHelperThreadState& locked);
-    void handleParseWorkload(AutoLockHelperThreadState& locked, uintptr_t stackLimit);
+    void handleParseWorkload(AutoLockHelperThreadState& locked);
     void handleCompressionWorkload(AutoLockHelperThreadState& locked);
     void handleGCHelperWorkload(AutoLockHelperThreadState& locked);
     void handleGCParallelWorkload(AutoLockHelperThreadState& locked);
 };
 
 /* Methods for interacting with helper threads. */
 
 // Create data structures used by helper threads.
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -627,17 +627,17 @@ FreeOp::isDefaultFreeOp() const
 {
     return runtime_ && runtime_->defaultFreeOp() == this;
 }
 
 JSObject*
 JSRuntime::getIncumbentGlobal(JSContext* cx)
 {
     MOZ_ASSERT(cx->runtime()->getIncumbentGlobalCallback,
-               "Must set a callback using JS_SetGetIncumbentGlobalCallback before using Promises");
+               "Must set a callback using SetGetIncumbentGlobalCallback before using Promises");
 
     return cx->runtime()->getIncumbentGlobalCallback(cx);
 }
 
 bool
 JSRuntime::enqueuePromiseJob(JSContext* cx, HandleFunction job, HandleObject promise,
                              HandleObject incumbentGlobal)
 {
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -15,17 +15,17 @@
 #include "nsContentUtils.h"
 #include "nsGlobalWindow.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIURI.h"
 #include "nsJSUtils.h"
 #include "nsNetUtil.h"
 #include "nsNullPrincipal.h"
-#include "nsPrincipal.h"
+#include "nsExpandedPrincipal.h"
 #include "WrapperFactory.h"
 #include "xpcprivate.h"
 #include "xpc_make_class.h"
 #include "XPCWrapper.h"
 #include "XrayWrapper.h"
 #include "Crypto.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/BlobBinding.h"
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* Class used to manage the wrapped native objects within a JS scope. */
 
 #include "xpcprivate.h"
 #include "XPCWrapper.h"
 #include "nsContentUtils.h"
 #include "nsCycleCollectionNoteRootCallback.h"
-#include "nsPrincipal.h"
+#include "nsExpandedPrincipal.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Preferences.h"
 #include "nsIAddonInterposition.h"
 #include "nsIXULRuntime.h"
 
 #include "mozilla/dom/BindingUtils.h"
 
 using namespace mozilla;
--- a/layout/base/MobileViewportManager.h
+++ b/layout/base/MobileViewportManager.h
@@ -90,9 +90,8 @@ private:
   bool mPainted;
   mozilla::LayoutDeviceIntSize mDisplaySize;
   mozilla::CSSSize mMobileViewportSize;
   mozilla::Maybe<float> mRestoreResolution;
   mozilla::Maybe<mozilla::ScreenIntSize> mRestoreDisplaySize;
 };
 
 #endif
-
--- a/layout/base/ZoomConstraintsClient.h
+++ b/layout/base/ZoomConstraintsClient.h
@@ -39,9 +39,8 @@ private:
 
   nsCOMPtr<nsIDocument> mDocument;
   nsIPresShell* MOZ_NON_OWNING_REF mPresShell; // raw ref since the presShell owns this
   nsCOMPtr<nsIDOMEventTarget> mEventTarget;
   mozilla::Maybe<mozilla::layers::ScrollableLayerGuid> mGuid;
 };
 
 #endif
-
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -621,18 +621,17 @@ nsDocumentViewer::SyncParentSubDocMap()
   nsCOMPtr<nsIDocument> parent_doc = parent_win->GetDoc();
   if (!parent_doc) {
     return NS_OK;
   }
 
   if (mDocument &&
       parent_doc->GetSubDocumentFor(element) != mDocument &&
       parent_doc->EventHandlingSuppressed()) {
-    mDocument->SuppressEventHandling(nsIDocument::eEvents,
-                                     parent_doc->EventHandlingSuppressed());
+    mDocument->SuppressEventHandling(parent_doc->EventHandlingSuppressed());
   }
   return parent_doc->SetSubDocumentFor(element, mDocument);
 }
 
 NS_IMETHODIMP
 nsDocumentViewer::SetContainer(nsIDocShell* aContainer)
 {
   mContainer = static_cast<nsDocShell*>(aContainer);
--- a/layout/style/GenericSpecifiedValuesInlines.h
+++ b/layout/style/GenericSpecifiedValuesInlines.h
@@ -155,9 +155,9 @@ GenericSpecifiedValues::SetFontFamily(co
 void
 GenericSpecifiedValues::SetTextDecorationColorOverride()
 {
   MOZ_STYLO_FORWARD(SetTextDecorationColorOverride, ())
 }
 
 } // namespace mozilla
 
-#endif // mozilla_GenericSpecifiedValuesInlines_h
\ No newline at end of file
+#endif // mozilla_GenericSpecifiedValuesInlines_h
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1869,9 +1869,9 @@ nsSVGUtils::GetCSSPxToDevPxMatrix(nsIFra
 {
   int32_t appUnitsPerDevPixel = aNonSVGFrame->PresContext()->AppUnitsPerDevPixel();
   float devPxPerCSSPx =
     1 / nsPresContext::AppUnitsToFloatCSSPixels(appUnitsPerDevPixel);
 
   return gfxMatrix(devPxPerCSSPx, 0.0,
                    0.0, devPxPerCSSPx,
                    0.0, 0.0);
-}
\ No newline at end of file
+}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -254,16 +254,17 @@ gvjar.sources += [geckoview_source_dir +
     'GeckoProfile.java',
     'GeckoProfileDirectories.java',
     'GeckoScreenOrientation.java',
     'GeckoSharedPrefs.java',
     'GeckoThread.java',
     'GeckoView.java',
     'GeckoViewChrome.java',
     'GeckoViewFragment.java',
+    'GeckoViewSettings.java',
     'gfx/BitmapUtils.java',
     'gfx/BufferedImage.java',
     'gfx/BufferedImageGLInfo.java',
     'gfx/DynamicToolbarAnimator.java',
     'gfx/FloatSize.java',
     'gfx/FullScreenState.java',
     'gfx/GeckoLayerClient.java',
     'gfx/ImmutableViewportMetrics.java',
--- a/mobile/android/chrome/content/geckoview.js
+++ b/mobile/android/chrome/content/geckoview.js
@@ -42,16 +42,18 @@ var ModuleManager = {
       return;
     }
     delete this.modules[type];
   }
 };
 
 function startup() {
   ModuleManager.init();
+  ModuleManager.add("resource://gre/modules/GeckoViewSettings.jsm",
+                    "GeckoViewSettings");
   ModuleManager.add("resource://gre/modules/GeckoViewContent.jsm",
                     "GeckoViewContent");
   ModuleManager.add("resource://gre/modules/GeckoViewNavigation.jsm",
                     "GeckoViewNavigation");
   ModuleManager.add("resource://gre/modules/GeckoViewProgress.jsm",
                     "GeckoViewProgress");
 
   dump("zerdatime " + Date.now() + " - geckoview chrome startup finished.");
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
@@ -46,27 +46,31 @@ public class GeckoView extends LayerView
     private final EventDispatcher eventDispatcher = new EventDispatcher();
 
     private ChromeDelegate mChromeDelegate;
     /* package */ ContentListener mContentListener;
     /* package */ NavigationListener mNavigationListener;
     /* package */ ProgressListener mProgressListener;
     private InputConnectionListener mInputConnectionListener;
 
+    private GeckoViewSettings mSettings;
+
     protected boolean onAttachedToWindowCalled;
     protected String chromeURI;
     protected int screenId = 0; // default to the primary screen
 
     @WrapForJNI(dispatchTo = "proxy")
     protected static final class Window extends JNIObject {
         @WrapForJNI(skip = true)
         /* package */ Window() {}
 
-        static native void open(Window instance, GeckoView view, Object compositor,
-                                EventDispatcher dispatcher, String chromeURI, int screenId);
+        static native void open(Window instance, GeckoView view,
+                                Object compositor, EventDispatcher dispatcher,
+                                String chromeURI, GeckoBundle settings,
+                                int screenId);
 
         @Override protected native void disposeNative();
         native void close();
         native void reattach(GeckoView view, Object compositor, EventDispatcher dispatcher);
         native void loadUri(String uri, int flags);
     }
 
     // Object to hold onto our nsWindow connection when GeckoView gets destroyed.
@@ -186,16 +190,18 @@ public class GeckoView extends LayerView
             GeckoAppShell.setContextGetter(this);
         }
 
         // Perform common initialization for Fennec/GeckoView.
         GeckoAppShell.setLayerView(this);
 
         initializeView();
         listener.registerListeners();
+
+        mSettings = new GeckoViewSettings(getEventDispatcher());
     }
 
     @Override
     protected Parcelable onSaveInstanceState()
     {
         final Parcelable superState = super.onSaveInstanceState();
         stateSaved = true;
         return new StateBinder(superState, this.window);
@@ -222,22 +228,27 @@ public class GeckoView extends LayerView
 
     protected void openWindow() {
         if (chromeURI == null) {
             chromeURI = getGeckoInterface().getDefaultChromeURI();
         }
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             Window.open(window, this, getCompositor(), eventDispatcher,
-                        chromeURI, screenId);
+                        chromeURI, mSettings.asBundle(), screenId);
         } else {
-            GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY, Window.class,
-                    "open", window, GeckoView.class, this, Object.class, getCompositor(),
-                    EventDispatcher.class, eventDispatcher,
-                    String.class, chromeURI, screenId);
+            GeckoThread.queueNativeCallUntil(
+                GeckoThread.State.PROFILE_READY,
+                Window.class, "open", window,
+                GeckoView.class, this,
+                Object.class, getCompositor(),
+                EventDispatcher.class, eventDispatcher,
+                String.class, chromeURI,
+                GeckoBundle.class, mSettings.asBundle(),
+                screenId);
         }
     }
 
     protected void reattachWindow() {
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             window.reattach(this, getCompositor(), eventDispatcher);
         } else {
             GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
@@ -322,16 +333,20 @@ public class GeckoView extends LayerView
 
     /**
     * Go forward in history.
     */
     public void goForward() {
         eventDispatcher.dispatch("GeckoView:GoForward", null);
     }
 
+    public GeckoViewSettings getSettings() {
+        return mSettings;
+    }
+
     @Override
     public Handler getHandler() {
         if (mInputConnectionListener != null) {
             return mInputConnectionListener.getHandler(super.getHandler());
         }
         return super.getHandler();
     }
 
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoViewSettings.java
@@ -0,0 +1,62 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * vim: ts=4 sw=4 expandtab:
+ * 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/. */
+
+package org.mozilla.gecko;
+
+import org.mozilla.gecko.util.GeckoBundle;
+
+import android.util.Log;
+
+public final class GeckoViewSettings {
+    private static final String LOGTAG = "GeckoViewSettings";
+    private static final boolean DEBUG = false;
+
+    private static class Key<T> {
+        private final String text;
+
+        public Key(final String text) {
+            this.text = text;
+        }
+    }
+
+    public static final Key<Boolean> USE_TRACKING_PROTECTION =
+        new Key<Boolean>("useTrackingProtection");
+
+    private final EventDispatcher mEventDispatcher;
+    private final GeckoBundle mBundle;
+
+    /* package */ GeckoViewSettings(EventDispatcher eventDispatcher) {
+        mEventDispatcher = eventDispatcher;
+        mBundle = new GeckoBundle();
+
+        setBoolean(USE_TRACKING_PROTECTION, false);
+    }
+
+    public void setBoolean(Key<Boolean> key, boolean value) {
+        synchronized (mBundle) {
+            final Object old = mBundle.get(key.text);
+            if (old != null && old.equals(value)) {
+                return;
+            }
+            mBundle.putBoolean(key.text, value);
+        }
+        dispatchUpdate();
+    }
+
+    public Object getBoolean(Key<Boolean> key) {
+        synchronized (mBundle) {
+            return mBundle.getBoolean(key.text);
+        }
+    }
+
+    /* package */ GeckoBundle asBundle() {
+        return mBundle;
+    }
+
+    private void dispatchUpdate() {
+        mEventDispatcher.dispatch("GeckoView:UpdateSettings", null);
+    }
+}
--- a/mobile/android/modules/GeckoViewModule.jsm
+++ b/mobile/android/modules/GeckoViewModule.jsm
@@ -3,23 +3,44 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["GeckoViewModule"];
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
+var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {})
+           .AndroidLog.d.bind(null, "ViewModule");
+
+function debug(msg) {
+  // dump(msg);
+}
+
 class GeckoViewModule {
   constructor(window, browser, eventDispatcher) {
     this.window = window;
     this.browser = browser;
     this.eventDispatcher = eventDispatcher;
 
+    this.eventDispatcher.registerListener(
+      () => this.onSettingsUpdate(),
+      "GeckoView:UpdateSettings");
+
     this.init();
+    this.onSettingsUpdate();
   }
 
+  // Override this with module initialization.
   init() {}
 
+  // Called when settings have changed. Access settings via this.settings.
+  onSettingsUpdate() {}
+
+  get settings() {
+    let view = this.window.arguments[0].QueryInterface(Ci.nsIAndroidView);
+    return Object.freeze(view.settings);
+  }
+
   get messageManager() {
     return this.browser.messageManager;
   }
 }
new file mode 100644
--- /dev/null
+++ b/mobile/android/modules/GeckoViewSettings.jsm
@@ -0,0 +1,55 @@
+/* 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/. */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["GeckoViewSettings"];
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+Cu.import("resource://gre/modules/GeckoViewModule.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
+  "resource://gre/modules/SafeBrowsing.jsm");
+
+var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {})
+           .AndroidLog.d.bind(null, "ViewSettings");
+
+function debug(msg) {
+  // dump(msg);
+}
+
+// Handles GeckoView settings including:
+// * tracking protection
+class GeckoViewSettings extends GeckoViewModule {
+  init() {
+    this._isSafeBrowsingInit = false;
+    this._useTrackingProtection = false;
+  }
+
+  onSettingsUpdate() {
+    debug("onSettingsUpdate: " + JSON.stringify(this.settings));
+
+    this.useTrackingProtection = !!this.settings.useTrackingProtection;
+  }
+
+  get useTrackingProtection() {
+    return this._useTrackingProtection;
+  }
+
+  set useTrackingProtection(use) {
+    if (use && !this._isSafeBrowsingInit) {
+      SafeBrowsing.init();
+      this._isSafeBrowsingInit = true;
+    }
+    if (use != this._useTrackingProtection) {
+      this.messageManager.loadFrameScript('data:,' +
+        'docShell.useTrackingProtection = ' + use,
+        true
+      );
+      this._useTrackingProtection = use;
+    }
+  }
+}
--- a/mobile/android/modules/moz.build
+++ b/mobile/android/modules/moz.build
@@ -31,10 +31,11 @@ EXTRA_JS_MODULES += [
     'WebsiteMetadata.jsm'
 ]
 
 # GeckoView-sepcific modules added separately.
 EXTRA_JS_MODULES += [
     'GeckoViewContent.jsm',
     'GeckoViewModule.jsm',
     'GeckoViewNavigation.jsm',
-    'GeckoViewProgress.jsm'
+    'GeckoViewProgress.jsm',
+    'GeckoViewSettings.jsm',
 ]
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -356,16 +356,17 @@ pref("media.wmf.disable-d3d9-for-dlls", 
 pref("media.ffmpeg.enabled", false);
 #else
 pref("media.ffmpeg.enabled", true);
 #endif
 pref("media.libavcodec.allow-obsolete", false);
 #endif
 #if defined(MOZ_FFVPX)
 pref("media.ffvpx.enabled", true);
+pref("media.ffvpx.low-latency.enabled", false);
 #endif
 pref("media.gmp.decoder.enabled", false);
 pref("media.gmp.decoder.aac", 0);
 pref("media.gmp.decoder.h264", 0);
 #ifdef MOZ_RAW
 pref("media.raw.enabled", true);
 #endif
 pref("media.ogg.enabled", true);
--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -120,16 +120,20 @@ IsCertChainRootBuiltInRoot(const UniqueC
   }
   CERTCertificate* root = rootNode->cert;
   if (!root) {
     return Result::FATAL_ERROR_LIBRARY_FAILURE;
   }
   return IsCertBuiltInRoot(root, result);
 }
 
+// The term "builtin root" traditionally refers to a root CA certificate that
+// has been added to the NSS trust store, because it has been approved
+// for inclusion according to the Mozilla CA policy, and might be accepted
+// by Mozilla applications as an issuer for certificates seen on the public web.
 Result
 IsCertBuiltInRoot(CERTCertificate* cert, bool& result)
 {
   result = false;
 #ifdef DEBUG
   nsCOMPtr<nsINSSComponent> component(do_GetService(PSM_COMPONENT_CONTRACTID));
   if (!component) {
     return Result::FATAL_ERROR_LIBRARY_FAILURE;
@@ -142,25 +146,38 @@ IsCertBuiltInRoot(CERTCertificate* cert,
     return Success;
   }
 #endif // DEBUG
   AutoSECMODListReadLock lock;
   for (SECMODModuleList* list = SECMOD_GetDefaultModuleList(); list;
        list = list->next) {
     for (int i = 0; i < list->module->slotCount; i++) {
       PK11SlotInfo* slot = list->module->slots[i];
-      // PK11_HasRootCerts should return true if and only if the given slot has
-      // an object with a CKA_CLASS of CKO_NETSCAPE_BUILTIN_ROOT_LIST, which
-      // should be true only of the builtin root list.
-      // If we can find a copy of the given certificate on the slot with the
-      // builtin root list, that certificate must be a builtin.
-      if (PK11_IsPresent(slot) && PK11_HasRootCerts(slot) &&
-          PK11_FindCertInSlot(slot, cert, nullptr) != CK_INVALID_HANDLE) {
-        result = true;
-        return Success;
+      // We're searching for the "builtin root module", which is a module that
+      // contains an object with a CKA_CLASS of CKO_NETSCAPE_BUILTIN_ROOT_LIST.
+      // We use PK11_HasRootCerts() to identify a module with that property.
+      // In the past, we exclusively used the PKCS#11 module named nssckbi,
+      // which is provided by the NSS library.
+      // Nowadays, some distributions use a replacement module, which contains
+      // the builtin roots, but which also contains additional CA certificates,
+      // such as CAs trusted in a local deployment.
+      // We want to be able to distinguish between these two categories,
+      // because a CA, which may issue certificates for the public web,
+      // is expected to comply with additional requirements.
+      // If the certificate has attribute CKA_NSS_MOZILLA_CA_POLICY set to true,
+      // then we treat it as a "builtin root".
+      if (PK11_IsPresent(slot) && PK11_HasRootCerts(slot)) {
+        CK_OBJECT_HANDLE handle = PK11_FindCertInSlot(slot, cert, nullptr);
+        if (handle != CK_INVALID_HANDLE &&
+            PK11_HasAttributeSet(slot, handle, CKA_NSS_MOZILLA_CA_POLICY,
+                                 false)) {
+          // Attribute was found, and is set to true
+          result = true;
+          break;
+        }
       }
     }
   }
   return Success;
 }
 
 static Result
 BuildCertChainForOneKeyUsage(NSSCertDBTrustDomain& trustDomain, Input certDER,
--- a/taskcluster/ci/l10n/kind.yml
+++ b/taskcluster/ci/l10n/kind.yml
@@ -22,17 +22,17 @@ only-for-build-platforms:
 job-template:
    description:
       by-build-platform:
          default: Localization
          android-api-15-l10n: Single Locale Repack
    locales-file:
       by-build-platform:
          default: browser/locales/all-locales
-         android-api-15-l10n: mobile/android/locales/all-locales
+         android-api-15-l10n: mobile/locales/l10n-changesets.json
    run-time:
       by-build-platform:
          default: 36000
          android-api-15-l10n: 18000
    tooltool:
       by-build-platform:
          default: public
          android-api-15-l10n: internal
--- a/taskcluster/ci/nightly-l10n/kind.yml
+++ b/taskcluster/ci/nightly-l10n/kind.yml
@@ -21,17 +21,17 @@ only-for-build-platforms:
 job-template:
    description:
       by-build-platform:
          default: Localization
          android-api-15-nightly: Single Locale Repack
    locales-file:
       by-build-platform:
          default: browser/locales/all-locales
-         android-api-15-nightly: mobile/android/locales/all-locales
+         android-api-15-nightly: mobile/locales/l10n-changesets.json
    chunks: 6
    run-time:
       by-build-platform:
          default: 36000
          android-api-15-nightly: 18000
    tooltool:
       by-build-platform:
          default: public
--- a/testing/marionette/harness/marionette_harness/tests/webapi-tests.ini
+++ b/testing/marionette/harness/marionette_harness/tests/webapi-tests.ini
@@ -1,6 +1,4 @@
 [include:../../../../../dom/system/gonk/tests/marionette/manifest.ini]
-[include:../../../../../dom/system/tests/marionette/manifest.ini]
-skip-if = android_version > '15' # Bug 1203072
 [include:../../../../../dom/events/test/marionette/manifest.ini]
 skip-if = android_version > '15' # Bug 1203075
 [include:../../../../../dom/network/tests/marionette/manifest.ini]
new file mode 100644
--- /dev/null
+++ b/testing/mozharness/configs/multi_locale/jamun_android-armv6.json
@@ -0,0 +1,28 @@
+{
+    "work_dir": ".",
+    "log_name": "multilocale",
+    "objdir": "obj-firefox",
+    "locales_file": "build/mobile/locales/l10n-changesets.json",
+    "locales_dir": "mobile/android/locales",
+    "ignore_locales": ["en-US", "multi"],
+    "repos": [{
+        "repo": "https://hg.mozilla.org/jamun",
+        "branch": "default",
+        "dest": "build"
+    },{
+        "repo": "https://hg.mozilla.org/build/buildbot-configs",
+        "branch": "production",
+        "dest": "build/configs"
+    },{
+        "repo": "https://hg.mozilla.org/build/tools",
+        "branch": "default",
+        "dest": "tools"
+    }],
+    "vcs_share_base": "/builds/hg-shared",
+    "hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-aurora",
+    "hg_l10n_tag": "default",
+    "l10n_dir": "mozilla-aurora",
+    "merge_locales": true,
+    "mozilla_dir": "build",
+    "mozconfig": "build/mobile/android/config/mozconfigs/android-armv6/nightly"
+}
new file mode 100644
--- /dev/null
+++ b/testing/mozharness/configs/multi_locale/jamun_android-x86.json
@@ -0,0 +1,28 @@
+{
+    "work_dir": ".",
+    "log_name": "multilocale",
+    "objdir": "obj-firefox",
+    "locales_file": "build/mobile/locales/l10n-changesets.json",
+    "locales_dir": "mobile/android/locales",
+    "ignore_locales": ["en-US", "multi"],
+    "repos": [{
+        "repo": "https://hg.mozilla.org/jamun",
+        "branch": "default",
+        "dest": "build"
+    },{
+        "repo": "https://hg.mozilla.org/build/buildbot-configs",
+        "branch": "production",
+        "dest": "build/configs"
+    },{
+        "repo": "https://hg.mozilla.org/build/tools",
+        "branch": "default",
+        "dest": "tools"
+    }],
+    "vcs_share_base": "/builds/hg-shared",
+    "hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-aurora",
+    "hg_l10n_tag": "default",
+    "l10n_dir": "mozilla-aurora",
+    "merge_locales": true,
+    "mozilla_dir": "build",
+    "mozconfig": "build/mobile/android/config/mozconfigs/android-x86/nightly"
+}
new file mode 100644
--- /dev/null
+++ b/testing/mozharness/configs/multi_locale/jamun_android.json
@@ -0,0 +1,27 @@
+{
+    "work_dir": ".",
+    "log_name": "multilocale",
+    "objdir": "obj-firefox",
+    "locales_file": "build/mobile/locales/l10n-changesets.json",
+    "locales_dir": "mobile/android/locales",
+    "ignore_locales": ["en-US", "multi"],
+    "repos": [{
+        "repo": "https://hg.mozilla.org/jamun",
+        "branch": "default",
+        "dest": "build"
+    },{
+        "repo": "https://hg.mozilla.org/build/buildbot-configs",
+        "branch": "production",
+        "dest": "build/configs"
+    },{
+        "repo": "https://hg.mozilla.org/build/tools",
+        "branch": "default",
+        "dest": "tools"
+    }],
+    "vcs_share_base": "/builds/hg-shared",
+    "hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-aurora",
+    "hg_l10n_tag": "default",
+    "l10n_dir": "mozilla-aurora",
+    "merge_locales": true,
+    "mozilla_dir": "build"
+}
new file mode 100644
--- /dev/null
+++ b/testing/mozharness/configs/single_locale/jamun.py
@@ -0,0 +1,35 @@
+import os
+
+config = {
+    "nightly_build": True,
+    "branch": "jamun",
+    "en_us_binary_url": "http://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central",
+    "update_channel": "nightly-jamun",
+    "latest_mar_dir": '/pub/firefox/nightly/latest-jamun-l10n',
+
+    # l10n
+    "hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-aurora",
+
+    # mar
+    "mar_tools_url": os.environ.get(
+        "MAR_TOOLS_URL",
+        # Buildbot l10n fetches from ftp rather than setting an environ var
+        "http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-mozilla-central/mar-tools/%(platform)s"
+    ),
+
+    # repositories
+    "mozilla_dir": "jamun",
+    "repos": [{
+        "vcs": "hg",
+        "repo": "https://hg.mozilla.org/build/tools",
+        "branch": "default",
+        "dest": "tools",
+    }, {
+        "vcs": "hg",
+        "repo": "https://hg.mozilla.org/projects/jamun",
+        "revision": "%(revision)s",
+        "dest": "jamun",
+    }],
+    # purge options
+    'is_automation': True,
+}
new file mode 100644
--- /dev/null
+++ b/testing/mozharness/configs/single_locale/jamun_android-api-15.py
@@ -0,0 +1,94 @@
+import os
+
+BRANCH = "jamun"
+MOZILLA_DIR = BRANCH
+EN_US_BINARY_URL = None     # No build has been uploaded to archive.m.o
+
+config = {
+    "branch": BRANCH,
+    "log_name": "single_locale",
+    "objdir": "obj-l10n",
+    "is_automation": True,
+    "buildbot_json_path": "buildprops.json",
+    "force_clobber": True,
+    "clobberer_url": "https://api.pub.build.mozilla.org/clobberer/lastclobber",
+    "locales_file": "%s/mobile/locales/l10n-changesets.json" % MOZILLA_DIR,
+    "locales_dir": "mobile/android/locales",
+    "ignore_locales": ["en-US"],
+    "nightly_build": True,
+    'balrog_credentials_file': 'oauth.txt',
+    "tools_repo": "https://hg.mozilla.org/build/tools",
+    "tooltool_config": {
+        "manifest": "mobile/android/config/tooltool-manifests/android/releng.manifest",
+        "output_dir": "%(abs_work_dir)s/" + MOZILLA_DIR,
+    },
+    "exes": {
+        'tooltool.py': '/builds/tooltool.py',
+    },
+    "repos": [{
+        "vcs": "hg",
+        "repo": "https://hg.mozilla.org/build/tools",
+        "branch": "default",
+        "dest": "tools",
+    }, {
+        "vcs": "hg",
+        "repo": "https://hg.mozilla.org/projects/jamun",
+        "revision": "%(revision)s",
+        "dest": MOZILLA_DIR,
+    }],
+    "hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-aurora",
+    "hg_l10n_tag": "default",
+    'vcs_share_base': "/builds/hg-shared",
+
+    "l10n_dir": "mozilla-aurora",
+    "repack_env": {
+        # so ugly, bug 951238
+        "LD_LIBRARY_PATH": "/lib:/tools/gcc-4.7.2-0moz1/lib:/tools/gcc-4.7.2-0moz1/lib64",
+        "MOZ_OBJDIR": "obj-l10n",
+        "EN_US_BINARY_URL": os.environ.get("EN_US_BINARY_URL", EN_US_BINARY_URL),
+        "LOCALE_MERGEDIR": "%(abs_merge_dir)s/",
+        "MOZ_UPDATE_CHANNEL": "nightly-jamun",
+    },
+    "upload_branch": "%s-android-api-15" % BRANCH,
+    "ssh_key_dir": "~/.ssh",
+    "merge_locales": True,
+    "mozilla_dir": MOZILLA_DIR,
+    "mozconfig": "%s/mobile/android/config/mozconfigs/android-api-15/l10n-nightly" % MOZILLA_DIR,
+    "signature_verification_script": "tools/release/signing/verify-android-signature.sh",
+    "stage_product": "mobile",
+    "platform": "android",
+    "build_type": "api-15-opt",
+
+    # Balrog
+    "build_target": "Android_arm-eabi-gcc3",
+
+    # Mock
+    "mock_target": "mozilla-centos6-x86_64-android",
+    "mock_packages": ['autoconf213', 'python', 'zip', 'mozilla-python27-mercurial', 'git', 'ccache',
+                      'glibc-static', 'libstdc++-static', 'perl-Test-Simple', 'perl-Config-General',
+                      'gtk2-devel', 'libnotify-devel', 'yasm',
+                      'alsa-lib-devel', 'libcurl-devel',
+                      'wireless-tools-devel', 'libX11-devel',
+                      'libXt-devel', 'mesa-libGL-devel',
+                      'gnome-vfs2-devel', 'GConf2-devel', 'wget',
+                      'mpfr',  # required for system compiler
+                      'xorg-x11-font*',  # fonts required for PGO
+                      'imake',  # required for makedepend!?!
+                      'gcc45_0moz3', 'gcc454_0moz1', 'gcc472_0moz1', 'gcc473_0moz1', 'yasm', 'ccache',  # <-- from releng repo
+                      'valgrind', 'dbus-x11',
+                      'pulseaudio-libs-devel',
+                      'gstreamer-devel', 'gstreamer-plugins-base-devel',
+                      'freetype-2.3.11-6.el6_1.8.x86_64',
+                      'freetype-devel-2.3.11-6.el6_1.8.x86_64',
+                      'java-1.7.0-openjdk-devel',
+                      'openssh-clients',
+                      'zlib-devel-1.2.3-27.el6.i686',
+                      ],
+    "mock_files": [
+        ("/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"),
+        ('/home/cltbld/.hgrc', '/builds/.hgrc'),
+        ('/builds/relengapi.tok', '/builds/relengapi.tok'),
+        ('/tools/tooltool.py', '/builds/tooltool.py'),
+        ('/usr/local/lib/hgext', '/usr/local/lib/hgext'),
+    ],
+}
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/tabular-data/the-caption-element/caption_001.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[caption_001.html]
-  type: testharness
-  [setting caption on a table]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/caption-methods.html.ini
+++ /dev/null
@@ -1,14 +0,0 @@
-[caption-methods.html]
-  type: testharness
-  [createCaption method creates a new caption and inserts it as the first node of the table element]
-    expected: FAIL
-
-  [createCaption method creates new caption if existing caption is not in html namespace]
-    expected: FAIL
-
-  [createCaption will not copy table's prefix]
-    expected: FAIL
-
-  [Assigning a caption to table.caption]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/tHead.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[tHead.html]
-  type: testharness
-  [tHead tests]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/table-insertRow.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[table-insertRow.html]
-  type: testharness
-  [insertRow should not copy prefixes]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/generic/subresource-test/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
--- a/testing/web-platform/meta/referrer-policy/generic/subresource-test/image-decoding.html.ini
+++ b/testing/web-platform/meta/referrer-policy/generic/subresource-test/image-decoding.html.ini
@@ -1,6 +1,5 @@
 [image-decoding.html]
   type: testharness
-  expected: TIMEOUT
   [Image is encoding headers as JSON.]
-    expected: NOTRUN
+    expected: FAIL
 
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/http-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/http-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/http-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/http-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-http/img-tag/insecure-protocol.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-http/img-tag/insecure-protocol.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-http/img-tag/insecure-protocol.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/img-tag/insecure-protocol.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/img-tag/insecure-protocol.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/img-tag/insecure-protocol.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/http-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/http-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/http-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/http-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/meta-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/meta-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/cross-origin/http-http/img-tag/generic.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/cross-origin/http-http/img-tag/generic.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/cross-origin/http-http/img-tag/generic.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/img-tag/generic.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/img-tag/generic.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/img-tag/generic.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/img-tag/generic.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/img-tag/generic.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is omitted when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/http-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/http-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/http-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/http-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/meta-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/meta-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-only/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/http-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/http-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/http-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/http-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-http/img-tag/cross-origin.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[cross-origin.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-http/img-tag/cross-origin.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[cross-origin.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-http/img-tag/cross-origin.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[cross-origin.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/cross-origin.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[cross-origin.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/cross-origin.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[cross-origin.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/cross-origin.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[cross-origin.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/img-tag/same-origin-insecure.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[same-origin-insecure.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/img-tag/same-origin-insecure.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[same-origin-insecure.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/img-tag/same-origin-insecure.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[same-origin-insecure.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-downgrade.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[same-origin-downgrade.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-downgrade.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[same-origin-downgrade.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-downgrade.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[same-origin-downgrade.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-insecure.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[same-origin-insecure.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-upgrade.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[same-origin-upgrade.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-upgrade.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[same-origin-upgrade.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-upgrade.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[same-origin-upgrade.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is origin when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/strict-origin-when-cross-origin/__dir__.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-disabled:
-  if os == "linux" and bits == 64: https://bugzilla.mozilla.org/show_bug.cgi?id=1302421
\ No newline at end of file
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/strict-origin/__dir__.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-disabled:
-  if os == "linux" and bits == 64: https://bugzilla.mozilla.org/show_bug.cgi?id=1302421
\ No newline at end of file
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/http-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/http-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/http-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/http-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/meta-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/meta-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-http/img-tag/generic.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-http/img-tag/generic.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-http/img-tag/generic.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/img-tag/generic.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/img-tag/generic.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/img-tag/generic.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/img-tag/generic.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/img-tag/generic.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[generic.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/http-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/http-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/http-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/http-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-csp/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-csp/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-csp/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-csp/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-http/img-tag/insecure-protocol.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-http/img-tag/insecure-protocol.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-http/img-tag/insecure-protocol.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is cross-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/img-tag/insecure-protocol.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/img-tag/insecure-protocol.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/img-tag/insecure-protocol.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[insecure-protocol.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an http\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
deleted file mode 100644
--- a/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/img-tag/__dir__.ini
+++ /dev/null
@@ -1,1 +0,0 @@
-disabled: https://github.com/w3c/web-platform-tests/issues/1874
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.keep-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with keep-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.no-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with no-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html.ini
@@ -0,0 +1,5 @@
+[upgrade-protocol.swap-origin-redirect.http.html]
+  type: testharness
+  [The referrer URL is stripped-referrer when a\n                                 document served over http requires an https\n                                 sub-resource via img-tag using the meta-referrer\n                                 delivery method with swap-origin-redirect and when\n                                 the target request is same-origin.]
+    expected: FAIL
+
--- a/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html
@@ -91,9 +91,27 @@ test(function () {
     var elarray = [];
     for (var i = 0; i < selly.length; i++) {
         elarray.push(selly[i].value);
     }
     assert_array_equals(elarray, ["a", "2", "3", "", "", "-1"]);
 
 }, "Setting element by index should correctly append and replace elements");
 
+test(function () {
+    var selection = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:select");
+
+    selection.length = 5;
+    assert_equals(selection.length, 5,
+                  "Number of nodes in collection should have changed");
+    for (var i = 0; i < 5; ++i) {
+        var child = selection.children[i];
+        assert_equals(child.localName, "option",
+                      "new child should be an option");
+        assert_equals(child.namespaceURI, "http://www.w3.org/1999/xhtml",
+                      "new child should be an HTML element");
+        assert_equals(child.prefix, null,
+                      "new child should not copy select's prefix");
+    }
+
+}, "Changing the length adds new nodes; The new nodes will not copy select's prefix");
+
 </script>
--- a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tFoot.html
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tFoot.html
@@ -49,9 +49,17 @@ test(function() {
     assert_throws(new TypeError(), function(){
         t.tFoot = document.createElement("div");
     });
 
     assert_throws("HierarchyRequestError", function(){
         t.tFoot = document.createElement("thead");
     });
 })
+
+test(function () {
+    var table = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:table")
+    var tfoot = table.createTFoot();
+
+    assert_equals(table.tFoot, tfoot);
+    assert_equals(tfoot.prefix, null);
+});
 </script>
--- a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tHead.html
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tHead.html
@@ -58,9 +58,17 @@ test(function() {
 test(function() {
     var t2 = document.getElementById("t2");
     var t2thead = document.getElementById("t2thead");
 
     assert_throws("HierarchyRequestError", function() {
         t2.tHead = t2thead;
     });
 });
+
+test(function () {
+    var table = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:table")
+    var thead = table.createTHead();
+
+    assert_equals(table.tHead, thead);
+    assert_equals(thead.prefix, null);
+});
 </script>
--- a/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/insertCell.html
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/insertCell.html
@@ -47,9 +47,18 @@ test(function () {
 }, "HTMLTableRowElement insertCell(-2)");
 
 test(function () {
   assert_throws("IndexSizeError", function () {
     tr.insertCell(tr.cells.length + 1);
   });
 }, "HTMLTableRowElement insertCell(cells.length + 1)");
 
+test(function () {
+  var table = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:table")
+  var row = table.insertRow(0);
+  var cell = row.insertCell(0);
+
+  assert_equals(row.cells[0], cell);
+  assert_equals(cell.prefix, null);
+}, "HTMLTableRowElement insertCell will not copy table's prefix");
+
 </script>
--- a/toolkit/themes/osx/global/dropmarker.css
+++ b/toolkit/themes/osx/global/dropmarker.css
@@ -2,30 +2,20 @@
  * 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/. */
 
 dropmarker {
   -moz-appearance: menulist-button;
   width: 16px;
   -moz-box-align: center;
   -moz-box-pack: center;
-  border: 2px solid;
-  -moz-border-top-colors: ThreeDLightShadow ThreeDHighlight;
-  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow;
-  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow;
-  -moz-border-left-colors: ThreeDLightShadow ThreeDHighlight;
-  background-color: -moz-Dialog;
   padding: 1px;
   list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
   -moz-image-region: auto;
 }
 
 dropmarker:hover:active:not([disabled="true"]) {
-  -moz-border-top-colors: ThreeDShadow ThreeDFace;
-  -moz-border-right-colors: ThreeDShadow ThreeDFace;
-  -moz-border-bottom-colors: ThreeDShadow ThreeDFace;
-  -moz-border-left-colors: ThreeDShadow ThreeDFace;
   padding: 2px 0 0 2px;
 }
 
 dropmarker[disabled="true"] {
   list-style-image: url("chrome://global/skin/arrow/arrow-dn-dis.gif");
 }
--- a/toolkit/themes/windows/global/button.css
+++ b/toolkit/themes/windows/global/button.css
@@ -83,18 +83,16 @@ button[disabled="true"] > .button-box {
 button[type="menu-button"] {
   margin: 0;
 }
 
 .button-menu-dropmarker,
 .button-menubutton-dropmarker {
   -moz-appearance: none !important;
   margin: 1px;
-  background-color: transparent;
-  border: none;
   width: 11px;
   height: 11px;
 }
 
 .button-menubutton-dropmarker[open="true"] {
   margin-top: 2px;
   margin-bottom: 0px;
   margin-inline-start: 2px;
--- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp
+++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp
@@ -144,17 +144,17 @@ OfflineCacheUpdateParent::Schedule(const
         documentURI->Clone(getter_AddRefs(stickURI));
         update->StickDocument(stickURI);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-OfflineCacheUpdateParent::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, uint32_t state)
+OfflineCacheUpdateParent::UpdateStateChanged(nsIOfflineCacheUpdate* aUpdate, uint32_t state)
 {
     if (mIPCClosed)
         return NS_ERROR_UNEXPECTED;
 
     LOG(("OfflineCacheUpdateParent::StateEvent [%p]", this));
 
     uint64_t byteProgress;
     aUpdate->GetByteProgress(&byteProgress);
@@ -171,17 +171,17 @@ OfflineCacheUpdateParent::UpdateStateCha
 
         Unused << SendFinish(succeeded, isUpgrade);
     }
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-OfflineCacheUpdateParent::ApplicationCacheAvailable(nsIApplicationCache *aApplicationCache)
+OfflineCacheUpdateParent::ApplicationCacheAvailable(nsIApplicationCache* aApplicationCache)
 {
     if (mIPCClosed)
         return NS_ERROR_UNEXPECTED;
 
     NS_ENSURE_ARG(aApplicationCache);
 
     nsCString cacheClientId;
     aApplicationCache->GetClientID(cacheClientId);
@@ -216,52 +216,52 @@ OfflineCacheUpdateParent::GetTopFrameEle
 
 NS_IMETHODIMP
 OfflineCacheUpdateParent::GetNestedFrameId(uint64_t* aId)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-OfflineCacheUpdateParent::GetIsContent(bool *aIsContent)
+OfflineCacheUpdateParent::GetIsContent(bool* aIsContent)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-OfflineCacheUpdateParent::GetUsePrivateBrowsing(bool *aUsePrivateBrowsing)
+OfflineCacheUpdateParent::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 NS_IMETHODIMP
 OfflineCacheUpdateParent::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 OfflineCacheUpdateParent::SetPrivateBrowsing(bool aUsePrivateBrowsing)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-OfflineCacheUpdateParent::GetUseRemoteTabs(bool *aUseRemoteTabs)
+OfflineCacheUpdateParent::GetUseRemoteTabs(bool* aUseRemoteTabs)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 OfflineCacheUpdateParent::SetRemoteTabs(bool aUseRemoteTabs)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-OfflineCacheUpdateParent::GetIsInIsolatedMozBrowserElement(bool *aIsInIsolatedMozBrowserElement)
+OfflineCacheUpdateParent::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserElement)
 {
     NS_ENSURE_TRUE(mLoadingPrincipal, NS_ERROR_UNEXPECTED);
     return mLoadingPrincipal->GetIsInIsolatedMozBrowserElement(aIsInIsolatedMozBrowserElement);
 }
 
 NS_IMETHODIMP
 OfflineCacheUpdateParent::GetOriginAttributes(JS::MutableHandleValue aAttrs)
 {
@@ -272,15 +272,21 @@ OfflineCacheUpdateParent::GetOriginAttri
 
     nsresult rv = mLoadingPrincipal->GetOriginAttributes(cx, aAttrs);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-OfflineCacheUpdateParent::IsTrackingProtectionOn(bool* aIsTrackingProtectionOn)
+OfflineCacheUpdateParent::GetUseTrackingProtection(bool* aUseTrackingProtection)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+OfflineCacheUpdateParent::SetUseTrackingProtection(bool aUseTrackingProtection)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 } // namespace docshell
 } // namespace mozilla
--- a/widget/EventMessageList.h
+++ b/widget/EventMessageList.h
@@ -221,16 +221,17 @@ NS_EVENT_MESSAGE(eSVGZoom)
 
 // XUL command events
 NS_EVENT_MESSAGE(eXULCommand)
 
 // Cut, copy, paste events
 NS_EVENT_MESSAGE(eCopy)
 NS_EVENT_MESSAGE(eCut)
 NS_EVENT_MESSAGE(ePaste)
+NS_EVENT_MESSAGE(ePasteNoFormatting)
 
 // Query for the selected text information, it return the selection offset,
 // selection length and selected text.
 NS_EVENT_MESSAGE(eQuerySelectedText)
 // Query for the text content of specified range, it returns actual lengh (if
 // the specified range is too long) and the text of the specified range.
 // Returns the entire text if requested length > actual length.
 NS_EVENT_MESSAGE(eQueryTextContent)
--- a/widget/android/EventDispatcher.cpp
+++ b/widget/android/EventDispatcher.cpp
@@ -961,10 +961,18 @@ EventDispatcher::DispatchToGecko(jni::St
     if (aCallback) {
         callback = new JavaCallbackDelegate(
                 java::EventCallback::Ref::From(aCallback));
     }
 
     DispatchOnGecko(list, event, data, callback);
 }
 
+/* static */
+nsresult
+EventDispatcher::UnboxBundle(JSContext* aCx, jni::Object::Param aData,
+                             JS::MutableHandleValue aOut)
+{
+    return detail::UnboxBundle(aCx, aData, aOut);
+}
+
 } // namespace widget
 } // namespace mozilla
--- a/widget/android/EventDispatcher.h
+++ b/widget/android/EventDispatcher.h
@@ -43,16 +43,20 @@ public:
 
     using NativesBase::DisposeNative;
 
     bool HasGeckoListener(jni::String::Param aEvent);
     void DispatchToGecko(jni::String::Param aEvent,
                          jni::Object::Param aData,
                          jni::Object::Param aCallback);
 
+    static nsresult UnboxBundle(JSContext* aCx,
+                                const jni::Object::Param aData,
+                                JS::MutableHandleValue aOut);
+
 private:
     java::EventDispatcher::GlobalRef mDispatcher;
     nsCOMPtr<nsPIDOMWindowOuter> mDOMWindow;
 
     virtual ~EventDispatcher() {}
 
     struct ListenersList {
         nsCOMArray<nsIAndroidEventListener> listeners{/* count */ 1};
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -3014,20 +3014,21 @@ public:
         typedef void ReturnType;
         typedef void SetterType;
         typedef mozilla::jni::Args<
                 Window::Param,
                 GeckoView::Param,
                 mozilla::jni::Object::Param,
                 mozilla::jni::Object::Param,
                 mozilla::jni::String::Param,
+                mozilla::jni::Object::Param,
                 int32_t> Args;
         static constexpr char name[] = "open";
         static constexpr char signature[] =
-                "(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;Ljava/lang/Object;Lorg/mozilla/gecko/EventDispatcher;Ljava/lang/String;I)V";
+                "(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;Ljava/lang/Object;Lorg/mozilla/gecko/EventDispatcher;Ljava/lang/String;Lorg/mozilla/gecko/util/GeckoBundle;I)V";
         static const bool isStatic = true;
         static const mozilla::jni::ExceptionMode exceptionMode =
                 mozilla::jni::ExceptionMode::ABORT;
         static const mozilla::jni::CallingThread callingThread =
                 mozilla::jni::CallingThread::ANY;
         static const mozilla::jni::DispatchTarget dispatchTarget =
                 mozilla::jni::DispatchTarget::PROXY;
     };
--- a/widget/android/nsIAndroidBridge.idl
+++ b/widget/android/nsIAndroidBridge.idl
@@ -60,16 +60,17 @@ interface nsIAndroidEventDispatcher : ns
   [implicit_jscontext]
   void unregisterListener(in nsIAndroidEventListener listener,
                           in jsval events);
 };
 
 [scriptable, uuid(60a78a94-6117-432f-9d49-304913a931c5)]
 interface nsIAndroidView : nsIAndroidEventDispatcher
 {
+  [implicit_jscontext] readonly attribute jsval settings;
 };
 
 [scriptable, uuid(1beb70d3-70f3-4742-98cc-a3d301b26c0c)]
 interface nsIAndroidBridge : nsIAndroidEventDispatcher
 {
   [implicit_jscontext] void handleGeckoMessage(in jsval message);
   attribute nsIAndroidBrowserApp browserApp;
   void contentDocumentChanged(in mozIDOMWindowProxy window);
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -359,16 +359,17 @@ private:
 
 public:
     // Create and attach a window.
     static void Open(const jni::Class::LocalRef& aCls,
                      GeckoView::Window::Param aWindow,
                      GeckoView::Param aView, jni::Object::Param aCompositor,
                      jni::Object::Param aDispatcher,
                      jni::String::Param aChromeURI,
+                     jni::Object::Param aSettings,
                      int32_t screenId);
 
     // Close and destroy the nsWindow.
     void Close();
 
     // Reattach this nsWindow to a new GeckoView.
     void Reattach(const GeckoView::Window::LocalRef& inst,
                   GeckoView::Param aView, jni::Object::Param aCompositor,
@@ -951,16 +952,33 @@ public:
 
 template<> const char
 nsWindow::NativePtr<nsWindow::NPZCSupport>::sName[] = "NPZCSupport";
 
 NS_IMPL_ISUPPORTS(nsWindow::AndroidView,
                   nsIAndroidEventDispatcher,
                   nsIAndroidView)
 
+
+nsresult
+nsWindow::AndroidView::GetSettings(JSContext* aCx, JS::MutableHandleValue aOut)
+{
+    if (!mSettings) {
+        aOut.setNull();
+        return NS_OK;
+    }
+
+    JNIEnv* const env = jni::GetGeckoThreadEnv();
+    env->MonitorEnter(mSettings.Get());
+    nsresult rv = widget::EventDispatcher::UnboxBundle(aCx, mSettings, aOut);
+    env->MonitorExit(mSettings.Get());
+
+    return rv;
+}
+
 /**
  * Compositor has some unique requirements for its native calls, so make it
  * separate from GeckoViewSupport.
  */
 class nsWindow::LayerViewSupport final
     : public LayerView::Compositor::Natives<LayerViewSupport>
 {
     using LockedWindowPtr = WindowPtr<LayerViewSupport>::Locked;
@@ -1366,16 +1384,17 @@ nsWindow::GeckoViewSupport::~GeckoViewSu
 
 /* static */ void
 nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls,
                                  GeckoView::Window::Param aWindow,
                                  GeckoView::Param aView,
                                  jni::Object::Param aCompositor,
                                  jni::Object::Param aDispatcher,
                                  jni::String::Param aChromeURI,
+                                 jni::Object::Param aSettings,
                                  int32_t aScreenId)
 {
     MOZ_ASSERT(NS_IsMainThread());
 
     PROFILER_LABEL("nsWindow", "GeckoViewSupport::Open",
                    js::ProfileEntry::Category::OTHER);
 
     nsCOMPtr<nsIWindowWatcher> ww = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
@@ -1389,16 +1408,19 @@ nsWindow::GeckoViewSupport::Open(const j
         if (!url) {
             url = NS_LITERAL_CSTRING("chrome://browser/content/browser.xul");
         }
     }
 
     RefPtr<AndroidView> androidView = new AndroidView();
     androidView->mEventDispatcher->Attach(
             java::EventDispatcher::Ref::From(aDispatcher), nullptr);
+    if (aSettings) {
+        androidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
+    }
 
     nsCOMPtr<mozIDOMWindowProxy> domWindow;
     ww->OpenWindow(nullptr, url, nullptr, "chrome,dialog=0,resizable,scrollbars=yes",
                    androidView, getter_AddRefs(domWindow));
     MOZ_RELEASE_ASSERT(domWindow);
 
     nsCOMPtr<nsPIDOMWindowOuter> pdomWindow =
             nsPIDOMWindowOuter::From(domWindow);
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -105,16 +105,18 @@ private:
             new mozilla::widget::EventDispatcher()};
 
         AndroidView() {}
 
         NS_DECL_ISUPPORTS
         NS_DECL_NSIANDROIDVIEW
 
         NS_FORWARD_NSIANDROIDEVENTDISPATCHER(mEventDispatcher->)
+
+        mozilla::java::GeckoBundle::GlobalRef mSettings;
     };
 
     RefPtr<AndroidView> mAndroidView;
 
     class LayerViewSupport;
     // Object that implements native LayerView calls.
     // Owned by the Java LayerView instance.
     NativePtr<LayerViewSupport> mLayerViewSupport;