diff --git a/layout/generic/nsHTMLReflowState.cpp b/layout/generic/nsHTMLReflowState.cpp index 59bf434d088..1aa9822f17d 100644 --- a/layout/generic/nsHTMLReflowState.cpp +++ b/layout/generic/nsHTMLReflowState.cpp @@ -55,8 +55,6 @@ #include "nsIServiceManager.h" #include "nsIPercentHeightObserver.h" #include "nsLayoutUtils.h" -#include "nsPlaceholderFrame.h" -#include "nsFrameManager.h" #include "mozilla/Preferences.h" #ifdef IBMBIDI #include "nsBidiUtils.h" @@ -851,7 +849,7 @@ static bool AreAllEarlierInFlowFramesEmpty(nsIFrame* aFrame, // cbrs->frame is the actual containing block void nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, - nsPlaceholderFrame* aPlaceholderFrame, + nsIFrame* aPlaceholderFrame, nsIFrame* aContainingBlock, nscoord aBlockLeftContentEdge, nscoord aBlockContentWidth, @@ -934,12 +932,17 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, nsLayoutUtils::GetAsBlock(aContainingBlock->GetContentInsertionFrame()); if (blockFrame) { nscoord blockYOffset = blockFrame->GetOffsetTo(aContainingBlock).y; - const nsLineBox* lineBox = aPlaceholderFrame->GetCachedLineBox(); - if (!lineBox) { + bool isValid; + nsBlockInFlowLineIterator iter(blockFrame, aPlaceholderFrame, &isValid); + if (!isValid) { // Give up. We're probably dealing with somebody using // position:absolute inside native-anonymous content anyway. aHypotheticalBox.mTop = placeholderOffset.y; } else { + NS_ASSERTION(iter.GetContainer() == blockFrame, + "Found placeholder in wrong block!"); + nsBlockFrame::line_iterator lineBox = iter.GetLine(); + // How we determine the hypothetical box depends on whether the element // would have been inline-level or block-level if (mStyleDisplay->IsOriginalDisplayInlineOutside()) { @@ -953,10 +956,10 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, // have been just before this line. // XXXbz the line box is not fully reflowed yet if our // containing block is relatively positioned... - bool allEmpty = true; - if (!lineBox->IsValidCachedIsEmpty() || !lineBox->CachedIsEmpty()) { + if (lineBox != iter.End()) { nsIFrame * firstFrame = lineBox->mFirstChild; bool found = false; + bool allEmpty = true; while (firstFrame) { // See bug 223064 allEmpty = AreAllEarlierInFlowFramesEmpty(firstFrame, aPlaceholderFrame, &found); @@ -965,17 +968,20 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, firstFrame = firstFrame->GetNextSibling(); } NS_ASSERTION(firstFrame, "Couldn't find placeholder!"); - } - if (allEmpty) { - // The top of the hypothetical box is the top of the line - // containing the placeholder, since there is nothing in the - // line before our placeholder except empty frames. - aHypotheticalBox.mTop = lineBox->mBounds.y + blockYOffset; + if (allEmpty) { + // The top of the hypothetical box is the top of the line + // containing the placeholder, since there is nothing in the + // line before our placeholder except empty frames. + aHypotheticalBox.mTop = lineBox->mBounds.y + blockYOffset; + } else { + // The top of the hypothetical box is just below the line + // containing the placeholder. + aHypotheticalBox.mTop = lineBox->mBounds.YMost() + blockYOffset; + } } else { - // The top of the hypothetical box is just below the line - // containing the placeholder. - aHypotheticalBox.mTop = lineBox->mBounds.YMost() + blockYOffset; + // Just use the placeholder's y-offset wrt the containing block + aHypotheticalBox.mTop = placeholderOffset.y; } } } @@ -1101,10 +1107,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext, "Why are we here?"); // Get the placeholder frame - nsPlaceholderFrame* placeholderFrame; + nsIFrame* placeholderFrame; - placeholderFrame = - aPresContext->PresShell()->FrameManager()->GetPlaceholderFrameFor(frame); + placeholderFrame = aPresContext->PresShell()->GetPlaceholderFrameFor(frame); NS_ASSERTION(nsnull != placeholderFrame, "no placeholder frame"); // If both 'left' and 'right' are 'auto' or both 'top' and 'bottom' are diff --git a/layout/generic/nsHTMLReflowState.h b/layout/generic/nsHTMLReflowState.h index 3f0cdb09d96..5b9281c072a 100644 --- a/layout/generic/nsHTMLReflowState.h +++ b/layout/generic/nsHTMLReflowState.h @@ -49,7 +49,6 @@ class nsRenderingContext; class nsFloatManager; class nsLineLayout; class nsIPercentHeightObserver; -class nsPlaceholderFrame; struct nsStyleDisplay; struct nsStyleVisibility; @@ -512,7 +511,7 @@ protected: nscoord& aCBWidth); void CalculateHypotheticalBox(nsPresContext* aPresContext, - nsPlaceholderFrame* aPlaceholderFrame, + nsIFrame* aPlaceholderFrame, nsIFrame* aContainingBlock, nscoord aBlockLeftContentEdge, nscoord aBlockContentWidth, diff --git a/layout/generic/nsLineBox.cpp b/layout/generic/nsLineBox.cpp index f8542387d0d..6e4010c8c62 100644 --- a/layout/generic/nsLineBox.cpp +++ b/layout/generic/nsLineBox.cpp @@ -289,7 +289,7 @@ nsLineBox::IsEmpty() const } bool -nsLineBox::CachedIsEmpty() const +nsLineBox::CachedIsEmpty() { if (mFlags.mDirty) { return IsEmpty(); diff --git a/layout/generic/nsLineBox.h b/layout/generic/nsLineBox.h index 369c73858d5..82c63ff5caf 100644 --- a/layout/generic/nsLineBox.h +++ b/layout/generic/nsLineBox.h @@ -486,14 +486,14 @@ public: // Call this only while in Reflow() for the block the line belongs // to, only between reflowing the line (or sliding it, if we skip // reflowing it) and the end of reflowing the block. - bool CachedIsEmpty() const; + bool CachedIsEmpty(); void InvalidateCachedIsEmpty() { mFlags.mEmptyCacheValid = false; } // For debugging purposes - bool IsValidCachedIsEmpty() const { + bool IsValidCachedIsEmpty() { return mFlags.mEmptyCacheValid; } @@ -514,8 +514,8 @@ public: PRUint32 mLineWrapped: 1; PRUint32 mInvalidateTextRuns : 1; PRUint32 mResizeReflowOptimizationDisabled: 1; // default 0 = means that the opt potentially applies to this line. 1 = never skip reflowing this line for a resize reflow - mutable PRUint32 mEmptyCacheValid: 1; - mutable PRUint32 mEmptyCacheState: 1; + PRUint32 mEmptyCacheValid: 1; + PRUint32 mEmptyCacheState: 1; // mHasBullet indicates that this is an inline line whose block's // bullet is adjacent to this line and non-empty. PRUint32 mHasBullet : 1; diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp index c86bcc9a9fa..6e7ec72759e 100644 --- a/layout/generic/nsPlaceholderFrame.cpp +++ b/layout/generic/nsPlaceholderFrame.cpp @@ -145,15 +145,6 @@ nsPlaceholderFrame::Reflow(nsPresContext* aPresContext, aDesiredSize.width = 0; aDesiredSize.height = 0; - // Cache our line box. - mCachedLineBox = nsnull; - if (aReflowState.mLineLayout) { - nsLineList::iterator* line = aReflowState.mLineLayout->GetLine(); - if (line) { - mCachedLineBox = line->get(); - } - } - aStatus = NS_FRAME_COMPLETE; NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; diff --git a/layout/generic/nsPlaceholderFrame.h b/layout/generic/nsPlaceholderFrame.h index 82e5c4e0246..e53d44e5af0 100644 --- a/layout/generic/nsPlaceholderFrame.h +++ b/layout/generic/nsPlaceholderFrame.h @@ -69,8 +69,6 @@ #include "nsFrame.h" #include "nsGkAtoms.h" -class nsLineBox; - nsIFrame* NS_NewPlaceholderFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrameState aTypeBit); @@ -202,17 +200,8 @@ public: return outOfFlow; } - // GetCachedLineBox is only OK to call if you're sure this - // placeholder has has Reflow() called since any changes to the - // frame tree that could have affected which line box the - // placeholder is in. - const nsLineBox* GetCachedLineBox() const { - return mCachedLineBox; - } - protected: nsIFrame* mOutOfFlowFrame; - nsLineBox* mCachedLineBox; }; #endif /* nsPlaceholderFrame_h___ */