Changed root frame class over to new reflow command handling
git-svn-id: svn://10.0.0.236/trunk@41287 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
177b8110fa
commit
dd72d8029f
@ -226,7 +226,7 @@ public:
|
||||
* @param aListName the name of the child list. A NULL pointer for the atom
|
||||
* name means the unnamed principal child list
|
||||
* @param aChildList list of child frames. Each of the frames has its
|
||||
* NS_FRAME_IS_DIRTY bit set
|
||||
* NS_FRAME_IS_DIRTY bit set
|
||||
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
|
||||
* name,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame or if the
|
||||
@ -246,10 +246,10 @@ public:
|
||||
* @param aListName the name of the child list. A NULL pointer for the atom
|
||||
* name means the unnamed principal child list
|
||||
* @param aFrameList list of child frames to append. Each of the frames has
|
||||
* its NS_FRAME_IS_DIRTY bit set
|
||||
* its NS_FRAME_IS_DIRTY bit set
|
||||
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
|
||||
* name,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
|
||||
* NS_OK otherwise
|
||||
*/
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
@ -266,10 +266,10 @@ public:
|
||||
* name means the unnamed principal child list
|
||||
* @param aPrevFrame the frame to insert frames <b>after</b>
|
||||
* @param aFrameList list of child frames to insert <b>after</b> aPrevFrame.
|
||||
* Each of the frames has its NS_FRAME_IS_DIRTY bit set
|
||||
* Each of the frames has its NS_FRAME_IS_DIRTY bit set
|
||||
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
|
||||
* name,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
|
||||
* NS_OK otherwise
|
||||
*/
|
||||
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
|
||||
@ -289,7 +289,9 @@ public:
|
||||
* @param aOldFrame the frame to remove
|
||||
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
|
||||
* name,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame
|
||||
* NS_ERROR_FAILURE if the child frame is not in the specified
|
||||
* child list,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
|
||||
* NS_OK otherwise
|
||||
*/
|
||||
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
|
||||
@ -306,10 +308,12 @@ public:
|
||||
* name means the unnamed principal child list
|
||||
* @param aOldFrame the frame to remove
|
||||
* @param aNewFrame the frame to replace it with. The new frame has its
|
||||
* NS_FRAME_IS_DIRTY bit set
|
||||
* NS_FRAME_IS_DIRTY bit set
|
||||
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
|
||||
* name,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame
|
||||
* NS_ERROR_FAILURE if the old child frame is not in the specified
|
||||
* child list,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
|
||||
* NS_OK otherwise
|
||||
*/
|
||||
NS_IMETHOD ReplaceFrame(nsIPresContext& aPresContext,
|
||||
|
||||
@ -120,7 +120,7 @@ nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame,
|
||||
// Because positioned frames aren't part of a flow, there's no additional
|
||||
// work to do, e.g. reflowing sibling frames. And because positioned frames
|
||||
// have a view, we don't need to repaint
|
||||
return NS_OK;
|
||||
return result ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -184,6 +184,10 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIFrame* aDelegatin
|
||||
f->GetFrameState(&frameState);
|
||||
if (frameState & NS_FRAME_IS_DIRTY) {
|
||||
nsReflowStatus status;
|
||||
|
||||
// Note: the only reason the frame would be dirty would be if it had
|
||||
// just been inserted or appended
|
||||
NS_ASSERTION(frameState & NS_FRAME_FIRST_REFLOW, "unexpected frame state");
|
||||
ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowState,
|
||||
f, PR_TRUE, status);
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsIAreaFrame.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
// Interface IDs
|
||||
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
|
||||
@ -54,6 +55,20 @@ static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
|
||||
*/
|
||||
class RootFrame : public nsHTMLContainerFrame {
|
||||
public:
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
@ -132,6 +147,102 @@ RootFrame::SetRect(const nsRect& aRect)
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RootFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ASSERTION(!aListName, "unexpected child list name");
|
||||
NS_PRECONDITION(mFrames.IsEmpty(), "already have a child frame");
|
||||
if (aListName) {
|
||||
// We only support unnamed principal child list
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
} else if (!mFrames.IsEmpty()) {
|
||||
// We only allow a single child frame
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
} else {
|
||||
// Insert the new frames
|
||||
#ifdef NS_DEBUG
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
#endif
|
||||
mFrames.AppendFrame(nsnull, aFrameList);
|
||||
|
||||
// Generate a reflow command to reflow the newly inserted frame
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RootFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Because we only support a single child frame inserting is the same
|
||||
// as appending
|
||||
NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame");
|
||||
if (aPrevFrame) {
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
} else {
|
||||
rv = AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RootFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ASSERTION(!aListName, "unexpected child list name");
|
||||
if (aListName) {
|
||||
// We only support the unnamed principal child list
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
} else if (aOldFrame == mFrames.FirstChild()) {
|
||||
// It's our one and only child frame
|
||||
// Damage the area occupied by the deleted frame
|
||||
nsRect damageRect;
|
||||
aOldFrame->GetRect(damageRect);
|
||||
Invalidate(damageRect, PR_FALSE);
|
||||
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
|
||||
// Generate a reflow command so we get reflowed
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
|
||||
} else {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RootFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
@ -144,50 +255,22 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
|
||||
// Initialize OUT parameter
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
PRBool isChildInitialReflow = PR_FALSE;
|
||||
PRBool isStyleChange = PR_FALSE;
|
||||
PRBool isDirtyChildReflow = PR_FALSE;
|
||||
|
||||
// Check for an incremental reflow
|
||||
// XXX This needs to use the new reflow command handling instead...
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
// See if we're the target frame
|
||||
nsIFrame* targetFrame;
|
||||
aReflowState.reflowCommand->GetTarget(targetFrame);
|
||||
if (this == targetFrame) {
|
||||
nsIReflowCommand::ReflowType reflowType;
|
||||
nsIFrame* childFrame;
|
||||
nsIFrame* deletedFrame;
|
||||
|
||||
// Get the reflow type
|
||||
nsIReflowCommand::ReflowType reflowType;
|
||||
aReflowState.reflowCommand->GetType(reflowType);
|
||||
|
||||
switch (reflowType) {
|
||||
case nsIReflowCommand::FrameAppended:
|
||||
case nsIReflowCommand::FrameInserted:
|
||||
NS_ASSERTION(mFrames.IsEmpty(), "only one child frame allowed");
|
||||
|
||||
// Insert the frame into the child list
|
||||
aReflowState.reflowCommand->GetChildFrame(childFrame);
|
||||
mFrames.SetFrames(childFrame);
|
||||
|
||||
// It's the child frame's initial reflow
|
||||
isChildInitialReflow = PR_TRUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameRemoved:
|
||||
// Get the child frame we should delete
|
||||
aReflowState.reflowCommand->GetChildFrame(deletedFrame);
|
||||
NS_ASSERTION(deletedFrame == mFrames.FirstChild(), "not a child frame");
|
||||
|
||||
// Remove it from the child list
|
||||
if (deletedFrame == mFrames.FirstChild()) {
|
||||
// Damage the area occupied by the deleted frame
|
||||
nsRect damageRect;
|
||||
deletedFrame->GetRect(damageRect);
|
||||
Invalidate(damageRect, PR_FALSE);
|
||||
|
||||
mFrames.DestroyFrame(aPresContext, deletedFrame);
|
||||
}
|
||||
case nsIReflowCommand::ReflowDirty:
|
||||
isDirtyChildReflow = PR_TRUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::StyleChanged:
|
||||
@ -210,7 +293,7 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
|
||||
// Reflow our one and only child frame
|
||||
nsHTMLReflowMetrics kidDesiredSize(nsnull);
|
||||
if (mFrames.IsEmpty()) {
|
||||
// Return our desired size
|
||||
// We have no child frame, so return an empty size
|
||||
aDesiredSize.width = aDesiredSize.height = 0;
|
||||
aDesiredSize.ascent = aDesiredSize.descent = 0;
|
||||
|
||||
@ -222,7 +305,9 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
|
||||
nsSize(aReflowState.availableWidth,
|
||||
NS_UNCONSTRAINEDSIZE));
|
||||
if (isChildInitialReflow) {
|
||||
if (isDirtyChildReflow) {
|
||||
// Note: the only reason the frame would be dirty would be if it had
|
||||
// just been inserted or appended
|
||||
kidReflowState.reason = eReflowReason_Initial;
|
||||
kidReflowState.reflowCommand = nsnull;
|
||||
} else if (isStyleChange) {
|
||||
@ -297,6 +382,13 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsRect rect(kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top,
|
||||
kidDesiredSize.width, kidDesiredSize.height);
|
||||
kidFrame->SetRect(rect);
|
||||
|
||||
// If the child frame was just inserted, then we're responsible for making sure
|
||||
// it repaints
|
||||
if (isDirtyChildReflow) {
|
||||
// Damage the area occupied by the deleted frame
|
||||
Invalidate(rect, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// Return our desired size
|
||||
|
||||
@ -226,7 +226,7 @@ public:
|
||||
* @param aListName the name of the child list. A NULL pointer for the atom
|
||||
* name means the unnamed principal child list
|
||||
* @param aChildList list of child frames. Each of the frames has its
|
||||
* NS_FRAME_IS_DIRTY bit set
|
||||
* NS_FRAME_IS_DIRTY bit set
|
||||
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
|
||||
* name,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame or if the
|
||||
@ -246,10 +246,10 @@ public:
|
||||
* @param aListName the name of the child list. A NULL pointer for the atom
|
||||
* name means the unnamed principal child list
|
||||
* @param aFrameList list of child frames to append. Each of the frames has
|
||||
* its NS_FRAME_IS_DIRTY bit set
|
||||
* its NS_FRAME_IS_DIRTY bit set
|
||||
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
|
||||
* name,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
|
||||
* NS_OK otherwise
|
||||
*/
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
@ -266,10 +266,10 @@ public:
|
||||
* name means the unnamed principal child list
|
||||
* @param aPrevFrame the frame to insert frames <b>after</b>
|
||||
* @param aFrameList list of child frames to insert <b>after</b> aPrevFrame.
|
||||
* Each of the frames has its NS_FRAME_IS_DIRTY bit set
|
||||
* Each of the frames has its NS_FRAME_IS_DIRTY bit set
|
||||
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
|
||||
* name,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
|
||||
* NS_OK otherwise
|
||||
*/
|
||||
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
|
||||
@ -289,7 +289,9 @@ public:
|
||||
* @param aOldFrame the frame to remove
|
||||
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
|
||||
* name,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame
|
||||
* NS_ERROR_FAILURE if the child frame is not in the specified
|
||||
* child list,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
|
||||
* NS_OK otherwise
|
||||
*/
|
||||
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
|
||||
@ -306,10 +308,12 @@ public:
|
||||
* name means the unnamed principal child list
|
||||
* @param aOldFrame the frame to remove
|
||||
* @param aNewFrame the frame to replace it with. The new frame has its
|
||||
* NS_FRAME_IS_DIRTY bit set
|
||||
* NS_FRAME_IS_DIRTY bit set
|
||||
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
|
||||
* name,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame
|
||||
* NS_ERROR_FAILURE if the old child frame is not in the specified
|
||||
* child list,
|
||||
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
|
||||
* NS_OK otherwise
|
||||
*/
|
||||
NS_IMETHOD ReplaceFrame(nsIPresContext& aPresContext,
|
||||
|
||||
@ -135,7 +135,7 @@ ViewportFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsresult rv;
|
||||
|
||||
// See which child list to add the frames to
|
||||
#ifdef NS_DEBUG
|
||||
@ -143,6 +143,8 @@ ViewportFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
#endif
|
||||
if (nsLayoutAtoms::fixedList == aListName) {
|
||||
mFixedFrames.SetFrames(aChildList);
|
||||
rv = NS_OK;
|
||||
|
||||
} else {
|
||||
rv = nsContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
}
|
||||
@ -156,24 +158,28 @@ ViewportFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsresult rv;
|
||||
|
||||
// We only expect incremental changes for our fixed frames
|
||||
NS_PRECONDITION(nsLayoutAtoms::fixedList == aListName, "unexpected child list");
|
||||
|
||||
// Add the frames to our list of fixed position frames
|
||||
#ifdef NS_DEBUG
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
#endif
|
||||
mFixedFrames.AppendFrames(nsnull, aFrameList);
|
||||
|
||||
// Generate a reflow command to reflow the dirty frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
reflowCmd->SetChildListName(nsLayoutAtoms::fixedList);
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
if (aListName != nsLayoutAtoms::fixedList) {
|
||||
// We only expect incremental changes for our fixed frames
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
} else {
|
||||
// Add the frames to our list of fixed position frames
|
||||
#ifdef NS_DEBUG
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
#endif
|
||||
mFixedFrames.AppendFrames(nsnull, aFrameList);
|
||||
|
||||
// Generate a reflow command to reflow the dirty frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
reflowCmd->SetChildListName(nsLayoutAtoms::fixedList);
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -186,24 +192,28 @@ ViewportFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsresult rv;
|
||||
|
||||
// We only expect incremental changes for our fixed frames
|
||||
NS_PRECONDITION(nsLayoutAtoms::fixedList == aListName, "unexpected child list");
|
||||
|
||||
// Insert the new frames
|
||||
#ifdef NS_DEBUG
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
#endif
|
||||
mFixedFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
if (aListName != nsLayoutAtoms::fixedList) {
|
||||
// We only expect incremental changes for our fixed frames
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
// Generate a reflow command to reflow the dirty frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
reflowCmd->SetChildListName(nsLayoutAtoms::fixedList);
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
} else {
|
||||
// Insert the new frames
|
||||
#ifdef NS_DEBUG
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
#endif
|
||||
mFixedFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
|
||||
// Generate a reflow command to reflow the dirty frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
reflowCmd->SetChildListName(nsLayoutAtoms::fixedList);
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -215,15 +225,23 @@ ViewportFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
// We only expect incremental changes for our fixed frames
|
||||
nsresult rv;
|
||||
|
||||
NS_PRECONDITION(nsLayoutAtoms::fixedList == aListName, "unexpected child list");
|
||||
|
||||
PRBool result = mFixedFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
NS_ASSERTION(result, "didn't find frame to delete");
|
||||
// Because fixed frames aren't part of a flow, there's no additional
|
||||
// work to do, e.g. reflowing sibling frames. And because fixed frames
|
||||
// have a view, we don't need to repaint
|
||||
return NS_OK;
|
||||
if (aListName != nsLayoutAtoms::fixedList) {
|
||||
// We only expect incremental changes for our fixed frames
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
} else {
|
||||
PRBool result = mFixedFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
NS_ASSERTION(result, "didn't find frame to delete");
|
||||
// Because fixed frames aren't part of a flow, there's no additional
|
||||
// work to do, e.g. reflowing sibling frames. And because fixed frames
|
||||
// have a view, we don't need to repaint
|
||||
rv = result ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -412,6 +430,10 @@ ViewportFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
f->GetFrameState(&frameState);
|
||||
if (frameState & NS_FRAME_IS_DIRTY) {
|
||||
nsReflowStatus status;
|
||||
|
||||
// Note: the only reason the frame would be dirty would be if it had
|
||||
// just been inserted or appended
|
||||
NS_ASSERTION(frameState & NS_FRAME_FIRST_REFLOW, "unexpected frame state");
|
||||
ReflowFixedFrame(aPresContext, reflowState, f, PR_TRUE, status);
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame,
|
||||
// Because positioned frames aren't part of a flow, there's no additional
|
||||
// work to do, e.g. reflowing sibling frames. And because positioned frames
|
||||
// have a view, we don't need to repaint
|
||||
return NS_OK;
|
||||
return result ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -184,6 +184,10 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIFrame* aDelegatin
|
||||
f->GetFrameState(&frameState);
|
||||
if (frameState & NS_FRAME_IS_DIRTY) {
|
||||
nsReflowStatus status;
|
||||
|
||||
// Note: the only reason the frame would be dirty would be if it had
|
||||
// just been inserted or appended
|
||||
NS_ASSERTION(frameState & NS_FRAME_FIRST_REFLOW, "unexpected frame state");
|
||||
ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowState,
|
||||
f, PR_TRUE, status);
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsIAreaFrame.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
||||
// Interface IDs
|
||||
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
|
||||
@ -54,6 +55,20 @@ static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
|
||||
*/
|
||||
class RootFrame : public nsHTMLContainerFrame {
|
||||
public:
|
||||
NS_IMETHOD AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList);
|
||||
NS_IMETHOD RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame);
|
||||
|
||||
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
@ -132,6 +147,102 @@ RootFrame::SetRect(const nsRect& aRect)
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RootFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ASSERTION(!aListName, "unexpected child list name");
|
||||
NS_PRECONDITION(mFrames.IsEmpty(), "already have a child frame");
|
||||
if (aListName) {
|
||||
// We only support unnamed principal child list
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
} else if (!mFrames.IsEmpty()) {
|
||||
// We only allow a single child frame
|
||||
rv = NS_ERROR_FAILURE;
|
||||
|
||||
} else {
|
||||
// Insert the new frames
|
||||
#ifdef NS_DEBUG
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
#endif
|
||||
mFrames.AppendFrame(nsnull, aFrameList);
|
||||
|
||||
// Generate a reflow command to reflow the newly inserted frame
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RootFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Because we only support a single child frame inserting is the same
|
||||
// as appending
|
||||
NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame");
|
||||
if (aPrevFrame) {
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
} else {
|
||||
rv = AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RootFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ASSERTION(!aListName, "unexpected child list name");
|
||||
if (aListName) {
|
||||
// We only support the unnamed principal child list
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
} else if (aOldFrame == mFrames.FirstChild()) {
|
||||
// It's our one and only child frame
|
||||
// Damage the area occupied by the deleted frame
|
||||
nsRect damageRect;
|
||||
aOldFrame->GetRect(damageRect);
|
||||
Invalidate(damageRect, PR_FALSE);
|
||||
|
||||
// Remove the frame and destroy it
|
||||
mFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
|
||||
// Generate a reflow command so we get reflowed
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
|
||||
} else {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RootFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
@ -144,50 +255,22 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
|
||||
// Initialize OUT parameter
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
PRBool isChildInitialReflow = PR_FALSE;
|
||||
PRBool isStyleChange = PR_FALSE;
|
||||
PRBool isDirtyChildReflow = PR_FALSE;
|
||||
|
||||
// Check for an incremental reflow
|
||||
// XXX This needs to use the new reflow command handling instead...
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
// See if we're the target frame
|
||||
nsIFrame* targetFrame;
|
||||
aReflowState.reflowCommand->GetTarget(targetFrame);
|
||||
if (this == targetFrame) {
|
||||
nsIReflowCommand::ReflowType reflowType;
|
||||
nsIFrame* childFrame;
|
||||
nsIFrame* deletedFrame;
|
||||
|
||||
// Get the reflow type
|
||||
nsIReflowCommand::ReflowType reflowType;
|
||||
aReflowState.reflowCommand->GetType(reflowType);
|
||||
|
||||
switch (reflowType) {
|
||||
case nsIReflowCommand::FrameAppended:
|
||||
case nsIReflowCommand::FrameInserted:
|
||||
NS_ASSERTION(mFrames.IsEmpty(), "only one child frame allowed");
|
||||
|
||||
// Insert the frame into the child list
|
||||
aReflowState.reflowCommand->GetChildFrame(childFrame);
|
||||
mFrames.SetFrames(childFrame);
|
||||
|
||||
// It's the child frame's initial reflow
|
||||
isChildInitialReflow = PR_TRUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::FrameRemoved:
|
||||
// Get the child frame we should delete
|
||||
aReflowState.reflowCommand->GetChildFrame(deletedFrame);
|
||||
NS_ASSERTION(deletedFrame == mFrames.FirstChild(), "not a child frame");
|
||||
|
||||
// Remove it from the child list
|
||||
if (deletedFrame == mFrames.FirstChild()) {
|
||||
// Damage the area occupied by the deleted frame
|
||||
nsRect damageRect;
|
||||
deletedFrame->GetRect(damageRect);
|
||||
Invalidate(damageRect, PR_FALSE);
|
||||
|
||||
mFrames.DestroyFrame(aPresContext, deletedFrame);
|
||||
}
|
||||
case nsIReflowCommand::ReflowDirty:
|
||||
isDirtyChildReflow = PR_TRUE;
|
||||
break;
|
||||
|
||||
case nsIReflowCommand::StyleChanged:
|
||||
@ -210,7 +293,7 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
|
||||
// Reflow our one and only child frame
|
||||
nsHTMLReflowMetrics kidDesiredSize(nsnull);
|
||||
if (mFrames.IsEmpty()) {
|
||||
// Return our desired size
|
||||
// We have no child frame, so return an empty size
|
||||
aDesiredSize.width = aDesiredSize.height = 0;
|
||||
aDesiredSize.ascent = aDesiredSize.descent = 0;
|
||||
|
||||
@ -222,7 +305,9 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
|
||||
nsSize(aReflowState.availableWidth,
|
||||
NS_UNCONSTRAINEDSIZE));
|
||||
if (isChildInitialReflow) {
|
||||
if (isDirtyChildReflow) {
|
||||
// Note: the only reason the frame would be dirty would be if it had
|
||||
// just been inserted or appended
|
||||
kidReflowState.reason = eReflowReason_Initial;
|
||||
kidReflowState.reflowCommand = nsnull;
|
||||
} else if (isStyleChange) {
|
||||
@ -297,6 +382,13 @@ RootFrame::Reflow(nsIPresContext& aPresContext,
|
||||
nsRect rect(kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top,
|
||||
kidDesiredSize.width, kidDesiredSize.height);
|
||||
kidFrame->SetRect(rect);
|
||||
|
||||
// If the child frame was just inserted, then we're responsible for making sure
|
||||
// it repaints
|
||||
if (isDirtyChildReflow) {
|
||||
// Damage the area occupied by the deleted frame
|
||||
Invalidate(rect, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// Return our desired size
|
||||
|
||||
@ -142,7 +142,7 @@ nsScrollFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
// Scroll frames doesn't support incremental changes
|
||||
// Scroll frame doesn't support incremental changes
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
@ -135,7 +135,7 @@ ViewportFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aChildList)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsresult rv;
|
||||
|
||||
// See which child list to add the frames to
|
||||
#ifdef NS_DEBUG
|
||||
@ -143,6 +143,8 @@ ViewportFrame::SetInitialChildList(nsIPresContext& aPresContext,
|
||||
#endif
|
||||
if (nsLayoutAtoms::fixedList == aListName) {
|
||||
mFixedFrames.SetFrames(aChildList);
|
||||
rv = NS_OK;
|
||||
|
||||
} else {
|
||||
rv = nsContainerFrame::SetInitialChildList(aPresContext, aListName, aChildList);
|
||||
}
|
||||
@ -156,24 +158,28 @@ ViewportFrame::AppendFrames(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsresult rv;
|
||||
|
||||
// We only expect incremental changes for our fixed frames
|
||||
NS_PRECONDITION(nsLayoutAtoms::fixedList == aListName, "unexpected child list");
|
||||
|
||||
// Add the frames to our list of fixed position frames
|
||||
#ifdef NS_DEBUG
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
#endif
|
||||
mFixedFrames.AppendFrames(nsnull, aFrameList);
|
||||
|
||||
// Generate a reflow command to reflow the dirty frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
reflowCmd->SetChildListName(nsLayoutAtoms::fixedList);
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
if (aListName != nsLayoutAtoms::fixedList) {
|
||||
// We only expect incremental changes for our fixed frames
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
} else {
|
||||
// Add the frames to our list of fixed position frames
|
||||
#ifdef NS_DEBUG
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
#endif
|
||||
mFixedFrames.AppendFrames(nsnull, aFrameList);
|
||||
|
||||
// Generate a reflow command to reflow the dirty frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
reflowCmd->SetChildListName(nsLayoutAtoms::fixedList);
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -186,24 +192,28 @@ ViewportFrame::InsertFrames(nsIPresContext& aPresContext,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsresult rv;
|
||||
|
||||
// We only expect incremental changes for our fixed frames
|
||||
NS_PRECONDITION(nsLayoutAtoms::fixedList == aListName, "unexpected child list");
|
||||
|
||||
// Insert the new frames
|
||||
#ifdef NS_DEBUG
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
#endif
|
||||
mFixedFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
if (aListName != nsLayoutAtoms::fixedList) {
|
||||
// We only expect incremental changes for our fixed frames
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
// Generate a reflow command to reflow the dirty frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
reflowCmd->SetChildListName(nsLayoutAtoms::fixedList);
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
} else {
|
||||
// Insert the new frames
|
||||
#ifdef NS_DEBUG
|
||||
nsFrame::VerifyDirtyBitSet(aFrameList);
|
||||
#endif
|
||||
mFixedFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
|
||||
// Generate a reflow command to reflow the dirty frames
|
||||
nsIReflowCommand* reflowCmd;
|
||||
rv = NS_NewHTMLReflowCommand(&reflowCmd, this, nsIReflowCommand::ReflowDirty);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
reflowCmd->SetChildListName(nsLayoutAtoms::fixedList);
|
||||
aPresShell.AppendReflowCommand(reflowCmd);
|
||||
NS_RELEASE(reflowCmd);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -215,15 +225,23 @@ ViewportFrame::RemoveFrame(nsIPresContext& aPresContext,
|
||||
nsIAtom* aListName,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
// We only expect incremental changes for our fixed frames
|
||||
nsresult rv;
|
||||
|
||||
NS_PRECONDITION(nsLayoutAtoms::fixedList == aListName, "unexpected child list");
|
||||
|
||||
PRBool result = mFixedFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
NS_ASSERTION(result, "didn't find frame to delete");
|
||||
// Because fixed frames aren't part of a flow, there's no additional
|
||||
// work to do, e.g. reflowing sibling frames. And because fixed frames
|
||||
// have a view, we don't need to repaint
|
||||
return NS_OK;
|
||||
if (aListName != nsLayoutAtoms::fixedList) {
|
||||
// We only expect incremental changes for our fixed frames
|
||||
rv = NS_ERROR_INVALID_ARG;
|
||||
|
||||
} else {
|
||||
PRBool result = mFixedFrames.DestroyFrame(aPresContext, aOldFrame);
|
||||
NS_ASSERTION(result, "didn't find frame to delete");
|
||||
// Because fixed frames aren't part of a flow, there's no additional
|
||||
// work to do, e.g. reflowing sibling frames. And because fixed frames
|
||||
// have a view, we don't need to repaint
|
||||
rv = result ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -412,6 +430,10 @@ ViewportFrame::IncrementalReflow(nsIPresContext& aPresContext,
|
||||
f->GetFrameState(&frameState);
|
||||
if (frameState & NS_FRAME_IS_DIRTY) {
|
||||
nsReflowStatus status;
|
||||
|
||||
// Note: the only reason the frame would be dirty would be if it had
|
||||
// just been inserted or appended
|
||||
NS_ASSERTION(frameState & NS_FRAME_FIRST_REFLOW, "unexpected frame state");
|
||||
ReflowFixedFrame(aPresContext, reflowState, f, PR_TRUE, status);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user