diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp index ac87281bfd3..4b49fe8ef2b 100644 --- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp @@ -1074,6 +1074,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, case NS_STYLE_DISPLAY_INLINE: rv = NS_NewCSSInlineFrame(&frame, aContent, aParentFrame); + ProcessChildren(aPresContext, frame, aContent); break; default: diff --git a/mozilla/layout/css/layout/src/nsCSSBlockFrame.cpp b/mozilla/layout/css/layout/src/nsCSSBlockFrame.cpp index 9acdb1a3df3..0bfe3c2d4a6 100644 --- a/mozilla/layout/css/layout/src/nsCSSBlockFrame.cpp +++ b/mozilla/layout/css/layout/src/nsCSSBlockFrame.cpp @@ -276,7 +276,7 @@ protected: nsPlaceholderFrame* CreatePlaceholderFrame(nsIPresContext* aPresContext, nsIFrame* aFloatedFrame); - nsresult AddNewFrames(nsIPresContext* aPresContext, nsIFrame*); + nsresult AppendNewFrames(nsIPresContext* aPresContext, nsIFrame*); #ifdef NS_DEBUG PRBool IsChild(nsIFrame* aFrame); @@ -1010,7 +1010,7 @@ NS_IMETHODIMP nsCSSBlockFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { mHasBeenInitialized = PR_TRUE; - return AddNewFrames(&aPresContext, aChildList); + return AppendNewFrames(&aPresContext, aChildList); } NS_IMETHODIMP @@ -1680,7 +1680,7 @@ nsCSSBlockFrame::CreatePlaceholderFrame(nsIPresContext* aPresContext, } nsresult -nsCSSBlockFrame::AddNewFrames(nsIPresContext* aPresContext, nsIFrame* aNewFrame) +nsCSSBlockFrame::AppendNewFrames(nsIPresContext* aPresContext, nsIFrame* aNewFrame) { // Get our last line and then get its last child nsIFrame* lastFrame; @@ -1729,6 +1729,7 @@ nsCSSBlockFrame::AddNewFrames(nsIPresContext* aPresContext, nsIFrame* aNewFrame) 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 if (nsnull != prevFrame) { @@ -1860,7 +1861,7 @@ nsCSSBlockFrame::FrameAppendedReflow(nsCSSBlockReflowState& aState) // Add the new frames to the child list, and create new lines. Each // impacted line will be marked dirty - AddNewFrames(aState.mPresContext, firstAppendedFrame); + AppendNewFrames(aState.mPresContext, firstAppendedFrame); #endif // Generate text-run information diff --git a/mozilla/layout/css/layout/src/nsCSSInlineFrame.cpp b/mozilla/layout/css/layout/src/nsCSSInlineFrame.cpp index 09781e13fa0..8b6655842a1 100644 --- a/mozilla/layout/css/layout/src/nsCSSInlineFrame.cpp +++ b/mozilla/layout/css/layout/src/nsCSSInlineFrame.cpp @@ -20,6 +20,7 @@ #include "nsIReflowCommand.h" #include "nsIStyleContext.h" +#include "nsPlaceholderFrame.h" #include "nsHTMLIIDs.h"// XXX #include "nsHTMLBase.h"// XXX rename to nsCSSBase? @@ -142,6 +143,82 @@ nsCSSInlineFrame::GetSkipSides() const return skip; } +nsPlaceholderFrame* +nsCSSInlineFrame::CreatePlaceholderFrame(nsIPresContext* aPresContext, + nsIFrame* aFloatedFrame) +{ + nsIContent* content; + aFloatedFrame->GetContent(content); + + // XXX We should wrap the floated element in a BODY frame... + nsPlaceholderFrame* placeholder; + nsPlaceholderFrame::NewFrame((nsIFrame**)&placeholder, content, this, aFloatedFrame); + NS_IF_RELEASE(content); + + // Let the placeholder share the same style context as the floated element + nsIStyleContext* kidSC; + aFloatedFrame->GetStyleContext(aPresContext, kidSC); + placeholder->SetStyleContext(aPresContext, kidSC); + NS_RELEASE(kidSC); + + return placeholder; +} + +nsresult +nsCSSInlineFrame::AppendNewFrames(nsIPresContext* aPresContext, + nsIFrame* aNewFrame) +{ + nsIFrame* lastFrame; + if (nsnull == mFirstChild) { + lastFrame = nsnull; + mFirstChild = aNewFrame; + } else { + LastChild(lastFrame); + lastFrame->SetNextSibling(aNewFrame); + } + mChildCount += LengthOf(aNewFrame); + + // Now walk the new frames and check if there are any elements that want + // to be floated + nsIFrame* prevFrame = lastFrame; + for (nsIFrame* frame = aNewFrame; nsnull != frame; frame->GetNextSibling(frame)) { + const nsStyleDisplay* display; + frame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&)display); + + // See if the element wants to be floated + if (NS_STYLE_FLOAT_NONE != display->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 + if (nsnull == prevFrame) { + mFirstChild = placeholder; + } else { + prevFrame->SetNextSibling(placeholder); + } + nsIFrame* nextSibling; + frame->GetNextSibling(nextSibling); + placeholder->SetNextSibling(nextSibling); + frame->SetNextSibling(nsnull); + + frame = placeholder; + } + + // Remember the previous frame + prevFrame = frame; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsCSSInlineFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + NS_PRECONDITION(nsnull == mFirstChild, "already initialized"); + return AppendNewFrames(&aPresContext, aChildList); +} + NS_IMETHODIMP nsCSSInlineFrame::CreateContinuingFrame(nsIPresContext& aCX, nsIFrame* aParent, @@ -180,31 +257,6 @@ nsCSSInlineFrame::FindTextRuns(nsCSSLineLayout& aLineLayout, // Gather up children from the overflow lists DrainOverflowLists(); - // Create new frames if necessary - if (NS_FRAME_FIRST_REFLOW & mState) { - if ((nsnull == mPrevInFlow) && (nsnull == mNextInFlow) && - (0 == mChildCount)) { - rv = CreateNewFrames(aLineLayout.mPresContext); - if (NS_OK != rv) { - goto done; - } - } - } - else if (nsnull != aReflowCommand) { - nsIFrame* target; - aReflowCommand->GetTarget(target); - if (this == target) { - nsIReflowCommand::ReflowType type; - aReflowCommand->GetType(type); - if (nsIReflowCommand::FrameAppended == type) { - rv = CreateNewFrames(aLineLayout.mPresContext); - if (NS_OK != rv) { - goto done; - } - } - } - } - // Ask each child frame for its text runs frame = mFirstChild; n = mChildCount; @@ -225,7 +277,6 @@ nsCSSInlineFrame::FindTextRuns(nsCSSLineLayout& aLineLayout, frame->GetNextSibling(frame); } - done:; NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("exit nsCSSInlineFrame::FindTextRuns rv=%x [%d,%d,%c]", rv, mFirstContentOffset, mLastContentOffset, @@ -402,19 +453,6 @@ nsCSSInlineFrame::InitialReflow(nsCSSInlineReflowState& aState) return rv; } -#if XXX - // Create any frames that need creating; note that they should have - // been created during FindTextRuns which should have been called - // before this, but we check anyway. - if ((nsnull == mPrevInFlow) && (nsnull == mNextInFlow) && - (0 == mChildCount)) { - nsresult rv = CreateNewFrames(aState.mPresContext); - if (NS_OK != rv) { - return rv; - } - } -#endif - nsInlineReflowStatus rs = NS_FRAME_COMPLETE; if (0 != mChildCount) { if (!ReflowMapped(aState, rs)) { @@ -430,13 +468,12 @@ nsCSSInlineFrame::FrameAppendedReflow(nsCSSInlineReflowState& aState) NS_PRECONDITION(nsnull == mNextInFlow, "bad frame-appended-reflow"); NS_PRECONDITION(mLastContentIsComplete == PR_TRUE, "bad state"); -#if XXX - // Create any frames that need creating - nsresult rv = CreateNewFrames(aState.mPresContext); - if (NS_OK != rv) { - return rv; - } -#endif + // Get the first of the newly appended frames + nsIFrame* firstAppendedFrame; + aState.reflowCommand->GetChildFrame(firstAppendedFrame); + + // Add the new frames + AppendNewFrames(aState.mPresContext, firstAppendedFrame); nsInlineReflowStatus rs = NS_FRAME_COMPLETE; if (0 != mChildCount) { @@ -447,86 +484,6 @@ nsCSSInlineFrame::FrameAppendedReflow(nsCSSInlineReflowState& aState) return rs; } -nsresult -nsCSSInlineFrame::CreateNewFrames(nsIPresContext* aPresContext) -{ - // reason: initial: (a) null nif, pif: create frames - // (b) pullup: don't create frames - // reason: incremental: (a) append targetted at us => create frames - - // Get the childPrevInFlow for our eventual first child if we are a - // continuation and we have no children and the last child in our - // prev-in-flow is incomplete. While we are at it, we also compute - // our kidContentIndex. - PRInt32 kidContentIndex; - nsIFrame* childPrevInFlow = nsnull; - nsIFrame* prevChild = nsnull; - if ((nsnull == mFirstChild) && (nsnull != mPrevInFlow)) { - nsCSSInlineFrame* prev = (nsCSSInlineFrame*)mPrevInFlow; - NS_ASSERTION(prev->mLastContentOffset >= prev->mFirstContentOffset, - "bad prevInFlow"); - kidContentIndex = prev->NextChildOffset(); - if (!prev->mLastContentIsComplete) { - // Our prev-in-flow's last child is not complete - prev->LastChild(childPrevInFlow); - } - } - else { - kidContentIndex = NextChildOffset(); - LastChild(prevChild); - } - - nsresult rv; - PRInt32 lastContentIndex; - mContent->ChildCount(lastContentIndex); - NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, - ("enter nsCSSInlineFrame::CreateNewFrames: kidContentIndex=%d lastContentIndex=%d childPrevInFlow=%p", - kidContentIndex, lastContentIndex, childPrevInFlow)); - while (kidContentIndex < lastContentIndex) { - nsIContent* kid; - mContent->ChildAt(kidContentIndex, kid); - if (nsnull == kid) { - // Our content container is bad - break; - } - - // Create child - nsIFrame* child; - rv = nsHTMLBase::CreateFrame(aPresContext, this, kid, childPrevInFlow, - child); - NS_RELEASE(kid); - if (NS_OK != rv) { - return rv; - } - if (nsnull == prevChild) { - mFirstChild = child; - mFirstContentOffset = kidContentIndex; - } - else { - prevChild->SetNextSibling(child); - } - mChildCount++; - kidContentIndex++; - childPrevInFlow = nsnull; - prevChild = child; - NS_FRAME_TRACE(NS_FRAME_TRACE_NEW_FRAMES, - ("nsCSSInlineFrame::CreateNewFrames: new-frame=%p prev-in-flow=%p", - child, childPrevInFlow)); - } - if (kidContentIndex == 0) { - NS_ASSERTION(lastContentIndex == 0, "bad kid content index"); - mLastContentOffset = 0; - } else { - mLastContentOffset = kidContentIndex - 1; - } - NS_ASSERTION(mFirstContentOffset <= mLastContentOffset, "bad fco/lco"); - mLastContentIsComplete = PR_TRUE; - - NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, - ("exit nsCSSInlineFrame::CreateNewFrames")); - return NS_OK; -} - nsInlineReflowStatus nsCSSInlineFrame::ChildIncrementalReflow(nsCSSInlineReflowState& aState) { diff --git a/mozilla/layout/css/layout/src/nsCSSInlineFrame.h b/mozilla/layout/css/layout/src/nsCSSInlineFrame.h index 35835544bcf..0b1baab348a 100644 --- a/mozilla/layout/css/layout/src/nsCSSInlineFrame.h +++ b/mozilla/layout/css/layout/src/nsCSSInlineFrame.h @@ -23,6 +23,7 @@ #include "nsCSSLineLayout.h" class nsCSSInlineFrame; +class nsPlaceholderFrame; /** * Reflow state object for managing css inline layout. Most of the state @@ -62,6 +63,7 @@ public: NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); // nsIFrame + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); NS_IMETHOD CreateContinuingFrame(nsIPresContext& aCX, nsIFrame* aParent, nsIStyleContext* aStyleContext, @@ -110,8 +112,6 @@ protected: nsIFrame* PullOneChild(nsCSSInlineFrame* aNextInFlow, nsIFrame* aLastChild); - nsresult CreateNewFrames(nsIPresContext* aPresContext); - nsresult MaybeCreateNextInFlow(nsCSSInlineReflowState& aState, nsIFrame* aFrame); @@ -120,6 +120,11 @@ protected: void DrainOverflowLists(); + nsPlaceholderFrame* CreatePlaceholderFrame(nsIPresContext* aPresContext, + nsIFrame* aFloatedFrame); + + nsresult AppendNewFrames(nsIPresContext* aPresContext, nsIFrame*); + friend nsresult NS_NewCSSInlineFrame(nsIFrame** aInstancePtrResult, nsIContent* aContent, nsIFrame* aParent); diff --git a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp index ac87281bfd3..4b49fe8ef2b 100644 --- a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp @@ -1074,6 +1074,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, case NS_STYLE_DISPLAY_INLINE: rv = NS_NewCSSInlineFrame(&frame, aContent, aParentFrame); + ProcessChildren(aPresContext, frame, aContent); break; default: diff --git a/mozilla/layout/style/nsHTMLStyleSheet.cpp b/mozilla/layout/style/nsHTMLStyleSheet.cpp index ac87281bfd3..4b49fe8ef2b 100644 --- a/mozilla/layout/style/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLStyleSheet.cpp @@ -1074,6 +1074,7 @@ NS_IMETHODIMP HTMLStyleSheetImpl::ConstructFrame(nsIPresContext* aPresContext, case NS_STYLE_DISPLAY_INLINE: rv = NS_NewCSSInlineFrame(&frame, aContent, aParentFrame); + ProcessChildren(aPresContext, frame, aContent); break; default: