mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 1258911. Correctly reframe an absolutely positioned frame that goes from having a transform to not having one and has an abs pos kid with a fixed-pos descendant. r=dbaron
Instead of skipping the absolute and fixed child lists, we walk all kids of the frame. But before recursing down into things that are absolute containing blocks we ensure that we're only looking for fixed-pos placeholders, so we don't reframe if we have a relatively positioned descendant with absolutely positioned kids, for example. Note that this part is pure optimization attempt, and it might be cheaper to not do it: IsAbsoluteContainingBlock is not that cheap and the situations where we avoid reframing due to this optimization are likely fairly rare.
This commit is contained in:
parent
0e5b46b6d6
commit
f795d19994
@ -661,10 +661,9 @@ static bool
|
||||
FrameHasPositionedPlaceholderDescendants(nsIFrame* aFrame,
|
||||
uint32_t aPositionMask)
|
||||
{
|
||||
const nsIFrame::ChildListIDs skip(nsIFrame::kAbsoluteList |
|
||||
nsIFrame::kFixedList);
|
||||
MOZ_ASSERT(aPositionMask & (1 << NS_STYLE_POSITION_FIXED));
|
||||
|
||||
for (nsIFrame::ChildListIterator lists(aFrame); !lists.IsDone(); lists.Next()) {
|
||||
if (!skip.Contains(lists.CurrentID())) {
|
||||
for (nsIFrame* f : lists.CurrentList()) {
|
||||
if (f->GetType() == nsGkAtoms::placeholderFrame) {
|
||||
nsIFrame* outOfFlow =
|
||||
@ -677,9 +676,19 @@ FrameHasPositionedPlaceholderDescendants(nsIFrame* aFrame,
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (FrameHasPositionedPlaceholderDescendants(f, aPositionMask)) {
|
||||
return true;
|
||||
uint32_t positionMask = aPositionMask;
|
||||
// Is it faster to check aPositionMask & (1 << NS_STYLE_POSITION_ABSOLUTE)
|
||||
// before we check IsAbsPosContainingBlock? Not clear....
|
||||
if (f->IsAbsPosContainingBlock()) {
|
||||
if (f->IsFixedPosContainingBlock()) {
|
||||
continue;
|
||||
}
|
||||
// We don't care about absolutely positioned things inside f, because
|
||||
// they will still use f as their containing block.
|
||||
positionMask = (1 << NS_STYLE_POSITION_FIXED);
|
||||
}
|
||||
if (FrameHasPositionedPlaceholderDescendants(f, positionMask)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
layout/reftests/transform/dynamic-addremove-2-ref.html
Normal file
3
layout/reftests/transform/dynamic-addremove-2-ref.html
Normal file
@ -0,0 +1,3 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="background: green">
|
||||
</html>
|
17
layout/reftests/transform/dynamic-addremove-2.html
Normal file
17
layout/reftests/transform/dynamic-addremove-2.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="background: red">
|
||||
<div style="transform: translate3d(0, 0, 0); position: absolute;
|
||||
top: 0; left: 0; width: 100px; height: 100px">
|
||||
<div style="position: absolute">
|
||||
<div style="position: fixed; width: 100%; height: 100%; top: 0; left: 0;
|
||||
background: green">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
onload = function() {
|
||||
document.body.offsetWidth;
|
||||
document.querySelector("div").style.transform = "none";
|
||||
}
|
||||
</script>
|
||||
</html>
|
@ -9,6 +9,7 @@
|
||||
== dynamic-addremove-1a.html dynamic-addremove-1-ref.html
|
||||
== dynamic-addremove-1b.html dynamic-addremove-1-ref.html
|
||||
== dynamic-addremove-1c.html dynamic-addremove-1-ref.html
|
||||
== dynamic-addremove-2.html dynamic-addremove-2-ref.html
|
||||
# translatex should act like position: relative
|
||||
skip-if(B2G||Mulet) == translatex-1a.html translatex-1-ref.html # bug 773482 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) == translatex-1b.html translatex-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
Loading…
Reference in New Issue
Block a user