mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-28 12:45:27 +00:00
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:
parent
bf197ee0b6
commit
aee7119fc8
@ -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
|
||||||
|
@ -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,
|
||||||
|
23
layout/reftests/bugs/849996-1-ref.html
Normal file
23
layout/reftests/bugs/849996-1-ref.html
Normal 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>
|
27
layout/reftests/bugs/849996-1.html
Normal file
27
layout/reftests/bugs/849996-1.html
Normal 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>
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user