From 0ee624eeb29958df5a2ee47e2b85bdb7c451a8eb Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 1 Dec 2009 12:21:00 -0500 Subject: [PATCH] Bug 531371. Correctly propagate the backround from a to the viewport as needed. r=bzbarsky --- content/base/src/nsGenericElement.cpp | 4 +--- layout/base/nsCSSRendering.cpp | 6 +++--- layout/base/nsCSSRendering.h | 8 ++++++-- layout/base/nsLayoutUtils.cpp | 15 ++++++++++++++- layout/base/nsLayoutUtils.h | 8 ++++++++ layout/reftests/bugs/531371-1-ref.html | 3 +++ layout/reftests/bugs/531371-1.html | 5 +++++ layout/reftests/bugs/reftest.list | 1 + layout/style/nsComputedDOMStyle.cpp | 19 ++----------------- 9 files changed, 43 insertions(+), 26 deletions(-) create mode 100644 layout/reftests/bugs/531371-1-ref.html create mode 100644 layout/reftests/bugs/531371-1.html diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 7ede8d405c05..8fd5a6d21d1d 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -1132,9 +1132,7 @@ nsIFrame* nsGenericElement::GetStyledFrame() { nsIFrame *frame = GetPrimaryFrame(Flush_Layout); - - return (frame && frame->GetType() == nsGkAtoms::tableOuterFrame) ? - frame->GetFirstChild(nsnull) : frame; + return frame ? nsLayoutUtils::GetStyleFrame(frame) : nsnull; } void diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index 34a3d2f2ecf6..1ae3f3af25d6 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -962,7 +962,7 @@ nsCSSRendering::IsCanvasFrame(nsIFrame* aFrame) } nsIFrame* -nsCSSRendering::FindRootFrame(nsIFrame* aForFrame) +nsCSSRendering::FindBackgroundStyleFrame(nsIFrame* aForFrame) { const nsStyleBackground* result = aForFrame->GetStyleBackground(); @@ -990,7 +990,7 @@ nsCSSRendering::FindRootFrame(nsIFrame* aForFrame) nsIFrame *bodyFrame = aForFrame->PresContext()->GetPresShell()-> GetPrimaryFrameFor(bodyContent); if (bodyFrame) { - return bodyFrame; + return nsLayoutUtils::GetStyleFrame(bodyFrame); } } } @@ -1030,7 +1030,7 @@ nsCSSRendering::FindRootFrame(nsIFrame* aForFrame) const nsStyleBackground* nsCSSRendering::FindRootFrameBackground(nsIFrame* aForFrame) { - return FindRootFrame(aForFrame)->GetStyleBackground(); + return FindBackgroundStyleFrame(aForFrame)->GetStyleBackground(); } inline PRBool diff --git a/layout/base/nsCSSRendering.h b/layout/base/nsCSSRendering.h index a49d3b1580e5..027cca08ab24 100644 --- a/layout/base/nsCSSRendering.h +++ b/layout/base/nsCSSRendering.h @@ -138,9 +138,13 @@ struct nsCSSRendering { const nsRect& aFillArea); /** - * Gets the root frame for the frame + * Find the frame whose background style should be used to draw the + * canvas background. aForFrame must be the frame for the root element + * whose background style should be used. This function will return + * aForFrame unless the background should be propagated, in + * which case we return the frame associated with the 's background. */ - static nsIFrame* FindRootFrame(nsIFrame* aForFrame); + static nsIFrame* FindBackgroundStyleFrame(nsIFrame* aForFrame); /** * @return PR_TRUE if |aFrame| is a canvas frame, in the CSS sense. diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index e51ae8c4b44f..c820fbaf6df0 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -227,6 +227,19 @@ nsLayoutUtils::GetClosestFrameOfType(nsIFrame* aFrame, nsIAtom* aFrameType) return nsnull; } +// static +nsIFrame* +nsLayoutUtils::GetStyleFrame(nsIFrame* aFrame) +{ + if (aFrame->GetType() == nsGkAtoms::tableOuterFrame) { + nsIFrame* inner = aFrame->GetFirstChild(nsnull); + NS_ASSERTION(inner, "Outer table must have an inner"); + return inner; + } + + return aFrame; +} + nsIFrame* nsLayoutUtils::GetFloatFromPlaceholder(nsIFrame* aFrame) { NS_ASSERTION(nsGkAtoms::placeholderFrame == aFrame->GetType(), @@ -2790,7 +2803,7 @@ nsLayoutUtils::GetGraphicsFilterForFrame(nsIFrame* aForFrame) { #ifdef MOZ_SVG nsIFrame *frame = nsCSSRendering::IsCanvasFrame(aForFrame) ? - nsCSSRendering::FindRootFrame(aForFrame) : aForFrame; + nsCSSRendering::FindBackgroundStyleFrame(aForFrame) : aForFrame; switch (frame->GetStyleSVG()->mImageRendering) { case NS_STYLE_IMAGE_RENDERING_OPTIMIZESPEED: diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 085764ea0621..58b5433c9dd2 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -121,6 +121,14 @@ public: return GetClosestFrameOfType(aFrame, nsGkAtoms::pageFrame); } + /** + * Given a frame which is the primary frame for an element, + * return the frame that has the non-psuedoelement style context for + * the content. + * This is aPrimaryFrame itself except for tableOuter frames. + */ + static nsIFrame* GetStyleFrame(nsIFrame* aPrimaryFrame); + /** * IsGeneratedContentFor returns PR_TRUE if aFrame is the outermost * frame for generated content of type aPseudoElement for aContent. diff --git a/layout/reftests/bugs/531371-1-ref.html b/layout/reftests/bugs/531371-1-ref.html new file mode 100644 index 000000000000..2634ffa254d3 --- /dev/null +++ b/layout/reftests/bugs/531371-1-ref.html @@ -0,0 +1,3 @@ + + + diff --git a/layout/reftests/bugs/531371-1.html b/layout/reftests/bugs/531371-1.html new file mode 100644 index 000000000000..726f9b206ddd --- /dev/null +++ b/layout/reftests/bugs/531371-1.html @@ -0,0 +1,5 @@ + + + + + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index c14dfacfb927..c233e1111d38 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -1347,4 +1347,5 @@ fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") == 488692-1.html 488692-1-ref.html # needs == 528038-1e.html 528038-1-ref.html == 528038-1f.html 528038-1-ref.html == 528038-2.html 528038-2-ref.html +== 531371-1.html 531371-1-ref.html == 530686-1.html 530686-1-ref.html diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index b0f80c3d4fa0..892f6238dc04 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -317,22 +317,6 @@ nsComputedDOMStyle::GetPropertyValue(const nsAString& aPropertyName, return rv; } -static nsStyleContext* -GetStyleContextForFrame(nsIFrame* aFrame) -{ - nsStyleContext* styleContext = aFrame->GetStyleContext(); - - /* For tables the primary frame is the "outer frame" but the style - * rules are applied to the "inner frame". Luckily, the "outer - * frame" actually inherits style from the "inner frame" so we can - * just move one level up in the style context hierarchy.... - */ - if (aFrame->GetType() == nsGkAtoms::tableOuterFrame) - return styleContext->GetParent(); - - return styleContext; -} - /* static */ already_AddRefed nsComputedDOMStyle::GetStyleContextForContent(nsIContent* aContent, @@ -373,7 +357,8 @@ nsComputedDOMStyle::GetStyleContextForContentNoFlush(nsIContent* aContent, if (!aPseudo) { nsIFrame* frame = aPresShell->GetPrimaryFrameFor(aContent); if (frame) { - nsStyleContext* result = GetStyleContextForFrame(frame); + nsStyleContext* result = + nsLayoutUtils::GetStyleFrame(frame)->GetStyleContext(); // Don't use the style context if it was influenced by // pseudo-elements, since then it's not the primary style // for this element.