diff --git a/mozilla/layout/generic/nsHTMLContainerFrame.cpp b/mozilla/layout/generic/nsHTMLContainerFrame.cpp
index bf2877f5c30..e000ca9ea7a 100644
--- a/mozilla/layout/generic/nsHTMLContainerFrame.cpp
+++ b/mozilla/layout/generic/nsHTMLContainerFrame.cpp
@@ -31,9 +31,17 @@
#include "nsIDocument.h"
#include "nsIURL.h"
#include "nsReflowCommand.h"
+#include "nsIPtr.h"
+#include "nsAbsoluteFrame.h"
+#include "nsPlaceholderFrame.h"
+#include "nsIContentDelegate.h"
static NS_DEFINE_IID(kStyleBorderSID, NS_STYLEBORDER_SID);
static NS_DEFINE_IID(kStyleColorSID, NS_STYLECOLOR_SID);
+static NS_DEFINE_IID(kStylePositionSID, NS_STYLEPOSITION_SID);
+static NS_DEFINE_IID(kStyleDisplaySID, NS_STYLEDISPLAY_SID);
+
+NS_DEF_PTR(nsIStyleContext);
nsHTMLContainerFrame::nsHTMLContainerFrame(nsIContent* aContent,
PRInt32 aIndexInParent,
@@ -235,6 +243,38 @@ static void AdjustIndexInParents(nsIFrame* aContainerFrame,
}
}
+nsIFrame* nsHTMLContainerFrame::CreateFrameFor(nsIPresContext* aPresContext,
+ nsIContent* aContent,
+ PRInt32 aIndexInParent)
+{
+ // Get the style content for the frame
+ nsIStyleContextPtr styleContext = aPresContext->ResolveStyleContextFor(aContent, this);
+ nsStylePosition* position = (nsStylePosition*)styleContext->GetData(kStylePositionSID);
+ nsStyleDisplay* display = (nsStyleDisplay*)styleContext->GetData(kStyleDisplaySID);
+ nsIFrame* result;
+
+ // See whether it wants any special handling
+ if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) {
+ AbsoluteFrame::NewFrame(&result, aContent, aIndexInParent, this);
+ } else if (display->mFloats != NS_STYLE_FLOAT_NONE) {
+ PlaceholderFrame::NewFrame(&result, aContent, aIndexInParent, this);
+ } else if (NS_STYLE_DISPLAY_NONE == display->mDisplay) {
+ nsFrame::NewFrame(&result, aContent, aIndexInParent, this);
+ } else {
+ nsIContentDelegate* delegate;
+
+ // Ask the content delegate to create the frame
+ // XXX The delegate will also resolve the style context...
+ delegate = aContent->GetDelegate(aPresContext);
+ result = delegate->CreateFrame(aPresContext, aContent, aIndexInParent, this);
+ NS_RELEASE(delegate);
+ }
+
+ // Set the frame's style context
+ result->SetStyleContext(aPresContext, styleContext);
+ return result;
+}
+
NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer,
@@ -263,6 +303,69 @@ NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell,
frame->GetNextInFlow((nsIFrame*&)frame);
}
+ // Find the frame that precedes this frame
+ nsIFrame* prevSibling = nsnull;
+
+ if (aIndexInParent > 0) {
+ nsIContent* precedingContent = aContainer->ChildAt(aIndexInParent - 1);
+ prevSibling = aShell->FindFrameWithContent(precedingContent);
+ NS_RELEASE(precedingContent);
+
+ // The frame may have a next-in-flow. Get the last-in-flow
+ nsIFrame* nextInFlow;
+ do {
+ prevSibling->GetNextInFlow(nextInFlow);
+ if (nsnull != nextInFlow) {
+ prevSibling = nextInFlow;
+ }
+ } while (nsnull != nextInFlow);
+ }
+
+ // Get the geometric parent. We expect it to be this frame or one of its
+ // next-in-flow(s). It could be a pseudo-frame, but then it better also be
+ // a nsHTMLContainerFrame...
+ nsHTMLContainerFrame* parent = this;
+
+ if (nsnull != prevSibling) {
+ prevSibling->GetGeometricParent((nsIFrame*&)parent);
+ }
+
+ // Create the new frame
+ nsIFrame* newFrame = parent->CreateFrameFor(aPresContext, aChild, aIndexInParent);
+
+ // Insert the frame
+ if (nsnull == prevSibling) {
+ // If there's no preceding frame, then this is the first content child
+ NS_ASSERTION(0 == aIndexInParent, "unexpected index-in-parent");
+ NS_ASSERTION(0 == parent->mFirstContentOffset, "unexpected first content offset");
+ newFrame->SetNextSibling(parent->mFirstChild);
+ parent->mFirstChild = newFrame;
+
+ } else {
+ nsIFrame* nextSibling;
+
+ // Link the new frame into
+ prevSibling->GetNextSibling(nextSibling);
+ newFrame->SetNextSibling(nextSibling);
+ prevSibling->SetNextSibling(newFrame);
+
+ if (nsnull == nextSibling) {
+ // The new frame is the last child frame
+ parent->SetLastContentOffset(newFrame);
+
+ if (parent->IsPseudoFrame()) {
+ parent->PropagateContentOffsets();
+ }
+ }
+ }
+ parent->mChildCount++;
+
+ // Generate a reflow command
+ nsReflowCommand* cmd = new nsReflowCommand(aPresContext, parent,
+ nsReflowCommand::FrameAppended,
+ newFrame);
+ aShell->AppendReflowCommand(cmd);
+
return NS_OK;
}
diff --git a/mozilla/layout/generic/nsHTMLContainerFrame.h b/mozilla/layout/generic/nsHTMLContainerFrame.h
index 627803cd997..c126f8711f7 100644
--- a/mozilla/layout/generic/nsHTMLContainerFrame.h
+++ b/mozilla/layout/generic/nsHTMLContainerFrame.h
@@ -61,6 +61,10 @@ protected:
const nsString& aBase,
const nsString& aURLSpec,
const nsString& aTargetSpec);
+
+ nsIFrame* CreateFrameFor(nsIPresContext* aPresContext,
+ nsIContent* aContent,
+ PRInt32 aIndexInParent);
};
#endif /* nsHTMLContainerFrame_h___ */
diff --git a/mozilla/layout/generic/nsPlaceholderFrame.cpp b/mozilla/layout/generic/nsPlaceholderFrame.cpp
index bd545e2068a..8a056b9c8c5 100644
--- a/mozilla/layout/generic/nsPlaceholderFrame.cpp
+++ b/mozilla/layout/generic/nsPlaceholderFrame.cpp
@@ -52,6 +52,15 @@ PlaceholderFrame::~PlaceholderFrame()
{
}
+NS_METHOD PlaceholderFrame::SetIndexInParent(PRInt32 aIndexInParent)
+{
+ if (nsnull != mAnchoredItem) {
+ mAnchoredItem->SetIndexInParent(aIndexInParent);
+ }
+
+ return nsFrame::SetIndexInParent(aIndexInParent);
+}
+
NS_METHOD PlaceholderFrame::ResizeReflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsSize& aMaxSize,
diff --git a/mozilla/layout/generic/nsPlaceholderFrame.h b/mozilla/layout/generic/nsPlaceholderFrame.h
index 6cae7e1c546..9f4d5a68a51 100644
--- a/mozilla/layout/generic/nsPlaceholderFrame.h
+++ b/mozilla/layout/generic/nsPlaceholderFrame.h
@@ -35,6 +35,8 @@ public:
// Returns the associated anchored item
nsIFrame* GetAnchoredItem() const {return mAnchoredItem;}
+ NS_IMETHOD SetIndexInParent(PRInt32 aIndexInParent);
+
// Resize reflow methods
NS_IMETHOD ResizeReflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
diff --git a/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp b/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp
index b9db91ad097..fbb9d22fc14 100644
--- a/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp
+++ b/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp
@@ -63,6 +63,15 @@ AbsoluteFrame::~AbsoluteFrame()
{
}
+NS_METHOD AbsoluteFrame::SetIndexInParent(PRInt32 aIndexInParent)
+{
+ if (nsnull != mFrame) {
+ mFrame->SetIndexInParent(aIndexInParent);
+ }
+
+ return nsFrame::SetIndexInParent(aIndexInParent);
+}
+
nsIView* AbsoluteFrame::CreateView(nsIView* aContainingView,
const nsRect& aRect,
nsStylePosition* aPosition)
@@ -101,8 +110,7 @@ nsIView* AbsoluteFrame::CreateView(nsIView* aContainingView,
if (aPosition->mZIndex.GetUnit() == eStyleUnit_Integer) {
zIndex = aPosition->mZIndex.GetIntValue();
} else if (aPosition->mZIndex.GetUnit() == eStyleUnit_Auto) {
- // XXX need to handle z-index "auto"
- NS_NOTYETIMPLEMENTED("zIndex: auto");
+ zIndex = 0;
} else if (aPosition->mZIndex.GetUnit() == eStyleUnit_Inherit) {
// XXX need to handle z-index "inherit"
NS_NOTYETIMPLEMENTED("zIndex: inherit");
diff --git a/mozilla/layout/html/base/src/nsAbsoluteFrame.h b/mozilla/layout/html/base/src/nsAbsoluteFrame.h
index 7046de8b6b3..2f410a11ce5 100644
--- a/mozilla/layout/html/base/src/nsAbsoluteFrame.h
+++ b/mozilla/layout/html/base/src/nsAbsoluteFrame.h
@@ -33,6 +33,8 @@ public:
PRInt32 aIndexInParent,
nsIFrame* aParent);
+ NS_IMETHOD SetIndexInParent(PRInt32 aIndexInParent);
+
// Resize reflow methods
NS_IMETHOD ResizeReflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
diff --git a/mozilla/layout/html/base/src/nsBodyFrame.cpp b/mozilla/layout/html/base/src/nsBodyFrame.cpp
index 1051b08b8ef..a5ea8976987 100644
--- a/mozilla/layout/html/base/src/nsBodyFrame.cpp
+++ b/mozilla/layout/html/base/src/nsBodyFrame.cpp
@@ -200,8 +200,7 @@ NS_METHOD nsBodyFrame::ResizeReflow(nsIPresContext* aPresContext,
aDesiredSize.height = PR_MAX(desiredRect.YMost(), mSpaceManager->YMost());
if (isPseudoFrame) {
aDesiredSize.width = desiredRect.XMost();
- }
- else {
+ } else {
aDesiredSize.width = aMaxSize.width;
aDesiredSize.height += mySpacing->mBorderPadding.top +
mySpacing->mBorderPadding.bottom;
@@ -275,7 +274,9 @@ NS_METHOD nsBodyFrame::IncrementalReflow(nsIPresContext* aPresContext,
// XXX Clear the list of regions. This fixes a problem with the way reflow
// appended is currently working (we're reflowing some framems twice)
- mSpaceManager->ClearRegions();
+ if (nsReflowCommand::FrameAppended == aReflowCommand.GetType()) {
+ mSpaceManager->ClearRegions();
+ }
mSpaceManager->Translate(leftInset, topInset);
// The reflow command should never be target for us
@@ -307,8 +308,7 @@ NS_METHOD nsBodyFrame::IncrementalReflow(nsIPresContext* aPresContext,
aDesiredSize.height = PR_MAX(aDesiredRect.YMost(), mSpaceManager->YMost());
if (isPseudoFrame) {
aDesiredSize.width = aDesiredRect.XMost();
- }
- else {
+ } else {
aDesiredSize.width = aMaxSize.width;
aDesiredSize.height += mySpacing->mBorderPadding.top +
mySpacing->mBorderPadding.bottom;
diff --git a/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp b/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp
index bf2877f5c30..e000ca9ea7a 100644
--- a/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp
+++ b/mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp
@@ -31,9 +31,17 @@
#include "nsIDocument.h"
#include "nsIURL.h"
#include "nsReflowCommand.h"
+#include "nsIPtr.h"
+#include "nsAbsoluteFrame.h"
+#include "nsPlaceholderFrame.h"
+#include "nsIContentDelegate.h"
static NS_DEFINE_IID(kStyleBorderSID, NS_STYLEBORDER_SID);
static NS_DEFINE_IID(kStyleColorSID, NS_STYLECOLOR_SID);
+static NS_DEFINE_IID(kStylePositionSID, NS_STYLEPOSITION_SID);
+static NS_DEFINE_IID(kStyleDisplaySID, NS_STYLEDISPLAY_SID);
+
+NS_DEF_PTR(nsIStyleContext);
nsHTMLContainerFrame::nsHTMLContainerFrame(nsIContent* aContent,
PRInt32 aIndexInParent,
@@ -235,6 +243,38 @@ static void AdjustIndexInParents(nsIFrame* aContainerFrame,
}
}
+nsIFrame* nsHTMLContainerFrame::CreateFrameFor(nsIPresContext* aPresContext,
+ nsIContent* aContent,
+ PRInt32 aIndexInParent)
+{
+ // Get the style content for the frame
+ nsIStyleContextPtr styleContext = aPresContext->ResolveStyleContextFor(aContent, this);
+ nsStylePosition* position = (nsStylePosition*)styleContext->GetData(kStylePositionSID);
+ nsStyleDisplay* display = (nsStyleDisplay*)styleContext->GetData(kStyleDisplaySID);
+ nsIFrame* result;
+
+ // See whether it wants any special handling
+ if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) {
+ AbsoluteFrame::NewFrame(&result, aContent, aIndexInParent, this);
+ } else if (display->mFloats != NS_STYLE_FLOAT_NONE) {
+ PlaceholderFrame::NewFrame(&result, aContent, aIndexInParent, this);
+ } else if (NS_STYLE_DISPLAY_NONE == display->mDisplay) {
+ nsFrame::NewFrame(&result, aContent, aIndexInParent, this);
+ } else {
+ nsIContentDelegate* delegate;
+
+ // Ask the content delegate to create the frame
+ // XXX The delegate will also resolve the style context...
+ delegate = aContent->GetDelegate(aPresContext);
+ result = delegate->CreateFrame(aPresContext, aContent, aIndexInParent, this);
+ NS_RELEASE(delegate);
+ }
+
+ // Set the frame's style context
+ result->SetStyleContext(aPresContext, styleContext);
+ return result;
+}
+
NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell,
nsIPresContext* aPresContext,
nsIContent* aContainer,
@@ -263,6 +303,69 @@ NS_METHOD nsHTMLContainerFrame::ContentInserted(nsIPresShell* aShell,
frame->GetNextInFlow((nsIFrame*&)frame);
}
+ // Find the frame that precedes this frame
+ nsIFrame* prevSibling = nsnull;
+
+ if (aIndexInParent > 0) {
+ nsIContent* precedingContent = aContainer->ChildAt(aIndexInParent - 1);
+ prevSibling = aShell->FindFrameWithContent(precedingContent);
+ NS_RELEASE(precedingContent);
+
+ // The frame may have a next-in-flow. Get the last-in-flow
+ nsIFrame* nextInFlow;
+ do {
+ prevSibling->GetNextInFlow(nextInFlow);
+ if (nsnull != nextInFlow) {
+ prevSibling = nextInFlow;
+ }
+ } while (nsnull != nextInFlow);
+ }
+
+ // Get the geometric parent. We expect it to be this frame or one of its
+ // next-in-flow(s). It could be a pseudo-frame, but then it better also be
+ // a nsHTMLContainerFrame...
+ nsHTMLContainerFrame* parent = this;
+
+ if (nsnull != prevSibling) {
+ prevSibling->GetGeometricParent((nsIFrame*&)parent);
+ }
+
+ // Create the new frame
+ nsIFrame* newFrame = parent->CreateFrameFor(aPresContext, aChild, aIndexInParent);
+
+ // Insert the frame
+ if (nsnull == prevSibling) {
+ // If there's no preceding frame, then this is the first content child
+ NS_ASSERTION(0 == aIndexInParent, "unexpected index-in-parent");
+ NS_ASSERTION(0 == parent->mFirstContentOffset, "unexpected first content offset");
+ newFrame->SetNextSibling(parent->mFirstChild);
+ parent->mFirstChild = newFrame;
+
+ } else {
+ nsIFrame* nextSibling;
+
+ // Link the new frame into
+ prevSibling->GetNextSibling(nextSibling);
+ newFrame->SetNextSibling(nextSibling);
+ prevSibling->SetNextSibling(newFrame);
+
+ if (nsnull == nextSibling) {
+ // The new frame is the last child frame
+ parent->SetLastContentOffset(newFrame);
+
+ if (parent->IsPseudoFrame()) {
+ parent->PropagateContentOffsets();
+ }
+ }
+ }
+ parent->mChildCount++;
+
+ // Generate a reflow command
+ nsReflowCommand* cmd = new nsReflowCommand(aPresContext, parent,
+ nsReflowCommand::FrameAppended,
+ newFrame);
+ aShell->AppendReflowCommand(cmd);
+
return NS_OK;
}
diff --git a/mozilla/layout/html/base/src/nsHTMLContainerFrame.h b/mozilla/layout/html/base/src/nsHTMLContainerFrame.h
index 627803cd997..c126f8711f7 100644
--- a/mozilla/layout/html/base/src/nsHTMLContainerFrame.h
+++ b/mozilla/layout/html/base/src/nsHTMLContainerFrame.h
@@ -61,6 +61,10 @@ protected:
const nsString& aBase,
const nsString& aURLSpec,
const nsString& aTargetSpec);
+
+ nsIFrame* CreateFrameFor(nsIPresContext* aPresContext,
+ nsIContent* aContent,
+ PRInt32 aIndexInParent);
};
#endif /* nsHTMLContainerFrame_h___ */
diff --git a/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp b/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp
index bd545e2068a..8a056b9c8c5 100644
--- a/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp
+++ b/mozilla/layout/html/base/src/nsPlaceholderFrame.cpp
@@ -52,6 +52,15 @@ PlaceholderFrame::~PlaceholderFrame()
{
}
+NS_METHOD PlaceholderFrame::SetIndexInParent(PRInt32 aIndexInParent)
+{
+ if (nsnull != mAnchoredItem) {
+ mAnchoredItem->SetIndexInParent(aIndexInParent);
+ }
+
+ return nsFrame::SetIndexInParent(aIndexInParent);
+}
+
NS_METHOD PlaceholderFrame::ResizeReflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsSize& aMaxSize,
diff --git a/mozilla/layout/html/base/src/nsPlaceholderFrame.h b/mozilla/layout/html/base/src/nsPlaceholderFrame.h
index 6cae7e1c546..9f4d5a68a51 100644
--- a/mozilla/layout/html/base/src/nsPlaceholderFrame.h
+++ b/mozilla/layout/html/base/src/nsPlaceholderFrame.h
@@ -35,6 +35,8 @@ public:
// Returns the associated anchored item
nsIFrame* GetAnchoredItem() const {return mAnchoredItem;}
+ NS_IMETHOD SetIndexInParent(PRInt32 aIndexInParent);
+
// Resize reflow methods
NS_IMETHOD ResizeReflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,