Back out bug 10209 and bug 656875 (its regression fix) from Aurora because the work on this bug has not been finished yet

--HG--
extra : transplant_source : t%9F%EB%2Aa%A4%C0%9Ab%A5%DDQ%3EMD%5E%01h%E7%2A
This commit is contained in:
Ehsan Akhgari 2011-06-01 16:18:15 -04:00
Родитель 8e4b8bf07f
Коммит f3e14ab46c
30 изменённых файлов: 486 добавлений и 296 удалений

Просмотреть файл

@ -1746,6 +1746,7 @@ 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")

Просмотреть файл

@ -1020,10 +1020,6 @@ nsFrameConstructorState::PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteConta
*/
mFixedPosIsAbsPos = (aNewAbsoluteContainingBlock &&
aNewAbsoluteContainingBlock->GetStyleDisplay()->HasTransform());
if (aNewAbsoluteContainingBlock) {
aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock();
}
}
void
@ -1219,14 +1215,7 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
nsresult rv = NS_OK;
if (childList.IsEmpty() &&
(containingBlock->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
// 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);
}
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
@ -1244,7 +1233,7 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
if (!lastChild ||
nsLayoutUtils::CompareTreePosition(lastChild, firstNewFrame, containingBlock) < 0) {
// no lastChild, or lastChild comes before the new children, so just append
rv = mFrameManager->AppendFrames(containingBlock, aChildListName, aFrameItems);
rv = containingBlock->AppendFrames(aChildListName, aFrameItems);
} else {
// try the other children
nsIFrame* insertionPoint = nsnull;
@ -1259,8 +1248,8 @@ nsFrameConstructorState::ProcessFrameInsertions(nsAbsoluteItems& aFrameItems,
}
insertionPoint = f;
}
rv = mFrameManager->InsertFrames(containingBlock, aChildListName,
insertionPoint, aFrameItems);
rv = containingBlock->InsertFrames(aChildListName, insertionPoint,
aFrameItems);
}
}
@ -2553,8 +2542,6 @@ nsCSSFrameConstructor::ConstructRootFrame(nsIFrame** aNewFrame)
// 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;
@ -2839,8 +2826,6 @@ nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell,
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,
@ -5528,7 +5513,7 @@ nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame)
#ifdef MOZ_XUL
nsGkAtoms::XULLabelFrame == frameType ||
#endif
(nsGkAtoms::inlineFrame == frameType && wrappedFrame->IsAbsoluteContainer())) {
nsGkAtoms::positionedInlineFrame == frameType) {
containingBlock = wrappedFrame;
} else if (nsGkAtoms::fieldSetFrame == frameType) {
// If the positioned frame is a fieldset, use the area frame inside it.
@ -8484,6 +8469,13 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
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;
@ -10714,7 +10706,11 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
NS_STYLE_DISPLAY_INLINE == aDisplay->mDisplay &&
(NS_STYLE_POSITION_RELATIVE == aDisplay->mPosition ||
aDisplay->HasTransform());
newFrame = NS_NewInlineFrame(mPresShell, styleContext);
if (positioned) {
newFrame = NS_NewPositionedInlineFrame(mPresShell, styleContext);
} else {
newFrame = NS_NewInlineFrame(mPresShell, styleContext);
}
// Initialize the frame
InitAndRestoreFrame(aState, content, aParentFrame, nsnull, newFrame);
@ -10723,7 +10719,7 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
// 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);
@ -10822,15 +10818,17 @@ nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState& aState,
// Now grab the initial inlines in aChildItems and put them into an inline
// frame
nsIFrame* inlineFrame = NS_NewInlineFrame(mPresShell, styleContext);
nsIFrame* inlineFrame;
if (aIsPositioned) {
inlineFrame = NS_NewPositionedInlineFrame(mPresShell, styleContext);
}
else {
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);

Просмотреть файл

@ -2545,7 +2545,8 @@ PrepareBackgroundLayer(nsPresContext* aPresContext,
nsIAtom* frameType = aForFrame->GetType();
nsIFrame* geometryFrame = aForFrame;
if (frameType == nsGkAtoms::inlineFrame) {
if (frameType == nsGkAtoms::inlineFrame ||
frameType == nsGkAtoms::positionedInlineFrame) {
// 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

Просмотреть файл

@ -93,7 +93,6 @@
#include "imgIRequest.h"
#include "nsTransitionManager.h"
#include "RestyleTracker.h"
#include "nsAbsoluteContainingBlock.h"
#include "nsFrameManager.h"
#include "nsRuleProcessorData.h"
@ -472,19 +471,6 @@ nsFrameManager::ClearAllUndisplayedContentIn(nsIContent* aParentContent)
}
//----------------------------------------------------------------------
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,
@ -497,13 +483,7 @@ nsFrameManager::InsertFrames(nsIFrame* aParentFrame,
&& !IS_TRUE_OVERFLOW_CONTAINER(aPrevFrame),
"aPrevFrame must be the last continuation in its chain!");
if (aParentFrame->IsAbsoluteContainer() &&
aListName == aParentFrame->GetAbsoluteListName()) {
return aParentFrame->GetAbsoluteContainingBlock()->
InsertFrames(aParentFrame, aListName, aPrevFrame, aFrameList);
} else {
return aParentFrame->InsertFrames(aListName, aPrevFrame, aFrameList);
}
return aParentFrame->InsertFrames(aListName, aPrevFrame, aFrameList);
}
nsresult
@ -528,15 +508,7 @@ nsFrameManager::RemoveFrame(nsIAtom* aListName,
NS_ASSERTION(!(aOldFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW &&
GetPlaceholderFrameFor(aOldFrame)),
"Must call RemoveFrame on placeholder for out-of-flows.");
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);
}
nsresult rv = aOldFrame->GetParent()->RemoveFrame(aListName, aOldFrame);
mIsDestroyingFrames = wasDestroyingFrames;

Просмотреть файл

@ -124,7 +124,10 @@ public:
// Functions for manipulating the frame model
NS_HIDDEN_(nsresult) AppendFrames(nsIFrame* aParentFrame,
nsIAtom* aListName,
nsFrameList& aFrameList);
nsFrameList& aFrameList)
{
return aParentFrame->AppendFrames(aListName, aFrameList);
}
NS_HIDDEN_(nsresult) InsertFrames(nsIFrame* aParentFrame,
nsIAtom* aListName,

Просмотреть файл

@ -173,6 +173,7 @@ The entries in the reflow log can be controlled on a frame level. For instance
<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>

Просмотреть файл

@ -427,7 +427,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
PRBool constrainHeight = (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE)
&& aConstrainHeight
// Don't split if told not to (e.g. for fixed frames)
&& (aDelegatingFrame->GetType() != nsGkAtoms::inlineFrame)
&& (aDelegatingFrame->GetType() != nsGkAtoms::positionedInlineFrame)
//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*

Просмотреть файл

@ -308,7 +308,7 @@ nsBlockFrame::~nsBlockFrame()
void
nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
DestroyAbsoluteFrames(aDestructRoot);
mAbsoluteContainer.DestroyFrames(this, aDestructRoot);
// Outside bullets are not in our child-list so check for them here
// and delete them when present.
if (mBullet && HaveOutsideBullet()) {
@ -585,7 +585,10 @@ nsBlockFrame::GetCaretBaseline() const
nsFrameList
nsBlockFrame::GetChildList(nsIAtom* aListName) const
{
if (nsnull == aListName) {
if (nsGkAtoms::absoluteList == aListName) {
return mAbsoluteContainer.GetChildList();
}
else if (nsnull == aListName) {
return mFrames;
}
else if (aListName == nsGkAtoms::overflowList) {
@ -617,7 +620,8 @@ nsBlockFrame::GetChildList(nsIAtom* aListName) const
#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_PUSHED_FLOATS_LIST_INDEX (NS_CONTAINER_LIST_COUNT_INCL_OC + 3)
#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)
// If adding/removing lists, don't forget to update the count in nsBlockFrame.h
nsIAtom*
@ -633,6 +637,8 @@ nsBlockFrame::GetAdditionalChildListName(PRInt32 aIndex) const
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:
@ -1170,8 +1176,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// 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 (HasAbsolutelyPositionedChildren()) {
nsAbsoluteContainingBlock* absoluteContainer = GetAbsoluteContainingBlock();
if (mAbsoluteContainer.HasAbsoluteFrames()) {
PRBool haveInterrupt = aPresContext->HasPendingInterrupt();
if (reflowState->WillReflowAgainForClearance() ||
haveInterrupt) {
@ -1182,9 +1187,9 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
// 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)) {
absoluteContainer->MarkAllFramesDirty();
mAbsoluteContainer.MarkAllFramesDirty();
} else {
absoluteContainer->MarkSizeDependentFramesDirty();
mAbsoluteContainer.MarkSizeDependentFramesDirty();
}
} else {
nsSize containingBlockSize =
@ -1208,12 +1213,12 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
!(isRoot && NS_UNCONSTRAINEDSIZE == reflowState->ComputedHeight()) &&
aMetrics.height != oldSize.height;
absoluteContainer->Reflow(this, aPresContext, *reflowState,
state.mReflowStatus,
containingBlockSize.width,
containingBlockSize.height, PR_TRUE,
cbWidthChanged, cbHeightChanged,
&aMetrics.mOverflowAreas);
rv = mAbsoluteContainer.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?
}
@ -4703,7 +4708,10 @@ nsBlockFrame::AppendFrames(nsIAtom* aListName,
return NS_OK;
}
if (aListName) {
if (nsGkAtoms::floatList == aListName) {
if (nsGkAtoms::absoluteList == aListName) {
return mAbsoluteContainer.AppendFrames(this, aListName, aFrameList);
}
else if (nsGkAtoms::floatList == aListName) {
mFloats.AppendFrames(nsnull, aFrameList);
return NS_OK;
}
@ -4748,7 +4756,11 @@ nsBlockFrame::InsertFrames(nsIAtom* aListName,
"inserting after sibling frame with different parent");
if (aListName) {
if (nsGkAtoms::floatList == aListName) {
if (nsGkAtoms::absoluteList == aListName) {
return mAbsoluteContainer.InsertFrames(this, aListName, aPrevFrame,
aFrameList);
}
else if (nsGkAtoms::floatList == aListName) {
mFloats.InsertFrames(this, aPrevFrame, aFrameList);
return NS_OK;
}
@ -5009,6 +5021,10 @@ nsBlockFrame::RemoveFrame(nsIAtom* aListName,
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.
@ -5051,9 +5067,9 @@ nsBlockFrame::DoRemoveOutOfFlowFrame(nsIFrame* aFrame)
const nsStyleDisplay* display = aFrame->GetStyleDisplay();
if (display->IsAbsolutelyPositioned()) {
// This also deletes the next-in-flows
block->GetAbsoluteContainingBlock()->RemoveFrame(block,
nsGkAtoms::absoluteList,
aFrame);
block->mAbsoluteContainer.RemoveFrame(block,
nsGkAtoms::absoluteList,
aFrame);
}
else {
// First remove aFrame's next-in-flows
@ -6252,6 +6268,8 @@ nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
aBuilder->MarkFramesForDisplayList(this, mFloats, aDirtyRect);
aBuilder->MarkFramesForDisplayList(this, mAbsoluteContainer.GetChildList(),
aDirtyRect);
// Prepare for text-overflow processing.
nsAutoPtr<TextOverflow> textOverflow(
@ -6515,7 +6533,10 @@ nsBlockFrame::SetInitialChildList(nsIAtom* aListName,
{
nsresult rv = NS_OK;
if (nsGkAtoms::floatList == aListName) {
if (nsGkAtoms::absoluteList == aListName) {
mAbsoluteContainer.SetInitialChildList(this, aListName, aChildList);
}
else if (nsGkAtoms::floatList == aListName) {
mFloats.SetFrames(aChildList);
}
else {

Просмотреть файл

@ -84,7 +84,7 @@ class nsIntervalSet;
* Child list name indices
* @see #GetAdditionalChildListName()
*/
#define NS_BLOCK_LIST_COUNT (NS_CONTAINER_LIST_COUNT_INCL_OC + 4)
#define NS_BLOCK_LIST_COUNT (NS_CONTAINER_LIST_COUNT_INCL_OC + 5)
/**
* Some invariants:
@ -341,6 +341,7 @@ protected:
: nsHTMLContainerFrame(aContext)
, mMinWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
, mPrefWidth(NS_INTRINSIC_WIDTH_UNKNOWN)
, mAbsoluteContainer(nsGkAtoms::absoluteList)
{
#ifdef DEBUG
InitDebugFlags();
@ -776,6 +777,10 @@ protected:
friend class nsBlockReflowState;
friend class nsBlockInFlowLineIterator;
private:
nsAbsoluteContainingBlock mAbsoluteContainer;
#ifdef DEBUG
public:
static PRBool gLamePaintMetrics;

Просмотреть файл

@ -52,6 +52,7 @@
#include "nsIPresShell.h"
#include "nsIScrollPositionListener.h"
#include "nsDisplayList.h"
#include "nsAbsoluteContainingBlock.h"
#include "nsCSSFrameConstructor.h"
#include "nsFrameManager.h"
@ -64,6 +65,8 @@
//#define DEBUG_CANVAS_FOCUS
#endif
#define CANVAS_ABS_POS_CHILD_LIST NS_CONTAINER_LIST_COUNT_INCL_OC
nsIFrame*
NS_NewCanvasFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@ -80,7 +83,8 @@ NS_QUERYFRAME_TAIL_INHERITING(nsHTMLContainerFrame)
void
nsCanvasFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
DestroyAbsoluteFrames(aDestructRoot);
mAbsoluteContainer.DestroyFrames(this, aDestructRoot);
nsIScrollableFrame* sf =
PresContext()->GetPresShell()->GetRootScrollFrameAsScrollable();
if (sf) {
@ -122,6 +126,9 @@ 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);
@ -131,6 +138,9 @@ 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) {
@ -163,6 +173,9 @@ 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");
@ -176,6 +189,11 @@ 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
@ -200,6 +218,24 @@ nsCanvasFrame::RemoveFrame(nsIAtom* aListName,
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
@ -278,6 +314,9 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
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
@ -514,6 +553,15 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext,
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
@ -554,7 +602,7 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext,
aStatus);
}
FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, aStatus);
FinishAndStoreOverflow(&aDesiredSize);
NS_FRAME_TRACE_REFLOW_OUT("nsCanvasFrame::Reflow", aStatus);
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsHTMLContainerFrame.h"
#include "nsIScrollPositionListener.h"
#include "nsAbsoluteContainingBlock.h"
#include "nsDisplayList.h"
#include "nsGkAtoms.h"
@ -63,7 +64,8 @@ public:
nsCanvasFrame(nsStyleContext* aContext)
: nsHTMLContainerFrame(aContext),
mDoPaintFocus(PR_FALSE),
mAddedScrollPositionListener(PR_FALSE) {}
mAddedScrollPositionListener(PR_FALSE),
mAbsoluteContainer(nsGkAtoms::absoluteList) {}
NS_DECL_QUERYFRAME_TARGET(nsCanvasFrame)
NS_DECL_QUERYFRAME
@ -82,6 +84,9 @@ public:
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,
@ -147,6 +152,7 @@ protected:
// Data members
PRPackedBool mDoPaintFocus;
PRPackedBool mAddedScrollPositionListener;
nsAbsoluteContainingBlock mAbsoluteContainer;
};
/**

Просмотреть файл

@ -319,12 +319,12 @@ nsContainerFrame::GetChildList(nsIAtom* aListName) const
return list ? *list : nsFrameList::EmptyList();
}
return nsSplittableFrame::GetChildList(aListName);
return nsFrameList::EmptyList();
}
#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
#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
// If adding/removing lists, don't forget to update count in .h file
@ -339,7 +339,7 @@ nsContainerFrame::GetAdditionalChildListName(PRInt32 aIndex) const
else if (NS_CONTAINER_FRAME_EXCESS_OVERFLOW_CONTAINERS_LIST_INDEX == aIndex)
return nsGkAtoms::excessOverflowContainersList;
}
return nsSplittableFrame::GetAdditionalChildListName(aIndex);
return nsnull;
}
/////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -50,7 +50,9 @@
* Child list name indices
* @see #GetAdditionalChildListName()
*/
#define NS_CONTAINER_LIST_COUNT_INCL_OC 4
#define NS_CONTAINER_LIST_COUNT_SANS_OC 1
// for frames that don't use overflow containers
#define NS_CONTAINER_LIST_COUNT_INCL_OC 3
// for frames that support overflow containers
// Option flags for ReflowChild() and FinishReflowChild()

Просмотреть файл

@ -122,7 +122,6 @@
#include "gfxContext.h"
#include "CSSCalc.h"
#include "nsAbsoluteContainingBlock.h"
#include "mozilla/Preferences.h"
@ -255,34 +254,6 @@ nsFrame::RootFrameList(nsPresContext* aPresContext, FILE* out, PRInt32 aIndent)
}
#endif
static void
DestroyAbsoluteContainingBlock(void* aPropertyValue)
{
delete static_cast<nsAbsoluteContainingBlock*>(aPropertyValue);
}
NS_DECLARE_FRAME_PROPERTY(AbsoluteContainingBlockProperty, DestroyAbsoluteContainingBlock)
PRBool
nsIFrame::HasAbsolutelyPositionedChildren() const {
return IsAbsoluteContainer() && GetAbsoluteContainingBlock()->HasAbsoluteFrames();
}
nsAbsoluteContainingBlock*
nsIFrame::GetAbsoluteContainingBlock() const {
NS_ASSERTION(IsAbsoluteContainer(), "The frame is not marked as an abspos container correctly");
nsAbsoluteContainingBlock* absCB = static_cast<nsAbsoluteContainingBlock*>
(Properties().Get(AbsoluteContainingBlockProperty()));
NS_ASSERTION(absCB, "The frame is marked as an abspos container but doesn't have the property");
return absCB;
}
void
nsIFrame::MarkAsAbsoluteContainingBlock() {
AddStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
Properties().Set(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListName()));
}
void
NS_MergeReflowStatusInto(nsReflowStatus* aPrimary, nsReflowStatus aSecondary)
{
@ -953,23 +924,13 @@ 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
{
if (IsAbsoluteContainer() &&
aListName == GetAbsoluteListName()) {
return GetAbsoluteContainingBlock()->GetChildList();
} else {
return nsFrameList::EmptyList();
}
return nsFrameList::EmptyList();
}
static nsIFrame*
@ -1489,9 +1450,6 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, dirtyRect);
}
// Mark the display list items for absolutely positioned children
MarkAbsoluteFramesForDisplayList(aBuilder, dirtyRect);
nsDisplayListCollection set;
nsresult rv;
{
@ -1624,7 +1582,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
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 =
@ -1670,15 +1628,9 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
dirty.SetEmpty();
}
pseudoStackingContext = PR_TRUE;
}
// 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)) {
} else if (aBuilder->GetSelectedFramesOnly() &&
aChild->IsLeaf() &&
!(aChild->GetStateBits() & NS_FRAME_SELECTED_CONTENT)) {
return NS_OK;
}
@ -1841,15 +1793,6 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
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,
@ -3600,7 +3543,6 @@ nsFrame::DidReflow(nsPresContext* aPresContext,
{
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);
@ -3621,55 +3563,6 @@ nsFrame::DidReflow(nsPresContext* aPresContext,
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
{
@ -6270,7 +6163,8 @@ inline PRBool
IsInlineFrame(nsIFrame *aFrame)
{
nsIAtom *type = aFrame->GetType();
return type == nsGkAtoms::inlineFrame;
return type == nsGkAtoms::inlineFrame ||
type == nsGkAtoms::positionedInlineFrame;
}
void
@ -7985,6 +7879,7 @@ void DR_State::InitFrameTypeTable()
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");

Просмотреть файл

@ -328,15 +328,6 @@ public:
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

Просмотреть файл

@ -139,6 +139,8 @@ 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);

Просмотреть файл

@ -1573,7 +1573,7 @@ nsHTMLReflowState::ComputeContainingBlockRectangle(nsPresContext* aPres
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 nsInlineFrame::Reflow will pass in
// called, since the code in nsPositionedInlineFrame::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.

Просмотреть файл

@ -103,7 +103,6 @@ class gfxSkipChars;
class gfxSkipCharsIterator;
class gfxContext;
class nsLineList_iterator;
class nsAbsoluteContainingBlock;
struct nsPeekOffsetStruct;
struct nsPoint;
@ -286,9 +285,6 @@ typedef PRUint64 nsFrameState;
// bit; we could free up this bit with a little extra complexity.
#define NS_FRAME_UPDATE_LAYER_TREE NS_FRAME_STATE_BIT(36)
// Frame can accept absolutely positioned children.
#define NS_FRAME_HAS_ABSPOS_CHILDREN NS_FRAME_STATE_BIT(37)
// The lower 20 bits and upper 32 bits of the frame state are reserved
// by this API.
#define NS_FRAME_RESERVED ~NS_FRAME_IMPL_RESERVED
@ -588,8 +584,6 @@ public:
* 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
@ -2707,17 +2701,7 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::EmbeddingLevelProperty()))
}
}
}
/**
* Accessors for the absolute containing block.
*/
PRBool IsAbsoluteContainer() const { return !!(mState & NS_FRAME_HAS_ABSPOS_CHILDREN); }
PRBool HasAbsolutelyPositionedChildren() const;
nsAbsoluteContainingBlock* GetAbsoluteContainingBlock() const;
virtual void MarkAsAbsoluteContainingBlock();
// Child frame types override this function to select their own child list name
virtual nsIAtom* GetAbsoluteListName() const { return nsGkAtoms::absoluteList; }
protected:
// Members
nsRect mRect;
@ -2728,8 +2712,6 @@ 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();

Просмотреть файл

@ -47,6 +47,7 @@
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsRenderingContext.h"
#include "nsAbsoluteContainingBlock.h"
#include "nsCSSAnonBoxes.h"
#include "nsAutoPtr.h"
#include "nsFrameManager.h"
@ -413,9 +414,7 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
}
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.
@ -923,13 +922,6 @@ nsInlineFrame::GetBaseline() const
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()
@ -1109,8 +1101,6 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext,
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;
@ -1131,3 +1121,162 @@ nsFirstLineFrame::PullOverflowsFromPrevInFlow()
}
}
//////////////////////////////////////////////////////////////////////
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;
}

Просмотреть файл

@ -41,6 +41,7 @@
#define nsInlineFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsAbsoluteContainingBlock.h"
#include "nsLineLayout.h"
class nsAnonymousBlockFrame;
@ -96,8 +97,6 @@ public:
virtual PRBool IsEmpty();
virtual PRBool IsSelfEmpty();
virtual void DestroyFrom(nsIFrame* aDestructRoot);
virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset,
PRBool aRespectClusters = PR_TRUE);
@ -228,4 +227,53 @@ protected:
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___ */

Просмотреть файл

@ -662,7 +662,8 @@ IsPercentageAware(const nsIFrame* aFrame)
}
// Some of these things don't apply to non-replaced inline frames
// (that is, fType == nsGkAtoms::inlineFrame), but we won't bother making
// (that is, fType == nsGkAtoms::inlineFrame || fType ==
// nsGkAtoms::positionedInlineFrame), but we won't bother making
// things unnecessarily complicated, since they'll probably be set
// quite rarely.

Просмотреть файл

@ -137,10 +137,13 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext,
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;
ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowState, fixedStatus);
mFixedContainer.Reflow(this, aPresContext, aReflowState, fixedStatus,
aReflowState.availableWidth,
aReflowState.availableHeight,
PR_FALSE, PR_TRUE, PR_TRUE, // XXX could be optimized
nsnull /* ignore overflow */);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(fixedStatus), "fixed frames can be truncated, but not incomplete");
// Return our desired size

Просмотреть файл

@ -184,6 +184,7 @@ public:
nsPageFrame_id,
nsPlaceholderFrame_id,
nsPopupSetFrame_id,
nsPositionedInlineFrame_id,
nsProgressFrame_id,
nsProgressMeterFrame_id,
nsResizerFrame_id,

Просмотреть файл

@ -47,7 +47,6 @@
#include "nsIScrollableFrame.h"
#include "nsDisplayList.h"
#include "FrameLayerBuilder.h"
#include "nsAbsoluteContainingBlock.h"
using namespace mozilla;
@ -70,7 +69,7 @@ ViewportFrame::Init(nsIContent* aContent,
void
ViewportFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
DestroyAbsoluteFrames(aDestructRoot);
mFixedContainer.DestroyFrames(this, aDestructRoot);
nsContainerFrame::DestroyFrom(aDestructRoot);
}
@ -78,11 +77,20 @@ 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
return nsContainerFrame::SetInitialChildList(aListName, aChildList);
if (nsGkAtoms::fixedList == aListName) {
rv = mFixedContainer.SetInitialChildList(this, aListName, aChildList);
}
else {
rv = nsContainerFrame::SetInitialChildList(aListName, aChildList);
}
return rv;
}
NS_IMETHODIMP
@ -90,6 +98,13 @@ 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;
@ -104,9 +119,18 @@ NS_IMETHODIMP
ViewportFrame::AppendFrames(nsIAtom* aListName,
nsFrameList& aFrameList)
{
NS_ASSERTION(!aListName, "unexpected child list");
NS_ASSERTION(GetChildList(nsnull).IsEmpty(), "Shouldn't have any kids!");
return nsContainerFrame::AppendFrames(aListName, 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_IMETHODIMP
@ -114,17 +138,57 @@ ViewportFrame::InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList)
{
NS_ASSERTION(!aListName, "unexpected child list");
NS_ASSERTION(GetChildList(nsnull).IsEmpty(), "Shouldn't have any kids!");
return nsContainerFrame::InsertFrames(aListName, aPrevFrame, 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_IMETHODIMP
ViewportFrame::RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame)
{
NS_ASSERTION(!aListName, "unexpected child list");
return nsContainerFrame::RemoveFrame(aListName, 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);
}
/* virtual */ nscoord
@ -136,6 +200,8 @@ ViewportFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
result = 0;
else
result = mFrames.FirstChild()->GetMinWidth(aRenderingContext);
// XXXldb Deal with mFixedContainer (matters for SizeToContent)!
return result;
}
@ -149,6 +215,8 @@ ViewportFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
result = 0;
else
result = mFrames.FirstChild()->GetPrefWidth(aRenderingContext);
// XXXldb Deal with mFixedContainer (matters for SizeToContent)!
return result;
}
@ -246,24 +314,20 @@ ViewportFrame::Reflow(nsPresContext* aPresContext,
// to reflect the available space for the fixed items
nsHTMLReflowState reflowState(aReflowState);
nsPoint offset = AdjustReflowStateForScrollbars(&reflowState);
#ifdef DEBUG
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");
}
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");
#endif
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 */);
}
// 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 we were dirty then do a repaint
if (GetStateBits() & NS_FRAME_IS_DIRTY) {

Просмотреть файл

@ -45,13 +45,15 @@
#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.
* list. It stores fixed positioned items in a secondary child list and its mFixedContainer
* delegate handles them.
*/
class ViewportFrame : public nsContainerFrame {
public:
@ -61,6 +63,7 @@ public:
ViewportFrame(nsStyleContext* aContext)
: nsContainerFrame(aContext)
, mFixedContainer(nsGkAtoms::fixedList)
{}
virtual ~ViewportFrame() { } // useful for debugging
@ -83,6 +86,10 @@ public:
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);
@ -111,11 +118,13 @@ 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;
};

Просмотреть файл

@ -1,12 +0,0 @@
<!DOCTYPE html>
<div>test</div>
<style>
body {
width: 100px; height: 300px;
position: absolute;
-moz-transform: scale(0.5);
}
div { position: absolute; }
</style>

Просмотреть файл

@ -1643,7 +1643,6 @@ HTTP(..) == 654057-1.html 654057-1-ref.html
fails-if(layersGPUAccelerated&&cocoaWidget) == 654950-1.html 654950-1-ref.html # Quartz alpha blending doesn't match GL alpha blending
== 652775-1.html 652775-1-ref.html
== 655549-1.html 655549-1-ref.html
!= 656875.html about:blank
== 658952.html 658952-ref.html
== 664127-1.xul 664127-1-ref.xul
== 660682-1.html 660682-1-ref.html

Просмотреть файл

@ -1086,7 +1086,7 @@ nsTableFrame::GetAdditionalChildListName(PRInt32 aIndex) const
if (aIndex == NS_TABLE_FRAME_OVERFLOW_LIST_INDEX) {
return nsGkAtoms::overflowList;
}
return nsHTMLContainerFrame::GetAdditionalChildListName(aIndex);
return nsnull;
}
nsRect

Просмотреть файл

@ -227,7 +227,7 @@ nsTableOuterFrame::GetChildList(nsIAtom* aListName) const
if (!aListName) {
return mFrames;
}
return nsHTMLContainerFrame::GetChildList(aListName);
return nsFrameList::EmptyList();
}
nsIAtom*
@ -236,7 +236,7 @@ nsTableOuterFrame::GetAdditionalChildListName(PRInt32 aIndex) const
if (aIndex == NS_TABLE_FRAME_CAPTION_LIST_INDEX) {
return nsGkAtoms::captionList;
}
return nsHTMLContainerFrame::GetAdditionalChildListName(aIndex);
return nsnull;
}
NS_IMETHODIMP

Просмотреть файл

@ -398,7 +398,7 @@ nsMenuFrame::GetAdditionalChildListName(PRInt32 aIndex) const
if (NS_MENU_POPUP_LIST_INDEX == aIndex) {
return nsGkAtoms::popupList;
}
return nsBoxFrame::GetAdditionalChildListName(aIndex);
return nsnull;
}
void