diff --git a/mozilla/layout/base/public/nsIFrame.h b/mozilla/layout/base/public/nsIFrame.h
index 43939d0d83f..7f2c807d8b1 100644
--- a/mozilla/layout/base/public/nsIFrame.h
+++ b/mozilla/layout/base/public/nsIFrame.h
@@ -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 after
* @param aFrameList list of child frames to insert after 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,
diff --git a/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp b/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp
index 936eb751ffd..7168cbef305 100644
--- a/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -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);
}
diff --git a/mozilla/layout/generic/nsHTMLFrame.cpp b/mozilla/layout/generic/nsHTMLFrame.cpp
index 13a62100cb5..c03c125ef7d 100644
--- a/mozilla/layout/generic/nsHTMLFrame.cpp
+++ b/mozilla/layout/generic/nsHTMLFrame.cpp
@@ -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
diff --git a/mozilla/layout/generic/nsIFrame.h b/mozilla/layout/generic/nsIFrame.h
index 43939d0d83f..7f2c807d8b1 100644
--- a/mozilla/layout/generic/nsIFrame.h
+++ b/mozilla/layout/generic/nsIFrame.h
@@ -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 after
* @param aFrameList list of child frames to insert after 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,
diff --git a/mozilla/layout/generic/nsViewportFrame.cpp b/mozilla/layout/generic/nsViewportFrame.cpp
index 35e68242a9d..5ad0c71f099 100644
--- a/mozilla/layout/generic/nsViewportFrame.cpp
+++ b/mozilla/layout/generic/nsViewportFrame.cpp
@@ -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);
}
}
diff --git a/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp b/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp
index 936eb751ffd..7168cbef305 100644
--- a/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp
+++ b/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp
@@ -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);
}
diff --git a/mozilla/layout/html/base/src/nsHTMLFrame.cpp b/mozilla/layout/html/base/src/nsHTMLFrame.cpp
index 13a62100cb5..c03c125ef7d 100644
--- a/mozilla/layout/html/base/src/nsHTMLFrame.cpp
+++ b/mozilla/layout/html/base/src/nsHTMLFrame.cpp
@@ -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
diff --git a/mozilla/layout/html/base/src/nsScrollFrame.cpp b/mozilla/layout/html/base/src/nsScrollFrame.cpp
index 14c8d88265b..48a54291e6b 100644
--- a/mozilla/layout/html/base/src/nsScrollFrame.cpp
+++ b/mozilla/layout/html/base/src/nsScrollFrame.cpp
@@ -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;
}
diff --git a/mozilla/layout/html/base/src/nsViewportFrame.cpp b/mozilla/layout/html/base/src/nsViewportFrame.cpp
index 35e68242a9d..5ad0c71f099 100644
--- a/mozilla/layout/html/base/src/nsViewportFrame.cpp
+++ b/mozilla/layout/html/base/src/nsViewportFrame.cpp
@@ -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);
}
}