diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index c0b46665c6a7..c846ff664103 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -21,6 +21,7 @@
#include "nsLineLayout.h"
#include "nsInlineReflow.h"
#include "nsCSSLayout.h"
+#include "nsAbsoluteFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsStyleConsts.h"
#include "nsHTMLIIDs.h"
@@ -2008,16 +2009,11 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
PRBool isBlock =
nsLineLayout::TreatFrameAsBlock(kidDisplay, kidPosition);
-// XXX yikes! this has to be here because otherwise we bust...why?
-#if 1
- // See if the element wants to be floated
- if (NS_STYLE_FLOAT_NONE != kidDisplay->mFloats) {
- // Create a placeholder frame that will serve as the anchor point.
- nsPlaceholderFrame* placeholder =
- CreatePlaceholderFrame(aPresContext, frame);
-
- // Remove the floated element from the flow, and replace it with the
- // placeholder frame
+ // See if we need to move the frame outside of the flow, and insert in
+ // its place a placeholder frame
+ nsIFrame* placeholder;
+ if (MoveFrameOutOfFlow(aPresContext, frame, kidDisplay, kidPosition, placeholder)) {
+ // Remove 'frame' from the flow, and replace it with 'placeholder'
if (nsnull != prevFrame) {
prevFrame->SetNextSibling(placeholder);
}
@@ -2026,58 +2022,17 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
placeholder->SetNextSibling(nextSibling);
frame->SetNextSibling(nsnull);
- // If the floated element can contain children then wrap it in a
- // BODY frame before floating it
- nsIContent* content;
- PRBool isContainer;
-
- frame->GetContent(content);
- content->CanContainChildren(isContainer);
- if (isContainer) {
- // Wrap the floated element in a BODY frame.
- nsIFrame* wrapperFrame;
- NS_NewBodyFrame(content, this, wrapperFrame);
-
- // The body wrapper frame gets the original style context, and the floated
- // frame gets a pseudo style context
- nsIStyleContext* kidStyle;
- frame->GetStyleContext(&aPresContext, kidStyle);
- wrapperFrame->SetStyleContext(&aPresContext, kidStyle);
- NS_RELEASE(kidStyle);
-
- nsIStyleContext* pseudoStyle;
- pseudoStyle = aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::columnPseudo,
- wrapperFrame);
- frame->SetStyleContext(&aPresContext, pseudoStyle);
- NS_RELEASE(pseudoStyle);
-
- // Init the body frame
- wrapperFrame->Init(aPresContext, frame);
-
- // Bind the wrapper frame to the placeholder
- placeholder->SetAnchoredItem(wrapperFrame);
- }
- NS_RELEASE(content);
-
// The placeholder frame is always inline
frame = placeholder;
isBlock = PR_FALSE;
}
-#endif
- // XXX CONSTRUCTION See if it wants to be absolutely positioned or scrolled
- // if overflows...
+ // XXX CONSTRUCTION See if it wants to be scrolled if overflows...
#if 0
nsIFrame* kidFrame = nsnull;
nsresult rv;
- if (NS_STYLE_POSITION_ABSOLUTE == kidPosition->mPosition) {
- rv = nsAbsoluteFrame::NewFrame(&kidFrame, aKid, aParentFrame);
- if (NS_OK == rv) {
- kidFrame->SetStyleContext(aPresContext, kidSC);
- }
- }
- else if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
- (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
+ if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
+ (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
rv = NS_NewScrollFrame(&kidFrame, aKid, aParentFrame);
if (NS_OK == rv) {
kidFrame->SetStyleContext(aPresContext, kidSC);
@@ -3446,6 +3401,8 @@ nsBlockFrame::DrainOverflowLines()
return drained;
}
+// XXX This code doesn't handle floating elements or absolutely positioned
+// elements...
nsresult
nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame,
nsIFrame* aNewFrame,
diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp
index c0b46665c6a7..c846ff664103 100644
--- a/layout/generic/nsBlockReflowState.cpp
+++ b/layout/generic/nsBlockReflowState.cpp
@@ -21,6 +21,7 @@
#include "nsLineLayout.h"
#include "nsInlineReflow.h"
#include "nsCSSLayout.h"
+#include "nsAbsoluteFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsStyleConsts.h"
#include "nsHTMLIIDs.h"
@@ -2008,16 +2009,11 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
PRBool isBlock =
nsLineLayout::TreatFrameAsBlock(kidDisplay, kidPosition);
-// XXX yikes! this has to be here because otherwise we bust...why?
-#if 1
- // See if the element wants to be floated
- if (NS_STYLE_FLOAT_NONE != kidDisplay->mFloats) {
- // Create a placeholder frame that will serve as the anchor point.
- nsPlaceholderFrame* placeholder =
- CreatePlaceholderFrame(aPresContext, frame);
-
- // Remove the floated element from the flow, and replace it with the
- // placeholder frame
+ // See if we need to move the frame outside of the flow, and insert in
+ // its place a placeholder frame
+ nsIFrame* placeholder;
+ if (MoveFrameOutOfFlow(aPresContext, frame, kidDisplay, kidPosition, placeholder)) {
+ // Remove 'frame' from the flow, and replace it with 'placeholder'
if (nsnull != prevFrame) {
prevFrame->SetNextSibling(placeholder);
}
@@ -2026,58 +2022,17 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
placeholder->SetNextSibling(nextSibling);
frame->SetNextSibling(nsnull);
- // If the floated element can contain children then wrap it in a
- // BODY frame before floating it
- nsIContent* content;
- PRBool isContainer;
-
- frame->GetContent(content);
- content->CanContainChildren(isContainer);
- if (isContainer) {
- // Wrap the floated element in a BODY frame.
- nsIFrame* wrapperFrame;
- NS_NewBodyFrame(content, this, wrapperFrame);
-
- // The body wrapper frame gets the original style context, and the floated
- // frame gets a pseudo style context
- nsIStyleContext* kidStyle;
- frame->GetStyleContext(&aPresContext, kidStyle);
- wrapperFrame->SetStyleContext(&aPresContext, kidStyle);
- NS_RELEASE(kidStyle);
-
- nsIStyleContext* pseudoStyle;
- pseudoStyle = aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::columnPseudo,
- wrapperFrame);
- frame->SetStyleContext(&aPresContext, pseudoStyle);
- NS_RELEASE(pseudoStyle);
-
- // Init the body frame
- wrapperFrame->Init(aPresContext, frame);
-
- // Bind the wrapper frame to the placeholder
- placeholder->SetAnchoredItem(wrapperFrame);
- }
- NS_RELEASE(content);
-
// The placeholder frame is always inline
frame = placeholder;
isBlock = PR_FALSE;
}
-#endif
- // XXX CONSTRUCTION See if it wants to be absolutely positioned or scrolled
- // if overflows...
+ // XXX CONSTRUCTION See if it wants to be scrolled if overflows...
#if 0
nsIFrame* kidFrame = nsnull;
nsresult rv;
- if (NS_STYLE_POSITION_ABSOLUTE == kidPosition->mPosition) {
- rv = nsAbsoluteFrame::NewFrame(&kidFrame, aKid, aParentFrame);
- if (NS_OK == rv) {
- kidFrame->SetStyleContext(aPresContext, kidSC);
- }
- }
- else if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
- (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
+ if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
+ (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
rv = NS_NewScrollFrame(&kidFrame, aKid, aParentFrame);
if (NS_OK == rv) {
kidFrame->SetStyleContext(aPresContext, kidSC);
@@ -3446,6 +3401,8 @@ nsBlockFrame::DrainOverflowLines()
return drained;
}
+// XXX This code doesn't handle floating elements or absolutely positioned
+// elements...
nsresult
nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame,
nsIFrame* aNewFrame,
diff --git a/layout/generic/nsBlockReflowState.h b/layout/generic/nsBlockReflowState.h
index c0b46665c6a7..c846ff664103 100644
--- a/layout/generic/nsBlockReflowState.h
+++ b/layout/generic/nsBlockReflowState.h
@@ -21,6 +21,7 @@
#include "nsLineLayout.h"
#include "nsInlineReflow.h"
#include "nsCSSLayout.h"
+#include "nsAbsoluteFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsStyleConsts.h"
#include "nsHTMLIIDs.h"
@@ -2008,16 +2009,11 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
PRBool isBlock =
nsLineLayout::TreatFrameAsBlock(kidDisplay, kidPosition);
-// XXX yikes! this has to be here because otherwise we bust...why?
-#if 1
- // See if the element wants to be floated
- if (NS_STYLE_FLOAT_NONE != kidDisplay->mFloats) {
- // Create a placeholder frame that will serve as the anchor point.
- nsPlaceholderFrame* placeholder =
- CreatePlaceholderFrame(aPresContext, frame);
-
- // Remove the floated element from the flow, and replace it with the
- // placeholder frame
+ // See if we need to move the frame outside of the flow, and insert in
+ // its place a placeholder frame
+ nsIFrame* placeholder;
+ if (MoveFrameOutOfFlow(aPresContext, frame, kidDisplay, kidPosition, placeholder)) {
+ // Remove 'frame' from the flow, and replace it with 'placeholder'
if (nsnull != prevFrame) {
prevFrame->SetNextSibling(placeholder);
}
@@ -2026,58 +2022,17 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
placeholder->SetNextSibling(nextSibling);
frame->SetNextSibling(nsnull);
- // If the floated element can contain children then wrap it in a
- // BODY frame before floating it
- nsIContent* content;
- PRBool isContainer;
-
- frame->GetContent(content);
- content->CanContainChildren(isContainer);
- if (isContainer) {
- // Wrap the floated element in a BODY frame.
- nsIFrame* wrapperFrame;
- NS_NewBodyFrame(content, this, wrapperFrame);
-
- // The body wrapper frame gets the original style context, and the floated
- // frame gets a pseudo style context
- nsIStyleContext* kidStyle;
- frame->GetStyleContext(&aPresContext, kidStyle);
- wrapperFrame->SetStyleContext(&aPresContext, kidStyle);
- NS_RELEASE(kidStyle);
-
- nsIStyleContext* pseudoStyle;
- pseudoStyle = aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::columnPseudo,
- wrapperFrame);
- frame->SetStyleContext(&aPresContext, pseudoStyle);
- NS_RELEASE(pseudoStyle);
-
- // Init the body frame
- wrapperFrame->Init(aPresContext, frame);
-
- // Bind the wrapper frame to the placeholder
- placeholder->SetAnchoredItem(wrapperFrame);
- }
- NS_RELEASE(content);
-
// The placeholder frame is always inline
frame = placeholder;
isBlock = PR_FALSE;
}
-#endif
- // XXX CONSTRUCTION See if it wants to be absolutely positioned or scrolled
- // if overflows...
+ // XXX CONSTRUCTION See if it wants to be scrolled if overflows...
#if 0
nsIFrame* kidFrame = nsnull;
nsresult rv;
- if (NS_STYLE_POSITION_ABSOLUTE == kidPosition->mPosition) {
- rv = nsAbsoluteFrame::NewFrame(&kidFrame, aKid, aParentFrame);
- if (NS_OK == rv) {
- kidFrame->SetStyleContext(aPresContext, kidSC);
- }
- }
- else if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
- (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
+ if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
+ (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
rv = NS_NewScrollFrame(&kidFrame, aKid, aParentFrame);
if (NS_OK == rv) {
kidFrame->SetStyleContext(aPresContext, kidSC);
@@ -3446,6 +3401,8 @@ nsBlockFrame::DrainOverflowLines()
return drained;
}
+// XXX This code doesn't handle floating elements or absolutely positioned
+// elements...
nsresult
nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame,
nsIFrame* aNewFrame,
diff --git a/layout/generic/nsHTMLContainerFrame.cpp b/layout/generic/nsHTMLContainerFrame.cpp
index 0e8be59e74e7..4031b89a1d02 100644
--- a/layout/generic/nsHTMLContainerFrame.cpp
+++ b/layout/generic/nsHTMLContainerFrame.cpp
@@ -160,6 +160,105 @@ nsHTMLContainerFrame::CreatePlaceholderFrame(nsIPresContext& aPresContext,
return placeholder;
}
+nsAbsoluteFrame*
+nsHTMLContainerFrame::CreateAbsolutePlaceholderFrame(nsIPresContext& aPresContext,
+ nsIFrame* aAbsoluteFrame)
+{
+ nsIContent* content;
+ aAbsoluteFrame->GetContent(content);
+
+ nsAbsoluteFrame* placeholder;
+ nsAbsoluteFrame::NewFrame((nsIFrame**)&placeholder, content, this, aAbsoluteFrame);
+ NS_IF_RELEASE(content);
+
+ // Let the placeholder share the same style context as the floated element
+ nsIStyleContext* kidSC;
+ aAbsoluteFrame->GetStyleContext(&aPresContext, kidSC);
+ placeholder->SetStyleContext(&aPresContext, kidSC);
+ NS_RELEASE(kidSC);
+
+ return placeholder;
+}
+
+PRBool
+nsHTMLContainerFrame::CreateWrapperFrame(nsIPresContext& aPresContext,
+ nsIFrame* aFrame,
+ nsIFrame*& aWrapperFrame)
+{
+ // If the floated element can contain children then wrap it in a
+ // BODY frame before floating it
+ nsIContent* content;
+ PRBool isContainer;
+
+ aFrame->GetContent(content);
+ content->CanContainChildren(isContainer);
+ if (isContainer) {
+ // Wrap the floated element in a BODY frame.
+ NS_NewBodyFrame(content, this, aWrapperFrame);
+
+ // The body wrapper frame gets the original style context, and the floated
+ // frame gets a pseudo style context
+ nsIStyleContext* kidStyle;
+ aFrame->GetStyleContext(&aPresContext, kidStyle);
+ aWrapperFrame->SetStyleContext(&aPresContext, kidStyle);
+ NS_RELEASE(kidStyle);
+
+ nsIStyleContext* pseudoStyle;
+ pseudoStyle = aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::columnPseudo,
+ aWrapperFrame);
+ aFrame->SetStyleContext(&aPresContext, pseudoStyle);
+ NS_RELEASE(pseudoStyle);
+
+ // Init the body frame
+ aWrapperFrame->Init(aPresContext, aFrame);
+ }
+
+ NS_RELEASE(content);
+ return isContainer;
+}
+
+PRBool
+nsHTMLContainerFrame::MoveFrameOutOfFlow(nsIPresContext& aPresContext,
+ nsIFrame* aFrame,
+ const nsStyleDisplay* aDisplay,
+ const nsStylePosition* aPosition,
+ nsIFrame*& aPlaceholderFrame)
+{
+ aPlaceholderFrame = nsnull;
+
+ // See if the element wants to be floated or absolutely positioned
+ if (NS_STYLE_FLOAT_NONE != aDisplay->mFloats) {
+ // Create a placeholder frame that will serve as the anchor point.
+ nsPlaceholderFrame* placeholder =
+ CreatePlaceholderFrame(aPresContext, aFrame);
+
+ // See if we need to wrap the frame in a BODY frame
+ nsIFrame* wrapperFrame;
+ if (CreateWrapperFrame(aPresContext, aFrame, wrapperFrame)) {
+ // Bind the wrapper frame to the placeholder
+ placeholder->SetAnchoredItem(wrapperFrame);
+ }
+
+ aPlaceholderFrame = placeholder;
+
+ } else if (NS_STYLE_POSITION_ABSOLUTE == aPosition->mPosition) {
+ // Create a placeholder frame that will serve as the anchor point.
+ nsAbsoluteFrame* placeholder =
+ CreateAbsolutePlaceholderFrame(aPresContext, aFrame);
+
+ // See if we need to wrap the frame in a BODY frame
+ nsIFrame* wrapperFrame;
+ if (CreateWrapperFrame(aPresContext, aFrame, wrapperFrame)) {
+ // Bind the wrapper frame to the placeholder
+ placeholder->SetAbsoluteFrame(wrapperFrame);
+ }
+
+ aPlaceholderFrame = placeholder;
+ }
+
+ return aPlaceholderFrame != nsnull;
+}
+
/**
* Create a next-in-flow for aFrame. Will return the newly created
* frame in aNextInFlowResult if and only if a new frame is
diff --git a/layout/generic/nsHTMLContainerFrame.h b/layout/generic/nsHTMLContainerFrame.h
index f7b3241f985b..aaf21664fb34 100644
--- a/layout/generic/nsHTMLContainerFrame.h
+++ b/layout/generic/nsHTMLContainerFrame.h
@@ -20,7 +20,10 @@
#include "nsContainerFrame.h"
class nsString;
+class nsAbsoluteFrame;
class nsPlaceholderFrame;
+struct nsStyleDisplay;
+struct nsStylePosition;
// Base class for html container frames that provides common
// functionality.
@@ -51,6 +54,17 @@ public:
nsPlaceholderFrame* CreatePlaceholderFrame(nsIPresContext& aPresContext,
nsIFrame* aFloatedFrame);
+ nsAbsoluteFrame* CreateAbsolutePlaceholderFrame(nsIPresContext& aPresContext,
+ nsIFrame* aAbsoluteFrame);
+ PRBool CreateWrapperFrame(nsIPresContext& aPresContext,
+ nsIFrame* aFrame,
+ nsIFrame*& aWrapperFrame);
+
+ PRBool MoveFrameOutOfFlow(nsIPresContext& aPresContext,
+ nsIFrame* aFrame,
+ const nsStyleDisplay* aDisplay,
+ const nsStylePosition* aPosition,
+ nsIFrame*& aPlaceholderFrame);
// Helper method to create next-in-flows if necessary
static nsresult CreateNextInFlow(nsIPresContext& aPresContext,
diff --git a/layout/html/base/src/nsAbsoluteFrame.cpp b/layout/html/base/src/nsAbsoluteFrame.cpp
index 77441c4a81a3..8bfe9d5b57cf 100644
--- a/layout/html/base/src/nsAbsoluteFrame.cpp
+++ b/layout/html/base/src/nsAbsoluteFrame.cpp
@@ -25,13 +25,14 @@
nsresult
nsAbsoluteFrame::NewFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent,
- nsIFrame* aParent)
+ nsIFrame* aParent,
+ nsIFrame* aAbsoluteFrame)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
- nsIFrame* it = new nsAbsoluteFrame(aContent, aParent);
+ nsIFrame* it = new nsAbsoluteFrame(aContent, aParent, aAbsoluteFrame);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
@@ -39,9 +40,12 @@ nsAbsoluteFrame::NewFrame(nsIFrame** aInstancePtrResult,
return NS_OK;
}
-nsAbsoluteFrame::nsAbsoluteFrame(nsIContent* aContent, nsIFrame* aParent)
+nsAbsoluteFrame::nsAbsoluteFrame(nsIContent* aContent,
+ nsIFrame* aParent,
+ nsIFrame* aAbsoluteFrame)
: nsFrame(aContent, aParent)
{
+ mFrame = aAbsoluteFrame;
}
nsAbsoluteFrame::~nsAbsoluteFrame()
@@ -53,31 +57,10 @@ NS_IMETHODIMP nsAbsoluteFrame::Reflow(nsIPresContext& aPresContext,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
- // Have we created the absolutely positioned item yet?
- if (nsnull == mFrame) {
- // If the content object is a container then wrap it in a body pseudo-frame
- PRBool canHaveKids;
- mContent->CanContainChildren(canHaveKids);
- if (canHaveKids) {
- nsBodyFrame::NewFrame(&mFrame, mContent, this);
-
- // Use our style context for the pseudo-frame
- mFrame->SetStyleContext(&aPresContext, mStyleContext);
-
- } else {
- // XXX CONSTRUCTION
-#if 0
- // Ask the content delegate to create the frame
- nsIContentDelegate* delegate = mContent->GetDelegate(&aPresContext);
-
- nsresult rv = delegate->CreateFrame(&aPresContext, mContent, this,
- mStyleContext, mFrame);
- NS_RELEASE(delegate);
- if (NS_OK != rv) {
- return rv;
- }
-#endif
- }
+ if (eReflowReason_Initial == aReflowState.reason) {
+ // By this point we expect to have been told which absolute frame we're
+ // associated with
+ NS_ASSERTION(nsnull != mFrame, "no absolute frame");
// Get the containing block
nsIFrame* containingBlock = GetContainingBlock();
diff --git a/layout/html/base/src/nsAbsoluteFrame.h b/layout/html/base/src/nsAbsoluteFrame.h
index 90ded94b3ff6..ece43bdce50e 100644
--- a/layout/html/base/src/nsAbsoluteFrame.h
+++ b/layout/html/base/src/nsAbsoluteFrame.h
@@ -32,10 +32,12 @@ public:
*/
static nsresult NewFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent,
- nsIFrame* aParent);
+ nsIFrame* aParent,
+ nsIFrame* aAbsoluteFrame = nsnull);
// Returns the associated anchored item
nsIFrame* GetAbsoluteFrame() const {return mFrame;}
+ void SetAbsoluteFrame(nsIFrame* aAbsoluteFrame) {mFrame = aAbsoluteFrame;}
// nsIFrame overrides
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
@@ -55,7 +57,7 @@ protected:
// Constructor. Takes as arguments the content object, the index in parent,
// and the Frame for the content parent
- nsAbsoluteFrame(nsIContent* aContent, nsIFrame* aParent);
+ nsAbsoluteFrame(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aAbsoluteFrame);
virtual ~nsAbsoluteFrame();
diff --git a/layout/html/base/src/nsBlockFrame.cpp b/layout/html/base/src/nsBlockFrame.cpp
index c0b46665c6a7..c846ff664103 100644
--- a/layout/html/base/src/nsBlockFrame.cpp
+++ b/layout/html/base/src/nsBlockFrame.cpp
@@ -21,6 +21,7 @@
#include "nsLineLayout.h"
#include "nsInlineReflow.h"
#include "nsCSSLayout.h"
+#include "nsAbsoluteFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsStyleConsts.h"
#include "nsHTMLIIDs.h"
@@ -2008,16 +2009,11 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
PRBool isBlock =
nsLineLayout::TreatFrameAsBlock(kidDisplay, kidPosition);
-// XXX yikes! this has to be here because otherwise we bust...why?
-#if 1
- // See if the element wants to be floated
- if (NS_STYLE_FLOAT_NONE != kidDisplay->mFloats) {
- // Create a placeholder frame that will serve as the anchor point.
- nsPlaceholderFrame* placeholder =
- CreatePlaceholderFrame(aPresContext, frame);
-
- // Remove the floated element from the flow, and replace it with the
- // placeholder frame
+ // See if we need to move the frame outside of the flow, and insert in
+ // its place a placeholder frame
+ nsIFrame* placeholder;
+ if (MoveFrameOutOfFlow(aPresContext, frame, kidDisplay, kidPosition, placeholder)) {
+ // Remove 'frame' from the flow, and replace it with 'placeholder'
if (nsnull != prevFrame) {
prevFrame->SetNextSibling(placeholder);
}
@@ -2026,58 +2022,17 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
placeholder->SetNextSibling(nextSibling);
frame->SetNextSibling(nsnull);
- // If the floated element can contain children then wrap it in a
- // BODY frame before floating it
- nsIContent* content;
- PRBool isContainer;
-
- frame->GetContent(content);
- content->CanContainChildren(isContainer);
- if (isContainer) {
- // Wrap the floated element in a BODY frame.
- nsIFrame* wrapperFrame;
- NS_NewBodyFrame(content, this, wrapperFrame);
-
- // The body wrapper frame gets the original style context, and the floated
- // frame gets a pseudo style context
- nsIStyleContext* kidStyle;
- frame->GetStyleContext(&aPresContext, kidStyle);
- wrapperFrame->SetStyleContext(&aPresContext, kidStyle);
- NS_RELEASE(kidStyle);
-
- nsIStyleContext* pseudoStyle;
- pseudoStyle = aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::columnPseudo,
- wrapperFrame);
- frame->SetStyleContext(&aPresContext, pseudoStyle);
- NS_RELEASE(pseudoStyle);
-
- // Init the body frame
- wrapperFrame->Init(aPresContext, frame);
-
- // Bind the wrapper frame to the placeholder
- placeholder->SetAnchoredItem(wrapperFrame);
- }
- NS_RELEASE(content);
-
// The placeholder frame is always inline
frame = placeholder;
isBlock = PR_FALSE;
}
-#endif
- // XXX CONSTRUCTION See if it wants to be absolutely positioned or scrolled
- // if overflows...
+ // XXX CONSTRUCTION See if it wants to be scrolled if overflows...
#if 0
nsIFrame* kidFrame = nsnull;
nsresult rv;
- if (NS_STYLE_POSITION_ABSOLUTE == kidPosition->mPosition) {
- rv = nsAbsoluteFrame::NewFrame(&kidFrame, aKid, aParentFrame);
- if (NS_OK == rv) {
- kidFrame->SetStyleContext(aPresContext, kidSC);
- }
- }
- else if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
- (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
+ if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
+ (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
rv = NS_NewScrollFrame(&kidFrame, aKid, aParentFrame);
if (NS_OK == rv) {
kidFrame->SetStyleContext(aPresContext, kidSC);
@@ -3446,6 +3401,8 @@ nsBlockFrame::DrainOverflowLines()
return drained;
}
+// XXX This code doesn't handle floating elements or absolutely positioned
+// elements...
nsresult
nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame,
nsIFrame* aNewFrame,
diff --git a/layout/html/base/src/nsBlockReflowState.cpp b/layout/html/base/src/nsBlockReflowState.cpp
index c0b46665c6a7..c846ff664103 100644
--- a/layout/html/base/src/nsBlockReflowState.cpp
+++ b/layout/html/base/src/nsBlockReflowState.cpp
@@ -21,6 +21,7 @@
#include "nsLineLayout.h"
#include "nsInlineReflow.h"
#include "nsCSSLayout.h"
+#include "nsAbsoluteFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsStyleConsts.h"
#include "nsHTMLIIDs.h"
@@ -2008,16 +2009,11 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
PRBool isBlock =
nsLineLayout::TreatFrameAsBlock(kidDisplay, kidPosition);
-// XXX yikes! this has to be here because otherwise we bust...why?
-#if 1
- // See if the element wants to be floated
- if (NS_STYLE_FLOAT_NONE != kidDisplay->mFloats) {
- // Create a placeholder frame that will serve as the anchor point.
- nsPlaceholderFrame* placeholder =
- CreatePlaceholderFrame(aPresContext, frame);
-
- // Remove the floated element from the flow, and replace it with the
- // placeholder frame
+ // See if we need to move the frame outside of the flow, and insert in
+ // its place a placeholder frame
+ nsIFrame* placeholder;
+ if (MoveFrameOutOfFlow(aPresContext, frame, kidDisplay, kidPosition, placeholder)) {
+ // Remove 'frame' from the flow, and replace it with 'placeholder'
if (nsnull != prevFrame) {
prevFrame->SetNextSibling(placeholder);
}
@@ -2026,58 +2022,17 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
placeholder->SetNextSibling(nextSibling);
frame->SetNextSibling(nsnull);
- // If the floated element can contain children then wrap it in a
- // BODY frame before floating it
- nsIContent* content;
- PRBool isContainer;
-
- frame->GetContent(content);
- content->CanContainChildren(isContainer);
- if (isContainer) {
- // Wrap the floated element in a BODY frame.
- nsIFrame* wrapperFrame;
- NS_NewBodyFrame(content, this, wrapperFrame);
-
- // The body wrapper frame gets the original style context, and the floated
- // frame gets a pseudo style context
- nsIStyleContext* kidStyle;
- frame->GetStyleContext(&aPresContext, kidStyle);
- wrapperFrame->SetStyleContext(&aPresContext, kidStyle);
- NS_RELEASE(kidStyle);
-
- nsIStyleContext* pseudoStyle;
- pseudoStyle = aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::columnPseudo,
- wrapperFrame);
- frame->SetStyleContext(&aPresContext, pseudoStyle);
- NS_RELEASE(pseudoStyle);
-
- // Init the body frame
- wrapperFrame->Init(aPresContext, frame);
-
- // Bind the wrapper frame to the placeholder
- placeholder->SetAnchoredItem(wrapperFrame);
- }
- NS_RELEASE(content);
-
// The placeholder frame is always inline
frame = placeholder;
isBlock = PR_FALSE;
}
-#endif
- // XXX CONSTRUCTION See if it wants to be absolutely positioned or scrolled
- // if overflows...
+ // XXX CONSTRUCTION See if it wants to be scrolled if overflows...
#if 0
nsIFrame* kidFrame = nsnull;
nsresult rv;
- if (NS_STYLE_POSITION_ABSOLUTE == kidPosition->mPosition) {
- rv = nsAbsoluteFrame::NewFrame(&kidFrame, aKid, aParentFrame);
- if (NS_OK == rv) {
- kidFrame->SetStyleContext(aPresContext, kidSC);
- }
- }
- else if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
- (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
+ if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
+ (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
rv = NS_NewScrollFrame(&kidFrame, aKid, aParentFrame);
if (NS_OK == rv) {
kidFrame->SetStyleContext(aPresContext, kidSC);
@@ -3446,6 +3401,8 @@ nsBlockFrame::DrainOverflowLines()
return drained;
}
+// XXX This code doesn't handle floating elements or absolutely positioned
+// elements...
nsresult
nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame,
nsIFrame* aNewFrame,
diff --git a/layout/html/base/src/nsBlockReflowState.h b/layout/html/base/src/nsBlockReflowState.h
index c0b46665c6a7..c846ff664103 100644
--- a/layout/html/base/src/nsBlockReflowState.h
+++ b/layout/html/base/src/nsBlockReflowState.h
@@ -21,6 +21,7 @@
#include "nsLineLayout.h"
#include "nsInlineReflow.h"
#include "nsCSSLayout.h"
+#include "nsAbsoluteFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsStyleConsts.h"
#include "nsHTMLIIDs.h"
@@ -2008,16 +2009,11 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
PRBool isBlock =
nsLineLayout::TreatFrameAsBlock(kidDisplay, kidPosition);
-// XXX yikes! this has to be here because otherwise we bust...why?
-#if 1
- // See if the element wants to be floated
- if (NS_STYLE_FLOAT_NONE != kidDisplay->mFloats) {
- // Create a placeholder frame that will serve as the anchor point.
- nsPlaceholderFrame* placeholder =
- CreatePlaceholderFrame(aPresContext, frame);
-
- // Remove the floated element from the flow, and replace it with the
- // placeholder frame
+ // See if we need to move the frame outside of the flow, and insert in
+ // its place a placeholder frame
+ nsIFrame* placeholder;
+ if (MoveFrameOutOfFlow(aPresContext, frame, kidDisplay, kidPosition, placeholder)) {
+ // Remove 'frame' from the flow, and replace it with 'placeholder'
if (nsnull != prevFrame) {
prevFrame->SetNextSibling(placeholder);
}
@@ -2026,58 +2022,17 @@ nsBlockFrame::AppendNewFrames(nsIPresContext& aPresContext,
placeholder->SetNextSibling(nextSibling);
frame->SetNextSibling(nsnull);
- // If the floated element can contain children then wrap it in a
- // BODY frame before floating it
- nsIContent* content;
- PRBool isContainer;
-
- frame->GetContent(content);
- content->CanContainChildren(isContainer);
- if (isContainer) {
- // Wrap the floated element in a BODY frame.
- nsIFrame* wrapperFrame;
- NS_NewBodyFrame(content, this, wrapperFrame);
-
- // The body wrapper frame gets the original style context, and the floated
- // frame gets a pseudo style context
- nsIStyleContext* kidStyle;
- frame->GetStyleContext(&aPresContext, kidStyle);
- wrapperFrame->SetStyleContext(&aPresContext, kidStyle);
- NS_RELEASE(kidStyle);
-
- nsIStyleContext* pseudoStyle;
- pseudoStyle = aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::columnPseudo,
- wrapperFrame);
- frame->SetStyleContext(&aPresContext, pseudoStyle);
- NS_RELEASE(pseudoStyle);
-
- // Init the body frame
- wrapperFrame->Init(aPresContext, frame);
-
- // Bind the wrapper frame to the placeholder
- placeholder->SetAnchoredItem(wrapperFrame);
- }
- NS_RELEASE(content);
-
// The placeholder frame is always inline
frame = placeholder;
isBlock = PR_FALSE;
}
-#endif
- // XXX CONSTRUCTION See if it wants to be absolutely positioned or scrolled
- // if overflows...
+ // XXX CONSTRUCTION See if it wants to be scrolled if overflows...
#if 0
nsIFrame* kidFrame = nsnull;
nsresult rv;
- if (NS_STYLE_POSITION_ABSOLUTE == kidPosition->mPosition) {
- rv = nsAbsoluteFrame::NewFrame(&kidFrame, aKid, aParentFrame);
- if (NS_OK == rv) {
- kidFrame->SetStyleContext(aPresContext, kidSC);
- }
- }
- else if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
- (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
+ if ((NS_STYLE_OVERFLOW_SCROLL == kidDisplay->mOverflow) ||
+ (NS_STYLE_OVERFLOW_AUTO == kidDisplay->mOverflow)) {
rv = NS_NewScrollFrame(&kidFrame, aKid, aParentFrame);
if (NS_OK == rv) {
kidFrame->SetStyleContext(aPresContext, kidSC);
@@ -3446,6 +3401,8 @@ nsBlockFrame::DrainOverflowLines()
return drained;
}
+// XXX This code doesn't handle floating elements or absolutely positioned
+// elements...
nsresult
nsBlockFrame::InsertNewFrame(nsBlockFrame* aParentFrame,
nsIFrame* aNewFrame,
diff --git a/layout/html/base/src/nsHTMLContainerFrame.cpp b/layout/html/base/src/nsHTMLContainerFrame.cpp
index 0e8be59e74e7..4031b89a1d02 100644
--- a/layout/html/base/src/nsHTMLContainerFrame.cpp
+++ b/layout/html/base/src/nsHTMLContainerFrame.cpp
@@ -160,6 +160,105 @@ nsHTMLContainerFrame::CreatePlaceholderFrame(nsIPresContext& aPresContext,
return placeholder;
}
+nsAbsoluteFrame*
+nsHTMLContainerFrame::CreateAbsolutePlaceholderFrame(nsIPresContext& aPresContext,
+ nsIFrame* aAbsoluteFrame)
+{
+ nsIContent* content;
+ aAbsoluteFrame->GetContent(content);
+
+ nsAbsoluteFrame* placeholder;
+ nsAbsoluteFrame::NewFrame((nsIFrame**)&placeholder, content, this, aAbsoluteFrame);
+ NS_IF_RELEASE(content);
+
+ // Let the placeholder share the same style context as the floated element
+ nsIStyleContext* kidSC;
+ aAbsoluteFrame->GetStyleContext(&aPresContext, kidSC);
+ placeholder->SetStyleContext(&aPresContext, kidSC);
+ NS_RELEASE(kidSC);
+
+ return placeholder;
+}
+
+PRBool
+nsHTMLContainerFrame::CreateWrapperFrame(nsIPresContext& aPresContext,
+ nsIFrame* aFrame,
+ nsIFrame*& aWrapperFrame)
+{
+ // If the floated element can contain children then wrap it in a
+ // BODY frame before floating it
+ nsIContent* content;
+ PRBool isContainer;
+
+ aFrame->GetContent(content);
+ content->CanContainChildren(isContainer);
+ if (isContainer) {
+ // Wrap the floated element in a BODY frame.
+ NS_NewBodyFrame(content, this, aWrapperFrame);
+
+ // The body wrapper frame gets the original style context, and the floated
+ // frame gets a pseudo style context
+ nsIStyleContext* kidStyle;
+ aFrame->GetStyleContext(&aPresContext, kidStyle);
+ aWrapperFrame->SetStyleContext(&aPresContext, kidStyle);
+ NS_RELEASE(kidStyle);
+
+ nsIStyleContext* pseudoStyle;
+ pseudoStyle = aPresContext.ResolvePseudoStyleContextFor(nsHTMLAtoms::columnPseudo,
+ aWrapperFrame);
+ aFrame->SetStyleContext(&aPresContext, pseudoStyle);
+ NS_RELEASE(pseudoStyle);
+
+ // Init the body frame
+ aWrapperFrame->Init(aPresContext, aFrame);
+ }
+
+ NS_RELEASE(content);
+ return isContainer;
+}
+
+PRBool
+nsHTMLContainerFrame::MoveFrameOutOfFlow(nsIPresContext& aPresContext,
+ nsIFrame* aFrame,
+ const nsStyleDisplay* aDisplay,
+ const nsStylePosition* aPosition,
+ nsIFrame*& aPlaceholderFrame)
+{
+ aPlaceholderFrame = nsnull;
+
+ // See if the element wants to be floated or absolutely positioned
+ if (NS_STYLE_FLOAT_NONE != aDisplay->mFloats) {
+ // Create a placeholder frame that will serve as the anchor point.
+ nsPlaceholderFrame* placeholder =
+ CreatePlaceholderFrame(aPresContext, aFrame);
+
+ // See if we need to wrap the frame in a BODY frame
+ nsIFrame* wrapperFrame;
+ if (CreateWrapperFrame(aPresContext, aFrame, wrapperFrame)) {
+ // Bind the wrapper frame to the placeholder
+ placeholder->SetAnchoredItem(wrapperFrame);
+ }
+
+ aPlaceholderFrame = placeholder;
+
+ } else if (NS_STYLE_POSITION_ABSOLUTE == aPosition->mPosition) {
+ // Create a placeholder frame that will serve as the anchor point.
+ nsAbsoluteFrame* placeholder =
+ CreateAbsolutePlaceholderFrame(aPresContext, aFrame);
+
+ // See if we need to wrap the frame in a BODY frame
+ nsIFrame* wrapperFrame;
+ if (CreateWrapperFrame(aPresContext, aFrame, wrapperFrame)) {
+ // Bind the wrapper frame to the placeholder
+ placeholder->SetAbsoluteFrame(wrapperFrame);
+ }
+
+ aPlaceholderFrame = placeholder;
+ }
+
+ return aPlaceholderFrame != nsnull;
+}
+
/**
* Create a next-in-flow for aFrame. Will return the newly created
* frame in aNextInFlowResult if and only if a new frame is
diff --git a/layout/html/base/src/nsHTMLContainerFrame.h b/layout/html/base/src/nsHTMLContainerFrame.h
index f7b3241f985b..aaf21664fb34 100644
--- a/layout/html/base/src/nsHTMLContainerFrame.h
+++ b/layout/html/base/src/nsHTMLContainerFrame.h
@@ -20,7 +20,10 @@
#include "nsContainerFrame.h"
class nsString;
+class nsAbsoluteFrame;
class nsPlaceholderFrame;
+struct nsStyleDisplay;
+struct nsStylePosition;
// Base class for html container frames that provides common
// functionality.
@@ -51,6 +54,17 @@ public:
nsPlaceholderFrame* CreatePlaceholderFrame(nsIPresContext& aPresContext,
nsIFrame* aFloatedFrame);
+ nsAbsoluteFrame* CreateAbsolutePlaceholderFrame(nsIPresContext& aPresContext,
+ nsIFrame* aAbsoluteFrame);
+ PRBool CreateWrapperFrame(nsIPresContext& aPresContext,
+ nsIFrame* aFrame,
+ nsIFrame*& aWrapperFrame);
+
+ PRBool MoveFrameOutOfFlow(nsIPresContext& aPresContext,
+ nsIFrame* aFrame,
+ const nsStyleDisplay* aDisplay,
+ const nsStylePosition* aPosition,
+ nsIFrame*& aPlaceholderFrame);
// Helper method to create next-in-flows if necessary
static nsresult CreateNextInFlow(nsIPresContext& aPresContext,