Merge inbound to mozilla-central. a=merge
authorshindli <shindli@mozilla.com>
Tue, 19 Jun 2018 00:40:13 +0300
changeset 479598 1e2c9151a09e43613a79daa8d4a94dc3e314020c
parent 479583 854d98803f6925fc8cb96f4ded4d7ad7de3e5922 (current diff)
parent 479597 0398e981e6a0958bc1788f897ae960d37e8ea2f8 (diff)
child 479613 4eae98be3a4fe1a0454509537f886ad7a32c2fb9
child 479652 3008516d3044cc540419dfb54a6bc7d50a1025ab
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone62.0a1
first release with
nightly linux32
1e2c9151a09e / 62.0a1 / 20180618220118 / files
nightly linux64
1e2c9151a09e / 62.0a1 / 20180618220118 / files
nightly mac
1e2c9151a09e / 62.0a1 / 20180618220118 / files
nightly win32
1e2c9151a09e / 62.0a1 / 20180618220118 / files
nightly win64
1e2c9151a09e / 62.0a1 / 20180618220118 / 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
browser/themes/linux/communicator/communicator.css
browser/themes/linux/communicator/jar.mn
browser/themes/linux/communicator/moz.build
browser/themes/osx/communicator/communicator.css
browser/themes/osx/communicator/jar.mn
browser/themes/osx/communicator/moz.build
browser/themes/windows/communicator/communicator.css
browser/themes/windows/communicator/jar.mn
browser/themes/windows/communicator/moz.build
layout/tools/reftest/manifest.jsm
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -164,19 +164,16 @@ var whitelist = [
 
 whitelist = new Set(whitelist.filter(item =>
   ("isFromDevTools" in item) == isDevtools &&
   (!item.skipUnofficial || !AppConstants.MOZILLA_OFFICIAL) &&
   (!item.platforms || item.platforms.includes(AppConstants.platform))
 ).map(item => item.file));
 
 const ignorableWhitelist = new Set([
-  // The communicator.css file is kept for add-on backward compat.
-  "chrome://communicator/skin/communicator.css",
-
   // These 2 files are unreferenced only when building without the crash
   // reporter (eg. Linux x64 asan builds on treeherder)
   "chrome://global/locale/crashes.dtd",
   "chrome://global/locale/crashes.properties",
 
   // The following files are outside of the omni.ja file, so we only catch them
   // when testing on a non-packaged build.
 
deleted file mode 100644
--- a/browser/themes/linux/communicator/communicator.css
+++ /dev/null
@@ -1,6 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-@import url("chrome://global/skin/");
-
deleted file mode 100644
--- a/browser/themes/linux/communicator/jar.mn
+++ /dev/null
@@ -1,7 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-browser.jar:
-% skin communicator classic/1.0 %skin/classic/communicator/
-        skin/classic/communicator/communicator.css
deleted file mode 100644
--- a/browser/themes/linux/communicator/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-JAR_MANIFESTS += ['jar.mn']
\ No newline at end of file
--- a/browser/themes/linux/moz.build
+++ b/browser/themes/linux/moz.build
@@ -1,12 +1,10 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-DIRS += ['communicator']
-
 JAR_MANIFESTS += ['jar.mn']
 
 DEFINES['MENUBAR_CAN_AUTOHIDE'] = 1
 
deleted file mode 100644
--- a/browser/themes/osx/communicator/communicator.css
+++ /dev/null
@@ -1,6 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-@import url("chrome://global/skin/");
-
deleted file mode 100644
--- a/browser/themes/osx/communicator/jar.mn
+++ /dev/null
@@ -1,7 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-browser.jar:
-% skin communicator classic/1.0 %skin/classic/communicator/
-        skin/classic/communicator/communicator.css
deleted file mode 100644
--- a/browser/themes/osx/communicator/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-JAR_MANIFESTS += ['jar.mn']
\ No newline at end of file
--- a/browser/themes/osx/moz.build
+++ b/browser/themes/osx/moz.build
@@ -1,10 +1,8 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-DIRS += ['communicator']
-
 JAR_MANIFESTS += ['jar.mn']
 
deleted file mode 100644
--- a/browser/themes/windows/communicator/communicator.css
+++ /dev/null
@@ -1,6 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-@import url("chrome://global/skin/");
-
deleted file mode 100644
--- a/browser/themes/windows/communicator/jar.mn
+++ /dev/null
@@ -1,7 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-browser.jar:
-% skin communicator classic/1.0 %skin/classic/communicator/
-        skin/classic/communicator/communicator.css
deleted file mode 100644
--- a/browser/themes/windows/communicator/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-JAR_MANIFESTS += ['jar.mn']
\ No newline at end of file
--- a/browser/themes/windows/moz.build
+++ b/browser/themes/windows/moz.build
@@ -1,12 +1,10 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-DIRS += ['communicator']
-
 JAR_MANIFESTS += ['jar.mn']
 
 DEFINES['MENUBAR_CAN_AUTOHIDE'] = 1
 
--- a/docshell/base/SerializedLoadContext.cpp
+++ b/docshell/base/SerializedLoadContext.cpp
@@ -8,21 +8,27 @@
 #include "nsNetUtil.h"
 #include "nsIChannel.h"
 #include "nsIPrivateBrowsingChannel.h"
 #include "nsIWebSocketChannel.h"
 
 namespace IPC {
 
 SerializedLoadContext::SerializedLoadContext(nsILoadContext* aLoadContext)
+  : mIsContent(false)
+  , mUseRemoteTabs(false)
+  , mUseTrackingProtection(false)
 {
   Init(aLoadContext);
 }
 
 SerializedLoadContext::SerializedLoadContext(nsIChannel* aChannel)
+  : mIsContent(false)
+  , mUseRemoteTabs(false)
+  , mUseTrackingProtection(false)
 {
   if (!aChannel) {
     Init(nullptr);
     return;
   }
 
   nsCOMPtr<nsILoadContext> loadContext;
   NS_QueryNotificationCallbacks(aChannel, loadContext);
@@ -40,16 +46,19 @@ SerializedLoadContext::SerializedLoadCon
         isOverriden) {
       mIsPrivateBitValid = true;
     }
     mOriginAttributes.SyncAttributesWithPrivateBrowsing(isPrivate);
   }
 }
 
 SerializedLoadContext::SerializedLoadContext(nsIWebSocketChannel* aChannel)
+  : mIsContent(false)
+  , mUseRemoteTabs(false)
+  , mUseTrackingProtection(false)
 {
   nsCOMPtr<nsILoadContext> loadContext;
   if (aChannel) {
     NS_QueryNotificationCallbacks(aChannel, loadContext);
   }
   Init(loadContext);
 }
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -382,16 +382,19 @@ nsDocShell::nsDocShell()
   , mIsPrintingOrPP(false)
   , mSavingOldViewer(false)
   , mDynamicallyCreated(false)
   , mAffectPrivateSessionLifetime(true)
   , mInvisible(false)
   , mHasLoadedNonBlankURI(false)
   , mBlankTiming(false)
 {
+  mHistoryID.m0 = 0;
+  mHistoryID.m1 = 0;
+  mHistoryID.m2 = 0;
   AssertOriginAttributesMatchPrivateBrowsing();
 
   nsContentUtils::GenerateUUIDInPlace(mHistoryID);
 
   if (gDocShellCount++ == 0) {
     NS_ASSERTION(sURIFixup == nullptr,
                  "Huh, sURIFixup not null in first nsDocShell ctor!");
 
--- a/dom/base/DirectionalityUtils.cpp
+++ b/dom/base/DirectionalityUtils.cpp
@@ -208,25 +208,27 @@
 
 #include "nsINode.h"
 #include "nsIContent.h"
 #include "nsIContentInlines.h"
 #include "nsIDocument.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/ShadowRoot.h"
 #include "nsUnicodeProperties.h"
 #include "nsTextFragment.h"
 #include "nsAttrValue.h"
 #include "nsTextNode.h"
 #include "nsCheapSets.h"
 
 namespace mozilla {
 
 using mozilla::dom::Element;
+using mozilla::dom::ShadowRoot;
 
 /**
  * Returns true if aElement is one of the elements whose text content should not
  * affect its own direction, nor the direction of ancestors with dir=auto.
  *
  * Note that this does not include <bdi>, whose content does affect its own
  * direction when it has dir=auto (which it has by default), so one needs to
  * test for it separately, e.g. with DoesNotAffectDirectionOfAncestors.
@@ -271,16 +273,18 @@ GetDirectionFromChar(uint32_t ch)
     case eCharType_LeftToRight:
       return eDir_LTR;
 
     default:
       return eDir_NotSet;
   }
 }
 
+// FIXME(bug 1100912): Should ShadowRoot children affect the host if it's
+// dir=auto? Probably not at least in closed mode.
 inline static bool
 NodeAffectsDirAutoAncestor(nsINode* aTextNode)
 {
   Element* parent = aTextNode->GetParentElement();
   return (parent &&
           !DoesNotParticipateInAutoDirection(parent) &&
           parent->NodeOrAncestorHasDirAuto() &&
           !aTextNode->IsInAnonymousSubtree());
@@ -366,17 +370,17 @@ GetDirectionFromText(const nsTextFragmen
  * http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-directionality
  *
  * @param[in] changedNode If we call this method because the content of a text
  *            node is about to change, pass in the changed node, so that we
  *            know not to return it
  * @return the text node containing the character that determined the direction
  */
 static nsTextNode*
-WalkDescendantsSetDirectionFromText(Element* aElement, bool aNotify = true,
+WalkDescendantsSetDirectionFromText(Element* aElement, bool aNotify,
                                     nsINode* aChangedNode = nullptr)
 {
   MOZ_ASSERT(aElement, "Must have an element");
   MOZ_ASSERT(aElement->HasDirAuto(), "Element must have dir=auto");
 
   if (DoesNotParticipateInAutoDirection(aElement)) {
     return nullptr;
   }
@@ -620,61 +624,79 @@ public:
 };
 
 Directionality
 RecomputeDirectionality(Element* aElement, bool aNotify)
 {
   MOZ_ASSERT(!aElement->HasDirAuto(),
              "RecomputeDirectionality called with dir=auto");
 
-  Directionality dir = eDir_LTR;
+  if (aElement->HasValidDir()) {
+    return aElement->GetDirectionality();
+  }
 
-  if (aElement->HasValidDir()) {
-    dir = aElement->GetDirectionality();
-  } else {
-    Element* parent = aElement->GetParentElement();
-    if (parent) {
-      // If the element doesn't have an explicit dir attribute with a valid
-      // value, the directionality is the same as the parent element (but
-      // don't propagate the parent directionality if it isn't set yet).
-      Directionality parentDir = parent->GetDirectionality();
+  Directionality dir = eDir_LTR;
+  if (nsINode* parent = aElement->GetParentNode()) {
+    if (ShadowRoot* shadow = ShadowRoot::FromNode(parent)) {
+      parent = shadow->GetHost();
+    }
+
+    if (parent && parent->IsElement()) {
+      // If the node doesn't have an explicit dir attribute with a valid value,
+      // the directionality is the same as the parent element (but don't propagate
+      // the parent directionality if it isn't set yet).
+      Directionality parentDir = parent->AsElement()->GetDirectionality();
       if (parentDir != eDir_NotSet) {
         dir = parentDir;
       }
-    } else {
-      // If there is no parent element and no dir attribute, the directionality
-      // is LTR.
-      dir = eDir_LTR;
     }
+  }
 
-    aElement->SetDirectionality(dir, aNotify);
-  }
+  aElement->SetDirectionality(dir, aNotify);
   return dir;
 }
 
-void
-SetDirectionalityOnDescendants(Element* aElement, Directionality aDir,
-                               bool aNotify)
+static void
+SetDirectionalityOnDescendantsInternal(nsINode* aNode,
+                                       Directionality aDir,
+                                       bool aNotify)
 {
-  for (nsIContent* child = aElement->GetFirstChild(); child; ) {
+  if (Element* element = Element::FromNode(aNode)) {
+    if (ShadowRoot* shadow = element->GetShadowRoot()) {
+      SetDirectionalityOnDescendantsInternal(shadow, aDir, aNotify);
+    }
+  }
+
+  for (nsIContent* child = aNode->GetFirstChild(); child; ) {
     if (!child->IsElement()) {
-      child = child->GetNextNode(aElement);
+      child = child->GetNextNode(aNode);
       continue;
     }
 
     Element* element = child->AsElement();
     if (element->HasValidDir() || element->HasDirAuto()) {
-      child = child->GetNextNonChildNode(aElement);
+      child = child->GetNextNonChildNode(aNode);
       continue;
     }
+    if (ShadowRoot* shadow = element->GetShadowRoot()) {
+      SetDirectionalityOnDescendantsInternal(shadow, aDir, aNotify);
+    }
     element->SetDirectionality(aDir, aNotify);
-    child = child->GetNextNode(aElement);
+    child = child->GetNextNode(aNode);
   }
 }
 
+// We want the public version of this only to acc
+void
+SetDirectionalityOnDescendants(Element* aElement, Directionality aDir,
+                               bool aNotify)
+{
+  return SetDirectionalityOnDescendantsInternal(aElement, aDir, aNotify);
+}
+
 /**
  * Walk the parent chain of a text node whose dir attribute has been removed and
  * reset the direction of any of its ancestors which have dir=auto and whose
  * directionality is determined by a text node descendant.
  */
 void
 WalkAncestorsResetAutoDirection(Element* aElement, bool aNotify)
 {
@@ -777,18 +799,19 @@ WalkDescendantsClearAncestorDirAuto(Elem
       continue;
     }
 
     child->ClearAncestorHasDirAuto();
     child = child->GetNextNode(aElement);
   }
 }
 
-void SetAncestorDirectionIfAuto(nsTextNode* aTextNode, Directionality aDir,
-                                bool aNotify = true)
+void
+SetAncestorDirectionIfAuto(nsTextNode* aTextNode, Directionality aDir,
+                           bool aNotify = true)
 {
   MOZ_ASSERT(aTextNode->NodeType() == nsINode::TEXT_NODE,
              "Must be a text node");
 
   Element* parent = aTextNode->GetParentElement();
   while (parent && parent->NodeOrAncestorHasDirAuto()) {
     if (DoesNotParticipateInAutoDirection(parent) || parent->HasFixedDir()) {
       break;
@@ -991,17 +1014,17 @@ OnSetDirAttr(Element* aElement, const ns
     }
     SetDirectionalityOnDescendants(aElement,
                                    RecomputeDirectionality(aElement, aNotify),
                                    aNotify);
   }
 }
 
 void
-SetDirOnBind(mozilla::dom::Element* aElement, nsIContent* aParent)
+SetDirOnBind(Element* aElement, nsIContent* aParent)
 {
   // Set the AncestorHasDirAuto flag, unless this element shouldn't affect
   // ancestors that have dir=auto
   if (!DoesNotParticipateInAutoDirection(aElement) &&
       !aElement->IsHTMLElement(nsGkAtoms::bdi) &&
       aParent && aParent->NodeOrAncestorHasDirAuto()) {
     aElement->SetAncestorHasDirAuto();
 
@@ -1029,17 +1052,18 @@ SetDirOnBind(mozilla::dom::Element* aEle
 
   if (!aElement->HasDirAuto()) {
     // if the element doesn't have dir=auto, set its own directionality from
     // the dir attribute or by inheriting from its ancestors.
     RecomputeDirectionality(aElement, false);
   }
 }
 
-void ResetDir(mozilla::dom::Element* aElement)
+void
+ResetDir(Element* aElement)
 {
   if (aElement->HasDirAutoSet()) {
     nsTextNode* setByNode =
       static_cast<nsTextNode*>(aElement->GetProperty(nsGkAtoms::dirAutoSetBy));
     nsTextNodeDirectionalityMap::RemoveElementFromMap(setByNode, aElement);
   }
 
   if (!aElement->HasDirAuto()) {
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1989,26 +1989,22 @@ Element::UnbindFromTree(bool aDeep, bool
   // This has to be here, rather than in nsGenericHTMLElement::UnbindFromTree,
   //  because it has to happen after unsetting the parent pointer, but before
   //  recursively unbinding the kids.
   if (IsHTMLElement()) {
     ResetDir(this);
   }
 
   if (aDeep) {
-    // Do the kids. Don't call GetChildCount() here since that'll force
-    // XUL to generate template children, which there is no need for since
-    // all we're going to do is unbind them anyway.
-    uint32_t i, n = mAttrsAndChildren.ChildCount();
-
-    for (i = 0; i < n; ++i) {
+    for (nsIContent* child = GetFirstChild(); child;
+         child = child->GetNextSibling()) {
       // Note that we pass false for aNullParent here, since we don't want
       // the kids to forget us.  We _do_ want them to forget their binding
       // parent, though, since this only walks non-anonymous kids.
-      mAttrsAndChildren.ChildAt(i)->UnbindFromTree(true, false);
+      child->UnbindFromTree(true, false);
     }
   }
 
   nsNodeUtils::ParentChainChanged(this);
 
   // Unbind children of shadow root.
   if (ShadowRoot* shadowRoot = GetShadowRoot()) {
     for (nsIContent* child = shadowRoot->GetFirstChild(); child;
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -1269,50 +1269,63 @@ FragmentOrElement::SetTextContentInterna
                                           ErrorResult& aError)
 {
   aError = nsContentUtils::SetNodeTextContent(this, aTextContent, false);
 }
 
 void
 FragmentOrElement::DestroyContent()
 {
-  nsIDocument* document = OwnerDoc();
-
   // Drop any servo data. We do this before the RemovedFromDocument call below
   // so that it doesn't need to try to keep the style state sane when shuffling
   // around the flattened tree.
   //
   // TODO(emilio): I suspect this can be asserted against instead, with a bit of
   // effort to avoid calling nsDocument::Destroy with a shell...
   if (IsElement()) {
     AsElement()->ClearServoData();
   }
 
+  nsIDocument* document = OwnerDoc();
+
   document->BindingManager()->RemovedFromDocument(this, document,
                                                   nsBindingManager::eRunDtor);
   document->ClearBoxObjectFor(this);
 
-  uint32_t i, count = mAttrsAndChildren.ChildCount();
-  for (i = 0; i < count; ++i) {
-    // The child can remove itself from the parent in BindToTree.
-    mAttrsAndChildren.ChildAt(i)->DestroyContent();
+#ifdef DEBUG
+  uint32_t oldChildCount = GetChildCount();
+#endif
+
+  for (nsIContent* child = GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+    child->DestroyContent();
+    MOZ_ASSERT(child->GetParent() == this,
+               "Mutating the tree during XBL destructors is evil");
   }
-  ShadowRoot* shadowRoot = GetShadowRoot();
-  if (shadowRoot) {
+
+  MOZ_ASSERT(oldChildCount == GetChildCount(),
+             "Mutating the tree during XBL destructors is evil");
+
+  if (ShadowRoot* shadowRoot = GetShadowRoot()) {
     shadowRoot->DestroyContent();
   }
 }
 
 void
 FragmentOrElement::SaveSubtreeState()
 {
-  uint32_t i, count = mAttrsAndChildren.ChildCount();
-  for (i = 0; i < count; ++i) {
-    mAttrsAndChildren.ChildAt(i)->SaveSubtreeState();
+  for (nsIContent* child = GetFirstChild();
+       child;
+       child = child->GetNextSibling()) {
+    child->SaveSubtreeState();
   }
+
+  // FIXME(bug 1469277): Pretty sure this wants to dig into shadow trees as
+  // well.
 }
 
 //----------------------------------------------------------------------
 
 // Generic DOMNode implementations
 
 void
 FragmentOrElement::FireNodeInserted(nsIDocument* aDoc,
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -4076,19 +4076,19 @@ Element*
 nsIDocument::GetRootElementInternal() const
 {
   // We invoke GetRootElement() immediately before the servo traversal, so we
   // should always have a cache hit from Servo.
   MOZ_ASSERT(NS_IsMainThread());
 
   // Loop backwards because any non-elements, such as doctypes and PIs
   // are likely to appear before the root element.
-  uint32_t i;
-  for (i = mChildren.ChildCount(); i > 0; --i) {
-    if (Element* element = Element::FromNode(mChildren.ChildAt(i - 1))) {
+  for (nsIContent* child = GetLastChild(); child;
+       child = child->GetPreviousSibling()) {
+    if (Element* element = Element::FromNode(child)) {
       const_cast<nsIDocument*>(this)->mCachedRootElement = element;
       return element;
     }
   }
 
   const_cast<nsIDocument*>(this)->mCachedRootElement = nullptr;
   return nullptr;
 }
@@ -8126,20 +8126,28 @@ nsDocument::Destroy()
   mIsGoingAway = true;
 
   ScriptLoader()->Destroy();
   SetScriptGlobalObject(nullptr);
   RemovedFromDocShell();
 
   bool oldVal = mInUnlinkOrDeletion;
   mInUnlinkOrDeletion = true;
-  uint32_t i, count = mChildren.ChildCount();
-  for (i = 0; i < count; ++i) {
-    mChildren.ChildAt(i)->DestroyContent();
-  }
+
+#ifdef DEBUG
+  uint32_t oldChildCount = GetChildCount();
+#endif
+
+  for (nsIContent* child = GetFirstChild(); child;
+       child = child->GetNextSibling()) {
+    child->DestroyContent();
+    MOZ_ASSERT(child->GetParentNode() == this);
+  }
+  MOZ_ASSERT(oldChildCount == GetChildCount());
+
   mInUnlinkOrDeletion = oldVal;
 
   mLayoutHistoryState = nullptr;
 
   // Shut down our external resource map.  We might not need this for
   // leak-fixing if we fix nsDocumentViewer to do cycle-collection, but
   // tearing down all those frame trees right now is the right thing to do.
   mExternalResourceMap.Shutdown();
@@ -8149,19 +8157,19 @@ void
 nsDocument::RemovedFromDocShell()
 {
   if (mRemovedFromDocShell)
     return;
 
   mRemovedFromDocShell = true;
   EnumerateActivityObservers(NotifyActivityChanged, nullptr);
 
-  uint32_t i, count = mChildren.ChildCount();
-  for (i = 0; i < count; ++i) {
-    mChildren.ChildAt(i)->SaveSubtreeState();
+  for (nsIContent* child = GetFirstChild(); child;
+       child = child->GetNextSibling()) {
+    child->SaveSubtreeState();
   }
 }
 
 already_AddRefed<nsILayoutHistoryState>
 nsIDocument::GetLayoutHistoryState() const
 {
   nsCOMPtr<nsILayoutHistoryState> state;
   if (!mScriptGlobalObject) {
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -2258,19 +2258,19 @@ nsJSContext::KillICCRunner()
   }
 }
 
 class NotifyGCEndRunnable : public Runnable
 {
   nsString mMessage;
 
 public:
-  explicit NotifyGCEndRunnable(const nsString& aMessage)
+  explicit NotifyGCEndRunnable(nsString&& aMessage)
     : mozilla::Runnable("NotifyGCEndRunnable")
-    , mMessage(aMessage)
+    , mMessage(std::move(aMessage))
   {
   }
 
   NS_DECL_NSIRUNNABLE
 };
 
 NS_IMETHODIMP
 NotifyGCEndRunnable::Run()
@@ -2318,17 +2318,17 @@ DOMGCSliceCallback(JSContext* aCx, JS::G
         }
       }
 
       if (!sShuttingDown) {
         if (StaticPrefs::javascript_options_mem_notify() ||
             Telemetry::CanRecordExtended()) {
           nsString json;
           json.Adopt(aDesc.formatJSON(aCx, PR_Now()));
-          RefPtr<NotifyGCEndRunnable> notify = new NotifyGCEndRunnable(json);
+          RefPtr<NotifyGCEndRunnable> notify = new NotifyGCEndRunnable(std::move(json));
           SystemGroup::Dispatch(TaskCategory::GarbageCollection, notify.forget());
         }
       }
 
       sCCLockedOut = false;
       sIsCompactingOnUserInactive = false;
 
       // May need to kill the inter-slice GC runner
--- a/dom/file/BaseBlobImpl.h
+++ b/dom/file/BaseBlobImpl.h
@@ -97,16 +97,21 @@ public:
 
   virtual void GetType(nsAString& aType) override;
 
   size_t GetAllocationSize() const override
   {
     return 0;
   }
 
+  size_t GetAllocationSize(FallibleTArray<BlobImpl*>& aVisitedBlobImpls) const override
+  {
+    return GetAllocationSize();
+  }
+
   virtual uint64_t GetSerialNumber() const override { return mSerialNumber; }
 
   virtual already_AddRefed<BlobImpl>
   CreateSlice(uint64_t aStart, uint64_t aLength,
               const nsAString& aContentType, ErrorResult& aRv) override
   {
     return nullptr;
   }
--- a/dom/file/BlobImpl.h
+++ b/dom/file/BlobImpl.h
@@ -47,16 +47,17 @@ public:
 
   virtual void GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) const = 0;
 
   virtual uint64_t GetSize(ErrorResult& aRv) = 0;
 
   virtual void GetType(nsAString& aType) = 0;
 
   virtual size_t GetAllocationSize() const = 0;
+  virtual size_t GetAllocationSize(FallibleTArray<BlobImpl*>& aVisitedBlobImpls) const  = 0;
 
   /**
    * An effectively-unique serial number identifying this instance of FileImpl.
    *
    * Implementations should obtain a serial number from
    * FileImplBase::NextSerialNumber().
    */
   virtual uint64_t GetSerialNumber() const = 0;
--- a/dom/file/BlobSet.cpp
+++ b/dom/file/BlobSet.cpp
@@ -24,19 +24,17 @@ BlobSet::AppendVoidPtr(const void* aData
   void* data = malloc(aLength);
   if (!data) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   memcpy((char*)data, aData, aLength);
 
   RefPtr<BlobImpl> blobImpl = new MemoryBlobImpl(data, aLength, EmptyString());
-  mBlobImpls.AppendElement(blobImpl);
-
-  return NS_OK;
+  return AppendBlobImpl(blobImpl);
 }
 
 nsresult
 BlobSet::AppendString(const nsAString& aString, bool nativeEOL)
 {
   nsCString utf8Str;
   if (NS_WARN_IF(!AppendUTF16toUTF8(aString, utf8Str, mozilla::fallible))) {
     return NS_ERROR_OUT_OF_MEMORY;
@@ -56,14 +54,16 @@ BlobSet::AppendString(const nsAString& a
     StringBlobImpl::Create(utf8Str, EmptyString());
   return AppendBlobImpl(blobImpl);
 }
 
 nsresult
 BlobSet::AppendBlobImpl(BlobImpl* aBlobImpl)
 {
   NS_ENSURE_ARG_POINTER(aBlobImpl);
-  mBlobImpls.AppendElement(aBlobImpl);
+  if (NS_WARN_IF(!mBlobImpls.AppendElement(aBlobImpl, fallible))) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
   return NS_OK;
 }
 
 } // dom namespace
 } // mozilla namespace
--- a/dom/file/BlobSet.h
+++ b/dom/file/BlobSet.h
@@ -15,24 +15,24 @@
 namespace mozilla {
 namespace dom {
 
 class BlobImpl;
 
 class BlobSet final
 {
 public:
-  nsresult AppendVoidPtr(const void* aData, uint32_t aLength);
+  MOZ_MUST_USE nsresult AppendVoidPtr(const void* aData, uint32_t aLength);
 
-  nsresult AppendString(const nsAString& aString, bool nativeEOL);
+  MOZ_MUST_USE nsresult AppendString(const nsAString& aString, bool nativeEOL);
 
-  nsresult AppendBlobImpl(BlobImpl* aBlobImpl);
+  MOZ_MUST_USE nsresult AppendBlobImpl(BlobImpl* aBlobImpl);
 
-  nsTArray<RefPtr<BlobImpl>>& GetBlobImpls() { return mBlobImpls; }
+  FallibleTArray<RefPtr<BlobImpl>>& GetBlobImpls() { return mBlobImpls; }
 
 private:
-  nsTArray<RefPtr<BlobImpl>> mBlobImpls;
+  FallibleTArray<RefPtr<BlobImpl>> mBlobImpls;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_BlobSet_h
--- a/dom/file/MemoryBlobImpl.h
+++ b/dom/file/MemoryBlobImpl.h
@@ -53,16 +53,21 @@ public:
     return true;
   }
 
   size_t GetAllocationSize() const override
   {
     return mLength;
   }
 
+  size_t GetAllocationSize(FallibleTArray<BlobImpl*>& aVisitedBlobImpls) const override
+  {
+    return GetAllocationSize();
+  }
+
   class DataOwner final : public mozilla::LinkedListElement<DataOwner>
   {
   public:
     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataOwner)
     DataOwner(void* aMemoryBuffer, uint64_t aLength)
       : mData(aMemoryBuffer)
       , mLength(aLength)
     {
--- a/dom/file/MultipartBlobImpl.cpp
+++ b/dom/file/MultipartBlobImpl.cpp
@@ -54,25 +54,37 @@ MultipartBlobImpl::Create(nsTArray<RefPt
 }
 
 void
 MultipartBlobImpl::CreateInputStream(nsIInputStream** aStream,
                                      ErrorResult& aRv)
 {
   *aStream = nullptr;
 
+  uint32_t length = mBlobImpls.Length();
+  if (length == 0) {
+    aRv = NS_NewCStringInputStream(aStream, EmptyCString());
+    return;
+  }
+
+  if (length == 1) {
+    BlobImpl* blobImpl = mBlobImpls.ElementAt(0);
+    blobImpl->CreateInputStream(aStream, aRv);
+    return;
+  }
+
   nsCOMPtr<nsIMultiplexInputStream> stream =
     do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
   if (NS_WARN_IF(!stream)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   uint32_t i;
-  for (i = 0; i < mBlobImpls.Length(); i++) {
+  for (i = 0; i < length; i++) {
     nsCOMPtr<nsIInputStream> scratchStream;
     BlobImpl* blobImpl = mBlobImpls.ElementAt(i).get();
 
     blobImpl->CreateInputStream(getter_AddRefs(scratchStream), aRv);
     if (NS_WARN_IF(aRv.Failed())) {
       return;
     }
 
@@ -177,17 +189,20 @@ MultipartBlobImpl::InitializeBlob(const 
   mContentType = aContentType;
   BlobSet blobSet;
 
   for (uint32_t i = 0, len = aData.Length(); i < len; ++i) {
     const Blob::BlobPart& data = aData[i];
 
     if (data.IsBlob()) {
       RefPtr<Blob> blob = data.GetAsBlob().get();
-      blobSet.AppendBlobImpl(blob->Impl());
+      aRv = blobSet.AppendBlobImpl(blob->Impl());
+      if (aRv.Failed()) {
+        return;
+      }
     }
 
     else if (data.IsUSVString()) {
       aRv = blobSet.AppendString(data.GetAsUSVString(), aNativeEOL);
       if (aRv.Failed()) {
         return;
       }
     }
@@ -378,17 +393,21 @@ MultipartBlobImpl::InitializeChromeFile(
   }
 
   // XXXkhuey this is terrible
   if (mContentType.IsEmpty()) {
     blob->GetType(mContentType);
   }
 
   BlobSet blobSet;
-  blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl());
+  rv = blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl());
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
   mBlobImpls = blobSet.GetBlobImpls();
 
   SetLengthAndModifiedDate(error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   if (aLastModifiedPassed) {
@@ -407,15 +426,36 @@ MultipartBlobImpl::MayBeClonedToOtherThr
     }
   }
 
   return true;
 }
 
 size_t MultipartBlobImpl::GetAllocationSize() const
 {
+  FallibleTArray<BlobImpl*> visitedBlobs;
+
+  // We want to report the unique blob allocation, avoiding duplicated blobs in
+  // the multipart blob tree.
   size_t total = 0;
   for (uint32_t i = 0; i < mBlobImpls.Length(); ++i) {
-    total += mBlobImpls[i]->GetAllocationSize();
+    total += mBlobImpls[i]->GetAllocationSize(visitedBlobs);
   }
 
   return total;
 }
+
+size_t MultipartBlobImpl::GetAllocationSize(FallibleTArray<BlobImpl*>& aVisitedBlobs) const
+{
+  FallibleTArray<BlobImpl*> visitedBlobs;
+
+  size_t total = 0;
+  for (BlobImpl* blobImpl : mBlobImpls) {
+    if (!aVisitedBlobs.Contains(blobImpl)) {
+      if (NS_WARN_IF(!aVisitedBlobs.AppendElement(blobImpl, fallible))) {
+        return 0;
+      }
+      total += blobImpl->GetAllocationSize(aVisitedBlobs);
+    }
+  }
+
+  return total;
+}
--- a/dom/file/MultipartBlobImpl.h
+++ b/dom/file/MultipartBlobImpl.h
@@ -88,16 +88,17 @@ public:
   void SetName(const nsAString& aName)
   {
     mName = aName;
   }
 
   virtual bool MayBeClonedToOtherThreads() const override;
 
   size_t GetAllocationSize() const override;
+  size_t GetAllocationSize(FallibleTArray<BlobImpl*>& aVisitedBlobImpls) const override;
 
 protected:
   MultipartBlobImpl(nsTArray<RefPtr<BlobImpl>>&& aBlobImpls,
                     const nsAString& aName,
                     const nsAString& aContentType)
     : BaseBlobImpl(aName, aContentType, UINT64_MAX),
       mBlobImpls(std::move(aBlobImpls)),
       mIsFromNsIFile(false)
--- a/dom/file/StreamBlobImpl.h
+++ b/dom/file/StreamBlobImpl.h
@@ -74,16 +74,21 @@ public:
 
   bool IsDirectory() const override
   {
     return mIsDirectory;
   }
 
   size_t GetAllocationSize() const override;
 
+  size_t GetAllocationSize(FallibleTArray<BlobImpl*>& aVisitedBlobImpls) const override
+  {
+    return GetAllocationSize();
+  }
+
 private:
   StreamBlobImpl(already_AddRefed<nsIInputStream> aInputStream,
                  const nsAString& aContentType,
                  uint64_t aLength);
 
   StreamBlobImpl(already_AddRefed<nsIInputStream> aInputStream,
                  const nsAString& aName,
                  const nsAString& aContentType,
--- a/dom/file/StringBlobImpl.h
+++ b/dom/file/StringBlobImpl.h
@@ -32,16 +32,21 @@ public:
   CreateSlice(uint64_t aStart, uint64_t aLength,
               const nsAString& aContentType, ErrorResult& aRv) override;
 
   size_t GetAllocationSize() const override
   {
     return mData.Length();
   }
 
+  size_t GetAllocationSize(FallibleTArray<BlobImpl*>& aVisitedBlobImpls) const override
+  {
+    return GetAllocationSize();
+  }
+
 private:
   StringBlobImpl(const nsACString& aData, const nsAString& aContentType);
 
   ~StringBlobImpl();
 
   nsCString mData;
 };
 
--- a/dom/indexedDB/FileSnapshot.h
+++ b/dom/indexedDB/FileSnapshot.h
@@ -109,16 +109,22 @@ private:
   }
 
   size_t
   GetAllocationSize() const override
   {
     return mBlobImpl->GetAllocationSize();
   }
 
+  size_t
+  GetAllocationSize(FallibleTArray<BlobImpl*>& aVisitedBlobs) const override
+  {
+    return mBlobImpl->GetAllocationSize(aVisitedBlobs);
+  }
+
   virtual uint64_t
   GetSerialNumber() const override
   {
     return mBlobImpl->GetSerialNumber();
   }
 
   virtual already_AddRefed<BlobImpl>
   CreateSlice(uint64_t aStart,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3500,24 +3500,26 @@ ContentParent::AllocPExternalHelperAppPa
                                              const uint32_t& aContentDispositionHint,
                                              const nsString& aContentDispositionFilename,
                                              const bool& aForceSave,
                                              const int64_t& aContentLength,
                                              const bool& aWasFileChannel,
                                              const OptionalURIParams& aReferrer,
                                              PBrowserParent* aBrowser)
 {
-  ExternalHelperAppParent *parent =
-    new ExternalHelperAppParent(uri, aContentLength, aWasFileChannel);
+  ExternalHelperAppParent* parent =
+    new ExternalHelperAppParent(uri,
+                                aContentLength,
+                                aWasFileChannel,
+                                aContentDisposition,
+                                aContentDispositionHint,
+                                aContentDispositionFilename);
   parent->AddRef();
   parent->Init(this,
                aMimeContentType,
-               aContentDisposition,
-               aContentDispositionHint,
-               aContentDispositionFilename,
                aForceSave,
                aReferrer,
                aBrowser);
   return parent;
 }
 
 bool
 ContentParent::DeallocPExternalHelperAppParent(PExternalHelperAppParent* aService)
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -8,17 +8,16 @@
 
 #include <algorithm>
 #ifndef XP_WIN
 #include <unistd.h>
 #endif
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/dom/BlobBinding.h"
-#include "mozilla/dom/BlobSet.h"
 #include "mozilla/dom/DocGroup.h"
 #include "mozilla/dom/DOMString.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/FileBinding.h"
 #include "mozilla/dom/FileCreatorHelper.h"
 #include "mozilla/dom/FetchUtil.h"
 #include "mozilla/dom/FormData.h"
 #include "mozilla/dom/MutableBlobStorage.h"
--- a/dom/xhr/XMLHttpRequestMainThread.h
+++ b/dom/xhr/XMLHttpRequestMainThread.h
@@ -56,17 +56,16 @@
 
 class nsIJARChannel;
 class nsILoadGroup;
 class nsIJSID;
 
 namespace mozilla {
 namespace dom {
 
-class BlobSet;
 class DOMString;
 class XMLHttpRequestUpload;
 struct OriginAttributesDictionary;
 
 // A helper for building up an ArrayBuffer object's data
 // before creating the ArrayBuffer itself.  Will do doubling
 // based reallocation, up to an optional maximum growth given.
 //
--- a/dom/xslt/tests/XSLTMark/XSLTMark.xul
+++ b/dom/xslt/tests/XSLTMark/XSLTMark.xul
@@ -1,14 +1,14 @@
 <?xml version="1.0"?><!-- -*- Mode: xml; tab-width: 2; indent-tabs-mode: nil -*- -->
 <!-- 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/. -->
 
-<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
 <?xml-stylesheet href="XSLTMark.css" type="text/css"?>
 <window id="XSLTMarkHarness"
         title="XSLTMark"
         onload="view.onLoad()"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         orient="vertical">
 <script type="application/x-javascript" src="XSLTMark-static.js" />
 <script type="application/x-javascript" src="XSLTMark-test.js" />
@@ -44,9 +44,9 @@
   <progressmeter id="totalProgress" mode="normal" value="0" flex="2"/>
 </hbox>
 <hbox flex="1">
   <textbox id="transformOutput" class="out" readonly="true" multiline="true" flex="1"/>
 </hbox>
 <hbox flex="1">
   <textbox id="transformDetailedOutput" class="out" readonly="true" multiline="true" flex="1"/>
 </hbox>
-</window>
\ No newline at end of file
+</window>
--- a/layout/tools/reftest/manifest.jsm
+++ b/layout/tools/reftest/manifest.jsm
@@ -678,9 +678,15 @@ function AddTestItem(aTest, aFilter) {
         aTest.needsFocus)
         return;
 
     if (url2 !== null)
         aTest.identifier = [url1.spec, aTest.type, url2.spec];
     else
         aTest.identifier = url1.spec;
     g.urls.push(aTest);
+    // Periodically log progress to avoid no-output timeout on slow platforms.
+    // No-output timeouts during manifest parsing have been a problem for
+    // jsreftests on Android/debug. Any logging resets the no-output timer,
+    // even debug logging which is normally not displayed.
+    if ((g.urls.length % 5000) == 0)
+        g.logger.debug(g.urls.length + " tests found...");
 }
--- a/layout/tools/reftest/reftest.jsm
+++ b/layout/tools/reftest/reftest.jsm
@@ -369,19 +369,16 @@ function ReadTests() {
                 g.urls = JSON.parse(decoder.decode(array)).map(CreateUrls);
                 StartTests();
             }).catch(function onFailure(e) {
                 logger.error("Failed to load test objects: " + e);
                 DoneTests();
             });
         } else if (manifests) {
             // Parse reftest manifests
-            // XXX There is a race condition in the manifest parsing code which
-            // sometimes shows up on Android jsreftests (bug 1416125). It seems
-            // adding/removing log statements can change its frequency.
             logger.debug("Reading " + manifests.length + " manifests");
             manifests = JSON.parse(manifests);
             g.urlsFilterRegex = manifests[null];
 
             var globalFilter = manifests.hasOwnProperty("") ? new RegExp(manifests[""]) : null;
             var manifestURLs = Object.keys(manifests);
 
             // Ensure we read manifests from higher up the directory tree first so that we
--- a/taskcluster/ci/build/windows.yml
+++ b/taskcluster/ci/build/windows.yml
@@ -586,17 +586,17 @@ win64-ccov/debug:
 win64-asan/debug:
     description: "Win64 Debug ASAN"
     index:
         product: firefox
         job-name: win64-asan-debug
     treeherder:
         platform: windows2012-64/asan
         symbol: Bd
-        tier: 2
+        tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
         max-run-time: 7200
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
             PERFHERDER_EXTRA_OPTIONS: "debug asan"
     run:
         using: mozharness
@@ -617,17 +617,17 @@ win64-asan/debug:
 win64-asan/opt:
     description: "Win64 Opt ASAN"
     index:
         product: firefox
         job-name: win64-asan-opt
     treeherder:
         platform: windows2012-64/asan
         symbol: Bo
-        tier: 2
+        tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
         max-run-time: 7200
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/releng.manifest"
             PERFHERDER_EXTRA_OPTIONS: "opt asan"
     run:
         using: mozharness
--- a/taskcluster/taskgraph/transforms/tests.py
+++ b/taskcluster/taskgraph/transforms/tests.py
@@ -590,16 +590,17 @@ def set_tier(config, tests):
                                          'windows7-32-pgo/opt',
                                          'windows7-32-devedition/opt',
                                          'windows7-32-nightly/opt',
                                          'windows10-64/debug',
                                          'windows10-64/opt',
                                          'windows10-64-pgo/opt',
                                          'windows10-64-devedition/opt',
                                          'windows10-64-nightly/opt',
+                                         'windows10-64-asan/opt',
                                          'macosx64/opt',
                                          'macosx64/debug',
                                          'macosx64-nightly/opt',
                                          'macosx64-devedition/opt',
                                          'android-4.3-arm7-api-16/opt',
                                          'android-4.3-arm7-api-16/debug',
                                          'android-4.2-x86/opt']:
                 test['tier'] = 1
--- a/testing/mozbase/mozdevice/mozdevice/adb.py
+++ b/testing/mozbase/mozdevice/mozdevice/adb.py
@@ -634,16 +634,23 @@ class ADBDevice(ADBCommand):
                 self._chmod_R = True
         except (ADBError, ADBTimeoutError) as e:
             self._logger.debug('Check chmod -R: %s' % e)
             match = re_recurse.search(e.message)
             if match:
                 self._chmod_R = True
         self._logger.info("Native chmod -R support: %s" % self._chmod_R)
 
+        try:
+            cleared = self.shell_bool('logcat -P ""', timeout=timeout)
+        except ADBError:
+            cleared = False
+        if not cleared:
+            self._logger.info("Unable to turn off logcat chatty")
+
         self._logger.debug("ADBDevice: %s" % self.__dict__)
 
     def _get_device_serial(self, device):
         if device is None:
             devices = ADBHost(adb=self._adb_path, adb_host=self._adb_host,
                               adb_port=self._adb_port).devices()
             if len(devices) > 1:
                 raise ValueError("ADBDevice called with multiple devices "
@@ -1966,37 +1973,41 @@ class ADBDevice(ADBCommand):
             the value set in the ADBDevice constructor is used.
         :type timeout: integer or None
         :returns: list of (pid, name, user) tuples for running processes
             on the device.
         :raises: * ADBTimeoutError
                  * ADBError
         """
         adb_process = None
+        max_attempts = 2
         try:
-            adb_process = self.shell("ps", timeout=timeout)
-            if adb_process.timedout:
-                raise ADBTimeoutError("%s" % adb_process)
-            elif adb_process.exitcode:
-                raise ADBProcessError(adb_process)
-            # first line is the headers
-            header = adb_process.stdout_file.readline()
-            pid_i = -1
-            user_i = -1
-            els = header.split()
-            for i in range(len(els)):
-                item = els[i].lower()
-                if item == 'user':
-                    user_i = i
-                elif item == 'pid':
-                    pid_i = i
-            if user_i == -1 or pid_i == -1:
+            for attempt in range(1, max_attempts + 1):
+                adb_process = self.shell("ps", timeout=timeout)
+                if adb_process.timedout:
+                    raise ADBTimeoutError("%s" % adb_process)
+                elif adb_process.exitcode:
+                    raise ADBProcessError(adb_process)
+                # first line is the headers
+                header = adb_process.stdout_file.readline()
+                pid_i = -1
+                user_i = -1
+                els = header.split()
+                for i in range(len(els)):
+                    item = els[i].lower()
+                    if item == 'user':
+                        user_i = i
+                    elif item == 'pid':
+                        pid_i = i
+                if user_i != -1 and pid_i != -1:
+                    break
                 self._logger.error('get_process_list: %s' % header)
-                raise ADBError('get_process_list: Unknown format: %s: %s' % (
-                    header, adb_process))
+                if attempt >= max_attempts:
+                    raise ADBError('get_process_list: Unknown format: %s: %s' % (
+                        header, adb_process))
             ret = []
             line = adb_process.stdout_file.readline()
             while line:
                 els = line.split()
                 try:
                     ret.append([int(els[pid_i]), els[-1], els[user_i]])
                 except ValueError:
                     self._logger.error('get_process_list: %s %s\n%s' % (
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -129326,16 +129326,40 @@
       [
        "/css/css-scoping/reference/green-box.html",
        "=="
       ]
      ],
      {}
     ]
    ],
+   "css/css-scoping/shadow-directionality-001.tentative.html": [
+    [
+     "/css/css-scoping/shadow-directionality-001.tentative.html",
+     [
+      [
+       "/css/css-scoping/reference/green-box.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-scoping/shadow-directionality-002.tentative.html": [
+    [
+     "/css/css-scoping/shadow-directionality-002.tentative.html",
+     [
+      [
+       "/css/css-scoping/reference/green-box.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-scoping/shadow-disabled-sheet-001.html": [
     [
      "/css/css-scoping/shadow-disabled-sheet-001.html",
      [
       [
        "/css/css-scoping/reference/green-box.html",
        "=="
       ]
@@ -182910,16 +182934,28 @@
       [
        "/service-workers/service-worker/resources/svg-target-reftest-001.html",
        "=="
       ]
      ],
      {}
     ]
    ],
+   "shadow-dom/directionality-001.tentative.html": [
+    [
+     "/shadow-dom/directionality-001.tentative.html",
+     [
+      [
+       "/shadow-dom/directionality-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "shadow-dom/layout-slot-no-longer-assigned.html": [
     [
      "/shadow-dom/layout-slot-no-longer-assigned.html",
      [
       [
        "/shadow-dom/reference/empty.html",
        "=="
       ]
@@ -295381,16 +295417,21 @@
      {}
     ]
    ],
    "shadow-dom/OWNERS": [
     [
      {}
     ]
    ],
+   "shadow-dom/directionality-001-ref.html": [
+    [
+     {}
+    ]
+   ],
    "shadow-dom/reference/empty.html": [
     [
      {}
     ]
    ],
    "shadow-dom/resources/Document-prototype-currentScript-helper.js": [
     [
      {}
@@ -522936,16 +522977,24 @@
   "css/css-scoping/shadow-at-import.html": [
    "67295000ad3c24c2d9ab0ac556d34758f3ce654c",
    "reftest"
   ],
   "css/css-scoping/shadow-cascade-order-001.html": [
    "46913ea7e47811b11be898de5c3bd0a330ea6637",
    "testharness"
   ],
+  "css/css-scoping/shadow-directionality-001.tentative.html": [
+   "51cf8c6780bb66f64082a0054f24f64c09b0258f",
+   "reftest"
+  ],
+  "css/css-scoping/shadow-directionality-002.tentative.html": [
+   "c5cc9738b5b81a728c7cc16569360bd65b857ab3",
+   "reftest"
+  ],
   "css/css-scoping/shadow-disabled-sheet-001.html": [
    "3de2d23c1b3339b964ec2c009832a3207a3b9dc4",
    "reftest"
   ],
   "css/css-scoping/shadow-fallback-dynamic-001.html": [
    "741cd9e29067a4634aa5beb6bd06afa540895d22",
    "reftest"
   ],
@@ -523373,17 +523422,17 @@
    "911a6f200540f78d662fd775899aa0249fb9a30d",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-003.html": [
    "7338abdd6edb1027dc2e12b001773ce5ad114286",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-004.html": [
-   "1e5377c120916557dc1525b38c9cf7eb86ae0151",
+   "3740c52d7bd26a3353721931ae2a6299db395968",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-005.html": [
    "7d6563a162ba640b77801c5c8280078d4b087649",
    "reftest"
   ],
   "css/css-shapes/shape-outside/shape-image/gradients/shape-outside-linear-gradient-006.html": [
    "72267d3bfbdbeb438f32266334bb5e4a9c91c1bf",
@@ -539597,17 +539646,17 @@
    "08bbc95f3078421a489e1e93cc7a4f035af40d5b",
    "support"
   ],
   "css/css-values/calc-rem-lang.html": [
    "6fa668d2bcaf01f5c4680e3e14a0e86160d1b5d5",
    "reftest"
   ],
   "css/css-values/calc-rounding-001.html": [
-   "c3071454184ca1bd97443cfb6298447d16d79b2f",
+   "a74b631cd97db18ef120a0a5e7132c9e14b67f81",
    "testharness"
   ],
   "css/css-values/calc-serialization.html": [
    "d0bcbd402cb78e704dabc7f1665d40ba163e30eb",
    "testharness"
   ],
   "css/css-values/calc-unit-analysis.html": [
    "c5fd567b4fa257ce53c48ebf8c444bf382459fec",
@@ -547357,17 +547406,17 @@
    "c9ed57c7ef7a035c25feff4ea60547a57d727f31",
    "testharness"
   ],
   "css/cssom/font-shorthand-serialization.html": [
    "9d0bce1c0d74bf90aca1eb8ee6aa2e2ed2b92b30",
    "testharness"
   ],
   "css/cssom/getComputedStyle-detached-subtree.html": [
-   "01978ca7ea08cbf61b28e9d77753fe5852bcbff9",
+   "886f72b4eaa82d3aeb4de5c5b27f71369dbe0186",
    "testharness"
   ],
   "css/cssom/getComputedStyle-dynamic-subdoc.html": [
    "3f379487727d9730de9e3569b26632c35d602d9d",
    "testharness"
   ],
   "css/cssom/getComputedStyle-pseudo.html": [
    "d3ef09fb6092078562f8923879b9ece97938df47",
@@ -610372,16 +610421,24 @@
   "shadow-dom/ShadowRoot-interface.html": [
    "8c39afc1c5648c3e95fe69c4ea5003958f7734b7",
    "testharness"
   ],
   "shadow-dom/Slotable-interface.html": [
    "61f7da763fa4eb6f21077868caf0a07a4a9e44ae",
    "testharness"
   ],
+  "shadow-dom/directionality-001-ref.html": [
+   "818d966e37de205936380fd47605f13b5aa505d7",
+   "support"
+  ],
+  "shadow-dom/directionality-001.tentative.html": [
+   "763fd90e8ed83fb616379997735a5c283f0bd869",
+   "reftest"
+  ],
   "shadow-dom/event-composed-path-after-dom-mutation.html": [
    "69ea3efc8230a0ed31968f24379289c6691d77d1",
    "testharness"
   ],
   "shadow-dom/event-composed-path-with-related-target.html": [
    "a4c58227f937a943b3845ed3f672419b62a8caad",
    "testharness"
   ],
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-directionality-001.tentative.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<title>CSS Test: directionality propagation in Shadow DOM.</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="help" href="https://html.spec.whatwg.org/#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="match" href="reference/green-box.html">
+<style>
+  div { width: 100px; }
+</style>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="host1"></div>
+<div id="host2" dir="rtl"></div>
+<div id="host3"></div>
+<div id="host4" dir="rtl"></div>
+<script>
+  host1.attachShadow({ mode: "open" }).innerHTML = `
+    <style>:dir(ltr) { background: green; height: 25px; }</style>
+    <div></div>
+  `;
+  host2.attachShadow({ mode: "open" }).innerHTML = `
+    <style>:dir(rtl) { background: green; height: 25px; }</style>
+    <div></div>
+  `;
+  host3.attachShadow({ mode: "open" }).innerHTML = `
+    <style>:dir(rtl) { background: green; height: 25px; }</style>
+    <div></div>
+  `;
+  host4.attachShadow({ mode: "open" }).innerHTML = `
+    <style>span:dir(ltr) { display: block; background: green; height: 25px; }</style>
+    <div dir="ltr"><span></span></div>
+  `;
+  document.body.offsetTop;
+  host3.setAttribute("dir", "rtl");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-scoping/shadow-directionality-002.tentative.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>CSS Test: directionality propagation in Shadow DOM, appending a shadow host.</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="help" href="https://html.spec.whatwg.org/#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="match" href="reference/green-box.html">
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<style>
+  div { width: 100px; }
+</style>
+<div id="host-parent" dir="rtl"></div>
+<script>
+  let host = document.createElement("div");
+  host.attachShadow({ mode: "open" }).innerHTML = `
+    <style>:dir(rtl) { background: green; height: 100px; width: 100px; }</style>
+    <div></div>
+  `;
+  document.getElementById("host-parent").appendChild(host);
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/shadow-dom/directionality-001-ref.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<div dir="rtl"> 123 456 <span><span> 789 101112 </span></span></div>
+<div dir="rtl"> 123 456 <span dir="ltr"><span> 789 101112 </span></span></div>
+<div dir="rtl"> 123 456 <span><span> 789 101112 </span></span></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/shadow-dom/directionality-001.tentative.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>Test: directionality propagation in Shadow DOM.</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="help" href="https://html.spec.whatwg.org/#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="match" href="directionality-001-ref.html">
+<div id="host0" dir="rtl"><span> 789 101112 </span></div>
+<div id="host1" dir="rtl"><span> 789 101112 </span></div>
+<div id="host2" dir="rtl"><span> 789 101112 </span></div>
+<script>
+  host0.attachShadow({mode: 'closed'}).innerHTML =
+    '<div> 123 456 <span><slot></slot></span></div>';
+
+  host1.attachShadow({mode: 'closed'}).innerHTML =
+    '<div> 123 456 <span dir="ltr"><slot></slot></span></div>';
+
+  host2.attachShadow({mode: 'closed'}).innerHTML =
+    '<div> 123 456 <span><slot dir="ltr"></slot></span></div>';
+</script>
--- a/uriloader/base/nsDocLoader.h
+++ b/uriloader/base/nsDocLoader.h
@@ -207,18 +207,19 @@ protected:
 protected:
     struct nsStatusInfo : public mozilla::LinkedListElement<nsStatusInfo>
     {
         nsString mStatusMessage;
         nsresult mStatusCode;
         // Weak mRequest is ok; we'll be told if it decides to go away.
         nsIRequest * const mRequest;
 
-        explicit nsStatusInfo(nsIRequest* aRequest) :
-            mRequest(aRequest)
+        explicit nsStatusInfo(nsIRequest* aRequest)
+            : mStatusCode(NS_ERROR_NOT_INITIALIZED)
+            , mRequest(aRequest)
         {
             MOZ_COUNT_CTOR(nsStatusInfo);
         }
         ~nsStatusInfo()
         {
             MOZ_COUNT_DTOR(nsStatusInfo);
         }
     };
--- a/uriloader/base/nsURILoader.cpp
+++ b/uriloader/base/nsURILoader.cpp
@@ -77,18 +77,16 @@ static bool InitPreferences()
  * document is being opened in order to discover the content type...
  * Each instance remains alive until its target URL has been loaded
  * (or aborted).
  */
 class nsDocumentOpenInfo final : public nsIStreamListener
                                , public nsIThreadRetargetableStreamListener
 {
 public:
-  // Needed for nsCOMPtr to work right... Don't call this!
-  nsDocumentOpenInfo();
 
   // Real constructor
   // aFlags is a combination of the flags on nsIURILoader
   nsDocumentOpenInfo(nsIInterfaceRequestor* aWindowContext,
                      uint32_t aFlags,
                      nsURILoader* aURILoader);
 
   NS_DECL_THREADSAFE_ISUPPORTS
@@ -181,21 +179,16 @@ NS_IMPL_RELEASE(nsDocumentOpenInfo)
 
 NS_INTERFACE_MAP_BEGIN(nsDocumentOpenInfo)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequestObserver)
   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
   NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)
 NS_INTERFACE_MAP_END
 
-nsDocumentOpenInfo::nsDocumentOpenInfo()
-{
-  NS_NOTREACHED("This should never be called\n");
-}
-
 nsDocumentOpenInfo::nsDocumentOpenInfo(nsIInterfaceRequestor* aWindowContext,
                                        uint32_t aFlags,
                                        nsURILoader* aURILoader)
   : m_originalContext(aWindowContext),
     mFlags(aFlags),
     mURILoader(aURILoader),
     mDataConversionDepthLimit(sConvertDataLimit)
 {
--- a/uriloader/exthandler/ExternalHelperAppParent.cpp
+++ b/uriloader/exthandler/ExternalHelperAppParent.cpp
@@ -35,28 +35,42 @@ NS_IMPL_ISUPPORTS_INHERITED(ExternalHelp
                             nsIPrivateBrowsingChannel,
                             nsIResumableChannel,
                             nsIStreamListener,
                             nsIExternalHelperAppParent)
 
 ExternalHelperAppParent::ExternalHelperAppParent(
     const OptionalURIParams& uri,
     const int64_t& aContentLength,
-    const bool& aWasFileChannel)
+    const bool& aWasFileChannel,
+    const nsCString& aContentDispositionHeader,
+    const uint32_t& aContentDispositionHint,
+    const nsString& aContentDispositionFilename)
   : mURI(DeserializeURI(uri))
   , mPending(false)
 #ifdef DEBUG
   , mDiverted(false)
 #endif
   , mIPCClosed(false)
   , mLoadFlags(0)
   , mStatus(NS_OK)
   , mContentLength(aContentLength)
   , mWasFileChannel(aWasFileChannel)
 {
+  mContentDispositionHeader = aContentDispositionHeader;
+  if (!mContentDispositionHeader.IsEmpty()) {
+    NS_GetFilenameFromDisposition(mContentDispositionFilename,
+                                  mContentDispositionHeader,
+                                  mURI);
+    mContentDisposition =
+      NS_GetContentDispositionFromHeader(mContentDispositionHeader, this);
+  } else {
+    mContentDisposition = aContentDispositionHint;
+    mContentDispositionFilename = aContentDispositionFilename;
+  }
 }
 
 already_AddRefed<nsIInterfaceRequestor>
 GetWindowFromTabParent(PBrowserParent* aBrowser)
 {
   if (!aBrowser) {
     return nullptr;
   }
@@ -76,44 +90,28 @@ UpdateContentContext(nsIStreamListener* 
   MOZ_ASSERT(aListener);
   nsCOMPtr<nsIInterfaceRequestor> window = GetWindowFromTabParent(aBrowser);
   static_cast<nsExternalAppHandler *>(aListener)->SetContentContext(window);
 }
 
 void
 ExternalHelperAppParent::Init(ContentParent *parent,
                               const nsCString& aMimeContentType,
-                              const nsCString& aContentDispositionHeader,
-                              const uint32_t& aContentDispositionHint,
-                              const nsString& aContentDispositionFilename,
                               const bool& aForceSave,
                               const OptionalURIParams& aReferrer,
                               PBrowserParent* aBrowser)
 {
   nsCOMPtr<nsIExternalHelperAppService> helperAppService =
     do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID);
   NS_ASSERTION(helperAppService, "No Helper App Service!");
 
   nsCOMPtr<nsIURI> referrer = DeserializeURI(aReferrer);
   if (referrer)
     SetPropertyAsInterface(NS_LITERAL_STRING("docshell.internalReferrer"), referrer);
 
-  mContentDispositionHeader = aContentDispositionHeader;
-  if (!mContentDispositionHeader.IsEmpty()) {  
-    NS_GetFilenameFromDisposition(mContentDispositionFilename, 
-                                  mContentDispositionHeader, 
-                                  mURI);
-    mContentDisposition = 
-      NS_GetContentDispositionFromHeader(mContentDispositionHeader, this);
-  }
-  else {
-    mContentDisposition = aContentDispositionHint;
-    mContentDispositionFilename = aContentDispositionFilename;
-  }
-
   nsCOMPtr<nsIInterfaceRequestor> window;
   if (aBrowser) {
     TabParent* tabParent = TabParent::GetFrom(aBrowser);
     if (tabParent->GetOwnerElement())
       window = do_QueryInterface(tabParent->GetOwnerElement()->OwnerDoc()->GetWindow());
 
     bool isPrivate = false;
     nsCOMPtr<nsILoadContext> loadContext = tabParent->GetLoadContext();
--- a/uriloader/exthandler/ExternalHelperAppParent.h
+++ b/uriloader/exthandler/ExternalHelperAppParent.h
@@ -78,22 +78,22 @@ public:
     mozilla::ipc::IPCResult RecvDivertToParentUsing(PChannelDiverterParent* diverter,
                                                     PBrowserParent* aBrowser) override;
 
     bool WasFileChannel() override {
       return mWasFileChannel;
     }
 
     ExternalHelperAppParent(const OptionalURIParams& uri, const int64_t& contentLength,
-                            const bool& wasFileChannel);
+                            const bool& wasFileChannel,
+                            const nsCString& aContentDispositionHeader,
+                            const uint32_t& aContentDispositionHint,
+                            const nsString& aContentDispositionFilename);
     void Init(ContentParent *parent,
               const nsCString& aMimeContentType,
-              const nsCString& aContentDisposition,
-              const uint32_t& aContentDispositionHint,
-              const nsString& aContentDispositionFilename,
               const bool& aForceSave,
               const OptionalURIParams& aReferrer,
               PBrowserParent* aBrowser);
 
 protected:
   virtual ~ExternalHelperAppParent();
 
   virtual void ActorDestroy(ActorDestroyReason why) override;
--- a/uriloader/exthandler/HandlerServiceParent.cpp
+++ b/uriloader/exthandler/HandlerServiceParent.cpp
@@ -31,16 +31,17 @@ protected:
   nsHandlerInfoAction mPrefAction;
   nsCOMPtr<nsIMutableArray> mPossibleApps;
 };
 
 NS_IMPL_ISUPPORTS(ProxyHandlerInfo, nsIHandlerInfo)
 
 ProxyHandlerInfo::ProxyHandlerInfo(const HandlerInfo& aHandlerInfo)
   : mHandlerInfo(aHandlerInfo),
+    mPrefAction(nsIHandlerInfo::alwaysAsk),
     mPossibleApps(do_CreateInstance(NS_ARRAY_CONTRACTID))
 {
   for (auto& happ : aHandlerInfo.possibleApplicationHandlers()) {
     mPossibleApps->AppendElement(new RemoteHandlerApp(happ));
   }
 }
 
 /* readonly attribute ACString type; */
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -1208,17 +1208,20 @@ nsExternalAppHandler::nsExternalAppHandl
                                            uint32_t aReason, bool aForceSave)
 : mMimeInfo(aMIMEInfo)
 , mContentContext(aContentContext)
 , mWindowContext(aWindowContext)
 , mSuggestedFileName(aSuggestedFilename)
 , mForceSave(aForceSave)
 , mCanceled(false)
 , mStopRequestIssued(false)
+, mIsFileChannel(false)
 , mReason(aReason)
+, mTempFileIsExecutable(false)
+, mTimeDownloadStarted(0)
 , mContentLength(-1)
 , mProgress(0)
 , mSaver(nullptr)
 , mDialogProgressListener(nullptr)
 , mTransfer(nullptr)
 , mRequest(nullptr)
 , mExtProtSvc(aExtProtSvc)
 {
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -468,22 +468,17 @@ protected:
    * has been canceled or completes.
    */
   nsCOMPtr<nsITransfer> mTransfer;
 
   nsCOMPtr<nsIChannel> mOriginalChannel; /**< in the case of a redirect, this will be the pre-redirect channel. */
   nsCOMPtr<nsIHelperAppLauncherDialog> mDialog;
 
   /**
-   * Keep request alive in case when helper non-modal dialog shown.
-   * Thus in OnStopRequest the mRequest will not be set to null (it will be set to null further).
-   */
-  bool mKeepRequestAlive;
 
-  /**
    * The request that's being loaded. Initialized in OnStartRequest.
    * Nulled out in OnStopRequest or once we know what we're doing
    * with the data, whichever happens later.
    */
   nsCOMPtr<nsIRequest> mRequest;
 
   RefPtr<nsExternalHelperAppService> mExtProtSvc;
 };