Bug 804323. Mark newly-transformed frames as abs-pos containers (or not). r=bzbarsky

This commit is contained in:
Robert O'Callahan 2012-10-26 22:11:24 +13:00
parent e9e379c62d
commit c23292286b
6 changed files with 84 additions and 7 deletions

View File

@ -8149,13 +8149,27 @@ nsCSSFrameConstructor::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
if (NeedToReframeForAddingOrRemovingTransform(frame)) {
NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
} else {
// We can just add this state bit unconditionally, since it's
// conservative. Normally frame construction would set this if needed,
// but we're not going to reconstruct the frame so we need to set it.
// It's because we need to set this bit on each affected frame
// Normally frame construction would set state bits as needed,
// but we're not going to reconstruct the frame so we need to set them.
// It's because we need to set this state on each affected frame
// that we can't coalesce nsChangeHint_AddOrRemoveTransform hints up
// to ancestors (i.e. it can't be an inherited change hint).
frame->AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
if (frame->IsPositioned()) {
// If a transform has been added, we'll be taking this path,
// but we may be taking this path even if a transform has been
// removed. It's OK to add the bit even if it's not needed.
frame->AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
if (!frame->IsAbsoluteContainer()) {
frame->MarkAsAbsoluteContainingBlock();
}
} else {
// Don't remove NS_FRAME_MAY_BE_TRANSFORMED since it may still by
// transformed by other means. It's OK to have the bit even if it's
// not needed.
if (frame->IsAbsoluteContainer()) {
frame->MarkAsNotAbsoluteContainingBlock();
}
}
}
}
if (hint & nsChangeHint_ReconstructFrame) {

View File

@ -249,11 +249,28 @@ nsIFrame::GetAbsoluteContainingBlock() const {
}
void
nsIFrame::MarkAsAbsoluteContainingBlock() {
nsIFrame::MarkAsAbsoluteContainingBlock()
{
NS_ASSERTION(!Properties().Get(AbsoluteContainingBlockProperty()),
"Already has an abs-pos containing block property?");
NS_ASSERTION(!HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN),
"Already has NS_FRAME_HAS_ABSPOS_CHILDREN state bit?");
AddStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
Properties().Set(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListID()));
}
void
nsIFrame::MarkAsNotAbsoluteContainingBlock()
{
NS_ASSERTION(!HasAbsolutelyPositionedChildren(), "Think of the children!");
NS_ASSERTION(Properties().Get(AbsoluteContainingBlockProperty()),
"Should have an abs-pos containing block property");
NS_ASSERTION(HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN),
"Should have NS_FRAME_HAS_ABSPOS_CHILDREN state bit");
RemoveStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
Properties().Delete(AbsoluteContainingBlockProperty());
}
void
nsIFrame::ClearDisplayItemCache()
{

View File

@ -2870,7 +2870,8 @@ NS_PTR_TO_INT32(frame->Properties().Get(nsIFrame::ParagraphDepthProperty()))
bool IsAbsoluteContainer() const { return !!(mState & NS_FRAME_HAS_ABSPOS_CHILDREN); }
bool HasAbsolutelyPositionedChildren() const;
nsAbsoluteContainingBlock* GetAbsoluteContainingBlock() const;
virtual void MarkAsAbsoluteContainingBlock();
void MarkAsAbsoluteContainingBlock();
void MarkAsNotAbsoluteContainingBlock();
// Child frame types override this function to select their own child list name
virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const { return kAbsoluteList; }

View File

@ -0,0 +1,19 @@
<!DOCTYPE HTML>
<html>
<head>
<style>
body { margin:0; padding:0; overflow:hidden; }
#new {
position: absolute;
left: 200px;
top: 100px;
width: 100px;
height: 100px;
background: yellow;
}
</style>
</head>
<body>
<div id="new"></div>
</body>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<html>
<head>
<style>
body { margin:0; padding:0; overflow:hidden; }
#new {
position: absolute;
left: 100px;
top: 100px;
width: 100px;
height: 100px;
background: yellow;
}
</style>
</head>
<body>
<div id="new" style="display:none"></div>
<script>
document.body.getBoundingClientRect().height;
document.body.style.transform = "translateX(100px)";
document.body.getBoundingClientRect().width;
document.getElementById("new").style.display = "";
</script>
</body>
</html>

View File

@ -1726,3 +1726,4 @@ fuzzy-if(true,17,5859) == 759036-2.html 759036-2-ref.html
fuzzy(40,800) == 797797-1.html 797797-1-ref.html # 'opacity:N' and rgba(,,,N) text don't match precisely
fuzzy(40,800) == 797797-2.html 797797-2-ref.html # 'opacity:N' and rgba(,,,N) text don't match precisely
== 801994-1.html 801994-1-ref.html
== 804323-1.html 804323-1-ref.html