Bug 830192. Integrate GetFixedContainingBlock into GetAbsoluteContainingBlock and ensure only elements which can be abs-pos containing blocks are turned into fixed-pos containing blocks when transformed. r=bzbarsky

--HG--
extra : rebase_source : 4d9bd92b23b1011a8ffba33d009615eb7f42a8a7
This commit is contained in:
Robert O'Callahan 2013-01-23 17:06:12 +13:00
parent a8f1c1e23c
commit cd0a72d12e
6 changed files with 116 additions and 39 deletions

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<body>
<math><menclose id="m" style="transform:translate(10px,0)">
<ll style="display:block">
<ll id=test2 style="display:none; position: fixed"></ll>
</ll>
</menclose></math>
<script>
function doTest() {
document.getElementById("test2").setAttribute("style", "position:fixed")
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</body>
</html>

View File

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<head>
<style>
.test {
position:fixed;
display:none;
width:100px; height:100px;
background:yellow;
}
.doTest .test {
display:block;
}
</style>
</head>
<body>
<table>
<tr style="transform:translate(10px,0)">
<td>
<div class="test"></div>
</td>
</tr>
</table>
<script>
function doTest() {
document.documentElement.setAttribute("class", "doTest");
}
window.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<head>
<style>
.test {
position:fixed;
display:none;
width:100px; height:100px;
background:yellow;
}
.doTest .test {
display:block;
}
</style>
</head>
<body>
<div style="transform:translate(10px,0); overflow:scroll; width:200px; height:200px;">
<div class="test"></div>
</div>
<script>
function doTest() {
document.documentElement.setAttribute("class", "doTest");
}
window.addEventListener("MozReftestInvalidate", doTest, false);
</script>
</body>
</html>

View File

@ -929,9 +929,10 @@ nsFrameConstructorState::nsFrameConstructorState(nsIPresShell* aPresShe
// See PushAbsoluteContaningBlock below
mFrameState(aHistoryState),
mAdditionalStateBits(0),
mFixedPosIsAbsPos(aAbsoluteContainingBlock &&
aAbsoluteContainingBlock->GetStyleDisplay()->
HasTransform(aAbsoluteContainingBlock)),
// If the fixed-pos containing block doesn't have its own fixed-child-list,
// use its abs-pos list instead.
mFixedPosIsAbsPos(aFixedContainingBlock &&
aFixedContainingBlock->GetAbsoluteListID() != nsIFrame::kFixedList),
mHavePendingPopupgroup(false),
mCreatingExtraFrames(false),
mTreeMatchContext(true, nsRuleWalker::eRelevantLinkUnvisited,
@ -962,9 +963,10 @@ nsFrameConstructorState::nsFrameConstructorState(nsIPresShell* aPresShell,
mFloatedItems(aFloatContainingBlock),
// See PushAbsoluteContaningBlock below
mAdditionalStateBits(0),
mFixedPosIsAbsPos(aAbsoluteContainingBlock &&
aAbsoluteContainingBlock->GetStyleDisplay()->
HasTransform(aAbsoluteContainingBlock)),
// If the fixed-pos containing block doesn't have its own fixed-child-list,
// use its abs-pos list instead.
mFixedPosIsAbsPos(aFixedContainingBlock &&
aFixedContainingBlock->GetAbsoluteListID() != nsIFrame::kFixedList),
mHavePendingPopupgroup(false),
mCreatingExtraFrames(false),
mTreeMatchContext(true, nsRuleWalker::eRelevantLinkUnvisited,
@ -5590,12 +5592,13 @@ nsCSSFrameConstructor::GetFrameFor(nsIContent* aContent)
}
nsIFrame*
nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame)
nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame,
ContainingBlockType aType)
{
NS_PRECONDITION(nullptr != mRootElementFrame, "no root element frame");
// Starting with aFrame, look for a frame that is absolutely positioned or
// relatively positioned
// relatively positioned (and transformed, if aType is FIXED)
for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) {
if (frame->IsFrameOfType(nsIFrame::eMathML)) {
// If it's mathml, bail out -- no absolute positioning out from inside
@ -5610,7 +5613,10 @@ nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame)
// Scrollframes are special since they're not positioned, but their
// scrolledframe might be. So, we need to check this special case to return
// the correct containing block (the scrolledframe) in that case.
if (!frame->IsPositioned()) {
// If we're looking for a fixed-pos containing block and the frame is
// not transformed, skip it.
if (!frame->IsPositioned() ||
(aType == FIXED_POS && !frame->GetStyleDisplay()->HasTransform(frame))) {
continue;
}
nsIFrame* absPosCBCandidate = nullptr;
@ -5626,9 +5632,9 @@ nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame)
continue;
}
// For tables, return the outer table frame.
// For tables, skip the inner frame and consider the outer table frame.
if (absPosCBCandidate->GetType() == nsGkAtoms::tableFrame) {
return absPosCBCandidate->GetParent();
continue;
}
// For outer table frames, we can just return absPosCBCandidate.
return absPosCBCandidate;
@ -5637,22 +5643,10 @@ nsCSSFrameConstructor::GetAbsoluteContainingBlock(nsIFrame* aFrame)
// It is possible for the search for the containing block to fail, because
// no absolute container can be found in the parent chain. In those cases,
// we fall back to the document element's containing block.
return mHasRootAbsPosContainingBlock ? mDocElementContainingBlock : nullptr;
}
nsIFrame*
nsCSSFrameConstructor::GetFixedContainingBlock(nsIFrame* aFrame)
{
NS_PRECONDITION(nullptr != mRootElementFrame, "no root element frame");
// Starting with aFrame, look for a frame that is CSS-transformed
for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) {
if (frame->GetStyleDisplay()->HasTransform(frame)) {
return frame;
}
if (aType == FIXED_POS) {
return mFixedContainingBlock;
}
return mFixedContainingBlock;
return mHasRootAbsPosContainingBlock ? mDocElementContainingBlock : nullptr;
}
nsIFrame*
@ -6649,8 +6643,9 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
&parentAfterFrame);
// Create some new frames
nsFrameConstructorState state(mPresShell, GetFixedContainingBlock(parentFrame),
GetAbsoluteContainingBlock(parentFrame),
nsFrameConstructorState state(mPresShell,
GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
GetAbsoluteContainingBlock(parentFrame, ABS_POS),
GetFloatContainingBlock(parentFrame));
state.mTreeMatchContext.InitAncestors(aContainer->AsElement());
@ -7084,8 +7079,9 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
return rv;
}
nsFrameConstructorState state(mPresShell, GetFixedContainingBlock(parentFrame),
GetAbsoluteContainingBlock(parentFrame),
nsFrameConstructorState state(mPresShell,
GetAbsoluteContainingBlock(parentFrame, FIXED_POS),
GetAbsoluteContainingBlock(parentFrame, ABS_POS),
GetFloatContainingBlock(parentFrame),
aFrameState);
state.mTreeMatchContext.InitAncestors(aContainer ?
@ -8698,8 +8694,9 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
// Replicate the header/footer frame.
nsTableRowGroupFrame* headerFooterFrame;
nsFrameItems childItems;
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
GetAbsoluteContainingBlock(newFrame),
nsFrameConstructorState state(mPresShell,
GetAbsoluteContainingBlock(newFrame, FIXED_POS),
GetAbsoluteContainingBlock(newFrame, ABS_POS),
nullptr);
state.mCreatingExtraFrames = true;
@ -10570,8 +10567,9 @@ nsCSSFrameConstructor::CreateLetterFrame(nsIFrame* aBlockFrame,
NS_ASSERTION(aBlockContinuation == GetFloatContainingBlock(aParentFrame),
"Containing block is confused");
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
GetAbsoluteContainingBlock(aParentFrame),
nsFrameConstructorState state(mPresShell,
GetAbsoluteContainingBlock(aParentFrame, FIXED_POS),
GetAbsoluteContainingBlock(aParentFrame, ABS_POS),
aBlockContinuation);
// Create the right type of first-letter frame
@ -10958,8 +10956,8 @@ nsCSSFrameConstructor::CreateListBoxContent(nsPresContext* aPresContext,
// Construct a new frame
if (nullptr != aParentFrame) {
nsFrameItems frameItems;
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
GetAbsoluteContainingBlock(aParentFrame),
nsFrameConstructorState state(mPresShell, GetAbsoluteContainingBlock(aParentFrame, FIXED_POS),
GetAbsoluteContainingBlock(aParentFrame, ABS_POS),
GetFloatContainingBlock(aParentFrame),
mTempFrameTreeState);

View File

@ -1463,8 +1463,11 @@ private:
* corresponding logic in these functions.
*/
public:
nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame);
nsIFrame* GetFixedContainingBlock(nsIFrame* aFrame);
enum ContainingBlockType {
ABS_POS,
FIXED_POS
};
nsIFrame* GetAbsoluteContainingBlock(nsIFrame* aFrame, ContainingBlockType aType);
nsIFrame* GetFloatContainingBlock(nsIFrame* aFrame);
private:

View File

@ -9006,7 +9006,8 @@ void ColorToString(nscolor aColor, nsAutoString &aString)
nsIFrame* nsIPresShell::GetAbsoluteContainingBlock(nsIFrame *aFrame)
{
return FrameConstructor()->GetAbsoluteContainingBlock(aFrame);
return FrameConstructor()->GetAbsoluteContainingBlock(aFrame,
nsCSSFrameConstructor::ABS_POS);
}
#ifdef ACCESSIBILITY