Bug 1740702 - Ensure grid's cached measurement won't prevent reflow from happending when its subtree is dirty r=dholbert

Differential Revision: https://phabricator.services.mozilla.com/D135611
This commit is contained in:
Sean Feng 2022-01-12 21:51:45 +00:00
Родитель f7f7f6ccba
Коммит e2805ac986
5 изменённых файлов: 161 добавлений и 0 удалений

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

@ -7,3 +7,4 @@
[chrome/test_grid_repeat_auto_fit.html]
[chrome/test_grid_repeat_auto_fill.html]
[chrome/test_grid_tracks.html]
[chrome/test_grid_subtree_dirty.html]

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

@ -0,0 +1,56 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<style>
#grid {
display: grid;
width: 100px;
height: 100px;
}
#initiallyHidden {
display: none;
width: 100px;
height: 100px;
background: lime;
}
</style>
<script>
"use strict";
SimpleTest.waitForExplicitFinish();
function runTests() {
const grid = document.getElementById("grid");
const initiallyHidden = document.getElementById("initiallyHidden");
document.documentElement.offsetHeight; // Flush layout to be sure we have grid-item sizes cached
grid.getGridFragments(); // This marks the grid and its descendants as dirty
document.documentElement.offsetHeight; // Flush layout again. In buggy builds, this layout will fail to reflow/clear-dirty-bits on the grid item.
initiallyHidden.style.display = "block"; // This should trigger a reflow.
let height = getComputedStyle(initiallyHidden).height;
is(height, "100px", "initiallyHidden element should get a reflow and arrive at the expected height after we toggle its display");
SimpleTest.finish();
}
</script>
</head>
<body onLoad="runTests();">
<div id="grid">
<div>
<div>
<div>
<div id="initiallyHidden">
PASS
</div>
</div>
</div>
</div>
</div>
</body>
</html>

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

@ -558,6 +558,10 @@ class nsGridContainerFrame final : public nsContainerFrame {
CachedBAxisMeasurement() = default;
bool IsValidFor(const nsIFrame* aFrame, const LogicalSize& aCBSize) const {
if (aFrame->IsSubtreeDirty()) {
return false;
}
if (!CanCacheMeasurement(aFrame, aCBSize)) {
return false;
}

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

@ -0,0 +1,50 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1740702">
<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
<style>
#grid {
display: grid;
width: 100px;
height: 100px;
background: red;
}
#initiallyHidden {
display: none;
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<p>Test passes if there is a filled green square.</p>
<div id="grid">
<div>
<div>
<div>
<div id="initiallyHidden">
</div>
</div>
</div>
</div>
</div>
<script>
"use strict";
const grid = document.getElementById("grid");
const initiallyHidden = document.getElementById("initiallyHidden");
document.documentElement.offsetHeight; // Flush layout
// Fails in buggy Firefox build because it prevents reflows from happening
getComputedStyle(grid).getPropertyValue("grid-template-columns");
document.documentElement.offsetHeight; // Flush layout again
initiallyHidden.style.display = "block"; // This should trigger a reflow.
</script>
</body>
</html>

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

@ -0,0 +1,50 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1740702">
<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
<style>
#grid {
display: grid;
width: 100px;
height: 90px;
background: red;
}
#initiallyHidden {
display: none;
width: 100px;
height: 100px;
background: green;
}
</style>
</head>
<body>
<p>Test passes if there is a filled green square.</p>
<div id="grid">
<div>
<div>
<div>
<div id="initiallyHidden">
</div>
</div>
</div>
</div>
</div>
<script>
"use strict";
const grid = document.getElementById("grid");
const initiallyHidden = document.getElementById("initiallyHidden");
document.documentElement.offsetHeight; // Flush layout
// Fails in buggy Firefox build because it prevents reflows from happening
grid.style.paddingBottom = "10px";
document.documentElement.offsetHeight; // Flush layout again
initiallyHidden.style.display = "block"; // This should trigger a reflow.
</script>
</body>
</html>