diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index 0320720099c..3aeee46e2de 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -6654,17 +6654,12 @@ already_AddRefed nsCSSFrameConstructor::ResolveStyleContext(nsIFrame* aParentFrame, nsIContent* aContent) { + aParentFrame = nsFrame::CorrectStyleParentFrame(aParentFrame, nsnull); + // Resolve the style context based on the content object and the parent // style context nsStyleContext* parentStyleContext = aParentFrame->GetStyleContext(); - // skip past any parents that are scrolled-content. We want to inherit directly - // from the outer scroll frame. - while (parentStyleContext && parentStyleContext->GetPseudoType() == - nsCSSAnonBoxes::scrolledContent) { - parentStyleContext = parentStyleContext->GetParent(); - } - nsStyleSet *styleSet = mPresShell->StyleSet(); if (aContent->IsNodeOfType(nsINode::eELEMENT)) { @@ -11216,7 +11211,10 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState, // XXXbz ideally, this would do all the pushing of various // containing blocks as needed, so callers don't have to do it... nsresult rv = NS_OK; - nsStyleContext* styleContext = aFrame->GetStyleContext(); + // :before/:after content should have the same style context parent + // as normal kids. + nsStyleContext* styleContext = + nsFrame::CorrectStyleParentFrame(aFrame, nsnull)->GetStyleContext(); if (aCanHaveGeneratedContent) { // Probe for generated content before diff --git a/layout/generic/Makefile.in b/layout/generic/Makefile.in index 30cf316de89..0e7d4da0cfc 100644 --- a/layout/generic/Makefile.in +++ b/layout/generic/Makefile.in @@ -41,6 +41,10 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk +ifdef MOZ_MOCHITEST +DIRS += test +endif + MODULE = layout LIBRARY_NAME = gkgeneric_s LIBXUL_LIBRARY = 1 diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 9523cb54ca7..d1fac274114 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -118,6 +118,7 @@ #include "nsWidgetsCID.h" // for NS_LOOKANDFEEL_CID #include "nsUnicharUtils.h" #include "nsLayoutErrors.h" +#include "nsContentErrors.h" #include "nsHTMLContainerFrame.h" #include "nsBoxLayoutState.h" #include "nsBlockFrame.h" @@ -5433,25 +5434,15 @@ GetIBSpecialSibling(nsPresContext* aPresContext, aPresContext->PropertyTable()->GetProperty(aFrame, nsGkAtoms::IBSplitSpecialPrevSibling, &rv)); - if (NS_OK == rv) { + if (NS_PROPTABLE_PROP_NOT_THERE == rv) { + *aSpecialSibling = nsnull; + rv = NS_OK; + } else if (NS_SUCCEEDED(rv)) { NS_ASSERTION(specialSibling, "null special sibling"); *aSpecialSibling = specialSibling; } - return NS_OK; -} - -static PRBool -IsTablePseudo(nsIAtom* aPseudo) -{ - return - aPseudo == nsCSSAnonBoxes::tableOuter || - aPseudo == nsCSSAnonBoxes::table || - aPseudo == nsCSSAnonBoxes::tableRowGroup || - aPseudo == nsCSSAnonBoxes::tableRow || - aPseudo == nsCSSAnonBoxes::tableCell || - aPseudo == nsCSSAnonBoxes::tableColGroup || - aPseudo == nsCSSAnonBoxes::tableCol; + return rv; } /** @@ -5469,37 +5460,73 @@ GetCorrectedParent(nsPresContext* aPresContext, nsIFrame* aFrame, nsIFrame** aSpecialParent) { nsIFrame *parent = aFrame->GetParent(); - *aSpecialParent = parent; - if (parent) { - nsIAtom* pseudo = aFrame->GetStyleContext()->GetPseudoType(); - - // if this frame itself is not scrolled-content, then skip any scrolled-content - // parents since they're basically anonymous as far as the style system goes - if (pseudo != nsCSSAnonBoxes::scrolledContent) { - while (parent->GetStyleContext()->GetPseudoType() == - nsCSSAnonBoxes::scrolledContent) { - parent = parent->GetParent(); - } - } - - // If the frame is not a table pseudo frame, we want to move up - // the tree till we get to a non-table-pseudo frame. - if (!IsTablePseudo(pseudo)) { - while (IsTablePseudo(parent->GetStyleContext()->GetPseudoType())) { - parent = parent->GetParent(); - } - } - - if (parent->GetStateBits() & NS_FRAME_IS_SPECIAL) { - GetIBSpecialSibling(aPresContext, parent, aSpecialParent); - } else { - *aSpecialParent = parent; - } + if (!parent) { + *aSpecialParent = nsnull; + } else { + *aSpecialParent = + nsFrame::CorrectStyleParentFrame(parent, + aFrame->GetStyleContext()-> + GetPseudoType()); } return NS_OK; } +/* static */ +nsIFrame* +nsFrame::CorrectStyleParentFrame(nsIFrame* aProspectiveParent, + nsIAtom* aChildPseudo) +{ + NS_PRECONDITION(aProspectiveParent, "Must have a prospective parent"); + + // Anon boxes are parented to their actual parent already, except + // for non-elements. Those should not be treated as an anon box. + if (aChildPseudo && aChildPseudo != nsCSSAnonBoxes::mozNonElement && + nsCSSAnonBoxes::IsAnonBox(aChildPseudo)) { + NS_ASSERTION(aChildPseudo != nsCSSAnonBoxes::mozAnonymousBlock && + aChildPseudo != nsCSSAnonBoxes::mozAnonymousPositionedBlock, + "Should have dealt with kids that have NS_FRAME_IS_SPECIAL " + "elsewhere"); + return aProspectiveParent; + } + + // Otherwise, walk up out of all anon boxes + nsIFrame* parent = aProspectiveParent; + do { + if (parent->GetStateBits() & NS_FRAME_IS_SPECIAL) { + nsIFrame* sibling; + nsresult rv = + GetIBSpecialSibling(parent->PresContext(), parent, &sibling); + if (NS_FAILED(rv)) { + // If GetIBSpecialSibling fails, then what? we used to return what is + // now |aProspectiveParent|, but maybe |parent| would make more sense? + NS_NOTREACHED("Shouldn't get here"); + return aProspectiveParent; + } + + if (sibling) { + // |parent| was the block in an {ib} split; use the inline as + // |the style parent. + parent = sibling; + } + } + + nsIAtom* parentPseudo = parent->GetStyleContext()->GetPseudoType(); + if (!parentPseudo || !nsCSSAnonBoxes::IsAnonBox(parentPseudo)) { + return parent; + } + + parent = parent->GetParent(); + } while (parent); + + // We can get here if aProspectiveParent is the scrollframe for a viewport + // and the kids are the anonymous scrollbars. + NS_ASSERTION(aProspectiveParent->GetStyleContext()->GetPseudoType() == + nsCSSAnonBoxes::viewportScroll, + "Should have found a parent before this"); + return aProspectiveParent; +} + nsresult nsFrame::DoGetParentStyleContextFrame(nsPresContext* aPresContext, nsIFrame** aProviderFrame, @@ -5521,9 +5548,16 @@ nsFrame::DoGetParentStyleContextFrame(nsPresContext* aPresContext, * using GetIBSpecialSibling */ if (mState & NS_FRAME_IS_SPECIAL) { - GetIBSpecialSibling(aPresContext, this, aProviderFrame); - if (*aProviderFrame) + nsresult rv = GetIBSpecialSibling(aPresContext, this, aProviderFrame); + if (NS_FAILED(rv)) { + NS_NOTREACHED("Shouldn't get here"); + *aProviderFrame = nsnull; + return rv; + } + + if (*aProviderFrame) { return NS_OK; + } } // If this frame is one of the blocks that split an inline, we must diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 286c135635c..066c1dea5e7 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -518,6 +518,18 @@ public: nsresult DisplayOutline(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists); + /** + * Adjust the given parent frame to the right style context parent frame for + * the child, given the pseudo-type of the prospective child. This handles + * things like walking out of table pseudos and so forth. + * + * @param aProspectiveParent what GetParent() on the child returns. + * Must not be null. + * @param aChildPseudo the child's pseudo type, if any. + */ + static nsIFrame* + CorrectStyleParentFrame(nsIFrame* aProspectiveParent, nsIAtom* aChildPseudo); + protected: // Protected constructor and destructor nsFrame(nsStyleContext* aContext); diff --git a/layout/generic/test/Makefile.in b/layout/generic/test/Makefile.in new file mode 100644 index 00000000000..608fcd11d4b --- /dev/null +++ b/layout/generic/test/Makefile.in @@ -0,0 +1,51 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2007 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ +relativesrcdir = layout/generic/test + +include $(DEPTH)/config/autoconf.mk +include $(topsrcdir)/config/rules.mk + +_TEST_FILES = test_bug323656.html \ + $(NULL) + +libs:: $(_TEST_FILES) + $(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) diff --git a/layout/generic/test/test_bug323656.html b/layout/generic/test/test_bug323656.html new file mode 100644 index 00000000000..73966728fc5 --- /dev/null +++ b/layout/generic/test/test_bug323656.html @@ -0,0 +1,52 @@ + + + + + Test for Bug 323656 + + + + + + +Mozilla Bug 323656 +

+ +

+ +
+
+
+ + + diff --git a/layout/reftests/bugs/323656-1-ref.html b/layout/reftests/bugs/323656-1-ref.html new file mode 100644 index 00000000000..4121bf482de --- /dev/null +++ b/layout/reftests/bugs/323656-1-ref.html @@ -0,0 +1,44 @@ + + + + Test inheritance through various table anonymous boxes + + + +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ + diff --git a/layout/reftests/bugs/323656-1.html b/layout/reftests/bugs/323656-1.html new file mode 100644 index 00000000000..74659141f5f --- /dev/null +++ b/layout/reftests/bugs/323656-1.html @@ -0,0 +1,56 @@ + + + + Test inheritance through various table anonymous boxes + + + + +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/layout/reftests/bugs/323656-2-ref.html b/layout/reftests/bugs/323656-2-ref.html new file mode 100644 index 00000000000..f4b5dcbfb4c --- /dev/null +++ b/layout/reftests/bugs/323656-2-ref.html @@ -0,0 +1,29 @@ + + + + Test inheritance through fieldsets and legends + + + +
+
+
+
+ + diff --git a/layout/reftests/bugs/323656-2.html b/layout/reftests/bugs/323656-2.html new file mode 100644 index 00000000000..f8ac2ec18ad --- /dev/null +++ b/layout/reftests/bugs/323656-2.html @@ -0,0 +1,39 @@ + + + + Test inheritance through fieldsets and legends + + + + +
+
+
+
+ + diff --git a/layout/reftests/bugs/323656-3-ref.html b/layout/reftests/bugs/323656-3-ref.html new file mode 100644 index 00000000000..db2ddf0beb1 --- /dev/null +++ b/layout/reftests/bugs/323656-3-ref.html @@ -0,0 +1,53 @@ + + + + + Test inheritance through various anonymous boxes: {ib} + situations, buttons, overflow, columns, listboxes, first-line + + + + +
+
+
+

+ +
+
+ + +
+
+
+

+ +
+
+ + +
+
+ + diff --git a/layout/reftests/bugs/323656-3.html b/layout/reftests/bugs/323656-3.html new file mode 100644 index 00000000000..e87a9638630 --- /dev/null +++ b/layout/reftests/bugs/323656-3.html @@ -0,0 +1,84 @@ + + + + Test inheritance through various anonymous boxes: {ib} + situations, buttons, overflow, columns, listboxes, first-line + + + + +
+
+
+

+ +
+
+ + +
+ + +
+ +
+
+ + +
+
+ + diff --git a/layout/reftests/bugs/323656-4-ref.html b/layout/reftests/bugs/323656-4-ref.html new file mode 100644 index 00000000000..e7116eb19d9 --- /dev/null +++ b/layout/reftests/bugs/323656-4-ref.html @@ -0,0 +1,14 @@ + + + + Test inheritance through first-letter + + +
ABC
+
ABC
+
ABC
+ + diff --git a/layout/reftests/bugs/323656-4.html b/layout/reftests/bugs/323656-4.html new file mode 100644 index 00000000000..c804b6de274 --- /dev/null +++ b/layout/reftests/bugs/323656-4.html @@ -0,0 +1,31 @@ + + + + Test inheritance through first-letter + + + +
ABC
+
+
+ + diff --git a/layout/reftests/bugs/323656-5-ref.svg b/layout/reftests/bugs/323656-5-ref.svg new file mode 100644 index 00000000000..2f68c90539b --- /dev/null +++ b/layout/reftests/bugs/323656-5-ref.svg @@ -0,0 +1,15 @@ + + + Testcase for foreignObject + + + + + +
+ + + diff --git a/layout/reftests/bugs/323656-5.svg b/layout/reftests/bugs/323656-5.svg new file mode 100644 index 00000000000..b98bbac63be --- /dev/null +++ b/layout/reftests/bugs/323656-5.svg @@ -0,0 +1,15 @@ + + + Testcase for foreignObject + + + + + +
+ + + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index eabcb72b328..7d857862676 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -97,6 +97,11 @@ fails == 25888-3r.html 25888-3r-ref.html # bug 25888 == 315620-2a.xhtml 315620-2-ref.xhtml != 315620-2b.xhtml 315620-2-ref.xhtml == 322461-1.xml 322461-1-ref.html +== 323656-1.html 323656-1-ref.html +== 323656-2.html 323656-2-ref.html +== 323656-3.html 323656-3-ref.html +== 323656-4.html 323656-4-ref.html +fails == 323656-5.svg 323656-5-ref.svg # bug 377584 == 325486-1.html 325486-1-ref.html random == 328829-1.xhtml 328829-1-ref.xhtml # bug 369046 (intermittent) == 328829-2.xhtml 328829-2-ref.xhtml diff --git a/layout/style/nsCSSAnonBoxList.h b/layout/style/nsCSSAnonBoxList.h index adec3b40d6a..9207f209c7f 100644 --- a/layout/style/nsCSSAnonBoxList.h +++ b/layout/style/nsCSSAnonBoxList.h @@ -57,7 +57,6 @@ CSS_ANON_BOX(mozNonElement, ":-moz-non-element") CSS_ANON_BOX(mozAnonymousBlock, ":-moz-anonymous-block") CSS_ANON_BOX(mozAnonymousPositionedBlock, ":-moz-anonymous-positioned-block") -CSS_ANON_BOX(mozFirstLineFixup, ":-moz-first-line-fixup") CSS_ANON_BOX(mozLineFrame, ":-moz-line-frame") CSS_ANON_BOX(buttonContent, ":-moz-button-content") @@ -90,7 +89,6 @@ CSS_ANON_BOX(scrolledPageSequence, ":-moz-scrolled-page-sequence") CSS_ANON_BOX(columnContent, ":-moz-column-content") CSS_ANON_BOX(viewport, ":-moz-viewport") CSS_ANON_BOX(viewportScroll, ":-moz-viewport-scroll") -CSS_ANON_BOX(selectScrolledContent, ":-moz-select-scrolled-content") #ifdef MOZ_XUL CSS_ANON_BOX(moztreecolumn, ":-moz-tree-column")