Bug 849996. Check the correct frame for transforms in PushAbsoluteContainingBlock --- it might not be the containing block itself. r=bzbarsky

This commit is contained in:
Robert O'Callahan 2013-04-08 16:09:35 +12:00
parent bf197ee0b6
commit aee7119fc8
5 changed files with 78 additions and 15 deletions

View File

@ -791,7 +791,12 @@ public:
// logic in GetAbsoluteContainingBlock. // logic in GetAbsoluteContainingBlock.
// Also makes aNewAbsoluteContainingBlock the containing block for // Also makes aNewAbsoluteContainingBlock the containing block for
// fixed-pos elements if necessary. // fixed-pos elements if necessary.
// aPositionedFrame is the frame whose style actually makes
// aNewAbsoluteContainingBlock a containing block. E.g. for a scrollable element
// aPositionedFrame is the element's primary frame and
// aNewAbsoluteContainingBlock is the scrolled frame.
void PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteContainingBlock, void PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteContainingBlock,
nsIFrame* aPositionedFrame,
nsFrameConstructorSaveState& aSaveState); nsFrameConstructorSaveState& aSaveState);
// Function to push the existing float containing block state and // Function to push the existing float containing block state and
@ -1029,6 +1034,7 @@ AdjustAbsoluteContainingBlock(nsIFrame* aContainingBlockIn)
void void
nsFrameConstructorState::PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteContainingBlock, nsFrameConstructorState::PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteContainingBlock,
nsIFrame* aPositionedFrame,
nsFrameConstructorSaveState& aSaveState) nsFrameConstructorSaveState& aSaveState)
{ {
aSaveState.mItems = &mAbsoluteItems; aSaveState.mItems = &mAbsoluteItems;
@ -1044,14 +1050,14 @@ nsFrameConstructorState::PushAbsoluteContainingBlock(nsIFrame* aNewAbsoluteConta
mFixedItems = mAbsoluteItems; mFixedItems = mAbsoluteItems;
} }
mAbsoluteItems = mAbsoluteItems =
nsAbsoluteItems(AdjustAbsoluteContainingBlock(aNewAbsoluteContainingBlock)); nsAbsoluteItems(AdjustAbsoluteContainingBlock(aNewAbsoluteContainingBlock));
/* See if we're wiring the fixed-pos and abs-pos lists together. This happens iff /* See if we're wiring the fixed-pos and abs-pos lists together. This happens iff
* we're a transformed element. * we're a transformed element.
*/ */
mFixedPosIsAbsPos = aNewAbsoluteContainingBlock && mFixedPosIsAbsPos = aPositionedFrame &&
aNewAbsoluteContainingBlock->StyleDisplay()->HasTransform(aNewAbsoluteContainingBlock); aPositionedFrame->StyleDisplay()->HasTransform(aPositionedFrame);
if (aNewAbsoluteContainingBlock) { if (aNewAbsoluteContainingBlock) {
aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock(); aNewAbsoluteContainingBlock->MarkAsAbsoluteContainingBlock();
@ -1955,7 +1961,7 @@ nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState,
(display->HasTransformStyle() && (display->HasTransformStyle() &&
aParentFrame->IsFrameOfType(nsIFrame::eSupportsCSSTransforms))) && aParentFrame->IsFrameOfType(nsIFrame::eSupportsCSSTransforms))) &&
!aParentFrame->IsSVGText()) { !aParentFrame->IsSVGText()) {
aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState); aState.PushAbsoluteContainingBlock(newFrame, newFrame, absoluteSaveState);
} }
if (aItem.mFCData->mBits & FCDATA_USE_CHILD_ITEMS) { if (aItem.mFCData->mBits & FCDATA_USE_CHILD_ITEMS) {
ConstructFramesFromItemList(aState, aItem.mChildItems, ConstructFramesFromItemList(aState, aItem.mChildItems,
@ -2357,6 +2363,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
// the root element // the root element
mDocElementContainingBlock->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); mDocElementContainingBlock->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
state.PushAbsoluteContainingBlock(mDocElementContainingBlock, state.PushAbsoluteContainingBlock(mDocElementContainingBlock,
mDocElementContainingBlock,
absoluteSaveState); absoluteSaveState);
} }
@ -2443,7 +2450,8 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
mDocElementContainingBlock), mDocElementContainingBlock),
mDocElementContainingBlock, styleContext, mDocElementContainingBlock, styleContext,
&contentFrame, frameItems, &contentFrame, frameItems,
display->IsPositioned(contentFrame), nullptr); display->IsPositioned(contentFrame) ? contentFrame : nullptr,
nullptr);
newFrame = frameItems.FirstChild(); newFrame = frameItems.FirstChild();
NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames"); NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
} }
@ -3064,7 +3072,7 @@ nsCSSFrameConstructor::ConstructFieldSetFrame(nsFrameConstructorState& aState,
newFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); newFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
if (newFrame->IsPositioned()) { if (newFrame->IsPositioned()) {
aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState); aState.PushAbsoluteContainingBlock(newFrame, newFrame, absoluteSaveState);
} }
ProcessChildren(aState, content, styleContext, blockFrame, true, ProcessChildren(aState, content, styleContext, blockFrame, true,
@ -3615,7 +3623,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
nsFrameConstructorSaveState absoluteSaveState; nsFrameConstructorSaveState absoluteSaveState;
if (bits & FCDATA_FORCE_NULL_ABSPOS_CONTAINER) { if (bits & FCDATA_FORCE_NULL_ABSPOS_CONTAINER) {
aState.PushAbsoluteContainingBlock(nullptr, absoluteSaveState); aState.PushAbsoluteContainingBlock(nullptr, nullptr, absoluteSaveState);
} else if (!(bits & FCDATA_SKIP_ABSPOS_PUSH)) { } else if (!(bits & FCDATA_SKIP_ABSPOS_PUSH)) {
nsIFrame* cb = maybeAbsoluteContainingBlock; nsIFrame* cb = maybeAbsoluteContainingBlock;
cb->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); cb->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
@ -3624,7 +3632,7 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
(maybeAbsoluteContainingBlockDisplay->HasTransformStyle() && (maybeAbsoluteContainingBlockDisplay->HasTransformStyle() &&
cb->IsFrameOfType(nsIFrame::eSupportsCSSTransforms))) && cb->IsFrameOfType(nsIFrame::eSupportsCSSTransforms))) &&
!cb->IsSVGText()) { !cb->IsSVGText()) {
aState.PushAbsoluteContainingBlock(cb, absoluteSaveState); aState.PushAbsoluteContainingBlock(cb, primaryFrame, absoluteSaveState);
} }
} }
@ -4359,7 +4367,7 @@ nsCSSFrameConstructor::ConstructScrollableBlock(nsFrameConstructorState& aState,
ConstructBlock(aState, scrolledContentStyle->StyleDisplay(), content, ConstructBlock(aState, scrolledContentStyle->StyleDisplay(), content,
newFrame, newFrame, scrolledContentStyle, newFrame, newFrame, scrolledContentStyle,
&scrolledFrame, blockItem, &scrolledFrame, blockItem,
aDisplay->IsPositioned(scrolledFrame), aDisplay->IsPositioned(newFrame) ? newFrame : nullptr,
aItem.mPendingBinding); aItem.mPendingBinding);
NS_ASSERTION(blockItem.FirstChild() == scrolledFrame, NS_ASSERTION(blockItem.FirstChild() == scrolledFrame,
@ -4402,7 +4410,8 @@ nsCSSFrameConstructor::ConstructNonScrollableBlock(nsFrameConstructorState& aSta
ConstructBlock(aState, aDisplay, aItem.mContent, ConstructBlock(aState, aDisplay, aItem.mContent,
aState.GetGeometricParent(aDisplay, aParentFrame), aState.GetGeometricParent(aDisplay, aParentFrame),
aParentFrame, styleContext, &newFrame, aParentFrame, styleContext, &newFrame,
aFrameItems, aDisplay->IsPositioned(newFrame), aFrameItems,
aDisplay->IsPositioned(newFrame) ? newFrame : nullptr,
aItem.mPendingBinding); aItem.mPendingBinding);
return newFrame; return newFrame;
} }
@ -10892,7 +10901,7 @@ nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState,
nsStyleContext* aStyleContext, nsStyleContext* aStyleContext,
nsIFrame** aNewFrame, nsIFrame** aNewFrame,
nsFrameItems& aFrameItems, nsFrameItems& aFrameItems,
bool aAbsPosContainer, nsIFrame* aPositionedFrameForAbsPosContainer,
PendingBinding* aPendingBinding) PendingBinding* aPendingBinding)
{ {
// Create column wrapper if necessary // Create column wrapper if necessary
@ -10937,9 +10946,9 @@ nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState,
// in nsBlockFrame::CalculateContainingBlockSizeForAbsolutes. // in nsBlockFrame::CalculateContainingBlockSizeForAbsolutes.
nsFrameConstructorSaveState absoluteSaveState; nsFrameConstructorSaveState absoluteSaveState;
(*aNewFrame)->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); (*aNewFrame)->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
if (aAbsPosContainer) { if (aPositionedFrameForAbsPosContainer) {
// NS_ASSERTION(aRelPos, "should have made area frame for this"); // NS_ASSERTION(aRelPos, "should have made area frame for this");
aState.PushAbsoluteContainingBlock(*aNewFrame, absoluteSaveState); aState.PushAbsoluteContainingBlock(*aNewFrame, aPositionedFrameForAbsPosContainer, absoluteSaveState);
} }
// Process the child content // Process the child content
@ -11038,7 +11047,7 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
if (positioned) { if (positioned) {
// Relatively positioned frames becomes a container for child // Relatively positioned frames becomes a container for child
// frames that are positioned // frames that are positioned
aState.PushAbsoluteContainingBlock(newFrame, absoluteSaveState); aState.PushAbsoluteContainingBlock(newFrame, newFrame, absoluteSaveState);
} }
// Process the child content // Process the child content

View File

@ -1582,6 +1582,9 @@ private:
// block // block
// @param aContentParent is the parent the block would have if it // @param aContentParent is the parent the block would have if it
// were in-flow // were in-flow
// @param aPositionedFrameForAbsPosContainer if non-null, then the new
// block should be an abs-pos container and aPositionedFrameForAbsPosContainer
// is the frame whose style is making this block an abs-pos container.
// @param aPendingBinding the pending binding from this block's frame // @param aPendingBinding the pending binding from this block's frame
// construction item. // construction item.
void ConstructBlock(nsFrameConstructorState& aState, void ConstructBlock(nsFrameConstructorState& aState,
@ -1592,7 +1595,7 @@ private:
nsStyleContext* aStyleContext, nsStyleContext* aStyleContext,
nsIFrame** aNewFrame, nsIFrame** aNewFrame,
nsFrameItems& aFrameItems, nsFrameItems& aFrameItems,
bool aAbsPosContainer, nsIFrame* aPositionedFrameForAbsPosContainer,
PendingBinding* aPendingBinding); PendingBinding* aPendingBinding);
nsIFrame* ConstructInline(nsFrameConstructorState& aState, nsIFrame* ConstructInline(nsFrameConstructorState& aState,

View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<style>
#parent {
width: 200px;
height: 200px;
margin-left: 10px;
background: green;
}
#child {
width: 90px;
height: 90px;
background: red;
}
</style>
</head>
<body>
<div id="parent">
<div id="child"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<style>
#parent {
width: 200px;
height: 200px;
overflow: hidden;
transform: translateX(10px);
background: green;
}
#child {
position: fixed;
top: -10px;
left: -10px;
width: 100px;
height: 100px;
background: red;
}
</style>
</head>
<body>
<div id="parent">
<div id="child"></div>
</div>
</body>
</html>

View File

@ -1753,5 +1753,6 @@ skip-if(B2G) == 818276-1.html 818276-1-ref.html
== 847850-1.html 847850-1-ref.html == 847850-1.html 847850-1-ref.html
== 848421-1.html 848421-1-ref.html == 848421-1.html 848421-1-ref.html
test-pref(layout.css.flexbox.enabled,true) == 849407-1.html 849407-1-ref.html test-pref(layout.css.flexbox.enabled,true) == 849407-1.html 849407-1-ref.html
== 849996-1.html 849996-1-ref.html
== 858803-1.html 858803-1-ref.html == 858803-1.html 858803-1-ref.html
!= 860370.html 860370-notref.html != 860370.html 860370-notref.html