Merge inbound to mozilla-central a=merge
authorCoroiu Cristina <ccoroiu@mozilla.com>
Tue, 31 Jul 2018 00:58:28 +0300
changeset 484342 fe2acb8f775a
parent 484307 896812b8a15b (current diff)
parent 484341 1161111168cf (diff)
child 484343 cb499a2e4650
child 484356 397b4d841690
child 484395 129b5ed91c3c
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone63.0a1
first release with
nightly linux32
fe2acb8f775a / 63.0a1 / 20180730221422 / files
nightly linux64
fe2acb8f775a / 63.0a1 / 20180730221422 / files
nightly mac
fe2acb8f775a / 63.0a1 / 20180730221422 / files
nightly win32
fe2acb8f775a / 63.0a1 / 20180730221422 / files
nightly win64
fe2acb8f775a / 63.0a1 / 20180730221422 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central a=merge
testing/web-platform/tests/xhr/overridemimetype-done-state.htm
testing/web-platform/tests/xhr/responsetype.html
widget/android/nsScreenManagerAndroid.cpp
widget/android/nsScreenManagerAndroid.h
--- a/browser/themes/shared/urlbar-searchbar.inc.css
+++ b/browser/themes/shared/urlbar-searchbar.inc.css
@@ -208,19 +208,19 @@
 :root[uidensity=compact] #pageActionSeparator {
   height: 24px;
 }
 
 :root[uidensity=touch] #pageActionSeparator {
   height: 30px;
 }
 
-:not(#pageActionSeparator):not([hidden]) ~ #pageActionSeparator {
+#page-action-buttons > :not([hidden]) ~ #pageActionSeparator {
   /* Show the separator between the page actions and other elements when at
-     least of the latter is shown. */
+     least one of the latter is shown. */
   visibility: visible;
   margin-left: 6px;
   margin-right: 6px;
 }
 
 #userContext-icons,
 #urlbar-zoom-button {
   margin-left: 6px;
new file mode 100644
--- /dev/null
+++ b/build/build-clang/clang-7-pre-mingw.json
@@ -0,0 +1,18 @@
+{
+    "llvm_revision": "337146",
+    "stages": "3",
+    "build_libcxx": true,
+    "build_type": "Release",
+    "assertions": false,
+    "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk",
+    "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
+    "lld_repo": "https://llvm.org/svn/llvm-project/lld/trunk",
+    "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
+    "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
+    "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/trunk",
+    "python_path": "/usr/bin/python2.7",
+    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
+    "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
+    "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++",
+    "as": "/builds/worker/workspace/build/src/gcc/bin/gcc"
+}
--- a/devtools/client/netmonitor/src/utils/request-utils.js
+++ b/devtools/client/netmonitor/src/utils/request-utils.js
@@ -148,78 +148,107 @@ function getAbbreviatedMimeType(mimeType
   if (!mimeType) {
     return "";
   }
   const abbrevType = (mimeType.split(";")[0].split("/")[1] || "").split("+")[0];
   return CONTENT_MIME_TYPE_ABBREVIATIONS[abbrevType] || abbrevType;
 }
 
 /**
+ * Helpers for retrieving a URL object from a string
+ *
+ * @param {string} url - unvalidated url string
+ * @return {URL} The URL object
+ */
+function getUrl(url) {
+  try {
+    return new URL(url);
+  } catch (err) {
+    return null;
+  }
+}
+
+/**
+ * Helpers for retrieving the value of a URL object property
+ *
+ * @param {string} input - unvalidated url string
+ * @param {string} string - desired property in the URL object
+ * @return {string} unicode query of a url
+ */
+function getUrlProperty(input, property) {
+  const url = getUrl(input);
+  return url && url[property] ? url[property] : "";
+}
+
+/**
  * Helpers for getting the last portion of a url.
  * For example helper returns "basename" from http://domain.com/path/basename
  * If basename portion is empty, it returns the url pathname.
  *
- * @param {string} url - url string
+ * @param {string} input - unvalidated url string
  * @return {string} unicode basename of a url
  */
 function getUrlBaseName(url) {
-  const pathname = (new URL(url)).pathname;
+  const pathname = getUrlProperty(url, "pathname");
   return getUnicodeUrlPath(
     pathname.replace(/\S*\//, "") || pathname || "/");
 }
 
 /**
  * Helpers for getting the query portion of a url.
  *
- * @param {string} url - url string
+ * @param {string} url - unvalidated url string
  * @return {string} unicode query of a url
  */
 function getUrlQuery(url) {
-  return (new URL(url)).search.replace(/^\?/, "");
+  return getUrlProperty(url, "search").replace(/^\?/, "");
 }
 
 /**
  * Helpers for getting unicode name and query portions of a url.
  *
- * @param {string} url - url string
+ * @param {string} url - unvalidated url string
  * @return {string} unicode basename and query portions of a url
  */
 function getUrlBaseNameWithQuery(url) {
-  return getUrlBaseName(url) + getUnicodeUrlPath((new URL(url)).search);
+  const basename = getUrlBaseName(url);
+  const search = getUrlProperty(url, "search");
+  return basename + getUnicodeUrlPath(search);
 }
 
 /**
  * Helpers for getting hostname portion of an URL.
  *
- * @param {string} url - url string
+ * @param {string} url - unvalidated url string
  * @return {string} unicode hostname of a url
  */
 function getUrlHostName(url) {
-  return new URL(url).hostname;
+  return getUrlProperty(url, "hostname");
 }
 
 /**
  * Helpers for getting host portion of an URL.
  *
- * @param {string} url - url string
+ * @param {string} url - unvalidated url string
  * @return {string} unicode host of a url
  */
 function getUrlHost(url) {
-  return new URL(url).host;
+  return getUrlProperty(url, "host");
 }
 
 /**
  * Helpers for getting the shceme portion of a url.
  * For example helper returns "http" from http://domain.com/path/basename
  *
- * @param {string} url - url string
+ * @param {string}  url - unvalidated url string
  * @return {string} string scheme of a url
  */
 function getUrlScheme(url) {
-  return (new URL(url)).protocol.replace(":", "").toLowerCase();
+  const protocol = getUrlProperty(url, "protocol");
+  return protocol.replace(":", "").toLowerCase();
 }
 
 /**
  * Extract several details fields from a URL at once.
  */
 function getUrlDetails(url) {
   const baseNameWithQuery = getUrlBaseNameWithQuery(url);
   let host = getUrlHost(url);
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -4141,51 +4141,16 @@ nsGlobalWindowInner::OpenDialog(JSContex
 }
 
 already_AddRefed<nsPIDOMWindowOuter>
 nsGlobalWindowInner::GetFrames(ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(GetFramesOuter, (), aError, nullptr);
 }
 
-nsGlobalWindowInner*
-nsGlobalWindowInner::CallerInnerWindow()
-{
-  JSContext *cx = nsContentUtils::GetCurrentJSContext();
-  NS_ENSURE_TRUE(cx, nullptr);
-  nsIGlobalObject* global = GetIncumbentGlobal();
-  NS_ENSURE_TRUE(global, nullptr);
-  JS::Rooted<JSObject*> scope(cx, global->GetGlobalJSObject());
-  NS_ENSURE_TRUE(scope, nullptr);
-
-  // When Jetpack runs content scripts inside a sandbox, it uses
-  // sandboxPrototype to make them appear as though they're running in the
-  // scope of the page. So when a content script invokes postMessage, it expects
-  // the |source| of the received message to be the window set as the
-  // sandboxPrototype. This used to work incidentally for unrelated reasons, but
-  // now we need to do some special handling to support it.
-  if (xpc::IsSandbox(scope)) {
-    JSAutoRealmAllowCCW ar(cx, scope);
-    JS::Rooted<JSObject*> scopeProto(cx);
-    bool ok = JS_GetPrototype(cx, scope, &scopeProto);
-    NS_ENSURE_TRUE(ok, nullptr);
-    if (scopeProto && xpc::IsSandboxPrototypeProxy(scopeProto) &&
-        (scopeProto = js::CheckedUnwrap(scopeProto, /* stopAtWindowProxy = */ false)))
-    {
-      global = xpc::NativeGlobal(scopeProto);
-      NS_ENSURE_TRUE(global, nullptr);
-    }
-  }
-
-  // The calling window must be holding a reference, so we can return a weak
-  // pointer.
-  nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(global);
-  return nsGlobalWindowInner::Cast(win);
-}
-
 void
 nsGlobalWindowInner::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
                                     const nsAString& aTargetOrigin,
                                     JS::Handle<JS::Value> aTransfer,
                                     nsIPrincipal& aSubjectPrincipal,
                                     ErrorResult& aError)
 {
   FORWARD_TO_OUTER_OR_THROW(PostMessageMozOuter,
--- a/dom/base/nsGlobalWindowInner.h
+++ b/dom/base/nsGlobalWindowInner.h
@@ -1090,17 +1090,16 @@ protected:
 
   friend class HashchangeCallback;
   friend class mozilla::dom::BarProp;
 
   // Object Management
   virtual ~nsGlobalWindowInner();
 
   void FreeInnerObjects();
-  nsGlobalWindowInner *CallerInnerWindow();
 
   // Only to be called on an inner window.
   // aDocument must not be null.
   void InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument);
 
   nsresult EnsureClientSource();
   nsresult ExecutionReady();
 
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -3099,17 +3099,16 @@ XMLHttpRequestMainThread::ReadyState() c
 void
 XMLHttpRequestMainThread::OverrideMimeType(const nsAString& aMimeType,
                                            ErrorResult& aRv)
 {
   NOT_CALLABLE_IN_SYNC_SEND_RV
 
   if (mState == XMLHttpRequest_Binding::LOADING ||
       mState == XMLHttpRequest_Binding::DONE) {
-    ResetResponse();
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_XHR_MUST_NOT_BE_LOADING_OR_DONE);
     return;
   }
 
   mOverrideMimeType = aMimeType;
 }
 
 bool
--- a/dom/xhr/XMLHttpRequestWorker.cpp
+++ b/dom/xhr/XMLHttpRequestWorker.cpp
@@ -1524,17 +1524,17 @@ SendRunnable::RunOnMainThread(ErrorResul
         MOZ_ASSERT(false, "This should never fail!");
       }
     }
   }
 }
 
 XMLHttpRequestWorker::XMLHttpRequestWorker(WorkerPrivate* aWorkerPrivate)
   : mWorkerPrivate(aWorkerPrivate)
-  , mResponseType(XMLHttpRequestResponseType::Text)
+  , mResponseType(XMLHttpRequestResponseType::_empty)
   , mTimeout(0)
   , mBackgroundRequest(false)
   , mWithCredentials(false)
   , mCanceled(false)
   , mMozAnon(false)
   , mMozSystem(false)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
--- a/dom/xhr/tests/test_xhr_overridemimetype_throws_on_invalid_state.html
+++ b/dom/xhr/tests/test_xhr_overridemimetype_throws_on_invalid_state.html
@@ -12,20 +12,20 @@ SimpleTest.waitForExplicitFinish();
 var url = "file_XHR_pass1.xml";
 
 function onWindowLoad() {
   runTest();
 }
 
 function runTest() {
   var testFunctions = [
-    function() { testOverMimeTypeThrowsDuringReadyState(3, "application/xml"); },
-    function() { testOverMimeTypeThrowsDuringReadyState(3, "application/xml;charset=Shift-JIS"); },
-    function() { testOverMimeTypeThrowsDuringReadyState(4, "application/xml"); },
-    function() { testOverMimeTypeThrowsDuringReadyState(4, "application/xml;charset=Shift-JIS"); },
+    function() { testOverMimeTypeThrowsDuringReadyState(3, "text/plain"); },
+    function() { testOverMimeTypeThrowsDuringReadyState(3, "text/plain;charset=Shift-JIS"); },
+    function() { testOverMimeTypeThrowsDuringReadyState(4, "text/plain"); },
+    function() { testOverMimeTypeThrowsDuringReadyState(4, "text/plain;charset=Shift-JIS"); },
   ];
 
   function nextTest() {
     if (testFunctions.length == 0) {
       SimpleTest.finish();
       return;
     }
     (testFunctions.shift())();
@@ -42,18 +42,19 @@ function runTest() {
           ok(false, "No exception thrown, but expected InvalidStateError" +
                     " for readyState=" + readyState + ", mimeType=" + mimeType);
         } catch(exc) {
           is(exc.name, "InvalidStateError", "Expected InvalidStateError, got " + exc.name +
                        " for readyState=" + readyState + ", mimeType=" + mimeType);
         }
       }
       if (xhr.readyState === 4) {
-        is(xhr.responseXML, null, "responseXML was not null" +
-                                  " for readyState=" + readyState + ", mimeType=" + mimeType);
+        isnot(xhr.responseXML, null, "responseXML was null" +
+                                     " for readyState=" + readyState +
+                                     ", mimeType=" + mimeType);
         nextTest();
       }
     }
     xhr.open("GET", url);
     xhr.send();
   }
 }
 </script>
--- a/dom/xhr/tests/xhr2_worker.js
+++ b/dom/xhr/tests/xhr2_worker.js
@@ -79,17 +79,17 @@ onmessage = function(event) {
   }
 
   testResponseTextException("arraybuffer");
   testResponseTextException("blob");
 
   // Make sure "document" works, but returns text.
   xhr = new XMLHttpRequest();
 
-  if (xhr.responseType != "text") {
+  if (xhr.responseType != "") {
     throw new Error("Default value for responseType is wrong!");
   }
 
   xhr.open("GET", url, false);
   xhr.responseType = "document";
   xhr.send();
 
   if (xhr.responseText != refText) {
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -51,21 +51,22 @@ gfxMacFont::gfxMacFont(const RefPtr<Unsc
 
         // Get the variation settings needed to instantiate the fontEntry
         // for a particular fontStyle.
         AutoTArray<gfxFontVariation,4> vars;
         aFontEntry->GetVariationsForStyle(vars, *aFontStyle);
 
         // Because of a Core Text bug, we need to ensure that if the font has
         // an 'opsz' axis, it is always explicitly set, and NOT to the font's
-        // default value. (See bug 1457417.)
+        // default value. (See bug 1457417, bug 1478720.)
         // We record the result of searching the font's axes in the font entry,
         // so that this only has to be done by the first instance created for
         // a given font resource.
         const uint32_t kOpszTag = HB_TAG('o','p','s','z');
+        const float kOpszFudgeAmount = 0.01f;
 
         if (!aFontEntry->mCheckedForOpszAxis) {
             aFontEntry->mCheckedForOpszAxis = true;
             AutoTArray<gfxFontVariationAxis,4> axes;
             aFontEntry->GetVariationAxes(axes);
             auto index =
                 axes.IndexOf(kOpszTag, 0, TagEquals<gfxFontVariationAxis>());
             if (index == axes.NoIndex) {
@@ -74,35 +75,35 @@ gfxMacFont::gfxMacFont(const RefPtr<Unsc
                 const auto& axis = axes[index];
                 aFontEntry->mHasOpszAxis = true;
                 aFontEntry->mOpszAxis = axis;
                 // Pick a slightly-adjusted version of the default that we'll
                 // use to work around Core Text's habit of ignoring any attempt
                 // to explicitly set the default value.
                 aFontEntry->mAdjustedDefaultOpsz =
                     axis.mDefaultValue == axis.mMinValue
-                        ? axis.mDefaultValue + 0.001f
-                        : axis.mDefaultValue - 0.001f;
+                        ? axis.mDefaultValue + kOpszFudgeAmount
+                        : axis.mDefaultValue - kOpszFudgeAmount;
             }
         }
 
         // Add 'opsz' if not present, or tweak its value if it looks too close
         // to the default (after clamping to the font's available range).
         if (aFontEntry->mHasOpszAxis) {
             auto index =
                 vars.IndexOf(kOpszTag, 0, TagEquals<gfxFontVariation>());
             if (index == vars.NoIndex) {
                 gfxFontVariation opsz{kOpszTag, aFontEntry->mAdjustedDefaultOpsz};
                 vars.AppendElement(opsz);
             } else {
                 // Figure out a "safe" value that Core Text won't ignore.
                 auto& value = vars[index].mValue;
                 auto& axis = aFontEntry->mOpszAxis;
                 value = fmin(fmax(value, axis.mMinValue), axis.mMaxValue);
-                if (std::abs(value - axis.mDefaultValue) < 0.001f) {
+                if (std::abs(value - axis.mDefaultValue) < kOpszFudgeAmount) {
                     value = aFontEntry->mAdjustedDefaultOpsz;
                 }
             }
         }
 
         mCGFont =
             UnscaledFontMac::CreateCGFontWithVariations(baseFont,
                                                         vars.Length(),
--- a/js/public/GCAnnotations.h
+++ b/js/public/GCAnnotations.h
@@ -37,21 +37,26 @@
 
 // Mark a function as something that runs a garbage collection, potentially
 // invalidating GC pointers.
 # define JS_HAZ_GC_CALL __attribute__((tag("GC Call")))
 
 // Mark an RAII class as suppressing GC within its scope.
 # define JS_HAZ_GC_SUPPRESSED __attribute__((tag("Suppress GC")))
 
+// Mark a function as one that can run script if called.  This obviously
+// subsumes JS_HAZ_GC_CALL, since anything that can run script can GC.`
+# define JS_HAZ_CAN_RUN_SCRIPT __attribute__((tag("Can run script")))
+
 #else
 
 # define JS_HAZ_GC_THING
 # define JS_HAZ_GC_POINTER
 # define JS_HAZ_ROOTED
 # define JS_HAZ_GC_INVALIDATED
 # define JS_HAZ_NON_GC_POINTER
 # define JS_HAZ_GC_CALL
 # define JS_HAZ_GC_SUPPRESSED
+# define JS_HAZ_CAN_RUN_SCRIPT
 
 #endif
 
 #endif /* js_GCAnnotations_h */
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/profiler/bug1478509.js
@@ -0,0 +1,5 @@
+// |jit-test| error: SyntaxError
+enableGeckoProfiling();
+s = newGlobal();
+evalcx("let x;", s);
+evalcx("let x;", s);
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -223,19 +223,23 @@ InterpreterFrame::prologue(JSContext* cx
         RootedObject varObjRoot(cx);
         if (script->hasNonSyntacticScope()) {
             lexicalEnv = &extensibleLexicalEnvironment();
             varObjRoot = &varObj();
         } else {
             lexicalEnv = &cx->global()->lexicalEnvironment();
             varObjRoot = cx->global();
         }
-        if (!probes::EnterScript(cx, script, nullptr, this))
+        if (!CheckGlobalDeclarationConflicts(cx, script, lexicalEnv, varObjRoot)) {
+            // Treat this as a script entry, for consistency with Ion.
+            if (script->trackRecordReplayProgress())
+                mozilla::recordreplay::AdvanceExecutionProgressCounter();
             return false;
-        return CheckGlobalDeclarationConflicts(cx, script, lexicalEnv, varObjRoot);
+        }
+        return probes::EnterScript(cx, script, nullptr, this);
     }
 
     if (isModuleFrame())
         return probes::EnterScript(cx, script, nullptr, this);
 
     // At this point, we've yet to push any environments. Check that they
     // match the enclosing scope.
     AssertScopeMatchesEnvironment(script->enclosingScope(), environmentChain());
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -6773,17 +6773,17 @@ private:
   const int32_t mAppUnitsPerDevPixel;
   AutoTArray<DisplayItemClip, 2> mClips;
   bool mDeferredPopClip;
 };
 
 
 /**
  * Returns a clip for the given |aItem|. If the clip can be simplified to not
- * include rounded rects, |aOutClip| is used to store the new clip.
+ * include rounded rects, |aOutClip| is used to store the simplified clip.
  */
 static const DisplayItemClip*
 GetItemClip(const nsDisplayItem* aItem, DisplayItemClip& aOutClip)
 {
   const DisplayItemClip& clip = aItem->GetClip();
 
   if (!clip.HasClip()) {
     return nullptr;
@@ -6794,17 +6794,17 @@ GetItemClip(const nsDisplayItem* aItem, 
     aOutClip.SetTo(clip.GetClipRect());
     return &aOutClip;
   }
 
   return &clip;
 }
 
 /**
- * Sets the clip chain and starts a new opacity group.
+ * Pushes a new opacity group for |aContext| based on |aItem|.
  */
 static void
 PushOpacity(gfxContext* aContext,
             AssignedDisplayItem& aItem)
 {
   MOZ_ASSERT(aItem.mType == DisplayItemEntryType::PUSH_OPACITY ||
              aItem.mType == DisplayItemEntryType::PUSH_OPACITY_WITH_BG);
   MOZ_ASSERT(aItem.mItem->GetType() == DisplayItemType::TYPE_OPACITY);
@@ -6813,16 +6813,20 @@ PushOpacity(gfxContext* aContext,
   const float opacity = item->GetOpacity();
   if (aItem.mType == DisplayItemEntryType::PUSH_OPACITY_WITH_BG) {
     aContext->PushGroupAndCopyBackground(gfxContentType::COLOR_ALPHA, opacity);
   } else {
     aContext->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity);
   }
 }
 
+/**
+ * Pushes the transformation matrix of |aItem| into |aMatrixStack| and sets the
+ * accumulated transform as the current transformation matrix for |aContext|.
+ */
 static void
 PushTransform(gfxContext* aContext,
               AssignedDisplayItem& aItem,
               nsDisplayListBuilder* aBuilder,
               MatrixStack4x4& aMatrixStack,
               const Matrix4x4Flagged& aBaseMatrix)
 {
   MOZ_ASSERT(aItem.mType == DisplayItemEntryType::PUSH_TRANSFORM);
@@ -6875,46 +6879,48 @@ FrameLayerBuilder::PaintItems(std::vecto
                               gfxContext *aContext,
                               nsDisplayListBuilder* aBuilder,
                               nsPresContext* aPresContext,
                               const nsIntPoint& aOffset,
                               float aXScale, float aYScale)
 {
   DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
 
-  int32_t appUnitsPerDevPixel  = aPresContext->AppUnitsPerDevPixel();
+  int32_t appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
   nsRect boundRect = ToAppUnits(aRect, appUnitsPerDevPixel);
   boundRect.MoveBy(NSIntPixelsToAppUnits(aOffset.x, appUnitsPerDevPixel),
                    NSIntPixelsToAppUnits(aOffset.y, appUnitsPerDevPixel));
   boundRect.ScaleInverseRoundOut(aXScale, aYScale);
 
 #ifdef DEBUG
   // Tracks effect nesting level. These are used to track that every effect
   // start marker has a corresponding end marker.
   int opacityLevel = 0;
   int transformLevel = 0;
 #endif
 
   // Tracks effect nesting level for skipping items between effect markers,
   // when the effect display item does not intersect with the invalidated area.
   int emptyEffectLevel = 0;
 
-  // Stores the simplified version of the clip, if needed.
+  // Stores a simplified version of the item clip, if needed.
   DisplayItemClip temporaryClip;
 
   // Two types of clips are used during PaintItems(): clips for items and clips
-  // for effects. Item clips are always at the top and they are never nested.
-  // Item clips are removed whenever an effect starts or ends.
+  // for effects. Item clips are always the most recent clip set, and they are
+  // never nested. The previous item clip is reused, if the next item has the
+  // same clip. Item clips are removed when an effect starts or ends.
   ItemClipTracker itemClipTracker(aContext, appUnitsPerDevPixel);
 
   // Since effects can be nested, the effect clips need to be nested as well.
-  // They are pushed whenever an effect start or end marker is processed.
-  // Pushing and popping possibly the same clip for each and every transform is
-  // expensive. This is why |effectClipStack| tracks the clips for effects and
-  // tries to reuse them, if consecutive effects are processed.
+  // They are pushed for effect start marker, and popped for effect end marker.
+  // Effect clips are tracked by |effectClipStack|. If there are consecutive
+  // effects with the same clip, |effectClipStack| defers popping the clip for
+  // the first end marker, and tries to reuse the previously set clip, when
+  // processing the start marker for the next effect.
   ClipStack effectClipStack(aContext, appUnitsPerDevPixel);
 
   MatrixStack4x4 matrixStack;
   const Matrix4x4Flagged base = Matrix4x4::From2D(aContext->CurrentMatrix());
 
   for (uint32_t i = 0; i < aItems.size(); ++i) {
     AssignedDisplayItem& cdi = aItems[i];
     nsDisplayItem* item = cdi.mItem;
@@ -6974,16 +6980,18 @@ FrameLayerBuilder::PaintItems(std::vecto
     if (cdi.mType != DisplayItemEntryType::ITEM) {
       // If we are processing an effect marker, remove the current item clip, if
       // there is one.
       itemClipTracker.Restore();
     }
 
     if (cdi.mType == DisplayItemEntryType::PUSH_OPACITY ||
         cdi.mType == DisplayItemEntryType::PUSH_OPACITY_WITH_BG) {
+      // To avoid pushing large temporary surfaces, it is important to clip
+      // opacity group with both the paint rect and the actual opacity clip.
       DisplayItemClip effectClip;
       effectClip.SetTo(item->GetPaintRect());
       effectClip.IntersectWith(item->GetClip());
       effectClipStack.PushClip(effectClip);
       PushOpacity(aContext, cdi);
     }
 
     if (cdi.mType == DisplayItemEntryType::POP_OPACITY) {
--- a/layout/reftests/css-invalid/default-style/reftest.list
+++ b/layout/reftests/css-invalid/default-style/reftest.list
@@ -1,5 +1,5 @@
 == input.html input-ref.html
-fuzzy-if(isDebugBuild&&gtkWidget,1,1) == button.html button-ref.html
+== button.html button-ref.html
 == textarea.html textarea-ref.html
 == select.html select-ref.html
 == fieldset.html fieldset-ref.html
--- a/layout/reftests/css-ui-invalid/default-style/reftest.list
+++ b/layout/reftests/css-ui-invalid/default-style/reftest.list
@@ -1,10 +1,10 @@
 == input.html input-ref.html
-fuzzy-if(cocoaWidget,2,32) == button.html button-ref.html
+fuzzy-if(isDebugBuild&&gtkWidget,1,1) fuzzy-if(cocoaWidget,2,32) == button.html button-ref.html
 == textarea.html textarea-ref.html
 == select.html select-ref.html
 == fieldset.html fieldset-ref.html
 == output.html output-ref.html
 random-if(winWidget) needs-focus == input-focus.html input-focus-ref.html # Intermittent failures, bug 660224
 needs-focus fuzzy-if(cocoaWidget,1,10) == button-focus.html button-focus-ref.html
 needs-focus == textarea-focus.html textarea-focus-ref.html
 random-if(winWidget) needs-focus == select-focus.html select-focus-ref.html # Intermittent failures, bug 660224
--- a/taskcluster/ci/toolchain/linux.yml
+++ b/taskcluster/ci/toolchain/linux.yml
@@ -65,16 +65,37 @@ linux64-clang-7:
         resources:
             - 'build/build-clang/build-clang.py'
             - 'build/build-clang/clang-7-pre-linux64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang.tar.xz
     toolchains:
         - linux64-gcc-4.9
 
+linux64-clang-7-mingw:
+    description: "MinGW-Clang 7 Pre toolchain build"
+    treeherder:
+        kind: build
+        platform: toolchains/opt
+        symbol: TMW(clang7p)
+        tier: 2
+    worker-type: aws-provisioner-v1/gecko-{level}-b-linux-xlarge
+    worker:
+        max-run-time: 7200
+    run:
+        using: toolchain-script
+        script: build-clang-7-pre-mingw.sh
+        resources:
+            - 'build/build-clang/build-clang.py'
+            - 'build/build-clang/clang-7-pre-mingw.json'
+            - 'taskcluster/scripts/misc/tooltool-download.sh'
+        toolchain-artifact: public/build/clangmingw.tar.xz
+    toolchains:
+        - linux64-gcc-4.9
+
 linux64-clang-6-macosx-cross:
     description: "Clang 6 toolchain build with MacOS Compiler RT libs"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(clang6-macosx-cross)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
new file mode 100755
--- /dev/null
+++ b/taskcluster/scripts/misc/build-clang-7-pre-mingw.sh
@@ -0,0 +1,292 @@
+#!/bin/bash
+set -x -e -v
+
+# This script is for building clang for Linux.
+
+WORKSPACE=$HOME/workspace
+HOME_DIR=$WORKSPACE/build
+UPLOAD_DIR=$HOME/artifacts
+
+TOOLCHAIN_DIR=$WORKSPACE/moz-toolchain
+INSTALL_DIR=$TOOLCHAIN_DIR/build/stage3/clang
+CROSS_PREFIX_DIR=$INSTALL_DIR/x86_64-w64-mingw32
+SRC_DIR=$TOOLCHAIN_DIR/src
+
+CLANG_VERSION=7.0.0
+make_flags="-j$(nproc)"
+
+mingw_version=49ca7cfe7e09f924e939921b42a3452203c437b7
+libunwind_version=86ab23972978242b6f9e27cebc239f3e8428b1af
+
+binutils_version=2.27
+binutils_ext=bz2
+binutils_sha=369737ce51587f92466041a97ab7d2358c6d9e1b6490b3940eb09fb0a9a6ac88
+
+# This is default value of _WIN32_WINNT. Gecko configure script explicitly sets this,
+# so this is not used to build Gecko itself. We default to 0x600, which is Windows Vista.
+default_win32_winnt=0x600
+
+cd $HOME_DIR/src
+
+. taskcluster/scripts/misc/tooltool-download.sh
+
+prepare() {
+  mkdir -p $TOOLCHAIN_DIR
+  touch $TOOLCHAIN_DIR/.build-clang
+
+  mkdir -p $SRC_DIR
+  pushd $SRC_DIR
+
+  git clone -n git://git.code.sf.net/p/mingw-w64/mingw-w64
+  pushd mingw-w64
+  git checkout $mingw_version
+  popd
+
+  git clone https://github.com/llvm-mirror/libunwind.git
+  pushd libunwind
+  git checkout $libunwind_version
+  popd
+
+  wget -c --progress=dot:mega ftp://ftp.gnu.org/gnu/binutils/binutils-$binutils_version.tar.$binutils_ext
+  if [ "$(sha256sum binutils-$binutils_version.tar.$binutils_ext)" != "$binutils_sha  binutils-$binutils_version.tar.$binutils_ext" ];
+  then
+    echo Corrupted binutils archive
+    exit 1
+  fi
+  tar -jxf binutils-$binutils_version.tar.$binutils_ext
+
+  popd
+}
+
+install_wrappers() {
+  pushd $INSTALL_DIR/bin
+
+  cat <<EOF >x86_64-w64-mingw32-clang
+#!/bin/sh
+DIR="\$(cd "\$(dirname "\$0")" && pwd)"
+\$DIR/clang -target x86_64-264-mingw32 --sysroot \$DIR/../x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libc++ -fuse-ld=lld -fdwarf-exceptions -Qunused-arguments "\$@"
+EOF
+  chmod +x x86_64-w64-mingw32-clang
+
+  cat <<EOF >x86_64-w64-mingw32-clang++
+#!/bin/sh
+DIR="\$(cd "\$(dirname "\$0")" && pwd)"
+\$DIR/clang -target x86_64-w64-mingw32 --sysroot \$DIR/../x86_64-w64-mingw32 --driver-mode=g++ -rtlib=compiler-rt -stdlib=libc++ -fuse-ld=lld -fdwarf-exceptions -Qunused-arguments "\$@"
+EOF
+  chmod +x x86_64-w64-mingw32-clang++
+
+  CC="x86_64-w64-mingw32-clang"
+  CXX="x86_64-w64-mingw32-clang++"
+
+  popd
+}
+
+build_mingw() {
+  mkdir mingw-w64-headers
+  pushd mingw-w64-headers
+  $SRC_DIR/mingw-w64/mingw-w64-headers/configure --host=x86_64-w64-mingw32 \
+                                                 --enable-sdk=all \
+                                                 --enable-secure-api \
+                                                 --enable-idl \
+                                                 --with-default-msvcrt=ucrt \
+                                                 --with-default-win32-winnt=$default_win32_winnt \
+                                                 --prefix=$CROSS_PREFIX_DIR
+  make $make_flags install
+  popd
+
+  mkdir mingw-w64-crt
+  pushd mingw-w64-crt
+  $SRC_DIR/mingw-w64/mingw-w64-crt/configure --host=x86_64-w64-mingw32 \
+                                             --disable-lib32 \
+                                             --enable-lib64 \
+                                             --with-default-msvcrt=ucrt \
+                                             CC="$CC" \
+                                             AR=llvm-ar \
+                                             RANLIB=llvm-ranlib \
+                                             DLLTOOL=llvm-dlltool \
+                                             --prefix=$CROSS_PREFIX_DIR
+  make $make_flags
+  make $make_flags install
+  popd
+
+  mkdir widl
+  pushd widl
+  $SRC_DIR/mingw-w64/mingw-w64-tools/widl/configure --target=x86_64-w64-mingw32 --prefix=$INSTALL_DIR
+  make $make_flags
+  make $make_flags install
+  popd
+}
+
+build_compiler_rt() {
+  mkdir compiler-rt
+  pushd compiler-rt
+  cmake \
+      -DCMAKE_BUILD_TYPE=Release \
+      -DCMAKE_C_COMPILER=$CC \
+      -DCMAKE_SYSTEM_NAME=Windows \
+      -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \
+      -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \
+      -DCMAKE_C_COMPILER_WORKS=1 \
+      -DCMAKE_C_COMPILER_TARGET=x86_64-windows-gnu \
+      -DCOMPILER_RT_DEFAULT_TARGET_ONLY=TRUE \
+      $SRC_DIR/compiler-rt/lib/builtins
+  make $make_flags
+  mkdir -p $INSTALL_DIR/lib/clang/$CLANG_VERSION/lib/windows
+  cp lib/windows/libclang_rt.builtins-x86_64.a $INSTALL_DIR/lib/clang/$CLANG_VERSION/lib/windows/
+  popd
+}
+
+merge_libs() {
+  cat <<EOF |llvm-ar -M
+CREATE tmp.a
+ADDLIB $1
+ADDLIB $2
+SAVE
+END
+EOF
+  llvm-ranlib tmp.a
+  mv tmp.a $1
+}
+
+build_libcxx() {
+  mkdir libunwind
+  pushd libunwind
+  cmake \
+      -DCMAKE_BUILD_TYPE=Release \
+      -DCMAKE_INSTALL_PREFIX=$CROSS_PREFIX_DIR \
+      -DCMAKE_C_COMPILER=$CC \
+      -DCMAKE_CXX_COMPILER=$CXX \
+      -DCMAKE_CROSSCOMPILING=TRUE \
+      -DCMAKE_SYSROOT=$CROSS_PREFIX_DIR \
+      -DCMAKE_SYSTEM_NAME=Windows \
+      -DCMAKE_C_COMPILER_WORKS=TRUE \
+      -DCMAKE_CXX_COMPILER_WORKS=TRUE \
+      -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \
+      -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \
+      -DLLVM_NO_OLD_LIBSTDCXX=TRUE \
+      -DCXX_SUPPORTS_CXX11=TRUE \
+      -DLIBUNWIND_USE_COMPILER_RT=TRUE \
+      -DLIBUNWIND_ENABLE_THREADS=TRUE \
+      -DLIBUNWIND_ENABLE_SHARED=FALSE \
+      -DLIBUNWIND_ENABLE_CROSS_UNWINDING=FALSE \
+      -DCMAKE_CXX_FLAGS="-nostdinc++ -I$SRC_DIR/libcxx/include -DPSAPI_VERSION=2" \
+      $SRC_DIR/libunwind
+  make $make_flags
+  make $make_flags install
+  popd
+
+  mkdir libcxxabi
+  pushd libcxxabi
+  cmake \
+      -DCMAKE_BUILD_TYPE=Release \
+      -DCMAKE_INSTALL_PREFIX=$CROSS_PREFIX_DIR \
+      -DCMAKE_C_COMPILER=$CC \
+      -DCMAKE_CXX_COMPILER=$CXX \
+      -DCMAKE_CROSSCOMPILING=TRUE \
+      -DCMAKE_SYSTEM_NAME=Windows \
+      -DCMAKE_C_COMPILER_WORKS=TRUE \
+      -DCMAKE_CXX_COMPILER_WORKS=TRUE \
+      -DCMAKE_SYSROOT=$CROSS_PREFIX_DIR \
+      -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \
+      -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \
+      -DLIBCXXABI_USE_COMPILER_RT=ON \
+      -DLIBCXXABI_ENABLE_EXCEPTIONS=ON \
+      -DLIBCXXABI_ENABLE_THREADS=ON \
+      -DLIBCXXABI_TARGET_TRIPLE=x86_64-w64-mingw32 \
+      -DLIBCXXABI_ENABLE_SHARED=OFF \
+      -DLIBCXXABI_LIBCXX_INCLUDES=$SRC_DIR/libcxx/include \
+      -DLLVM_NO_OLD_LIBSTDCXX=TRUE \
+      -DCXX_SUPPORTS_CXX11=TRUE \
+      -DCMAKE_CXX_FLAGS="-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D_LIBCPP_HAS_THREAD_API_WIN32" \
+      $SRC_DIR/libcxxabi
+  make $make_flags VERBOSE=1
+  popd
+
+  mkdir libcxx
+  pushd libcxx
+  cmake \
+      -DCMAKE_BUILD_TYPE=Release \
+      -DCMAKE_INSTALL_PREFIX=$CROSS_PREFIX_DIR \
+      -DCMAKE_C_COMPILER=$CC \
+      -DCMAKE_CXX_COMPILER=$CXX \
+      -DCMAKE_CROSSCOMPILING=TRUE \
+      -DCMAKE_SYSTEM_NAME=Windows \
+      -DCMAKE_C_COMPILER_WORKS=TRUE \
+      -DCMAKE_CXX_COMPILER_WORKS=TRUE \
+      -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \
+      -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \
+      -DLIBCXX_USE_COMPILER_RT=ON \
+      -DLIBCXX_INSTALL_HEADERS=ON \
+      -DLIBCXX_ENABLE_EXCEPTIONS=ON \
+      -DLIBCXX_ENABLE_THREADS=ON \
+      -DLIBCXX_HAS_WIN32_THREAD_API=ON \
+      -DLIBCXX_ENABLE_MONOTONIC_CLOCK=ON \
+      -DLIBCXX_ENABLE_SHARED=OFF \
+      -DLIBCXX_SUPPORTS_STD_EQ_CXX11_FLAG=TRUE \
+      -DLIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB=TRUE \
+      -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF \
+      -DLIBCXX_ENABLE_FILESYSTEM=OFF \
+      -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=TRUE \
+      -DLIBCXX_CXX_ABI=libcxxabi \
+      -DLIBCXX_CXX_ABI_INCLUDE_PATHS=$SRC_DIR/libcxxabi/include \
+      -DLIBCXX_CXX_ABI_LIBRARY_PATH=../libcxxabi/lib \
+      -DCMAKE_CXX_FLAGS="-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS" \
+      $SRC_DIR/libcxx
+  make $make_flags VERBOSE=1
+  make $make_flags install
+
+  # libc++.a depends on libunwind.a. Whild linker will automatically link
+  # to libc++.a in C++ mode, it won't pick libunwind.a, requiring caller
+  # to explicitly pass -lunwind. Wo work around that, we merge libunwind.a
+  # into libc++.a.
+  merge_libs $CROSS_PREFIX_DIR/lib/libc++.a $CROSS_PREFIX_DIR/lib/libunwind.a
+  popd
+}
+
+build_windres() {
+  # we build whole binutils, but use only windres in our toolchain
+  mkdir binutils
+  pushd binutils
+  $SRC_DIR/binutils-$binutils_version/configure --prefix=$INSTALL_DIR \
+                                                --disable-multilib \
+                                                --disable-nls \
+                                                --target=x86_64-w64-mingw32
+  make $make_flags
+
+  # Manually install only nm and windres
+  cp binutils/windres $INSTALL_DIR/bin/x86_64-w64-mingw32-windres
+  cp binutils/nm-new $INSTALL_DIR/bin/x86_64-w64-mingw32-nm
+  popd
+}
+
+export PATH=$INSTALL_DIR/bin:$PATH
+
+prepare
+
+# gets a bit too verbose here
+set +x
+
+cd build/build-clang
+# |mach python| sets up a virtualenv for us!
+../../mach python ./build-clang.py -c clang-7-pre-mingw.json --skip-tar
+
+set -x
+
+pushd $TOOLCHAIN_DIR/build
+
+install_wrappers
+build_mingw
+build_compiler_rt
+build_libcxx
+build_windres
+
+popd
+
+# Put a tarball in the artifacts dir
+mkdir -p $UPLOAD_DIR
+
+pushd $(dirname $INSTALL_DIR)
+rm -f clang/lib/libstdc++*
+tar caf clangmingw.tar.xz clang
+mv clangmingw.tar.xz $UPLOAD_DIR
+popd
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -389436,19 +389436,23 @@
     ]
    ],
    "xhr/overridemimetype-blob.html": [
     [
      "/xhr/overridemimetype-blob.html",
      {}
     ]
    ],
-   "xhr/overridemimetype-done-state.htm": [
-    [
-     "/xhr/overridemimetype-done-state.htm",
+   "xhr/overridemimetype-done-state.any.js": [
+    [
+     "/xhr/overridemimetype-done-state.any.html",
+     {}
+    ],
+    [
+     "/xhr/overridemimetype-done-state.any.worker.html",
      {}
     ]
    ],
    "xhr/overridemimetype-edge-cases.window.js": [
     [
      "/xhr/overridemimetype-edge-cases.window.html",
      {}
     ]
@@ -389588,19 +389592,23 @@
     ]
    ],
    "xhr/responsetext-decoding.htm": [
     [
      "/xhr/responsetext-decoding.htm",
      {}
     ]
    ],
-   "xhr/responsetype.html": [
-    [
-     "/xhr/responsetype.html",
+   "xhr/responsetype.any.js": [
+    [
+     "/xhr/responsetype.any.html",
+     {}
+    ],
+    [
+     "/xhr/responsetype.any.worker.html",
      {}
     ]
    ],
    "xhr/responseurl.html": [
     [
      "/xhr/responseurl.html",
      {}
     ]
@@ -633253,18 +633261,18 @@
   "xhr/open-user-password-non-same-origin.htm": [
    "9e28bf35af12bb962fdfd2213d7e20e031a29703",
    "testharness"
   ],
   "xhr/overridemimetype-blob.html": [
    "38a7f6e2871ac0def651e5b82bb8a43b061633bb",
    "testharness"
   ],
-  "xhr/overridemimetype-done-state.htm": [
-   "167f34f8dfc1312a9124c12ee4f8de808fa41680",
+  "xhr/overridemimetype-done-state.any.js": [
+   "5924cec26f0bf551a7d37969a62941fc88c177f1",
    "testharness"
   ],
   "xhr/overridemimetype-edge-cases.window.js": [
    "a76e1c81a86823765be280747d2fa6994395cc25",
    "testharness"
   ],
   "xhr/overridemimetype-headers-received-state-force-shiftjis.htm": [
    "92a00af686310d8b44fb5e4c70cc6fbea28e0a88",
@@ -633741,18 +633749,18 @@
   "xhr/responsedocument-decoding.htm": [
    "ab52417826b3953b71b5f6037ebd616d4b862ad4",
    "testharness"
   ],
   "xhr/responsetext-decoding.htm": [
    "d08dd5c1d0b21b639389dfc1deec65215b3334dc",
    "testharness"
   ],
-  "xhr/responsetype.html": [
-   "090ae5981aed9e0ed5e5f8a2f5615d57df0c366b",
+  "xhr/responsetype.any.js": [
+   "eda46254f0b786635b91fdd7f2b63992f2f9ad5d",
    "testharness"
   ],
   "xhr/responseurl.html": [
    "b7ac10fed9c8a07afcd13f1d4906e10996ae56c6",
    "testharness"
   ],
   "xhr/responsexml-basic.htm": [
    "962765bd28850b740b0945d08f31fd94c8883191",
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/xhr/responsetype.any.js.ini
@@ -0,0 +1,16 @@
+[responsetype.any.worker.html]
+  [Set responseType to "" when readyState is HEADERS_RECEIVED.]
+    expected: FAIL
+
+  [Set responseType to "json" when readyState is HEADERS_RECEIVED.]
+    expected: FAIL
+
+  [Set responseType to "arraybuffer" when readyState is HEADERS_RECEIVED.]
+    expected: FAIL
+
+  [Set responseType to "blob" when readyState is HEADERS_RECEIVED.]
+    expected: FAIL
+
+  [Set responseType to "text" when readyState is HEADERS_RECEIVED.]
+    expected: FAIL
+
rename from testing/web-platform/tests/xhr/overridemimetype-done-state.htm
rename to testing/web-platform/tests/xhr/overridemimetype-done-state.any.js
--- a/testing/web-platform/tests/xhr/overridemimetype-done-state.htm
+++ b/testing/web-platform/tests/xhr/overridemimetype-done-state.any.js
@@ -1,26 +1,20 @@
-<!doctype html>
-<html>
-  <head>
-    <title>XMLHttpRequest: overrideMimeType() in DONE state</title>
-    <meta charset="utf-8">
-    <script src="/resources/testharness.js"></script>
-    <script src="/resources/testharnessreport.js"></script>
-    <link rel="help" href="https://xhr.spec.whatwg.org/#the-overridemimetype()-method" data-tested-assertations="/following::ol/li[1]" />
-  </head>
-  <body>
-    <div id="log"></div>
-    <script>
-      var test = async_test();
-      var client = new XMLHttpRequest();
-      client.onreadystatechange = test.step_func( function() {
-        if (client.readyState !== 4) return;
-        assert_throws("InvalidStateError", function() { client.overrideMimeType('application/xml;charset=Shift-JIS'); });
-        assert_equals(client.responseXML, null);
-        test.done();
-      });
-      client.open("GET", "resources/status.py?type="+encodeURIComponent('text/plain;charset=iso-8859-1')+'&content=%3Cmsg%3E%83%65%83%58%83%67%3C%2Fmsg%3E');
-      client.send();
-    </script>
+// META title= XMLHttpRequest: overrideMimeType() in DONE state</title>
 
-  </body>
-</html>
+/**
+ * Spec: <https://xhr.spec.whatwg.org/#the-overridemimetype()-method>; data-tested-assertations="/following::ol/li[1]"
+ */
+var test = async_test();
+var client = new XMLHttpRequest();
+client.onreadystatechange = test.step_func( function() {
+  if (client.readyState !== 4) return;
+  var text = client.responseText;
+  assert_not_equals(text, "");
+  assert_throws("InvalidStateError", function() { client.overrideMimeType('application/xml;charset=Shift-JIS'); });
+  if (GLOBAL.isWindow()) {
+    assert_equals(client.responseXML, null);
+  }
+  assert_equals(client.responseText, text);
+  test.done();
+});
+client.open("GET", "resources/status.py?type="+encodeURIComponent('text/plain;charset=iso-8859-1')+'&content=%3Cmsg%3E%83%65%83%58%83%67%3C%2Fmsg%3E');
+client.send();
rename from testing/web-platform/tests/xhr/responsetype.html
rename to testing/web-platform/tests/xhr/responsetype.any.js
--- a/testing/web-platform/tests/xhr/responsetype.html
+++ b/testing/web-platform/tests/xhr/responsetype.any.js
@@ -1,96 +1,135 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>XMLHttpRequest.responseType</title>
-<link rel="author" title="Mathias Bynens" href="http://mathiasbynens.be/">
-<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
-<link rel="help" href="https://xhr.spec.whatwg.org/#the-responsetype-attribute">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<div id="log"></div>
-<script>
+// META: title=XMLHttpRequest.responseType
+
+/**
+ * Author: Mathias Bynens <http://mathiasbynens.be/>
+ * Author: Ms2ger <mailto:Ms2ger@gmail.com>
+ *
+ * Spec: <https://xhr.spec.whatwg.org/#the-responsetype-attribute>
+ */
 test(function() {
   var xhr = new XMLHttpRequest();
   assert_equals(xhr.responseType, '');
 }, 'Initial value of responseType');
 
-var types = ['', 'json', 'document', 'arraybuffer', 'blob', 'text'];
+var types = ['', 'json', 'document', 'arraybuffer', 'blob', 'text', "nosuchtype"];
+
+function isIgnoredType(type) {
+  if (type == "nosuchtype") {
+    return true;
+  }
+
+  if (type != "document") {
+    return false;
+  }
+
+  // "document" is ignored only on workers.
+  return GLOBAL.isWorker();
+}
+
+function expectedType(type) {
+  if (!isIgnoredType(type)) {
+    return type;
+  }
+
+  return "";
+}
+
 types.forEach(function(type) {
   test(function() {
     var xhr = new XMLHttpRequest();
     xhr.responseType = type;
-    assert_equals(xhr.responseType, type);
+    assert_equals(xhr.responseType, expectedType(type));
   }, 'Set responseType to ' + format_value(type) + ' when readyState is UNSENT.');
 
   test(function() {
     var xhr = new XMLHttpRequest();
     xhr.open('get', '/');
     xhr.responseType = type;
-    assert_equals(xhr.responseType, type);
+    assert_equals(xhr.responseType, expectedType(type));
   }, 'Set responseType to ' + format_value(type) + ' when readyState is OPENED.');
 
   async_test(function() {
     var xhr = new XMLHttpRequest();
     xhr.open('get', '/');
     xhr.onreadystatechange = this.step_func(function() {
       if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
         xhr.responseType = type;
-        assert_equals(xhr.responseType, type);
+        assert_equals(xhr.responseType, expectedType(type));
         this.done();
       }
     });
     xhr.send();
   }, 'Set responseType to ' + format_value(type) + ' when readyState is HEADERS_RECEIVED.');
 
   async_test(function() {
     var xhr = new XMLHttpRequest();
     xhr.open('get', '/');
     xhr.onreadystatechange = this.step_func(function() {
       if (xhr.readyState === XMLHttpRequest.LOADING) {
-        assert_throws("InvalidStateError", function() {
+        if (isIgnoredType(type)) {
           xhr.responseType = type;
-        });
+        } else {
+          assert_throws("InvalidStateError", function() {
+            xhr.responseType = type;
+          });
+        }
         assert_equals(xhr.responseType, "");
         this.done();
       }
     });
     xhr.send();
   }, 'Set responseType to ' + format_value(type) + ' when readyState is LOADING.');
 
   async_test(function() {
     var xhr = new XMLHttpRequest();
     xhr.open('get', '/');
     xhr.onreadystatechange = this.step_func(function() {
       if (xhr.readyState === XMLHttpRequest.DONE) {
-        assert_throws("InvalidStateError", function() {
+        var text = xhr.responseText;
+        assert_not_equals(text, "");
+        if (isIgnoredType(type)) {
           xhr.responseType = type;
-        });
+        } else {
+          assert_throws("InvalidStateError", function() {
+            xhr.responseType = type;
+          });
+        }
         assert_equals(xhr.responseType, "");
+        assert_equals(xhr.responseText, text);
         this.done();
       }
     });
     xhr.send();
   }, 'Set responseType to ' + format_value(type) + ' when readyState is DONE.');
 
   // Note: the case of setting responseType first, and then calling synchronous
   // open(), is tested in open-method-responsetype-set-sync.htm.
   test(function() {
     var xhr = new XMLHttpRequest();
     xhr.open('get', '/', false);
-    assert_throws("InvalidAccessError", function() {
+    if (GLOBAL.isWorker() || isIgnoredType(type)) {
+      // Setting responseType on workers is valid even for a sync XHR.
       xhr.responseType = type;
-    });
-    assert_equals(xhr.responseType, "");
+      assert_equals(xhr.responseType, expectedType(type));
+    } else {
+      assert_throws("InvalidAccessError", function() {
+        xhr.responseType = type;
+      });
+    }
   }, 'Set responseType to ' + format_value(type) + ' when readyState is OPENED and the sync flag is set.');
 
   test(function() {
     var xhr = new XMLHttpRequest();
     xhr.open('get', '/', false);
     xhr.send();
     assert_equals(xhr.readyState, XMLHttpRequest.DONE);
-    assert_throws("InvalidStateError", function() {
+    if (isIgnoredType(type)) {
       xhr.responseType = type;
-    });
+    } else {
+      assert_throws("InvalidStateError", function() {
+        xhr.responseType = type;
+      });
+    }
     assert_equals(xhr.responseType, "");
   }, 'Set responseType to ' + format_value(type) + ' when readyState is DONE and the sync flag is set.');
 });
-</script>
--- a/toolkit/content/aboutTelemetry.js
+++ b/toolkit/content/aboutTelemetry.js
@@ -6,17 +6,16 @@
 
 ChromeUtils.import("resource://gre/modules/BrowserUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/TelemetryTimestamps.jsm");
 ChromeUtils.import("resource://gre/modules/TelemetryController.jsm");
 ChromeUtils.import("resource://gre/modules/TelemetryArchive.jsm");
 ChromeUtils.import("resource://gre/modules/TelemetryUtils.jsm");
 ChromeUtils.import("resource://gre/modules/TelemetrySend.jsm");
-ChromeUtils.import("resource://gre/modules/Preferences.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 ChromeUtils.defineModuleGetter(this, "AppConstants",
                                "resource://gre/modules/AppConstants.jsm");
 ChromeUtils.defineModuleGetter(this, "Preferences",
                                "resource://gre/modules/Preferences.jsm");
 
 const Telemetry = Services.telemetry;
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -318,33 +318,16 @@ AndroidBridge::GetClipboardText(nsAStrin
 
     if (text) {
         aText = text->ToString();
     }
     return !!text;
 }
 
 int
-AndroidBridge::GetDPI()
-{
-    static int sDPI = 0;
-    if (sDPI)
-        return sDPI;
-
-    const int DEFAULT_DPI = 160;
-
-    sDPI = GeckoAppShell::GetDpi();
-    if (!sDPI) {
-        return DEFAULT_DPI;
-    }
-
-    return sDPI;
-}
-
-int
 AndroidBridge::GetScreenDepth()
 {
     ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
 
     static int sDepth = 0;
     if (sDepth)
         return sDepth;
 
@@ -353,16 +336,17 @@ AndroidBridge::GetScreenDepth()
     if (jni::IsAvailable()) {
         sDepth = GeckoAppShell::GetScreenDepth();
     }
     if (!sDepth)
         return DEFAULT_DEPTH;
 
     return sDepth;
 }
+
 void
 AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern)
 {
     ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
 
     uint32_t len = aPattern.Length();
     if (!len) {
         ALOG_BRIDGE("  invalid 0-length array");
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -111,17 +111,16 @@ public:
     bool GetHWEncoderCapability();
     bool GetHWDecoderCapability();
 
     void GetMimeTypeFromExtensions(const nsACString& aFileExt, nsCString& aMimeType);
     void GetExtensionFromMimeType(const nsACString& aMimeType, nsACString& aFileExt);
 
     bool GetClipboardText(nsAString& aText);
 
-    int GetDPI();
     int GetScreenDepth();
 
     void Vibrate(const nsTArray<uint32_t>& aPattern);
 
     void GetSystemColors(AndroidSystemColors *aColors);
 
     void GetIconForExtension(const nsACString& aFileExt, uint32_t aIconSize, uint8_t * const aBuf);
 
new file mode 100644
--- /dev/null
+++ b/widget/android/ScreenHelperAndroid.cpp
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=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/. */
+
+#include "ScreenHelperAndroid.h"
+#include "AndroidRect.h"
+#include "GeneratedJNINatives.h"
+#include "nsThreadUtils.h"
+
+#include <mozilla/jni/Refs.h>
+
+#include "mozilla/widget/ScreenManager.h"
+
+using namespace mozilla;
+using namespace mozilla::java;
+using namespace mozilla::widget;
+
+static already_AddRefed<Screen>
+MakePrimaryScreen() {
+    MOZ_ASSERT(XRE_IsParentProcess());
+    if (!jni::IsAvailable()) {
+        return nullptr;
+    }
+
+    java::sdk::Rect::LocalRef rect = GeckoAppShell::GetScreenSize();
+    LayoutDeviceIntRect bounds = LayoutDeviceIntRect(rect->Left(), rect->Top(),
+                                                     rect->Width(), rect->Height());
+    uint32_t depth = GeckoAppShell::GetScreenDepth();
+    float density = GeckoAppShell::GetDensity();
+    float dpi = GeckoAppShell::GetDpi();
+    RefPtr<Screen> screen = new Screen(bounds, bounds, depth, depth,
+                      DesktopToLayoutDeviceScale(density),
+                      CSSToLayoutDeviceScale(1.0f),
+                      dpi);
+    return screen.forget();
+}
+
+void
+ScreenHelperAndroid::Refresh() {
+    AutoTArray<RefPtr<Screen>, 1> screenList;
+    RefPtr<Screen> screen = MakePrimaryScreen();
+    if (screen) {
+        screenList.AppendElement(screen);
+    }
+
+    ScreenManager& manager = ScreenManager::GetSingleton();
+    manager.Refresh(std::move(screenList));
+}
new file mode 100644
--- /dev/null
+++ b/widget/android/ScreenHelperAndroid.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * 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/. */
+
+#ifndef ScreenHelperAndroid_h___
+#define ScreenHelperAndroid_h___
+
+#include "mozilla/widget/ScreenManager.h"
+
+class ScreenHelperAndroid final : public mozilla::widget::ScreenManager::Helper
+{
+public:
+    ScreenHelperAndroid() {
+        Refresh();
+    }
+
+    ~ScreenHelperAndroid() {
+    }
+
+    void Refresh();
+};
+
+#endif /* ScreenHelperAndroid_h___ */
--- a/widget/android/moz.build
+++ b/widget/android/moz.build
@@ -53,19 +53,19 @@ UNIFIED_SOURCES += [
     'nsAndroidProtocolHandler.cpp',
     'nsAppShell.cpp',
     'nsClipboard.cpp',
     'nsDeviceContextAndroid.cpp',
     'nsIdleServiceAndroid.cpp',
     'nsLookAndFeel.cpp',
     'nsNativeThemeAndroid.cpp',
     'nsPrintSettingsServiceAndroid.cpp',
-    'nsScreenManagerAndroid.cpp',
     'nsWidgetFactory.cpp',
     'nsWindow.cpp',
+    'ScreenHelperAndroid.cpp',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 # The recursive make backend treats the first output specially: it's passed as
 # an open FileAvoidWrite to the invoked script.  That doesn't work well with
 # the Gradle task that generates all of the outputs, so we add a dummy first
 # output.
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -33,16 +33,17 @@
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Services.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Hal.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/intl/OSPreferences.h"
+#include "mozilla/widget/ScreenManager.h"
 #include "prenv.h"
 
 #include "AndroidBridge.h"
 #include "AndroidBridgeUtilities.h"
 #include "GeneratedJNINatives.h"
 #include <android/log.h>
 #include <pthread.h>
 #include <wchar.h>
@@ -65,24 +66,26 @@
 #include "GeckoNetworkManager.h"
 #include "GeckoProcessManager.h"
 #include "GeckoScreenOrientation.h"
 #include "GeckoVRManager.h"
 #include "PrefsHelper.h"
 #include "fennec/MemoryMonitor.h"
 #include "fennec/Telemetry.h"
 #include "fennec/ThumbnailHelper.h"
+#include "ScreenHelperAndroid.h"
 
 #ifdef DEBUG_ANDROID_EVENTS
 #define EVLOG(args...)  ALOG(args)
 #else
 #define EVLOG(args...) do { } while (0)
 #endif
 
 using namespace mozilla;
+using namespace mozilla::widget;
 
 nsIGeolocationUpdate *gLocationCallback = nullptr;
 
 nsAppShell* nsAppShell::sAppShell;
 StaticAutoPtr<Mutex> nsAppShell::sAppShellLock;
 
 uint32_t nsAppShell::Queue::sLatencyCount[];
 uint64_t nsAppShell::Queue::sLatencyTime[];
@@ -410,16 +413,20 @@ nsAppShell::nsAppShell()
             GeckoAppShellSupport::Init();
 
             // Set the corresponding state in GeckoThread.
             java::GeckoThread::SetState(java::GeckoThread::State::RUNNING());
         }
         return;
     }
 
+
+    ScreenManager& screenManager = ScreenManager::GetSingleton();
+    screenManager.SetHelper(mozilla::MakeUnique<ScreenHelperAndroid>());
+
     if (jni::IsAvailable()) {
         // Initialize JNI and Set the corresponding state in GeckoThread.
         AndroidBridge::ConstructBridge();
         GeckoAppShellSupport::Init();
         GeckoThreadSupport::Init();
         mozilla::GeckoBatteryManager::Init();
         mozilla::GeckoNetworkManager::Init();
         mozilla::GeckoProcessManager::Init();
deleted file mode 100644
--- a/widget/android/nsScreenManagerAndroid.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set sw=4 ts=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/. */
-
-#define MOZ_FATAL_ASSERTIONS_FOR_THREAD_SAFETY
-
-#include "mozilla/SyncRunnable.h"
-#include "nsScreenManagerAndroid.h"
-#include "nsServiceManagerUtils.h"
-#include "AndroidRect.h"
-#include "GeneratedJNINatives.h"
-#include "nsAppShell.h"
-#include "nsThreadUtils.h"
-
-#include <android/log.h>
-#include <mozilla/jni/Refs.h>
-
-#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "nsScreenManagerAndroid", ## args)
-
-using namespace mozilla;
-using namespace mozilla::java;
-
-static uint32_t sScreenId = 0;
-const uint32_t PRIMARY_SCREEN_ID = 0;
-
-nsScreenAndroid::nsScreenAndroid(DisplayType aDisplayType, nsIntRect aRect)
-    : mId(sScreenId++)
-    , mDisplayType(aDisplayType)
-    , mRect(aRect)
-    , mDensity(0.0)
-{
-    // ensure that the ID of the primary screen would be PRIMARY_SCREEN_ID.
-    if (mDisplayType == DisplayType::DISPLAY_PRIMARY) {
-        mId = PRIMARY_SCREEN_ID;
-    }
-}
-
-nsScreenAndroid::~nsScreenAndroid()
-{
-}
-
-float
-nsScreenAndroid::GetDensity() {
-    if (mDensity != 0.0) {
-        return mDensity;
-    }
-    if (mDisplayType == DisplayType::DISPLAY_PRIMARY) {
-        mDensity = mozilla::jni::IsAvailable() ? GeckoAppShell::GetDensity()
-                                               : 1.0; // xpcshell most likely
-        return mDensity;
-    }
-    return 1.0;
-}
-
-NS_IMETHODIMP
-nsScreenAndroid::GetRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight)
-{
-    if (mDisplayType != DisplayType::DISPLAY_PRIMARY) {
-        *outLeft   = mRect.x;
-        *outTop    = mRect.y;
-        *outWidth  = mRect.width;
-        *outHeight = mRect.height;
-
-        return NS_OK;
-    }
-
-    if (!mozilla::jni::IsAvailable()) {
-      // xpcshell most likely
-      *outLeft = *outTop = *outWidth = *outHeight = 0;
-      return NS_ERROR_FAILURE;
-    }
-
-    java::sdk::Rect::LocalRef rect = java::GeckoAppShell::GetScreenSize();
-    *outLeft = rect->Left();
-    *outTop = rect->Top();
-    *outWidth = rect->Width();
-    *outHeight = rect->Height();
-
-    return NS_OK;
-}
-
-
-NS_IMETHODIMP
-nsScreenAndroid::GetAvailRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight)
-{
-    return GetRect(outLeft, outTop, outWidth, outHeight);
-}
-
-
-
-NS_IMETHODIMP
-nsScreenAndroid::GetPixelDepth(int32_t *aPixelDepth)
-{
-    if (!mozilla::jni::IsAvailable()) {
-      // xpcshell most likely
-      *aPixelDepth = 16;
-      return NS_ERROR_FAILURE;
-    }
-
-    *aPixelDepth = java::GeckoAppShell::GetScreenDepth();
-    return NS_OK;
-}
-
-
-NS_IMETHODIMP
-nsScreenAndroid::GetColorDepth(int32_t *aColorDepth)
-{
-    return GetPixelDepth(aColorDepth);
-}
-
-class nsScreenManagerAndroid::ScreenManagerHelperSupport final
-    : public ScreenManagerHelper::Natives<ScreenManagerHelperSupport>
-{
-public:
-    typedef ScreenManagerHelper::Natives<ScreenManagerHelperSupport> Base;
-
-    static int32_t AddDisplay(int32_t aDisplayType, int32_t aWidth, int32_t aHeight, float aDensity) {
-        int32_t screenId = -1; // return value
-        nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
-        SyncRunnable::DispatchToThread(mainThread, NS_NewRunnableFunction(
-            "nsScreenManagerAndroid::ScreenManagerHelperSupport::AddDisplay",
-            [&aDisplayType, &aWidth, &aHeight, &aDensity, &screenId] {
-                MOZ_ASSERT(NS_IsMainThread());
-                nsCOMPtr<nsIScreenManager> screenMgr =
-                do_GetService("@mozilla.org/gfx/screenmanager;1");
-                MOZ_ASSERT(screenMgr, "Failed to get nsIScreenManager");
-
-                RefPtr<nsScreenManagerAndroid> screenMgrAndroid =
-                (nsScreenManagerAndroid*) screenMgr.get();
-                RefPtr<nsScreenAndroid> screen =
-                screenMgrAndroid->AddScreen(static_cast<DisplayType>(aDisplayType),
-                                            nsIntRect(0, 0, aWidth, aHeight));
-                MOZ_ASSERT(screen);
-                screen->SetDensity(aDensity);
-                screenId = static_cast<int32_t>(screen->GetId());
-            }).take());
-        return screenId;
-    }
-
-    static void RemoveDisplay(int32_t aScreenId) {
-        nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
-        SyncRunnable::DispatchToThread(mainThread, NS_NewRunnableFunction(
-            "nsScreenManagerAndroid::ScreenManagerHelperSupport::RemoveDisplay",
-            [&aScreenId] {
-                MOZ_ASSERT(NS_IsMainThread());
-                nsCOMPtr<nsIScreenManager> screenMgr =
-                    do_GetService("@mozilla.org/gfx/screenmanager;1");
-                MOZ_ASSERT(screenMgr, "Failed to get nsIScreenManager");
-
-                RefPtr<nsScreenManagerAndroid> screenMgrAndroid =
-                    (nsScreenManagerAndroid*) screenMgr.get();
-                screenMgrAndroid->RemoveScreen(aScreenId);
-            }).take());
-    }
-};
-
-NS_IMPL_ISUPPORTS(nsScreenManagerAndroid, nsIScreenManager)
-
-nsScreenManagerAndroid::nsScreenManagerAndroid()
-{
-    if (mozilla::jni::IsAvailable()) {
-        ScreenManagerHelperSupport::Base::Init();
-    }
-    nsCOMPtr<nsIScreen> screen = AddScreen(DisplayType::DISPLAY_PRIMARY);
-    MOZ_ASSERT(screen);
-}
-
-nsScreenManagerAndroid::~nsScreenManagerAndroid()
-{
-}
-
-NS_IMETHODIMP
-nsScreenManagerAndroid::GetPrimaryScreen(nsIScreen **outScreen)
-{
-    RefPtr<nsScreenAndroid> screen = ScreenForId(PRIMARY_SCREEN_ID);
-    if (screen) {
-        screen.forget(outScreen);
-    }
-    return NS_OK;
-}
-
-already_AddRefed<nsScreenAndroid>
-nsScreenManagerAndroid::ScreenForId(uint32_t aId)
-{
-    for (size_t i = 0; i < mScreens.Length(); ++i) {
-        if (aId == mScreens[i]->GetId()) {
-            RefPtr<nsScreenAndroid> screen = mScreens[i];
-            return screen.forget();
-        }
-    }
-
-    return nullptr;
-}
-
-NS_IMETHODIMP
-nsScreenManagerAndroid::ScreenForRect(int32_t inLeft,
-                                      int32_t inTop,
-                                      int32_t inWidth,
-                                      int32_t inHeight,
-                                      nsIScreen **outScreen)
-{
-    // Not support to query non-primary screen with rect.
-    return GetPrimaryScreen(outScreen);
-}
-
-already_AddRefed<nsScreenAndroid>
-nsScreenManagerAndroid::AddScreen(DisplayType aDisplayType, nsIntRect aRect)
-{
-    ALOG("nsScreenManagerAndroid: add %s screen",
-        (aDisplayType == DisplayType::DISPLAY_PRIMARY  ? "PRIMARY"  :
-        (aDisplayType == DisplayType::DISPLAY_EXTERNAL ? "EXTERNAL" :
-                                                         "VIRTUAL")));
-    RefPtr<nsScreenAndroid> screen = new nsScreenAndroid(aDisplayType, aRect);
-    mScreens.AppendElement(screen);
-    return screen.forget();
-}
-
-void
-nsScreenManagerAndroid::RemoveScreen(uint32_t aScreenId)
-{
-    for (size_t i = 0; i < mScreens.Length(); i++) {
-        if (aScreenId == mScreens[i]->GetId()) {
-            mScreens.RemoveElementAt(i);
-        }
-    }
-}
deleted file mode 100644
--- a/widget/android/nsScreenManagerAndroid.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * 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/. */
-
-#ifndef nsScreenManagerAndroid_h___
-#define nsScreenManagerAndroid_h___
-
-#include "nsCOMPtr.h"
-
-#include "nsBaseScreen.h"
-#include "nsIScreenManager.h"
-#include "nsRect.h"
-#include "mozilla/WidgetUtils.h"
-
-class nsScreenAndroid final : public nsBaseScreen
-{
-public:
-    nsScreenAndroid(DisplayType aDisplayType, nsIntRect aRect);
-    ~nsScreenAndroid();
-
-    NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override;
-    NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight) override;
-    NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override;
-    NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override;
-
-    uint32_t GetId() const { return mId; };
-    DisplayType GetDisplayType() const { return mDisplayType; }
-
-    void SetDensity(double aDensity) { mDensity = aDensity; }
-    float GetDensity();
-
-private:
-    uint32_t mId;
-    DisplayType mDisplayType;
-    nsIntRect mRect;
-    float mDensity;
-};
-
-class nsScreenManagerAndroid final : public nsIScreenManager
-{
-private:
-    ~nsScreenManagerAndroid();
-
-public:
-    class ScreenManagerHelperSupport;
-
-    nsScreenManagerAndroid();
-
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSISCREENMANAGER
-
-    already_AddRefed<nsScreenAndroid> ScreenForId(uint32_t aId);
-    already_AddRefed<nsScreenAndroid> AddScreen(DisplayType aDisplayType,
-                                                nsIntRect aRect = nsIntRect());
-    void RemoveScreen(uint32_t aScreenId);
-
-protected:
-    nsTArray<RefPtr<nsScreenAndroid>> mScreens;
-};
-
-#endif /* nsScreenManagerAndroid_h___ */
--- a/widget/android/nsWidgetFactory.cpp
+++ b/widget/android/nsWidgetFactory.cpp
@@ -9,35 +9,39 @@
 #include "nsCOMPtr.h"
 #include "nsWidgetsCID.h"
 #include "nsAppShell.h"
 #include "AndroidBridge.h"
 
 #include "nsWindow.h"
 #include "nsLookAndFeel.h"
 #include "nsAppShellSingleton.h"
-#include "nsScreenManagerAndroid.h"
 
 #include "nsIdleServiceAndroid.h"
 #include "nsClipboard.h"
 #include "nsClipboardHelper.h"
 #include "nsTransferable.h"
 #include "nsPrintSession.h"
 #include "nsPrintSettingsServiceAndroid.h"
 #include "nsDeviceContextAndroid.h"
 #include "nsHTMLFormatConverter.h"
 #include "nsXULAppAPI.h"
 #include "nsAndroidProtocolHandler.h"
 
 #include "nsToolkitCompsCID.h"
 #include "AndroidAlerts.h"
 #include "nsNativeThemeAndroid.h"
 
+#include "mozilla/widget/ScreenManager.h"
+
+using namespace mozilla;
+using namespace mozilla::widget;
+
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerAndroid)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ScreenManager, ScreenManager::GetAddRefedSingleton)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceAndroid, nsIdleServiceAndroid::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSettingsServiceAndroid, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecAndroid)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
@@ -90,17 +94,18 @@ NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
 NS_DEFINE_NAMED_CID(NS_ANDROIDBRIDGE_CID);
 NS_DEFINE_NAMED_CID(NS_ANDROIDPROTOCOLHANDLER_CID);
 NS_DEFINE_NAMED_CID(NS_SYSTEMALERTSSERVICE_CID);
 
 static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
   { &kNS_WINDOW_CID, false, nullptr, nsWindowConstructor },
   { &kNS_CHILD_CID, false, nullptr, nsWindowConstructor },
   { &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor },
-  { &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerAndroidConstructor },
+  { &kNS_SCREENMANAGER_CID, false, NULL, ScreenManagerConstructor,
+    mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_THEMERENDERER_CID, false, nullptr, nsNativeThemeAndroidConstructor },
   { &kNS_IDLE_SERVICE_CID, false, nullptr, nsIdleServiceAndroidConstructor },
   { &kNS_TRANSFERABLE_CID, false, nullptr, nsTransferableConstructor },
   { &kNS_CLIPBOARD_CID, false, nullptr, nsClipboardConstructor },
   { &kNS_CLIPBOARDHELPER_CID, false, nullptr, nsClipboardHelperConstructor },
   { &kNS_PRINTSETTINGSSERVICE_CID, false, nullptr, nsPrintSettingsServiceAndroidConstructor },
   { &kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor },
   { &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecAndroidConstructor },
@@ -111,17 +116,18 @@ static const mozilla::Module::CIDEntry k
   { &kNS_SYSTEMALERTSSERVICE_CID, false, nullptr, mozilla::widget::AndroidAlertsConstructor },
   { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
   { "@mozilla.org/widgets/window/android;1", &kNS_WINDOW_CID },
   { "@mozilla.org/widgets/child_window/android;1", &kNS_CHILD_CID },
   { "@mozilla.org/widget/appshell/android;1", &kNS_APPSHELL_CID },
-  { "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID },
+  { "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID,
+    mozilla::Module::MAIN_PROCESS_ONLY },
   { "@mozilla.org/chrome/chrome-native-theme;1", &kNS_THEMERENDERER_CID },
   { "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
   { "@mozilla.org/widget/transferable;1", &kNS_TRANSFERABLE_CID },
   { "@mozilla.org/widget/clipboard;1", &kNS_CLIPBOARD_CID },
   { "@mozilla.org/widget/clipboardhelper;1", &kNS_CLIPBOARDHELPER_CID },
   { "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
   { "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
   { "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -1519,29 +1519,35 @@ nsIWidget*
 nsWindow::GetParent()
 {
     return mParent;
 }
 
 float
 nsWindow::GetDPI()
 {
-    if (AndroidBridge::Bridge())
-        return AndroidBridge::Bridge()->GetDPI();
-    return 160.0f;
+    nsCOMPtr<nsIScreen> screen = GetWidgetScreen();
+    if (!screen) {
+        return 160.0f;
+    }
+
+    float dpi;
+    screen->GetDpi(&dpi);
+    return dpi;
 }
 
 double
 nsWindow::GetDefaultScaleInternal()
 {
-
     nsCOMPtr<nsIScreen> screen = GetWidgetScreen();
     MOZ_ASSERT(screen);
-    RefPtr<nsScreenAndroid> screenAndroid = (nsScreenAndroid*) screen.get();
-    return screenAndroid->GetDensity();
+
+    double scale;
+    screen->GetContentsScaleFactor(&scale);
+    return scale;
 }
 
 void
 nsWindow::Show(bool aState)
 {
     ALOG("nsWindow[%p]::Show %d", (void*)this, aState);
 
     if (mWindowType == eWindowType_invisible) {
@@ -2273,19 +2279,19 @@ nsWindow::GetCompositorBridgeChild() con
 
 already_AddRefed<nsIScreen>
 nsWindow::GetWidgetScreen()
 {
     nsCOMPtr<nsIScreenManager> screenMgr =
         do_GetService("@mozilla.org/gfx/screenmanager;1");
     MOZ_ASSERT(screenMgr, "Failed to get nsIScreenManager");
 
-    RefPtr<nsScreenManagerAndroid> screenMgrAndroid =
-        (nsScreenManagerAndroid*) screenMgr.get();
-    return screenMgrAndroid->ScreenForId(mScreenId);
+    nsCOMPtr<nsIScreen> screen;
+    screenMgr->GetPrimaryScreen(getter_AddRefs(screen));
+    return screen.forget();
 }
 
 void
 nsWindow::SetContentDocumentDisplayed(bool aDisplayed)
 {
     mContentDocumentDisplayed = aDisplayed;
 }
 
--- a/xpcom/idl-parser/xpidl/header.py
+++ b/xpcom/idl-parser/xpidl/header.py
@@ -129,16 +129,25 @@ def paramlistAsNative(m, empty='void'):
             paramIter -= 1
 
     if len(l) == 0:
         return empty
 
     return ", ".join(l)
 
 
+def memberCanRunScript(member):
+    # This can only happen if the member is scriptable and its interface is not builtinclass.
+    return member.isScriptable() and not member.iface.attributes.builtinclass
+
+
+def runScriptAnnotation(member):
+    return "JS_HAZ_CAN_RUN_SCRIPT " if memberCanRunScript(member) else ""
+
+
 def paramAsNative(p):
     default_spec = ''
     if p.default_value:
         default_spec = " = " + p.default_value
     return "%s%s%s" % (p.nativeType(),
                        p.name,
                        default_spec)
 
@@ -179,16 +188,20 @@ jsvalue_include = """
 """
 
 infallible_includes = """
 #include "mozilla/AlreadyAddRefed.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/DebugOnly.h"
 """
 
+can_run_script_includes = """
+#include "js/GCAnnotations.h"
+"""
+
 header_end = """/* For IDL files that don't want to include root IDL files. */
 #ifndef NS_NO_VTABLE
 #define NS_NO_VTABLE
 #endif
 """
 
 footer = """
 #endif /* __gen_%(basename)s_h__ */
@@ -214,22 +227,33 @@ def print_header(idl, fd, filename):
             foundinc = True
             fd.write('\n')
         fd.write(include % {'basename': idl_basename(inc.filename)})
 
     if idl.needsJSTypes():
         fd.write(jsvalue_include)
 
     # Include some extra files if any attributes are infallible.
-    for iface in [p for p in idl.productions if p.kind == 'interface']:
-        for attr in [m for m in iface.members if isinstance(m, xpidl.Attribute)]:
+    interfaces = [p for p in idl.productions if p.kind == 'interface']
+    wroteRunScriptIncludes = False
+    for iface in interfaces:
+        attrs = [m for m in iface.members if isinstance(m, xpidl.Attribute)]
+        for attr in attrs:
             if attr.infallible:
                 fd.write(infallible_includes)
                 break
 
+        if not wroteRunScriptIncludes:
+            methods = [m for m in iface.members if isinstance(m, xpidl.Method)]
+            for member in itertools.chain(attrs, methods):
+                if memberCanRunScript(member):
+                    fd.write(can_run_script_includes)
+                    wroteRunScriptIncludes = True
+                    break
+
     fd.write('\n')
     fd.write(header_end)
 
     for p in idl.productions:
         if p.kind == 'include':
             continue
         if p.kind == 'cdata':
             fd.write(p.data)
@@ -365,40 +389,43 @@ def write_interface(iface, fd):
                          'signed': (not basetype.signed) and 'U' or ''})
         fd.write(",\n".join(enums))
         fd.write("\n  };\n\n")
 
     def write_method_decl(m):
         printComments(fd, m.doccomments, '  ')
 
         fd.write("  /* %s */\n" % m.toIDL())
-        fd.write("  %s = 0;\n\n" % methodAsNative(m))
+        fd.write("  %s%s = 0;\n\n" % (runScriptAnnotation(m),
+                                      methodAsNative(m)))
 
     def write_attr_decl(a):
         printComments(fd, a.doccomments, '  ')
 
         fd.write("  /* %s */\n" % a.toIDL())
 
-        fd.write("  %s = 0;\n" % attributeAsNative(a, True))
+        fd.write("  %s%s = 0;\n" % (runScriptAnnotation(a),
+                                    attributeAsNative(a, True)))
         if a.infallible:
             realtype = a.realtype.nativeType('in')
             tmpl = attr_builtin_infallible_tmpl
 
             if a.realtype.kind != 'builtin':
                 assert realtype.endswith(' *'), "bad infallible type"
                 tmpl = attr_refcnt_infallible_tmpl
                 realtype = realtype[:-2]  # strip trailing pointer
 
             fd.write(tmpl % {'realtype': realtype,
                              'nativename': attributeNativeName(a, getter=True),
                              'args': '' if not a.implicit_jscontext else 'JSContext* cx',
                              'argnames': '' if not a.implicit_jscontext else 'cx, '})
 
         if not a.readonly:
-            fd.write("  %s = 0;\n" % attributeAsNative(a, False))
+            fd.write("  %s%s = 0;\n" % (runScriptAnnotation(a),
+                                        attributeAsNative(a, False)))
         fd.write("\n")
 
     defname = iface.name.upper()
     if iface.name[0:2] == 'ns':
         defname = 'NS_' + defname[2:]
 
     names = uuid_decoder.match(iface.attributes.uuid).groupdict()
     m3str = names['m3'] + names['m4']
--- a/xpcom/idl-parser/xpidl/runtests.py
+++ b/xpcom/idl-parser/xpidl/runtests.py
@@ -97,16 +97,17 @@ attribute long bar;
         self.assertEqual("long", a.type)
 
     def testOverloadedVirtual(self):
         i = self.p.parse("""[uuid(abc)] interface foo {
 attribute long bar;
 void getBar();
 };""", filename='f')
         self.assertTrue(isinstance(i, xpidl.IDL))
+        i.resolve([], self.p, {})
 
         class FdMock:
             def write(self, s):
                 pass
         try:
             header.print_header(i, FdMock(), filename='f')
         except Exception as e:
             self.assertEqual(