gecko-dev/layout/style/test/test_flexbox_reflow_counts....

138 строки
3.8 KiB
HTML

<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1142686
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1142686</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
.flex {
display: flex;
}
#outerFlex {
border: 1px solid black;
}
</style>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1142686">Mozilla Bug 1142686</a>
<div id="display">
<div id="content">
<div class="flex" id="outerFlex">
<div class="flex" id="midFlex">
<div id="innerBlock">
</div>
</div>
</div>
</div>
</div>
<pre id="test">
<script type="application/javascript">
"use strict";
/** Test for Bug 1142686 **/
/**
* This test checks how many reflows are required, when we make a change inside
* a set of two nested flex containers, with various styles applied to
* the containers & innermost child. Some flex layout operations require two
* passes (which can cause exponential blowup). This test is intended to verify
* that certain configurations do *not* require two-pass layout, by comparing
* the reflow-count for a more-complex scenario against a less-complex scenario.
*
* We have two nested flex containers around an initially-empty block. For each
* measurement, we put some text in the block, and we see how many frame-reflow
* operations occur as a result.
*/
const gUtils = SpecialPowers.getDOMWindowUtils(window);
// The elements:
const gOuterFlex = document.getElementById("outerFlex");
const gMidFlex = document.getElementById("midFlex");
const gInnerBlock = document.getElementById("innerBlock");
// Remove contents of inner block, and remove manual styling:
function cleanup()
{
outerFlex.style = midFlex.style = innerBlock.style = "";
while (innerBlock.firstChild) {
innerBlock.firstChild.remove();
}
}
// Each testcase here has a label (used in test output), a function to set up
// the testcase, and (optionally) a function to set up the reference case.
let gTestcases = [
{
label : "border on flex items",
addTestStyle : function() {
midFlex.style.border = innerBlock.style.border = "3px solid black";
},
},
{
label : "padding on flex items",
addTestStyle : function() {
midFlex.style.padding = innerBlock.style.padding = "5px";
},
},
{
label : "margin on flex items",
addTestStyle : function() {
midFlex.style.margin = innerBlock.style.margin = "2px";
},
},
];
// Flush layout & return the global frame-reflow-count
function getReflowCount()
{
let unusedVal = gOuterFlex.offsetHeight; // flush layout
return gUtils.framesReflowed;
}
// This function adds some text inside of gInnerBlock, and returns the number
// of frames that need to be reflowed as a result.
function makeTweakAndCountReflows()
{
let beforeCount = getReflowCount();
gInnerBlock.appendChild(document.createTextNode("hello"));
let afterCount = getReflowCount();
let numReflows = afterCount - beforeCount;
if (numReflows <= 0) {
ok(false, "something's wrong -- we should've reflowed *something*");
}
return numReflows;
}
// Given a testcase (from gTestcases), this function verifies that the
// testcase scenario requires the same number of reflows as the reference
// scenario.
function runOneTest(aTestcase)
{
aTestcase.addTestStyle();
let numTestcaseReflows = makeTweakAndCountReflows();
cleanup();
if (aTestcase.addReferenceStyle) {
aTestcase.addReferenceStyle();
}
let numReferenceReflows = makeTweakAndCountReflows();
cleanup();
is(numTestcaseReflows, numReferenceReflows,
"Testcase & reference case should require same number of reflows" +
" (testcase label: '" + aTestcase.label + "')");
}
gTestcases.forEach(runOneTest);
</script>
</pre>
</body>
</html>