зеркало из https://github.com/mozilla/pjs.git
Move the floats we reparent in AdjustFloatParentPtrs() to the "inner" state so that they end up in the right containing block. b=307277 r+sr=bzbarsky
This commit is contained in:
Родитель
6581dc0d66
Коммит
cdc77e87e4
|
@ -716,6 +716,8 @@ struct nsFrameItems {
|
||||||
|
|
||||||
// Appends the frame to the end of the list
|
// Appends the frame to the end of the list
|
||||||
void AddChild(nsIFrame* aChild);
|
void AddChild(nsIFrame* aChild);
|
||||||
|
// Remove the frame from the list, return PR_FALSE if not found.
|
||||||
|
PRBool RemoveChild(nsIFrame* aChild);
|
||||||
};
|
};
|
||||||
|
|
||||||
nsFrameItems::nsFrameItems(nsIFrame* aFrame)
|
nsFrameItems::nsFrameItems(nsIFrame* aFrame)
|
||||||
|
@ -748,6 +750,30 @@ nsFrameItems::AddChild(nsIFrame* aChild)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
nsFrameItems::RemoveChild(nsIFrame* aFrame)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aFrame, "null ptr");
|
||||||
|
nsIFrame* prev = nsnull;
|
||||||
|
nsIFrame* sib = childList;
|
||||||
|
for (; sib && sib != aFrame; sib = sib->GetNextSibling()) {
|
||||||
|
prev = sib;
|
||||||
|
}
|
||||||
|
if (!sib) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
if (sib == childList) {
|
||||||
|
childList = sib->GetNextSibling();
|
||||||
|
} else {
|
||||||
|
prev->SetNextSibling(sib->GetNextSibling());
|
||||||
|
}
|
||||||
|
if (sib == lastChild) {
|
||||||
|
lastChild = prev;
|
||||||
|
}
|
||||||
|
sib->SetNextSibling(nsnull);
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
||||||
|
|
||||||
// Structure used when constructing formatting object trees. Contains
|
// Structure used when constructing formatting object trees. Contains
|
||||||
|
@ -1574,32 +1600,40 @@ PRBool IsBorderCollapse(nsIFrame* aFrame)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
AdjustFloatParentPtrs(nsIFrame* aFrame,
|
AdjustFloatParentPtrs(nsIFrame* aFrame,
|
||||||
nsFrameConstructorState& aState)
|
nsFrameConstructorState& aState,
|
||||||
|
nsFrameConstructorState& aOuterState)
|
||||||
{
|
{
|
||||||
|
NS_PRECONDITION(aFrame, "must have frame to work with");
|
||||||
|
|
||||||
nsIFrame *outOfFlowFrame = nsPlaceholderFrame::GetRealFrameFor(aFrame);
|
nsIFrame *outOfFlowFrame = nsPlaceholderFrame::GetRealFrameFor(aFrame);
|
||||||
|
if (outOfFlowFrame != aFrame) {
|
||||||
if (outOfFlowFrame && outOfFlowFrame != aFrame) {
|
|
||||||
|
|
||||||
// Get the display data for the outOfFlowFrame so we can
|
|
||||||
// figure out if it is a float.
|
|
||||||
|
|
||||||
if (outOfFlowFrame->GetStyleDisplay()->IsFloating()) {
|
if (outOfFlowFrame->GetStyleDisplay()->IsFloating()) {
|
||||||
// Update the parent pointer for outOfFlowFrame if it's
|
// Update the parent pointer for outOfFlowFrame since its
|
||||||
// containing block has changed as the result of reparenting,
|
// containing block has changed as the result of reparenting
|
||||||
|
// and move it from the outer state to the inner, bug 307277.
|
||||||
|
|
||||||
nsIFrame *parent = aState.mFloatedItems.containingBlock;
|
nsIFrame *parent = aState.mFloatedItems.containingBlock;
|
||||||
NS_ASSERTION(parent, "Should have float containing block here!");
|
NS_ASSERTION(parent, "Should have float containing block here!");
|
||||||
|
NS_ASSERTION(outOfFlowFrame->GetParent() == aOuterState.mFloatedItems.containingBlock,
|
||||||
|
"expected the float to be a child of the outer CB");
|
||||||
|
|
||||||
|
if (aOuterState.mFloatedItems.RemoveChild(outOfFlowFrame)) {
|
||||||
|
aState.mFloatedItems.AddChild(outOfFlowFrame);
|
||||||
|
} else {
|
||||||
|
NS_NOTREACHED("float wasn't in the outer state float list");
|
||||||
|
}
|
||||||
|
|
||||||
outOfFlowFrame->SetParent(parent);
|
outOfFlowFrame->SetParent(parent);
|
||||||
if (outOfFlowFrame->GetStateBits() &
|
if (outOfFlowFrame->GetStateBits() &
|
||||||
(NS_FRAME_HAS_VIEW | NS_FRAME_HAS_CHILD_WITH_VIEW)) {
|
(NS_FRAME_HAS_VIEW | NS_FRAME_HAS_CHILD_WITH_VIEW)) {
|
||||||
// We don't need to walk up the tree, since we're doing this
|
// We don't need to walk up the tree, since we're doing this
|
||||||
// recursively
|
// recursively.
|
||||||
parent->AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW);
|
parent->AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All out-of-flows are automatically float containing blocks, so we're
|
// All out-of-flows are automatically float containing blocks, so we're
|
||||||
// done here
|
// done here.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1611,14 +1645,11 @@ AdjustFloatParentPtrs(nsIFrame* aFrame,
|
||||||
|
|
||||||
// Dive down into children to see if any of their
|
// Dive down into children to see if any of their
|
||||||
// placeholders need adjusting.
|
// placeholders need adjusting.
|
||||||
|
|
||||||
nsIFrame *childFrame = aFrame->GetFirstChild(nsnull);
|
nsIFrame *childFrame = aFrame->GetFirstChild(nsnull);
|
||||||
|
while (childFrame) {
|
||||||
while (childFrame)
|
|
||||||
{
|
|
||||||
// XXX_kin: Do we need to prevent descent into anonymous content here?
|
// XXX_kin: Do we need to prevent descent into anonymous content here?
|
||||||
|
|
||||||
AdjustFloatParentPtrs(childFrame, aState);
|
AdjustFloatParentPtrs(childFrame, aState, aOuterState);
|
||||||
childFrame = childFrame->GetNextSibling();
|
childFrame = childFrame->GetNextSibling();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1635,7 +1666,8 @@ MoveChildrenTo(nsFrameManager* aFrameManager,
|
||||||
nsStyleContext* aNewParentSC,
|
nsStyleContext* aNewParentSC,
|
||||||
nsIFrame* aNewParent,
|
nsIFrame* aNewParent,
|
||||||
nsIFrame* aFrameList,
|
nsIFrame* aFrameList,
|
||||||
nsFrameConstructorState* aState)
|
nsFrameConstructorState* aState,
|
||||||
|
nsFrameConstructorState* aOuterState)
|
||||||
{
|
{
|
||||||
PRBool setHasChildWithView = PR_FALSE;
|
PRBool setHasChildWithView = PR_FALSE;
|
||||||
|
|
||||||
|
@ -1650,8 +1682,10 @@ MoveChildrenTo(nsFrameManager* aFrameManager,
|
||||||
// If aState is not null, the caller expects us to make adjustments so that
|
// If aState is not null, the caller expects us to make adjustments so that
|
||||||
// floats whose placeholders are descendants of frames in aFrameList point
|
// floats whose placeholders are descendants of frames in aFrameList point
|
||||||
// to the correct parent.
|
// to the correct parent.
|
||||||
if (aState)
|
if (aState) {
|
||||||
AdjustFloatParentPtrs(aFrameList, *aState);
|
NS_ASSERTION(aOuterState, "need an outer state too");
|
||||||
|
AdjustFloatParentPtrs(aFrameList, *aState, *aOuterState);
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// XXX When this is used with {ib} frame hierarchies, it seems
|
// XXX When this is used with {ib} frame hierarchies, it seems
|
||||||
|
@ -12739,13 +12773,12 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
|
||||||
GetAbsoluteContainingBlock(blockFrame),
|
GetAbsoluteContainingBlock(blockFrame),
|
||||||
GetFloatContainingBlock(blockFrame));
|
GetFloatContainingBlock(blockFrame));
|
||||||
|
|
||||||
// XXXbz MoveChildrenTo just sets parent pointers on the out-of-flows!
|
// If we have an inline between two blocks all inside an inline and the inner
|
||||||
// Shouldn't it move the frames to the right child list too? Right now, if
|
|
||||||
// we have an inline between two blocks all inside an inline and the inner
|
|
||||||
// inline contains a float, the float will end up in the float list of the
|
// inline contains a float, the float will end up in the float list of the
|
||||||
// parent block of the inline, but its parent pointer will be the anonymous
|
// parent block of the inline, but its parent pointer will be the anonymous
|
||||||
// block we create....
|
// block we create... AdjustFloatParentPtrs() deals with this by moving the
|
||||||
MoveChildrenTo(state.mFrameManager, blockSC, blockFrame, list2, &state);
|
// float from the outer state |aState| to the inner |state|.
|
||||||
|
MoveChildrenTo(state.mFrameManager, blockSC, blockFrame, list2, &state, &aState);
|
||||||
|
|
||||||
// list3's frames belong to another inline frame
|
// list3's frames belong to another inline frame
|
||||||
nsIFrame* inlineFrame = nsnull;
|
nsIFrame* inlineFrame = nsnull;
|
||||||
|
@ -12774,7 +12807,7 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
|
||||||
// Reparent (cheaply) the frames in list3 - we don't have to futz
|
// Reparent (cheaply) the frames in list3 - we don't have to futz
|
||||||
// with their style context because they already have the right one.
|
// with their style context because they already have the right one.
|
||||||
inlineFrame->SetInitialChildList(aState.mPresContext, nsnull, list3);
|
inlineFrame->SetInitialChildList(aState.mPresContext, nsnull, list3);
|
||||||
MoveChildrenTo(aState.mFrameManager, nsnull, inlineFrame, list3, nsnull);
|
MoveChildrenTo(aState.mFrameManager, nsnull, inlineFrame, list3, nsnull, nsnull);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the 3 frames as special. That way if any of the
|
// Mark the 3 frames as special. That way if any of the
|
||||||
|
@ -12982,7 +13015,6 @@ nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState,
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsCSSFrameConstructor::ReframeContainingBlock(nsIFrame* aFrame)
|
nsCSSFrameConstructor::ReframeContainingBlock(nsIFrame* aFrame)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче