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

This commit is contained in:
Robert O'Callahan 2013-01-25 17:50:32 +13:00
parent 2f49e6acff
commit b6c051330b
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 is equal to the abs-pos containing
// block, use the abs-pos containing block's abs-pos list for fixed-pos
// frames.
mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock),
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 is equal to the abs-pos containing
// block, use the abs-pos containing block's abs-pos list for fixed-pos
// frames.
mFixedPosIsAbsPos(aFixedContainingBlock == aAbsoluteContainingBlock),
mHavePendingPopupgroup(false),
mCreatingExtraFrames(false),
mTreeMatchContext(true, nsRuleWalker::eRelevantLinkUnvisited,
@ -5588,12 +5590,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
@ -5608,7 +5611,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;
@ -5624,9 +5630,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;
@ -5635,22 +5641,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*
@ -6647,8 +6641,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());
@ -7082,8 +7077,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 ?
@ -8696,8 +8692,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;
@ -10568,8 +10565,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
@ -10956,8 +10954,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