зеркало из https://github.com/mozilla/pjs.git
More incremental reflow work.
This commit is contained in:
Родитель
3fe3d7ca6d
Коммит
eaaa05815e
|
@ -319,8 +319,7 @@ public:
|
|||
/**
|
||||
* This call is invoked when content is changed in the content tree.
|
||||
* The first frame that maps that content is asked to deal with the
|
||||
* change by generating an incremental reflow command which will be
|
||||
* to reflow the frame tree.
|
||||
* change by generating an incremental reflow command.
|
||||
*
|
||||
* @param aIndexInParent the index in the content container where
|
||||
* the new content was deleted.
|
||||
|
|
|
@ -958,13 +958,24 @@ NS_METHOD nsFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
nsReflowCommand& aReflowCommand,
|
||||
ReflowStatus& aStatus)
|
||||
{
|
||||
NS_ERROR("not a reflow command handler");
|
||||
aDesiredSize.width = 0;
|
||||
aDesiredSize.height = 0;
|
||||
aDesiredSize.ascent = 0;
|
||||
aDesiredSize.descent = 0;
|
||||
aStatus = frComplete;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
NS_PRECONDITION(aReflowCommand.GetTarget() == this, "bad target");
|
||||
|
||||
// The only type of incremental reflow command we expect to get is a
|
||||
// content changed reflow command
|
||||
if (aReflowCommand.GetType() == nsReflowCommand.ContentChanged) {
|
||||
// Generic response is to reflow the child
|
||||
return ResizeReflow(aPresContext, aDesiredSize, aMaxSize, nsnull, aStatus);
|
||||
|
||||
} else {
|
||||
NS_ERROR("not a container reflow command handler");
|
||||
aDesiredSize.width = 0;
|
||||
aDesiredSize.height = 0;
|
||||
aDesiredSize.ascent = 0;
|
||||
aDesiredSize.descent = 0;
|
||||
aStatus = frComplete;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NS_METHOD nsFrame::ContentAppended(nsIPresShell* aShell,
|
||||
|
@ -1007,10 +1018,9 @@ NS_METHOD nsFrame::ContentChanged(nsIPresShell* aShell,
|
|||
nsIContent* aChild,
|
||||
nsISupports* aSubContent)
|
||||
{
|
||||
// Generate a reflow command with our geometric parent as the target,
|
||||
// and us as the child frame
|
||||
nsReflowCommand* cmd = new nsReflowCommand(aPresContext, mGeometricParent,
|
||||
nsReflowCommand::ContentChanged, this);
|
||||
// Generate a reflow command with this frame as the target frame
|
||||
nsReflowCommand* cmd = new nsReflowCommand(aPresContext, this,
|
||||
nsReflowCommand::ContentChanged);
|
||||
aShell->AppendReflowCommand(cmd);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -525,16 +525,12 @@ PresShell::ContentChanged(nsIContent* aContent,
|
|||
{
|
||||
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
|
||||
|
||||
#if XXX_enable_once_content_changed_is_limping
|
||||
// Notify the first frame that maps the content. It will generate a reflow
|
||||
// command
|
||||
nsIFrame* frame = FindFrameWithContent(aContent);
|
||||
NS_PRECONDITION(nsnull != frame, "null frame");
|
||||
frame->ContentChanged(this, mPresContext, aContent, aSubContent);
|
||||
ProcessReflowCommands();
|
||||
#else
|
||||
mResizeReflows++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -29,13 +29,16 @@ class nsReflowCommand {
|
|||
public:
|
||||
enum ReflowType {
|
||||
// Reflow commands generated in response to a content insert/delete/append
|
||||
// notification
|
||||
// notification. The target of the reflow command is the container frame
|
||||
// itself
|
||||
FrameAppended,
|
||||
FrameInserted,
|
||||
FrameDeleted,
|
||||
|
||||
// This reflow command is used when a leaf node's content changes
|
||||
// (e.g. some text in a text run, an image's source, etc.)
|
||||
// This reflow command is used when a leaf node's content changes (e.g. some
|
||||
// text in a text run, an image's source, etc.). The target of the reflow
|
||||
// command is the frame that changed (see nsIFrame#ContentChanged() for how
|
||||
// the target frame is determined).
|
||||
ContentChanged,
|
||||
|
||||
// When an incremental reflow operation affects a next-in-flow,
|
||||
|
|
|
@ -1368,7 +1368,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
else {
|
||||
rv = ReflowUnmapped(state);
|
||||
}
|
||||
|
||||
#if 0
|
||||
} else if (aReflowCommand.GetType() == nsReflowCommand::ContentChanged) {
|
||||
// Restore our state as if the child that changed is the next frame to reflow
|
||||
nsLineData* line = FindLine(aReflowCommand.GetChildFrame());
|
||||
|
@ -1380,7 +1380,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
// Reflow the affected line, and all the lines that follow...
|
||||
// XXX Obviously this needs to be more efficient
|
||||
rv = ReflowMappedFrom(state, line);
|
||||
|
||||
#endif
|
||||
} else {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
}
|
||||
|
|
|
@ -1368,7 +1368,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
else {
|
||||
rv = ReflowUnmapped(state);
|
||||
}
|
||||
|
||||
#if 0
|
||||
} else if (aReflowCommand.GetType() == nsReflowCommand::ContentChanged) {
|
||||
// Restore our state as if the child that changed is the next frame to reflow
|
||||
nsLineData* line = FindLine(aReflowCommand.GetChildFrame());
|
||||
|
@ -1380,7 +1380,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
// Reflow the affected line, and all the lines that follow...
|
||||
// XXX Obviously this needs to be more efficient
|
||||
rv = ReflowMappedFrom(state, line);
|
||||
|
||||
#endif
|
||||
} else {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
}
|
||||
|
|
|
@ -1368,7 +1368,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
else {
|
||||
rv = ReflowUnmapped(state);
|
||||
}
|
||||
|
||||
#if 0
|
||||
} else if (aReflowCommand.GetType() == nsReflowCommand::ContentChanged) {
|
||||
// Restore our state as if the child that changed is the next frame to reflow
|
||||
nsLineData* line = FindLine(aReflowCommand.GetChildFrame());
|
||||
|
@ -1380,7 +1380,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
// Reflow the affected line, and all the lines that follow...
|
||||
// XXX Obviously this needs to be more efficient
|
||||
rv = ReflowMappedFrom(state, line);
|
||||
|
||||
#endif
|
||||
} else {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
}
|
||||
|
|
|
@ -319,8 +319,7 @@ public:
|
|||
/**
|
||||
* This call is invoked when content is changed in the content tree.
|
||||
* The first frame that maps that content is asked to deal with the
|
||||
* change by generating an incremental reflow command which will be
|
||||
* to reflow the frame tree.
|
||||
* change by generating an incremental reflow command.
|
||||
*
|
||||
* @param aIndexInParent the index in the content container where
|
||||
* the new content was deleted.
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nsHTMLAtoms.h"
|
||||
#include "nsAbsoluteFrame.h"
|
||||
#include "nsLeafFrame.h"
|
||||
#include "nsIPtr.h"
|
||||
|
||||
// XXX To Do:
|
||||
// 2. horizontal child margins
|
||||
|
@ -49,6 +50,10 @@ static NS_DEFINE_IID(kStyleFontSID, NS_STYLEFONT_SID);
|
|||
static NS_DEFINE_IID(kStyleDisplaySID, NS_STYLEDISPLAY_SID);
|
||||
static NS_DEFINE_IID(kStyleSpacingSID, NS_STYLESPACING_SID);
|
||||
|
||||
NS_DEF_PTR(nsIStyleContext);
|
||||
NS_DEF_PTR(nsIContent);
|
||||
NS_DEF_PTR(nsIContentDelegate);
|
||||
|
||||
class nsInlineState
|
||||
{
|
||||
public:
|
||||
|
@ -192,18 +197,22 @@ void nsInlineFrame::PlaceChild(nsIFrame* aChild,
|
|||
*
|
||||
* @param aPresContext presentation context to use
|
||||
* @param aState current inline state
|
||||
* @param aChildFrame the first child frame to reflow
|
||||
* @param aChildIndex the first child frame's index in the frame list
|
||||
* @return true if we successfully reflowed all the mapped children and false
|
||||
* otherwise, e.g. we pushed children to the next in flow
|
||||
*/
|
||||
PRBool nsInlineFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState)
|
||||
PRBool nsInlineFrame::ReflowMappedChildrenFrom(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aChildFrame,
|
||||
PRInt32 aChildIndex)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
NS_PRECONDITION(nsnull != mFirstChild, "no children");
|
||||
NS_PRECONDITION(nsnull != aChildFrame, "no children");
|
||||
|
||||
PRInt32 childCount = 0;
|
||||
PRInt32 childCount = aChildIndex;
|
||||
nsIFrame* prevKidFrame = nsnull;
|
||||
|
||||
// Remember our original mLastContentIsComplete so that if we end up
|
||||
|
@ -215,7 +224,7 @@ PRBool nsInlineFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
|
|||
nsSize* pKidMaxElementSize = (nsnull != aState.maxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
|
||||
for (nsIFrame* kidFrame = aChildFrame; nsnull != kidFrame; ) {
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status;
|
||||
|
||||
|
@ -259,11 +268,10 @@ PRBool nsInlineFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
|
|||
// frame. This hooks the child into the flow
|
||||
nsIFrame* continuingFrame;
|
||||
|
||||
nsIStyleContext* kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC);
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC,
|
||||
continuingFrame);
|
||||
NS_RELEASE(kidSC);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Add the continuing frame to the sibling list
|
||||
|
@ -447,11 +455,10 @@ PRBool nsInlineFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame;
|
||||
|
||||
nsIStyleContext* kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC);
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC,
|
||||
continuingFrame);
|
||||
NS_RELEASE(kidSC);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Add the continuing frame to our sibling list and then push
|
||||
|
@ -554,7 +561,7 @@ nsInlineFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
LastChild(prevKidFrame);
|
||||
for (;;) {
|
||||
// Get the next content object
|
||||
nsIContent* kid = mContent->ChildAt(kidIndex);
|
||||
nsIContentPtr kid = mContent->ChildAt(kidIndex);
|
||||
if (nsnull == kid) {
|
||||
result = frComplete;
|
||||
break;
|
||||
|
@ -563,13 +570,11 @@ nsInlineFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
// Make sure we still have room left
|
||||
if (aState.availSize.width <= 0) {
|
||||
// Note: return status was set to frNotComplete above...
|
||||
NS_RELEASE(kid);
|
||||
break;
|
||||
}
|
||||
|
||||
// Resolve style for the child
|
||||
nsIStyleContext* kidStyleContext =
|
||||
aPresContext->ResolveStyleContextFor(kid, this);
|
||||
nsIStyleContextPtr kidStyleContext = aPresContext->ResolveStyleContextFor(kid, this);
|
||||
|
||||
// Figure out how we should treat the child
|
||||
nsIFrame* kidFrame;
|
||||
|
@ -591,15 +596,13 @@ nsInlineFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
kidFrame->SetStyleContext(aPresContext, kidStyleContext);
|
||||
}
|
||||
} else if (nsnull == kidPrevInFlow) {
|
||||
nsIContentDelegate* kidDel;
|
||||
nsIContentDelegatePtr kidDel;
|
||||
switch (kidDisplay->mDisplay) {
|
||||
case NS_STYLE_DISPLAY_BLOCK:
|
||||
case NS_STYLE_DISPLAY_LIST_ITEM:
|
||||
if (kidIndex != mFirstContentOffset) {
|
||||
// We don't allow block elements to be placed in us anywhere
|
||||
// other than at our left margin.
|
||||
NS_RELEASE(kidStyleContext);
|
||||
NS_RELEASE(kid);
|
||||
goto done;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
|
@ -608,7 +611,6 @@ nsInlineFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
kidDel = kid->GetDelegate(aPresContext);
|
||||
rv = kidDel->CreateFrame(aPresContext, kid, this,
|
||||
kidStyleContext, kidFrame);
|
||||
NS_RELEASE(kidDel);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -623,8 +625,6 @@ nsInlineFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
rv = kidPrevInFlow->CreateContinuingFrame(aPresContext, this,
|
||||
kidStyleContext, kidFrame);
|
||||
}
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidStyleContext);
|
||||
|
||||
// Try to reflow the child into the available space. It might not
|
||||
// fit or might need continuing.
|
||||
|
@ -732,7 +732,7 @@ NS_METHOD nsInlineFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
|
||||
// Reflow any existing frames
|
||||
if (nsnull != mFirstChild) {
|
||||
reflowMappedOK = ReflowMappedChildren(aPresContext, state);
|
||||
reflowMappedOK = ReflowMappedChildrenFrom(aPresContext, state, mFirstChild, 0);
|
||||
|
||||
if (PR_FALSE == reflowMappedOK) {
|
||||
aStatus = frNotComplete;
|
||||
|
@ -854,14 +854,14 @@ NS_METHOD nsInlineFrame::GetReflowMetrics(nsIPresContext* aPresContext,
|
|||
* of aSkipChild in our list of children.
|
||||
* If aSkipChild is nsnull then resets the state for appended content.
|
||||
*/
|
||||
PRIntn nsInlineFrame::RecoverState(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aSkipChild)
|
||||
PRInt32 nsInlineFrame::RecoverState(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aSkipChild)
|
||||
{
|
||||
// Get ascent & descent info for all the children up to but not
|
||||
// including aSkipChild. Also compute the x coordinate for where
|
||||
// aSkipChild will be place after it is reflowed.
|
||||
PRIntn i = 0;
|
||||
PRInt32 i = 0;
|
||||
nsIFrame* kid = mFirstChild;
|
||||
nscoord x = aState.x;
|
||||
nscoord maxAscent = 0;
|
||||
|
@ -885,6 +885,78 @@ PRIntn nsInlineFrame::RecoverState(nsIPresContext* aPresContext,
|
|||
return i;
|
||||
}
|
||||
|
||||
// XXX We need to return information about whether our next-in-flow is
|
||||
// dirty...
|
||||
nsIFrame::ReflowStatus
|
||||
nsInlineFrame::IncrementalReflowFrom(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aChildFrame,
|
||||
PRInt32 aChildIndex)
|
||||
{
|
||||
ReflowStatus status = frComplete;
|
||||
|
||||
// Just reflow all the mapped children starting with childFrame.
|
||||
// XXX This isn't the optimal thing to do...
|
||||
if (ReflowMappedChildrenFrom(aPresContext, aState, aChildFrame, aChildIndex)) {
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
// Any space left?
|
||||
if (aState.availSize.width <= 0) {
|
||||
// No space left. Don't try to pull-up children
|
||||
status = frNotComplete;
|
||||
} else {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if (!PullUpChildren(aPresContext, aState)) {
|
||||
// We were not able to pull-up all the child frames from our
|
||||
// next-in-flow
|
||||
status = frNotComplete;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We were unable to reflow all our mapped frames
|
||||
status = frNotComplete;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
nsIFrame::ReflowStatus
|
||||
nsInlineFrame::IncrementalReflowAfter(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aChildFrame,
|
||||
PRInt32 aChildIndex)
|
||||
{
|
||||
ReflowStatus status = frComplete;
|
||||
nsIFrame* nextFrame;
|
||||
|
||||
aChildFrame->GetNextSibling(nextFrame);
|
||||
|
||||
// Just reflow all the remaining mapped children
|
||||
// XXX This isn't the optimal thing to do...
|
||||
if ((nsnull == nextFrame) ||
|
||||
ReflowMappedChildrenFrom(aPresContext, aState, nextFrame, aChildIndex + 1)) {
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
// Any space left?
|
||||
if (aState.availSize.width <= 0) {
|
||||
// No space left. Don't try to pull-up children
|
||||
status = frNotComplete;
|
||||
} else {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if (!PullUpChildren(aPresContext, aState)) {
|
||||
// We were not able to pull-up all the child frames from our
|
||||
// next-in-flow
|
||||
status = frNotComplete;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We were unable to reflow all our mapped frames
|
||||
status = frNotComplete;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NS_METHOD nsInlineFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsSize& aMaxSize,
|
||||
|
@ -899,7 +971,9 @@ NS_METHOD nsInlineFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
nsStyleSpacing* styleSpacing =
|
||||
(nsStyleSpacing*)mStyleContext->GetData(kStyleSpacingSID);
|
||||
|
||||
nscoord lineHeight;
|
||||
nscoord lineHeight;
|
||||
nsIFrame* kidFrame;
|
||||
PRInt32 kidIndex;
|
||||
|
||||
nsInlineState state(styleFont, styleSpacing, aMaxSize, nsnull);
|
||||
InitializeState(aPresContext, state);
|
||||
|
@ -913,22 +987,112 @@ NS_METHOD nsInlineFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
aStatus = ReflowUnmappedChildren(aPresContext, state);
|
||||
|
||||
// Vertically align the children
|
||||
lineHeight =
|
||||
nsCSSLayout::VerticallyAlignChildren(aPresContext, this, styleFont,
|
||||
styleSpacing->mBorderPadding.top,
|
||||
mFirstChild, mChildCount,
|
||||
state.ascents, state.maxAscent);
|
||||
lineHeight = nsCSSLayout::VerticallyAlignChildren(aPresContext, this,
|
||||
styleFont, styleSpacing->mBorderPadding.top, mFirstChild,
|
||||
mChildCount, state.ascents, state.maxAscent);
|
||||
|
||||
ComputeFinalSize(aPresContext, state, aDesiredSize);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case nsReflowCommand::ContentChanged:
|
||||
// Recover our state
|
||||
kidFrame = aReflowCommand.GetChildFrame();
|
||||
kidIndex = RecoverState(aPresContext, state, kidFrame);
|
||||
aStatus = IncrementalReflowFrom(aPresContext, state, kidFrame, kidIndex);
|
||||
|
||||
// Vertically align the children
|
||||
lineHeight = nsCSSLayout::VerticallyAlignChildren(aPresContext, this,
|
||||
styleFont, styleSpacing->mBorderPadding.top, mFirstChild,
|
||||
mChildCount, state.ascents, state.maxAscent);
|
||||
|
||||
ComputeFinalSize(aPresContext, state, aDesiredSize);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
// The command is passing through us. Get the next frame in the reflow chain
|
||||
nsIFrame* kidFrame = aReflowCommand.GetNext();
|
||||
nsReflowMetrics kidSize;
|
||||
|
||||
// Restore our state as if nextFrame is the next frame to reflow
|
||||
kidIndex = RecoverState(aPresContext, state, kidFrame);
|
||||
|
||||
// Reflow the child into the available space
|
||||
aStatus = aReflowCommand.Next(kidSize, state.availSize, kidFrame);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidSize.width > state.availSize.width) && (kidFrame != mFirstChild)) {
|
||||
nsIFrame* prevFrame;
|
||||
|
||||
// The child is too wide to fit in the available space, and it's not our
|
||||
// first child
|
||||
PrevChild(kidFrame, prevFrame);
|
||||
PushChildren(kidFrame, prevFrame, mLastContentIsComplete);
|
||||
SetLastContentOffset(prevFrame);
|
||||
mChildCount = kidIndex - 1;
|
||||
aStatus = frNotComplete;
|
||||
|
||||
} else {
|
||||
// Place and size the child
|
||||
PlaceChild(kidFrame, kidIndex, state, kidSize, nsnull);
|
||||
|
||||
nsIFrame* kidNextInFlow;
|
||||
kidFrame->GetNextInFlow(kidNextInFlow);
|
||||
|
||||
// Is the child complete?
|
||||
if (frComplete == aStatus) {
|
||||
// Check whether the frame has next-in-flow(s) that are no longer needed
|
||||
if (nsnull != kidNextInFlow) {
|
||||
// Remove the next-in-flow(s)
|
||||
DeleteChildsNextInFlow(kidFrame);
|
||||
}
|
||||
|
||||
// Adjust the frames that follow
|
||||
aStatus = IncrementalReflowAfter(aPresContext, state, kidFrame, kidIndex);
|
||||
|
||||
} else {
|
||||
nsIFrame* nextSibling;
|
||||
|
||||
// No, the child isn't complete
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a continuing
|
||||
// frame.
|
||||
nsIFrame* continuingFrame;
|
||||
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC, continuingFrame);
|
||||
|
||||
// Link the child into the sibling list
|
||||
kidFrame->GetNextSibling(nextSibling);
|
||||
continuingFrame->SetNextSibling(nextSibling);
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
}
|
||||
|
||||
// We've used up all of our available space, so push the remaining
|
||||
// children to the next-in-flow
|
||||
kidFrame->GetNextSibling(nextSibling);
|
||||
if (nsnull != nextSibling) {
|
||||
PushChildren(nextSibling, kidFrame, mLastContentIsComplete);
|
||||
}
|
||||
|
||||
SetLastContentOffset(kidFrame);
|
||||
mChildCount = kidIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Vertically align the children
|
||||
lineHeight = nsCSSLayout::VerticallyAlignChildren(aPresContext, this,
|
||||
styleFont, styleSpacing->mBorderPadding.top, mFirstChild,
|
||||
mChildCount, state.ascents, state.maxAscent);
|
||||
|
||||
ComputeFinalSize(aPresContext, state, aDesiredSize);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -59,8 +59,10 @@ protected:
|
|||
nsInlineState& aState,
|
||||
nsReflowMetrics& aSize);
|
||||
|
||||
PRBool ReflowMappedChildren(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState);
|
||||
PRBool ReflowMappedChildrenFrom(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aChildFrame,
|
||||
PRInt32 aChildIndex);
|
||||
|
||||
PRBool PullUpChildren(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState);
|
||||
|
@ -74,8 +76,19 @@ protected:
|
|||
const nsReflowMetrics& aChildSize,
|
||||
const nsSize* aChildMaxElementSize);
|
||||
|
||||
PRIntn RecoverState(nsIPresContext* aCX, nsInlineState& aState,
|
||||
nsIFrame* aSkipChild);
|
||||
PRInt32 RecoverState(nsIPresContext* aCX,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aSkipChild);
|
||||
|
||||
ReflowStatus IncrementalReflowFrom(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aChildFrame,
|
||||
PRInt32 aChildIndex);
|
||||
|
||||
ReflowStatus IncrementalReflowAfter(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aChildFrame,
|
||||
PRInt32 aChildIndex);
|
||||
|
||||
ReflowStatus AdjustChildren(nsIPresContext* aPresContext,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
|
|
|
@ -1368,7 +1368,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
else {
|
||||
rv = ReflowUnmapped(state);
|
||||
}
|
||||
|
||||
#if 0
|
||||
} else if (aReflowCommand.GetType() == nsReflowCommand::ContentChanged) {
|
||||
// Restore our state as if the child that changed is the next frame to reflow
|
||||
nsLineData* line = FindLine(aReflowCommand.GetChildFrame());
|
||||
|
@ -1380,7 +1380,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
// Reflow the affected line, and all the lines that follow...
|
||||
// XXX Obviously this needs to be more efficient
|
||||
rv = ReflowMappedFrom(state, line);
|
||||
|
||||
#endif
|
||||
} else {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
}
|
||||
|
|
|
@ -1368,7 +1368,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
else {
|
||||
rv = ReflowUnmapped(state);
|
||||
}
|
||||
|
||||
#if 0
|
||||
} else if (aReflowCommand.GetType() == nsReflowCommand::ContentChanged) {
|
||||
// Restore our state as if the child that changed is the next frame to reflow
|
||||
nsLineData* line = FindLine(aReflowCommand.GetChildFrame());
|
||||
|
@ -1380,7 +1380,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
// Reflow the affected line, and all the lines that follow...
|
||||
// XXX Obviously this needs to be more efficient
|
||||
rv = ReflowMappedFrom(state, line);
|
||||
|
||||
#endif
|
||||
} else {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
}
|
||||
|
|
|
@ -1368,7 +1368,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
else {
|
||||
rv = ReflowUnmapped(state);
|
||||
}
|
||||
|
||||
#if 0
|
||||
} else if (aReflowCommand.GetType() == nsReflowCommand::ContentChanged) {
|
||||
// Restore our state as if the child that changed is the next frame to reflow
|
||||
nsLineData* line = FindLine(aReflowCommand.GetChildFrame());
|
||||
|
@ -1380,7 +1380,7 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
// Reflow the affected line, and all the lines that follow...
|
||||
// XXX Obviously this needs to be more efficient
|
||||
rv = ReflowMappedFrom(state, line);
|
||||
|
||||
#endif
|
||||
} else {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
}
|
||||
|
|
|
@ -251,6 +251,14 @@ NS_METHOD nsBodyFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
nsReflowCommand& aReflowCommand,
|
||||
ReflowStatus& aStatus)
|
||||
{
|
||||
// XXX Currently there's a bug that when the body background image dimension
|
||||
// is resolved we're treating that as a content change rather than just repainting
|
||||
// the body...
|
||||
if (aReflowCommand.GetTarget() == this) {
|
||||
NS_ASSERTION(aReflowCommand.GetType() == nsReflowCommand::ContentChanged, "unexpected type");
|
||||
return ResizeReflow(aPresContext, aDesiredSize, aMaxSize, nsnull, aStatus);
|
||||
}
|
||||
|
||||
// Get our border/padding info
|
||||
nsStyleSpacing* mySpacing =
|
||||
(nsStyleSpacing*)mStyleContext->GetData(kStyleSpacingSID);
|
||||
|
@ -265,8 +273,10 @@ NS_METHOD nsBodyFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
|
||||
mSpaceManager->Translate(leftInset, topInset);
|
||||
|
||||
#if 0
|
||||
// The reflow command should never be target for us
|
||||
NS_ASSERTION(aReflowCommand.GetTarget() != this, "bad reflow command target");
|
||||
#endif
|
||||
|
||||
// Compute the child frame's max size
|
||||
nsSize columnMaxSize = GetColumnAvailSpace(aPresContext, mySpacing,
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nsHTMLAtoms.h"
|
||||
#include "nsAbsoluteFrame.h"
|
||||
#include "nsLeafFrame.h"
|
||||
#include "nsIPtr.h"
|
||||
|
||||
// XXX To Do:
|
||||
// 2. horizontal child margins
|
||||
|
@ -49,6 +50,10 @@ static NS_DEFINE_IID(kStyleFontSID, NS_STYLEFONT_SID);
|
|||
static NS_DEFINE_IID(kStyleDisplaySID, NS_STYLEDISPLAY_SID);
|
||||
static NS_DEFINE_IID(kStyleSpacingSID, NS_STYLESPACING_SID);
|
||||
|
||||
NS_DEF_PTR(nsIStyleContext);
|
||||
NS_DEF_PTR(nsIContent);
|
||||
NS_DEF_PTR(nsIContentDelegate);
|
||||
|
||||
class nsInlineState
|
||||
{
|
||||
public:
|
||||
|
@ -192,18 +197,22 @@ void nsInlineFrame::PlaceChild(nsIFrame* aChild,
|
|||
*
|
||||
* @param aPresContext presentation context to use
|
||||
* @param aState current inline state
|
||||
* @param aChildFrame the first child frame to reflow
|
||||
* @param aChildIndex the first child frame's index in the frame list
|
||||
* @return true if we successfully reflowed all the mapped children and false
|
||||
* otherwise, e.g. we pushed children to the next in flow
|
||||
*/
|
||||
PRBool nsInlineFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState)
|
||||
PRBool nsInlineFrame::ReflowMappedChildrenFrom(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aChildFrame,
|
||||
PRInt32 aChildIndex)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
VerifyLastIsComplete();
|
||||
#endif
|
||||
NS_PRECONDITION(nsnull != mFirstChild, "no children");
|
||||
NS_PRECONDITION(nsnull != aChildFrame, "no children");
|
||||
|
||||
PRInt32 childCount = 0;
|
||||
PRInt32 childCount = aChildIndex;
|
||||
nsIFrame* prevKidFrame = nsnull;
|
||||
|
||||
// Remember our original mLastContentIsComplete so that if we end up
|
||||
|
@ -215,7 +224,7 @@ PRBool nsInlineFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
|
|||
nsSize* pKidMaxElementSize = (nsnull != aState.maxElementSize) ? &kidMaxElementSize : nsnull;
|
||||
PRBool result = PR_TRUE;
|
||||
|
||||
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
|
||||
for (nsIFrame* kidFrame = aChildFrame; nsnull != kidFrame; ) {
|
||||
nsReflowMetrics kidSize;
|
||||
ReflowStatus status;
|
||||
|
||||
|
@ -259,11 +268,10 @@ PRBool nsInlineFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
|
|||
// frame. This hooks the child into the flow
|
||||
nsIFrame* continuingFrame;
|
||||
|
||||
nsIStyleContext* kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC);
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC,
|
||||
continuingFrame);
|
||||
NS_RELEASE(kidSC);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Add the continuing frame to the sibling list
|
||||
|
@ -447,11 +455,10 @@ PRBool nsInlineFrame::PullUpChildren(nsIPresContext* aPresContext,
|
|||
// prepares it for reflow.
|
||||
nsIFrame* continuingFrame;
|
||||
|
||||
nsIStyleContext* kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC);
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC,
|
||||
continuingFrame);
|
||||
NS_RELEASE(kidSC);
|
||||
NS_ASSERTION(nsnull != continuingFrame, "frame creation failed");
|
||||
|
||||
// Add the continuing frame to our sibling list and then push
|
||||
|
@ -554,7 +561,7 @@ nsInlineFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
LastChild(prevKidFrame);
|
||||
for (;;) {
|
||||
// Get the next content object
|
||||
nsIContent* kid = mContent->ChildAt(kidIndex);
|
||||
nsIContentPtr kid = mContent->ChildAt(kidIndex);
|
||||
if (nsnull == kid) {
|
||||
result = frComplete;
|
||||
break;
|
||||
|
@ -563,13 +570,11 @@ nsInlineFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
// Make sure we still have room left
|
||||
if (aState.availSize.width <= 0) {
|
||||
// Note: return status was set to frNotComplete above...
|
||||
NS_RELEASE(kid);
|
||||
break;
|
||||
}
|
||||
|
||||
// Resolve style for the child
|
||||
nsIStyleContext* kidStyleContext =
|
||||
aPresContext->ResolveStyleContextFor(kid, this);
|
||||
nsIStyleContextPtr kidStyleContext = aPresContext->ResolveStyleContextFor(kid, this);
|
||||
|
||||
// Figure out how we should treat the child
|
||||
nsIFrame* kidFrame;
|
||||
|
@ -591,15 +596,13 @@ nsInlineFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
kidFrame->SetStyleContext(aPresContext, kidStyleContext);
|
||||
}
|
||||
} else if (nsnull == kidPrevInFlow) {
|
||||
nsIContentDelegate* kidDel;
|
||||
nsIContentDelegatePtr kidDel;
|
||||
switch (kidDisplay->mDisplay) {
|
||||
case NS_STYLE_DISPLAY_BLOCK:
|
||||
case NS_STYLE_DISPLAY_LIST_ITEM:
|
||||
if (kidIndex != mFirstContentOffset) {
|
||||
// We don't allow block elements to be placed in us anywhere
|
||||
// other than at our left margin.
|
||||
NS_RELEASE(kidStyleContext);
|
||||
NS_RELEASE(kid);
|
||||
goto done;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
|
@ -608,7 +611,6 @@ nsInlineFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
kidDel = kid->GetDelegate(aPresContext);
|
||||
rv = kidDel->CreateFrame(aPresContext, kid, this,
|
||||
kidStyleContext, kidFrame);
|
||||
NS_RELEASE(kidDel);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -623,8 +625,6 @@ nsInlineFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
|
|||
rv = kidPrevInFlow->CreateContinuingFrame(aPresContext, this,
|
||||
kidStyleContext, kidFrame);
|
||||
}
|
||||
NS_RELEASE(kid);
|
||||
NS_RELEASE(kidStyleContext);
|
||||
|
||||
// Try to reflow the child into the available space. It might not
|
||||
// fit or might need continuing.
|
||||
|
@ -732,7 +732,7 @@ NS_METHOD nsInlineFrame::ResizeReflow(nsIPresContext* aPresContext,
|
|||
|
||||
// Reflow any existing frames
|
||||
if (nsnull != mFirstChild) {
|
||||
reflowMappedOK = ReflowMappedChildren(aPresContext, state);
|
||||
reflowMappedOK = ReflowMappedChildrenFrom(aPresContext, state, mFirstChild, 0);
|
||||
|
||||
if (PR_FALSE == reflowMappedOK) {
|
||||
aStatus = frNotComplete;
|
||||
|
@ -854,14 +854,14 @@ NS_METHOD nsInlineFrame::GetReflowMetrics(nsIPresContext* aPresContext,
|
|||
* of aSkipChild in our list of children.
|
||||
* If aSkipChild is nsnull then resets the state for appended content.
|
||||
*/
|
||||
PRIntn nsInlineFrame::RecoverState(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aSkipChild)
|
||||
PRInt32 nsInlineFrame::RecoverState(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aSkipChild)
|
||||
{
|
||||
// Get ascent & descent info for all the children up to but not
|
||||
// including aSkipChild. Also compute the x coordinate for where
|
||||
// aSkipChild will be place after it is reflowed.
|
||||
PRIntn i = 0;
|
||||
PRInt32 i = 0;
|
||||
nsIFrame* kid = mFirstChild;
|
||||
nscoord x = aState.x;
|
||||
nscoord maxAscent = 0;
|
||||
|
@ -885,6 +885,78 @@ PRIntn nsInlineFrame::RecoverState(nsIPresContext* aPresContext,
|
|||
return i;
|
||||
}
|
||||
|
||||
// XXX We need to return information about whether our next-in-flow is
|
||||
// dirty...
|
||||
nsIFrame::ReflowStatus
|
||||
nsInlineFrame::IncrementalReflowFrom(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aChildFrame,
|
||||
PRInt32 aChildIndex)
|
||||
{
|
||||
ReflowStatus status = frComplete;
|
||||
|
||||
// Just reflow all the mapped children starting with childFrame.
|
||||
// XXX This isn't the optimal thing to do...
|
||||
if (ReflowMappedChildrenFrom(aPresContext, aState, aChildFrame, aChildIndex)) {
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
// Any space left?
|
||||
if (aState.availSize.width <= 0) {
|
||||
// No space left. Don't try to pull-up children
|
||||
status = frNotComplete;
|
||||
} else {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if (!PullUpChildren(aPresContext, aState)) {
|
||||
// We were not able to pull-up all the child frames from our
|
||||
// next-in-flow
|
||||
status = frNotComplete;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We were unable to reflow all our mapped frames
|
||||
status = frNotComplete;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
nsIFrame::ReflowStatus
|
||||
nsInlineFrame::IncrementalReflowAfter(nsIPresContext* aPresContext,
|
||||
nsInlineState& aState,
|
||||
nsIFrame* aChildFrame,
|
||||
PRInt32 aChildIndex)
|
||||
{
|
||||
ReflowStatus status = frComplete;
|
||||
nsIFrame* nextFrame;
|
||||
|
||||
aChildFrame->GetNextSibling(nextFrame);
|
||||
|
||||
// Just reflow all the remaining mapped children
|
||||
// XXX This isn't the optimal thing to do...
|
||||
if ((nsnull == nextFrame) ||
|
||||
ReflowMappedChildrenFrom(aPresContext, aState, nextFrame, aChildIndex + 1)) {
|
||||
if (NextChildOffset() < mContent->ChildCount()) {
|
||||
// Any space left?
|
||||
if (aState.availSize.width <= 0) {
|
||||
// No space left. Don't try to pull-up children
|
||||
status = frNotComplete;
|
||||
} else {
|
||||
// Try and pull-up some children from a next-in-flow
|
||||
if (!PullUpChildren(aPresContext, aState)) {
|
||||
// We were not able to pull-up all the child frames from our
|
||||
// next-in-flow
|
||||
status = frNotComplete;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We were unable to reflow all our mapped frames
|
||||
status = frNotComplete;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NS_METHOD nsInlineFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
||||
nsReflowMetrics& aDesiredSize,
|
||||
const nsSize& aMaxSize,
|
||||
|
@ -899,7 +971,9 @@ NS_METHOD nsInlineFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
nsStyleSpacing* styleSpacing =
|
||||
(nsStyleSpacing*)mStyleContext->GetData(kStyleSpacingSID);
|
||||
|
||||
nscoord lineHeight;
|
||||
nscoord lineHeight;
|
||||
nsIFrame* kidFrame;
|
||||
PRInt32 kidIndex;
|
||||
|
||||
nsInlineState state(styleFont, styleSpacing, aMaxSize, nsnull);
|
||||
InitializeState(aPresContext, state);
|
||||
|
@ -913,22 +987,112 @@ NS_METHOD nsInlineFrame::IncrementalReflow(nsIPresContext* aPresContext,
|
|||
aStatus = ReflowUnmappedChildren(aPresContext, state);
|
||||
|
||||
// Vertically align the children
|
||||
lineHeight =
|
||||
nsCSSLayout::VerticallyAlignChildren(aPresContext, this, styleFont,
|
||||
styleSpacing->mBorderPadding.top,
|
||||
mFirstChild, mChildCount,
|
||||
state.ascents, state.maxAscent);
|
||||
lineHeight = nsCSSLayout::VerticallyAlignChildren(aPresContext, this,
|
||||
styleFont, styleSpacing->mBorderPadding.top, mFirstChild,
|
||||
mChildCount, state.ascents, state.maxAscent);
|
||||
|
||||
ComputeFinalSize(aPresContext, state, aDesiredSize);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case nsReflowCommand::ContentChanged:
|
||||
// Recover our state
|
||||
kidFrame = aReflowCommand.GetChildFrame();
|
||||
kidIndex = RecoverState(aPresContext, state, kidFrame);
|
||||
aStatus = IncrementalReflowFrom(aPresContext, state, kidFrame, kidIndex);
|
||||
|
||||
// Vertically align the children
|
||||
lineHeight = nsCSSLayout::VerticallyAlignChildren(aPresContext, this,
|
||||
styleFont, styleSpacing->mBorderPadding.top, mFirstChild,
|
||||
mChildCount, state.ascents, state.maxAscent);
|
||||
|
||||
ComputeFinalSize(aPresContext, state, aDesiredSize);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
NS_NOTYETIMPLEMENTED("unexpected reflow command");
|
||||
// The command is passing through us. Get the next frame in the reflow chain
|
||||
nsIFrame* kidFrame = aReflowCommand.GetNext();
|
||||
nsReflowMetrics kidSize;
|
||||
|
||||
// Restore our state as if nextFrame is the next frame to reflow
|
||||
kidIndex = RecoverState(aPresContext, state, kidFrame);
|
||||
|
||||
// Reflow the child into the available space
|
||||
aStatus = aReflowCommand.Next(kidSize, state.availSize, kidFrame);
|
||||
|
||||
// Did the child fit?
|
||||
if ((kidSize.width > state.availSize.width) && (kidFrame != mFirstChild)) {
|
||||
nsIFrame* prevFrame;
|
||||
|
||||
// The child is too wide to fit in the available space, and it's not our
|
||||
// first child
|
||||
PrevChild(kidFrame, prevFrame);
|
||||
PushChildren(kidFrame, prevFrame, mLastContentIsComplete);
|
||||
SetLastContentOffset(prevFrame);
|
||||
mChildCount = kidIndex - 1;
|
||||
aStatus = frNotComplete;
|
||||
|
||||
} else {
|
||||
// Place and size the child
|
||||
PlaceChild(kidFrame, kidIndex, state, kidSize, nsnull);
|
||||
|
||||
nsIFrame* kidNextInFlow;
|
||||
kidFrame->GetNextInFlow(kidNextInFlow);
|
||||
|
||||
// Is the child complete?
|
||||
if (frComplete == aStatus) {
|
||||
// Check whether the frame has next-in-flow(s) that are no longer needed
|
||||
if (nsnull != kidNextInFlow) {
|
||||
// Remove the next-in-flow(s)
|
||||
DeleteChildsNextInFlow(kidFrame);
|
||||
}
|
||||
|
||||
// Adjust the frames that follow
|
||||
aStatus = IncrementalReflowAfter(aPresContext, state, kidFrame, kidIndex);
|
||||
|
||||
} else {
|
||||
nsIFrame* nextSibling;
|
||||
|
||||
// No, the child isn't complete
|
||||
if (nsnull == kidNextInFlow) {
|
||||
// The child doesn't have a next-in-flow so create a continuing
|
||||
// frame.
|
||||
nsIFrame* continuingFrame;
|
||||
|
||||
nsIStyleContextPtr kidSC;
|
||||
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
|
||||
kidFrame->CreateContinuingFrame(aPresContext, this, kidSC, continuingFrame);
|
||||
|
||||
// Link the child into the sibling list
|
||||
kidFrame->GetNextSibling(nextSibling);
|
||||
continuingFrame->SetNextSibling(nextSibling);
|
||||
kidFrame->SetNextSibling(continuingFrame);
|
||||
}
|
||||
|
||||
// We've used up all of our available space, so push the remaining
|
||||
// children to the next-in-flow
|
||||
kidFrame->GetNextSibling(nextSibling);
|
||||
if (nsnull != nextSibling) {
|
||||
PushChildren(nextSibling, kidFrame, mLastContentIsComplete);
|
||||
}
|
||||
|
||||
SetLastContentOffset(kidFrame);
|
||||
mChildCount = kidIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// Vertically align the children
|
||||
lineHeight = nsCSSLayout::VerticallyAlignChildren(aPresContext, this,
|
||||
styleFont, styleSpacing->mBorderPadding.top, mFirstChild,
|
||||
mChildCount, state.ascents, state.maxAscent);
|
||||
|
||||
ComputeFinalSize(aPresContext, state, aDesiredSize);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче