Change the way we determine the style context parent frame to skip css anonboxes unless we're determining the style context parent for something that isitself a css anon box (and is not a non-element frame). Fixes bug 323656(which is where the patch is), bug 85872, bug 280610. As far as I can tell,also fixes bug 317876, bug 372376, bug 374297. r+sr=dbaron
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user