Added nsIReflowCommand interface

This commit is contained in:
troy 1998-06-09 04:51:44 +00:00
parent eebf3db2c1
commit 66b6882d23
56 changed files with 783 additions and 360 deletions

View File

@ -28,7 +28,7 @@ class nsIFrame;
class nsIPresContext;
class nsIStyleSet;
class nsIViewManager;
class nsReflowCommand;
class nsIReflowCommand;
#define NS_IPRESSHELL_IID \
{ 0x76e79c60, 0x944e, 0x11d1, \
@ -80,7 +80,7 @@ public:
virtual nsIFrame* FindFrameWithContent(nsIContent* aContent) = 0;
virtual void AppendReflowCommand(nsReflowCommand* aReflowCommand) = 0;
virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand) = 0;
virtual void ProcessReflowCommands() = 0;

View File

@ -30,6 +30,7 @@ EXPORTS = \
nsIFrameImageLoader.h \
nsIPresContext.h \
nsIPresShell.h \
nsIReflowCommand.h \
nsIRunaround.h \
nsISelection.h \
nsISpaceManager.h \

View File

@ -28,6 +28,7 @@ EXPORTS = \
nsIFrameImageLoader.h \
nsIPresContext.h \
nsIPresShell.h \
nsIReflowCommand.h \
nsIRunaround.h \
nsISelection.h \
nsISpaceManager.h \

View File

@ -35,7 +35,7 @@ class nsISpaceManager;
class nsIStyleContext;
class nsIView;
class nsIWidget;
class nsReflowCommand;
class nsIReflowCommand;
struct nsPoint;
struct nsRect;
@ -87,7 +87,7 @@ enum nsReflowReason {
*/
struct nsReflowState {
nsReflowReason reason; // the reason for the reflow
nsReflowCommand* reflowCommand; // only used for incremental changes
nsIReflowCommand* reflowCommand; // only used for incremental changes
nsSize maxSize; // the available space in which to reflow
const nsReflowState* parentReflowState; // pointer to parent's reflow state
nsIFrame* frame; // the frame being reflowed
@ -100,9 +100,9 @@ struct nsReflowState {
// Constructs an initial reflow state (no parent reflow state) for an
// incremental reflow command
nsReflowState(nsIFrame* aFrame,
nsReflowCommand& aReflowCommand,
const nsSize& aMaxSize);
nsReflowState(nsIFrame* aFrame,
nsIReflowCommand& aReflowCommand,
const nsSize& aMaxSize);
// Construct a reflow state for the given frame, parent reflow state, and
// max size. Uses the reflow reason and reflow command from the parent's
@ -617,9 +617,9 @@ inline nsReflowState::nsReflowState(nsIFrame* aFrame,
// Constructs an initial reflow state (no parent reflow state) for an
// incremental reflow command
inline nsReflowState::nsReflowState(nsIFrame* aFrame,
nsReflowCommand& aReflowCommand,
const nsSize& aMaxSize)
inline nsReflowState::nsReflowState(nsIFrame* aFrame,
nsIReflowCommand& aReflowCommand,
const nsSize& aMaxSize)
{
#ifdef NS_DEBUG
nsIFrame* parent;

View File

@ -28,7 +28,7 @@ class nsIFrame;
class nsIPresContext;
class nsIStyleSet;
class nsIViewManager;
class nsReflowCommand;
class nsIReflowCommand;
#define NS_IPRESSHELL_IID \
{ 0x76e79c60, 0x944e, 0x11d1, \
@ -80,7 +80,7 @@ public:
virtual nsIFrame* FindFrameWithContent(nsIContent* aContent) = 0;
virtual void AppendReflowCommand(nsReflowCommand* aReflowCommand) = 0;
virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand) = 0;
virtual void ProcessReflowCommands() = 0;

View File

@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIReflowCommand_h___
#define nsIReflowCommand_h___
#include "nsISupports.h"
class nsIFrame;
class nsIPresContext;
struct nsReflowMetrics;
struct nsSize;
// IID for the nsIReflowCommand interface {C3658E40-FF20-11d1-85BC-00A02468FAB6}
#define NS_IREFLOWCOMMAND_IID \
{ 0xc3658e40, 0xff20, 0x11d1, \
{0x85, 0xbc, 0x0, 0xa0, 0x24, 0x68, 0xfa, 0xb6}}
/**
* A reflow command is an object that is generated in response to a content
* model change notification. The reflow command is given to a presentation
* shell where it is queued and then dispatched by invoking the reflow
* commands's Dispatch() member function.
*
* Reflow command processing follows a path from the root frame down to the
* target frame (the frame for which the reflow command is destined). Reflow
* commands are processed by invoking the frame's Reflow() member function.
*
* @see nsIFrame#ContentAppended()
* @see nsIFrame#ContentChanged()
* @see nsIFrame#ContentDeleted()
* @see nsIFrame#ContentInserted()
* @see nsIFrame#ContentReplaced()
* @see nsIPresShell#AppendReflowCommand()
* @see nsIPresShell#ProcessReflowCommands()
*/
class nsIReflowCommand : public nsISupports {
public:
enum ReflowType {
// Reflow commands generated in response to a content insert/delete/append
// 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.). 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,
// these commands are used to get the next-in-flow to update
// itself.
PullupReflow,
PushReflow,
// This command is used to see if a prev-in-flow wants to pullup
// some children from a next-in-flow that has changed because of
// an incremental reflow.
CheckPullupReflow,
// Trap door for extensions
UserDefined
};
/**
* Dispatch the reflow command.
*
* Builds a path from the target frame back to the root frame, and then
* invokes the root frame's Reflow() member function.
*
* @see nsIFrame#Reflow()
*/
NS_IMETHOD Dispatch(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsSize& aMaxSize) = 0;
/**
* Get the next frame in the command processing path. Note that this removes
* the frame from the path so you must only call it once.
*/
NS_IMETHOD GetNext(nsIFrame*& aNextFrame) = 0;
/**
* Get the target of the reflow command.
*/
NS_IMETHOD GetTarget(nsIFrame*& aTargetFrame) const = 0;
/**
* Get the type of reflow command.
*/
NS_IMETHOD GetType(ReflowType& aReflowType) const = 0;
/**
* Get the child frame associated with the reflow command.
*/
NS_IMETHOD GetChildFrame(nsIFrame*& aChildFrame) const = 0;
};
#endif /* nsIReflowCommand_h___ */

View File

@ -30,7 +30,6 @@ CPPSRCS = \
nsPresContext.cpp \
nsPresShell.cpp \
nsPrintPreviewContext.cpp \
nsReflowCommand.cpp \
nsSelection.cpp \
nsSelectionPoint.cpp \
nsSelectionRange.cpp \

View File

@ -29,7 +29,6 @@ CPPSRCS = \
nsPresContext.cpp \
nsPresShell.cpp \
nsPrintPreviewContext.cpp \
nsReflowCommand.cpp \
nsSelection.cpp \
nsSelectionPoint.cpp \
nsSelectionRange.cpp \
@ -53,7 +52,6 @@ CPP_OBJS= \
.\$(OBJDIR)\nsPresContext.obj \
.\$(OBJDIR)\nsPresShell.obj \
.\$(OBJDIR)\nsPrintPreviewContext.obj \
.\$(OBJDIR)\nsReflowCommand.obj \
.\$(OBJDIR)\nsSelection.obj \
.\$(OBJDIR)\nsSelectionPoint.obj \
.\$(OBJDIR)\nsSelectionRange.obj \

View File

@ -26,7 +26,6 @@
#include "nsCRT.h"
#include "nsGUIEvent.h"
#include "nsStyleConsts.h"
#include "nsReflowCommand.h"
#include "nsIPresShell.h"
#include "prlog.h"
#include "prprf.h"
@ -1118,10 +1117,6 @@ NS_METHOD nsFrame::ContentChanged(nsIPresShell* aShell,
nsIContent* aChild,
nsISupports* aSubContent)
{
// 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;
}

View File

@ -24,11 +24,12 @@
#include "nsIStyleSet.h"
#include "nsIStyleContext.h"
#include "nsFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIViewManager.h"
#include "nsCRT.h"
#include "plhash.h"
#include "prlog.h"
#include "nsVoidArray.h"
#undef NOISY
@ -187,7 +188,7 @@ public:
virtual void ResizeReflow(nscoord aWidth, nscoord aHeight);
virtual nsIFrame* GetRootFrame();
virtual nsIFrame* FindFrameWithContent(nsIContent* aContent);
virtual void AppendReflowCommand(nsReflowCommand* aReflowCommand);
virtual void AppendReflowCommand(nsIReflowCommand* aReflowCommand);
virtual void ProcessReflowCommands();
virtual void PutCachedData(nsIFrame* aKeyFrame, void* aData);
virtual void* GetCachedData(nsIFrame* aKeyFrame);
@ -514,9 +515,10 @@ PresShell::EndReflow(nsIPresShell* aShell)
}
void
PresShell::AppendReflowCommand(nsReflowCommand* aReflowCommand)
PresShell::AppendReflowCommand(nsIReflowCommand* aReflowCommand)
{
mReflowCommands.AppendElement(aReflowCommand);
NS_ADDREF(aReflowCommand);
}
void
@ -526,18 +528,22 @@ PresShell::ProcessReflowCommands()
nsReflowMetrics desiredSize(nsnull);
while (0 != mReflowCommands.Count()) {
nsReflowCommand* rc = (nsReflowCommand*) mReflowCommands.ElementAt(0);
nsIReflowCommand* rc = (nsIReflowCommand*) mReflowCommands.ElementAt(0);
mReflowCommands.RemoveElementAt(0);
// Dispatch the reflow command
nsSize maxSize;
mRootFrame->GetSize(maxSize);
#ifdef NS_DEBUG
nsIReflowCommand::ReflowType type;
rc->GetType(type);
PR_LOG(gShellLogModuleInfo, PR_LOG_DEBUG,
("PresShell::ProcessReflowCommands: reflow command type=%d",
rc->GetType()));
rc->Dispatch(desiredSize, maxSize);
delete rc;
("PresShell::ProcessReflowCommands: reflow command type=%d", type));
#endif
rc->Dispatch(*mPresContext, desiredSize, maxSize);
NS_RELEASE(rc);
}
// Place and size the root frame

View File

@ -1,94 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsReflowCommand.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIContent.h"
#include "nsIRunaround.h"
static NS_DEFINE_IID(kIRunaroundIID, NS_IRUNAROUND_IID);
// Construct a reflow command given a presentation context, target frame,
// and a reflow command type
nsReflowCommand::nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType)
: mType(aReflowType), mTargetFrame(aTargetFrame), mPresContext(aPresContext),
mChildFrame(nsnull)
{
NS_PRECONDITION(mTargetFrame != nsnull, "null target frame");
aPresContext->AddRef();
}
nsReflowCommand::nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIFrame* aChildFrame)
: mType(aReflowType), mTargetFrame(aTargetFrame), mPresContext(aPresContext),
mChildFrame(aChildFrame)
{
NS_PRECONDITION(mTargetFrame != nsnull, "null target frame");
NS_PRECONDITION(mChildFrame != nsnull, "null child frame");
NS_ADDREF(aPresContext);
}
nsReflowCommand::~nsReflowCommand()
{
NS_IF_RELEASE(mPresContext);
}
void nsReflowCommand::Dispatch(nsReflowMetrics& aDesiredSize,
const nsSize& aMaxSize)
{
// Build the path from the target frame (index 0) to the root frame
mPath.Clear();
for (nsIFrame* f = (nsIFrame*)mTargetFrame; nsnull != f;
f->GetGeometricParent(f)) {
mPath.AppendElement((void*)f);
}
// Send an incremental reflow notification to the root frame
nsIFrame* root = (nsIFrame*)mPath[mPath.Count() - 1];
#ifdef NS_DEBUG
nsIPresShell* shell = mPresContext->GetShell();
if (nsnull != shell) {
NS_ASSERTION(shell->GetRootFrame() == root, "bad root frame");
NS_RELEASE(shell);
}
#endif
if (nsnull != root) {
mPath.RemoveElementAt(mPath.Count() - 1);
nsReflowState reflowState(root, *this, aMaxSize);
nsReflowStatus status;
root->Reflow(mPresContext, aDesiredSize, reflowState, status);
}
}
nsIFrame* nsReflowCommand::GetNext()
{
PRInt32 count = mPath.Count();
nsIFrame* rv = nsnull;
if (count > 0) {
rv = (nsIFrame*) mPath[count - 1];
mPath.RemoveElementAt(count - 1);
}
return rv;
}

View File

@ -1,109 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsReflowCommand_h___
#define nsReflowCommand_h___
#include "nsIFrame.h"
#include "nsVoidArray.h"
class nsIPresContext;
class nsISpaceManager;
// A reflow command.
class nsReflowCommand {
public:
enum ReflowType {
// Reflow commands generated in response to a content insert/delete/append
// 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.). 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,
// these commands are used to get the next-in-flow to update
// itself.
PullupReflow,
PushReflow,
// This command is used to see if a prev-in-flow wants to pullup
// some children from a next-in-flow that has changed because of
// an incremental reflow.
CheckPullupReflow,
// Trap door for extensions
UserDefined
};
// XXX factory methods?
nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType);
nsReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIFrame* aChildFrame);
virtual ~nsReflowCommand();
/**
* Dispatch the reflow command.
*
* Builds a path from the target frame back to the root frame, and then invokes
* the root frame's Reflow() member function.
*/
void Dispatch(nsReflowMetrics& aDesiredSize, const nsSize& aMaxSize);
/**
* Get the next frame in the command chain. Note that this removes the frame
* from the target chain
*/
nsIFrame* GetNext();
/**
* Get the target of the reflow command
*/
nsIFrame* GetTarget() const {return mTargetFrame;}
/**
* Get the type of reflow command
*/
ReflowType GetType() const {return mType;}
/**
* Get the child frame associated with the reflow command
*/
nsIFrame* GetChildFrame() const {return mChildFrame;}
private:
nsIPresContext* mPresContext;
ReflowType mType;
nsIFrame* mTargetFrame;
nsIFrame* mChildFrame;
nsVoidArray mPath;
};
#endif /* nsReflowCommand_h___ */

View File

@ -22,12 +22,12 @@
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIAnchoredItems.h"
#include "nsIReflowCommand.h"
#include "nsPlaceholderFrame.h"
#include "nsIPtr.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
#include "nsCSSLayout.h"
#include "nsIView.h"
@ -1446,8 +1446,13 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowState.reflowCommand->GetTarget()) {
if (nsReflowCommand::FrameAppended == aReflowState.reflowCommand->GetType()) {
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
if (this == target) {
nsIReflowCommand::ReflowType type;
aReflowState.reflowCommand->GetType(type);
if (nsIReflowCommand::FrameAppended == type) {
nsLineData* lastLine = LastLine();
// Restore the state
@ -1473,7 +1478,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
} else {
// The command is passing through us. Get the next frame in the
// reflow chain
nsIFrame* nextFrame = aReflowState.reflowCommand->GetNext();
nsIFrame* nextFrame;
aReflowState.reflowCommand->GetNext(nextFrame);
// Restore our state as if nextFrame is the next frame to reflow
nsLineData* line = FindLine(nextFrame);

View File

@ -22,12 +22,12 @@
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIAnchoredItems.h"
#include "nsIReflowCommand.h"
#include "nsPlaceholderFrame.h"
#include "nsIPtr.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
#include "nsCSSLayout.h"
#include "nsIView.h"
@ -1446,8 +1446,13 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowState.reflowCommand->GetTarget()) {
if (nsReflowCommand::FrameAppended == aReflowState.reflowCommand->GetType()) {
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
if (this == target) {
nsIReflowCommand::ReflowType type;
aReflowState.reflowCommand->GetType(type);
if (nsIReflowCommand::FrameAppended == type) {
nsLineData* lastLine = LastLine();
// Restore the state
@ -1473,7 +1478,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
} else {
// The command is passing through us. Get the next frame in the
// reflow chain
nsIFrame* nextFrame = aReflowState.reflowCommand->GetNext();
nsIFrame* nextFrame;
aReflowState.reflowCommand->GetNext(nextFrame);
// Restore our state as if nextFrame is the next frame to reflow
nsLineData* line = FindLine(nextFrame);

View File

@ -22,12 +22,12 @@
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIAnchoredItems.h"
#include "nsIReflowCommand.h"
#include "nsPlaceholderFrame.h"
#include "nsIPtr.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
#include "nsCSSLayout.h"
#include "nsIView.h"
@ -1446,8 +1446,13 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowState.reflowCommand->GetTarget()) {
if (nsReflowCommand::FrameAppended == aReflowState.reflowCommand->GetType()) {
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
if (this == target) {
nsIReflowCommand::ReflowType type;
aReflowState.reflowCommand->GetType(type);
if (nsIReflowCommand::FrameAppended == type) {
nsLineData* lastLine = LastLine();
// Restore the state
@ -1473,7 +1478,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
} else {
// The command is passing through us. Get the next frame in the
// reflow chain
nsIFrame* nextFrame = aReflowState.reflowCommand->GetNext();
nsIFrame* nextFrame;
aReflowState.reflowCommand->GetNext(nextFrame);
// Restore our state as if nextFrame is the next frame to reflow
nsLineData* line = FindLine(nextFrame);

View File

@ -30,7 +30,6 @@
#include "nsGUIEvent.h"
#include "nsIDocument.h"
#include "nsIURL.h"
#include "nsReflowCommand.h"
#include "nsIPtr.h"
#include "nsAbsoluteFrame.h"
#include "nsPlaceholderFrame.h"
@ -40,6 +39,7 @@
#include "nsHTMLFrame.h"
#include "nsScrollFrame.h"
#include "nsIView.h"
#include "nsIReflowCommand.h"
NS_DEF_PTR(nsIStyleContext);
@ -144,9 +144,15 @@ NS_METHOD nsHTMLContainerFrame::ContentAppended(nsIPresShell* aShell,
nsHTMLContainerFrame* lastInFlow = (nsHTMLContainerFrame*)GetLastInFlow();
// Generate a reflow command for the frame
nsReflowCommand* cmd = new nsReflowCommand(aPresContext, lastInFlow,
nsReflowCommand::FrameAppended);
aShell->AppendReflowCommand(cmd);
nsIReflowCommand* cmd;
nsresult result;
result = NS_NewHTMLReflowCommand(&cmd, lastInFlow, nsIReflowCommand::FrameAppended);
if (NS_OK == result) {
aShell->AppendReflowCommand(cmd);
NS_RELEASE(cmd);
}
return NS_OK;
}
@ -348,12 +354,16 @@ NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell,
parent->mChildCount++;
// Generate a reflow command
nsReflowCommand* cmd = new nsReflowCommand(aPresContext, parent,
nsReflowCommand::FrameAppended,
newFrame);
aShell->AppendReflowCommand(cmd);
nsIReflowCommand* cmd;
rv = NS_NewHTMLReflowCommand(&cmd, parent, nsIReflowCommand::FrameAppended,
newFrame);
if (NS_OK == rv) {
aShell->AppendReflowCommand(cmd);
NS_RELEASE(cmd);
}
return NS_OK;
return rv;
}
nsresult

View File

@ -20,6 +20,7 @@
#include "nscore.h"
#include "nsISupports.h"
#include "nsIReflowCommand.h"
class nsIArena;
class nsIAtom;
class nsIContent;
@ -137,4 +138,11 @@ extern nsresult
NS_NewHTMLImage(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag);
/** Create a new HTML reflow command */
extern nsresult
NS_NewHTMLReflowCommand(nsIReflowCommand** aInstancePtrResult,
nsIFrame* aTargetFrame,
nsIReflowCommand::ReflowType aReflowType,
nsIFrame* aChildFrame = nsnull);
#endif /* nsHTMLParts_h___ */

View File

@ -0,0 +1,124 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsHTMLReflowCommand.h"
#include "nsIFrame.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIContent.h"
static NS_DEFINE_IID(kIReflowCommandIID, NS_IREFLOWCOMMAND_IID);
nsresult
NS_NewHTMLReflowCommand(nsIReflowCommand** aInstancePtrResult,
nsIFrame* aTargetFrame,
nsIReflowCommand::ReflowType aReflowType,
nsIFrame* aChildFrame)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsHTMLReflowCommand* cmd = new nsHTMLReflowCommand(aTargetFrame, aReflowType, aChildFrame);
if (nsnull == cmd) {
return NS_ERROR_OUT_OF_MEMORY;
}
return cmd->QueryInterface(kIReflowCommandIID, (void**)aInstancePtrResult);
}
// Construct a reflow command given a target frame, reflow command type,
// and optional child frame
nsHTMLReflowCommand::nsHTMLReflowCommand(nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIFrame* aChildFrame)
: mType(aReflowType), mTargetFrame(aTargetFrame), mChildFrame(aChildFrame)
{
NS_PRECONDITION(mTargetFrame != nsnull, "null target frame");
NS_INIT_REFCNT();
}
nsHTMLReflowCommand::~nsHTMLReflowCommand()
{
}
NS_IMPL_ISUPPORTS(nsHTMLReflowCommand, kIReflowCommandIID);
NS_METHOD nsHTMLReflowCommand::Dispatch(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsSize& aMaxSize)
{
// Build the path from the target frame (index 0) to the root frame
mPath.Clear();
for (nsIFrame* f = (nsIFrame*)mTargetFrame; nsnull != f;
f->GetGeometricParent(f)) {
mPath.AppendElement((void*)f);
}
// Send an incremental reflow notification to the root frame
nsIFrame* root = (nsIFrame*)mPath[mPath.Count() - 1];
#ifdef NS_DEBUG
nsIPresShell* shell = aPresContext.GetShell();
if (nsnull != shell) {
NS_ASSERTION(shell->GetRootFrame() == root, "bad root frame");
NS_RELEASE(shell);
}
#endif
if (nsnull != root) {
mPath.RemoveElementAt(mPath.Count() - 1);
nsReflowState reflowState(root, *this, aMaxSize);
nsReflowStatus status;
root->Reflow(&aPresContext, aDesiredSize, reflowState, status);
}
return NS_OK;
}
NS_METHOD nsHTMLReflowCommand::GetNext(nsIFrame*& aNextFrame)
{
PRInt32 count = mPath.Count();
aNextFrame = nsnull;
if (count > 0) {
aNextFrame = (nsIFrame*)mPath[count - 1];
mPath.RemoveElementAt(count - 1);
}
return NS_OK;
}
NS_METHOD nsHTMLReflowCommand::GetTarget(nsIFrame*& aTargetFrame) const
{
aTargetFrame = mTargetFrame;
return NS_OK;
}
NS_METHOD nsHTMLReflowCommand::GetType(ReflowType& aReflowType) const
{
aReflowType = mType;
return NS_OK;
}
NS_METHOD nsHTMLReflowCommand::GetChildFrame(nsIFrame*& aChildFrame) const
{
aChildFrame = mChildFrame;
return NS_OK;
}

View File

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsHTMLReflowCommand_h___
#define nsHTMLReflowCommand_h___
#include "nsIReflowCommand.h"
#include "nsVoidArray.h"
/**
* An HTML reflow command
*/
class nsHTMLReflowCommand : public nsIReflowCommand {
public:
/**
* Construct an HTML reflow command of type aReflowType and with target
* frame aTargetFrame. You can also specify an optional child frame, e.g.
* to indicate the inserted child frame
*/
nsHTMLReflowCommand(nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIFrame* aChildFrame = nsnull);
virtual ~nsHTMLReflowCommand();
// nsISupports
NS_DECL_ISUPPORTS
// nsIReflowCommand
NS_IMETHOD Dispatch(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsSize& aMaxSize);
NS_IMETHOD GetNext(nsIFrame*& aNextFrame);
NS_IMETHOD GetTarget(nsIFrame*& aTargetFrame) const;
NS_IMETHOD GetType(ReflowType& aReflowType) const;
NS_IMETHOD GetChildFrame(nsIFrame*& aChildFrame) const;
private:
ReflowType mType;
nsIFrame* mTargetFrame;
nsIFrame* mChildFrame;
nsVoidArray mPath;
};
#endif /* nsHTMLReflowCommand_h___ */

View File

@ -35,7 +35,7 @@ class nsISpaceManager;
class nsIStyleContext;
class nsIView;
class nsIWidget;
class nsReflowCommand;
class nsIReflowCommand;
struct nsPoint;
struct nsRect;
@ -87,7 +87,7 @@ enum nsReflowReason {
*/
struct nsReflowState {
nsReflowReason reason; // the reason for the reflow
nsReflowCommand* reflowCommand; // only used for incremental changes
nsIReflowCommand* reflowCommand; // only used for incremental changes
nsSize maxSize; // the available space in which to reflow
const nsReflowState* parentReflowState; // pointer to parent's reflow state
nsIFrame* frame; // the frame being reflowed
@ -100,9 +100,9 @@ struct nsReflowState {
// Constructs an initial reflow state (no parent reflow state) for an
// incremental reflow command
nsReflowState(nsIFrame* aFrame,
nsReflowCommand& aReflowCommand,
const nsSize& aMaxSize);
nsReflowState(nsIFrame* aFrame,
nsIReflowCommand& aReflowCommand,
const nsSize& aMaxSize);
// Construct a reflow state for the given frame, parent reflow state, and
// max size. Uses the reflow reason and reflow command from the parent's
@ -617,9 +617,9 @@ inline nsReflowState::nsReflowState(nsIFrame* aFrame,
// Constructs an initial reflow state (no parent reflow state) for an
// incremental reflow command
inline nsReflowState::nsReflowState(nsIFrame* aFrame,
nsReflowCommand& aReflowCommand,
const nsSize& aMaxSize)
inline nsReflowState::nsReflowState(nsIFrame* aFrame,
nsIReflowCommand& aReflowCommand,
const nsSize& aMaxSize)
{
#ifdef NS_DEBUG
nsIFrame* parent;

View File

@ -26,7 +26,7 @@
#include "nsIPresShell.h"
#include "nsCSSLayout.h"
#include "nsPlaceholderFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsHTMLAtoms.h"
#include "nsAbsoluteFrame.h"
#include "nsLeafFrame.h"
@ -896,9 +896,15 @@ NS_METHOD nsInlineFrame::Reflow(nsIPresContext* aPresContext,
if (eReflowReason_Incremental == aReflowState.reason) {
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command");
if (aReflowState.reflowCommand->GetTarget() == this) {
switch (aReflowState.reflowCommand->GetType()) {
case nsReflowCommand::FrameAppended:
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
if (target == this) {
nsIReflowCommand::ReflowType type;
aReflowState.reflowCommand->GetType(type);
switch (type) {
case nsIReflowCommand::FrameAppended:
// Recover our state
RecoverState(aPresContext, state, nsnull);
aStatus = ReflowUnmappedChildren(aPresContext, state);
@ -911,7 +917,9 @@ NS_METHOD nsInlineFrame::Reflow(nsIPresContext* aPresContext,
} else {
// The command is passing through us. Get the next frame in the reflow chain
nsIFrame* kidFrame = aReflowState.reflowCommand->GetNext();
nsIFrame* kidFrame;
aReflowState.reflowCommand->GetNext(kidFrame);
nsReflowMetrics kidSize(aDesiredSize.maxElementSize);
nsReflowState kidReflowState(kidFrame, aReflowState, state.availSize);

View File

@ -18,6 +18,8 @@
#include "nsLeafFrame.h"
#include "nsIStyleContext.h"
#include "nsCSSRendering.h"
#include "nsHTMLParts.h"
#include "nsIPresShell.h"
nsLeafFrame::nsLeafFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsFrame(aContent, aParentFrame)
@ -98,11 +100,21 @@ void nsLeafFrame::GetInnerArea(nsIPresContext* aPresContext,
(borderPadding.top + borderPadding.bottom);
}
NS_METHOD nsLeafFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
nsIFrame* aParent,
nsIFrame*& aContinuingFrame)
NS_METHOD nsLeafFrame::ContentChanged(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aChild,
nsISupports* aSubContent)
{
NS_NOTREACHED("Attempt to split the unsplittable");
aContinuingFrame = nsnull;
return NS_OK;
// Generate a reflow command with this frame as the target frame
nsIReflowCommand* cmd;
nsresult result;
result = NS_NewHTMLReflowCommand(&cmd, this, nsIReflowCommand::ContentChanged);
if (NS_OK == result) {
aShell->AppendReflowCommand(cmd);
NS_RELEASE(cmd);
}
return result;
}

View File

@ -37,9 +37,10 @@ public:
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD CreateContinuingFrame(nsIPresContext* aPresContext,
nsIFrame* aParent,
nsIFrame*& aContinuingFrame);
NS_IMETHOD ContentChanged(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aChild,
nsISupports* aSubContent);
protected:
nsLeafFrame(nsIContent* aContent, nsIFrame* aParentFrame);

View File

@ -28,7 +28,7 @@
#include "nsPlaceholderFrame.h"
#include "nsCSSLayout.h"
#include "nsCRT.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIFontMetrics.h"
#include "nsHTMLFrame.h"
#include "nsScrollFrame.h"
@ -595,7 +595,7 @@ nsLineLayout::ReflowMappedChild()
// Return values: <0 for error
// 0 == NS_LINE_LAYOUT
nsresult
nsLineLayout::ReflowChild(nsReflowCommand* aReflowCommand,
nsLineLayout::ReflowChild(nsIReflowCommand* aReflowCommand,
PRBool aNewChild)
{
nsIFrame* kidFrame = mState.mKidFrame;
@ -1016,8 +1016,8 @@ nsLineLayout::PlaceChild(nsRect& kidRect,
}
nsresult
nsLineLayout::IncrementalReflowFromChild(nsReflowCommand* aReflowCommand,
nsIFrame* aChildFrame)
nsLineLayout::IncrementalReflowFromChild(nsIReflowCommand* aReflowCommand,
nsIFrame* aChildFrame)
{
nsresult reflowStatus = NS_LINE_LAYOUT_COMPLETE;

View File

@ -100,8 +100,8 @@ struct nsLineLayout {
nsresult ReflowLine();
nsresult IncrementalReflowFromChild(nsReflowCommand* aReflowCommand,
nsIFrame* aChildFrame);
nsresult IncrementalReflowFromChild(nsIReflowCommand* aReflowCommand,
nsIFrame* aChildFrame);
void AtSpace();
@ -183,7 +183,7 @@ protected:
nsresult ReflowMappedChild();
nsresult ReflowChild(nsReflowCommand* aReflowCommand, PRBool aNewChild);
nsresult ReflowChild(nsIReflowCommand* aReflowCommand, PRBool aNewChild);
nsresult PlaceChild(nsRect& kidRect,
const nsReflowMetrics& kidMetrics,

View File

@ -20,7 +20,7 @@
#include "nsIContentDelegate.h"
#include "nsIPresContext.h"
#include "nsIStyleContext.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIRenderingContext.h"
nsPageFrame::nsPageFrame(nsIContent* aContent, nsIFrame* aParent)
@ -67,12 +67,17 @@ NS_METHOD nsPageFrame::Reflow(nsIPresContext* aPresContext,
// XXX Do something sensible in page mode...
if (eReflowReason_Incremental == aReflowState.reason) {
// We don't expect the target of the reflow command to be page frame
#ifdef NS_DEUG
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command");
NS_ASSERTION(aReflowState.reflowCommand->GetTarget() != this,
"page frame is reflow command target");
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
NS_ASSERTION(target != this, "page frame is reflow command target");
#endif
// Verify the next reflow command frame is our one and only child frame
nsIFrame* next = aReflowState.reflowCommand->GetNext();
nsIFrame* next;
aReflowState.reflowCommand->GetNext(next);
NS_ASSERTION(next == mFirstChild, "bad reflow frame");
// Dispatch the reflow command to our content child. Allow it to be as high

View File

@ -37,6 +37,7 @@ CPPSRCS = \
nsHTMLHead.cpp \
nsHTMLIIDs.cpp \
nsHTMLImage.cpp \
nsHTMLReflowCommand.cpp \
nsHTMLTagContent.cpp \
nsHTMLTags.cpp \
nsImageMap.cpp \

View File

@ -39,6 +39,7 @@ CPPSRCS= \
nsHTMLHead.cpp \
nsHTMLIIDs.cpp \
nsHTMLImage.cpp \
nsHTMLReflowCommand.cpp \
nsHTMLTagContent.cpp \
nsImageMap.cpp \
nsInlineFrame.cpp \
@ -72,6 +73,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsHTMLHead.obj \
.\$(OBJDIR)\nsHTMLIIDs.obj \
.\$(OBJDIR)\nsHTMLImage.obj \
.\$(OBJDIR)\nsHTMLReflowCommand.obj \
.\$(OBJDIR)\nsHTMLTagContent.obj \
.\$(OBJDIR)\nsHTMLTags.obj \
.\$(OBJDIR)\nsImageMap.obj \

View File

@ -22,12 +22,12 @@
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIAnchoredItems.h"
#include "nsIReflowCommand.h"
#include "nsPlaceholderFrame.h"
#include "nsIPtr.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
#include "nsCSSLayout.h"
#include "nsIView.h"
@ -1446,8 +1446,13 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowState.reflowCommand->GetTarget()) {
if (nsReflowCommand::FrameAppended == aReflowState.reflowCommand->GetType()) {
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
if (this == target) {
nsIReflowCommand::ReflowType type;
aReflowState.reflowCommand->GetType(type);
if (nsIReflowCommand::FrameAppended == type) {
nsLineData* lastLine = LastLine();
// Restore the state
@ -1473,7 +1478,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
} else {
// The command is passing through us. Get the next frame in the
// reflow chain
nsIFrame* nextFrame = aReflowState.reflowCommand->GetNext();
nsIFrame* nextFrame;
aReflowState.reflowCommand->GetNext(nextFrame);
// Restore our state as if nextFrame is the next frame to reflow
nsLineData* line = FindLine(nextFrame);

View File

@ -22,12 +22,12 @@
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIAnchoredItems.h"
#include "nsIReflowCommand.h"
#include "nsPlaceholderFrame.h"
#include "nsIPtr.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
#include "nsCSSLayout.h"
#include "nsIView.h"
@ -1446,8 +1446,13 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowState.reflowCommand->GetTarget()) {
if (nsReflowCommand::FrameAppended == aReflowState.reflowCommand->GetType()) {
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
if (this == target) {
nsIReflowCommand::ReflowType type;
aReflowState.reflowCommand->GetType(type);
if (nsIReflowCommand::FrameAppended == type) {
nsLineData* lastLine = LastLine();
// Restore the state
@ -1473,7 +1478,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
} else {
// The command is passing through us. Get the next frame in the
// reflow chain
nsIFrame* nextFrame = aReflowState.reflowCommand->GetNext();
nsIFrame* nextFrame;
aReflowState.reflowCommand->GetNext(nextFrame);
// Restore our state as if nextFrame is the next frame to reflow
nsLineData* line = FindLine(nextFrame);

View File

@ -22,12 +22,12 @@
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIAnchoredItems.h"
#include "nsIReflowCommand.h"
#include "nsPlaceholderFrame.h"
#include "nsIPtr.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLValue.h"
#include "nsReflowCommand.h"
#include "nsCSSLayout.h"
#include "nsIView.h"
@ -1446,8 +1446,13 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
shell->PutCachedData(this, &state);
// Is the reflow command target at us?
if (this == aReflowState.reflowCommand->GetTarget()) {
if (nsReflowCommand::FrameAppended == aReflowState.reflowCommand->GetType()) {
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
if (this == target) {
nsIReflowCommand::ReflowType type;
aReflowState.reflowCommand->GetType(type);
if (nsIReflowCommand::FrameAppended == type) {
nsLineData* lastLine = LastLine();
// Restore the state
@ -1473,7 +1478,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
} else {
// The command is passing through us. Get the next frame in the
// reflow chain
nsIFrame* nextFrame = aReflowState.reflowCommand->GetNext();
nsIFrame* nextFrame;
aReflowState.reflowCommand->GetNext(nextFrame);
// Restore our state as if nextFrame is the next frame to reflow
nsLineData* line = FindLine(nextFrame);

View File

@ -19,7 +19,7 @@
#include "nsIContent.h"
#include "nsIContentDelegate.h"
#include "nsBlockFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
@ -164,9 +164,12 @@ NS_METHOD nsBodyFrame::Reflow(nsIPresContext* aPresContext,
if (eReflowReason_Incremental == aReflowState.reason) {
// The reflow command should never be target for us
#ifdef NS_DEBUG
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command");
NS_ASSERTION(aReflowState.reflowCommand->GetTarget() != this,
"bad reflow command target");
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
NS_ASSERTION(target != this, "bad reflow command target");
#endif
// Is the next frame in the reflow chain the pseudo block-frame or a
// floating frame?
@ -176,7 +179,8 @@ NS_METHOD nsBodyFrame::Reflow(nsIPresContext* aPresContext,
// is that the placeholder frame was changed to return the floating frame
// as a child frame. That's wrong, because the floating frame now appears
// to be both a geometric child of the body and of the placeholder. Yuck...
nsIFrame* next = aReflowState.reflowCommand->GetNext();
nsIFrame* next;
aReflowState.reflowCommand->GetNext(next);
if (mFirstChild != next) {
// It's a floating frame that's the target. Reflow the body making it
// look like a resize occured. This will reflow the placeholder which will

View File

@ -30,7 +30,6 @@
#include "nsGUIEvent.h"
#include "nsIDocument.h"
#include "nsIURL.h"
#include "nsReflowCommand.h"
#include "nsIPtr.h"
#include "nsAbsoluteFrame.h"
#include "nsPlaceholderFrame.h"
@ -40,6 +39,7 @@
#include "nsHTMLFrame.h"
#include "nsScrollFrame.h"
#include "nsIView.h"
#include "nsIReflowCommand.h"
NS_DEF_PTR(nsIStyleContext);
@ -144,9 +144,15 @@ NS_METHOD nsHTMLContainerFrame::ContentAppended(nsIPresShell* aShell,
nsHTMLContainerFrame* lastInFlow = (nsHTMLContainerFrame*)GetLastInFlow();
// Generate a reflow command for the frame
nsReflowCommand* cmd = new nsReflowCommand(aPresContext, lastInFlow,
nsReflowCommand::FrameAppended);
aShell->AppendReflowCommand(cmd);
nsIReflowCommand* cmd;
nsresult result;
result = NS_NewHTMLReflowCommand(&cmd, lastInFlow, nsIReflowCommand::FrameAppended);
if (NS_OK == result) {
aShell->AppendReflowCommand(cmd);
NS_RELEASE(cmd);
}
return NS_OK;
}
@ -348,12 +354,16 @@ NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell,
parent->mChildCount++;
// Generate a reflow command
nsReflowCommand* cmd = new nsReflowCommand(aPresContext, parent,
nsReflowCommand::FrameAppended,
newFrame);
aShell->AppendReflowCommand(cmd);
nsIReflowCommand* cmd;
rv = NS_NewHTMLReflowCommand(&cmd, parent, nsIReflowCommand::FrameAppended,
newFrame);
if (NS_OK == rv) {
aShell->AppendReflowCommand(cmd);
NS_RELEASE(cmd);
}
return NS_OK;
return rv;
}
nsresult

View File

@ -20,6 +20,7 @@
#include "nscore.h"
#include "nsISupports.h"
#include "nsIReflowCommand.h"
class nsIArena;
class nsIAtom;
class nsIContent;
@ -137,4 +138,11 @@ extern nsresult
NS_NewHTMLImage(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag);
/** Create a new HTML reflow command */
extern nsresult
NS_NewHTMLReflowCommand(nsIReflowCommand** aInstancePtrResult,
nsIFrame* aTargetFrame,
nsIReflowCommand::ReflowType aReflowType,
nsIFrame* aChildFrame = nsnull);
#endif /* nsHTMLParts_h___ */

View File

@ -0,0 +1,124 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsHTMLReflowCommand.h"
#include "nsIFrame.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIContent.h"
static NS_DEFINE_IID(kIReflowCommandIID, NS_IREFLOWCOMMAND_IID);
nsresult
NS_NewHTMLReflowCommand(nsIReflowCommand** aInstancePtrResult,
nsIFrame* aTargetFrame,
nsIReflowCommand::ReflowType aReflowType,
nsIFrame* aChildFrame)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsHTMLReflowCommand* cmd = new nsHTMLReflowCommand(aTargetFrame, aReflowType, aChildFrame);
if (nsnull == cmd) {
return NS_ERROR_OUT_OF_MEMORY;
}
return cmd->QueryInterface(kIReflowCommandIID, (void**)aInstancePtrResult);
}
// Construct a reflow command given a target frame, reflow command type,
// and optional child frame
nsHTMLReflowCommand::nsHTMLReflowCommand(nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIFrame* aChildFrame)
: mType(aReflowType), mTargetFrame(aTargetFrame), mChildFrame(aChildFrame)
{
NS_PRECONDITION(mTargetFrame != nsnull, "null target frame");
NS_INIT_REFCNT();
}
nsHTMLReflowCommand::~nsHTMLReflowCommand()
{
}
NS_IMPL_ISUPPORTS(nsHTMLReflowCommand, kIReflowCommandIID);
NS_METHOD nsHTMLReflowCommand::Dispatch(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsSize& aMaxSize)
{
// Build the path from the target frame (index 0) to the root frame
mPath.Clear();
for (nsIFrame* f = (nsIFrame*)mTargetFrame; nsnull != f;
f->GetGeometricParent(f)) {
mPath.AppendElement((void*)f);
}
// Send an incremental reflow notification to the root frame
nsIFrame* root = (nsIFrame*)mPath[mPath.Count() - 1];
#ifdef NS_DEBUG
nsIPresShell* shell = aPresContext.GetShell();
if (nsnull != shell) {
NS_ASSERTION(shell->GetRootFrame() == root, "bad root frame");
NS_RELEASE(shell);
}
#endif
if (nsnull != root) {
mPath.RemoveElementAt(mPath.Count() - 1);
nsReflowState reflowState(root, *this, aMaxSize);
nsReflowStatus status;
root->Reflow(&aPresContext, aDesiredSize, reflowState, status);
}
return NS_OK;
}
NS_METHOD nsHTMLReflowCommand::GetNext(nsIFrame*& aNextFrame)
{
PRInt32 count = mPath.Count();
aNextFrame = nsnull;
if (count > 0) {
aNextFrame = (nsIFrame*)mPath[count - 1];
mPath.RemoveElementAt(count - 1);
}
return NS_OK;
}
NS_METHOD nsHTMLReflowCommand::GetTarget(nsIFrame*& aTargetFrame) const
{
aTargetFrame = mTargetFrame;
return NS_OK;
}
NS_METHOD nsHTMLReflowCommand::GetType(ReflowType& aReflowType) const
{
aReflowType = mType;
return NS_OK;
}
NS_METHOD nsHTMLReflowCommand::GetChildFrame(nsIFrame*& aChildFrame) const
{
aChildFrame = mChildFrame;
return NS_OK;
}

View File

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsHTMLReflowCommand_h___
#define nsHTMLReflowCommand_h___
#include "nsIReflowCommand.h"
#include "nsVoidArray.h"
/**
* An HTML reflow command
*/
class nsHTMLReflowCommand : public nsIReflowCommand {
public:
/**
* Construct an HTML reflow command of type aReflowType and with target
* frame aTargetFrame. You can also specify an optional child frame, e.g.
* to indicate the inserted child frame
*/
nsHTMLReflowCommand(nsIFrame* aTargetFrame,
ReflowType aReflowType,
nsIFrame* aChildFrame = nsnull);
virtual ~nsHTMLReflowCommand();
// nsISupports
NS_DECL_ISUPPORTS
// nsIReflowCommand
NS_IMETHOD Dispatch(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsSize& aMaxSize);
NS_IMETHOD GetNext(nsIFrame*& aNextFrame);
NS_IMETHOD GetTarget(nsIFrame*& aTargetFrame) const;
NS_IMETHOD GetType(ReflowType& aReflowType) const;
NS_IMETHOD GetChildFrame(nsIFrame*& aChildFrame) const;
private:
ReflowType mType;
nsIFrame* mTargetFrame;
nsIFrame* mChildFrame;
nsVoidArray mPath;
};
#endif /* nsHTMLReflowCommand_h___ */

View File

@ -26,7 +26,7 @@
#include "nsIPresShell.h"
#include "nsCSSLayout.h"
#include "nsPlaceholderFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsHTMLAtoms.h"
#include "nsAbsoluteFrame.h"
#include "nsLeafFrame.h"
@ -896,9 +896,15 @@ NS_METHOD nsInlineFrame::Reflow(nsIPresContext* aPresContext,
if (eReflowReason_Incremental == aReflowState.reason) {
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command");
if (aReflowState.reflowCommand->GetTarget() == this) {
switch (aReflowState.reflowCommand->GetType()) {
case nsReflowCommand::FrameAppended:
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
if (target == this) {
nsIReflowCommand::ReflowType type;
aReflowState.reflowCommand->GetType(type);
switch (type) {
case nsIReflowCommand::FrameAppended:
// Recover our state
RecoverState(aPresContext, state, nsnull);
aStatus = ReflowUnmappedChildren(aPresContext, state);
@ -911,7 +917,9 @@ NS_METHOD nsInlineFrame::Reflow(nsIPresContext* aPresContext,
} else {
// The command is passing through us. Get the next frame in the reflow chain
nsIFrame* kidFrame = aReflowState.reflowCommand->GetNext();
nsIFrame* kidFrame;
aReflowState.reflowCommand->GetNext(kidFrame);
nsReflowMetrics kidSize(aDesiredSize.maxElementSize);
nsReflowState kidReflowState(kidFrame, aReflowState, state.availSize);

View File

@ -18,6 +18,8 @@
#include "nsLeafFrame.h"
#include "nsIStyleContext.h"
#include "nsCSSRendering.h"
#include "nsHTMLParts.h"
#include "nsIPresShell.h"
nsLeafFrame::nsLeafFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsFrame(aContent, aParentFrame)
@ -98,11 +100,21 @@ void nsLeafFrame::GetInnerArea(nsIPresContext* aPresContext,
(borderPadding.top + borderPadding.bottom);
}
NS_METHOD nsLeafFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
nsIFrame* aParent,
nsIFrame*& aContinuingFrame)
NS_METHOD nsLeafFrame::ContentChanged(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aChild,
nsISupports* aSubContent)
{
NS_NOTREACHED("Attempt to split the unsplittable");
aContinuingFrame = nsnull;
return NS_OK;
// Generate a reflow command with this frame as the target frame
nsIReflowCommand* cmd;
nsresult result;
result = NS_NewHTMLReflowCommand(&cmd, this, nsIReflowCommand::ContentChanged);
if (NS_OK == result) {
aShell->AppendReflowCommand(cmd);
NS_RELEASE(cmd);
}
return result;
}

View File

@ -37,9 +37,10 @@ public:
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD CreateContinuingFrame(nsIPresContext* aPresContext,
nsIFrame* aParent,
nsIFrame*& aContinuingFrame);
NS_IMETHOD ContentChanged(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aChild,
nsISupports* aSubContent);
protected:
nsLeafFrame(nsIContent* aContent, nsIFrame* aParentFrame);

View File

@ -28,7 +28,7 @@
#include "nsPlaceholderFrame.h"
#include "nsCSSLayout.h"
#include "nsCRT.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIFontMetrics.h"
#include "nsHTMLFrame.h"
#include "nsScrollFrame.h"
@ -595,7 +595,7 @@ nsLineLayout::ReflowMappedChild()
// Return values: <0 for error
// 0 == NS_LINE_LAYOUT
nsresult
nsLineLayout::ReflowChild(nsReflowCommand* aReflowCommand,
nsLineLayout::ReflowChild(nsIReflowCommand* aReflowCommand,
PRBool aNewChild)
{
nsIFrame* kidFrame = mState.mKidFrame;
@ -1016,8 +1016,8 @@ nsLineLayout::PlaceChild(nsRect& kidRect,
}
nsresult
nsLineLayout::IncrementalReflowFromChild(nsReflowCommand* aReflowCommand,
nsIFrame* aChildFrame)
nsLineLayout::IncrementalReflowFromChild(nsIReflowCommand* aReflowCommand,
nsIFrame* aChildFrame)
{
nsresult reflowStatus = NS_LINE_LAYOUT_COMPLETE;

View File

@ -100,8 +100,8 @@ struct nsLineLayout {
nsresult ReflowLine();
nsresult IncrementalReflowFromChild(nsReflowCommand* aReflowCommand,
nsIFrame* aChildFrame);
nsresult IncrementalReflowFromChild(nsIReflowCommand* aReflowCommand,
nsIFrame* aChildFrame);
void AtSpace();
@ -183,7 +183,7 @@ protected:
nsresult ReflowMappedChild();
nsresult ReflowChild(nsReflowCommand* aReflowCommand, PRBool aNewChild);
nsresult ReflowChild(nsIReflowCommand* aReflowCommand, PRBool aNewChild);
nsresult PlaceChild(nsRect& kidRect,
const nsReflowMetrics& kidMetrics,

View File

@ -20,7 +20,7 @@
#include "nsIContentDelegate.h"
#include "nsIPresContext.h"
#include "nsIStyleContext.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIRenderingContext.h"
nsPageFrame::nsPageFrame(nsIContent* aContent, nsIFrame* aParent)
@ -67,12 +67,17 @@ NS_METHOD nsPageFrame::Reflow(nsIPresContext* aPresContext,
// XXX Do something sensible in page mode...
if (eReflowReason_Incremental == aReflowState.reason) {
// We don't expect the target of the reflow command to be page frame
#ifdef NS_DEUG
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command");
NS_ASSERTION(aReflowState.reflowCommand->GetTarget() != this,
"page frame is reflow command target");
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
NS_ASSERTION(target != this, "page frame is reflow command target");
#endif
// Verify the next reflow command frame is our one and only child frame
nsIFrame* next = aReflowState.reflowCommand->GetNext();
nsIFrame* next;
aReflowState.reflowCommand->GetNext(next);
NS_ASSERTION(next == mFirstChild, "bad reflow frame");
// Dispatch the reflow command to our content child. Allow it to be as high

View File

@ -19,7 +19,7 @@
#include "nsHTMLContainer.h"
#include "nsContainerFrame.h"
#include "nsIDocument.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIPresContext.h"
#include "nsIStyleContext.h"
#include "nsViewsCID.h"
@ -90,12 +90,17 @@ NS_METHOD RootFrame::Reflow(nsIPresContext* aPresContext,
if (eReflowReason_Incremental == aReflowState.reason) {
// We don't expect the target of the reflow command to be the root frame
#ifdef NS_DEBUG
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "no reflow command");
NS_ASSERTION(aReflowState.reflowCommand->GetTarget() != this,
"root frame is reflow command target");
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
NS_ASSERTION(target != this, "root frame is reflow command target");
#endif
// Verify that the next frame in the reflow chain is our pseudo frame
nsIFrame* next = aReflowState.reflowCommand->GetNext();
nsIFrame* next;
aReflowState.reflowCommand->GetNext(next);
NS_ASSERTION(next == mFirstChild, "unexpected next reflow command frame");
} else {
@ -287,11 +292,15 @@ NS_METHOD RootContentFrame::Reflow(nsIPresContext* aPresContext,
if (eReflowReason_Incremental == aReflowState.reason) {
// We don't expect the target of the reflow command to be the root
// content frame
NS_ASSERTION(aReflowState.reflowCommand->GetTarget() != this,
"root content frame is reflow command target");
#ifdef NS_DEBUG
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
NS_ASSERTION(target != this, "root content frame is reflow command target");
#endif
// Verify the next frame in the reflow chain is our child frame
nsIFrame* next = aReflowState.reflowCommand->GetNext();
nsIFrame* next;
aReflowState.reflowCommand->GetNext(next);
NS_ASSERTION(next == mFirstChild, "unexpected next reflow command frame");
nsSize maxSize(aReflowState.maxSize.width, NS_UNCONSTRAINEDSIZE);

View File

@ -19,7 +19,7 @@
#include "nsIPresContext.h"
#include "nsIContentDelegate.h"
#include "nsIStyleContext.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIDeviceContext.h"
#include "nsPageFrame.h"
#include "nsViewsCID.h"
@ -113,11 +113,15 @@ nsScrollBodyFrame::Reflow(nsIPresContext* aPresContext,
if (eReflowReason_Incremental == aReflowState.reason) {
// We don't expect the target of the reflow command to be the root
// content frame
NS_ASSERTION(aReflowState.reflowCommand->GetTarget() != this,
"root content frame is reflow command target");
#ifdef NS_DEBUG
nsIFrame* target;
aReflowState.reflowCommand->GetTarget(target);
NS_ASSERTION(target != this, "root content frame is reflow command target");
#endif
// Verify the next frame in the reflow chain is our child frame
nsIFrame* next = aReflowState.reflowCommand->GetNext();
nsIFrame* next;
aReflowState.reflowCommand->GetNext(next);
NS_ASSERTION(next == mFirstChild, "unexpected next reflow command frame");
nsSize maxSize(aReflowState.maxSize.width, NS_UNCONSTRAINEDSIZE);

View File

@ -22,7 +22,7 @@
#include "nsHTMLParts.h"
#include "nsHTMLContainer.h"
#include "nsContainerFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"

View File

@ -17,7 +17,7 @@
*/
#include "nsTableCaptionFrame.h"
#include "nsBodyFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"

View File

@ -17,7 +17,7 @@
*/
#include "nsTableCellFrame.h"
#include "nsBodyFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"

View File

@ -22,7 +22,7 @@
#include "nsHTMLParts.h"
#include "nsHTMLContainer.h"
#include "nsContainerFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"

View File

@ -20,7 +20,7 @@
#include "nsTableCol.h"
#include "nsTablePart.h"
#include "nsContainerFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"

View File

@ -16,7 +16,7 @@
* Reserved.
*/
#include "nsTableColGroupFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"

View File

@ -21,7 +21,7 @@
#include "nsITableContent.h"
#include "nsTableContent.h"
#include "nsBodyFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
@ -31,7 +31,7 @@
#include "nsIContentDelegate.h"
#include "nsCSSLayout.h"
#include "nsVoidArray.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIPtr.h"
#ifdef NS_DEBUG

View File

@ -24,7 +24,7 @@
#include "nsHTMLParts.h"
#include "nsHTMLContainer.h"
#include "nsTableRowFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIContentDelegate.h"

View File

@ -23,7 +23,7 @@
#include "nsHTMLParts.h"
#include "nsHTMLContainer.h"
#include "nsIContentDelegate.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsIRenderingContext.h"
#include "nsStyleConsts.h"

View File

@ -17,7 +17,7 @@
*/
#include "nsTableCellFrame.h"
#include "nsBodyFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"

View File

@ -16,7 +16,7 @@
* Reserved.
*/
#include "nsTableColGroupFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"

View File

@ -21,7 +21,7 @@
#include "nsITableContent.h"
#include "nsTableContent.h"
#include "nsBodyFrame.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
@ -31,7 +31,7 @@
#include "nsIContentDelegate.h"
#include "nsCSSLayout.h"
#include "nsVoidArray.h"
#include "nsReflowCommand.h"
#include "nsIReflowCommand.h"
#include "nsIPtr.h"
#ifdef NS_DEBUG