<!DOCTYPE HTML> <html> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1367568 --> <head> <meta charset="utf-8"> <title>Test for Bug 1367568</title> <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug 1367568</a> <div id="content"> <!-- Some fixed-width divs that we shouldn't have to reflow when the viewport changes: --> <div style="width: 100px"> fixed-width <div>(child)</div> </div> <div style="position: absolute; width: 150px"> abs-fixed-width <div>(child)</div> </div> </div> <pre id="test"> <script type="application/javascript"> "use strict"; /** Test for Bug 1367568 **/ /** * This test verifies that "overflow" changes on the <body> don't cause * an unnecessarily large amount of reflow. */ // Vars used in setStyleAndMeasure that we really only have to look up once: const gUtils = SpecialPowers.getDOMWindowUtils(window); function setStyleAndMeasure(initialStyle, finalStyle) { is(document.body.style.length, 0, "Bug in test - body should start with empty style"); let unusedVal = document.body.offsetHeight; // flush layout let constructCount = gUtils.framesConstructed; document.body.style = initialStyle; unusedVal = document.body.offsetHeight; // flush layout let reflowCountBeforeTweak = gUtils.framesReflowed; document.body.style = finalStyle; unusedVal = document.body.offsetHeight; // flush layout let reflowCountAfterTweak = gUtils.framesReflowed; // Clean up: document.body.style = ""; is(gUtils.framesConstructed, constructCount, "Style tweak shouldn't have triggered frame construction"); // ...and return the delta: return reflowCountAfterTweak - reflowCountBeforeTweak; } function main() { // First, we sanity-check that our measurement make sense -- if we leave // styles unchanged, we should measure no frames being reflowed: let count = setStyleAndMeasure("width: 50px; height: 80px", "width: 50px; height: 80px"); is(count, 0, "Shouldn't reflow anything when we leave 'width' & 'height' unchanged"); // Now: see how many frames are reflowed when the "width" & "height" change. // We'll use this as the reference when measuring reflow counts for various // changes to "overflow" below. count = setStyleAndMeasure("width: 50px; height: 80px", "width: 90px; height: 60px"); ok(count > 0, "Should reflow some frames when 'width' & 'height' change"); // Expected maximum number of frames reflowed for "overflow" changes // (+2 is to allow for reflowing scrollbars themselves): const expectedMax = count + 2; // Shared ending for messages in all ok() checks below: const messageSuffix = " shouldn't be greater than count for tweaking width/height on body (" + expectedMax + ")"; // OK, here is where the relevant tests actually begin!! // See how many frames we reflow for various tweaks to "overflow" on // the body -- we expect the count to be no larger than |expectedMax|. count = setStyleAndMeasure("", "overflow: scroll"); ok(count <= expectedMax, "Reflow count when setting 'overflow: scroll' on body (" + count + ")" + messageSuffix); count = setStyleAndMeasure("", "overflow: hidden"); ok(count <= expectedMax, "Reflow count when setting 'overflow: hidden' on body (" + count + ")" + messageSuffix); // Test removal of "overflow: scroll": count = setStyleAndMeasure("overflow: scroll", ""); ok(count <= expectedMax, "Reflow count when removing 'overflow: scroll' from body (" + count + ")" + messageSuffix); count = setStyleAndMeasure("overflow: hidden", ""); ok(count <= expectedMax, "Reflow count when removing 'overflow: hidden' from body (" + count + ")" + messageSuffix); // Test change between two non-'visible' overflow values: count = setStyleAndMeasure("overflow: scroll", "overflow: hidden"); ok(count <= expectedMax, "Reflow count when changing 'overflow' on body (" + count + ")" + messageSuffix); } main(); </script> </pre> </body> </html>