From 7135d9040a18ca87180943f2b1e319ddc627fde7 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 4 Jun 2013 00:15:29 +1000 Subject: [PATCH] Bug 873806 - Part 2: Make descendants of non-display nsSVGForeignObjectFrame also non-display. r=longsonr --- layout/svg/crashtests/873806-1.svg | 10 ++++++++++ layout/svg/crashtests/crashtests.list | 1 + layout/svg/nsSVGOuterSVGFrame.cpp | 13 +++++++++++++ layout/svg/nsSVGTextFrame2.cpp | 5 +++++ layout/svg/nsSVGUtils.cpp | 13 +++++++++++++ layout/svg/nsSVGUtils.h | 1 + 6 files changed, 43 insertions(+) create mode 100644 layout/svg/crashtests/873806-1.svg diff --git a/layout/svg/crashtests/873806-1.svg b/layout/svg/crashtests/873806-1.svg new file mode 100644 index 000000000000..e40aff201b78 --- /dev/null +++ b/layout/svg/crashtests/873806-1.svg @@ -0,0 +1,10 @@ + + + + a + + + + diff --git a/layout/svg/crashtests/crashtests.list b/layout/svg/crashtests/crashtests.list index e6cd2d856d3b..82cf4d677647 100644 --- a/layout/svg/crashtests/crashtests.list +++ b/layout/svg/crashtests/crashtests.list @@ -163,4 +163,5 @@ load 849688-1.svg load 849688-2.svg load 860378-1.svg load 868904-1.svg +load 873806-1.svg load 877029-1.svg diff --git a/layout/svg/nsSVGOuterSVGFrame.cpp b/layout/svg/nsSVGOuterSVGFrame.cpp index 3b2e4cda4bf7..3b8121539b1a 100644 --- a/layout/svg/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/nsSVGOuterSVGFrame.cpp @@ -167,6 +167,19 @@ nsSVGOuterSVGFrame::Init(nsIContent* aContent, SVGSVGElement *svg = static_cast(aContent); if (!svg->PassesConditionalProcessingTests()) { AddStateBits(NS_STATE_SVG_NONDISPLAY_CHILD); + } else { + // If this outer element is the child of a that + // is non-display, or is the child of a frame for HTML content that + // itself is a descendant of a non-display SVG frame, then we want to + // it non-display also. The second case is not as simple to handle + // as copying a state bit from the parent, since non-SVG frames do + // not use NS_STATE_SVG_NONDISPLAY_CHILD. + for (nsIFrame* f = aParent; f; f = f->GetParent()) { + if (f->IsFrameOfType(eSVG)) { + AddStateBits(f->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD); + break; + } + } } nsSVGOuterSVGFrameBase::Init(aContent, aParent, aPrevInFlow); diff --git a/layout/svg/nsSVGTextFrame2.cpp b/layout/svg/nsSVGTextFrame2.cpp index cf5db68a20f5..c7dbd8f6be7f 100644 --- a/layout/svg/nsSVGTextFrame2.cpp +++ b/layout/svg/nsSVGTextFrame2.cpp @@ -3074,6 +3074,9 @@ nsSVGTextFrame2::DidSetStyleContext(nsStyleContext* aOldStyleContext) void nsSVGTextFrame2::ReflowSVGNonDisplayText() { + MOZ_ASSERT(nsSVGUtils::AnyOuterSVGIsCallingReflowSVG(this), + "only call ReflowSVGNonDisplayText when an outer SVG frame is " + "under ReflowSVG"); MOZ_ASSERT(mState & NS_STATE_SVG_NONDISPLAY_CHILD, "only call ReflowSVGNonDisplayText if the frame is " "NS_STATE_SVG_NONDISPLAY_CHILD"); @@ -4832,6 +4835,8 @@ nsSVGTextFrame2::UpdateGlyphPositioning() // by nsSVGDisplayContainerFrame::ReflowSVG.) kid->AddStateBits(NS_FRAME_IS_DIRTY); } + MOZ_ASSERT(nsSVGUtils::AnyOuterSVGIsCallingReflowSVG(this), + "should be under ReflowSVG"); nsPresContext::InterruptPreventer noInterrupts(PresContext()); DoReflow(); } diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 5d24ff7bc8fc..58b0e1a7d80d 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -451,6 +451,19 @@ nsSVGUtils::OuterSVGIsCallingReflowSVG(nsIFrame *aFrame) return GetOuterSVGFrame(aFrame)->IsCallingReflowSVG(); } +bool +nsSVGUtils::AnyOuterSVGIsCallingReflowSVG(nsIFrame* aFrame) +{ + nsSVGOuterSVGFrame* outer = GetOuterSVGFrame(aFrame); + do { + if (outer->IsCallingReflowSVG()) { + return true; + } + outer = GetOuterSVGFrame(outer->GetParent()); + } while (outer); + return false; +} + void nsSVGUtils::ScheduleReflowSVG(nsIFrame *aFrame) { diff --git a/layout/svg/nsSVGUtils.h b/layout/svg/nsSVGUtils.h index 5c0243ab7599..41f3ea626873 100644 --- a/layout/svg/nsSVGUtils.h +++ b/layout/svg/nsSVGUtils.h @@ -521,6 +521,7 @@ public: static nsIFrame* GetFirstNonAAncestorFrame(nsIFrame* aStartFrame); static bool OuterSVGIsCallingReflowSVG(nsIFrame *aFrame); + static bool AnyOuterSVGIsCallingReflowSVG(nsIFrame *aFrame); /* * Get any additional transforms that apply only to stroking