Changed body to create block pseudo-frame instead of a column pseudo frame,

and hooked up the reflow appended code
This commit is contained in:
troy 1998-05-03 03:51:48 +00:00
Родитель bf507ab492
Коммит df86871d93
27 изменённых файлов: 999 добавлений и 697 удалений

Просмотреть файл

@ -250,12 +250,12 @@ public:
ReflowStatus& aStatus) = 0;
/**
* This call is invoked when content is appended to the content
* tree. The container frame that maps that content is asked to deal
* with the appended content by creating new frames and updating the
* index-in-parent values for it's affected children. In addition,
* the call must generate reflow commands that will incrementally
* reflow and repair the damaged portion of the frame tree.
* This call is invoked when content is appended to the content tree.
*
* This frame is the frame that maps the content object that has appended
* content. A typical response to this notification is to generate a
* FrameAppended incremental reflow command. You then handle the incremental
* reflow command by creating frames for the appended content.
*/
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
@ -263,11 +263,15 @@ public:
/**
* This call is invoked when content is inserted in the content
* tree. The container frame that maps that content is asked to deal
* with the inserted content by creating new frames and updating the
* index-in-parent values for it's affected children. In addition,
* the call must generate reflow commands that will incrementally
* reflow and repair the damaged portion of the frame tree.
* tree.
*
* This frame is the frame that maps the content object that has inserted
* content. A typical response to this notification is to update the
* index-in-parent values for the affected child frames, create and insert
* new frame(s), and generate a FrameInserted incremental reflow command.
*
* You respond to the incremental reflow command by reflowing the newly
* inserted frame and any impacted frames.
*
* @param aIndexInParent the index in the content container where
* the new content was inserted.

Просмотреть файл

@ -476,61 +476,55 @@ void PresShell::ContentChanged(nsIContent* aContent,
void PresShell::ContentAppended(nsIContent* aContainer)
{
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
nsReflowCommand* rc = new nsReflowCommand(mPresContext,
FindFrameWithContent(aContainer),
nsReflowCommand::ContentAppended,
aContainer);
AppendReflowCommand(rc);
nsIFrame* frame = FindFrameWithContent(aContainer);
NS_PRECONDITION(nsnull != frame, "null frame");
frame->ContentAppended(this, mPresContext, aContainer);
ProcessReflowCommands();
}
void PresShell::ContentInserted(nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
PRInt32 aIndexInContainer)
{
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
nsReflowCommand* rc = new nsReflowCommand(mPresContext,
FindFrameWithContent(aContainer),
nsReflowCommand::ContentInserted,
aContainer, aChild,
aIndexInContainer);
AppendReflowCommand(rc);
nsIFrame* frame = FindFrameWithContent(aContainer);
NS_PRECONDITION(nsnull != frame, "null frame");
frame->ContentInserted(this, mPresContext, aContainer, aChild, aIndexInContainer);
ProcessReflowCommands();
}
void PresShell::ContentReplaced(nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
PRInt32 aIndexInContainer)
{
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
nsReflowCommand* rc = new nsReflowCommand(mPresContext,
FindFrameWithContent(aContainer),
nsReflowCommand::ContentReplaced,
aContainer, aOldChild, aNewChild,
aIndexInContainer);
AppendReflowCommand(rc);
nsIFrame* frame = FindFrameWithContent(aContainer);
NS_PRECONDITION(nsnull != frame, "null frame");
frame->ContentReplaced(this, mPresContext, aContainer, aOldChild,
aNewChild, aIndexInContainer);
ProcessReflowCommands();
}
// XXX keep this?
void PresShell::ContentWillBeRemoved(nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
PRInt32 aIndexInContainer)
{
}
void PresShell::ContentHasBeenRemoved(nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
PRInt32 aIndexInContainer)
{
NS_PRECONDITION(nsnull != mRootFrame, "null root frame");
nsReflowCommand* rc = new nsReflowCommand(mPresContext,
FindFrameWithContent(aContainer),
nsReflowCommand::ContentDeleted,
aContainer, aChild,
aIndexInContainer);
AppendReflowCommand(rc);
nsIFrame* frame = FindFrameWithContent(aContainer);
NS_PRECONDITION(nsnull != frame, "null frame");
frame->ContentDeleted(this, mPresContext, aContainer, aChild, aIndexInContainer);
ProcessReflowCommands();
}

Просмотреть файл

@ -27,13 +27,9 @@ static NS_DEFINE_IID(kIRunaroundIID, NS_IRUNAROUND_IID);
// and a reflow command type
nsReflowCommand::nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType,
PRInt32 aIndex)
ReflowType aReflowType)
: mType(aReflowType), mTargetFrame(aTargetFrame), mPresContext(aPresContext),
mIndex(aIndex),
mContainer(nsnull),
mChild(nsnull),
mOldChild(nsnull)
mChildFrame(nsnull)
{
NS_PRECONDITION(mTargetFrame != nsnull, "null target frame");
aPresContext->AddRef();
@ -42,104 +38,23 @@ nsReflowCommand::nsReflowCommand(nsIPresContext* aPresContext,
nsReflowCommand::nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIContent* aContainer)
nsIFrame* aChildFrame)
: mType(aReflowType), mTargetFrame(aTargetFrame), mPresContext(aPresContext),
mIndex(-1),
mContainer(aContainer),
mChild(nsnull),
mOldChild(nsnull)
mChildFrame(aChildFrame)
{
NS_PRECONDITION(mTargetFrame != nsnull, "null target frame");
NS_PRECONDITION(mContainer != nsnull, "null container");
NS_PRECONDITION(mChildFrame != nsnull, "null child frame");
NS_ADDREF(aPresContext);
NS_ADDREF(aContainer);
}
nsReflowCommand::nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInParent)
: mType(aReflowType), mTargetFrame(aTargetFrame), mPresContext(aPresContext),
mIndex(aIndexInParent),
mContainer(aContainer),
mChild(aChild),
mOldChild(nsnull)
{
NS_PRECONDITION(mTargetFrame != nsnull, "null target frame");
NS_PRECONDITION(mContainer != nsnull, "null container");
NS_PRECONDITION(mChild != nsnull, "null child");
NS_ADDREF(aPresContext);
NS_ADDREF(aContainer);
NS_ADDREF(aChild);
}
nsReflowCommand::nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInParent)
: mType(aReflowType), mTargetFrame(aTargetFrame), mPresContext(aPresContext),
mIndex(aIndexInParent),
mContainer(aContainer),
mChild(aNewChild),
mOldChild(aOldChild)
{
NS_PRECONDITION(mTargetFrame != nsnull, "null target frame");
NS_PRECONDITION(mContainer != nsnull, "null container");
NS_PRECONDITION(mChild != nsnull, "null new child");
NS_PRECONDITION(mOldChild != nsnull, "null old child");
NS_ADDREF(aPresContext);
NS_ADDREF(aContainer);
NS_ADDREF(aNewChild);
NS_ADDREF(aOldChild);
}
nsReflowCommand::~nsReflowCommand()
{
NS_IF_RELEASE(mPresContext);
NS_IF_RELEASE(mContainer);
NS_IF_RELEASE(mChild);
NS_IF_RELEASE(mOldChild);
}
void nsReflowCommand::Dispatch(nsReflowMetrics& aDesiredSize,
const nsSize& aMaxSize)
{
// Special handling for content tree change commands
nsIPresShell* shell;
switch (mType) {
case nsReflowCommand::ContentAppended:
shell = mPresContext->GetShell();
mTargetFrame->ContentAppended(shell, mPresContext, mContainer);
NS_RELEASE(shell);
return;
case nsReflowCommand::ContentInserted:
shell = mPresContext->GetShell();
mTargetFrame->ContentInserted(shell, mPresContext, mContainer,
mChild, mIndex);
NS_RELEASE(shell);
return;
case nsReflowCommand::ContentReplaced:
shell = mPresContext->GetShell();
mTargetFrame->ContentReplaced(shell, mPresContext, mContainer,
mOldChild, mChild, mIndex);
NS_RELEASE(shell);
return;
case nsReflowCommand::ContentDeleted:
shell = mPresContext->GetShell();
mTargetFrame->ContentDeleted(shell, mPresContext, mContainer,
mChild, mIndex);
NS_RELEASE(shell);
return;
}
// Build the path from the target frame (index 0) to the root frame
mPath.Clear();
for (nsIFrame* f = (nsIFrame*)mTargetFrame; nsnull != f;
@ -151,7 +66,7 @@ void nsReflowCommand::Dispatch(nsReflowMetrics& aDesiredSize,
nsIFrame* root = (nsIFrame*)mPath[mPath.Count() - 1];
#ifdef NS_DEBUG
shell = mPresContext->GetShell();
nsIPresShell* shell = mPresContext->GetShell();
if (nsnull != shell) {
NS_ASSERTION(shell->GetRootFrame() == root, "bad root frame");
NS_RELEASE(shell);

Просмотреть файл

@ -28,20 +28,8 @@ class nsISpaceManager;
class nsReflowCommand {
public:
enum ReflowType {
// These reflow types are used for pre-processing a content
// append, insert or delete. The target frame is responsible for
// creating frames for the new children (or removing frames for
// delete) and then updating it's children's index-in-parent
// values. After that, the frame is responsible for creating new
// reflow commands to deal with the appended, inserted or deleted
// frames.
ContentAppended,
ContentInserted,
ContentReplaced,
ContentDeleted,
// These are the reflow commands generated after the previous
// commands have completed.
// Reflow commands generated in response to a content insert/delete/append
// notification
FrameAppended,
FrameInserted,
FrameDeleted,
@ -68,33 +56,13 @@ public:
// XXX factory methods?
nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType);
nsIFrame* aTargetFrame,
ReflowType aReflowType);
nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType,
PRInt32 aIndexValue);
nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIContent* aContainer);
nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInParent);
nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInParent);
nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIFrame* aChildFrame);
virtual ~nsReflowCommand();
@ -124,22 +92,19 @@ public:
nsIFrame* GetNext() const;
// Get the target of the reflow command
nsIFrame* GetTarget() const { return mTargetFrame; }
nsIFrame* GetTarget() const {return mTargetFrame;}
// Get the type of reflow command
ReflowType GetType() const { return mType; }
ReflowType GetType() const {return mType;}
// Get the index value
PRInt32 GetIndex() const { return mIndex; }
// Get the child frame associated with the reflow command
nsIFrame* GetChildFrame() const {return mChildFrame;}
private:
nsIPresContext* mPresContext;
ReflowType mType;
nsIContent* mContainer;
nsIContent* mChild;
nsIContent* mOldChild;
PRInt32 mIndex;
nsIFrame* mTargetFrame;
nsIFrame* mChildFrame;
nsVoidArray mPath;
};

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
// XXX what do we do with catastrophic errors (rv < 0)? What is the
// state of the reflow world after such an error?
@ -794,12 +795,12 @@ nsBlockFrame::ReflowUnmapped(nsBlockReflowState& aState)
while (nsnull != line->mNextLine) {
line = line->mNextLine;
}
prevLine = line;
prevLine = line->mPrevLine;
// If the last line is not complete then kidPrevInFlow should be
// set to the last-line's last child.
if (!prevLine->mLastContentIsComplete) {
kidPrevInFlow = prevLine->GetLastChild();
if (!line->mLastContentIsComplete) {
kidPrevInFlow = line->GetLastChild();
}
}
@ -964,6 +965,8 @@ PRBool
nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
{
PRBool rv = PR_FALSE;
#if 0
// XXX Don't need this anymore now that body has changed...
if (aState.mBlockIsPseudo) {
// Get the next content object that we would like to reflow
PRInt32 kidIndex = NextChildOffset();
@ -986,10 +989,13 @@ nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
}
}
} else {
#endif
if (NextChildOffset() < mContent->ChildCount()) {
rv = PR_TRUE;
}
#if 0
}
#endif
return rv;
}
@ -1141,8 +1147,7 @@ nsBlockFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
nsresult rv = NS_OK;
return rv;
return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer);
}
NS_METHOD
@ -1217,7 +1222,110 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
nsReflowCommand& aReflowCommand,
nsIFrame::ReflowStatus& aStatus)
{
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PreReflowCheck();
#endif
nsresult rv = NS_OK;
aStatus = frComplete;
nsBlockReflowState state;
rv = InitializeState(aPresContext, aSpaceManager, aMaxSize,
nsnull, state);
nsIPresShell* shell = state.mPresContext->GetShell();
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowCommand.GetTarget()) {
if (aReflowCommand.GetType() == nsReflowCommand::FrameAppended) {
nsLineData* lastLine = mLines;
// Get the last line
if (nsnull != lastLine) {
while (nsnull != lastLine->mNextLine) {
lastLine = lastLine->mNextLine;
}
}
// Restore the state
if ((nsnull != lastLine) && (nsnull != lastLine->mPrevLine)) {
nsLineData* prevLine = lastLine->mPrevLine;
state.mY = prevLine->mBounds.YMost();
if (!state.mUnconstrainedHeight) {
state.mAvailSize.height -= state.mY;
}
state.mKidXMost = mRect.XMost();
#if 0
// XXX Set this...
state.mPrevMaxNegBottomMargin = ?;
state.mPrevMaxPosBottomMargin = ?;
#endif
}
// Reflow unmapped children
rv = ReflowUnmapped(state);
// Set return status
aStatus = frComplete;
if (NS_LINE_LAYOUT_NOT_COMPLETE == rv) {
rv = NS_OK;
aStatus = frNotComplete;
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
// Return our desired rect and our status
// XXX Share this code with DoResizeReflow()...
aDesiredRect.x = 0;
aDesiredRect.y = 0;
aDesiredRect.width = state.mKidXMost + state.mBorderPadding.right;
if (!state.mUnconstrainedWidth) {
// Make sure we're at least as wide as the max size we were given
nscoord maxWidth = state.mAvailSize.width + state.mBorderPadding.left +
state.mBorderPadding.right;
if (aDesiredRect.width < maxWidth) {
aDesiredRect.width = maxWidth;
}
}
state.mY += state.mBorderPadding.bottom;
nscoord lastBottomMargin = state.mPrevMaxPosBottomMargin -
state.mPrevMaxNegBottomMargin;
if (!state.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (state.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - state.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
state.mY += lastBottomMargin;
}
aDesiredRect.height = state.mY;
// Now that reflow has finished, remove the cached pointer
shell->RemoveCachedData(this);
NS_RELEASE(shell);
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PostReflowCheck(aStatus);
#endif
return rv;
}

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
// XXX what do we do with catastrophic errors (rv < 0)? What is the
// state of the reflow world after such an error?
@ -794,12 +795,12 @@ nsBlockFrame::ReflowUnmapped(nsBlockReflowState& aState)
while (nsnull != line->mNextLine) {
line = line->mNextLine;
}
prevLine = line;
prevLine = line->mPrevLine;
// If the last line is not complete then kidPrevInFlow should be
// set to the last-line's last child.
if (!prevLine->mLastContentIsComplete) {
kidPrevInFlow = prevLine->GetLastChild();
if (!line->mLastContentIsComplete) {
kidPrevInFlow = line->GetLastChild();
}
}
@ -964,6 +965,8 @@ PRBool
nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
{
PRBool rv = PR_FALSE;
#if 0
// XXX Don't need this anymore now that body has changed...
if (aState.mBlockIsPseudo) {
// Get the next content object that we would like to reflow
PRInt32 kidIndex = NextChildOffset();
@ -986,10 +989,13 @@ nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
}
}
} else {
#endif
if (NextChildOffset() < mContent->ChildCount()) {
rv = PR_TRUE;
}
#if 0
}
#endif
return rv;
}
@ -1141,8 +1147,7 @@ nsBlockFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
nsresult rv = NS_OK;
return rv;
return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer);
}
NS_METHOD
@ -1217,7 +1222,110 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
nsReflowCommand& aReflowCommand,
nsIFrame::ReflowStatus& aStatus)
{
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PreReflowCheck();
#endif
nsresult rv = NS_OK;
aStatus = frComplete;
nsBlockReflowState state;
rv = InitializeState(aPresContext, aSpaceManager, aMaxSize,
nsnull, state);
nsIPresShell* shell = state.mPresContext->GetShell();
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowCommand.GetTarget()) {
if (aReflowCommand.GetType() == nsReflowCommand::FrameAppended) {
nsLineData* lastLine = mLines;
// Get the last line
if (nsnull != lastLine) {
while (nsnull != lastLine->mNextLine) {
lastLine = lastLine->mNextLine;
}
}
// Restore the state
if ((nsnull != lastLine) && (nsnull != lastLine->mPrevLine)) {
nsLineData* prevLine = lastLine->mPrevLine;
state.mY = prevLine->mBounds.YMost();
if (!state.mUnconstrainedHeight) {
state.mAvailSize.height -= state.mY;
}
state.mKidXMost = mRect.XMost();
#if 0
// XXX Set this...
state.mPrevMaxNegBottomMargin = ?;
state.mPrevMaxPosBottomMargin = ?;
#endif
}
// Reflow unmapped children
rv = ReflowUnmapped(state);
// Set return status
aStatus = frComplete;
if (NS_LINE_LAYOUT_NOT_COMPLETE == rv) {
rv = NS_OK;
aStatus = frNotComplete;
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
// Return our desired rect and our status
// XXX Share this code with DoResizeReflow()...
aDesiredRect.x = 0;
aDesiredRect.y = 0;
aDesiredRect.width = state.mKidXMost + state.mBorderPadding.right;
if (!state.mUnconstrainedWidth) {
// Make sure we're at least as wide as the max size we were given
nscoord maxWidth = state.mAvailSize.width + state.mBorderPadding.left +
state.mBorderPadding.right;
if (aDesiredRect.width < maxWidth) {
aDesiredRect.width = maxWidth;
}
}
state.mY += state.mBorderPadding.bottom;
nscoord lastBottomMargin = state.mPrevMaxPosBottomMargin -
state.mPrevMaxNegBottomMargin;
if (!state.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (state.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - state.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
state.mY += lastBottomMargin;
}
aDesiredRect.height = state.mY;
// Now that reflow has finished, remove the cached pointer
shell->RemoveCachedData(this);
NS_RELEASE(shell);
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PostReflowCheck(aStatus);
#endif
return rv;
}

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
// XXX what do we do with catastrophic errors (rv < 0)? What is the
// state of the reflow world after such an error?
@ -794,12 +795,12 @@ nsBlockFrame::ReflowUnmapped(nsBlockReflowState& aState)
while (nsnull != line->mNextLine) {
line = line->mNextLine;
}
prevLine = line;
prevLine = line->mPrevLine;
// If the last line is not complete then kidPrevInFlow should be
// set to the last-line's last child.
if (!prevLine->mLastContentIsComplete) {
kidPrevInFlow = prevLine->GetLastChild();
if (!line->mLastContentIsComplete) {
kidPrevInFlow = line->GetLastChild();
}
}
@ -964,6 +965,8 @@ PRBool
nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
{
PRBool rv = PR_FALSE;
#if 0
// XXX Don't need this anymore now that body has changed...
if (aState.mBlockIsPseudo) {
// Get the next content object that we would like to reflow
PRInt32 kidIndex = NextChildOffset();
@ -986,10 +989,13 @@ nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
}
}
} else {
#endif
if (NextChildOffset() < mContent->ChildCount()) {
rv = PR_TRUE;
}
#if 0
}
#endif
return rv;
}
@ -1141,8 +1147,7 @@ nsBlockFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
nsresult rv = NS_OK;
return rv;
return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer);
}
NS_METHOD
@ -1217,7 +1222,110 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
nsReflowCommand& aReflowCommand,
nsIFrame::ReflowStatus& aStatus)
{
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PreReflowCheck();
#endif
nsresult rv = NS_OK;
aStatus = frComplete;
nsBlockReflowState state;
rv = InitializeState(aPresContext, aSpaceManager, aMaxSize,
nsnull, state);
nsIPresShell* shell = state.mPresContext->GetShell();
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowCommand.GetTarget()) {
if (aReflowCommand.GetType() == nsReflowCommand::FrameAppended) {
nsLineData* lastLine = mLines;
// Get the last line
if (nsnull != lastLine) {
while (nsnull != lastLine->mNextLine) {
lastLine = lastLine->mNextLine;
}
}
// Restore the state
if ((nsnull != lastLine) && (nsnull != lastLine->mPrevLine)) {
nsLineData* prevLine = lastLine->mPrevLine;
state.mY = prevLine->mBounds.YMost();
if (!state.mUnconstrainedHeight) {
state.mAvailSize.height -= state.mY;
}
state.mKidXMost = mRect.XMost();
#if 0
// XXX Set this...
state.mPrevMaxNegBottomMargin = ?;
state.mPrevMaxPosBottomMargin = ?;
#endif
}
// Reflow unmapped children
rv = ReflowUnmapped(state);
// Set return status
aStatus = frComplete;
if (NS_LINE_LAYOUT_NOT_COMPLETE == rv) {
rv = NS_OK;
aStatus = frNotComplete;
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
// Return our desired rect and our status
// XXX Share this code with DoResizeReflow()...
aDesiredRect.x = 0;
aDesiredRect.y = 0;
aDesiredRect.width = state.mKidXMost + state.mBorderPadding.right;
if (!state.mUnconstrainedWidth) {
// Make sure we're at least as wide as the max size we were given
nscoord maxWidth = state.mAvailSize.width + state.mBorderPadding.left +
state.mBorderPadding.right;
if (aDesiredRect.width < maxWidth) {
aDesiredRect.width = maxWidth;
}
}
state.mY += state.mBorderPadding.bottom;
nscoord lastBottomMargin = state.mPrevMaxPosBottomMargin -
state.mPrevMaxNegBottomMargin;
if (!state.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (state.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - state.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
state.mY += lastBottomMargin;
}
aDesiredRect.height = state.mY;
// Now that reflow has finished, remove the cached pointer
shell->RemoveCachedData(this);
NS_RELEASE(shell);
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PostReflowCheck(aStatus);
#endif
return rv;
}

Просмотреть файл

@ -18,6 +18,7 @@
#include "nsHTMLContainerFrame.h"
#include "nsIRenderingContext.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsCSSRendering.h"
@ -29,6 +30,7 @@
#include "nsGUIEvent.h"
#include "nsIDocument.h"
#include "nsIURL.h"
#include "nsReflowCommand.h"
static NS_DEFINE_IID(kStyleBorderSID, NS_STYLEBORDER_SID);
static NS_DEFINE_IID(kStyleColorSID, NS_STYLECOLOR_SID);
@ -170,6 +172,40 @@ NS_METHOD nsHTMLContainerFrame::GetCursorAt(nsIPresContext& aPresContext,
return NS_OK;
}
NS_METHOD nsHTMLContainerFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
// Get the last-in-flow
nsHTMLContainerFrame* lastInFlow = (nsHTMLContainerFrame*)GetLastInFlow();
// Generate a reflow command for the frame
nsReflowCommand* cmd = new nsReflowCommand(aPresContext, lastInFlow,
nsReflowCommand::FrameAppended);
aShell->AppendReflowCommand(cmd);
return NS_OK;
}
#if 0
void nsHTMLContainerFrame::AdjustIndexInParents(nsIContent* aChild,
PRInt32 aIndexInParent,
ContentChange aChange)
{
// Walk each child
}
NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInParent)
{
// Adjust the index-in-parent of each frame that follows the child that was
// inserted
AdjustIndexInParents(aChild, aIndexInParent, ContentInserted);
}
#endif
#if 0
nsIFrame::ReflowStatus
nsHTMLContainerFrame::IncrementalReflow(nsIPresContext* aPresContext,

Просмотреть файл

@ -42,6 +42,10 @@ public:
nsIFrame** aFrame,
PRInt32& aCursor);
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
protected:
virtual ~nsHTMLContainerFrame();

Просмотреть файл

@ -250,12 +250,12 @@ public:
ReflowStatus& aStatus) = 0;
/**
* This call is invoked when content is appended to the content
* tree. The container frame that maps that content is asked to deal
* with the appended content by creating new frames and updating the
* index-in-parent values for it's affected children. In addition,
* the call must generate reflow commands that will incrementally
* reflow and repair the damaged portion of the frame tree.
* This call is invoked when content is appended to the content tree.
*
* This frame is the frame that maps the content object that has appended
* content. A typical response to this notification is to generate a
* FrameAppended incremental reflow command. You then handle the incremental
* reflow command by creating frames for the appended content.
*/
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
@ -263,11 +263,15 @@ public:
/**
* This call is invoked when content is inserted in the content
* tree. The container frame that maps that content is asked to deal
* with the inserted content by creating new frames and updating the
* index-in-parent values for it's affected children. In addition,
* the call must generate reflow commands that will incrementally
* reflow and repair the damaged portion of the frame tree.
* tree.
*
* This frame is the frame that maps the content object that has inserted
* content. A typical response to this notification is to update the
* index-in-parent values for the affected child frames, create and insert
* new frame(s), and generate a FrameInserted incremental reflow command.
*
* You respond to the incremental reflow command by reflowing the newly
* inserted frame and any impacted frames.
*
* @param aIndexInParent the index in the content container where
* the new content was inserted.

Просмотреть файл

@ -1029,49 +1029,3 @@ nsInlineFrame::AdjustChildren(nsIPresContext* aPresContext,
return frComplete;
}
// My container has new content at the end of it. Create frames for
// the appended content and then generate an incremental reflow
// command for ourselves.
NS_METHOD nsInlineFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
// Get the last in flow
nsInlineFrame* flow = (nsInlineFrame*)GetLastInFlow();
// Get index of where the content has been appended
PRInt32 kidIndex = flow->NextChildOffset();
PRInt32 startIndex = kidIndex;
nsIFrame* prevKidFrame;
flow->LastChild(prevKidFrame);
// Create frames for each new child
for (;;) {
// Get the next content object
nsIContent* kid = mContent->ChildAt(kidIndex);
if (nsnull == kid) {
break;
}
nsIContentDelegate* del = kid->GetDelegate(aPresContext);
nsIFrame* kidFrame = del->CreateFrame(aPresContext, kid, kidIndex, flow);
NS_RELEASE(del);
NS_RELEASE(kid);
// Append kidFrame to the sibling list
prevKidFrame->SetNextSibling(kidFrame);
prevKidFrame = kidFrame;
kidIndex++;
}
flow->SetLastContentOffset(prevKidFrame);
// Now generate a reflow command for flow
if (aContainer == mContent) {
nsReflowCommand* rc =
new nsReflowCommand(aPresContext, flow, nsReflowCommand::FrameAppended,
startIndex);
aShell->AppendReflowCommand(rc);
}
return NS_OK;
}

Просмотреть файл

@ -200,7 +200,10 @@ nsLineLayout::nsLineLayout(nsBlockReflowState& aState)
mSpaceManager = aState.mSpaceManager;
mBlock->GetContent(mBlockContent);
mPresContext = aState.mPresContext;
#if 0
// XXX Do we still need this?
mBlockIsPseudo = aState.mBlockIsPseudo;
#endif
mUnconstrainedWidth = aState.mUnconstrainedWidth;
mUnconstrainedHeight = aState.mUnconstrainedHeight;
mMaxElementSizePointer = aState.mMaxElementSizePointer;
@ -856,6 +859,9 @@ nsLineLayout::CreateFrameFor(nsIContent* aKid)
switch (kidDisplay->mDisplay) {
case NS_STYLE_DISPLAY_BLOCK:
case NS_STYLE_DISPLAY_LIST_ITEM:
#if 0
// XXX Do we still need this? Now that the body code is changed it
// causes a problem...
if (mBlockIsPseudo) {
// Don't create the frame! It doesn't belong in us.
@ -864,6 +870,7 @@ nsLineLayout::CreateFrameFor(nsIContent* aKid)
return NS_LINE_LAYOUT_PSEUDO_BREAK_BEFORE_BLOCK;
}
#endif
kidDel = aKid->GetDelegate(mPresContext);
kidFrame = kidDel->CreateFrame(mPresContext, aKid, mKidIndex, mBlock);
NS_RELEASE(kidDel);

Просмотреть файл

@ -106,7 +106,10 @@ struct nsLineLayout {
// The block behind the line
nsBlockFrame* mBlock;
nsISpaceManager* mSpaceManager;
#if 0
// XXX I don't think we need this anymore...
PRBool mBlockIsPseudo;
#endif
nsIContent* mBlockContent;
PRInt32 mKidIndex;

Просмотреть файл

@ -43,10 +43,6 @@ public:
nsReflowCommand& aReflowCommand,
ReflowStatus& aStatus);
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
NS_IMETHOD GetReflowMetrics(nsIPresContext* aPresContext,
nsReflowMetrics& aMetrics);

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
// XXX what do we do with catastrophic errors (rv < 0)? What is the
// state of the reflow world after such an error?
@ -794,12 +795,12 @@ nsBlockFrame::ReflowUnmapped(nsBlockReflowState& aState)
while (nsnull != line->mNextLine) {
line = line->mNextLine;
}
prevLine = line;
prevLine = line->mPrevLine;
// If the last line is not complete then kidPrevInFlow should be
// set to the last-line's last child.
if (!prevLine->mLastContentIsComplete) {
kidPrevInFlow = prevLine->GetLastChild();
if (!line->mLastContentIsComplete) {
kidPrevInFlow = line->GetLastChild();
}
}
@ -964,6 +965,8 @@ PRBool
nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
{
PRBool rv = PR_FALSE;
#if 0
// XXX Don't need this anymore now that body has changed...
if (aState.mBlockIsPseudo) {
// Get the next content object that we would like to reflow
PRInt32 kidIndex = NextChildOffset();
@ -986,10 +989,13 @@ nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
}
}
} else {
#endif
if (NextChildOffset() < mContent->ChildCount()) {
rv = PR_TRUE;
}
#if 0
}
#endif
return rv;
}
@ -1141,8 +1147,7 @@ nsBlockFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
nsresult rv = NS_OK;
return rv;
return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer);
}
NS_METHOD
@ -1217,7 +1222,110 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
nsReflowCommand& aReflowCommand,
nsIFrame::ReflowStatus& aStatus)
{
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PreReflowCheck();
#endif
nsresult rv = NS_OK;
aStatus = frComplete;
nsBlockReflowState state;
rv = InitializeState(aPresContext, aSpaceManager, aMaxSize,
nsnull, state);
nsIPresShell* shell = state.mPresContext->GetShell();
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowCommand.GetTarget()) {
if (aReflowCommand.GetType() == nsReflowCommand::FrameAppended) {
nsLineData* lastLine = mLines;
// Get the last line
if (nsnull != lastLine) {
while (nsnull != lastLine->mNextLine) {
lastLine = lastLine->mNextLine;
}
}
// Restore the state
if ((nsnull != lastLine) && (nsnull != lastLine->mPrevLine)) {
nsLineData* prevLine = lastLine->mPrevLine;
state.mY = prevLine->mBounds.YMost();
if (!state.mUnconstrainedHeight) {
state.mAvailSize.height -= state.mY;
}
state.mKidXMost = mRect.XMost();
#if 0
// XXX Set this...
state.mPrevMaxNegBottomMargin = ?;
state.mPrevMaxPosBottomMargin = ?;
#endif
}
// Reflow unmapped children
rv = ReflowUnmapped(state);
// Set return status
aStatus = frComplete;
if (NS_LINE_LAYOUT_NOT_COMPLETE == rv) {
rv = NS_OK;
aStatus = frNotComplete;
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
// Return our desired rect and our status
// XXX Share this code with DoResizeReflow()...
aDesiredRect.x = 0;
aDesiredRect.y = 0;
aDesiredRect.width = state.mKidXMost + state.mBorderPadding.right;
if (!state.mUnconstrainedWidth) {
// Make sure we're at least as wide as the max size we were given
nscoord maxWidth = state.mAvailSize.width + state.mBorderPadding.left +
state.mBorderPadding.right;
if (aDesiredRect.width < maxWidth) {
aDesiredRect.width = maxWidth;
}
}
state.mY += state.mBorderPadding.bottom;
nscoord lastBottomMargin = state.mPrevMaxPosBottomMargin -
state.mPrevMaxNegBottomMargin;
if (!state.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (state.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - state.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
state.mY += lastBottomMargin;
}
aDesiredRect.height = state.mY;
// Now that reflow has finished, remove the cached pointer
shell->RemoveCachedData(this);
NS_RELEASE(shell);
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PostReflowCheck(aStatus);
#endif
return rv;
}

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
// XXX what do we do with catastrophic errors (rv < 0)? What is the
// state of the reflow world after such an error?
@ -794,12 +795,12 @@ nsBlockFrame::ReflowUnmapped(nsBlockReflowState& aState)
while (nsnull != line->mNextLine) {
line = line->mNextLine;
}
prevLine = line;
prevLine = line->mPrevLine;
// If the last line is not complete then kidPrevInFlow should be
// set to the last-line's last child.
if (!prevLine->mLastContentIsComplete) {
kidPrevInFlow = prevLine->GetLastChild();
if (!line->mLastContentIsComplete) {
kidPrevInFlow = line->GetLastChild();
}
}
@ -964,6 +965,8 @@ PRBool
nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
{
PRBool rv = PR_FALSE;
#if 0
// XXX Don't need this anymore now that body has changed...
if (aState.mBlockIsPseudo) {
// Get the next content object that we would like to reflow
PRInt32 kidIndex = NextChildOffset();
@ -986,10 +989,13 @@ nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
}
}
} else {
#endif
if (NextChildOffset() < mContent->ChildCount()) {
rv = PR_TRUE;
}
#if 0
}
#endif
return rv;
}
@ -1141,8 +1147,7 @@ nsBlockFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
nsresult rv = NS_OK;
return rv;
return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer);
}
NS_METHOD
@ -1217,7 +1222,110 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
nsReflowCommand& aReflowCommand,
nsIFrame::ReflowStatus& aStatus)
{
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PreReflowCheck();
#endif
nsresult rv = NS_OK;
aStatus = frComplete;
nsBlockReflowState state;
rv = InitializeState(aPresContext, aSpaceManager, aMaxSize,
nsnull, state);
nsIPresShell* shell = state.mPresContext->GetShell();
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowCommand.GetTarget()) {
if (aReflowCommand.GetType() == nsReflowCommand::FrameAppended) {
nsLineData* lastLine = mLines;
// Get the last line
if (nsnull != lastLine) {
while (nsnull != lastLine->mNextLine) {
lastLine = lastLine->mNextLine;
}
}
// Restore the state
if ((nsnull != lastLine) && (nsnull != lastLine->mPrevLine)) {
nsLineData* prevLine = lastLine->mPrevLine;
state.mY = prevLine->mBounds.YMost();
if (!state.mUnconstrainedHeight) {
state.mAvailSize.height -= state.mY;
}
state.mKidXMost = mRect.XMost();
#if 0
// XXX Set this...
state.mPrevMaxNegBottomMargin = ?;
state.mPrevMaxPosBottomMargin = ?;
#endif
}
// Reflow unmapped children
rv = ReflowUnmapped(state);
// Set return status
aStatus = frComplete;
if (NS_LINE_LAYOUT_NOT_COMPLETE == rv) {
rv = NS_OK;
aStatus = frNotComplete;
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
// Return our desired rect and our status
// XXX Share this code with DoResizeReflow()...
aDesiredRect.x = 0;
aDesiredRect.y = 0;
aDesiredRect.width = state.mKidXMost + state.mBorderPadding.right;
if (!state.mUnconstrainedWidth) {
// Make sure we're at least as wide as the max size we were given
nscoord maxWidth = state.mAvailSize.width + state.mBorderPadding.left +
state.mBorderPadding.right;
if (aDesiredRect.width < maxWidth) {
aDesiredRect.width = maxWidth;
}
}
state.mY += state.mBorderPadding.bottom;
nscoord lastBottomMargin = state.mPrevMaxPosBottomMargin -
state.mPrevMaxNegBottomMargin;
if (!state.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (state.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - state.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
state.mY += lastBottomMargin;
}
aDesiredRect.height = state.mY;
// Now that reflow has finished, remove the cached pointer
shell->RemoveCachedData(this);
NS_RELEASE(shell);
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PostReflowCheck(aStatus);
#endif
return rv;
}

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
// XXX what do we do with catastrophic errors (rv < 0)? What is the
// state of the reflow world after such an error?
@ -794,12 +795,12 @@ nsBlockFrame::ReflowUnmapped(nsBlockReflowState& aState)
while (nsnull != line->mNextLine) {
line = line->mNextLine;
}
prevLine = line;
prevLine = line->mPrevLine;
// If the last line is not complete then kidPrevInFlow should be
// set to the last-line's last child.
if (!prevLine->mLastContentIsComplete) {
kidPrevInFlow = prevLine->GetLastChild();
if (!line->mLastContentIsComplete) {
kidPrevInFlow = line->GetLastChild();
}
}
@ -964,6 +965,8 @@ PRBool
nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
{
PRBool rv = PR_FALSE;
#if 0
// XXX Don't need this anymore now that body has changed...
if (aState.mBlockIsPseudo) {
// Get the next content object that we would like to reflow
PRInt32 kidIndex = NextChildOffset();
@ -986,10 +989,13 @@ nsBlockFrame::MoreToReflow(nsBlockReflowState& aState)
}
}
} else {
#endif
if (NextChildOffset() < mContent->ChildCount()) {
rv = PR_TRUE;
}
#if 0
}
#endif
return rv;
}
@ -1141,8 +1147,7 @@ nsBlockFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
nsresult rv = NS_OK;
return rv;
return nsHTMLContainerFrame::ContentAppended(aShell, aPresContext, aContainer);
}
NS_METHOD
@ -1217,7 +1222,110 @@ nsBlockFrame::IncrementalReflow(nsIPresContext* aPresContext,
nsReflowCommand& aReflowCommand,
nsIFrame::ReflowStatus& aStatus)
{
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PreReflowCheck();
#endif
nsresult rv = NS_OK;
aStatus = frComplete;
nsBlockReflowState state;
rv = InitializeState(aPresContext, aSpaceManager, aMaxSize,
nsnull, state);
nsIPresShell* shell = state.mPresContext->GetShell();
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowCommand.GetTarget()) {
if (aReflowCommand.GetType() == nsReflowCommand::FrameAppended) {
nsLineData* lastLine = mLines;
// Get the last line
if (nsnull != lastLine) {
while (nsnull != lastLine->mNextLine) {
lastLine = lastLine->mNextLine;
}
}
// Restore the state
if ((nsnull != lastLine) && (nsnull != lastLine->mPrevLine)) {
nsLineData* prevLine = lastLine->mPrevLine;
state.mY = prevLine->mBounds.YMost();
if (!state.mUnconstrainedHeight) {
state.mAvailSize.height -= state.mY;
}
state.mKidXMost = mRect.XMost();
#if 0
// XXX Set this...
state.mPrevMaxNegBottomMargin = ?;
state.mPrevMaxPosBottomMargin = ?;
#endif
}
// Reflow unmapped children
rv = ReflowUnmapped(state);
// Set return status
aStatus = frComplete;
if (NS_LINE_LAYOUT_NOT_COMPLETE == rv) {
rv = NS_OK;
aStatus = frNotComplete;
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
// Return our desired rect and our status
// XXX Share this code with DoResizeReflow()...
aDesiredRect.x = 0;
aDesiredRect.y = 0;
aDesiredRect.width = state.mKidXMost + state.mBorderPadding.right;
if (!state.mUnconstrainedWidth) {
// Make sure we're at least as wide as the max size we were given
nscoord maxWidth = state.mAvailSize.width + state.mBorderPadding.left +
state.mBorderPadding.right;
if (aDesiredRect.width < maxWidth) {
aDesiredRect.width = maxWidth;
}
}
state.mY += state.mBorderPadding.bottom;
nscoord lastBottomMargin = state.mPrevMaxPosBottomMargin -
state.mPrevMaxNegBottomMargin;
if (!state.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (state.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - state.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
state.mY += lastBottomMargin;
}
aDesiredRect.height = state.mY;
// Now that reflow has finished, remove the cached pointer
shell->RemoveCachedData(this);
NS_RELEASE(shell);
#ifdef NS_DEBUG
VerifyLines(PR_TRUE);
PostReflowCheck(aStatus);
#endif
return rv;
}

Просмотреть файл

@ -26,7 +26,7 @@
#include "nsIPresShell.h"
#include "nsIViewManager.h"
#include "nsIDeviceContext.h"
#include "nsColumnFrame.h"
#include "nsBlockFrame.h"
#include "nsSpaceManager.h"
static NS_DEFINE_IID(kIRunaroundIID, NS_IRUNAROUND_IID);
@ -84,7 +84,7 @@ void nsBodyFrame::CreateColumnFrame(nsIPresContext* aPresContext)
// Do we have a prev-in-flow?
if (nsnull == mPrevInFlow) {
// No, create a column pseudo frame
mFirstChild = new ColumnFrame(mContent, mIndexInParent, this);
nsBlockFrame::NewFrame(&mFirstChild, mContent, mIndexInParent, this);
mChildCount = 1;
// Resolve style and set the style context
@ -278,72 +278,43 @@ NS_METHOD nsBodyFrame::IncrementalReflow(nsIPresContext* aPresContext,
mSpaceManager->ClearRegions();
mSpaceManager->Translate(leftInset, topInset);
// Is the reflow command targeted for us?
if (aReflowCommand.GetTarget() == this) {
// Currently we only support appended content
if (aReflowCommand.GetType() != nsReflowCommand::FrameAppended) {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
// The reflow command should never be target for us
NS_ASSERTION(aReflowCommand.GetTarget() != this, "bad reflow command target");
// Compute the column's max size
nsSize columnMaxSize = GetColumnAvailSpace(aPresContext, mySpacing,
aMaxSize);
// Compute the column's max size
nsSize columnMaxSize = GetColumnAvailSpace(aPresContext, mySpacing,
aMaxSize);
// Pass the command along to our column pseudo frame
nsIRunaround* reflowRunaround;
nsRect aDesiredRect;
// Pass the command along to our column pseudo frame
nsIRunaround* reflowRunaround;
nsRect aDesiredRect;
NS_ASSERTION(nsnull != mFirstChild, "no first child");
mFirstChild->QueryInterface(kIRunaroundIID, (void**)&reflowRunaround);
reflowRunaround->IncrementalReflow(aPresContext, mSpaceManager,
columnMaxSize, aDesiredRect, aReflowCommand, aStatus);
NS_ASSERTION(nsnull != mFirstChild, "no first child");
mFirstChild->QueryInterface(kIRunaroundIID, (void**)&reflowRunaround);
reflowRunaround->IncrementalReflow(aPresContext, mSpaceManager,
columnMaxSize, aDesiredRect, aReflowCommand, aStatus);
// Place and size the column
aDesiredRect.x += leftInset;
aDesiredRect.y += topInset;
mFirstChild->SetRect(aDesiredRect);
// Place and size the column
aDesiredRect.x += leftInset;
aDesiredRect.y += topInset;
mFirstChild->SetRect(aDesiredRect);
// Set our last content offset and whether the last content is complete
// based on the state of the pseudo frame
SetLastContentOffset(mFirstChild);
// Set our last content offset and whether the last content is complete
// based on the state of the pseudo frame
SetLastContentOffset(mFirstChild);
// Return our desired size
#if 0
// Return our desired size
aDesiredSize.height = PR_MAX(aDesiredRect.YMost(), mSpaceManager->YMost());
if (isPseudoFrame) {
aDesiredSize.width = aDesiredRect.XMost();
aDesiredSize.height = aDesiredRect.YMost();
if (!isPseudoFrame) {
aDesiredSize.width += mySpacing->mBorderPadding.left + mySpacing->mBorderPadding.right;
aDesiredSize.height += mySpacing->mBorderPadding.top + mySpacing->mBorderPadding.bottom;
}
#else
aDesiredSize.height = PR_MAX(aDesiredRect.YMost(), mSpaceManager->YMost());
if (isPseudoFrame) {
aDesiredSize.width = aDesiredRect.XMost();
}
else {
aDesiredSize.width = aMaxSize.width;
aDesiredSize.height += mySpacing->mBorderPadding.top +
mySpacing->mBorderPadding.bottom;
}
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
#endif
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
nsRect desiredRect;
nsIFrame* child;
aStatus = aReflowCommand.Next(mSpaceManager, desiredRect, aMaxSize, child);
// XXX Deal with next in flow, adjusting of siblings, adjusting the
// content length...
// Return our desired size
aDesiredSize.width = 0;
aDesiredSize.height = 0;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
}
else {
aDesiredSize.width = aMaxSize.width;
aDesiredSize.height += mySpacing->mBorderPadding.top +
mySpacing->mBorderPadding.bottom;
}
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
mSpaceManager->Translate(-leftInset, -topInset);
return NS_OK;
@ -355,20 +326,9 @@ NS_METHOD nsBodyFrame::ContentAppended(nsIPresShell* aShell,
{
NS_ASSERTION(mContent == aContainer, "bad content-appended target");
// Get the last-in-flow
nsBodyFrame* flow = (nsBodyFrame*)GetLastInFlow();
// Since body frame's have only a single pseudo-frame in them,
// pass on the content-appended call to the pseudo-frame
PRInt32 oldLastContentOffset = mLastContentOffset;
flow->mFirstChild->ContentAppended(aShell, aPresContext, aContainer);
// Now generate a frame reflow command aimed at flow
nsReflowCommand* rc =
new nsReflowCommand(aPresContext, flow, nsReflowCommand::FrameAppended,
oldLastContentOffset);
aShell->AppendReflowCommand(rc);
return NS_OK;
// Pass along the notification to our pseudo frame. It will generate a
// reflow command
return mFirstChild->ContentAppended(aShell, aPresContext, aContainer);
}
void nsBodyFrame::AddAnchoredItem(nsIFrame* aAnchoredItem,

Просмотреть файл

@ -990,188 +990,117 @@ NS_METHOD ColumnFrame::IncrementalReflow(nsIPresContext* aPresContext,
aSpaceManager->GetTranslation(txIn, tyIn);
#endif
// Who's the reflow command targeted for?
if (aReflowCommand.GetTarget() == mGeometricParent) {
// It's targeted for our parent frame which passed the reflow
// command along to us.
//
// Currently we only support appended content, but this could also
// be an inserted reflow command.
if (aReflowCommand.GetType() != nsReflowCommand::FrameAppended) {
// Initialize our reflow state
ColumnReflowState state(aPresContext, aSpaceManager, aMaxSize);
// XXX This nees to be computed the hard way. This value will be
// wrong because it includes our previous border+padding
// values. Since those values may have changed we need to
// recalculate our maxChildWidth based on our children and then we
// can add back in order border+padding
state.kidXMost = mRect.width;
nsIFrame* target = aReflowCommand.GetTarget();
if (this == target) {
if (aReflowCommand.GetType() == nsReflowCommand::FrameAppended) {
nsIFrame* prevKidFrame;
LastChild(prevKidFrame);
// Factor in the previous kid's bottom margin information
if (nsnull != prevKidFrame) {
// When we have a previous kid frame, get it's y most coordinate
// and then setup the state so that the starting y is correct
// and the previous kid's bottom margin information is correct.
nsRect startKidRect;
prevKidFrame->GetRect(startKidRect);
// Get style info
nsStyleSpacing* kidSpacing;
prevKidFrame->GetStyleData(kStyleSpacingSID, (nsStyleStruct*&)kidSpacing);
// XXX Style system should do this...
nscoord bottomMargin = ChildIsPseudoFrame(prevKidFrame)
? 0
: kidSpacing->mMargin.bottom;
state.y = startKidRect.YMost();
if (bottomMargin < 0) {
state.prevMaxNegBottomMargin = -bottomMargin;
} else {
state.prevMaxPosBottomMargin = bottomMargin;
}
if (PR_FALSE == state.unconstrainedHeight) {
state.availSize.height -= state.y;
}
}
aSpaceManager->Translate(0, state.y);
// Now reflow unmapped children
aStatus = ReflowUnmappedChildren(aPresContext, state, nsnull);
// Restore the coordinate space
aSpaceManager->Translate(0, -state.y);
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
} else if (ChildIsPseudoFrame(target)) {
if (aReflowCommand.GetType() == nsReflowCommand::FrameAppended) {
// Because our last child is a pseudo-frame we passed along the content
// appended notification. First let the pseudo-frame reflow unmapped,
// and then we'll reflow unmapped
nsRect kidRect;
#if 0
// Initialize body reflow state
ColumnReflowState state(aPresContext, aSpaceManager, aMaxSize);
// Get to the frame that we should begin reflowing (where the
// append occured).
PRInt32 startOffset = aReflowCommand.GetIndex();
nsIFrame* kidFrame = mFirstChild;
nsIFrame* prevKidFrame = nsnull;
PRInt32 kidIndex = mFirstContentOffset;
for (;;) {
if (ChildIsPseudoFrame(kidFrame)) {
nsBlockFrame* pseudo = (nsBlockFrame*) kidFrame;
PRInt32 fco = pseudo->GetFirstContentOffset();
PRInt32 lco = pseudo->GetLastContentOffset();
/* XXX <=? mLastContentIsComplete? */
if ((fco <= startOffset) && (startOffset <= lco)) {
break;
}
} else {
PRInt32 kidIndexInParent;
kidFrame->GetIndexInParent(kidIndexInParent);
if (kidIndexInParent == startOffset) {
break;
}
}
prevKidFrame = kidFrame;
kidFrame->GetNextSibling(kidFrame);
}
// Factor in the previous kid's bottom margin information
// XXX inline version of RecoverState
if (nsnull != prevKidFrame) {
// When we have a previous kid frame, get it's y most coordinate
// and then setup the state so that the starting y is correct
// and the previous kid's bottom margin information is correct.
nsRect startKidRect;
prevKidFrame->GetRect(startKidRect);
// Get style info
nsIStyleContextPtr kidSC;
prevKidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
nsStyleSpacing* kidSpacing = (nsStyleSpacing*)
kidSC->GetData(kStyleSpacingSID);
// XXX Style system should do this...
nscoord bottomMargin = ChildIsPseudoFrame(prevKidFrame)
? 0
: kidSpacing->mMargin.bottom;
state.y = startKidRect.YMost();
if (bottomMargin < 0) {
state.prevMaxNegBottomMargin = -bottomMargin;
} else {
state.prevMaxPosBottomMargin = bottomMargin;
}
} else {
state.prevMaxNegBottomMargin = 0;
state.prevMaxPosBottomMargin = 0;
state.y = 0;
}
aSpaceManager->Translate(0, state.y);
// XXX This nees to be computed the hard way. This value will be
// wrong because it includes our previous border+padding
// values. Since those values may have changed we need to
// recalculate our maxChildWidth based on our children and then we
// can add back in order border+padding
// XXX subtract out old border+padding?
state.kidXMost = mRect.width;
// Now ResizeReflow the appended frames
while (nsnull != kidFrame) {
nsIStyleContextPtr kidSC;
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
nsStyleSpacing* kidSpacing = (nsStyleSpacing*)
kidSC->GetData(kStyleSpacingSID);
nscoord topMargin = GetTopMarginFor(aPresContext, state,
kidFrame, kidSpacing);
nsRect kidRect;
nsSize kidAvailSize(state.availSize);
// Restore our state's running y-offset and available size
target->GetRect(kidRect);
state.y = kidRect.y;
if (PR_FALSE == state.unconstrainedHeight) {
kidAvailSize.height -= topMargin;
}
// Reflow the child
state.spaceManager->Translate(0, topMargin);
aStatus = ReflowChild(kidFrame, aPresContext, state.spaceManager,
kidAvailSize, kidRect, nsnull);
state.spaceManager->Translate(0, -topMargin);
// Did it fit?
if ((kidFrame != mFirstChild) &&
((kidAvailSize.height <= 0) ||
(kidRect.YMost() > kidAvailSize.height)))
{
// No, it didn't fit. This means we need to push this child
// to our next-in-flow and get it to reflow the appended
// children.
// XXX write me
NS_ABORT();
state.availSize.height -= state.y;
}
// Place the child
state.y += topMargin;
state.spaceManager->Translate(0, topMargin);
nsSize kidMaxElementSize; // XXX unused
kidRect.x += kidSpacing->mMargin.left;
kidRect.y += state.y;
PlaceChild(aPresContext, state, kidFrame, kidSpacing,
kidRect, nsnull, kidMaxElementSize);
nsIRunaround* reflowRunaround;
nsSize kidAvailSize(state.availSize);
// XXX Style system should do this...
nscoord bottomMargin = ChildIsPseudoFrame(kidFrame)
? 0
: kidSpacing->mMargin.bottom;
if (bottomMargin < 0) {
state.prevMaxNegBottomMargin = -bottomMargin;
} else {
state.prevMaxPosBottomMargin = bottomMargin;
aSpaceManager->Translate(0, state.y);
target->QueryInterface(kIRunaroundIID, (void**)&reflowRunaround);
reflowRunaround->IncrementalReflow(aPresContext, aSpaceManager,
kidAvailSize, kidRect, aReflowCommand, aStatus);
// Place and size the child
nsSize kidMaxElementSize;
nsStyleSpacing* kidSpacing;
target->GetStyleData(kStyleSpacingSID, (nsStyleStruct*&)kidSpacing);
PlaceChild(aPresContext, state, target, kidSpacing, kidRect,
nsnull, kidMaxElementSize);
// Set our last content offset
SetLastContentOffset(target);
// If the child's status is complete then reflow unmapped children
if (frComplete == aStatus) {
aStatus = ReflowUnmappedChildren(aPresContext, state, nsnull);
}
// Is the child complete?
if (frNotComplete == aStatus) {
// No. Create a continuing frame
nsIFrame* continuingFrame;
kidFrame->CreateContinuingFrame(aPresContext, this, continuingFrame);
aSpaceManager->Translate(0, -state.y);
// Insert the frame. We'll reflow it next pass through the loop
nsIFrame* nextSibling;
kidFrame->GetNextSibling(nextSibling);
continuingFrame->SetNextSibling(nextSibling);
kidFrame->SetNextSibling(continuingFrame);
mChildCount++;
}
// Get the next child frame
prevKidFrame = kidFrame;
kidFrame->GetNextSibling(kidFrame);
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
SetLastContentOffset(prevKidFrame);
// Restore the coordinate space
aSpaceManager->Translate(0, -state.y);
// Return our desired size
// XXX What about adding in the bottom margin from our last child like we
// did in ResizeReflow()?
aDesiredRect.x = 0;
aDesiredRect.y = 0;
aDesiredRect.width = state.kidXMost;/* XXX */
aDesiredRect.height = state.y;
#endif
return ResizeReflow(aPresContext, aSpaceManager, aMaxSize, aDesiredRect,
nsnull, aStatus);
} else if (aReflowCommand.GetTarget() == this) {
// The reflow command is targeted for us. This could be a deleted or
// changed reflow command
NS_NOTYETIMPLEMENTED("unexpected reflow command");
} else {
NS_NOTYETIMPLEMENTED("unexpected reflow command");
}
// Return our desired size
// XXX What about adding in the bottom margin from our last child like we
// did in ResizeReflow()?
aDesiredRect.x = 0;
aDesiredRect.y = 0;
aDesiredRect.width = state.kidXMost;/* XXX */
aDesiredRect.height = state.y;
#ifdef NS_DEBUG
// Verify we properly restored the coordinate space
nscoord txOut, tyOut;
@ -1182,149 +1111,28 @@ NS_METHOD ColumnFrame::IncrementalReflow(nsIPresContext* aPresContext,
return NS_OK;
}
// XXX factor nicely with reflow-unmapped
NS_METHOD ColumnFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
#if 0
// We must only be called by the body frame since we are a
// pseudo-frame; the body frame makes sure that it's dealing with
// it's last-in-flow therefore we must also be a last-in-flow
NS_ASSERTION(nsnull == mNextInFlow, "improper content-appended");
NS_ASSERTION(mLastContentIsComplete == PR_TRUE, "huh?");
// Get the last-in-flow
ColumnFrame* lastInFlow = (ColumnFrame*)GetLastInFlow();
// Get index of where the content has been appended
PRInt32 kidIndex = NextChildOffset();
PRInt32 startIndex = kidIndex;
nsIContent* content = mContent;
nsIFrame* prevKidFrame;
LastChild(prevKidFrame);
nsBlockFrame* pseudoFrame = nsnull;
if ((nsnull != prevKidFrame) && ChildIsPseudoFrame(prevKidFrame)) {
pseudoFrame = (nsBlockFrame*) prevKidFrame;
// Get the last child frame, and see if it's a pseudo frame
nsIFrame* lastKidFrame;
LastChild(lastKidFrame);
if ((nsnull != lastKidFrame) && ChildIsPseudoFrame(lastKidFrame)) {
// Pass along the notification to the pseudo frame
return lastKidFrame->ContentAppended(aShell, aPresContext, aContainer);
} else {
// Generate a reflow command for the last-in-flow
nsReflowCommand* cmd = new nsReflowCommand(aPresContext, lastInFlow,
nsReflowCommand::FrameAppended);
aShell->AppendReflowCommand(cmd);
return NS_OK;
}
// Create frames for each new child
for (;;) {
// Get the next content object
nsIContentPtr kid = content->ChildAt(kidIndex);
if (nsnull == kid) {
break;
}
// Get style context for the kid
nsIStyleContextPtr kidStyleContext =
aPresContext->ResolveStyleContextFor(kid, this);
nsStyleDisplay* kidDisplay = (nsStyleDisplay*)
kidStyleContext->GetData(kStyleDisplaySID);
nsStylePosition* kidPosition = (nsStylePosition*)
kidStyleContext->GetData(kStylePositionSID);
// See what display mode it has
nsIFrame* kidFrame;
nsIContentDelegate* del;
if (NS_STYLE_POSITION_ABSOLUTE == kidPosition->mPosition) {
AbsoluteFrame::NewFrame(&kidFrame, kid, kidIndex, this);
} else {
switch (kidDisplay->mDisplay) {
case NS_STYLE_DISPLAY_NONE:
// Create place holder frame
nsFrame::NewFrame(&kidFrame, kid, kidIndex, this);
kidFrame->SetStyleContext(aPresContext,kidStyleContext);
// Append it to the child list
if (nsnull == prevKidFrame) {
mFirstChild = kidFrame;
mFirstContentOffset = kidIndex;
} else {
prevKidFrame->SetNextSibling(kidFrame);
}
mChildCount++;
prevKidFrame = kidFrame;
pseudoFrame = nsnull;
kidIndex++;
mLastContentOffset = kidIndex;
break;
case NS_STYLE_DISPLAY_BLOCK:
case NS_STYLE_DISPLAY_LIST_ITEM:
// Block and list-item's don't go into our pseudo-frames
// therefore we just make a frame.
del = kid->GetDelegate(aPresContext);
kidFrame = del->CreateFrame(aPresContext, kid, kidIndex, this);
NS_RELEASE(del);
kidFrame->SetStyleContext(aPresContext,kidStyleContext);
// Append it to the child list
if (nsnull == prevKidFrame) {
mFirstChild = kidFrame;
mFirstContentOffset = kidIndex;
} else {
prevKidFrame->SetNextSibling(kidFrame);
}
mChildCount++;
prevKidFrame = kidFrame;
pseudoFrame = nsnull;
kidIndex++;
mLastContentOffset = kidIndex;
break;
case NS_STYLE_DISPLAY_INLINE:
if (nsnull == pseudoFrame) {
// Inline elements are wrapped in a block pseudo frame; that
// way the body doesn't have to deal with 2D layout
nsBlockFrame::NewFrame(&kidFrame, mContent, mIndexInParent, this);
// Resolve style for the pseudo-frame (kid's style won't do)
kidStyleContext = aPresContext->ResolveStyleContextFor(mContent, this);
kidFrame->SetStyleContext(aPresContext,kidStyleContext);
// Append the pseudo frame to the child list
pseudoFrame = (nsBlockFrame*) kidFrame;
if (nsnull == prevKidFrame) {
mFirstChild = kidFrame;
mFirstContentOffset = kidIndex;
} else {
prevKidFrame->SetNextSibling(pseudoFrame);
}
mChildCount++;
// Set the content offset for the pseudo frame, so it knows
// which content to begin with
pseudoFrame->SetFirstContentOffset(kidIndex);
pseudoFrame->SetLastContentOffset(kidIndex);
prevKidFrame = pseudoFrame;
}
// The child frame needs to belong to the pseudo-frame (or one
// of it's pseudos). Let it do the content appended frame
// creation.
pseudoFrame->ContentAppended(aShell, aPresContext, aContainer);
// Update *our* last content offset since this child is our last
// child and it just consumed one or more of the appended
// children.
#ifdef NS_DEBUG
if (pseudoFrame == mFirstChild) {
PRInt32 pfco = pseudoFrame->GetFirstContentOffset();
NS_ASSERTION(mFirstContentOffset == pfco, "bad pseudo first offset");
}
#endif
mLastContentOffset = pseudoFrame->GetLastContentOffset();
// Pick up where it stopped
kidIndex = NextChildOffset();
break;
}
}
}
SetLastContentOffset(prevKidFrame);
// Note: Column frames *never* directly generate reflow commands
// because they are always pseudo-frames for bodies.
#endif
return NS_OK;
}
NS_METHOD ColumnFrame::CreateContinuingFrame(nsIPresContext* aPresContext,

Просмотреть файл

@ -47,14 +47,14 @@ public:
nsReflowCommand& aReflowCommand,
ReflowStatus& aStatus);
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
NS_IMETHOD CreateContinuingFrame(nsIPresContext* aPresContext,
nsIFrame* aParent,
nsIFrame*& aContinuingFrame);
NS_IMETHOD ColumnFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
// Debugging
NS_IMETHOD ListTag(FILE* out = stdout) const;

Просмотреть файл

@ -18,6 +18,7 @@
#include "nsHTMLContainerFrame.h"
#include "nsIRenderingContext.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsCSSRendering.h"
@ -29,6 +30,7 @@
#include "nsGUIEvent.h"
#include "nsIDocument.h"
#include "nsIURL.h"
#include "nsReflowCommand.h"
static NS_DEFINE_IID(kStyleBorderSID, NS_STYLEBORDER_SID);
static NS_DEFINE_IID(kStyleColorSID, NS_STYLECOLOR_SID);
@ -170,6 +172,40 @@ NS_METHOD nsHTMLContainerFrame::GetCursorAt(nsIPresContext& aPresContext,
return NS_OK;
}
NS_METHOD nsHTMLContainerFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
// Get the last-in-flow
nsHTMLContainerFrame* lastInFlow = (nsHTMLContainerFrame*)GetLastInFlow();
// Generate a reflow command for the frame
nsReflowCommand* cmd = new nsReflowCommand(aPresContext, lastInFlow,
nsReflowCommand::FrameAppended);
aShell->AppendReflowCommand(cmd);
return NS_OK;
}
#if 0
void nsHTMLContainerFrame::AdjustIndexInParents(nsIContent* aChild,
PRInt32 aIndexInParent,
ContentChange aChange)
{
// Walk each child
}
NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInParent)
{
// Adjust the index-in-parent of each frame that follows the child that was
// inserted
AdjustIndexInParents(aChild, aIndexInParent, ContentInserted);
}
#endif
#if 0
nsIFrame::ReflowStatus
nsHTMLContainerFrame::IncrementalReflow(nsIPresContext* aPresContext,

Просмотреть файл

@ -42,6 +42,10 @@ public:
nsIFrame** aFrame,
PRInt32& aCursor);
NS_IMETHOD ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer);
protected:
virtual ~nsHTMLContainerFrame();

Просмотреть файл

@ -1029,49 +1029,3 @@ nsInlineFrame::AdjustChildren(nsIPresContext* aPresContext,
return frComplete;
}
// My container has new content at the end of it. Create frames for
// the appended content and then generate an incremental reflow
// command for ourselves.
NS_METHOD nsInlineFrame::ContentAppended(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer)
{
// Get the last in flow
nsInlineFrame* flow = (nsInlineFrame*)GetLastInFlow();
// Get index of where the content has been appended
PRInt32 kidIndex = flow->NextChildOffset();
PRInt32 startIndex = kidIndex;
nsIFrame* prevKidFrame;
flow->LastChild(prevKidFrame);
// Create frames for each new child
for (;;) {
// Get the next content object
nsIContent* kid = mContent->ChildAt(kidIndex);
if (nsnull == kid) {
break;
}
nsIContentDelegate* del = kid->GetDelegate(aPresContext);
nsIFrame* kidFrame = del->CreateFrame(aPresContext, kid, kidIndex, flow);
NS_RELEASE(del);
NS_RELEASE(kid);
// Append kidFrame to the sibling list
prevKidFrame->SetNextSibling(kidFrame);
prevKidFrame = kidFrame;
kidIndex++;
}
flow->SetLastContentOffset(prevKidFrame);
// Now generate a reflow command for flow
if (aContainer == mContent) {
nsReflowCommand* rc =
new nsReflowCommand(aPresContext, flow, nsReflowCommand::FrameAppended,
startIndex);
aShell->AppendReflowCommand(rc);
}
return NS_OK;
}

Просмотреть файл

@ -200,7 +200,10 @@ nsLineLayout::nsLineLayout(nsBlockReflowState& aState)
mSpaceManager = aState.mSpaceManager;
mBlock->GetContent(mBlockContent);
mPresContext = aState.mPresContext;
#if 0
// XXX Do we still need this?
mBlockIsPseudo = aState.mBlockIsPseudo;
#endif
mUnconstrainedWidth = aState.mUnconstrainedWidth;
mUnconstrainedHeight = aState.mUnconstrainedHeight;
mMaxElementSizePointer = aState.mMaxElementSizePointer;
@ -856,6 +859,9 @@ nsLineLayout::CreateFrameFor(nsIContent* aKid)
switch (kidDisplay->mDisplay) {
case NS_STYLE_DISPLAY_BLOCK:
case NS_STYLE_DISPLAY_LIST_ITEM:
#if 0
// XXX Do we still need this? Now that the body code is changed it
// causes a problem...
if (mBlockIsPseudo) {
// Don't create the frame! It doesn't belong in us.
@ -864,6 +870,7 @@ nsLineLayout::CreateFrameFor(nsIContent* aKid)
return NS_LINE_LAYOUT_PSEUDO_BREAK_BEFORE_BLOCK;
}
#endif
kidDel = aKid->GetDelegate(mPresContext);
kidFrame = kidDel->CreateFrame(mPresContext, aKid, mKidIndex, mBlock);
NS_RELEASE(kidDel);

Просмотреть файл

@ -106,7 +106,10 @@ struct nsLineLayout {
// The block behind the line
nsBlockFrame* mBlock;
nsISpaceManager* mSpaceManager;
#if 0
// XXX I don't think we need this anymore...
PRBool mBlockIsPseudo;
#endif
nsIContent* mBlockContent;
PRInt32 mKidIndex;

Просмотреть файл

@ -30,7 +30,7 @@
#ifdef NS_DEBUG
static PRBool gsDebug = PR_FALSE;
#define NOISY_STYLE
//#define NOISY_STYLE
//#define NOISY_FLOW
#else
static const PRBool gsDebug = PR_FALSE;

Просмотреть файл

@ -30,7 +30,7 @@
#ifdef NS_DEBUG
static PRBool gsDebug = PR_FALSE;
#define NOISY_STYLE
//#define NOISY_STYLE
//#define NOISY_FLOW
#else
static const PRBool gsDebug = PR_FALSE;