diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index c00df142b8c..a30293b8a90 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -6960,17 +6960,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->IsContentOfType(nsIContent::eELEMENT)) { @@ -12191,7 +12186,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/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index 0e051e6a4b9..d1973763afd 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -108,6 +108,7 @@ #include "nsWidgetsCID.h" // for NS_LOOKANDFEEL_CID #include "nsUnicharUtils.h" #include "nsLayoutErrors.h" +#include "nsContentErrors.h" #include "nsHTMLContainerFrame.h" #include "nsBoxLayoutState.h" @@ -4502,25 +4503,15 @@ GetIBSpecialSibling(nsPresContext* aPresContext, aPresContext->PropertyTable()->GetProperty(aFrame, nsLayoutAtoms::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; } /** @@ -4538,37 +4529,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->GetPresContext(), 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, @@ -4590,9 +4617,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/mozilla/layout/generic/nsFrame.h b/mozilla/layout/generic/nsFrame.h index a7ca0f378d6..42605f412c6 100644 --- a/mozilla/layout/generic/nsFrame.h +++ b/mozilla/layout/generic/nsFrame.h @@ -446,6 +446,18 @@ public: static void DisplayReflowShutdown(); #endif + /** + * 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(); diff --git a/mozilla/layout/style/nsCSSAnonBoxList.h b/mozilla/layout/style/nsCSSAnonBoxList.h index ea8bb1f1e9f..72191e75676 100644 --- a/mozilla/layout/style/nsCSSAnonBoxList.h +++ b/mozilla/layout/style/nsCSSAnonBoxList.h @@ -55,7 +55,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") @@ -88,7 +87,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")