test_flexbox_reflow_counts.html 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <!DOCTYPE HTML>
  2. <html>
  3. <!--
  4. https://bugzilla.mozilla.org/show_bug.cgi?id=1142686
  5. -->
  6. <head>
  7. <meta charset="utf-8">
  8. <title>Test for Bug 1142686</title>
  9. <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  10. <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
  11. <style>
  12. .flex {
  13. display: flex;
  14. }
  15. #outerFlex {
  16. border: 1px solid black;
  17. }
  18. </style>
  19. </head>
  20. <body>
  21. <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1142686">Mozilla Bug 1142686</a>
  22. <div id="display">
  23. <div id="content">
  24. <div class="flex" id="outerFlex">
  25. <div class="flex" id="midFlex">
  26. <div id="innerBlock">
  27. </div>
  28. </div>
  29. </div>
  30. </div>
  31. </div>
  32. <pre id="test">
  33. <script type="application/javascript;version=1.7">
  34. "use strict";
  35. /** Test for Bug 1142686 **/
  36. /**
  37. * This test checks how many reflows are required, when we make a change inside
  38. * a set of two nested flex containers, with various styles applied to
  39. * the containers & innermost child. Some flex layout operations require two
  40. * passes (which can cause exponential blowup). This test is intended to verify
  41. * that certain configurations do *not* require two-pass layout, by comparing
  42. * the reflow-count for a more-complex scenario against a less-complex scenario.
  43. *
  44. * We have two nested flex containers around an initially-empty block. For each
  45. * measurement, we put some text in the block, and we see how many frame-reflow
  46. * operations occur as a result.
  47. */
  48. const gUtils = SpecialPowers.getDOMWindowUtils(window);
  49. // The elements:
  50. const gOuterFlex = document.getElementById("outerFlex");
  51. const gMidFlex = document.getElementById("midFlex");
  52. const gInnerBlock = document.getElementById("innerBlock");
  53. // Remove contents of inner block, and remove manual styling:
  54. function cleanup()
  55. {
  56. outerFlex.style = midFlex.style = innerBlock.style = "";
  57. while (innerBlock.firstChild) {
  58. innerBlock.removeChild(innerBlock.firstChild);
  59. }
  60. }
  61. // Each testcase here has a label (used in test output), a function to set up
  62. // the testcase, and (optionally) a function to set up the reference case.
  63. let gTestcases = [
  64. {
  65. label : "border on flex items",
  66. addTestStyle : function() {
  67. midFlex.style.border = innerBlock.style.border = "3px solid black";
  68. },
  69. },
  70. {
  71. label : "padding on flex items",
  72. addTestStyle : function() {
  73. midFlex.style.padding = innerBlock.style.padding = "5px";
  74. },
  75. },
  76. {
  77. label : "margin on flex items",
  78. addTestStyle : function() {
  79. midFlex.style.margin = innerBlock.style.margin = "2px";
  80. },
  81. },
  82. ];
  83. // Flush layout & return the global frame-reflow-count
  84. function getReflowCount()
  85. {
  86. let unusedVal = gOuterFlex.offsetHeight; // flush layout
  87. return gUtils.framesReflowed;
  88. }
  89. // This function adds some text inside of gInnerBlock, and returns the number
  90. // of frames that need to be reflowed as a result.
  91. function makeTweakAndCountReflows()
  92. {
  93. let beforeCount = getReflowCount();
  94. gInnerBlock.appendChild(document.createTextNode("hello"));
  95. let afterCount = getReflowCount();
  96. let numReflows = afterCount - beforeCount;
  97. if (numReflows <= 0) {
  98. ok(false, "something's wrong -- we should've reflowed *something*");
  99. }
  100. return numReflows;
  101. }
  102. // Given a testcase (from gTestcases), this function verifies that the
  103. // testcase scenario requires the same number of reflows as the reference
  104. // scenario.
  105. function runOneTest(aTestcase)
  106. {
  107. aTestcase.addTestStyle();
  108. let numTestcaseReflows = makeTweakAndCountReflows();
  109. cleanup();
  110. if (aTestcase.addReferenceStyle) {
  111. aTestcase.addReferenceStyle();
  112. }
  113. let numReferenceReflows = makeTweakAndCountReflows();
  114. cleanup();
  115. is(numTestcaseReflows, numReferenceReflows,
  116. "Testcase & reference case should require same number of reflows" +
  117. " (testcase label: '" + aTestcase.label + "')");
  118. }
  119. gTestcases.forEach(runOneTest);
  120. </script>
  121. </pre>
  122. </body>
  123. </html>