Bug 1417601 - Override dirty rect for OOF frames with containing block outside a modified stacking context r=mattwoodrow

MozReview-Commit-ID: DqvdDECU7dM

--HG--
extra : rebase_source : 3abb1741d8fec40249a4450ed3e867691c490f95
extra : intermediate-source : 0ac00e0c1d107480da7c387ac6969f4eafd96475
extra : source : e88d129b7a6d372adddb781b8e6384f70c08c380
This commit is contained in:
Miko Mynttinen 2017-11-16 16:09:16 +01:00
Родитель fcb1dba461
Коммит 3b508a2e1b
4 изменённых файлов: 82 добавлений и 0 удалений

Просмотреть файл

@ -1119,12 +1119,30 @@ nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsDisplayItem* aItem)
return FindAnimatedGeometryRootFor(aItem->Frame());
}
static bool
AnyContentAncestorModified(nsIFrame* aFrame,
nsIFrame* aStopAtFrame = nullptr)
{
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
if (f->IsFrameModified()) {
return true;
}
if (aStopAtFrame && f == aStopAtFrame) {
break;
}
}
return false;
}
void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
nsIFrame* aFrame)
{
nsRect visible = GetVisibleRect();
nsRect dirtyRectRelativeToDirtyFrame = GetDirtyRect();
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
IsPaintingToWindow()) {
NS_ASSERTION(aDirtyFrame == aFrame->GetParent(), "Dirty frame should be viewport frame");
@ -1168,6 +1186,14 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
return;
}
// If the nearest stacking context for the modified frame is an ancestor of
// of it, and if the stacking context is a descendant of the containing block
// of this OOF frame, we override the dirty rect to ensure that the frame will
// get marked.
if (AnyContentAncestorModified(aFrame, aDirtyFrame)) {
dirty = visible;
}
// Always store OutOfFlowDisplayData for visible frames (even when they aren't dirty)
// since a nested out-of-flow frame might force building and we'll need to have this
// data available.

Просмотреть файл

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#modified {
left: 10px;
}
</style>
</head>
<body>
<div style="opacity:0.9">
<div style="position:fixed; left:300px; top:300px; width:200px; height:200px; background-color:red; z-index:-10"></div>
<div style="width:200px; height:200px; position:relative; background-color:green" id="modified">
<div style="opacity:0.9">
<div style="position:fixed; left:300px; top:300px; width:200px; height:200px; background-color:green; z-index:-10"></div>
</div>
</div>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html class="reftest-wait">
<head>
<meta charset="UTF-8">
<style>
#modified {
left: 0px;
}
</style>
<script type="text/javascript">
function doTest() {
document.getElementById("modified").style.left = "10px";
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", doTest);
</script>
</head>
<body>
<div style="opacity:0.9">
<div style="position:fixed; left:300px; top:300px; width:200px; height:200px; background-color:red; z-index:-10"></div>
<div style="width:200px; height:200px; position:relative; background-color:green" id="modified">
<div style="opacity:0.9">
<div style="position:fixed; left:300px; top:300px; width:200px; height:200px; background-color:green; z-index:-10"></div>
</div>
</div>
</div>
</body>
</html>

Просмотреть файл

@ -10,3 +10,4 @@ skip-if(!retainedDisplayList) == retained-dl-prerender-transform-1.html retained
== retained-dl-wrap-list.html retained-dl-wrap-list-ref.html
fuzzy(1,235200) == 1413073.html 1413073-ref.html
== 1416291.html 1416291-ref.html
== 1417601-1.html 1417601-1-ref.html