123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- <!DOCTYPE HTML>
- <html>
- <!--
- https://bugzilla.mozilla.org/show_bug.cgi?id=1131371
- -->
- <head>
- <meta charset="utf-8">
- <title>Test for Bug 1131371</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=1131371">Mozilla Bug 1131371</a>
- <div id="display">
- <div id="content">
- </div>
- </div>
- <pre id="test">
- <script type="application/javascript;version=1.7">
- "use strict";
- /** Test for Bug 1131371 **/
- /**
- * This test verifies that certain style changes do or don't cause reflow
- * and/or frame construction. We do this by checking the framesReflowed &
- * framesConstructed counts, before & after a style-change, and verifying
- * that any change to these counts is in line with our expectations.
- *
- * Each entry in gTestcases contains these member-values:
- * - beforeStyle (optional): initial value to use for "style" attribute.
- * - afterStyle: value to change the "style" attribute to.
- *
- * Testcases may also include two optional member-values to express that reflow
- * and/or frame construction *are* in fact expected:
- * - expectConstruction (optional): if set to something truthy, then we expect
- * frame construction to occur when afterStyle is set. Otherwise, we
- * expect that frame construction should *not* occur.
- * - expectReflow (optional): if set to something truthy, then we expect
- * reflow to occur when afterStyle is set. Otherwise, we expect that
- * reflow should *not* occur.
- */
- const gTestcases = [
- // Things that shouldn't cause reflow:
- // -----------------------------------
- // * Adding an outline (e.g. for focus ring).
- {
- afterStyle: "outline: 1px dotted black",
- },
- // * Changing between completely different outlines.
- {
- beforeStyle: "outline: 2px solid black",
- afterStyle: "outline: 6px dashed yellow",
- },
- // * Adding a box-shadow.
- {
- afterStyle: "box-shadow: inset 3px 3px gray",
- },
- {
- afterStyle: "box-shadow: 0px 0px 10px 30px blue"
- },
- // * Changing between completely different box-shadow values,
- // e.g. from an upper-left shadow to a bottom-right shadow:
- {
- beforeStyle: "box-shadow: -15px -20px teal",
- afterStyle: "box-shadow: 30px 40px yellow",
- },
- // * Adding a text-shadow.
- {
- afterStyle: "text-shadow: 3px 3px gray",
- },
- {
- afterStyle: "text-shadow: 0px 0px 10px blue"
- },
- // * Changing between completely different text-shadow values,
- // e.g. from an upper-left shadow to a bottom-right shadow:
- {
- beforeStyle: "text-shadow: -15px -20px teal",
- afterStyle: "text-shadow: 30px 40px yellow",
- },
- // Things that *should* cause reflow:
- // ----------------------------------
- // (e.g. to make sure our counts are actually measuring something)
- // * Changing 'height' should cause reflow, but not frame construction.
- {
- beforeStyle: "height: 10px",
- afterStyle: "height: 15px",
- expectReflow: true,
- },
- // * Changing 'overflow' on <body> should cause reflow,
- // but not frame reconstruction
- {
- elem: document.body,
- /* beforeStyle: implicitly 'overflow:visible' */
- afterStyle: "overflow: hidden",
- expectConstruction: false,
- expectReflow: true,
- },
- {
- elem: document.body,
- /* beforeStyle: implicitly 'overflow:visible' */
- afterStyle: "overflow: scroll",
- expectConstruction: false,
- expectReflow: true,
- },
- {
- elem: document.body,
- beforeStyle: "overflow: hidden",
- afterStyle: "overflow: auto",
- expectConstruction: false,
- expectReflow: true,
- },
- {
- elem: document.body,
- beforeStyle: "overflow: hidden",
- afterStyle: "overflow: scroll",
- expectConstruction: false,
- expectReflow: true,
- },
- {
- elem: document.body,
- beforeStyle: "overflow: hidden",
- afterStyle: "overflow: visible",
- expectConstruction: false,
- expectReflow: true,
- },
- {
- elem: document.body,
- beforeStyle: "overflow: auto",
- afterStyle: "overflow: hidden",
- expectConstruction: false,
- expectReflow: true,
- },
- {
- elem: document.body,
- beforeStyle: "overflow: visible",
- afterStyle: "overflow: hidden",
- expectConstruction: false,
- expectReflow: true,
- },
- // * Changing 'overflow' on <html> should cause reflow,
- // but not frame reconstruction
- {
- elem: document.documentElement,
- /* beforeStyle: implicitly 'overflow:visible' */
- afterStyle: "overflow: auto",
- expectConstruction: false,
- expectReflow: true,
- },
- {
- elem: document.documentElement,
- beforeStyle: "overflow: visible",
- afterStyle: "overflow: auto",
- expectConstruction: false,
- expectReflow: true,
- },
- // * Setting 'overflow' on arbitrary node should cause reflow as well as
- // frame reconstruction
- {
- /* beforeStyle: implicitly 'overflow:visible' */
- afterStyle: "overflow: auto",
- expectConstruction: true,
- expectReflow: true,
- },
- {
- beforeStyle: "overflow: auto",
- afterStyle: "overflow: visible",
- expectConstruction: true,
- expectReflow: true,
- },
- // * Changing 'display' should cause frame construction and reflow.
- {
- beforeStyle: "display: inline",
- afterStyle: "display: table",
- expectConstruction: true,
- expectReflow: true,
- },
- ];
- // Helper function to let us call either "is" or "isnot" & assemble
- // the failure message, based on the provided parameters.
- function checkFinalCount(aFinalCount, aExpectedCount,
- aExpectChange, aMsgPrefix, aCountDescription)
- {
- let compareFunc;
- let msg = aMsgPrefix;
- if (aExpectChange) {
- compareFunc = isnot;
- msg += "should cause " + aCountDescription;
- } else {
- compareFunc = is;
- msg += "should not cause " + aCountDescription;
- }
- compareFunc(aFinalCount, aExpectedCount, msg);
- }
- // Vars used in runOneTest that we really only have to look up once:
- const gUtils = SpecialPowers.getDOMWindowUtils(window);
- const gElem = document.getElementById("content");
- function runOneTest(aTestcase)
- {
- // sanity-check that we have the one main thing we need:
- if (!aTestcase.afterStyle) {
- ok(false, "testcase is missing an 'afterStyle' to change to");
- return;
- }
- // Figure out which element we'll be tweaking (defaulting to gElem)
- let elem = aTestcase.elem ?
- aTestcase.elem : gElem;
- // Verify that 'style' attribute is unset (avoid causing ourselves trouble):
- if (elem.hasAttribute("style")) {
- ok(false,
- "test element has 'style' attribute already set! We're going to stomp " +
- "on whatever's there when we clean up...");
- }
- // Set the "before" style, and compose the first part of the message
- // to be used in our "is"/"isnot" invocations:
- let msgPrefix = "Changing style ";
- if (aTestcase.beforeStyle) {
- elem.setAttribute("style", aTestcase.beforeStyle);
- msgPrefix += "from '" + aTestcase.beforeStyle + "' ";
- }
- msgPrefix += "on " + elem.nodeName + " ";
- // Establish initial counts:
- let unusedVal = elem.offsetHeight; // flush layout
- let origFramesConstructed = gUtils.framesConstructed;
- let origFramesReflowed = gUtils.framesReflowed;
- // Make the change and flush:
- elem.setAttribute("style", aTestcase.afterStyle);
- unusedVal = elem.offsetHeight; // flush layout
- // Make our is/isnot assertions about whether things should have changed:
- checkFinalCount(gUtils.framesConstructed, origFramesConstructed,
- aTestcase.expectConstruction, msgPrefix,
- "frame construction");
- checkFinalCount(gUtils.framesReflowed, origFramesReflowed,
- aTestcase.expectReflow, msgPrefix,
- "reflow");
- // Clean up!
- elem.removeAttribute("style");
- }
- gTestcases.forEach(runOneTest);
- </script>
- </pre>
- </body>
- </html>
|