Bug 1458968 - Create the nsDisplaySVGWrapper item in nsSVGOuterSVGAnonChildFrame, not in nsSVGOuterSVGFrame. r?mattwoodrow draft
authorMarkus Stange <mstange@themasta.com>
Thu, 03 May 2018 15:57:25 -0400
changeset 791256 7200b36b154260eb01f4fa27fd3506285f3c1d04
parent 791255 d2325064fdecce27de54c6939cc9c7ea0a174071
child 791683 4616b2529700b206abea2167fe563b32acc770cb
push id108759
push userbmo:mstange@themasta.com
push dateThu, 03 May 2018 21:27:59 +0000
reviewersmattwoodrow
bugs1458968, 1407938
milestone61.0a1
Bug 1458968 - Create the nsDisplaySVGWrapper item in nsSVGOuterSVGAnonChildFrame, not in nsSVGOuterSVGFrame. r?mattwoodrow This ensures that the nsDisplaySVGWrapper's mFrame and its reference frame are the same frame: the nsSVGOuterSVGAnonChildFrame. It'll also cause the nsDisplaySVGWrapper to be *inside* the nsDisplayTransform for the <svg> element's viewbox transform. This patch reverts nsSVGOuterSVGFrame::BuildDisplayList to its pre-bug 1407938 form. (That's the bug that introduced nsDisplaySVGWrapper.) MozReview-Commit-ID: 3jCyP6Sj8x9
layout/svg/nsSVGOuterSVGFrame.cpp
layout/svg/nsSVGOuterSVGFrame.h
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -778,21 +778,20 @@ nsSVGOuterSVGFrame::BuildDisplayList(nsD
       StyleDisplay()->IsScrollableOverflow()) {
     autoSR.ClipContainingBlockDescendantsToContentBox(aBuilder, this);
   }
 
   if ((aBuilder->IsForEventDelivery() &&
        NS_SVGDisplayListHitTestingEnabled()) ||
       (!aBuilder->IsForEventDelivery() &&
        NS_SVGDisplayListPaintingEnabled())) {
-    nsDisplayList newList;
-    nsDisplayListSet set(&newList, &newList, &newList,
-                         &newList, &newList, &newList);
+    nsDisplayList* contentList = aLists.Content();
+    nsDisplayListSet set(contentList, contentList, contentList,
+                         contentList, contentList, contentList);
     BuildDisplayListForNonBlockChildren(aBuilder, set);
-    aLists.Content()->AppendToTop(MakeDisplayItem<nsDisplaySVGWrapper>(aBuilder, this, &newList));
   } else if (IsVisibleForPainting(aBuilder) || !aBuilder->IsForPainting()) {
     aLists.Content()->AppendToTop(
       MakeDisplayItem<nsDisplayOuterSVG>(aBuilder, this));
   }
 }
 
 nsSplittableType
 nsSVGOuterSVGFrame::GetSplittableType() const
@@ -997,16 +996,34 @@ nsSVGOuterSVGAnonChildFrame::Init(nsICon
                                   nsContainerFrame* aParent,
                                   nsIFrame*         aPrevInFlow)
 {
   MOZ_ASSERT(aParent->IsSVGOuterSVGFrame(), "Unexpected parent");
   nsSVGDisplayContainerFrame::Init(aContent, aParent, aPrevInFlow);
 }
 #endif
 
+void
+nsSVGOuterSVGAnonChildFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
+                                              const nsDisplayListSet& aLists)
+{
+  // Wrap our contents into an nsDisplaySVGWrapper.
+  // We wrap this frame instead of the nsSVGOuterSVGFrame so that the wrapper
+  // doesn't contain the <svg> element's CSS styles, like backgrounds or borders.
+  // Creating the nsDisplaySVGWrapper here also means that it'll be inside the
+  // nsDisplayTransform for our viewbox transform.
+  // The nsDisplaySVGWrapper's reference frame is this frame, because this frame
+  // always returns true from IsSVGTransformed.
+  nsDisplayList newList;
+  nsDisplayListSet set(&newList, &newList, &newList,
+                       &newList, &newList, &newList);
+  BuildDisplayListForNonBlockChildren(aBuilder, set);
+  aLists.Content()->AppendToTop(MakeDisplayItem<nsDisplaySVGWrapper>(aBuilder, this, &newList));
+}
+
 static Matrix
 ComputeOuterSVGAnonChildFrameTransform(const nsSVGOuterSVGAnonChildFrame* aFrame)
 {
   // Our elements 'transform' attribute is applied to our nsSVGOuterSVGFrame
   // parent, and the element's children-only transforms are applied to us, the
   // anonymous child frame. Since we are the child frame, we apply the
   // children-only transforms as if they are our own transform.
   SVGSVGElement* content = static_cast<SVGSVGElement*>(aFrame->GetContent());
--- a/layout/svg/nsSVGOuterSVGFrame.h
+++ b/layout/svg/nsSVGOuterSVGFrame.h
@@ -235,16 +235,19 @@ public:
   NS_DECL_FRAMEARENA_HELPERS(nsSVGOuterSVGAnonChildFrame)
 
 #ifdef DEBUG
   virtual void Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
                     nsIFrame*         aPrevInFlow) override;
 #endif
 
+  virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
+                                const nsDisplayListSet& aLists) override;
+
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override {
     return MakeFrameName(NS_LITERAL_STRING("SVGOuterSVGAnonChild"), aResult);
   }
 #endif
 
   bool IsSVGTransformed(Matrix *aOwnTransform,
                         Matrix *aFromParentTransform) const override;