--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1743,17 +1743,16 @@ GK_ATOM(menuBarFrame,"MenuBarFrame")
GK_ATOM(menuFrame,"MenuFrame")
GK_ATOM(menuPopupFrame,"MenuPopupFrame")
GK_ATOM(objectFrame, "ObjectFrame")
GK_ATOM(pageFrame, "PageFrame")
GK_ATOM(pageBreakFrame, "PageBreakFrame")
GK_ATOM(pageContentFrame, "PageContentFrame")
GK_ATOM(placeholderFrame, "PlaceholderFrame")
GK_ATOM(popupSetFrame, "PopupSetFrame")
-GK_ATOM(positionedInlineFrame, "PositionedInlineFrame")
GK_ATOM(canvasFrame, "CanvasFrame")
GK_ATOM(rootFrame, "RootFrame")
GK_ATOM(scrollFrame, "ScrollFrame")
GK_ATOM(scrollbarFrame, "ScrollbarFrame")
GK_ATOM(sequenceFrame, "SequenceFrame")
GK_ATOM(sliderFrame, "sliderFrame")
GK_ATOM(tableCaptionFrame, "TableCaptionFrame")
GK_ATOM(tableCellFrame, "TableCellFrame")
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1018,17 +1018,19 @@ nsFrameConstructorState::PushAbsoluteCon
nsAbsoluteItems(AdjustAbsoluteContainingBlock(aNewAbsoluteContainingBlock));
/* See if we're wiring the fixed-pos and abs-pos lists together. This happens iff
* we're a transformed element.
*/
mFixedPosIsAbsPos = (aNewAbsoluteContainingBlock &&
aNewAbsoluteContainingBlock->GetStyleDisplay()->HasTransform());
- aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock();
+ if (aNewAbsoluteContainingBlock) {
+ aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock();
+ }
}
void
nsFrameConstructorState::PushFloatContainingBlock(nsIFrame* aNewFloatContainingBlock,
nsFrameConstructorSaveState& aSaveState)
{
NS_PRECONDITION(!aNewFloatContainingBlock ||
aNewFloatContainingBlock->IsFloatContainingBlock(),
@@ -1214,17 +1216,24 @@ nsFrameConstructorState::ProcessFrameIns
// Insert the frames hanging out in aItems. We can use SetInitialChildList()
// if the containing block hasn't been reflowed yet (so NS_FRAME_FIRST_REFLOW
// is set) and doesn't have any frames in the aChildListName child list yet.
const nsFrameList& childList = containingBlock->GetChildList(aChildListName);
nsresult rv = NS_OK;
if (childList.IsEmpty() &&
(containingBlock->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
- rv = containingBlock->SetInitialChildList(aChildListName, aFrameItems);
+ // If we're injecting absolutely positioned frames, inject them on the
+ // absolute containing block
+ if (aChildListName == containingBlock->GetAbsoluteListName()) {
+ rv = containingBlock->GetAbsoluteContainingBlock()->
+ SetInitialChildList(containingBlock, aChildListName, aFrameItems);
+ } else {
+ rv = containingBlock->SetInitialChildList(aChildListName, aFrameItems);
+ }
} else {
// Note that whether the frame construction context is doing an append or
// not is not helpful here, since it could be appending to some frame in
// the middle of the document, which means we're not necessarily
// appending to the children of the containing block.
//
// We need to make sure the 'append to the end of document' case is fast.
// So first test the last child of the containing block
@@ -1232,33 +1241,33 @@ nsFrameConstructorState::ProcessFrameIns
// CompareTreePosition uses placeholder hierarchy for out of flow frames,
// so this will make out-of-flows respect the ordering of placeholders,
// which is great because it takes care of anonymous content.
nsIFrame* firstNewFrame = aFrameItems.FirstChild();
if (!lastChild ||
nsLayoutUtils::CompareTreePosition(lastChild, firstNewFrame, containingBlock) < 0) {
// no lastChild, or lastChild comes before the new children, so just append
- rv = containingBlock->AppendFrames(aChildListName, aFrameItems);
+ rv = mFrameManager->AppendFrames(containingBlock, aChildListName, aFrameItems);
} else {
// try the other children
nsIFrame* insertionPoint = nsnull;
for (nsIFrame* f = childList.FirstChild(); f != lastChild;
f = f->GetNextSibling()) {
PRInt32 compare =
nsLayoutUtils::CompareTreePosition(f, firstNewFrame, containingBlock);
if (compare > 0) {
// f comes after the new children, so stop here and insert after
// the previous frame
break;
}
insertionPoint = f;
}
- rv = containingBlock->InsertFrames(aChildListName, insertionPoint,
- aFrameItems);
+ rv = mFrameManager->InsertFrames(containingBlock, aChildListName,
+ insertionPoint, aFrameItems);
}
}
NS_POSTCONDITION(aFrameItems.IsEmpty(), "How did that happen?");
// XXXbz And if NS_FAILED(rv), what? I guess we need to clean up the list
// and deal with all the placeholders... but what if the placeholders aren't
// in the document yet? Could that happen?
@@ -2555,16 +2564,18 @@ nsCSSFrameConstructor::ConstructRootFram
nsContainerFrame::SyncFrameViewProperties(mPresShell->GetPresContext(), viewportFrame,
viewportPseudoStyle, rootView);
nsContainerFrame::SyncWindowProperties(mPresShell->GetPresContext(), viewportFrame,
rootView);
// The viewport is the containing block for 'fixed' elements
mFixedContainingBlock = viewportFrame;
+ // Make it an absolute container for fixed-pos elements
+ mFixedContainingBlock->MarkAsAbsoluteContainingBlock();
*aNewFrame = viewportFrame;
return NS_OK;
}
nsresult
nsCSSFrameConstructor::SetUpDocElementContainingBlock(nsIContent* aDocElement)
{
@@ -2839,16 +2850,18 @@ nsCSSFrameConstructor::ConstructPageFram
nsIFrame* prevPageContentFrame = nsnull;
if (aPrevPageFrame) {
prevPageContentFrame = aPrevPageFrame->GetFirstChild(nsnull);
NS_ASSERTION(prevPageContentFrame, "missing page content frame");
}
pageContentFrame->Init(nsnull, aPageFrame, prevPageContentFrame);
SetInitialSingleChild(aPageFrame, pageContentFrame);
mFixedContainingBlock = pageContentFrame;
+ // Make it an absolute container for fixed-pos elements
+ mFixedContainingBlock->MarkAsAbsoluteContainingBlock();
nsRefPtr<nsStyleContext> canvasPseudoStyle;
canvasPseudoStyle = styleSet->ResolveAnonymousBoxStyle(nsCSSAnonBoxes::canvas,
pageContentPseudoStyle);
aCanvasFrame = NS_NewCanvasFrame(aPresShell, canvasPseudoStyle);
if (NS_UNLIKELY(!aCanvasFrame))
return NS_ERROR_OUT_OF_MEMORY;
@@ -5534,17 +5547,17 @@ nsCSSFrameConstructor::GetAbsoluteContai
// Find the outermost wrapped block under this frame
for (nsIFrame* wrappedFrame = aFrame; wrappedFrame != frame->GetParent();
wrappedFrame = wrappedFrame->GetParent()) {
nsIAtom* frameType = wrappedFrame->GetType();
if (nsGkAtoms::blockFrame == frameType ||
#ifdef MOZ_XUL
nsGkAtoms::XULLabelFrame == frameType ||
#endif
- nsGkAtoms::positionedInlineFrame == frameType) {
+ (nsGkAtoms::inlineFrame == frameType && wrappedFrame->IsAbsoluteContainer())) {
containingBlock = wrappedFrame;
} else if (nsGkAtoms::fieldSetFrame == frameType) {
// If the positioned frame is a fieldset, use the area frame inside it.
// We don't use GetContentInsertionFrame for fieldsets yet.
containingBlock = GetFieldSetBlockFrame(wrappedFrame);
}
}
@@ -8498,23 +8511,16 @@ nsCSSFrameConstructor::CreateContinuingF
}
#endif
} else if (nsGkAtoms::columnSetFrame == frameType) {
newFrame = NS_NewColumnSetFrame(shell, styleContext, 0);
if (newFrame) {
newFrame->Init(content, aParentFrame, aFrame);
}
-
- } else if (nsGkAtoms::positionedInlineFrame == frameType) {
- newFrame = NS_NewPositionedInlineFrame(shell, styleContext);
-
- if (newFrame) {
- newFrame->Init(content, aParentFrame, aFrame);
- }
} else if (nsGkAtoms::pageFrame == frameType) {
nsIFrame* canvasFrame;
rv = ConstructPageFrame(shell, aPresContext, aParentFrame, aFrame,
newFrame, canvasFrame);
} else if (nsGkAtoms::tableOuterFrame == frameType) {
rv = CreateContinuingOuterTableFrame(shell, aPresContext, aFrame, aParentFrame,
content, styleContext, &newFrame);
@@ -10715,30 +10721,26 @@ nsCSSFrameConstructor::ConstructInline(n
nsStyleContext* const styleContext = aItem.mStyleContext;
nsIFrame *newFrame;
PRBool positioned =
NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay &&
(NS_STYLE_POSITION_RELATIVE == aDisplay->mPosition ||
aDisplay->HasTransform());
- if (positioned) {
- newFrame = NS_NewPositionedInlineFrame(mPresShell, styleContext);
- } else {
- newFrame = NS_NewInlineFrame(mPresShell, styleContext);
- }
+ newFrame = NS_NewInlineFrame(mPresShell, styleContext);
// Initialize the frame
InitAndRestoreFrame(aState, content, aParentFrame, nsnull, newFrame);
nsFrameConstructorSaveState absoluteSaveState; // definition cannot be inside next block
// because the object's destructor is significant
// this is part of the fix for bug 42372
- if (positioned) {
+ if (positioned) {
// Relatively positioned frames becomes a container for child
// frames that are positioned
aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState);
}
// Process the child content
nsFrameItems childItems;
nsresult rv = ConstructFramesFromItemList(aState, aItem.mChildItems, newFrame,
@@ -10827,27 +10829,25 @@ nsCSSFrameConstructor::CreateIBSiblings(
MoveChildrenTo(aState.mPresContext, aInitialInline, blockFrame, blockKids);
SetFrameIsSpecial(lastNewInline, blockFrame);
aSiblings.AddChild(blockFrame);
// Now grab the initial inlines in aChildItems and put them into an inline
// frame
- nsIFrame* inlineFrame;
- if (aIsPositioned) {
- inlineFrame = NS_NewPositionedInlineFrame(mPresShell, styleContext);
- }
- else {
- inlineFrame = NS_NewInlineFrame(mPresShell, styleContext);
- }
+ nsIFrame* inlineFrame = NS_NewInlineFrame(mPresShell, styleContext);
InitAndRestoreFrame(aState, content, parentFrame, nsnull, inlineFrame,
PR_FALSE);
+ if (aIsPositioned) {
+ inlineFrame->MarkAsAbsoluteContainingBlock();
+ }
+
if (aChildItems.NotEmpty()) {
nsFrameList::FrameLinkEnumerator firstBlock(aChildItems);
FindFirstBlock(firstBlock);
nsFrameList inlineKids = aChildItems.ExtractHead(firstBlock);
MoveChildrenTo(aState.mPresContext, aInitialInline, inlineFrame,
inlineKids);
}
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2538,18 +2538,17 @@ PrepareBackgroundLayer(nsPresContext* aP
}
// Compute background origin area relative to aBorderArea now as we may need
// it to compute the effective image size for a CSS gradient.
nsRect bgPositioningArea(0, 0, 0, 0);
nsIAtom* frameType = aForFrame->GetType();
nsIFrame* geometryFrame = aForFrame;
- if (frameType == nsGkAtoms::inlineFrame ||
- frameType == nsGkAtoms::positionedInlineFrame) {
+ if (frameType == nsGkAtoms::inlineFrame) {
// XXXjwalden Strictly speaking this is not quite faithful to how
// background-break is supposed to interact with background-origin values,
// but it's a non-trivial amount of work to make it fully conformant, and
// until the specification is more finalized (and assuming background-break
// even makes the cut) it doesn't make sense to hammer out exact behavior.
switch (aBackground.mBackgroundInlinePolicy) {
case NS_STYLE_BG_INLINE_POLICY_EACH_BOX:
bgPositioningArea = nsRect(nsPoint(0,0), aBorderArea.Size());
--- a/layout/base/nsFrameManager.cpp
+++ b/layout/base/nsFrameManager.cpp
@@ -88,16 +88,17 @@
#include "nsUnicharUtils.h"
#include "nsPrintfCString.h"
#include "nsLayoutErrors.h"
#include "nsLayoutUtils.h"
#include "nsAutoPtr.h"
#include "imgIRequest.h"
#include "nsTransitionManager.h"
#include "RestyleTracker.h"
+#include "nsAbsoluteContainingBlock.h"
#include "nsFrameManager.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
#endif
#ifdef DEBUG
@@ -467,29 +468,48 @@ nsFrameManager::ClearAllUndisplayedConte
if (child->GetParent() != aParentContent) {
ClearUndisplayedContentIn(child, child->GetParent());
}
}
}
}
//----------------------------------------------------------------------
+nsresult
+nsFrameManager::AppendFrames(nsIFrame* aParentFrame,
+ nsIAtom* aListName,
+ nsFrameList& aFrameList)
+{
+ if (aParentFrame->IsAbsoluteContainer() &&
+ aListName == aParentFrame->GetAbsoluteListName()) {
+ return aParentFrame->GetAbsoluteContainingBlock()->
+ AppendFrames(aParentFrame, aListName, aFrameList);
+ } else {
+ return aParentFrame->AppendFrames(aListName, aFrameList);
+ }
+}
nsresult
nsFrameManager::InsertFrames(nsIFrame* aParentFrame,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList)
{
NS_PRECONDITION(!aPrevFrame || (!aPrevFrame->GetNextContinuation()
|| IS_TRUE_OVERFLOW_CONTAINER(aPrevFrame->GetNextContinuation()))
&& !IS_TRUE_OVERFLOW_CONTAINER(aPrevFrame),
"aPrevFrame must be the last continuation in its chain!");
- return aParentFrame->InsertFrames(aListName, aPrevFrame, aFrameList);
+ if (aParentFrame->IsAbsoluteContainer() &&
+ aListName == aParentFrame->GetAbsoluteListName()) {
+ return aParentFrame->GetAbsoluteContainingBlock()->
+ InsertFrames(aParentFrame, aListName, aPrevFrame, aFrameList);
+ } else {
+ return aParentFrame->InsertFrames(aListName, aPrevFrame, aFrameList);
+ }
}
nsresult
nsFrameManager::RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame)
{
PRBool wasDestroyingFrames = mIsDestroyingFrames;
mIsDestroyingFrames = PR_TRUE;
@@ -504,17 +524,25 @@ nsFrameManager::RemoveFrame(nsIAtom*
NS_ASSERTION(!aOldFrame->GetPrevContinuation() ||
// exception for nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames
aOldFrame->GetType() == nsGkAtoms::textFrame,
"Must remove first continuation.");
NS_ASSERTION(!(aOldFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW &&
GetPlaceholderFrameFor(aOldFrame)),
"Must call RemoveFrame on placeholder for out-of-flows.");
- nsresult rv = aOldFrame->GetParent()->RemoveFrame(aListName, aOldFrame);
+ nsresult rv = NS_OK;
+ nsIFrame* parentFrame = aOldFrame->GetParent();
+ if (parentFrame->IsAbsoluteContainer() &&
+ aListName == parentFrame->GetAbsoluteListName()) {
+ parentFrame->GetAbsoluteContainingBlock()->
+ RemoveFrame(parentFrame, aListName, aOldFrame);
+ } else {
+ rv = parentFrame->RemoveFrame(aListName, aOldFrame);
+ }
mIsDestroyingFrames = wasDestroyingFrames;
return rv;
}
//----------------------------------------------------------------------
--- a/layout/base/nsFrameManager.h
+++ b/layout/base/nsFrameManager.h
@@ -117,20 +117,17 @@ public:
nsStyleContext* aStyleContext);
NS_HIDDEN_(void) ClearUndisplayedContentIn(nsIContent* aContent,
nsIContent* aParentContent);
NS_HIDDEN_(void) ClearAllUndisplayedContentIn(nsIContent* aParentContent);
// Functions for manipulating the frame model
NS_HIDDEN_(nsresult) AppendFrames(nsIFrame* aParentFrame,
nsIAtom* aListName,
- nsFrameList& aFrameList)
- {
- return aParentFrame->AppendFrames(aListName, aFrameList);
- }
+ nsFrameList& aFrameList);
NS_HIDDEN_(nsresult) InsertFrames(nsIFrame* aParentFrame,
nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList);
NS_HIDDEN_(nsresult) RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
--- a/layout/doc/frame_reflow_debug.html
+++ b/layout/doc/frame_reflow_debug.html
@@ -168,17 +168,16 @@ The entries in the reflow log can be con
<tr><td>img</td><td>image</td></tr>
<tr><td>inline</td><td>inline</td></tr>
<tr><td>letter</td><td>letter</td></tr>
<tr><td>line</td><td>line</td></tr>
<tr><td>select</td><td>select</td></tr>
<tr><td>obj</td><td>object</td></tr>
<tr><td>page</td><td>page</td></tr>
<tr><td>place</td><td>placeholder</td></tr>
- <tr><td>posInline</td><td>positionedInline</td></tr>
<tr><td>canvas</td><td>canvas</td></tr>
<tr><td>root</td><td>root</td></tr>
<tr><td>scroll</td><td>scroll</td></tr>
<tr><td>caption</td><td>tableCaption</td></tr>
<tr><td>cell</td><td>tableCell</td></tr>
<tr><td>bcCell</td><td>bcTableCell</td></tr>
<tr><td>col</td><td>tableCol</td></tr>
<tr><td>colG</td><td>tableColGroup</td></tr>
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -422,17 +422,17 @@ nsAbsoluteContainingBlock::ReflowAbsolut
aContainingBlockHeight);
// Send the WillReflow() notification and position the frame
aKidFrame->WillReflow(aPresContext);
PRBool constrainHeight = (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE)
&& aConstrainHeight
// Don't split if told not to (e.g. for fixed frames)
- && (aDelegatingFrame->GetType() != nsGkAtoms::positionedInlineFrame)
+ && (aDelegatingFrame->GetType() != nsGkAtoms::inlineFrame)
//XXX we don't handle splitting frames for inline absolute containing blocks yet
&& (aKidFrame->GetRect().y <= aReflowState.availableHeight);
// Don't split things below the fold. (Ideally we shouldn't *have*
// anything totally below the fold, but we can't position frames
// across next-in-flow breaks yet.
if (constrainHeight) {
kidReflowState.availableHeight = aReflowState.availableHeight - border.top
- kidReflowState.mComputedMargin.top;
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -300,17 +300,17 @@ NS_IMPL_FRAMEARENA_HELPERS(nsBlockFrame)
nsBlockFrame::~nsBlockFrame()
{
}
void
nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
- mAbsoluteContainer.DestroyFrames(this, aDestructRoot);
+ DestroyAbsoluteFrames(aDestructRoot);
// Outside bullets are not in our child-list so check for them here
// and delete them when present.
if (mBullet && HaveOutsideBullet()) {
mBullet->DestroyFrom(aDestructRoot);
mBullet = nsnull;
}
mFloats.DestroyFramesFrom(aDestructRoot);
@@ -577,20 +577,17 @@ nsBlockFrame::GetCaretBaseline() const
}
/////////////////////////////////////////////////////////////////////////////
// Child frame enumeration
nsFrameList
nsBlockFrame::GetChildList(nsIAtom* aListName) const
{
- if (nsGkAtoms::absoluteList == aListName) {
- return mAbsoluteContainer.GetChildList();
- }
- else if (nsnull == aListName) {
+ if (nsnull == aListName) {
return mFrames;
}
else if (aListName == nsGkAtoms::overflowList) {
// XXXbz once we start using nsFrameList for our overflow list, we
// could switch GetChildList to returning a |const nsFrameList&|.
nsLineList* overflowLines = GetOverflowLines();
return overflowLines ? nsFrameList(overflowLines->front()->mFirstChild,
overflowLines->back()->LastChild())
@@ -612,35 +609,32 @@ nsBlockFrame::GetChildList(nsIAtom* aLis
: nsFrameList::EmptyList();
}
return nsContainerFrame::GetChildList(aListName);
}
#define NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX (NS_CONTAINER_LIST_COUNT_INCL_OC + 0)
#define NS_BLOCK_FRAME_FLOAT_LIST_INDEX (NS_CONTAINER_LIST_COUNT_INCL_OC + 1)
#define NS_BLOCK_FRAME_BULLET_LIST_INDEX (NS_CONTAINER_LIST_COUNT_INCL_OC + 2)
-#define NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX (NS_CONTAINER_LIST_COUNT_INCL_OC + 3)
-#define NS_BLOCK_FRAME_PUSHED_FLOATS_LIST_INDEX (NS_CONTAINER_LIST_COUNT_INCL_OC + 4)
+#define NS_BLOCK_FRAME_PUSHED_FLOATS_LIST_INDEX (NS_CONTAINER_LIST_COUNT_INCL_OC + 3)
// If adding/removing lists, don't forget to update the count in nsBlockFrame.h
nsIAtom*
nsBlockFrame::GetAdditionalChildListName(PRInt32 aIndex) const
{
if (aIndex < NS_CONTAINER_LIST_COUNT_INCL_OC)
return nsContainerFrame::GetAdditionalChildListName(aIndex);
switch (aIndex) {
case NS_BLOCK_FRAME_FLOAT_LIST_INDEX:
return nsGkAtoms::floatList;
case NS_BLOCK_FRAME_BULLET_LIST_INDEX:
return nsGkAtoms::bulletList;
case NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX:
return nsGkAtoms::overflowOutOfFlowList;
- case NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX:
- return nsGkAtoms::absoluteList;
case NS_BLOCK_FRAME_PUSHED_FLOATS_LIST_INDEX:
return nsGkAtoms::pushedFloatsList;
default:
return nsnull;
}
}
/* virtual */ PRBool
@@ -1168,30 +1162,31 @@ nsBlockFrame::Reflow(nsPresContext*
// condition 1.
// XXX checking oldSize is bogus, there are various reasons we might have
// reflowed but our size might not have been changed to what we
// asked for (e.g., we ended up being pushed to a new page)
// When WillReflowAgainForClearance is true, we will reflow again without
// resetting the size. Because of this, we must not reflow our abs-pos children
// in that situation --- what we think is our "new size"
// will not be our real new size. This also happens to be more efficient.
- if (mAbsoluteContainer.HasAbsoluteFrames()) {
+ if (HasAbsolutelyPositionedChildren()) {
+ nsAbsoluteContainingBlock* absoluteContainer = GetAbsoluteContainingBlock();
PRBool haveInterrupt = aPresContext->HasPendingInterrupt();
if (reflowState->WillReflowAgainForClearance() ||
haveInterrupt) {
// Make sure that when we reflow again we'll actually reflow all the abs
// pos frames that might conceivably depend on our size (or all of them,
// if we're dirty right now and interrupted; in that case we also need
// to mark them all with NS_FRAME_IS_DIRTY). Sadly, we can't do much
// better than that, because we don't really know what our size will be,
// and it might in fact not change on the followup reflow!
if (haveInterrupt && (GetStateBits() & NS_FRAME_IS_DIRTY)) {
- mAbsoluteContainer.MarkAllFramesDirty();
+ absoluteContainer->MarkAllFramesDirty();
} else {
- mAbsoluteContainer.MarkSizeDependentFramesDirty();
+ absoluteContainer->MarkSizeDependentFramesDirty();
}
} else {
nsSize containingBlockSize =
CalculateContainingBlockSizeForAbsolutes(*reflowState,
nsSize(aMetrics.width,
aMetrics.height));
// Mark frames that depend on changes we just made to this frame as dirty:
@@ -1205,22 +1200,22 @@ nsBlockFrame::Reflow(nsPresContext*
// If isRoot and we have auto height, then we are the initial
// containing block and the containing block height is the
// viewport height, which can't change during incremental
// reflow.
PRBool cbHeightChanged =
!(isRoot && NS_UNCONSTRAINEDSIZE == reflowState->ComputedHeight()) &&
aMetrics.height != oldSize.height;
- rv = mAbsoluteContainer.Reflow(this, aPresContext, *reflowState,
- state.mReflowStatus,
- containingBlockSize.width,
- containingBlockSize.height, PR_TRUE,
- cbWidthChanged, cbHeightChanged,
- &aMetrics.mOverflowAreas);
+ absoluteContainer->Reflow(this, aPresContext, *reflowState,
+ state.mReflowStatus,
+ containingBlockSize.width,
+ containingBlockSize.height, PR_TRUE,
+ cbWidthChanged, cbHeightChanged,
+ &aMetrics.mOverflowAreas);
//XXXfr Why isn't this rv (and others in this file) checked/returned?
}
}
// Determine if we need to repaint our border, background or outline
CheckInvalidateSizeChange(aMetrics);
@@ -4705,20 +4700,17 @@ nsBlockFrame::RemovePushedFloats()
NS_IMETHODIMP
nsBlockFrame::AppendFrames(nsIAtom* aListName,
nsFrameList& aFrameList)
{
if (aFrameList.IsEmpty()) {
return NS_OK;
}
if (aListName) {
- if (nsGkAtoms::absoluteList == aListName) {
- return mAbsoluteContainer.AppendFrames(this, aListName, aFrameList);
- }
- else if (nsGkAtoms::floatList == aListName) {
+ if (nsGkAtoms::floatList == aListName) {
mFloats.AppendFrames(nsnull, aFrameList);
return NS_OK;
}
else {
NS_ERROR("unexpected child list");
return NS_ERROR_INVALID_ARG;
}
}
@@ -4753,21 +4745,17 @@ NS_IMETHODIMP
nsBlockFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList)
{
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
if (aListName) {
- if (nsGkAtoms::absoluteList == aListName) {
- return mAbsoluteContainer.InsertFrames(this, aListName, aPrevFrame,
- aFrameList);
- }
- else if (nsGkAtoms::floatList == aListName) {
+ if (nsGkAtoms::floatList == aListName) {
mFloats.InsertFrames(this, aPrevFrame, aFrameList);
return NS_OK;
}
#ifdef IBMBIDI
else if (nsGkAtoms::nextBidi == aListName) {}
#endif // IBMBIDI
else {
NS_ERROR("unexpected child list");
@@ -5018,20 +5006,16 @@ nsBlockFrame::RemoveFrame(nsIAtom* aLis
if (nsnull == aListName) {
PRBool hasFloats = BlockHasAnyFloats(aOldFrame);
rv = DoRemoveFrame(aOldFrame, REMOVE_FIXED_CONTINUATIONS);
if (hasFloats) {
MarkSameFloatManagerLinesDirty(this);
}
}
- else if (nsGkAtoms::absoluteList == aListName) {
- mAbsoluteContainer.RemoveFrame(this, aListName, aOldFrame);
- return NS_OK;
- }
else if (nsGkAtoms::floatList == aListName) {
// Make sure to mark affected lines dirty for the float frame
// we are removing; this way is a bit messy, but so is the rest of the code.
// See bug 390762.
NS_ASSERTION(!aOldFrame->GetPrevContinuation(),
"RemoveFrame should not be called on pushed floats.");
for (nsIFrame* f = aOldFrame;
f && !(f->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER);
@@ -5064,19 +5048,19 @@ nsBlockFrame::DoRemoveOutOfFlowFrame(nsI
{
// The containing block is always the parent of aFrame.
nsBlockFrame* block = (nsBlockFrame*)aFrame->GetParent();
// Remove aFrame from the appropriate list.
const nsStyleDisplay* display = aFrame->GetStyleDisplay();
if (display->IsAbsolutelyPositioned()) {
// This also deletes the next-in-flows
- block->mAbsoluteContainer.RemoveFrame(block,
- nsGkAtoms::absoluteList,
- aFrame);
+ block->GetAbsoluteContainingBlock()->RemoveFrame(block,
+ nsGkAtoms::absoluteList,
+ aFrame);
}
else {
// First remove aFrame's next-in-flows
nsIFrame* nif = aFrame->GetNextInFlow();
if (nif) {
static_cast<nsContainerFrame*>(nif->GetParent())
->DeleteNextInFlowChild(aFrame->PresContext(), nif, PR_FALSE);
}
@@ -6251,18 +6235,16 @@ nsBlockFrame::BuildDisplayList(nsDisplay
DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
for (nsIFrame* f = mFloats.FirstChild(); f; f = f->GetNextSibling()) {
if (f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT)
BuildDisplayListForChild(aBuilder, f, aDirtyRect, aLists);
}
}
aBuilder->MarkFramesForDisplayList(this, mFloats, aDirtyRect);
- aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetChildList(),
- aDirtyRect);
// Don't use the line cursor if we might have a descendant placeholder ...
// it might skip lines that contain placeholders but don't themselves
// intersect with the dirty area.
// In particular, we really want to check ShouldDescendIntoFrame()
// on all our child frames, but that might be expensive. So we
// approximate it by checking it on |this|; if it's true for any
// frame in our child list, it's also true for |this|.
@@ -6507,20 +6489,17 @@ nsBlockFrame::Init(nsIContent* aCon
}
NS_IMETHODIMP
nsBlockFrame::SetInitialChildList(nsIAtom* aListName,
nsFrameList& aChildList)
{
nsresult rv = NS_OK;
- if (nsGkAtoms::absoluteList == aListName) {
- mAbsoluteContainer.SetInitialChildList(this, aListName, aChildList);
- }
- else if (nsGkAtoms::floatList == aListName) {
+ if (nsGkAtoms::floatList == aListName) {
mFloats.SetFrames(aChildList);
}
else {
nsPresContext* presContext = PresContext();
#ifdef DEBUG
// The only times a block that is an anonymous box is allowed to have a
// first-letter frame are when it's the block inside a non-anonymous cell,
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -79,17 +79,17 @@ class nsBlockInFlowLineIterator;
class nsBulletFrame;
class nsLineBox;
class nsFirstLineFrame;
class nsIntervalSet;
/**
* Child list name indices
* @see #GetAdditionalChildListName()
*/
-#define NS_BLOCK_LIST_COUNT (NS_CONTAINER_LIST_COUNT_INCL_OC + 5)
+#define NS_BLOCK_LIST_COUNT (NS_CONTAINER_LIST_COUNT_INCL_OC + 4)
/**
* Some invariants:
* -- The overflow out-of-flows list contains the out-of-
* flow frames whose placeholders are in the overflow list.
* -- A given piece of content has at most one placeholder
* frame in a block's normal child list.
* -- While a block is being reflowed, and from then until
@@ -336,17 +336,16 @@ public:
*/
static nsBlockFrame* GetNearestAncestorBlock(nsIFrame* aCandidate);
protected:
nsBlockFrame(nsStyleContext* aContext)
: nsHTMLContainerFrame(aContext)
, mMinWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
, mPrefWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
- , mAbsoluteContainer(nsGkAtoms::absoluteList)
{
#ifdef DEBUG
InitDebugFlags();
#endif
}
virtual ~nsBlockFrame();
#ifdef DEBUG
@@ -771,20 +770,16 @@ protected:
// XXX_fix_me: subclass one more time!
// For list-item frames, this is the bullet frame.
nsBulletFrame* mBullet;
friend class nsBlockReflowState;
friend class nsBlockInFlowLineIterator;
-private:
- nsAbsoluteContainingBlock mAbsoluteContainer;
-
-
#ifdef DEBUG
public:
static PRBool gLamePaintMetrics;
static PRBool gLameReflowMetrics;
static PRBool gNoisy;
static PRBool gNoisyDamageRepair;
static PRBool gNoisyIntrinsic;
static PRBool gNoisyReflow;
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -47,49 +47,45 @@
#include "nsRenderingContext.h"
#include "nsGUIEvent.h"
#include "nsStyleConsts.h"
#include "nsGkAtoms.h"
#include "nsEventStateManager.h"
#include "nsIPresShell.h"
#include "nsIScrollPositionListener.h"
#include "nsDisplayList.h"
-#include "nsAbsoluteContainingBlock.h"
#include "nsCSSFrameConstructor.h"
#include "nsFrameManager.h"
// for focus
#include "nsIDOMWindowInternal.h"
#include "nsIScrollableFrame.h"
#include "nsIDocShell.h"
#ifdef DEBUG_rods
//#define DEBUG_CANVAS_FOCUS
#endif
-#define CANVAS_ABS_POS_CHILD_LIST NS_CONTAINER_LIST_COUNT_INCL_OC
-
nsIFrame*
NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
return new (aPresShell) nsCanvasFrame(aContext);
}
NS_IMPL_FRAMEARENA_HELPERS(nsCanvasFrame)
NS_QUERYFRAME_HEAD(nsCanvasFrame)
NS_QUERYFRAME_ENTRY(nsCanvasFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsHTMLContainerFrame)
void
nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
- mAbsoluteContainer.DestroyFrames(this, aDestructRoot);
-
+ DestroyAbsoluteFrames(aDestructRoot);
nsIScrollableFrame* sf =
PresContext()->GetPresShell()->GetRootScrollFrameAsScrollable();
if (sf) {
sf->RemoveScrollPositionListener(this);
}
nsHTMLContainerFrame::DestroyFrom(aDestructRoot);
}
@@ -121,31 +117,25 @@ nsCanvasFrame::SetHasFocus(PRBool aHasFo
}
return NS_OK;
}
NS_IMETHODIMP
nsCanvasFrame::SetInitialChildList(nsIAtom* aListName,
nsFrameList& aChildList)
{
- if (nsGkAtoms::absoluteList == aListName)
- return mAbsoluteContainer.SetInitialChildList(this, aListName, aChildList);
-
NS_ASSERTION(aListName || aChildList.IsEmpty() || aChildList.OnlyChild(),
"Primary child list can have at most one frame in it");
return nsHTMLContainerFrame::SetInitialChildList(aListName, aChildList);
}
NS_IMETHODIMP
nsCanvasFrame::AppendFrames(nsIAtom* aListName,
nsFrameList& aFrameList)
{
- if (nsGkAtoms::absoluteList == aListName)
- return mAbsoluteContainer.AppendFrames(this, aListName, aFrameList);
-
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
return NS_ERROR_INVALID_ARG;
}
if (!mFrames.IsEmpty()) {
@@ -168,37 +158,29 @@ nsCanvasFrame::AppendFrames(nsIAtom*
return NS_OK;
}
NS_IMETHODIMP
nsCanvasFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList)
{
- if (nsGkAtoms::absoluteList == aListName)
- return mAbsoluteContainer.InsertFrames(this, aListName, aPrevFrame, aFrameList);
-
// Because we only support a single child frame inserting is the same
// as appending
NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame");
if (aPrevFrame)
return NS_ERROR_UNEXPECTED;
return AppendFrames(aListName, aFrameList);
}
NS_IMETHODIMP
nsCanvasFrame::RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame)
{
- if (nsGkAtoms::absoluteList == aListName) {
- mAbsoluteContainer.RemoveFrame(this, aListName, aOldFrame);
- return NS_OK;
- }
-
NS_ASSERTION(!aListName, "unexpected child list name");
if (aListName) {
// We only support the unnamed principal child list
return NS_ERROR_INVALID_ARG;
}
if (aOldFrame != mFrames.FirstChild())
return NS_ERROR_FAILURE;
@@ -213,34 +195,16 @@ nsCanvasFrame::RemoveFrame(nsIAtom*
mFrames.DestroyFrame(aOldFrame);
PresContext()->PresShell()->
FrameNeedsReflow(this, nsIPresShell::eTreeChange,
NS_FRAME_HAS_DIRTY_CHILDREN);
return NS_OK;
}
-nsIAtom*
-nsCanvasFrame::GetAdditionalChildListName(PRInt32 aIndex) const
-{
- if (CANVAS_ABS_POS_CHILD_LIST == aIndex)
- return nsGkAtoms::absoluteList;
-
- return nsHTMLContainerFrame::GetAdditionalChildListName(aIndex);
-}
-
-nsFrameList
-nsCanvasFrame::GetChildList(nsIAtom* aListName) const
-{
- if (nsGkAtoms::absoluteList == aListName)
- return mAbsoluteContainer.GetChildList();
-
- return nsHTMLContainerFrame::GetChildList(aListName);
-}
-
nsRect nsCanvasFrame::CanvasArea() const
{
// Not clear which overflow rect we want here, but it probably doesn't
// matter.
nsRect result(GetVisualOverflowRect());
nsIScrollableFrame *scrollableFrame = do_QueryFrame(GetParent());
if (scrollableFrame) {
@@ -309,19 +273,16 @@ nsCanvasFrame::BuildDisplayList(nsDispla
const nsDisplayListSet& aLists)
{
nsresult rv;
if (GetPrevInFlow()) {
DisplayOverflowContainers(aBuilder, aDirtyRect, aLists);
}
- aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetChildList(),
- aDirtyRect);
-
// Force a background to be shown. We may have a background propagated to us,
// in which case GetStyleBackground wouldn't have the right background
// and the code in nsFrame::DisplayBorderBackgroundOutline might not give us
// a background.
// We don't have any border or outline, and our background draws over
// the overflow area, so just add nsDisplayCanvasBackground instead of
// calling DisplayBorderBackgroundOutline.
if (IsVisibleForPainting(aBuilder)) {
@@ -548,25 +509,16 @@ nsCanvasFrame::Reflow(nsPresContext*
} else {
aDesiredSize.height = aReflowState.ComputedHeight();
}
aDesiredSize.SetOverflowAreasToDesiredBounds();
aDesiredSize.mOverflowAreas.UnionWith(
kidDesiredSize.mOverflowAreas + kidPt);
- if (mAbsoluteContainer.HasAbsoluteFrames()) {
- PRBool widthChanged = aDesiredSize.width != mRect.width;
- PRBool heightChanged = aDesiredSize.height != mRect.height;
- mAbsoluteContainer.Reflow(this, aPresContext, aReflowState, aStatus,
- aDesiredSize.width, aDesiredSize.height,
- PR_TRUE, widthChanged, heightChanged,
- &aDesiredSize.mOverflowAreas);
- }
-
// Handle invalidating fixed-attachment backgrounds propagated to the
// canvas when the canvas size (and therefore the background positioning
// area's size) changes. Such backgrounds are not invalidated in the
// normal manner because the size of the original frame for that background
// may not have changed.
//
// This isn't the right fix for this issue, taken more generally. In
// particular, this doesn't handle fixed-attachment backgrounds that are *not*
@@ -597,17 +549,17 @@ nsCanvasFrame::Reflow(nsPresContext*
}
if (prevCanvasFrame) {
ReflowOverflowContainerChildren(aPresContext, aReflowState,
aDesiredSize.mOverflowAreas, 0,
aStatus);
}
- FinishAndStoreOverflow(&aDesiredSize);
+ FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
NS_FRAME_TRACE_REFLOW_OUT("nsCanvasFrame::Reflow", aStatus);
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return NS_OK;
}
PRIntn
nsCanvasFrame::GetSkipSides() const
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -37,17 +37,16 @@
/* rendering object that goes directly inside the document's scrollbars */
#ifndef nsCanvasFrame_h___
#define nsCanvasFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsIScrollPositionListener.h"
-#include "nsAbsoluteContainingBlock.h"
#include "nsDisplayList.h"
#include "nsGkAtoms.h"
class nsPresContext;
class nsRenderingContext;
class nsEvent;
/**
@@ -59,18 +58,17 @@ class nsEvent;
*/
class nsCanvasFrame : public nsHTMLContainerFrame,
public nsIScrollPositionListener
{
public:
nsCanvasFrame(nsStyleContext* aContext)
: nsHTMLContainerFrame(aContext),
mDoPaintFocus(PR_FALSE),
- mAddedScrollPositionListener(PR_FALSE),
- mAbsoluteContainer(nsGkAtoms::absoluteList) {}
+ mAddedScrollPositionListener(PR_FALSE) {}
NS_DECL_QUERYFRAME_TARGET(nsCanvasFrame)
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS
virtual void DestroyFrom(nsIFrame* aDestructRoot);
@@ -79,19 +77,16 @@ public:
NS_IMETHOD AppendFrames(nsIAtom* aListName,
nsFrameList& aFrameList);
NS_IMETHOD InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList);
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
- virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
- virtual nsFrameList GetChildList(nsIAtom* aListName) const;
-
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
NS_IMETHOD Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
virtual PRBool IsContainingBlock() const { return PR_TRUE; }
virtual PRBool IsFrameOfType(PRUint32 aFlags) const
@@ -147,17 +142,16 @@ public:
nsRect CanvasArea() const;
protected:
virtual PRIntn GetSkipSides() const;
// Data members
PRPackedBool mDoPaintFocus;
PRPackedBool mAddedScrollPositionListener;
- nsAbsoluteContainingBlock mAbsoluteContainer;
};
/**
* Override nsDisplayBackground methods so that we pass aBGClipRect to
* PaintBackground, covering the whole overflow area.
* We can also paint an "extra background color" behind the normal
* background.
*/
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -314,37 +314,37 @@ nsContainerFrame::GetChildList(nsIAtom*
}
if (nsGkAtoms::excessOverflowContainersList == aListName) {
nsFrameList* list = GetPropTableFrames(PresContext(),
ExcessOverflowContainersProperty());
return list ? *list : nsFrameList::EmptyList();
}
- return nsFrameList::EmptyList();
+ return nsSplittableFrame::GetChildList(aListName);
}
-#define NS_CONTAINER_FRAME_OVERFLOW_LIST_INDEX 0
-#define NS_CONTAINER_FRAME_OVERFLOW_CONTAINERS_LIST_INDEX 1
-#define NS_CONTAINER_FRAME_EXCESS_OVERFLOW_CONTAINERS_LIST_INDEX 2
+#define NS_CONTAINER_FRAME_OVERFLOW_LIST_INDEX 1
+#define NS_CONTAINER_FRAME_OVERFLOW_CONTAINERS_LIST_INDEX 2
+#define NS_CONTAINER_FRAME_EXCESS_OVERFLOW_CONTAINERS_LIST_INDEX 3
// If adding/removing lists, don't forget to update count in .h file
nsIAtom*
nsContainerFrame::GetAdditionalChildListName(PRInt32 aIndex) const
{
if (NS_CONTAINER_FRAME_OVERFLOW_LIST_INDEX == aIndex)
return nsGkAtoms::overflowList;
else if (IsFrameOfType(nsIFrame::eCanContainOverflowContainers)) {
if (NS_CONTAINER_FRAME_OVERFLOW_CONTAINERS_LIST_INDEX == aIndex)
return nsGkAtoms::overflowContainersList;
else if (NS_CONTAINER_FRAME_EXCESS_OVERFLOW_CONTAINERS_LIST_INDEX == aIndex)
return nsGkAtoms::excessOverflowContainersList;
}
- return nsnull;
+ return nsSplittableFrame::GetAdditionalChildListName(aIndex);
}
/////////////////////////////////////////////////////////////////////////////
// Painting/Events
NS_IMETHODIMP
nsContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -45,19 +45,17 @@
#include "nsFrameList.h"
#include "nsLayoutUtils.h"
#include "nsAutoPtr.h"
/**
* Child list name indices
* @see #GetAdditionalChildListName()
*/
-#define NS_CONTAINER_LIST_COUNT_SANS_OC 1
- // for frames that don't use overflow containers
-#define NS_CONTAINER_LIST_COUNT_INCL_OC 3
+#define NS_CONTAINER_LIST_COUNT_INCL_OC 4
// for frames that support overflow containers
// Option flags for ReflowChild() and FinishReflowChild()
// member functions
#define NS_FRAME_NO_MOVE_VIEW 0x0001
#define NS_FRAME_NO_MOVE_FRAME (0x0002 | NS_FRAME_NO_MOVE_VIEW)
#define NS_FRAME_NO_SIZE_VIEW 0x0004
#define NS_FRAME_NO_VISIBILITY 0x0008
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -954,23 +954,33 @@ nsFrame::GetBaseline() const
}
// Child frame enumeration
nsIAtom*
nsFrame::GetAdditionalChildListName(PRInt32 aIndex) const
{
NS_PRECONDITION(aIndex >= 0, "invalid index number");
+ // An index of 0 should always be an absolute list, we should ignore anything
+ // else if child frame types have ignored them.
+ if (aIndex == 0) {
+ return GetAbsoluteListName();
+ }
return nsnull;
}
nsFrameList
nsFrame::GetChildList(nsIAtom* aListName) const
{
- return nsFrameList::EmptyList();
+ if (IsAbsoluteContainer() &&
+ aListName == GetAbsoluteListName()) {
+ return GetAbsoluteContainingBlock()->GetChildList();
+ } else {
+ return nsFrameList::EmptyList();
+ }
}
static nsIFrame*
GetActiveSelectionFrame(nsPresContext* aPresContext, nsIFrame* aFrame)
{
nsIContent* capturingContent = nsIPresShell::GetCapturingContent();
if (capturingContent) {
nsIFrame* activeFrame = aPresContext->GetPrimaryFrameFor(capturingContent);
@@ -1482,16 +1492,19 @@ nsIFrame::BuildDisplayListForStackingCon
#ifdef MOZ_SVG
PRBool usingSVGEffects = nsSVGIntegrationUtils::UsingEffectsForFrame(this);
if (usingSVGEffects) {
dirtyRect =
nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, dirtyRect);
}
#endif
+ // Mark the display list items for absolutely positioned children
+ MarkAbsoluteFramesForDisplayList(aBuilder, aDirtyRect);
+
nsDisplayListCollection set;
nsresult rv;
{
nsDisplayListBuilder::AutoIsRootSetter rootSetter(aBuilder, PR_TRUE);
nsDisplayListBuilder::AutoInTransformSetter
inTransformSetter(aBuilder, inTransform);
rv = BuildDisplayList(aBuilder, dirtyRect, set);
}
@@ -1616,17 +1629,17 @@ nsIFrame::BuildDisplayListForChild(nsDis
PRUint32 aFlags) {
// If painting is restricted to just the background of the top level frame,
// then we have nothing to do here.
if (aBuilder->IsBackgroundOnly())
return NS_OK;
if (aChild->GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE)
return NS_OK;
-
+
const nsStyleDisplay* disp = aChild->GetStyleDisplay();
// PR_TRUE if this is a real or pseudo stacking context
PRBool pseudoStackingContext =
(aFlags & DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT) != 0;
// XXX we REALLY need a "are you an inline-block sort of thing?" here!!!
if ((aFlags & DISPLAY_CHILD_INLINE) &&
(disp->mDisplay != NS_STYLE_DISPLAY_INLINE ||
aChild->IsContainingBlock() ||
@@ -1662,19 +1675,25 @@ nsIFrame::BuildDisplayListForChild(nsDis
dirty = *savedDirty;
} else {
// The out-of-flow frame did not intersect the dirty area. We may still
// need to traverse into it, since it may contain placeholders we need
// to enter to reach other out-of-flow frames that are visible.
dirty.SetEmpty();
}
pseudoStackingContext = PR_TRUE;
- } else if (aBuilder->GetSelectedFramesOnly() &&
- aChild->IsLeaf() &&
- !(aChild->GetStateBits() & NS_FRAME_SELECTED_CONTENT)) {
+ }
+
+ // Mark the display list items for absolutely positioned children
+ aChild->MarkAbsoluteFramesForDisplayList(aBuilder, dirty);
+
+ if (childType != nsGkAtoms::placeholderFrame &&
+ aBuilder->GetSelectedFramesOnly() &&
+ aChild->IsLeaf() &&
+ !(aChild->GetStateBits() & NS_FRAME_SELECTED_CONTENT)) {
return NS_OK;
}
if (aBuilder->GetIncludeAllOutOfFlows() &&
(aChild->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
dirty = aChild->GetVisualOverflowRect();
} else if (!(aChild->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
// No need to descend into aChild to catch placeholders for visible
@@ -1830,16 +1849,25 @@ nsIFrame::BuildDisplayListForChild(nsDis
// This doesn't affect correctness because the positioned descendants list
// is sorted by z-order and content in BuildDisplayListForStackingContext,
// but it means that sort routine needs to do less work.
aLists.PositionedDescendants()->AppendToTop(&extraPositionedDescendants);
return NS_OK;
}
void
+nsIFrame::MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder,
+ const nsRect& aDirtyRect)
+{
+ if (IsAbsoluteContainer()) {
+ aBuilder->MarkFramesForDisplayList(this, GetAbsoluteContainingBlock()->GetChildList(), aDirtyRect);
+ }
+}
+
+void
nsIFrame::WrapReplacedContentForBorderRadius(nsDisplayListBuilder* aBuilder,
nsDisplayList* aFromList,
const nsDisplayListSet& aToLists)
{
nscoord radii[8];
if (GetContentBoxBorderRadii(radii)) {
// If we have a border-radius, we have to clip our content to that
// radius.
@@ -3579,16 +3607,17 @@ nsFrame::WillReflow(nsPresContext* aPres
NS_IMETHODIMP
nsFrame::DidReflow(nsPresContext* aPresContext,
const nsHTMLReflowState* aReflowState,
nsDidReflowStatus aStatus)
{
NS_FRAME_TRACE_MSG(NS_FRAME_TRACE_CALLS,
("nsFrame::DidReflow: aStatus=%d", aStatus));
+
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
mState &= ~(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY |
NS_FRAME_HAS_DIRTY_CHILDREN);
}
// Notify the percent height observer if there is a percent height.
// The observer may be able to initiate another reflow with a computed
// height. This happens in the case where a table cell has no computed
@@ -3599,16 +3628,65 @@ nsFrame::DidReflow(nsPresContext*
if (height.HasPercent()) {
aReflowState->mPercentHeightObserver->NotifyPercentHeight(*aReflowState);
}
}
return NS_OK;
}
+void
+nsFrame::FinishReflowWithAbsoluteFrames(nsPresContext* aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus)
+{
+ ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
+
+ FinishAndStoreOverflow(&aDesiredSize);
+}
+
+void
+nsFrame::DestroyAbsoluteFrames(nsIFrame* aDestructRoot)
+{
+ if (IsAbsoluteContainer()) {
+ GetAbsoluteContainingBlock()->DestroyFrames(this, aDestructRoot);
+ }
+}
+
+void
+nsFrame::ReflowAbsoluteFrames(nsPresContext* aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus)
+{
+ if (HasAbsolutelyPositionedChildren()) {
+ nsAbsoluteContainingBlock* absoluteContainer = GetAbsoluteContainingBlock();
+
+ // Let the absolutely positioned container reflow any absolutely positioned
+ // child frames that need to be reflowed
+
+ // The containing block for the abs pos kids is formed by our padding edge.
+ nsMargin computedBorder =
+ aReflowState.mComputedBorderPadding - aReflowState.mComputedPadding;
+ nscoord containingBlockWidth =
+ aDesiredSize.width - computedBorder.LeftRight();
+ nscoord containingBlockHeight =
+ aDesiredSize.height - computedBorder.TopBottom();
+
+ nsContainerFrame* container = do_QueryFrame(this);
+ NS_ASSERTION(container, "Abs-pos children only supported on container frames for now");
+
+ absoluteContainer->Reflow(container, aPresContext, aReflowState, aStatus,
+ containingBlockWidth, containingBlockHeight,
+ PR_TRUE, PR_TRUE, PR_TRUE, // XXX could be optimized
+ &aDesiredSize.mOverflowAreas);
+ }
+}
+
/* virtual */ PRBool
nsFrame::CanContinueTextRun() const
{
// By default, a frame will *not* allow a text run to be continued
// through it.
return PR_FALSE;
}
@@ -6184,18 +6262,17 @@ nsIFrame::SetOverflowAreas(const nsOverf
*overflow = aOverflowAreas;
}
}
inline PRBool
IsInlineFrame(nsIFrame *aFrame)
{
nsIAtom *type = aFrame->GetType();
- return type == nsGkAtoms::inlineFrame ||
- type == nsGkAtoms::positionedInlineFrame;
+ return type == nsGkAtoms::inlineFrame;
}
void
nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
nsSize aNewSize)
{
nsRect bounds(nsPoint(0, 0), aNewSize);
@@ -7900,17 +7977,16 @@ void DR_State::InitFrameTypeTable()
AddFrameTypeInfo(nsGkAtoms::imageFrame, "img", "image");
AddFrameTypeInfo(nsGkAtoms::inlineFrame, "inline", "inline");
AddFrameTypeInfo(nsGkAtoms::letterFrame, "letter", "letter");
AddFrameTypeInfo(nsGkAtoms::lineFrame, "line", "line");
AddFrameTypeInfo(nsGkAtoms::listControlFrame, "select", "select");
AddFrameTypeInfo(nsGkAtoms::objectFrame, "obj", "object");
AddFrameTypeInfo(nsGkAtoms::pageFrame, "page", "page");
AddFrameTypeInfo(nsGkAtoms::placeholderFrame, "place", "placeholder");
- AddFrameTypeInfo(nsGkAtoms::positionedInlineFrame, "posInline", "positionedInline");
AddFrameTypeInfo(nsGkAtoms::canvasFrame, "canvas", "canvas");
AddFrameTypeInfo(nsGkAtoms::rootFrame, "root", "root");
AddFrameTypeInfo(nsGkAtoms::scrollFrame, "scroll", "scroll");
AddFrameTypeInfo(nsGkAtoms::tableCaptionFrame, "caption", "tableCaption");
AddFrameTypeInfo(nsGkAtoms::tableCellFrame, "cell", "tableCell");
AddFrameTypeInfo(nsGkAtoms::bcTableCellFrame, "bcCell", "bcTableCell");
AddFrameTypeInfo(nsGkAtoms::tableColFrame, "col", "tableCol");
AddFrameTypeInfo(nsGkAtoms::tableColGroupFrame, "colG", "tableColGroup");
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -323,16 +323,25 @@ public:
NS_IMETHOD WillReflow(nsPresContext* aPresContext);
NS_IMETHOD Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD DidReflow(nsPresContext* aPresContext,
const nsHTMLReflowState* aReflowState,
nsDidReflowStatus aStatus);
+ void ReflowAbsoluteFrames(nsPresContext* aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus);
+ void FinishReflowWithAbsoluteFrames(nsPresContext* aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus);
+ void DestroyAbsoluteFrames(nsIFrame* aDestructRoot);
virtual PRBool CanContinueTextRun() const;
// Selection Methods
// XXX Doc me... (in nsIFrame.h puhleeze)
// XXX If these are selection specific, then the name should imply selection
// rather than generic event processing, e.g., SelectionHandlePress...
NS_IMETHOD HandlePress(nsPresContext* aPresContext,
nsGUIEvent * aEvent,
--- a/layout/generic/nsHTMLParts.h
+++ b/layout/generic/nsHTMLParts.h
@@ -134,18 +134,16 @@ nsIFrame*
NS_NewViewportFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
-NS_NewPositionedInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewContinuingTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewEmptyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
inline nsIFrame*
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -1570,17 +1570,17 @@ nsHTMLReflowState::ComputeContainingBloc
aContainingBlockWidth = aContainingBlockRS->mComputedWidth;
aContainingBlockHeight = aContainingBlockRS->mComputedHeight;
if (NS_FRAME_GET_TYPE(mFrameType) == NS_CSS_FRAME_TYPE_ABSOLUTE) {
// See if the ancestor is block-level or inline-level
if (NS_FRAME_GET_TYPE(aContainingBlockRS->mFrameType) == NS_CSS_FRAME_TYPE_INLINE) {
// Base our size on the actual size of the frame. In cases when this is
// completely bogus (eg initial reflow), this code shouldn't even be
- // called, since the code in nsPositionedInlineFrame::Reflow will pass in
+ // called, since the code in nsInlineFrame::Reflow will pass in
// the containing block dimensions to our constructor.
// XXXbz we should be taking the in-flows into account too, but
// that's very hard.
nsMargin computedBorder = aContainingBlockRS->mComputedBorderPadding -
aContainingBlockRS->mComputedPadding;
aContainingBlockWidth = aContainingBlockRS->frame->GetRect().width -
computedBorder.LeftRight();;
NS_ASSERTION(aContainingBlockWidth >= 0,
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -583,16 +583,18 @@ public:
*
* This is only called once for a given child list, and won't be called
* at all for child lists with no initial list of frames.
*
* @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. Must not be empty.
+ * This method cannot handle the child list returned by
+ * GetAbsoluteListName().
* @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
* initial list of frames has already been set for that child list,
* NS_OK otherwise. In this case, SetInitialChildList empties out
* aChildList in the process of moving the frames over to its own
* child list.
* @see #Init()
@@ -2719,16 +2721,18 @@ protected:
nsRect mRect;
nsIContent* mContent;
nsStyleContext* mStyleContext;
nsIFrame* mParent;
private:
nsIFrame* mNextSibling; // doubly-linked list of frames
nsIFrame* mPrevSibling; // Do not touch outside SetNextSibling!
+ void MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect);
+
static void DestroyPaintedPresShellList(void* propertyValue) {
nsTArray<nsWeakPtr>* list = static_cast<nsTArray<nsWeakPtr>*>(propertyValue);
list->Clear();
delete list;
}
// Stores weak references to all the PresShells that were painted during
// the last paint event so that we can increment their paint count during
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -42,17 +42,16 @@
#include "nsBlockFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsGkAtoms.h"
#include "nsHTMLParts.h"
#include "nsStyleContext.h"
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsRenderingContext.h"
-#include "nsAbsoluteContainingBlock.h"
#include "nsCSSAnonBoxes.h"
#include "nsAutoPtr.h"
#include "nsFrameManager.h"
#ifdef ACCESSIBILITY
#include "nsIServiceManager.h"
#include "nsAccessibilityService.h"
#endif
#include "nsDisplayList.h"
@@ -409,17 +408,19 @@ nsInlineFrame::Reflow(nsPresContext*
if (mFrames.IsEmpty()) {
// Try to pull over one frame before starting so that we know
// whether we have an anonymous block or not.
PRBool complete;
(void) PullOneFrame(aPresContext, irs, &complete);
}
rv = ReflowFrames(aPresContext, aReflowState, irs, aMetrics, aStatus);
-
+
+ ReflowAbsoluteFrames(aPresContext, aMetrics, aReflowState, aStatus);
+
// Note: the line layout code will properly compute our
// overflow-rect state for us.
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
return rv;
}
/* virtual */ PRBool
@@ -917,16 +918,23 @@ nsInlineFrame::GetBaseline() const
nsRefPtr<nsFontMetrics> fm;
nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
if (fm) {
ascent = fm->MaxAscent();
}
return NS_MIN(mRect.height, ascent + GetUsedBorderAndPadding().top);
}
+void
+nsInlineFrame::DestroyFrom(nsIFrame* aDestructRoot)
+{
+ DestroyAbsoluteFrames(aDestructRoot);
+ nsInlineFrameSuper::DestroyFrom(aDestructRoot);
+}
+
#ifdef ACCESSIBILITY
already_AddRefed<nsAccessible>
nsInlineFrame::CreateAccessible()
{
// Broken image accessibles are created here, because layout
// replaces the image or image control frame with an inline frame
nsIAtom *tagAtom = mContent->Tag();
if ((tagAtom == nsGkAtoms::img || tagAtom == nsGkAtoms::input ||
@@ -1096,16 +1104,18 @@ nsFirstLineFrame::Reflow(nsPresContext*
}
NS_ASSERTION(!aReflowState.mLineLayout->GetInFirstLine(),
"Nested first-line frames? BOGUS");
aReflowState.mLineLayout->SetInFirstLine(PR_TRUE);
rv = ReflowFrames(aPresContext, aReflowState, irs, aMetrics, aStatus);
aReflowState.mLineLayout->SetInFirstLine(PR_FALSE);
+ ReflowAbsoluteFrames(aPresContext, aMetrics, aReflowState, aStatus);
+
// Note: the line layout code will properly compute our overflow state for us
return rv;
}
/* virtual */ void
nsFirstLineFrame::PullOverflowsFromPrevInFlow()
{
@@ -1116,167 +1126,8 @@ nsFirstLineFrame::PullOverflowsFromPrevI
// Assume that our prev-in-flow has the same line container that we do.
const nsFrameList::Slice& newFrames =
mFrames.InsertFrames(this, nsnull, *prevOverflowFrames);
ReparentChildListStyle(PresContext(), newFrames, this);
}
}
}
-//////////////////////////////////////////////////////////////////////
-
-nsIFrame*
-NS_NewPositionedInlineFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
-{
- return new (aPresShell) nsPositionedInlineFrame(aContext);
-}
-
-NS_IMPL_FRAMEARENA_HELPERS(nsPositionedInlineFrame)
-
-void
-nsPositionedInlineFrame::DestroyFrom(nsIFrame* aDestructRoot)
-{
- mAbsoluteContainer.DestroyFrames(this, aDestructRoot);
- nsInlineFrame::DestroyFrom(aDestructRoot);
-}
-
-NS_IMETHODIMP
-nsPositionedInlineFrame::SetInitialChildList(nsIAtom* aListName,
- nsFrameList& aChildList)
-{
- nsresult rv;
-
- if (nsGkAtoms::absoluteList == aListName) {
- rv = mAbsoluteContainer.SetInitialChildList(this, aListName, aChildList);
- } else {
- rv = nsInlineFrame::SetInitialChildList(aListName, aChildList);
- }
-
- return rv;
-}
-
-NS_IMETHODIMP
-nsPositionedInlineFrame::AppendFrames(nsIAtom* aListName,
- nsFrameList& aFrameList)
-{
- nsresult rv;
-
- if (nsGkAtoms::absoluteList == aListName) {
- rv = mAbsoluteContainer.AppendFrames(this, aListName, aFrameList);
- } else {
- rv = nsInlineFrame::AppendFrames(aListName, aFrameList);
- }
-
- return rv;
-}
-
-NS_IMETHODIMP
-nsPositionedInlineFrame::InsertFrames(nsIAtom* aListName,
- nsIFrame* aPrevFrame,
- nsFrameList& aFrameList)
-{
- nsresult rv;
-
- if (nsGkAtoms::absoluteList == aListName) {
- rv = mAbsoluteContainer.InsertFrames(this, aListName, aPrevFrame,
- aFrameList);
- } else {
- rv = nsInlineFrame::InsertFrames(aListName, aPrevFrame, aFrameList);
- }
-
- return rv;
-}
-
-NS_IMETHODIMP
-nsPositionedInlineFrame::RemoveFrame(nsIAtom* aListName,
- nsIFrame* aOldFrame)
-{
- nsresult rv;
-
- if (nsGkAtoms::absoluteList == aListName) {
- mAbsoluteContainer.RemoveFrame(this, aListName, aOldFrame);
- rv = NS_OK;
- } else {
- rv = nsInlineFrame::RemoveFrame(aListName, aOldFrame);
- }
-
- return rv;
-}
-
-NS_IMETHODIMP
-nsPositionedInlineFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
- const nsRect& aDirtyRect,
- const nsDisplayListSet& aLists)
-{
- aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetChildList(),
- aDirtyRect);
- return nsHTMLContainerFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
-}
-
-nsIAtom*
-nsPositionedInlineFrame::GetAdditionalChildListName(PRInt32 aIndex) const
-{
- if (0 == aIndex) {
- return nsGkAtoms::absoluteList;
- }
- return nsnull;
-}
-
-nsFrameList
-nsPositionedInlineFrame::GetChildList(nsIAtom* aListName) const
-{
- if (nsGkAtoms::absoluteList == aListName)
- return mAbsoluteContainer.GetChildList();
-
- return nsInlineFrame::GetChildList(aListName);
-}
-
-nsIAtom*
-nsPositionedInlineFrame::GetType() const
-{
- return nsGkAtoms::positionedInlineFrame;
-}
-
-NS_IMETHODIMP
-nsPositionedInlineFrame::Reflow(nsPresContext* aPresContext,
- nsHTMLReflowMetrics& aDesiredSize,
- const nsHTMLReflowState& aReflowState,
- nsReflowStatus& aStatus)
-{
- nsresult rv = NS_OK;
-
- // Don't bother optimizing for fast incremental reflow of absolute
- // children of an inline
-
- // Let the inline frame do its reflow first
- rv = nsInlineFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
-
- // Let the absolutely positioned container reflow any absolutely positioned
- // child frames that need to be reflowed
- // We want to do this under either of two conditions:
- // 1. If we didn't do the incremental reflow above.
- // 2. If our size changed.
- // Even though it's the padding edge that's the containing block, we
- // can use our rect (the border edge) since if the border style
- // changed, the reflow would have been targeted at us so we'd satisfy
- // condition 1.
- if (NS_SUCCEEDED(rv) &&
- mAbsoluteContainer.HasAbsoluteFrames()) {
- // The containing block for the abs pos kids is formed by our padding edge.
- nsMargin computedBorder =
- aReflowState.mComputedBorderPadding - aReflowState.mComputedPadding;
- nscoord containingBlockWidth =
- aDesiredSize.width - computedBorder.LeftRight();
- nscoord containingBlockHeight =
- aDesiredSize.height - computedBorder.TopBottom();
-
- // Factor the absolutely positioned child bounds into the overflow area
- // Don't include this frame's bounds, nor its inline descendants' bounds,
- // and don't store the overflow property.
- // That will all be done by nsLineLayout::RelativePositionFrames.
- rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState, aStatus,
- containingBlockWidth, containingBlockHeight,
- PR_TRUE, PR_TRUE, PR_TRUE, // XXX could be optimized
- &aDesiredSize.mOverflowAreas);
- }
-
- return rv;
-}
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -36,17 +36,16 @@
* ***** END LICENSE BLOCK ***** */
/* rendering object for CSS display:inline objects */
#ifndef nsInlineFrame_h___
#define nsInlineFrame_h___
#include "nsHTMLContainerFrame.h"
-#include "nsAbsoluteContainingBlock.h"
#include "nsLineLayout.h"
class nsAnonymousBlockFrame;
#define nsInlineFrameSuper nsHTMLContainerFrame
/** In Bidi left (or right) margin/padding/border should be applied to left
* (or right) most frame (or a continuation frame).
@@ -92,16 +91,18 @@ public:
{
return nsInlineFrameSuper::IsFrameOfType(aFlags &
~(nsIFrame::eBidiInlineContainer | nsIFrame::eLineParticipant));
}
virtual PRBool IsEmpty();
virtual PRBool IsSelfEmpty();
+ virtual void DestroyFrom(nsIFrame* aDestructRoot);
+
virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset,
PRBool aRespectClusters = PR_TRUE);
// nsIHTMLReflow overrides
virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
InlineMinWidthData *aData);
virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
InlinePrefWidthData *aData);
@@ -222,58 +223,9 @@ public:
protected:
nsFirstLineFrame(nsStyleContext* aContext) : nsInlineFrame(aContext) {}
virtual nsIFrame* PullOneFrame(nsPresContext* aPresContext,
InlineReflowState& rs,
PRBool* aIsComplete);
};
-//----------------------------------------------------------------------
-
-// Derived class created for relatively positioned inline-level elements
-// that acts as a containing block for child absolutely positioned
-// elements
-
-class nsPositionedInlineFrame : public nsInlineFrame
-{
-public:
- NS_DECL_FRAMEARENA_HELPERS
-
- nsPositionedInlineFrame(nsStyleContext* aContext)
- : nsInlineFrame(aContext)
- , mAbsoluteContainer(nsGkAtoms::absoluteList)
- {}
-
- virtual ~nsPositionedInlineFrame() { } // useful for debugging
-
- virtual void DestroyFrom(nsIFrame* aDestructRoot);
-
- NS_IMETHOD SetInitialChildList(nsIAtom* aListName,
- nsFrameList& aChildList);
- NS_IMETHOD AppendFrames(nsIAtom* aListName,
- nsFrameList& aFrameList);
- NS_IMETHOD InsertFrames(nsIAtom* aListName,
- nsIFrame* aPrevFrame,
- nsFrameList& aFrameList);
- NS_IMETHOD RemoveFrame(nsIAtom* aListName,
- nsIFrame* aOldFrame);
-
- NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
- const nsRect& aDirtyRect,
- const nsDisplayListSet& aLists);
-
- virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
-
- virtual nsFrameList GetChildList(nsIAtom* aListName) const;
-
- NS_IMETHOD Reflow(nsPresContext* aPresContext,
- nsHTMLReflowMetrics& aDesiredSize,
- const nsHTMLReflowState& aReflowState,
- nsReflowStatus& aStatus);
-
- virtual nsIAtom* GetType() const;
-
-protected:
- nsAbsoluteContainingBlock mAbsoluteContainer;
-};
-
#endif /* nsInlineFrame_h___ */
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -657,18 +657,17 @@ IsPercentageAware(const nsIFrame* aFrame
nsIAtom *fType = aFrame->GetType();
if (fType == nsGkAtoms::textFrame) {
// None of these things can ever be true for text frames.
return PR_FALSE;
}
// Some of these things don't apply to non-replaced inline frames
- // (that is, fType == nsGkAtoms::inlineFrame || fType ==
- // nsGkAtoms::positionedInlineFrame), but we won't bother making
+ // (that is, fType == nsGkAtoms::inlineFrame), but we won't bother making
// things unnecessarily complicated, since they'll probably be set
// quite rarely.
const nsStyleMargin* margin = aFrame->GetStyleMargin();
if (HasPercentageUnitSide(margin->mMargin)) {
return PR_TRUE;
}
--- a/layout/generic/nsPageContentFrame.cpp
+++ b/layout/generic/nsPageContentFrame.cpp
@@ -132,23 +132,20 @@ nsPageContentFrame::Reflow(nsPresContext
}
// Place and size the child
FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, 0, 0, 0);
NS_ASSERTION(aPresContext->IsDynamic() || !NS_FRAME_IS_FULLY_COMPLETE(aStatus) ||
!frame->GetNextInFlow(), "bad child flow list");
}
- // Reflow our fixed frames
+
+ // Reflow our fixed frames
nsReflowStatus fixedStatus = NS_FRAME_COMPLETE;
- mFixedContainer.Reflow(this, aPresContext, aReflowState, fixedStatus,
- aReflowState.availableWidth,
- aReflowState.availableHeight,
- PR_FALSE, PR_TRUE, PR_TRUE, // XXX could be optimized
- nsnull /* ignore overflow */);
+ ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, fixedStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(fixedStatus), "fixed frames can be truncated, but not incomplete");
// Return our desired size
aDesiredSize.width = aReflowState.availableWidth;
if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) {
aDesiredSize.height = aReflowState.availableHeight;
}
--- a/layout/generic/nsQueryFrame.h
+++ b/layout/generic/nsQueryFrame.h
@@ -180,17 +180,16 @@ public:
nsMenuFrame_id,
nsMenuPopupFrame_id,
nsObjectFrame_id,
nsPageBreakFrame_id,
nsPageContentFrame_id,
nsPageFrame_id,
nsPlaceholderFrame_id,
nsPopupSetFrame_id,
- nsPositionedInlineFrame_id,
nsProgressMeterFrame_id,
nsResizerFrame_id,
nsRootBoxFrame_id,
nsScrollbarButtonFrame_id,
nsScrollbarFrame_id,
nsSelectsAreaFrame_id,
nsSimplePageSequenceFrame_id,
nsSliderFrame_id,
--- a/layout/generic/nsViewportFrame.cpp
+++ b/layout/generic/nsViewportFrame.cpp
@@ -42,16 +42,17 @@
#include "nsCOMPtr.h"
#include "nsViewportFrame.h"
#include "nsHTMLParts.h"
#include "nsGkAtoms.h"
#include "nsIScrollableFrame.h"
#include "nsDisplayList.h"
#include "FrameLayerBuilder.h"
+#include "nsAbsoluteContainingBlock.h"
using namespace mozilla;
nsIFrame*
NS_NewViewportFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
return new (aPresShell) ViewportFrame(aContext);
}
@@ -64,164 +65,95 @@ ViewportFrame::Init(nsIContent* aCo
nsIFrame* aPrevInFlow)
{
return Super::Init(aContent, aParent, aPrevInFlow);
}
void
ViewportFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
- mFixedContainer.DestroyFrames(this, aDestructRoot);
+ DestroyAbsoluteFrames(aDestructRoot);
nsContainerFrame::DestroyFrom(aDestructRoot);
}
NS_IMETHODIMP
ViewportFrame::SetInitialChildList(nsIAtom* aListName,
nsFrameList& aChildList)
{
- nsresult rv = NS_OK;
-
// See which child list to add the frames to
#ifdef NS_DEBUG
nsFrame::VerifyDirtyBitSet(aChildList);
#endif
- if (nsGkAtoms::fixedList == aListName) {
- rv = mFixedContainer.SetInitialChildList(this, aListName, aChildList);
- }
- else {
- rv = nsContainerFrame::SetInitialChildList(aListName, aChildList);
- }
-
- return rv;
+ return nsContainerFrame::SetInitialChildList(aListName, aChildList);
}
NS_IMETHODIMP
ViewportFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists)
{
- // We don't need any special painting or event handling. We just need to
- // mark our visible out-of-flow frames (i.e., the fixed position frames) so
- // that display list construction is guaranteed to recurse into their
- // ancestors.
- aBuilder->MarkFramesForDisplayList(this, mFixedContainer.GetChildList(),
- aDirtyRect);
-
nsIFrame* kid = mFrames.FirstChild();
if (!kid)
return NS_OK;
// make the kid's BorderBackground our own. This ensures that the canvas
// frame's background becomes our own background and therefore appears
// below negative z-index elements.
return BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
}
NS_IMETHODIMP
ViewportFrame::AppendFrames(nsIAtom* aListName,
nsFrameList& aFrameList)
{
- nsresult rv = NS_OK;
-
- if (nsGkAtoms::fixedList == aListName) {
- rv = mFixedContainer.AppendFrames(this, aListName, aFrameList);
- }
- else {
- NS_ASSERTION(!aListName, "unexpected child list");
- NS_ASSERTION(GetChildList(nsnull).IsEmpty(), "Shouldn't have any kids!");
- rv = nsContainerFrame::AppendFrames(aListName, aFrameList);
- }
-
- return rv;
+ NS_ASSERTION(!aListName, "unexpected child list");
+ NS_ASSERTION(GetChildList(nsnull).IsEmpty(), "Shouldn't have any kids!");
+ return nsContainerFrame::AppendFrames(aListName, aFrameList);
}
NS_IMETHODIMP
ViewportFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList)
{
- nsresult rv = NS_OK;
-
- if (nsGkAtoms::fixedList == aListName) {
- rv = mFixedContainer.InsertFrames(this, aListName, aPrevFrame, aFrameList);
- }
- else {
- NS_ASSERTION(!aListName, "unexpected child list");
- NS_ASSERTION(GetChildList(nsnull).IsEmpty(), "Shouldn't have any kids!");
- rv = nsContainerFrame::InsertFrames(aListName, aPrevFrame, aFrameList);
- }
-
- return rv;
+ NS_ASSERTION(!aListName, "unexpected child list");
+ NS_ASSERTION(GetChildList(nsnull).IsEmpty(), "Shouldn't have any kids!");
+ return nsContainerFrame::InsertFrames(aListName, aPrevFrame, aFrameList);
}
NS_IMETHODIMP
ViewportFrame::RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame)
{
- nsresult rv = NS_OK;
-
- if (nsGkAtoms::fixedList == aListName) {
- mFixedContainer.RemoveFrame(this, aListName, aOldFrame);
- rv = NS_OK;
- }
- else {
- NS_ASSERTION(!aListName, "unexpected child list");
- rv = nsContainerFrame::RemoveFrame(aListName, aOldFrame);
- }
-
- return rv;
-}
-
-nsIAtom*
-ViewportFrame::GetAdditionalChildListName(PRInt32 aIndex) const
-{
- NS_PRECONDITION(aIndex >= 0, "illegal index");
-
- if (0 == aIndex) {
- return nsGkAtoms::fixedList;
- }
-
- return nsnull;
-}
-
-nsFrameList
-ViewportFrame::GetChildList(nsIAtom* aListName) const
-{
- if (nsGkAtoms::fixedList == aListName)
- return mFixedContainer.GetChildList();
-
- return nsContainerFrame::GetChildList(aListName);
+ NS_ASSERTION(!aListName, "unexpected child list");
+ return nsContainerFrame::RemoveFrame(aListName, aOldFrame);
}
/* virtual */ nscoord
ViewportFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
{
nscoord result;
DISPLAY_MIN_WIDTH(this, result);
if (mFrames.IsEmpty())
result = 0;
else
result = mFrames.FirstChild()->GetMinWidth(aRenderingContext);
-
- // XXXldb Deal with mFixedContainer (matters for SizeToContent)!
return result;
}
/* virtual */ nscoord
ViewportFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
{
nscoord result;
DISPLAY_PREF_WIDTH(this, result);
if (mFrames.IsEmpty())
result = 0;
else
result = mFrames.FirstChild()->GetPrefWidth(aRenderingContext);
-
- // XXXldb Deal with mFixedContainer (matters for SizeToContent)!
return result;
}
nsPoint
ViewportFrame::AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const
{
// Calculate how much room is available for fixed frames. That means
@@ -309,30 +241,34 @@ ViewportFrame::Reflow(nsPresContext*
aDesiredSize.height = aReflowState.ComputedHeight() != NS_UNCONSTRAINEDSIZE
? aReflowState.ComputedHeight()
: kidHeight;
// Make a copy of the reflow state and change the computed width and height
// to reflect the available space for the fixed items
nsHTMLReflowState reflowState(aReflowState);
nsPoint offset = AdjustReflowStateForScrollbars(&reflowState);
-
+
#ifdef DEBUG
- NS_ASSERTION(mFixedContainer.GetChildList().IsEmpty() ||
- (offset.x == 0 && offset.y == 0),
- "We don't handle correct positioning of fixed frames with "
- "scrollbars in odd positions");
+ if (IsAbsoluteContainer()) {
+ NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
+ (offset.x == 0 && offset.y == 0),
+ "We don't handle correct positioning of fixed frames with "
+ "scrollbars in odd positions");
+ }
#endif
- // Just reflow all the fixed-pos frames.
- rv = mFixedContainer.Reflow(this, aPresContext, reflowState, aStatus,
- reflowState.ComputedWidth(),
- reflowState.ComputedHeight(),
- PR_FALSE, PR_TRUE, PR_TRUE, // XXX could be optimized
- nsnull /* ignore overflow */);
+ if (IsAbsoluteContainer()) {
+ // Just reflow all the fixed-pos frames.
+ rv = GetAbsoluteContainingBlock()->Reflow(this, aPresContext, reflowState, aStatus,
+ reflowState.ComputedWidth(),
+ reflowState.ComputedHeight(),
+ PR_FALSE, PR_TRUE, PR_TRUE, // XXX could be optimized
+ nsnull /* ignore overflow */);
+ }
// If we were dirty then do a repaint
if (GetStateBits() & NS_FRAME_IS_DIRTY) {
nsRect damageRect(0, 0, aDesiredSize.width, aDesiredSize.height);
Invalidate(damageRect);
}
// XXX Should we do something to clip our children to this?
--- a/layout/generic/nsViewportFrame.h
+++ b/layout/generic/nsViewportFrame.h
@@ -40,35 +40,32 @@
* the document's scrollbars and contains fixed-positioned elements
*/
#ifndef nsViewportFrame_h___
#define nsViewportFrame_h___
#include "nsContainerFrame.h"
#include "nsGkAtoms.h"
-#include "nsAbsoluteContainingBlock.h"
class nsPresContext;
/**
* ViewportFrame is the parent of a single child - the doc root frame or a scroll frame
* containing the doc root frame. ViewportFrame stores this child in its primary child
- * list. It stores fixed positioned items in a secondary child list and its mFixedContainer
- * delegate handles them.
+ * list.
*/
class ViewportFrame : public nsContainerFrame {
public:
NS_DECL_FRAMEARENA_HELPERS
typedef nsContainerFrame Super;
ViewportFrame(nsStyleContext* aContext)
: nsContainerFrame(aContext)
- , mFixedContainer(nsGkAtoms::fixedList)
{}
virtual ~ViewportFrame() { } // useful for debugging
virtual void DestroyFrom(nsIFrame* aDestructRoot);
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* asPrevInFlow);
@@ -81,20 +78,16 @@ public:
NS_IMETHOD InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList);
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
- virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
-
- virtual nsFrameList GetChildList(nsIAtom* aListName) const;
-
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
NS_IMETHOD Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@@ -118,17 +111,12 @@ public:
NS_IMETHOD GetFrameName(nsAString& aResult) const;
#endif
private:
virtual nsIAtom* GetAbsoluteListName() const { return nsGkAtoms::fixedList; }
protected:
nsPoint AdjustReflowStateForScrollbars(nsHTMLReflowState* aReflowState) const;
-
-protected:
- // position: fixed content is really content which is absolutely positioned with
- // respect to the viewport.
- nsAbsoluteContainingBlock mFixedContainer;
};
#endif // nsViewportFrame_h___
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1081,17 +1081,17 @@ nsIAtom*
nsTableFrame::GetAdditionalChildListName(PRInt32 aIndex) const
{
if (aIndex == NS_TABLE_FRAME_COLGROUP_LIST_INDEX) {
return nsGkAtoms::colGroupList;
}
if (aIndex == NS_TABLE_FRAME_OVERFLOW_LIST_INDEX) {
return nsGkAtoms::overflowList;
}
- return nsnull;
+ return nsHTMLContainerFrame::GetAdditionalChildListName(aIndex);
}
nsRect
nsDisplayTableItem::GetBounds(nsDisplayListBuilder* aBuilder) {
return mFrame->GetVisualOverflowRect() + ToReferenceFrame();
}
PRBool
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -222,26 +222,26 @@ nsFrameList
nsTableOuterFrame::GetChildList(nsIAtom* aListName) const
{
if (nsGkAtoms::captionList == aListName) {
return mCaptionFrames;
}
if (!aListName) {
return mFrames;
}
- return nsFrameList::EmptyList();
+ return nsHTMLContainerFrame::GetChildList(aListName);
}
nsIAtom*
nsTableOuterFrame::GetAdditionalChildListName(PRInt32 aIndex) const
{
if (aIndex == NS_TABLE_FRAME_CAPTION_LIST_INDEX) {
return nsGkAtoms::captionList;
}
- return nsnull;
+ return nsHTMLContainerFrame::GetAdditionalChildListName(aIndex);
}
NS_IMETHODIMP
nsTableOuterFrame::SetInitialChildList(nsIAtom* aListName,
nsFrameList& aChildList)
{
if (nsGkAtoms::captionList == aListName) {
// the frame constructor already checked for table-caption display type
--- a/layout/xul/base/src/nsMenuFrame.cpp
+++ b/layout/xul/base/src/nsMenuFrame.cpp
@@ -395,17 +395,17 @@ nsMenuFrame::SetInitialChildList(nsIAtom
}
nsIAtom*
nsMenuFrame::GetAdditionalChildListName(PRInt32 aIndex) const
{
if (NS_MENU_POPUP_LIST_INDEX == aIndex) {
return nsGkAtoms::popupList;
}
- return nsnull;
+ return nsBoxFrame::GetAdditionalChildListName(aIndex);
}
void
nsMenuFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
// Kill our timer if one is active. This is not strictly necessary as
// the pointer to this frame will be cleared from the mediator, but
// this is done for added safety.