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
--- 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;