Merge mozilla-central to autoland. a=merge CLOSED TREE
authorBogdan Tara <btara@mozilla.com>
Sun, 30 Sep 2018 00:59:24 +0300
changeset 494637 e540269f91e25d1735c619facf0af77115a8abb9
parent 494636 b96cec26d463643b2dc0347930cf2561bfcb0071 (current diff)
parent 494628 3632445ae3db388e7b214b83acec5a042391a7bb (diff)
child 494638 70f1b33a2dacf7798be831b35d0dec474ea5b067
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to autoland. a=merge CLOSED TREE
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -61,17 +61,17 @@ public:
     , mDocWrapper(aDocWrapper)
     , mVectorImage(aVectorImage)
     , mHonoringInvalidations(true)
   {
     MOZ_ASSERT(mDocWrapper, "Need a non-null SVG document wrapper");
     MOZ_ASSERT(mVectorImage, "Need a non-null VectorImage");
 
     StartObserving();
-    Element* elem = GetTarget();
+    Element* elem = GetReferencedElementWithoutObserving();
     MOZ_ASSERT(elem, "no root SVG node for us to observe");
 
     SVGObserverUtils::AddRenderingObserver(elem, this);
     mInObserverList = true;
   }
 
 
   void ResumeHonoringInvalidations()
@@ -80,24 +80,24 @@ public:
   }
 
 protected:
   virtual ~SVGRootRenderingObserver()
   {
     StopObserving();
   }
 
-  virtual Element* GetTarget() override
+  Element* GetReferencedElementWithoutObserving() override
   {
     return mDocWrapper->GetRootSVGElem();
   }
 
   virtual void OnRenderingChange() override
   {
-    Element* elem = GetTarget();
+    Element* elem = GetReferencedElementWithoutObserving();
     MOZ_ASSERT(elem, "missing root SVG node");
 
     if (mHonoringInvalidations && !mDocWrapper->ShouldIgnoreInvalidation()) {
       nsIFrame* frame = elem->GetPrimaryFrame();
       if (!frame || frame->PresShell()->IsDestroying()) {
         // We're being destroyed. Bail out.
         return;
       }
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1168,19 +1168,18 @@ nsFrame::DidSetComputedStyle(ComputedSty
 
   // SVGObserverUtils::GetEffectProperties() asserts that we only invoke it with
   // the first continuation so we need to check that in advance. Continuing text
   // frame doesn't initialize its continuation pointer before reaching here for
   // the first time, so we have to exclude text frames. This doesn't affect
   // correctness because text nodes themselves shouldn't have effects applied.
   if (!IsTextFrame() && !GetPrevContinuation()) {
     // Kick off loading of external SVG resources referenced from properties if
-    // any. This currently includes filter, clip-path, and mask. We don't care
-    // about the return value. We only want its side effect.
-    Unused << SVGObserverUtils::GetEffectProperties(this);
+    // any. This currently includes filter, clip-path, and mask.
+    SVGObserverUtils::InitiateResourceDocLoads(this);
   }
 
   // If the page contains markup that overrides text direction, and
   // does not contain any characters that would activate the Unicode
   // bidi algorithm, we need to call |SetBidiEnabled| on the pres
   // context before reflow starts.  See bug 115921.
   if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
     PresContext()->SetBidiEnabled();
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -9713,17 +9713,18 @@ nsDisplayMasksAndClipPaths::IsValidMask(
     return false;
   }
 
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
   SVGObserverUtils::EffectProperties effectProperties =
     SVGObserverUtils::GetEffectProperties(firstFrame);
 
-  if (effectProperties.HasInvalidClipPath() ||
+  if (SVGObserverUtils::GetAndObserveClipPath(firstFrame, nullptr) ==
+        SVGObserverUtils::eHasRefsSomeInvalid ||
       effectProperties.HasInvalidMask()) {
     return false;
   }
 
   return true;
 }
 
 
@@ -10031,33 +10032,33 @@ nsDisplayMasksAndClipPaths::GetClipWithR
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplayMasksAndClipPaths::PrintEffects(nsACString& aTo)
 {
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
   SVGObserverUtils::EffectProperties effectProperties =
     SVGObserverUtils::GetEffectProperties(firstFrame);
-  nsSVGClipPathFrame* clipPathFrame = effectProperties.GetClipPathFrame();
   bool first = true;
   aTo += " effects=(";
   if (mFrame->StyleEffects()->mOpacity != 1.0f && mHandleOpacity) {
     first = false;
     aTo += nsPrintfCString("opacity(%f)", mFrame->StyleEffects()->mOpacity);
   }
+  nsSVGClipPathFrame* clipPathFrame;
+  // XXX Check return value?
+  SVGObserverUtils::GetAndObserveClipPath(firstFrame, &clipPathFrame);
   if (clipPathFrame) {
     if (!first) {
       aTo += ", ";
     }
     aTo += nsPrintfCString(
       "clip(%s)", clipPathFrame->IsTrivial() ? "trivial" : "non-trivial");
     first = false;
-  }
-  const nsStyleSVGReset* style = mFrame->StyleSVGReset();
-  if (style->HasClipPath() && !clipPathFrame) {
+  } else if (mFrame->StyleSVGReset()->HasClipPath()) {
     if (!first) {
       aTo += ", ";
     }
     aTo += "clip(basic-shape)";
     first = false;
   }
 
   nsTArray<nsSVGMaskFrame*> masks = effectProperties.GetMaskFrames();
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -189,20 +189,20 @@ nsImageRenderer::PrepareImage()
           SVGObserverUtils::BackgroundImageProperty());
       if (!property) {
         mPrepareResult = ImgDrawResult::BAD_IMAGE;
         return false;
       }
 
       // If the referenced element is an <img>, <canvas>, or <video> element,
       // prefer SurfaceFromElement as it's more reliable.
-      mImageElementSurface =
-        nsLayoutUtils::SurfaceFromElement(property->GetReferencedElement());
+      mImageElementSurface = nsLayoutUtils::SurfaceFromElement(
+                               property->GetAndObserveReferencedElement());
       if (!mImageElementSurface.GetSourceSurface()) {
-        nsIFrame* paintServerFrame = property->GetReferencedFrame();
+        nsIFrame* paintServerFrame = property->GetAndObserveReferencedFrame();
         // If there's no referenced frame, or the referenced frame is
         // non-displayable SVG, then we have nothing valid to paint.
         if (!paintServerFrame ||
             (paintServerFrame->IsFrameOfType(nsIFrame::eSVG) &&
              !paintServerFrame->IsFrameOfType(nsIFrame::eSVGPaintServer) &&
              !static_cast<nsSVGDisplayableFrame*>(
                do_QueryFrame(paintServerFrame)))) {
           mPrepareResult = ImgDrawResult::BAD_IMAGE;
--- a/layout/svg/SVGObserverUtils.cpp
+++ b/layout/svg/SVGObserverUtils.cpp
@@ -26,26 +26,26 @@
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 
 void
 SVGRenderingObserver::StartObserving()
 {
-  Element* target = GetTarget();
+  Element* target = GetReferencedElementWithoutObserving();
   if (target) {
     target->AddMutationObserver(this);
   }
 }
 
 void
 SVGRenderingObserver::StopObserving()
 {
-  Element* target = GetTarget();
+  Element* target = GetReferencedElementWithoutObserving();
 
   if (target) {
     target->RemoveMutationObserver(this);
     if (mInObserverList) {
       SVGObserverUtils::RemoveRenderingObserver(target, this);
       mInObserverList = false;
     }
   }
@@ -55,19 +55,19 @@ SVGRenderingObserver::StopObserving()
 static SVGRenderingObserverList*
 GetObserverList(Element *aElement)
 {
   return static_cast<SVGRenderingObserverList*>
     (aElement->GetProperty(nsGkAtoms::renderingobserverlist));
 }
 
 Element*
-SVGRenderingObserver::GetReferencedElement()
+SVGRenderingObserver::GetAndObserveReferencedElement()
 {
-  Element* target = GetTarget();
+  Element* target = GetReferencedElementWithoutObserving();
 #ifdef DEBUG
   if (target) {
     SVGRenderingObserverList* observerList = GetObserverList(target);
     bool inObserverList = observerList && observerList->Contains(this);
     NS_ASSERTION(inObserverList == mInObserverList, "failed to track whether we're in our referenced element's observer list!");
   } else {
     NS_ASSERTION(!mInObserverList, "In whose observer list are we, then?");
   }
@@ -75,27 +75,27 @@ SVGRenderingObserver::GetReferencedEleme
   if (target && !mInObserverList) {
     SVGObserverUtils::AddRenderingObserver(target, this);
     mInObserverList = true;
   }
   return target;
 }
 
 nsIFrame*
-SVGRenderingObserver::GetReferencedFrame()
+SVGRenderingObserver::GetAndObserveReferencedFrame()
 {
-  Element* referencedElement = GetReferencedElement();
+  Element* referencedElement = GetAndObserveReferencedElement();
   return referencedElement ? referencedElement->GetPrimaryFrame() : nullptr;
 }
 
 nsIFrame*
-SVGRenderingObserver::GetReferencedFrame(LayoutFrameType aFrameType,
-                                         bool* aOK)
+SVGRenderingObserver::GetAndObserveReferencedFrame(LayoutFrameType aFrameType,
+                                                   bool* aOK)
 {
-  nsIFrame* frame = GetReferencedFrame();
+  nsIFrame* frame = GetAndObserveReferencedFrame();
   if (frame) {
     if (frame->Type() == aFrameType)
       return frame;
     if (aOK) {
       *aOK = false;
     }
   }
   return nullptr;
@@ -160,17 +160,17 @@ SVGRenderingObserver::ContentRemoved(nsI
 /**
  * Note that in the current setup there are two separate observer lists.
  *
  * In SVGIDRenderingObserver's ctor, the new object adds itself to the
  * mutation observer list maintained by the referenced element. In this way the
  * SVGIDRenderingObserver is notified if there are any attribute or content
  * tree changes to the element or any of its *descendants*.
  *
- * In SVGIDRenderingObserver::GetReferencedElement() the
+ * In SVGIDRenderingObserver::GetAndObserveReferencedElement() the
  * SVGIDRenderingObserver object also adds itself to an
  * SVGRenderingObserverList object belonging to the referenced
  * element.
  *
  * XXX: it would be nice to have a clear and concise executive summary of the
  * benefits/necessity of maintaining a second observer list.
  */
 
@@ -281,21 +281,21 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservedElementTracker)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SVGFilterObserver)
   tmp->StopObserving();
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservedElementTracker);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-nsSVGFilterFrame *
-SVGFilterObserver::GetFilterFrame()
+nsSVGFilterFrame*
+SVGFilterObserver::GetAndObserveFilterFrame()
 {
   return static_cast<nsSVGFilterFrame*>(
-    GetReferencedFrame(LayoutFrameType::SVGFilter, nullptr));
+    GetAndObserveReferencedFrame(LayoutFrameType::SVGFilter, nullptr));
 }
 
 void
 SVGFilterObserver::OnRenderingChange()
 {
   SVGIDRenderingObserver::OnRenderingChange();
 
   if (mFilterObserverList) {
@@ -495,17 +495,17 @@ SVGMaskObserverList::ResolveImage(uint32
       imageLoader->AssociateRequestToFrame(req, mFrame, 0);
     }
   }
 }
 
 bool
 SVGTextPathObserver::TargetIsValid()
 {
-  Element* target = GetTarget();
+  Element* target = GetReferencedElementWithoutObserving();
   return target && target->IsSVGElement(nsGkAtoms::path);
 }
 
 void
 SVGTextPathObserver::OnRenderingChange()
 {
   nsSVGRenderingObserverProperty::OnRenderingChange();
 
@@ -575,16 +575,53 @@ GetOrCreateMaskProperty(nsIFrame* aFrame
     return prop;
 
   prop = new SVGMaskObserverList(aFrame);
   NS_ADDREF(prop);
   aFrame->SetProperty(SVGObserverUtils::MaskProperty(), prop);
   return prop;
 }
 
+static already_AddRefed<URLAndReferrerInfo>
+ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValueData* aURL)
+{
+  MOZ_ASSERT(aFrame);
+
+  if (!aURL) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsIURI> uri = aURL->GetURI();
+  RefPtr<URLAndReferrerInfo> result;
+
+  // Non-local-reference URL.
+  if (!aURL->IsLocalRef()) {
+    if (!uri) {
+      return nullptr;
+    }
+    result = new URLAndReferrerInfo(uri,
+                                    aURL->mExtraData->GetReferrer(),
+                                    aURL->mExtraData->GetReferrerPolicy());
+    return result.forget();
+  }
+
+  nsCOMPtr<nsIURI> baseURI =
+    SVGObserverUtils::GetBaseURLForLocalRef(aFrame->GetContent(), uri);
+
+  nsCOMPtr<nsIURI> resolvedURI = aURL->ResolveLocalRef(baseURI);
+  if (!resolvedURI) {
+    return nullptr;
+  }
+
+  result = new URLAndReferrerInfo(resolvedURI,
+                                  aURL->mExtraData->GetReferrer(),
+                                  aURL->mExtraData->GetReferrerPolicy());
+  return result.forget();
+}
+
 template<class T>
 static T*
 GetEffectProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame,
   const mozilla::FramePropertyDescriptor<T>* aProperty)
 {
   if (!aURI)
     return nullptr;
 
@@ -611,17 +648,18 @@ SVGObserverUtils::GetMarkerFrames(nsIFra
   SVGMarkerObserver* observer;
   nsIFrame* marker;
 
 #define GET_MARKER(type)                                                      \
   markerURL = GetMarkerURI(aMarkedFrame, &nsStyleSVG::mMarker##type);         \
   observer = GetEffectProperty(markerURL, aMarkedFrame,                       \
                                SVGObserverUtils::Marker##type##Property());   \
   marker = observer ?                                                         \
-           observer->GetReferencedFrame(LayoutFrameType::SVGMarker, nullptr) :\
+           observer->GetAndObserveReferencedFrame(LayoutFrameType::SVGMarker, \
+                                                  nullptr) :                  \
            nullptr;                                                           \
   foundMarker = foundMarker || bool(marker);                                  \
   (*aFrames)[nsSVGMark::e##type] = static_cast<nsSVGMarkerFrame*>(marker);
 
   GET_MARKER(Start)
   GET_MARKER(Mid)
   GET_MARKER(End)
 
@@ -646,31 +684,31 @@ GetOrCreateFilterObserverListForCSS(nsIF
   }
   observers = new SVGFilterObserverListForCSSProp(effects->mFilters, aFrame);
   NS_ADDREF(observers);
   aFrame->SetProperty(SVGObserverUtils::FilterProperty(), observers);
   return observers;
 }
 
 static SVGObserverUtils::ReferenceState
-GetFilters(SVGFilterObserverListForCSSProp* aObserverList,
-           nsTArray<nsSVGFilterFrame*>* aFilterFrames)
+GetAndObserveFilters(SVGFilterObserverListForCSSProp* aObserverList,
+                     nsTArray<nsSVGFilterFrame*>* aFilterFrames)
 {
   if (!aObserverList) {
     return SVGObserverUtils::eHasNoRefs;
   }
 
   const nsTArray<RefPtr<SVGFilterObserver>>& observers =
     aObserverList->GetObservers();
   if (observers.IsEmpty()) {
     return SVGObserverUtils::eHasNoRefs;
   }
 
   for (uint32_t i = 0; i < observers.Length(); i++) {
-    nsSVGFilterFrame* filter = observers[i]->GetFilterFrame();
+    nsSVGFilterFrame* filter = observers[i]->GetAndObserveFilterFrame();
     if (!filter) {
       if (aFilterFrames) {
         aFilterFrames->Clear();
       }
       return SVGObserverUtils::eHasRefsSomeInvalid;
     }
     if (aFilterFrames) {
       aFilterFrames->AppendElement(filter);
@@ -681,26 +719,26 @@ GetFilters(SVGFilterObserverListForCSSPr
 }
 
 SVGObserverUtils::ReferenceState
 SVGObserverUtils::GetAndObserveFilters(nsIFrame* aFilteredFrame,
                                        nsTArray<nsSVGFilterFrame*>* aFilterFrames)
 {
   SVGFilterObserverListForCSSProp* observerList =
     GetOrCreateFilterObserverListForCSS(aFilteredFrame);
-  return GetFilters(observerList, aFilterFrames);
+  return ::GetAndObserveFilters(observerList, aFilterFrames);
 }
 
 SVGObserverUtils::ReferenceState
 SVGObserverUtils::GetFiltersIfObserving(nsIFrame* aFilteredFrame,
                                         nsTArray<nsSVGFilterFrame*>* aFilterFrames)
 {
   SVGFilterObserverListForCSSProp* observerList =
     aFilteredFrame->GetProperty(SVGObserverUtils::FilterProperty());
-  return GetFilters(observerList, aFilterFrames);
+  return ::GetAndObserveFilters(observerList, aFilterFrames);
 }
 
 already_AddRefed<nsISupports>
 SVGObserverUtils::ObserveFiltersForCanvasContext(CanvasRenderingContext2D* aContext,
                                                  Element* aCanvasElement,
                                                  nsTArray<nsStyleFilter>& aFilters)
 {
   return do_AddRef(new SVGFilterObserverListForCanvasContext(aContext,
@@ -710,16 +748,56 @@ SVGObserverUtils::ObserveFiltersForCanva
 
 void
 SVGObserverUtils::DetachFromCanvasContext(nsISupports* aAutoObserver)
 {
   static_cast<SVGFilterObserverListForCanvasContext*>(aAutoObserver)->
     DetachFromContext();
 }
 
+
+static nsSVGPaintingProperty*
+GetOrCreateClipPathObserver(nsIFrame* aClippedFrame)
+{
+  const nsStyleSVGReset* svgStyleReset = aClippedFrame->StyleSVGReset();
+  if (svgStyleReset->mClipPath.GetType() != StyleShapeSourceType::URL) {
+    return nullptr;
+  }
+  css::URLValue* url = svgStyleReset->mClipPath.GetURL();
+  RefPtr<URLAndReferrerInfo> pathURI = ResolveURLUsingLocalRef(aClippedFrame, url);
+  return SVGObserverUtils::GetPaintingProperty(pathURI, aClippedFrame,
+                                         SVGObserverUtils::ClipPathProperty());
+}
+
+SVGObserverUtils::ReferenceState
+SVGObserverUtils::GetAndObserveClipPath(nsIFrame* aClippedFrame,
+                                        nsSVGClipPathFrame** aClipPathFrame)
+{
+  if (aClipPathFrame) {
+    *aClipPathFrame = nullptr;
+  }
+  nsSVGPaintingProperty* observers = GetOrCreateClipPathObserver(aClippedFrame);
+  if (!observers) {
+    return eHasNoRefs;
+  }
+  bool frameTypeOK = true;
+  nsSVGClipPathFrame* frame = static_cast<nsSVGClipPathFrame*>(
+    observers->GetAndObserveReferencedFrame(LayoutFrameType::SVGClipPath,
+                                            &frameTypeOK));
+  // Note that, unlike for filters, a reference to an ID that doesn't exist
+  // is not invalid for clip-path or mask.
+  if (!frameTypeOK || (frame && !frame->IsValid())) {
+    return eHasRefsSomeInvalid;
+  }
+  if (aClipPathFrame) {
+    *aClipPathFrame = frame;
+  }
+  return frame ? eHasRefsAllValid : eHasNoRefs;
+}
+
 SVGGeometryElement*
 SVGObserverUtils::GetTextPathsReferencedPath(nsIFrame* aTextPathFrame)
 {
   SVGTextPathObserver* property =
     aTextPathFrame->GetProperty(SVGObserverUtils::HrefAsTextPathProperty());
 
   if (!property) {
     nsIContent* content = aTextPathFrame->GetContent();
@@ -743,22 +821,32 @@ SVGObserverUtils::GetTextPathsReferenced
 
     property = GetEffectProperty(target, aTextPathFrame,
                                  HrefAsTextPathProperty());
     if (!property) {
       return nullptr;
     }
   }
 
-  Element* element = property->GetReferencedElement();
+  Element* element = property->GetAndObserveReferencedElement();
   return (element && element->IsNodeOfType(nsINode::eSHAPE)) ?
     static_cast<SVGGeometryElement*>(element) : nullptr;
 }
 
 void
+SVGObserverUtils::InitiateResourceDocLoads(nsIFrame* aFrame)
+{
+  // We create observer objects and attach them to aFrame, but we do not
+  // make aFrame start observing the referenced frames.
+  Unused << GetOrCreateFilterObserverListForCSS(aFrame);
+  Unused << GetOrCreateClipPathObserver(aFrame);
+  Unused << GetEffectProperties(aFrame);
+}
+
+void
 SVGObserverUtils::RemoveTextPathObserver(nsIFrame* aTextPathFrame)
 {
   aTextPathFrame->DeleteProperty(HrefAsTextPathProperty());
 }
 
 nsIFrame*
 SVGObserverUtils::GetTemplateFrame(nsIFrame* aFrame,
                                    HrefToTemplateCallback aGetHref)
@@ -786,17 +874,17 @@ SVGObserverUtils::GetTemplateFrame(nsIFr
       new URLAndReferrerInfo(targetURI,
                              content->OwnerDoc()->GetDocumentURI(),
                              content->OwnerDoc()->GetReferrerPolicy());
 
     observer = GetEffectProperty(target, aFrame,
                                  SVGObserverUtils::HrefToTemplateProperty());
   }
 
-  return observer ? observer->GetReferencedFrame() : nullptr;
+  return observer ? observer->GetAndObserveReferencedFrame() : nullptr;
 }
 
 void
 SVGObserverUtils::RemoveTemplateObserver(nsIFrame* aFrame)
 {
   aFrame->DeleteProperty(SVGObserverUtils::HrefToTemplateProperty());
 }
 
@@ -834,24 +922,16 @@ SVGObserverUtils::GetPaintingPropertyFor
 SVGObserverUtils::EffectProperties
 SVGObserverUtils::GetEffectProperties(nsIFrame* aFrame)
 {
   NS_ASSERTION(!aFrame->GetPrevContinuation(), "aFrame should be first continuation");
 
   EffectProperties result;
   const nsStyleSVGReset *style = aFrame->StyleSVGReset();
 
-  if (style->mClipPath.GetType() == StyleShapeSourceType::URL) {
-    RefPtr<URLAndReferrerInfo> pathURI = SVGObserverUtils::GetClipPathURI(aFrame);
-    result.mClipPath =
-      GetPaintingProperty(pathURI, aFrame, ClipPathProperty());
-  } else {
-    result.mClipPath = nullptr;
-  }
-
   MOZ_ASSERT(style->mMask.mImageCount > 0);
   result.mMaskObservers = style->HasMask()
                           ? GetOrCreateMaskProperty(aFrame) : nullptr;
 
   return result;
 }
 
 nsSVGPaintServerFrame *
@@ -880,55 +960,43 @@ SVGObserverUtils::GetPaintServer(nsIFram
   MOZ_ASSERT(aPaint == &nsStyleSVG::mFill || aPaint == &nsStyleSVG::mStroke);
   PaintingPropertyDescriptor propDesc = (aPaint == &nsStyleSVG::mFill) ?
                                         SVGObserverUtils::FillProperty() :
                                         SVGObserverUtils::StrokeProperty();
   nsSVGPaintingProperty *property =
     SVGObserverUtils::GetPaintingProperty(paintServerURL, frame, propDesc);
   if (!property)
     return nullptr;
-  nsIFrame* result = property->GetReferencedFrame();
+  nsIFrame* result = property->GetAndObserveReferencedFrame();
   if (!result)
     return nullptr;
 
   LayoutFrameType type = result->Type();
   if (type != LayoutFrameType::SVGLinearGradient &&
       type != LayoutFrameType::SVGRadialGradient &&
       type != LayoutFrameType::SVGPattern)
     return nullptr;
 
   return static_cast<nsSVGPaintServerFrame*>(result);
 }
 
-nsSVGClipPathFrame *
-SVGObserverUtils::EffectProperties::GetClipPathFrame()
-{
-  if (!mClipPath)
-    return nullptr;
-
-  nsSVGClipPathFrame* frame = static_cast<nsSVGClipPathFrame*>(
-    mClipPath->GetReferencedFrame(LayoutFrameType::SVGClipPath, nullptr));
-
-  return frame;
-}
-
 nsTArray<nsSVGMaskFrame *>
 SVGObserverUtils::EffectProperties::GetMaskFrames()
 {
   nsTArray<nsSVGMaskFrame *> result;
   if (!mMaskObservers) {
     return result;
   }
 
   bool ok = true;
   const nsTArray<RefPtr<nsSVGPaintingProperty>>& observers =
     mMaskObservers->GetObservers();
   for (size_t i = 0; i < observers.Length(); i++) {
     nsSVGMaskFrame* maskFrame = static_cast<nsSVGMaskFrame*>(
-      observers[i]->GetReferencedFrame(LayoutFrameType::SVGMask, &ok));
+      observers[i]->GetAndObserveReferencedFrame(LayoutFrameType::SVGMask, &ok));
     MOZ_ASSERT(!maskFrame || ok);
     if (!ok) {
       // We can not find the specific SVG mask resource in the downloaded SVG
       // document. There are two possibilities:
       // 1. The given resource id is invalid.
       // 2. The given resource id refers to a viewbox.
       //
       // Hand it over to the style image.
@@ -938,43 +1006,28 @@ SVGObserverUtils::EffectProperties::GetM
   }
 
   return result;
 }
 
 bool
 SVGObserverUtils::EffectProperties::HasNoOrValidEffects()
 {
-  return HasNoOrValidClipPath() && HasNoOrValidMask();
-}
-
-bool
-SVGObserverUtils::EffectProperties::HasNoOrValidClipPath()
-{
-  if (mClipPath) {
-    bool ok = true;
-    nsSVGClipPathFrame* frame = static_cast<nsSVGClipPathFrame*>(
-      mClipPath->GetReferencedFrame(LayoutFrameType::SVGClipPath, &ok));
-    if (!ok || (frame && !frame->IsValid())) {
-      return false;
-    }
-  }
-
-  return true;
+  return HasNoOrValidMask();
 }
 
 bool
 SVGObserverUtils::EffectProperties::HasNoOrValidMask()
 {
   if (mMaskObservers) {
     bool ok = true;
     const nsTArray<RefPtr<nsSVGPaintingProperty>>& observers =
       mMaskObservers->GetObservers();
     for (size_t i = 0; i < observers.Length(); i++) {
-      observers[i]->GetReferencedFrame(LayoutFrameType::SVGMask, &ok);
+      observers[i]->GetAndObserveReferencedFrame(LayoutFrameType::SVGMask, &ok);
       if (!ok) {
         return false;
       }
     }
   }
 
   return true;
 }
@@ -1225,71 +1278,24 @@ SVGObserverUtils::GetBaseURLForLocalRef(
     if (isEqualsExceptRef) {
       return originalURI.forget();
     }
   }
 
   return baseURI.forget();
 }
 
-static already_AddRefed<URLAndReferrerInfo>
-ResolveURLUsingLocalRef(nsIFrame* aFrame, const css::URLValueData* aURL)
-{
-  MOZ_ASSERT(aFrame);
-
-  if (!aURL) {
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIURI> uri = aURL->GetURI();
-  RefPtr<URLAndReferrerInfo> result;
-
-  // Non-local-reference URL.
-  if (!aURL->IsLocalRef()) {
-    if (!uri) {
-      return nullptr;
-    }
-    result = new URLAndReferrerInfo(uri,
-                                    aURL->mExtraData->GetReferrer(),
-                                    aURL->mExtraData->GetReferrerPolicy());
-    return result.forget();
-  }
-
-  nsCOMPtr<nsIURI> baseURI =
-    SVGObserverUtils::GetBaseURLForLocalRef(aFrame->GetContent(), uri);
-
-  nsCOMPtr<nsIURI> resolvedURI = aURL->ResolveLocalRef(baseURI);
-  if (!resolvedURI) {
-    return nullptr;
-  }
-
-  result = new URLAndReferrerInfo(resolvedURI,
-                                  aURL->mExtraData->GetReferrer(),
-                                  aURL->mExtraData->GetReferrerPolicy());
-  return result.forget();
-}
-
 already_AddRefed<URLAndReferrerInfo>
 SVGObserverUtils::GetMarkerURI(nsIFrame* aFrame,
                                RefPtr<css::URLValue> nsStyleSVG::* aMarker)
 {
   return ResolveURLUsingLocalRef(aFrame, aFrame->StyleSVG()->*aMarker);
 }
 
 already_AddRefed<URLAndReferrerInfo>
-SVGObserverUtils::GetClipPathURI(nsIFrame* aFrame)
-{
-  const nsStyleSVGReset* svgResetStyle = aFrame->StyleSVGReset();
-  MOZ_ASSERT(svgResetStyle->mClipPath.GetType() == StyleShapeSourceType::URL);
-
-  css::URLValue* url = svgResetStyle->mClipPath.GetURL();
-  return ResolveURLUsingLocalRef(aFrame, url);
-}
-
-already_AddRefed<URLAndReferrerInfo>
 SVGObserverUtils::GetFilterURI(nsIFrame* aFrame, uint32_t aIndex)
 {
   const nsStyleEffects* effects = aFrame->StyleEffects();
   MOZ_ASSERT(effects->mFilters.Length() > aIndex);
   MOZ_ASSERT(effects->mFilters[aIndex].GetType() == NS_STYLE_FILTER_URL);
 
   return ResolveURLUsingLocalRef(aFrame, effects->mFilters[aIndex].GetURL());
 }
--- a/layout/svg/SVGObserverUtils.h
+++ b/layout/svg/SVGObserverUtils.h
@@ -70,26 +70,35 @@ public:
 private:
   ~URLAndReferrerInfo() = default;
 
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIURI> mReferrer;
   mozilla::net::ReferrerPolicy mReferrerPolicy;
 };
 
-/*
+/**
  * This interface allows us to be notified when a piece of SVG content is
  * re-rendered.
  *
- * Concrete implementations of this interface need to implement
- * "GetTarget()" to specify the piece of SVG content that they'd like to
- * monitor, and they need to implement "OnRenderingChange" to specify how
- * we'll react when that content gets re-rendered. They also need to implement
- * a constructor and destructor, which should call StartObserving and
- * StopObserving, respectively.
+ * Concrete implementations of this base class need to implement
+ * GetReferencedElementWithoutObserving to specify the SVG element that
+ * they'd like to monitor for rendering changes, and they need to implement
+ * OnRenderingChange to specify how we'll react when that content gets
+ * re-rendered.  They also need to implement a constructor and destructor,
+ * which should call StartObserving and StopObserving, respectively.
+ *
+ * The referenced element is generally looked up and stored during
+ * construction.  If the referenced element is in an extenal SVG resource
+ * document, the lookup code will initiate loading of the external resource and
+ * OnRenderingChange will be called once the element in the external resource
+ * is available.
+ *
+ * Although the referenced element may be found and stored during construction,
+ * observing for rendering changes does not start until requested.
  */
 class SVGRenderingObserver : public nsStubMutationObserver
 {
 
 protected:
   virtual ~SVGRenderingObserver() = default;
 
 public:
@@ -115,24 +124,25 @@ public:
    */
   void OnNonDOMMutationRenderingChange();
 
   // When a SVGRenderingObserver list gets forcibly cleared, it uses this
   // callback to notify every observer that's cleared from it, so they can
   // react.
   void NotifyEvictedFromRenderingObserverList();
 
-  nsIFrame* GetReferencedFrame();
+  nsIFrame* GetAndObserveReferencedFrame();
   /**
    * @param aOK this is only for the convenience of callers. We set *aOK to false
    * if the frame is the wrong type
    */
-  nsIFrame* GetReferencedFrame(mozilla::LayoutFrameType aFrameType, bool* aOK);
+  nsIFrame* GetAndObserveReferencedFrame(mozilla::LayoutFrameType aFrameType,
+                                         bool* aOK);
 
-  Element* GetReferencedElement();
+  Element* GetAndObserveReferencedElement();
 
   virtual bool ObservesReflow() { return true; }
 
 protected:
   void StartObserving();
   void StopObserving();
 
   /**
@@ -144,28 +154,26 @@ protected:
    * SVGObserverUtils::InvalidateDirectRenderingObservers is called for the
    * observed element's frame.
    *
    * Subclasses should override this method to handle rendering changes
    * appropriately.
    */
   virtual void OnRenderingChange() = 0;
 
-  // This is an internally-used version of GetReferencedElement that doesn't
-  // forcibly add us as an observer. (whereas GetReferencedElement does)
-  virtual Element* GetTarget() = 0;
+  virtual Element* GetReferencedElementWithoutObserving() = 0;
 
   // Whether we're in our referenced element's observer list at this time.
   bool mInObserverList;
 };
 
 
 /*
  * SVG elements reference supporting resources by element ID. We need to
- * track when those resources change and when the DOM changes in ways
+ * track when those resources change and when the document changes in ways
  * that affect which element is referenced by a given ID (e.g., when
  * element IDs change). The code here is responsible for that.
  *
  * When a frame references a supporting resource, we create a property
  * object derived from SVGIDRenderingObserver to manage the relationship. The
  * property object is attached to the referencing frame.
  */
 class SVGIDRenderingObserver : public SVGRenderingObserver
@@ -174,17 +182,19 @@ public:
   typedef mozilla::dom::Element Element;
   typedef mozilla::dom::IDTracker IDTracker;
 
   SVGIDRenderingObserver(URLAndReferrerInfo* aURI, nsIContent* aObservingContent,
                          bool aReferenceImage);
   virtual ~SVGIDRenderingObserver();
 
 protected:
-  Element* GetTarget() override { return mObservedElementTracker.get(); }
+  Element* GetReferencedElementWithoutObserving() override {
+    return mObservedElementTracker.get();
+  }
 
   void OnRenderingChange() override;
 
   /**
    * Helper that provides a reference to the element with the ID that our
    * observer wants to observe, and that will invalidate our observer if the
    * element that that ID identifies changes to a different element (or none).
    */
@@ -309,24 +319,26 @@ public:
   SVGFilterObserver(URLAndReferrerInfo* aURI,
                     nsIContent* aObservingContent,
                     SVGFilterObserverList* aFilterChainObserver)
     : SVGIDRenderingObserver(aURI, aObservingContent, false)
     , mFilterObserverList(aFilterChainObserver)
   {
   }
 
-  bool ReferencesValidResource() { return GetFilterFrame(); }
+  // XXXjwatt: This will return false if the reference is to a filter in an
+  // external resource document that hasn't loaded yet!
+  bool ReferencesValidResource() { return GetAndObserveFilterFrame(); }
 
   void DetachFromChainObserver() { mFilterObserverList = nullptr; }
 
   /**
    * @return the filter frame, or null if there is no filter frame
    */
-  nsSVGFilterFrame *GetFilterFrame();
+  nsSVGFilterFrame* GetAndObserveFilterFrame();
 
   // nsISupports
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(SVGFilterObserver)
 
   void Invalidate() { OnRenderingChange(); };
 
 protected:
@@ -566,22 +578,16 @@ public:
   NS_DECLARE_FRAME_PROPERTY_RELEASABLE(StrokeProperty, nsSVGPaintingProperty)
   NS_DECLARE_FRAME_PROPERTY_RELEASABLE(HrefAsTextPathProperty,
                                        SVGTextPathObserver)
   NS_DECLARE_FRAME_PROPERTY_DELETABLE(BackgroundImageProperty,
                                       URIObserverHashtable)
 
   struct EffectProperties {
     SVGMaskObserverList* mMaskObservers;
-    nsSVGPaintingProperty* mClipPath;
-
-    /**
-     * @return the clip-path frame, or null if there is no clip-path frame
-     */
-    nsSVGClipPathFrame* GetClipPathFrame();
 
     /**
      * @return an array which contains all SVG mask frames.
      */
     nsTArray<nsSVGMaskFrame*> GetMaskFrames();
 
     /*
      * @return true if all effects we have are valid or we have no effect
@@ -592,29 +598,16 @@ public:
     /*
      * @return true if we have any invalid effect.
      */
     bool HasInvalidEffects() {
       return !HasNoOrValidEffects();
     }
 
     /*
-     * @return true if we either do not have clip-path or have a valid
-     * clip-path.
-     */
-    bool HasNoOrValidClipPath();
-
-    /*
-     * @return true if we have an invalid clip-path.
-     */
-    bool HasInvalidClipPath() {
-      return !HasNoOrValidClipPath();
-    }
-
-    /*
      * @return true if we either do not have mask or all masks we have
      * are valid.
      */
     bool HasNoOrValidMask();
 
     /*
      * @return true if we have an invalid mask.
      */
@@ -624,16 +617,24 @@ public:
   };
 
   /**
    * @param aFrame should be the first continuation
    */
   static EffectProperties GetEffectProperties(nsIFrame* aFrame);
 
   /**
+   * Ensures that that if the given frame requires any resources that are in
+   * SVG resource documents that the loading of those documents is initiated.
+   * This does not make aFrame start to observe any elements that it
+   * references.
+   */
+  static void InitiateResourceDocLoads(nsIFrame* aFrame);
+
+  /**
    * Called when changes to an element (e.g. CSS property changes) cause its
    * frame to start/stop referencing (or reference different) SVG resource
    * elements. (_Not_ called for changes to referenced resource elements.)
    *
    * This function handles such changes by discarding _all_ the frame's SVG
    * effects frame properties (causing those properties to stop watching their
    * target element). It also synchronously (re)creates the filter and marker
    * frame properties (XXX why not the other properties?), which makes it
@@ -769,16 +770,37 @@ public:
    * in OnRenderingChange if that pointer is null indicates that this isn't
    * even doing anything useful in terms of preventing further invalidation
    * from any observed filters.
    */
   static void
   DetachFromCanvasContext(nsISupports* aAutoObserver);
 
   /**
+   * Get the frame of the SVG clipPath applied to aClippedFrame, if any, and
+   * set up aClippedFrame as a rendering observer of the clipPath's frame, to
+   * be invalidated if it changes.
+   *
+   * Currently we only have support for 'clip-path' with a single item, but the
+   * spec. now says 'clip-path' can be set to an arbitrary number of items.
+   * Once we support that, aClipPathFrame will need to be an nsTArray as it
+   * is for 'filter' and 'mask'.  Currently a return value of eHasNoRefs means
+   * that there is no clipping at all, but once we support more than one item
+   * then - as for filter and mask - we could still have basic shape clipping
+   * to apply even if there are no references to SVG clipPath elements.
+   *
+   * Note that, unlike for filters, a reference to an ID that doesn't exist
+   * is not invalid for clip-path or mask.  We will return eHasNoRefs in that
+   * case.
+   */
+  static ReferenceState
+  GetAndObserveClipPath(nsIFrame* aClippedFrame,
+                        nsSVGClipPathFrame** aClipPathFrame);
+
+  /**
    * Get the SVGGeometryElement that is referenced by aTextPathFrame, and make
    * aTextPathFrame start observing rendering changes to that element.
    */
   static SVGGeometryElement*
   GetTextPathsReferencedPath(nsIFrame* aTextPathFrame);
 
   /**
    * Make aTextPathFrame stop observing rendering changes to the
@@ -825,22 +847,16 @@ public:
   /**
    * A helper function to resolve marker's URL.
    */
   static already_AddRefed<URLAndReferrerInfo>
   GetMarkerURI(nsIFrame* aFrame,
                RefPtr<mozilla::css::URLValue> nsStyleSVG::* aMarker);
 
   /**
-   * A helper function to resolve clip-path URL.
-   */
-  static already_AddRefed<URLAndReferrerInfo>
-  GetClipPathURI(nsIFrame* aFrame);
-
-  /**
    * A helper function to resolve filter URL.
    */
   static already_AddRefed<URLAndReferrerInfo>
   GetFilterURI(nsIFrame* aFrame, uint32_t aIndex);
 
   /**
    * A helper function to resolve filter URL.
    */
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -141,18 +141,19 @@ nsSVGClipPathFrame::PaintClipMask(gfxCon
 
   // Paint this clipPath's contents into aMaskDT:
   // We need to set mMatrixForChildren here so that under the PaintSVG calls
   // on our children (below) our GetCanvasTM() method will return the correct
   // transform.
   mMatrixForChildren = GetClipPathTransform(aClippedFrame) * aMatrix;
 
   // Check if this clipPath is itself clipped by another clipPath:
-  nsSVGClipPathFrame* clipPathThatClipsClipPath =
-    SVGObserverUtils::GetEffectProperties(this).GetClipPathFrame();
+  nsSVGClipPathFrame* clipPathThatClipsClipPath;
+  // XXX check return value?
+  SVGObserverUtils::GetAndObserveClipPath(this, &clipPathThatClipsClipPath);
   nsSVGUtils::MaskUsage maskUsage;
   nsSVGUtils::DetermineMaskUsage(this, true, maskUsage);
 
   if (maskUsage.shouldApplyClipPath) {
     clipPathThatClipsClipPath->ApplyClipPath(aMaskContext, aClippedFrame,
                                              aMatrix);
   } else if (maskUsage.shouldGenerateClipMaskLayer) {
     Matrix maskTransform;
@@ -198,23 +199,22 @@ nsSVGClipPathFrame::PaintFrameIntoMask(n
   if (!frame) {
     return;
   }
 
   // The CTM of each frame referencing us can be different.
   frame->NotifySVGChanged(nsSVGDisplayableFrame::TRANSFORM_CHANGED);
 
   // Children of this clipPath may themselves be clipped.
-  SVGObserverUtils::EffectProperties effectProperties =
-    SVGObserverUtils::GetEffectProperties(aFrame);
-  if (effectProperties.HasInvalidClipPath()) {
+  nsSVGClipPathFrame* clipPathThatClipsChild;
+  // XXX check return value?
+  if (SVGObserverUtils::GetAndObserveClipPath(aFrame, &clipPathThatClipsChild) ==
+        SVGObserverUtils::eHasRefsSomeInvalid) {
     return;
   }
-  nsSVGClipPathFrame *clipPathThatClipsChild =
-    effectProperties.GetClipPathFrame();
 
   nsSVGUtils::MaskUsage maskUsage;
   nsSVGUtils::DetermineMaskUsage(aFrame, true, maskUsage);
   if (maskUsage.shouldApplyClipPath) {
     clipPathThatClipsChild->ApplyClipPath(aTarget, aClippedFrame, aMatrix);
   } else if (maskUsage.shouldGenerateClipMaskLayer) {
     Matrix maskTransform;
     RefPtr<SourceSurface> maskSurface =
@@ -301,18 +301,19 @@ nsSVGClipPathFrame::PointIsInsideClipPat
   }
   gfxPoint point = matrix.TransformPoint(aPoint);
 
   // clipPath elements can themselves be clipped by a different clip path. In
   // that case the other clip path further clips away the element that is being
   // clipped by the original clipPath. If this clipPath is being clipped by a
   // different clip path we need to check if it prevents the original element
   // from receiving events at aPoint:
-  nsSVGClipPathFrame *clipPathFrame =
-    SVGObserverUtils::GetEffectProperties(this).GetClipPathFrame();
+  nsSVGClipPathFrame* clipPathFrame;
+  // XXX check return value?
+  SVGObserverUtils::GetAndObserveClipPath(this, &clipPathFrame);
   if (clipPathFrame &&
       !clipPathFrame->PointIsInsideClipPath(aClippedFrame, aPoint)) {
     return false;
   }
 
   for (nsIFrame* kid = mFrames.FirstChild(); kid;
        kid = kid->GetNextSibling()) {
     nsSVGDisplayableFrame* SVGFrame = do_QueryFrame(kid);
@@ -334,18 +335,20 @@ nsSVGClipPathFrame::PointIsInsideClipPat
 
   return false;
 }
 
 bool
 nsSVGClipPathFrame::IsTrivial(nsSVGDisplayableFrame **aSingleChild)
 {
   // If the clip path is clipped then it's non-trivial
-  if (SVGObserverUtils::GetEffectProperties(this).GetClipPathFrame())
+  if (SVGObserverUtils::GetAndObserveClipPath(this, nullptr) ==
+        SVGObserverUtils::eHasRefsAllValid) {
     return false;
+  }
 
   if (aSingleChild) {
     *aSingleChild = nullptr;
   }
 
   nsSVGDisplayableFrame* foundChild = nullptr;
 
   for (nsIFrame* kid = mFrames.FirstChild(); kid;
@@ -353,18 +356,20 @@ nsSVGClipPathFrame::IsTrivial(nsSVGDispl
     nsSVGDisplayableFrame* svgChild = do_QueryFrame(kid);
     if (svgChild) {
       // We consider a non-trivial clipPath to be one containing
       // either more than one svg child and/or a svg container
       if (foundChild || svgChild->IsDisplayContainer())
         return false;
 
       // or where the child is itself clipped
-      if (SVGObserverUtils::GetEffectProperties(kid).GetClipPathFrame())
+      if (SVGObserverUtils::GetAndObserveClipPath(kid, nullptr) ==
+            SVGObserverUtils::eHasRefsAllValid) {
         return false;
+      }
 
       foundChild = svgChild;
     }
   }
   if (aSingleChild) {
     *aSingleChild = foundChild;
   }
   return true;
@@ -379,17 +384,18 @@ nsSVGClipPathFrame::IsValid()
   // that must all be applied.  We re-enter this method for each clipPath in a
   // chain, so we need to protect against reference chain related crashes etc.:
   AutoReferenceChainGuard refChainGuard(this, &mIsBeingProcessed,
                                         &sRefChainLengthCounter);
   if (MOZ_UNLIKELY(!refChainGuard.Reference())) {
     return false; // Break reference chain
   }
 
-  if (SVGObserverUtils::GetEffectProperties(this).HasInvalidClipPath()) {
+  if (SVGObserverUtils::GetAndObserveClipPath(this, nullptr) ==
+        SVGObserverUtils::eHasRefsSomeInvalid) {
     return false;
   }
 
   for (nsIFrame* kid = mFrames.FirstChild(); kid;
        kid = kid->GetNextSibling()) {
 
     LayoutFrameType kidType = kid->Type();
 
@@ -473,51 +479,46 @@ nsSVGClipPathFrame::GetClipPathTransform
                                           aClippedFrame, flags);
 }
 
 SVGBBox
 nsSVGClipPathFrame::GetBBoxForClipPathFrame(const SVGBBox &aBBox,
                                             const gfxMatrix &aMatrix,
                                             uint32_t aFlags)
 {
+  nsSVGClipPathFrame* clipPathThatClipsClipPath;
+  if (SVGObserverUtils::GetAndObserveClipPath(this, &clipPathThatClipsClipPath) ==
+        SVGObserverUtils::eHasRefsSomeInvalid) {
+    return SVGBBox();
+  }
+
   nsIContent* node = GetContent()->GetFirstChild();
   SVGBBox unionBBox, tmpBBox;
   for (; node; node = node->GetNextSibling()) {
     nsSVGElement* svgNode = static_cast<nsSVGElement*>(node);
     nsIFrame* frame = svgNode->GetPrimaryFrame();
     if (frame) {
       nsSVGDisplayableFrame* svg = do_QueryFrame(frame);
       if (svg) {
         gfxMatrix matrix = svgNode->PrependLocalTransformsTo(aMatrix, eUserSpaceToParent);
         tmpBBox = svg->GetBBoxContribution(mozilla::gfx::ToMatrix(matrix),
                                            nsSVGUtils::eBBoxIncludeFill);
-        SVGObserverUtils::EffectProperties effectProperties =
-                              SVGObserverUtils::GetEffectProperties(frame);
-        if (effectProperties.HasNoOrValidClipPath()) {
-          nsSVGClipPathFrame *clipPathFrame =
-            effectProperties.GetClipPathFrame();
-          if (clipPathFrame) {
-            tmpBBox = clipPathFrame->GetBBoxForClipPathFrame(tmpBBox, aMatrix, aFlags);
-          }
+        nsSVGClipPathFrame* clipPathFrame;
+        if (SVGObserverUtils::GetAndObserveClipPath(frame, &clipPathFrame) !=
+              SVGObserverUtils::eHasRefsSomeInvalid &&
+            clipPathFrame) {
+          tmpBBox = clipPathFrame->GetBBoxForClipPathFrame(tmpBBox, aMatrix, aFlags);
         }
         if (!(aFlags & nsSVGUtils::eDoNotClipToBBoxOfContentInsideClipPath)) {
           tmpBBox.Intersect(aBBox);
         }
         unionBBox.UnionEdges(tmpBBox);
       }
     }
   }
 
-  SVGObserverUtils::EffectProperties props =
-    SVGObserverUtils::GetEffectProperties(this);
-  if (props.mClipPath) {
-    if (props.HasInvalidClipPath()) {
-      unionBBox = SVGBBox();
-    } else  {
-      nsSVGClipPathFrame *clipPathFrame = props.GetClipPathFrame();
-      if (clipPathFrame) {
-        tmpBBox = clipPathFrame->GetBBoxForClipPathFrame(aBBox, aMatrix, aFlags);
-        unionBBox.Intersect(tmpBBox);
-      }
-    }
+  if (clipPathThatClipsClipPath) {
+    tmpBBox =
+      clipPathThatClipsClipPath->GetBBoxForClipPathFrame(aBBox, aMatrix, aFlags);
+    unionBBox.Intersect(tmpBBox);
   }
   return unionBBox;
 }
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -870,17 +870,19 @@ nsSVGIntegrationUtils::PaintMask(const P
   if (maskUsage.shouldGenerateClipMaskLayer || maskUsage.shouldApplyClipPath) {
     matSR.Restore();
     matSR.SetContext(&ctx);
 
     MoveContextOriginToUserSpace(firstFrame, aParams);
     Matrix clipMaskTransform;
     gfxMatrix cssPxToDevPxMatrix = nsSVGUtils::GetCSSPxToDevPxMatrix(frame);
 
-    nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame();
+    nsSVGClipPathFrame* clipPathFrame;
+    // XXX check return value?
+    SVGObserverUtils::GetAndObserveClipPath(firstFrame, &clipPathFrame);
     RefPtr<SourceSurface> maskSurface =
       maskUsage.shouldGenerateMaskLayer ? maskTarget->Snapshot() : nullptr;
     clipPathFrame->PaintClipMask(ctx, frame, cssPxToDevPxMatrix,
                                    &clipMaskTransform, maskSurface,
                                    ctx.CurrentMatrix());
   }
 
   return true;
@@ -924,17 +926,19 @@ void PaintMaskAndClipPathInternal(const 
 
   /* Properties are added lazily and may have been removed by a restyle,
      so make sure all applicable ones are set again. */
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(frame);
   SVGObserverUtils::EffectProperties effectProperties =
     SVGObserverUtils::GetEffectProperties(firstFrame);
 
-  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame();
+  nsSVGClipPathFrame* clipPathFrame;
+  // XXX check return value?
+  SVGObserverUtils::GetAndObserveClipPath(firstFrame, &clipPathFrame);
 
   gfxMatrix cssPxToDevPxMatrix = nsSVGUtils::GetCSSPxToDevPxMatrix(frame);
   nsTArray<nsSVGMaskFrame*> maskFrames = effectProperties.GetMaskFrames();
 
   bool shouldGenerateMask = (maskUsage.opacity != 1.0f ||
                              maskUsage.shouldGenerateClipMaskLayer ||
                              maskUsage.shouldGenerateMaskLayer);
   bool shouldPushMask = false;
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -490,17 +490,19 @@ nsSVGUtils::DetermineMaskUsage(nsIFrame*
   SVGObserverUtils::EffectProperties effectProperties =
     SVGObserverUtils::GetEffectProperties(firstFrame);
   const nsStyleSVGReset *svgReset = firstFrame->StyleSVGReset();
 
   nsTArray<nsSVGMaskFrame*> maskFrames = effectProperties.GetMaskFrames();
 
   aUsage.shouldGenerateMaskLayer = (maskFrames.Length() > 0);
 
-  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame();
+  nsSVGClipPathFrame* clipPathFrame;
+  // XXX check return value?
+  SVGObserverUtils::GetAndObserveClipPath(firstFrame, &clipPathFrame);
   MOZ_ASSERT(!clipPathFrame ||
              svgReset->mClipPath.GetType() == StyleShapeSourceType::URL);
 
   switch (svgReset->mClipPath.GetType()) {
     case StyleShapeSourceType::URL:
       if (clipPathFrame) {
         if (clipPathFrame->IsTrivial()) {
           aUsage.shouldApplyClipPath = true;
@@ -706,29 +708,31 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
    * + Use cairo's clipPath when representable natively (single object
    *   clip region).
    *f
    * + Merge opacity and masking if both used together.
    */
 
   /* Properties are added lazily and may have been removed by a restyle,
      so make sure all applicable ones are set again. */
+  nsSVGClipPathFrame* clipPathFrame;
   SVGObserverUtils::EffectProperties effectProperties =
     SVGObserverUtils::GetEffectProperties(aFrame);
   // TODO: We currently pass nullptr instead of an nsTArray* here, but we
   // actually should get the filter frames and then pass them into
   // PaintFilteredFrame below!  See bug 1494263.
   if (effectProperties.HasInvalidEffects() ||
       SVGObserverUtils::GetAndObserveFilters(aFrame, nullptr) ==
+        SVGObserverUtils::eHasRefsSomeInvalid ||
+      SVGObserverUtils::GetAndObserveClipPath(aFrame, &clipPathFrame) ==
         SVGObserverUtils::eHasRefsSomeInvalid) {
     // Some resource is invalid. We shouldn't paint anything.
     return;
   }
 
-  nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame();
   nsTArray<nsSVGMaskFrame*> masks = effectProperties.GetMaskFrames();
   nsSVGMaskFrame *maskFrame = masks.IsEmpty() ? nullptr : masks[0];
 
   MixModeBlender blender(aFrame, &aContext);
   gfxContext* target = blender.ShouldCreateDrawTargetForBlend()
                        ? blender.CreateBlendTarget(aTransform) : &aContext;
 
   if (!target) {
@@ -867,39 +871,28 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
     MOZ_ASSERT(target != &aContext);
     blender.BlendToTarget();
   }
 }
 
 bool
 nsSVGUtils::HitTestClip(nsIFrame *aFrame, const gfxPoint &aPoint)
 {
-  SVGObserverUtils::EffectProperties props =
-    SVGObserverUtils::GetEffectProperties(aFrame);
-  if (!props.mClipPath) {
-    const nsStyleSVGReset *style = aFrame->StyleSVGReset();
-    if (style->HasClipPath()) {
-      return nsCSSClipPathInstance::HitTestBasicShapeOrPathClip(aFrame, aPoint);
-    }
-    return true;
+  nsSVGClipPathFrame* clipPathFrame;
+  if (SVGObserverUtils::GetAndObserveClipPath(aFrame, &clipPathFrame) ==
+        SVGObserverUtils::eHasRefsSomeInvalid) {
+    return false; // everything clipped away if clip path is invalid
   }
-
-  if (props.HasInvalidClipPath()) {
-    // clipPath is not a valid resource, so nothing gets painted, so
-    // hit-testing must fail.
-    return false;
+  if (clipPathFrame) {
+    return clipPathFrame->PointIsInsideClipPath(aFrame, aPoint);
   }
-  nsSVGClipPathFrame *clipPathFrame = props.GetClipPathFrame();
-
-  if (!clipPathFrame) {
-    // clipPath doesn't exist, ignore it.
-    return true;
+  if (aFrame->StyleSVGReset()->HasClipPath()) {
+    return nsCSSClipPathInstance::HitTestBasicShapeOrPathClip(aFrame, aPoint);
   }
-
-  return clipPathFrame->PointIsInsideClipPath(aFrame, aPoint);
+  return true;
 }
 
 nsIFrame *
 nsSVGUtils::HitTestChildren(nsSVGDisplayContainerFrame* aFrame,
                             const gfxPoint& aPoint)
 {
   // First we transform aPoint into the coordinate space established by aFrame
   // for its children (e.g. take account of any 'viewBox' attribute):
@@ -1157,23 +1150,21 @@ nsSVGUtils::GetBBox(nsIFrame* aFrame, ui
     bool hasClip = aFrame->StyleDisplay()->IsScrollableOverflow();
     if (hasClip) {
       clipRect =
         nsSVGUtils::GetClipRectForFrame(aFrame, x, y, width, height);
       if (aFrame->IsSVGForeignObjectFrame() || aFrame->IsSVGUseFrame()) {
         clipRect = matrix.TransformBounds(clipRect);
       }
     }
-    SVGObserverUtils::EffectProperties effectProperties =
-      SVGObserverUtils::GetEffectProperties(aFrame);
-    if (effectProperties.HasInvalidClipPath()) {
+    nsSVGClipPathFrame* clipPathFrame;
+    if (SVGObserverUtils::GetAndObserveClipPath(aFrame, &clipPathFrame) ==
+          SVGObserverUtils::eHasRefsSomeInvalid) {
       bbox = gfxRect(0, 0, 0, 0);
     } else {
-      nsSVGClipPathFrame *clipPathFrame =
-        effectProperties.GetClipPathFrame();
       if (clipPathFrame) {
         SVGClipPathElement *clipContent =
           static_cast<SVGClipPathElement*>(clipPathFrame->GetContent());
         if (clipContent->IsUnitsObjectBoundingBox()) {
           matrix.PreTranslate(gfxPoint(x, y));
           matrix.PreScale(width, height);
         } else if (aFrame->IsSVGForeignObjectFrame()) {
           matrix = gfxMatrix();
--- a/testing/geckodriver/src/marionette.rs
+++ b/testing/geckodriver/src/marionette.rs
@@ -94,39 +94,37 @@ impl MarionetteHandler {
 
     pub fn create_connection(
         &mut self,
         session_id: &Option<String>,
         new_session_parameters: &NewSessionParameters,
     ) -> WebDriverResult<Map<String, Value>> {
         let (options, capabilities) = {
             let mut fx_capabilities = FirefoxCapabilities::new(self.settings.binary.as_ref());
-            let mut capabilities = try!(
-                try!(new_session_parameters.match_browser(&mut fx_capabilities)).ok_or(
-                    WebDriverError::new(
-                        ErrorStatus::SessionNotCreated,
-                        "Unable to find a matching set of capabilities",
-                    ),
-                )
-            );
+            let mut capabilities = new_session_parameters
+                .match_browser(&mut fx_capabilities)?
+                .ok_or(WebDriverError::new(
+                    ErrorStatus::SessionNotCreated,
+                    "Unable to find a matching set of capabilities",
+                ))?;
 
-            let options = try!(FirefoxOptions::from_capabilities(
+            let options = FirefoxOptions::from_capabilities(
                 fx_capabilities.chosen_binary,
-                &mut capabilities
-            ));
+                &mut capabilities,
+            )?;
             (options, capabilities)
         };
 
         if let Some(l) = options.log.level {
             logging::set_max_level(l);
         }
 
         let port = self.settings.port.unwrap_or(get_free_port()?);
         if !self.settings.connect_existing {
-            try!(self.start_browser(port, options));
+            self.start_browser(port, options)?;
         }
 
         let mut connection = MarionetteConnection::new(port, session_id.clone());
         connection.connect(&mut self.browser).or_else(|e| {
             if let Some(ref mut runner) = self.browser {
                 runner.kill()?;
             }
             Err(e)
@@ -205,34 +203,31 @@ impl MarionetteHandler {
             if !custom_profile || !prefs.contains_key(name) {
                 prefs.insert((*name).clone(), (*value).clone());
             }
         }
 
         prefs.insert_slice(&extra_prefs[..]);
 
         if self.settings.jsdebugger {
-            prefs.insert(
-                "devtools.browsertoolbox.panel",
-                Pref::new("jsdebugger".to_owned()),
-            );
+            prefs.insert("devtools.browsertoolbox.panel", Pref::new("jsdebugger"));
             prefs.insert("devtools.debugger.remote-enabled", Pref::new(true));
             prefs.insert("devtools.chrome.enabled", Pref::new(true));
             prefs.insert("devtools.debugger.prompt-connection", Pref::new(false));
             prefs.insert("marionette.debugging.clicktostart", Pref::new(true));
         }
 
-        prefs.insert(
-            "marionette.log.level",
-            Pref::new(logging::max_level().to_string()),
-        );
+        prefs.insert("marionette.log.level", logging::max_level().into());
         prefs.insert("marionette.port", Pref::new(port));
 
-        prefs.write().map_err(|_| {
-            WebDriverError::new(ErrorStatus::UnknownError, "Unable to write Firefox profile")
+        prefs.write().map_err(|e| {
+            WebDriverError::new(
+                ErrorStatus::UnknownError,
+                format!("Unable to write Firefox profile: {}", e),
+            )
         })
     }
 }
 
 impl WebDriverHandler<GeckoExtensionRoute> for MarionetteHandler {
     fn handle_command(
         &mut self,
         _: &Option<Session>,
@@ -1482,9 +1477,37 @@ impl ToMarionette for WindowRectParamete
             serde_json::to_value(self)?.as_object(),
             ErrorStatus::UnknownError,
             "Expected an object"
         ).clone())
     }
 }
 
 #[cfg(test)]
-mod tests {}
+mod tests {
+    use super::{MarionetteHandler, MarionetteSettings};
+    use mozprofile::preferences::PrefValue;
+    use mozprofile::profile::Profile;
+
+    // This is not a pretty test, mostly due to the nature of
+    // mozprofile's and MarionetteHandler's APIs, but we have had
+    // several regressions related to marionette.log.level.
+    #[test]
+    fn test_marionette_log_level() {
+        let mut profile = Profile::new(None).unwrap();
+        let handler = MarionetteHandler::new(MarionetteSettings::default());
+        handler.set_prefs(2828, &mut profile, false, vec![]).ok();
+        let user_prefs = profile.user_prefs().unwrap();
+
+        let pref = user_prefs.get("marionette.log.level").unwrap();
+        let value = match pref.value {
+            PrefValue::String(ref s) => s,
+            _ => panic!(),
+        };
+        for (i, ch) in value.chars().enumerate() {
+            if i == 0 {
+                assert!(ch.is_uppercase());
+            } else {
+                assert!(ch.is_lowercase());
+            }
+        }
+    }
+}
--- a/testing/mozbase/rust/mozprofile/src/preferences.rs
+++ b/testing/mozbase/rust/mozprofile/src/preferences.rs
@@ -74,26 +74,29 @@ impl From<i64> for PrefValue {
 
 #[derive(Debug, PartialEq, Clone)]
 pub struct Pref {
     pub value: PrefValue,
     pub sticky: bool,
 }
 
 impl Pref {
+    /// Create a new preference with `value`.
     pub fn new<T>(value: T) -> Pref
     where
         T: Into<PrefValue>,
     {
         Pref {
             value: value.into(),
             sticky: false,
         }
     }
 
+    /// Create a new sticky, or locked, preference with `value`.
+    /// These cannot be changed by the user in `about:config`.
     pub fn new_sticky<T>(value: T) -> Pref
     where
         T: Into<PrefValue>,
     {
         Pref {
             value: value.into(),
             sticky: true,
         }
--- a/testing/web-platform/meta/payment-request/MerchantValidationEvent/complete-method.https.html.ini
+++ b/testing/web-platform/meta/payment-request/MerchantValidationEvent/complete-method.https.html.ini
@@ -1,4 +1,5 @@
 [complete-method.https.html]
   [If event's isTrusted attribute is false, then then throw an InvalidStateError DOMException.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/MerchantValidationEvent/constructor.https.html.ini
+++ b/testing/web-platform/meta/payment-request/MerchantValidationEvent/constructor.https.html.ini
@@ -1,34 +1,45 @@
 [constructor.https.html]
   [MerchantValidationEvent can be dispatched, even if not trusted.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent can be constructed with an EventInitDict, even if not trusted.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Relative validationURLs use the document as the base.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Must have a validationURL IDL attribute, which is initialized with to the validationURL dictionary value.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent can be constructed in secure-context.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Must throw if initialized with an invalid URL.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Must throw TypeError if initialized with an invalid URL.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [When no methodName is passed, methodName attribute defaults to the empty string]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent can be constructed with valid PMIs]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent can't be constructed with invalid PMIs]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Must have a methodName IDL attribute, which is initialized with to the methodName dictionary value.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/PaymentItem/type_member.https.html.ini
+++ b/testing/web-platform/meta/payment-request/PaymentItem/type_member.https.html.ini
@@ -1,13 +1,17 @@
 [type_member.https.html]
   [Smoke test]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [An invalid enum value for PaymentDetailsInit.total's type throws TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Invalid enum value for PaymentItem.type member throws a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Valid enum values for PaymentItem.type member does not throw]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/PaymentMethodChangeEvent/methodDetails-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/PaymentMethodChangeEvent/methodDetails-attribute.https.html.ini
@@ -1,7 +1,9 @@
 [methodDetails-attribute.https.html]
   [Must have a methodDetails IDL attribute, which is initialized with to the methodName dictionary value]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [The methodDetails member defaults to null]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/PaymentMethodChangeEvent/methodName-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/PaymentMethodChangeEvent/methodName-attribute.https.html.ini
@@ -1,7 +1,9 @@
 [methodName-attribute.https.html]
   [Must have a methodName IDL attribute, which is initialized with to the methodName dictionary value]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [When no dictionary is passed, the methodName member defaults to the empty string]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/PaymentRequestUpdateEvent/constructor.https.html.ini
+++ b/testing/web-platform/meta/payment-request/PaymentRequestUpdateEvent/constructor.https.html.ini
@@ -1,10 +1,13 @@
 [constructor.https.html]
   [PaymentRequestUpdateEvent can be constructed in secure-context]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent can be constructed with an EventInitDict, even if not trusted]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent can be dispatched, even if not trusted]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/PaymentRequestUpdateEvent/updatewith-method.https.html.ini
+++ b/testing/web-platform/meta/payment-request/PaymentRequestUpdateEvent/updatewith-method.https.html.ini
@@ -1,10 +1,13 @@
 [updatewith-method.https.html]
   [Let target be the request which is dispatching the event.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Calling .updateWith() with an undispatched untrusted event throws "InvalidStateError"]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Calling .updateWith() with a dispatched, untrusted event, throws "InvalidStateError"]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/payment-request/__dir__.ini
@@ -0,0 +1,1 @@
+prefs: [dom.payments.request.enabled:true]
--- a/testing/web-platform/meta/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub.html.ini
+++ b/testing/web-platform/meta/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub.html.ini
@@ -1,4 +1,5 @@
 [active-document-cross-origin.https.sub.html]
   [PaymentRequest <iframe allowpaymentrequest> in non-active document (cross-origin)]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/allowpaymentrequest/active-document-same-origin.https.html.ini
+++ b/testing/web-platform/meta/payment-request/allowpaymentrequest/active-document-same-origin.https.html.ini
@@ -1,4 +1,5 @@
 [active-document-same-origin.https.html]
   [PaymentRequest <iframe allowpaymentrequest> in non-active document (same-origin)]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html.ini
+++ b/testing/web-platform/meta/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html.ini
@@ -1,13 +1,16 @@
 [allowpaymentrequest-attribute-cross-origin-bc-containers.https.html]
   [iframe]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [frame]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [object]
     expected:
-      FAIL
+      if not e10s: FAIL
 
   [embed]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
--- a/testing/web-platform/meta/payment-request/allowpaymentrequest/basic.https.html.ini
+++ b/testing/web-platform/meta/payment-request/allowpaymentrequest/basic.https.html.ini
@@ -1,4 +1,5 @@
 [basic.https.html]
   [PaymentRequest <iframe allowpaymentrequest> basic]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html.ini
+++ b/testing/web-platform/meta/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html.ini
@@ -1,13 +1,17 @@
 [no-attribute-cross-origin-bc-containers.https.html]
   [iframe]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [frame]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [embed]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/historical.https.html.ini
+++ b/testing/web-platform/meta/payment-request/historical.https.html.ini
@@ -1,25 +1,33 @@
 [historical.https.html]
   [paymentRequestID in PaymentRequest]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [paymentRequestID in PaymentResponse]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [careOf in PaymentAddress]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [totalAmount in PaymentResponse]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [paymentRequestId in PaymentRequest]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [paymentRequestId in PaymentResponse]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [supportedMethods must not support sequence<DOMString>]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [languageCode in PaymentAddress]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/idlharness.https.window.js.ini
+++ b/testing/web-platform/meta/payment-request/idlharness.https.window.js.ini
@@ -1,325 +1,430 @@
 [idlharness.https.window.html]
   [PaymentRequest interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface object length]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface object name]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: operation show([object Object\])]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: operation abort()]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: operation canMakePayment()]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute id]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute shippingAddress]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute shippingOption]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute shippingType]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute onshippingaddresschange]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute onshippingoptionchange]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute onpaymentmethodchange]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest must be primary interface of paymentRequest]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [Stringification of paymentRequest]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "show([object Object\])" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: calling show([object Object\]) on paymentRequest with too few arguments must throw TypeError]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "abort()" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "canMakePayment()" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "id" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "shippingAddress" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "shippingOption" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "shippingType" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "onshippingaddresschange" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "onshippingoptionchange" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "onpaymentmethodchange" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface object length]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface object name]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: operation toJSON()]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute city]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute country]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute dependentLocality]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute languageCode]
     expected: FAIL
 
   [PaymentAddress interface: attribute organization]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute phone]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute postalCode]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute recipient]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute region]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute regionCode]
     expected: FAIL
 
   [PaymentAddress interface: attribute sortingCode]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute addressLine]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface object length]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface object name]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: operation toJSON()]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute requestId]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute methodName]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute details]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute shippingAddress]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute shippingOption]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute payerName]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute payerEmail]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute payerPhone]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: operation complete(PaymentComplete)]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentResponse interface: operation retry(PaymentValidationErrors)]
     expected: FAIL
 
   [PaymentResponse interface: attribute onpayerdetailchange]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface object length]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface object name]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: attribute methodName]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: attribute methodDetails]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent must be primary interface of new PaymentMethodChangeEvent("paymentmethodchange")]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [Stringification of new PaymentMethodChangeEvent("paymentmethodchange")]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: new PaymentMethodChangeEvent("paymentmethodchange") must inherit property "methodName" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: new PaymentMethodChangeEvent("paymentmethodchange") must inherit property "methodDetails" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: new PaymentMethodChangeEvent("paymentmethodchange") must inherit property "updateWith([object Object\])" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: calling updateWith([object Object\]) on new PaymentMethodChangeEvent("paymentmethodchange") with too few arguments must throw TypeError]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface object length]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface object name]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: operation updateWith([object Object\])]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent must be primary interface of new PaymentRequestUpdateEvent("paymentrequestupdate")]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [Stringification of new PaymentRequestUpdateEvent("paymentrequestupdate")]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: new PaymentRequestUpdateEvent("paymentrequestupdate") must inherit property "updateWith([object Object\])" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: calling updateWith([object Object\]) on new PaymentRequestUpdateEvent("paymentrequestupdate") with too few arguments must throw TypeError]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface object length]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent must be primary interface of new MerchantValidationEvent("merchantvalidation")]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: new MerchantValidationEvent("merchantvalidation") must inherit property "complete([object Object\])" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface object name]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: attribute validationURL]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: operation complete([object Object\])]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute onmerchantvalidation]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: calling complete([object Object\]) on new MerchantValidationEvent("merchantvalidation") with too few arguments must throw TypeError]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [Stringification of new MerchantValidationEvent("merchantvalidation")]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: new MerchantValidationEvent("merchantvalidation") must inherit property "validationURL" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface: paymentRequest must inherit property "onmerchantvalidation" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: attribute methodName]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: new MerchantValidationEvent("merchantvalidation") must inherit property "methodName" with the proper type]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/interfaces.https.html.ini
+++ b/testing/web-platform/meta/payment-request/interfaces.https.html.ini
@@ -1,413 +1,547 @@
 [interfaces.https.html]
   prefs: [dom.webcomponents.shadowdom.enabled:true]
   [PaymentRequest interface: existence and properties of interface object]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [PaymentRequest interface object length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface object name]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: operation show()]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: operation abort()]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute shippingAddress]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute shippingOption]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute onshippingaddresschange]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute onshippingoptionchange]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest must be primary interface of new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}})]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Stringification of new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}})]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "show" with the proper type (0)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "abort" with the proper type (1)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingAddress" with the proper type (2)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingOption" with the proper type (3)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "onshippingaddresschange" with the proper type (4)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "onshippingoptionchange" with the proper type (5)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: existence and properties of interface object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface object length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface object name]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute country]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute addressLine]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute region]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute city]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute dependentLocality]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute postalCode]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute sortingCode]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute languageCode]
     expected: FAIL
 
   [PaymentAddress interface: attribute organization]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute recipient]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute careOf]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute phone]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: existence and properties of interface object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface object length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface object name]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute methodName]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute details]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute shippingAddress]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute shippingOption]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute payerEmail]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute payerPhone]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: operation complete(PaymentComplete)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: existence and properties of interface object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface object length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface object name]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequestUpdateEvent interface: operation updateWith([object Object\])]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: operation canMakePayment()]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute id]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute shippingType]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "canMakePayment" with the proper type (2)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "id" with the proper type (3)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingAddress" with the proper type (4)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingOption" with the proper type (5)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingType" with the proper type (6)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "onshippingaddresschange" with the proper type (7)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: ['foo'\]}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "onshippingoptionchange" with the proper type (8)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute requestId]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: attribute payerName]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest must be primary interface of new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}})]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Stringification of new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}})]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "show" with the proper type (0)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "abort" with the proper type (1)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "canMakePayment" with the proper type (2)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "id" with the proper type (3)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingAddress" with the proper type (4)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingOption" with the proper type (5)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingType" with the proper type (6)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "onshippingaddresschange" with the proper type (7)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "onshippingoptionchange" with the proper type (8)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "show()" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "abort()" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "canMakePayment()" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "id" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingAddress" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingOption" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "shippingType" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "onshippingaddresschange" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'BAZ', value: '0'}}}) must inherit property "onshippingoptionchange" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: operation toJSON()]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: operation toJSON()]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Document interface: attribute origin]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest must be primary interface of new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} })]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Stringification of new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} })]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "show()" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "abort()" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "canMakePayment()" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "id" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "shippingAddress" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "shippingOption" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "shippingType" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "onshippingaddresschange" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "onshippingoptionchange" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [EventTarget interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "addEventListener(DOMString, EventListener, [object Object\],[object Object\])" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object\],[object Object\]) on new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) with too few arguments must throw TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [EventTarget interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "removeEventListener(DOMString, EventListener, [object Object\],[object Object\])" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object\],[object Object\]) on new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) with too few arguments must throw TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [EventTarget interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "dispatchEvent(Event)" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [EventTarget interface: calling dispatchEvent(Event) on new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) with too few arguments must throw TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentAddress interface: attribute regionCode]
     expected: FAIL
 
   [PaymentRequest interface: operation show([object Object\])]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "show([object Object\])" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: calling show([object Object\]) on new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) with too few arguments must throw TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute onpaymentmethodchange]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "onpaymentmethodchange" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse interface: operation retry(PaymentValidationErrors)]
     expected: FAIL
 
   [PaymentResponse interface: attribute onpayerdetailchange]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: existence and properties of interface object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface object length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface object name]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: attribute methodName]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentMethodChangeEvent interface: attribute methodDetails]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: existence and properties of interface prototype object's "constructor" property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface object length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: attribute validationURL]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: existence and properties of interface prototype object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: existence and properties of interface prototype object's @@unscopables property]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: new PaymentRequest([{supportedMethods: 'foo'}\], {total: {label: 'bar', amount: {currency: 'USD', value: '0'}} }) must inherit property "onmerchantvalidation" with the proper type]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface object name]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: existence and properties of interface object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: operation complete([object Object\])]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest interface: attribute onmerchantvalidation]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [MerchantValidationEvent interface: attribute methodName]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/onmerchantvalidation-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/onmerchantvalidation-attribute.https.html.ini
@@ -1,13 +1,17 @@
 [onmerchantvalidation-attribute.https.html]
   [onmerchantvalidation attribute and listeners both work]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Must have a onmerchantvalidation IDL attribute]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [onmerchantvalidation attribute is a generic handler for "merchantvalidation"]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [onmerchantvalidation attribute is a handler for MerchantValidationEvent]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/onpaymentmenthodchange-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/onpaymentmenthodchange-attribute.https.html.ini
@@ -1,13 +1,17 @@
 [onpaymentmenthodchange-attribute.https.html]
   [Must have a onpaymentmethodchange IDL attribute]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [onpaymentmethodchange attribute is a generic handler for "paymentmethodchange"]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [onpaymentmethodchange attribute is a handler for PaymentMethodChangeEvent]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [onpaymentmethodchange attribute and listeners both work]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-abort-method.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-abort-method.https.html.ini
@@ -1,13 +1,15 @@
 [payment-request-abort-method.https.html]
   [Throws if the promise [[state\]\] is not "interactive"]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Test for PaymentRequest.abort() method]
     expected: FAIL
 
   [Calling abort() multiple times is always a new object.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Test for PaymentRequest.abort() method 1]
     expected: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-canmakepayment-method.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-canmakepayment-method.https.html.ini
@@ -1,22 +1,27 @@
 [payment-request-canmakepayment-method.https.html]
   [If payment method identifier and serialized parts are supported, resolve promise with true.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If request.[[state\]\] is "closed", then return a promise rejected with an "InvalidStateError" DOMException.]
     expected: FAIL
 
   [If payment method identifier is unknown, resolve promise with false.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If request.[[state\]\] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException.]
     expected: FAIL
 
   [If request.[[state\]\] is "created", then return a promise that resolves to true for known method.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Calling canMakePayment() multiple times is always a new object.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-constructor-crash.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-constructor-crash.https.html.ini
@@ -1,37 +1,49 @@
 [payment-request-constructor-crash.https.html]
   [Don't crash if there is a abusive number of payment methods in the methodData sequence]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if there is a abusive number of supported methods in one sequence]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if the request id has an abusive length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if PaymentDetailsInit.total.label is an abusive length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if total.amount.value is an abusive length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if details.displayItems has an abusive number of items]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if details.shippingOptions has an abusive number of items]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if PaymentShippingOptions.label is an abusive length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if the PaymentShippingOptions.amount.value is an abusive length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if PaymentItem.label is an abusive length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if there is an abusive number of payment methods in the methodData sequence]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Don't crash if PaymentMethodData.supportedMethods is an abusive length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-constructor.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-constructor.https.html.ini
@@ -1,460 +1,611 @@
 [payment-request-constructor.https.html]
   [Use provided request ID]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If the length of the methodData sequence is zero, then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If the length of the paymentMethod.supportedMethods sequence is zero, then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Method data must be JSON-serializable object (a list in this case)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Method data must be JSON-serializable object (a dictionary in this case)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Rethrow any exceptions of JSON-serializing paymentMethod.data into a string]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "-"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "notdigits"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "ALSONOTDIGITS"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "10."), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case ".99"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "-10."), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "-.99"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "10-"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "1-0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "1.0.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "1/3"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case ""), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "null"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If the first character of details.total.amount.value is U+002D HYPHEN-MINUS, then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "-"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "notdigits"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "ALSONOTDIGITS"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "10."), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case ".99"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "-10."), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "-.99"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "10-"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "1-0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "1.0.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "1/3"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case ""), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "null"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Modifier data must be JSON-serializable object (a list in this case)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Modifier data must be JSON-serializable object (a dictionary in this case)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Rethrow any exceptions of JSON-serializing modifier.data into a string]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Total is required]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Label is required]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Amount is required]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Amount value is required]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Amount currency is required]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Shipping type should be valid]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.id is missing, assign a identifier]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.id is missing, assign a unique identifier]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If the same id is provided, then use it]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Use ids even if they are strange]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Method data must be JSON-serializable object (an object in this case)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case " 1.0  "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case " 1.0 "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "1.0 "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "USD$1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "$1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case " 1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "-1"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "-1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "-1.00"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value (in this case "-1000.000"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentDetailsBase.0 can be 0 length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentDetailsBase.1 can be 0 length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentDetailsBase.2 can be 0 length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case " 1.0  "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case " 1.0 "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "1.0 "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "USD$1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case "$1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value (in this case " 1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Negative values are allowed for displayItems.amount.value, irrespective of total amount]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [it handles high precision currency values without throwing]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "-"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "notdigits"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "ALSONOTDIGITS"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "10."), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case ".99"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "-10."), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "-.99"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "10-"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "1-0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "1.0.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "1/3"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case ""), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "null"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case " 1.0  "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case " 1.0 "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "1.0 "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "USD$1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case "$1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value (in this case " 1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If there is no selected shipping option, then PaymentRequest.shippingOption remains null]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If there is a selected shipping option, then it becomes synchronously selected]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If there is a multiple selected shipping options, only the last is selected]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If there are any duplicate shipping option ids, then there are no shipping options]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "-"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "notdigits"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "ALSONOTDIGITS"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "10."), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case ".99"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "-10."), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "-.99"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "10-"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "1-0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "1.0.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "1/3"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case ""), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "null"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case " 1.0  "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case " 1.0 "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "1.0 "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "USD$1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "$1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case " 1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "-1"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "-1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "-1.00"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If modifier.total.amount.value is not a valid decimal monetary value (in this case "-1000.000"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "-"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "notdigits"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "ALSONOTDIGITS"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "10."), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case ".99"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "-10."), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "-.99"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "10-"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "1-0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "1.0.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "1/3"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case ""), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "null"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case " 1.0  "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case " 1.0 "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "1.0 "), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "USD$1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case "$1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is is not a valid decimal monetary value (in this case " 1.0"), then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Modifier data must be JSON-serializable object (a object in this case)]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest.shippingAddress must initially be null]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If options.requestShipping is not set, then request.shippingType attribute is null.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If options.requestShipping is true, request.shippingType will be options.shippingType.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.id is missing, assign an identifier]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [ignore invalid payment method URLs]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Modifier method data must be JSON-serializable object]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If details.total.amount.value is not a valid decimal monetary value, then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentDetailsBase members can be 0 length]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each item in details.displayItems: if item.amount.value is not a valid decimal monetary value, then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [For each option in details.shippingOptions: if option.amount.value is not a valid decimal monetary value, then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Throw TypeError if modifier.total.amount.value is not a valid decimal monetary value]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If amount.value of additionalDisplayItems is not a valid decimal monetary value, then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Modifier data must be JSON-serializable object (an Array in this case)]
     expected: FAIL
 
   [Modifier data must be JSON-serializable object (an Object in this case)]
     expected: FAIL
 
   [Rethrow any exceptions of JSON-serializing modifier.data]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If there is a selected shipping option, and requestShipping is set, then that option becomes synchronously selected]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If requestShipping is set, and if there is a multiple selected shipping options, only the last is selected.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If there are any duplicate shipping option ids, and shipping is requested, then throw a TypeError]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Throw when there are duplicate shippingOption ids, even if other values are different]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-ctor-currency-code-checks.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-ctor-currency-code-checks.https.html.ini
@@ -1,31 +1,41 @@
 [payment-request-ctor-currency-code-checks.https.html]
   [Check and canonicalize valid details.total.amount]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Check and canonicalize invalid details.total.amount and rethrow any exceptions.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Check and canonicalize valid details.displayItems amount]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Check and canonicalize invalid details.displayItems amount and rethrow RangeError.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Check and canonicalize valid details.shippingOptions amount.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Check and canonicalize invalid details.shippingOptions amount and rethrow RangeError.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Check and canonicalize valid modifiers[n\].total amount.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Check and canonicalize invalid modifiers[n\].total amount and rethrow RangeError.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Check and canonicalize valid modifiers[n\].additionaDisplayItem amount.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Check and canonicalize invalid modifiers[n\].additionaDisplayItem amount and rethrow RangeError.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-ctor-pmi-handling.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-ctor-pmi-handling.https.html.ini
@@ -1,16 +1,21 @@
 [payment-request-ctor-pmi-handling.https.html]
   [Must support valid standard URL PMIs]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Must not throw on syntactically valid standardized payment method identifiers, even if they are not supported]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Test for validity of payment method identifiers during construction]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Constructor MUST throw if given an invalid URL-based payment method identifier]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Must throw on syntactically invalid standardized payment method identifiers]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-id-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-id-attribute.https.html.ini
@@ -1,10 +1,14 @@
 [payment-request-id-attribute.https.html]
   [PaymentRequest id attribute]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest's id attribute's value can be set via PaymentDetailsInit dictionary]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentRequest's id attribute must be a UUID when PaymentDetailsInit.id is missing]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
+      if (os == "mac"): FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-onshippingaddresschange-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-onshippingaddresschange-attribute.https.html.ini
@@ -1,13 +1,17 @@
 [payment-request-onshippingaddresschange-attribute.https.html]
   [onshippingaddresschange attribute is a generic handler for "shippingaddresschange"]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [onshippingaddresschange attribute is a handler for PaymentRequestUpdateEvent]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [onshippingaddresschange attribute and listeners both work]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Must have a onshippingaddresschange IDL attribute]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-onshippingoptionchange-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-onshippingoptionchange-attribute.https.html.ini
@@ -1,13 +1,17 @@
 [payment-request-onshippingoptionchange-attribute.https.html]
   [onshippingoptionchange attribute is a generic handler for "shippingoptionchange"]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [onshippingoptionchange attribute is a handler for PaymentRequestUpdateEvent]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [onshippingoptionchange attribute and listeners both work]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Must have a onshippingoptionchange IDL attribute]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-shippingAddress-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-shippingAddress-attribute.https.html.ini
@@ -1,7 +1,9 @@
 [payment-request-shippingAddress-attribute.https.html]
   [Must have a .shippingAddress IDL attribute.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [.shippingAddress attribute must default to null.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-shippingOption-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-shippingOption-attribute.https.html.ini
@@ -1,19 +1,25 @@
 [payment-request-shippingOption-attribute.https.html]
   [Must have a .shippingOption IDL attribute.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [.shippingOption attribute must default to null.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If there is a single shipping option, but selected is false, then .shippingOption must be null.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If there are multiple shipping options all with `selected` set to false, then .shippingOption is null.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Given multiple shipping options, it must use the selected shipping option for .shippingOption value.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If there are multiple of the shipping options with selected true, then .shippingOption is the last selected shipping option in order.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-shippingType-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-shippingType-attribute.https.html.ini
@@ -1,10 +1,13 @@
 [payment-request-shippingType-attribute.https.html]
   [If options.requestShipping is false, then request.shippingType attribute is null.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [If options.requestShipping is true, request.shippingType will be options.shippingType.]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [Must have a shippingType IDL attribute]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/payment-request-show-method.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-request-show-method.https.html.ini
@@ -1,17 +1,12 @@
 [payment-request-show-method.https.html]
-  [Throws if the promise [[state\]\] is not "created"]
-    expected: FAIL
-
-  [Must be possible to construct a payment request]
-    expected: FAIL
-
   [Calling show() without being triggered by user interaction throws]
-    expected: FAIL
+    expected:
+      if not e10s: FAIL
 
   [Throws if the promise [[state\]\] is not 'created'.]
     expected: FAIL
 
   [If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.]
     expected: FAIL
 
   [If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.]
--- a/testing/web-platform/meta/payment-request/payment-response/onpayerdetailchange-attribute.https.html.ini
+++ b/testing/web-platform/meta/payment-request/payment-response/onpayerdetailchange-attribute.https.html.ini
@@ -1,7 +1,9 @@
 [onpayerdetailchange-attribute.https.html]
   [PaymentResponse inherits from EventTarget]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
   [PaymentResponse has an onpayerdetailchange in the prototype chain]
-    expected: FAIL
+    expected: 
+      if not e10s: FAIL
 
--- a/testing/web-platform/meta/payment-request/rejects_if_not_active.https.html.ini
+++ b/testing/web-platform/meta/payment-request/rejects_if_not_active.https.html.ini
@@ -1,10 +1,2 @@
 [rejects_if_not_active.https.html]
-  [PaymentRequest.show() aborts if the document is not active]
-    expected: FAIL
-
-  [PaymentRequest.show() aborts if the document is active, but not fully active]
-    expected: FAIL
-
-  [If a payment request is showing, but its document is navigated away (so no longer fully active), the payment request aborts.]
-    expected: FAIL
-
+  disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1408234