зеркало из https://github.com/mozilla/pjs.git
Bug 368863. Reparent floats properly when placeholders move between inline continuations. r+sr=dbaron
This commit is contained in:
Родитель
6d10cd5a6b
Коммит
91567bbb8f
|
@ -1605,10 +1605,11 @@ static PRBool LineHasClear(nsLineBox* aLine) {
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
nsBlockFrame::ReparentFloats(nsIFrame* aFirstFrame,
|
nsBlockFrame::ReparentFloats(nsIFrame* aFirstFrame,
|
||||||
nsBlockFrame* aOldParent, PRBool aFromOverflow) {
|
nsBlockFrame* aOldParent, PRBool aFromOverflow,
|
||||||
|
PRBool aReparentSiblings) {
|
||||||
nsFrameList list;
|
nsFrameList list;
|
||||||
nsIFrame* tail = nsnull;
|
nsIFrame* tail = nsnull;
|
||||||
aOldParent->CollectFloats(aFirstFrame, list, &tail, aFromOverflow);
|
aOldParent->CollectFloats(aFirstFrame, list, &tail, aFromOverflow, aReparentSiblings);
|
||||||
if (list.NotEmpty()) {
|
if (list.NotEmpty()) {
|
||||||
for (nsIFrame* f = list.FirstChild(); f; f = f->GetNextSibling()) {
|
for (nsIFrame* f = list.FirstChild(); f; f = f->GetNextSibling()) {
|
||||||
ReparentFrame(f, aOldParent, this);
|
ReparentFrame(f, aOldParent, this);
|
||||||
|
@ -1983,7 +1984,7 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
||||||
lastFrame->SetNextSibling(nsnull);
|
lastFrame->SetNextSibling(nsnull);
|
||||||
|
|
||||||
// Reparent floats whose placeholders are in the line.
|
// Reparent floats whose placeholders are in the line.
|
||||||
ReparentFloats(toMove->mFirstChild, nextInFlow, collectOverflowFloats);
|
ReparentFloats(toMove->mFirstChild, nextInFlow, collectOverflowFloats, PR_TRUE);
|
||||||
|
|
||||||
// Add line to our line list
|
// Add line to our line list
|
||||||
if (aState.mPrevChild) {
|
if (aState.mPrevChild) {
|
||||||
|
@ -2344,7 +2345,7 @@ nsBlockFrame::PullFrameFrom(nsBlockReflowState& aState,
|
||||||
|
|
||||||
// The frame might have (or contain) floats that need to be
|
// The frame might have (or contain) floats that need to be
|
||||||
// brought over too.
|
// brought over too.
|
||||||
ReparentFloats(frame, aFromContainer, aFromOverflowLine);
|
ReparentFloats(frame, aFromContainer, aFromOverflowLine, PR_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop pulling because we found a frame to pull
|
// Stop pulling because we found a frame to pull
|
||||||
|
@ -3983,7 +3984,7 @@ nsBlockFrame::PushLines(nsBlockReflowState& aState,
|
||||||
// Remove floats in the lines from mFloats
|
// Remove floats in the lines from mFloats
|
||||||
nsFrameList floats;
|
nsFrameList floats;
|
||||||
nsIFrame* tail = nsnull;
|
nsIFrame* tail = nsnull;
|
||||||
CollectFloats(overBegin->mFirstChild, floats, &tail, PR_FALSE);
|
CollectFloats(overBegin->mFirstChild, floats, &tail, PR_FALSE, PR_TRUE);
|
||||||
|
|
||||||
if (floats.NotEmpty()) {
|
if (floats.NotEmpty()) {
|
||||||
// Push the floats onto the front of the overflow out-of-flows list
|
// Push the floats onto the front of the overflow out-of-flows list
|
||||||
|
@ -6199,7 +6200,7 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
|
||||||
// floats from whatever list they might be in. We don't search descendants
|
// floats from whatever list they might be in. We don't search descendants
|
||||||
// that are float containing blocks. The floats must be children of 'this'.
|
// that are float containing blocks. The floats must be children of 'this'.
|
||||||
void nsBlockFrame::CollectFloats(nsIFrame* aFrame, nsFrameList& aList, nsIFrame** aTail,
|
void nsBlockFrame::CollectFloats(nsIFrame* aFrame, nsFrameList& aList, nsIFrame** aTail,
|
||||||
PRBool aFromOverflow) {
|
PRBool aFromOverflow, PRBool aCollectSiblings) {
|
||||||
while (aFrame) {
|
while (aFrame) {
|
||||||
// Don't descend into float containing blocks.
|
// Don't descend into float containing blocks.
|
||||||
if (!aFrame->IsFloatContainingBlock()) {
|
if (!aFrame->IsFloatContainingBlock()) {
|
||||||
|
@ -6221,9 +6222,11 @@ void nsBlockFrame::CollectFloats(nsIFrame* aFrame, nsFrameList& aList, nsIFrame*
|
||||||
*aTail = outOfFlowFrame;
|
*aTail = outOfFlowFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectFloats(aFrame->GetFirstChild(nsnull), aList, aTail, aFromOverflow);
|
CollectFloats(aFrame->GetFirstChild(nsnull), aList, aTail, aFromOverflow,
|
||||||
|
PR_TRUE);
|
||||||
}
|
}
|
||||||
|
if (!aCollectSiblings)
|
||||||
|
break;
|
||||||
aFrame = aFrame->GetNextSibling();
|
aFrame = aFrame->GetNextSibling();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,6 +379,11 @@ public:
|
||||||
*/
|
*/
|
||||||
nsresult DoRemoveFrame(nsIFrame* aDeletedFrame, PRBool aDestroyFrames = PR_TRUE,
|
nsresult DoRemoveFrame(nsIFrame* aDeletedFrame, PRBool aDestroyFrames = PR_TRUE,
|
||||||
PRBool aRemoveOnlyFluidContinuations = PR_TRUE);
|
PRBool aRemoveOnlyFluidContinuations = PR_TRUE);
|
||||||
|
|
||||||
|
void ReparentFloats(nsIFrame* aFirstFrame,
|
||||||
|
nsBlockFrame* aOldParent, PRBool aFromOverflow,
|
||||||
|
PRBool aReparentSiblings);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** grab overflow lines from this block's prevInFlow, and make them
|
/** grab overflow lines from this block's prevInFlow, and make them
|
||||||
|
@ -394,7 +399,7 @@ protected:
|
||||||
line_iterator RemoveFloat(nsIFrame* aFloat);
|
line_iterator RemoveFloat(nsIFrame* aFloat);
|
||||||
|
|
||||||
void CollectFloats(nsIFrame* aFrame, nsFrameList& aList, nsIFrame** aTail,
|
void CollectFloats(nsIFrame* aFrame, nsFrameList& aList, nsIFrame** aTail,
|
||||||
PRBool aFromOverflow);
|
PRBool aFromOverflow, PRBool aCollectFromSiblings);
|
||||||
// Remove a float, abs, rel positioned frame from the appropriate block's list
|
// Remove a float, abs, rel positioned frame from the appropriate block's list
|
||||||
static void DoRemoveOutOfFlowFrame(nsIFrame* aFrame);
|
static void DoRemoveOutOfFlowFrame(nsIFrame* aFrame);
|
||||||
|
|
||||||
|
@ -508,10 +513,6 @@ protected:
|
||||||
void PushLines(nsBlockReflowState& aState,
|
void PushLines(nsBlockReflowState& aState,
|
||||||
nsLineList::iterator aLineBefore);
|
nsLineList::iterator aLineBefore);
|
||||||
|
|
||||||
|
|
||||||
void ReparentFloats(nsIFrame* aFirstFrame,
|
|
||||||
nsBlockFrame* aOldParent, PRBool aFromOverflow);
|
|
||||||
|
|
||||||
void PropagateFloatDamage(nsBlockReflowState& aState,
|
void PropagateFloatDamage(nsBlockReflowState& aState,
|
||||||
nsLineBox* aLine,
|
nsLineBox* aLine,
|
||||||
nscoord aDeltaY);
|
nscoord aDeltaY);
|
||||||
|
|
|
@ -270,7 +270,8 @@ nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute extra space and divide it among the columns
|
// Compute extra space and divide it among the columns
|
||||||
nscoord extraSpace = availContentWidth - (colWidth*numColumns + colGap*(numColumns - 1));
|
nscoord extraSpace =
|
||||||
|
PR_MAX(0, availContentWidth - (colWidth*numColumns + colGap*(numColumns - 1)));
|
||||||
nscoord extraToColumns = extraSpace/numColumns;
|
nscoord extraToColumns = extraSpace/numColumns;
|
||||||
colWidth += extraToColumns;
|
colWidth += extraToColumns;
|
||||||
expectedWidthLeftOver = extraSpace - (extraToColumns*numColumns);
|
expectedWidthLeftOver = extraSpace - (extraToColumns*numColumns);
|
||||||
|
|
|
@ -247,37 +247,6 @@ nsFrameList::Split(nsIFrame* aAfterFrame, nsIFrame** aNextFrameResult)
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame*
|
|
||||||
nsFrameList::PullFrame(nsIFrame* aParent,
|
|
||||||
nsIFrame* aLastChild,
|
|
||||||
nsFrameList& aFromList)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(nsnull != aParent, "null ptr");
|
|
||||||
|
|
||||||
nsIFrame* pulledFrame = nsnull;
|
|
||||||
if (nsnull != aParent) {
|
|
||||||
pulledFrame = aFromList.FirstChild();
|
|
||||||
if (nsnull != pulledFrame) {
|
|
||||||
// Take frame off old list
|
|
||||||
aFromList.RemoveFirstChild();
|
|
||||||
|
|
||||||
// Put it on the end of this list
|
|
||||||
if (nsnull == aLastChild) {
|
|
||||||
NS_ASSERTION(nsnull == mFirstChild, "bad aLastChild");
|
|
||||||
mFirstChild = pulledFrame;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aLastChild->SetNextSibling(pulledFrame);
|
|
||||||
}
|
|
||||||
pulledFrame->SetParent(aParent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
CheckForLoops();
|
|
||||||
#endif
|
|
||||||
return pulledFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIFrame*
|
nsIFrame*
|
||||||
nsFrameList::LastChild() const
|
nsFrameList::LastChild() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -121,10 +121,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void SortByContentOrder();
|
void SortByContentOrder();
|
||||||
|
|
||||||
nsIFrame* PullFrame(nsIFrame* aParent,
|
|
||||||
nsIFrame* aLastChild,
|
|
||||||
nsFrameList& aFromList);
|
|
||||||
|
|
||||||
nsIFrame* FirstChild() const {
|
nsIFrame* FirstChild() const {
|
||||||
return mFirstChild;
|
return mFirstChild;
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,6 +247,58 @@ nsInlineFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
|
||||||
return nsSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
return nsSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsInlineFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
|
||||||
|
nsIFrame* aFrame,
|
||||||
|
PRBool aReparentSiblings)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aOurLineContainer->GetNextContinuation() ||
|
||||||
|
aOurLineContainer->GetPrevContinuation(),
|
||||||
|
"Don't call this when we have no continuation, it's a waste");
|
||||||
|
|
||||||
|
nsIFrame* ancestor = aFrame;
|
||||||
|
nsIFrame* ancestorBlockChild;
|
||||||
|
do {
|
||||||
|
ancestorBlockChild = ancestor;
|
||||||
|
ancestor = ancestor->GetParent();
|
||||||
|
if (!ancestor)
|
||||||
|
return;
|
||||||
|
} while (!ancestor->IsFloatContainingBlock());
|
||||||
|
|
||||||
|
if (ancestor == aOurLineContainer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nsBlockFrame* ourBlock;
|
||||||
|
nsresult rv = aOurLineContainer->QueryInterface(kBlockFrameCID, (void**)&ourBlock);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Not a block, but broke vertically?");
|
||||||
|
nsBlockFrame* frameBlock;
|
||||||
|
rv = ancestor->QueryInterface(kBlockFrameCID, (void**)&frameBlock);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "ancestor not a block");
|
||||||
|
|
||||||
|
nsFrameList blockChildren(ancestor->GetFirstChild(nsnull));
|
||||||
|
PRBool isOverflow = !blockChildren.ContainsFrame(ancestorBlockChild);
|
||||||
|
|
||||||
|
while (PR_TRUE) {
|
||||||
|
ourBlock->ReparentFloats(aFrame, frameBlock, isOverflow, PR_FALSE);
|
||||||
|
|
||||||
|
if (!aReparentSiblings)
|
||||||
|
return;
|
||||||
|
nsIFrame* next = aFrame->GetNextSibling();
|
||||||
|
if (!next)
|
||||||
|
return;
|
||||||
|
if (next->GetParent() == aFrame->GetParent()) {
|
||||||
|
aFrame = next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// This is paranoid and will hardly ever get hit ... but we can't actually
|
||||||
|
// trust that the frames in the sibling chain all have the same parent,
|
||||||
|
// because lazy reparenting may be going on. If we find a different
|
||||||
|
// parent we need to redo our analysis.
|
||||||
|
ReparentFloatsForInlineChild(aOurLineContainer, next, aReparentSiblings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||||
nsHTMLReflowMetrics& aMetrics,
|
nsHTMLReflowMetrics& aMetrics,
|
||||||
|
@ -261,7 +313,9 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||||
|
|
||||||
PRBool lazilySetParentPointer = PR_FALSE;
|
PRBool lazilySetParentPointer = PR_FALSE;
|
||||||
|
|
||||||
// Check for an overflow list with our prev-in-flow
|
nsIFrame* lineContainer = aReflowState.mLineLayout->GetLineContainerFrame();
|
||||||
|
|
||||||
|
// Check for an overflow list with our prev-in-flow
|
||||||
nsInlineFrame* prevInFlow = (nsInlineFrame*)GetPrevInFlow();
|
nsInlineFrame* prevInFlow = (nsInlineFrame*)GetPrevInFlow();
|
||||||
if (nsnull != prevInFlow) {
|
if (nsnull != prevInFlow) {
|
||||||
nsIFrame* prevOverflowFrames = prevInFlow->GetOverflowFrames(aPresContext, PR_TRUE);
|
nsIFrame* prevOverflowFrames = prevInFlow->GetOverflowFrames(aPresContext, PR_TRUE);
|
||||||
|
@ -282,8 +336,11 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||||
NS_ASSERTION(mFrames.IsEmpty(), "child list is not empty for initial reflow");
|
NS_ASSERTION(mFrames.IsEmpty(), "child list is not empty for initial reflow");
|
||||||
mFrames.SetFrames(prevOverflowFrames);
|
mFrames.SetFrames(prevOverflowFrames);
|
||||||
lazilySetParentPointer = PR_TRUE;
|
lazilySetParentPointer = PR_TRUE;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// Assign all floats to our block if necessary
|
||||||
|
if (lineContainer && lineContainer->GetPrevContinuation()) {
|
||||||
|
ReparentFloatsForInlineChild(lineContainer, prevOverflowFrames, PR_TRUE);
|
||||||
|
}
|
||||||
// Insert the new frames at the beginning of the child list
|
// Insert the new frames at the beginning of the child list
|
||||||
// and set their parent pointer
|
// and set their parent pointer
|
||||||
mFrames.InsertFrames(this, nsnull, prevOverflowFrames);
|
mFrames.InsertFrames(this, nsnull, prevOverflowFrames);
|
||||||
|
@ -331,6 +388,7 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
|
||||||
// aReflowState)
|
// aReflowState)
|
||||||
InlineReflowState irs;
|
InlineReflowState irs;
|
||||||
irs.mPrevFrame = nsnull;
|
irs.mPrevFrame = nsnull;
|
||||||
|
irs.mLineContainer = lineContainer;
|
||||||
irs.mNextInFlow = (nsInlineFrame*) GetNextInFlow();
|
irs.mNextInFlow = (nsInlineFrame*) GetNextInFlow();
|
||||||
irs.mSetParentPointer = lazilySetParentPointer;
|
irs.mSetParentPointer = lazilySetParentPointer;
|
||||||
|
|
||||||
|
@ -393,8 +451,22 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
|
||||||
|
|
||||||
// Check if we should lazily set the child frame's parent pointer
|
// Check if we should lazily set the child frame's parent pointer
|
||||||
if (irs.mSetParentPointer) {
|
if (irs.mSetParentPointer) {
|
||||||
|
PRBool havePrevBlock =
|
||||||
|
irs.mLineContainer && irs.mLineContainer->GetPrevContinuation();
|
||||||
|
// If our block is the first in flow, then any floats under the pulled
|
||||||
|
// frame must already belong to our block.
|
||||||
|
if (havePrevBlock) {
|
||||||
|
// This has to happen before we update frame's parent; we need to
|
||||||
|
// know frame's ancestry under its old block.
|
||||||
|
// The blockChildren.ContainsFrame check performed by
|
||||||
|
// ReparentFloatsForInlineChild here may be slow, but we can't
|
||||||
|
// easily avoid it because we don't know where 'frame' originally
|
||||||
|
// came from. If we really really have to optimize this we could
|
||||||
|
// cache whether frame->GetParent() is under its containing blocks
|
||||||
|
// overflowList or not.
|
||||||
|
ReparentFloatsForInlineChild(irs.mLineContainer, frame, PR_FALSE);
|
||||||
|
}
|
||||||
frame->SetParent(this);
|
frame->SetParent(this);
|
||||||
|
|
||||||
// We also need to check if frame has a next-in-flow. If it does, then set
|
// We also need to check if frame has a next-in-flow. If it does, then set
|
||||||
// its parent frame pointer, too. Otherwise, if we reflow frame and it's
|
// its parent frame pointer, too. Otherwise, if we reflow frame and it's
|
||||||
// complete we'll fail when deleting its next-in-flow which is no longer
|
// complete we'll fail when deleting its next-in-flow which is no longer
|
||||||
|
@ -406,6 +478,9 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext,
|
||||||
// the continuing child frame must be in our child list as well. If
|
// the continuing child frame must be in our child list as well. If
|
||||||
// not, then something is wrong
|
// not, then something is wrong
|
||||||
NS_ASSERTION(mFrames.ContainsFrame(nextInFlow), "unexpected flow");
|
NS_ASSERTION(mFrames.ContainsFrame(nextInFlow), "unexpected flow");
|
||||||
|
if (havePrevBlock) {
|
||||||
|
ReparentFloatsForInlineChild(irs.mLineContainer, nextInFlow, PR_FALSE);
|
||||||
|
}
|
||||||
nextInFlow->SetParent(this);
|
nextInFlow->SetParent(this);
|
||||||
nextInFlow = nextInFlow->GetNextInFlow();
|
nextInFlow = nextInFlow->GetNextInFlow();
|
||||||
}
|
}
|
||||||
|
@ -567,6 +642,10 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext,
|
||||||
// remaining child frames in our child list with the wrong parent
|
// remaining child frames in our child list with the wrong parent
|
||||||
// frame pointer...
|
// frame pointer...
|
||||||
if (irs.mSetParentPointer) {
|
if (irs.mSetParentPointer) {
|
||||||
|
if (irs.mLineContainer && irs.mLineContainer->GetPrevContinuation()) {
|
||||||
|
ReparentFloatsForInlineChild(irs.mLineContainer, aFrame->GetNextSibling(),
|
||||||
|
PR_TRUE);
|
||||||
|
}
|
||||||
for (nsIFrame* f = aFrame->GetNextSibling(); f; f = f->GetNextSibling()) {
|
for (nsIFrame* f = aFrame->GetNextSibling(); f; f = f->GetNextSibling()) {
|
||||||
f->SetParent(this);
|
f->SetParent(this);
|
||||||
}
|
}
|
||||||
|
@ -635,8 +714,19 @@ nsInlineFrame::PullOneFrame(nsPresContext* aPresContext,
|
||||||
nsIFrame* frame = nsnull;
|
nsIFrame* frame = nsnull;
|
||||||
nsInlineFrame* nextInFlow = irs.mNextInFlow;
|
nsInlineFrame* nextInFlow = irs.mNextInFlow;
|
||||||
while (nsnull != nextInFlow) {
|
while (nsnull != nextInFlow) {
|
||||||
frame = mFrames.PullFrame(this, irs.mPrevFrame, nextInFlow->mFrames);
|
frame = nextInFlow->mFrames.FirstChild();
|
||||||
if (nsnull != frame) {
|
if (nsnull != frame) {
|
||||||
|
// If our block has no next continuation, then any floats belonging to
|
||||||
|
// the pulled frame must belong to our block already. This check ensures
|
||||||
|
// we do no extra work in the common non-vertical-breaking case.
|
||||||
|
if (irs.mLineContainer && irs.mLineContainer->GetNextContinuation()) {
|
||||||
|
// The blockChildren.ContainsFrame check performed by
|
||||||
|
// ReparentFloatsForInlineChild will be fast because frame's ancestor
|
||||||
|
// will be the first child of its containing block.
|
||||||
|
ReparentFloatsForInlineChild(irs.mLineContainer, frame, PR_FALSE);
|
||||||
|
}
|
||||||
|
nextInFlow->mFrames.RemoveFirstChild();
|
||||||
|
mFrames.InsertFrame(this, irs.mPrevFrame, frame);
|
||||||
isComplete = PR_FALSE;
|
isComplete = PR_FALSE;
|
||||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, nextInFlow, this);
|
nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, nextInFlow, this);
|
||||||
break;
|
break;
|
||||||
|
@ -782,7 +872,8 @@ nsFirstLineFrame::StealFramesFrom(nsIFrame* aFrame)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame*
|
nsIFrame*
|
||||||
nsFirstLineFrame::PullOneFrame(nsPresContext* aPresContext, InlineReflowState& irs, PRBool* aIsComplete)
|
nsFirstLineFrame::PullOneFrame(nsPresContext* aPresContext, InlineReflowState& irs,
|
||||||
|
PRBool* aIsComplete)
|
||||||
{
|
{
|
||||||
nsIFrame* frame = nsInlineFrame::PullOneFrame(aPresContext, irs, aIsComplete);
|
nsIFrame* frame = nsInlineFrame::PullOneFrame(aPresContext, irs, aIsComplete);
|
||||||
if (frame && !GetPrevInFlow()) {
|
if (frame && !GetPrevInFlow()) {
|
||||||
|
@ -804,6 +895,8 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext,
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsIFrame* lineContainer = aReflowState.mLineLayout->GetLineContainerFrame();
|
||||||
|
|
||||||
// Check for an overflow list with our prev-in-flow
|
// Check for an overflow list with our prev-in-flow
|
||||||
nsFirstLineFrame* prevInFlow = (nsFirstLineFrame*)GetPrevInFlow();
|
nsFirstLineFrame* prevInFlow = (nsFirstLineFrame*)GetPrevInFlow();
|
||||||
if (nsnull != prevInFlow) {
|
if (nsnull != prevInFlow) {
|
||||||
|
@ -811,6 +904,10 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext,
|
||||||
if (prevOverflowFrames) {
|
if (prevOverflowFrames) {
|
||||||
nsFrameList frames(prevOverflowFrames);
|
nsFrameList frames(prevOverflowFrames);
|
||||||
|
|
||||||
|
// Assign all floats to our block if necessary
|
||||||
|
if (lineContainer && lineContainer->GetPrevContinuation()) {
|
||||||
|
ReparentFloatsForInlineChild(lineContainer, prevOverflowFrames, PR_TRUE);
|
||||||
|
}
|
||||||
mFrames.InsertFrames(this, nsnull, prevOverflowFrames);
|
mFrames.InsertFrames(this, nsnull, prevOverflowFrames);
|
||||||
ReParentChildListStyle(aPresContext, frames, this);
|
ReParentChildListStyle(aPresContext, frames, this);
|
||||||
}
|
}
|
||||||
|
@ -830,6 +927,7 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext,
|
||||||
// aReflowState)
|
// aReflowState)
|
||||||
InlineReflowState irs;
|
InlineReflowState irs;
|
||||||
irs.mPrevFrame = nsnull;
|
irs.mPrevFrame = nsnull;
|
||||||
|
irs.mLineContainer = lineContainer;
|
||||||
irs.mNextInFlow = (nsInlineFrame*) GetNextInFlow();
|
irs.mNextInFlow = (nsInlineFrame*) GetNextInFlow();
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
|
@ -160,12 +160,14 @@ protected:
|
||||||
struct InlineReflowState {
|
struct InlineReflowState {
|
||||||
nsIFrame* mPrevFrame;
|
nsIFrame* mPrevFrame;
|
||||||
nsInlineFrame* mNextInFlow;
|
nsInlineFrame* mNextInFlow;
|
||||||
|
nsIFrame* mLineContainer;
|
||||||
PRPackedBool mSetParentPointer; // when reflowing child frame first set its
|
PRPackedBool mSetParentPointer; // when reflowing child frame first set its
|
||||||
// parent frame pointer
|
// parent frame pointer
|
||||||
|
|
||||||
InlineReflowState() {
|
InlineReflowState() {
|
||||||
mPrevFrame = nsnull;
|
mPrevFrame = nsnull;
|
||||||
mNextInFlow = nsnull;
|
mNextInFlow = nsnull;
|
||||||
|
mLineContainer = nsnull;
|
||||||
mSetParentPointer = PR_FALSE;
|
mSetParentPointer = PR_FALSE;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -186,6 +188,15 @@ protected:
|
||||||
nsIFrame* aFrame,
|
nsIFrame* aFrame,
|
||||||
nsReflowStatus& aStatus);
|
nsReflowStatus& aStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reparent floats whose placeholders are inline descendants of aFrame from
|
||||||
|
* whatever block they're currently parented by to aOurBlock.
|
||||||
|
* @param aReparentSiblings if this is true, we follow aFrame's
|
||||||
|
* GetNextSibling chain reparenting them all
|
||||||
|
*/
|
||||||
|
void ReparentFloatsForInlineChild(nsIFrame* aOurBlock, nsIFrame* aFrame,
|
||||||
|
PRBool aReparentSiblings);
|
||||||
|
|
||||||
virtual nsIFrame* PullOneFrame(nsPresContext* aPresContext,
|
virtual nsIFrame* PullOneFrame(nsPresContext* aPresContext,
|
||||||
InlineReflowState& rs,
|
InlineReflowState& rs,
|
||||||
PRBool* aIsComplete);
|
PRBool* aIsComplete);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче