tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

contain-layout-dynamic-001.html (7060B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>Dynamic change to layout containment</title>
      4 <link rel="help" href="https://drafts.csswg.org/css-contain/#contain-property">
      5 <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1765615">
      6 <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
      7 <script src="/resources/testharness.js"></script>
      8 <script src="/resources/testharnessreport.js"></script>
      9 <meta name="assert" content="Verify layout containment is properly updated after dynamic change to the contain property.">
     10 <style>
     11  /* Selectors for contain */
     12  #none .wrapper {
     13      contain: none;
     14  }
     15  #layout .wrapper {
     16      contain: layout;
     17  }
     18  #none_to_layout .wrapper {
     19      contain: none;
     20  }
     21  #layout_to_none .wrapper {
     22      contain: layout;
     23  }
     24 
     25  /* Selectors for testing absolute/fixed positioned elements */
     26  #top_spacer {
     27      height: 100px;
     28      background: lightgray;
     29  }
     30  .absolute_pos {
     31      position: absolute;
     32      top: 42px;
     33  }
     34  .fixed_pos {
     35      position: fixed;
     36      top: 42px;
     37  }
     38 
     39  /* Selectors for testing baseline */
     40  .flex {
     41      display: inline-flex;
     42      align-items: baseline;
     43  }
     44 
     45  /* Selectors for testing IFC (floats) */
     46  .floatleft {
     47      float: left;
     48  }
     49  .clearleft {
     50      clear: left;
     51  }
     52 
     53  /* Selectors for testing IFC (margin collapsing) */
     54  .blockmargin {
     55      margin: 25px 0;
     56  }
     57  .wrapper.blockmargin {
     58      background: lightgray;
     59  }
     60 
     61  .rect {
     62      background: black;
     63      width: 50px;
     64      height: 100px;
     65  }
     66 </style>
     67 <body>
     68  <div id="log"></div>
     69 
     70  <div id="top_spacer"></div>
     71 
     72  <div id="none">
     73    <div class="wrapper">
     74      <div class="absolute_pos"></div>
     75      <div class="fixed_pos"></div>
     76    </div>
     77    <div class="flex">
     78      <div class="rect"></div>
     79      <div class="wrapper rect">X</div>
     80    </div>
     81    <div>
     82      <div class="floatleft rect"></div>
     83      <div class="wrapper">
     84        <div class="clearleft rect"></div>
     85      </div>
     86    </div>
     87    <div>
     88      <div class="wrapper blockmargin">
     89        <div class="rect blockmargin"></div>
     90      </div>
     91    </div>
     92  </div>
     93 
     94  <div id="layout">
     95    <div class="wrapper">
     96      <div class="absolute_pos"></div>
     97      <div class="fixed_pos"></div>
     98    </div>
     99    <div class="flex">
    100      <div class="rect"></div>
    101      <div class="wrapper rect">X</div>
    102    </div>
    103    <div>
    104      <div class="floatleft rect"></div>
    105      <div class="wrapper">
    106        <div class="clearleft rect"></div>
    107      </div>
    108    </div>
    109    <div>
    110      <div class="wrapper blockmargin">
    111        <div class="rect blockmargin"></div>
    112      </div>
    113    </div>
    114  </div>
    115 
    116  <div id="none_to_layout">
    117    <div class="wrapper">
    118      <div class="absolute_pos"></div>
    119      <div class="fixed_pos"></div>
    120    </div>
    121    <div class="flex">
    122      <div class="rect"></div>
    123      <div class="wrapper rect">X</div>
    124    </div>
    125    <div>
    126      <div class="floatleft rect"></div>
    127      <div class="wrapper">
    128        <div class="clearleft rect"></div>
    129      </div>
    130    </div>
    131    <div>
    132      <div class="wrapper blockmargin">
    133        <div class="rect blockmargin"></div>
    134      </div>
    135    </div>
    136  </div>
    137 
    138  <div id="layout_to_none">
    139    <div class="wrapper">
    140      <div class="absolute_pos"></div>
    141      <div class="fixed_pos"></div>
    142    </div>
    143    <div class="flex">
    144      <div class="rect"></div>
    145      <div class="wrapper rect">X</div>
    146    </div>
    147    <div>
    148      <div class="floatleft rect"></div>
    149      <div class="wrapper">
    150        <div class="clearleft rect"></div>
    151      </div>
    152    </div>
    153    <div>
    154      <div class="wrapper blockmargin">
    155        <div class="rect blockmargin"></div>
    156      </div>
    157    </div>
    158  </div>
    159 
    160  <script>
    161    function verifyLayoutContainment(id, applied) {
    162        let container = document.getElementById(id);
    163        let wrappers = container.getElementsByClassName("wrapper");
    164 
    165        // To verify the containment box establishes an absolute positioning
    166        // containing block and a fixed positioning containing block, we test
    167        // positions of absolutely/fixed positioned children (a bit below the
    168        // containment box rather than a bit below the top of the viewport).
    169        let containingBlockTop = wrappers[0].getBoundingClientRect().top;
    170        let absTop = container.getElementsByClassName("absolute_pos")[0]
    171            .getBoundingClientRect().top;
    172        assert_equals(absTop > containingBlockTop, applied, "absolute positioning containing block");
    173        let fixedTop = container.getElementsByClassName("fixed_pos")[0]
    174            .getBoundingClientRect().top;
    175        assert_equals(fixedTop > containingBlockTop, applied, "fixed positioning containing block");
    176 
    177        // To verify the containment box suppresses baseline, we verify that
    178        // the two items in the flex container are properly aligned.
    179        let item1 = wrappers[1];
    180        let item2 = item1.previousElementSibling;
    181        let aligned = Math.abs(item1.getBoundingClientRect().top - item2.getBoundingClientRect().top) <= 1;
    182        assert_equals(aligned, applied, "vertical baseline suppressed");
    183 
    184        // To verify the containment box establishes an independent formatting
    185        // context, we test position the clear: left div with respect to the
    186        // float: left div.
    187        let floatLeft = wrappers[2].previousElementSibling;
    188        let clearLeft = wrappers[2].firstElementChild;
    189        let clearNextToFloat = Math.abs(floatLeft.getBoundingClientRect().top - clearLeft.getBoundingClientRect().top) <= 1;
    190        assert_equals(clearNextToFloat, applied, "independent formatting context (floats)");
    191 
    192        // In addition, we verify that the margin inside the containment box
    193        // are not collapsed.
    194        let IFCWithMargin = wrappers[3];
    195        let childWithMargin = IFCWithMargin.firstElementChild;
    196        let marginCollapsed = Math.abs(IFCWithMargin.getBoundingClientRect().height - childWithMargin.getBoundingClientRect().height) <= 1;
    197        assert_equals(!marginCollapsed, applied, "independent formatting context (margins collapsing)");
    198    }
    199 
    200    function setContain(id, value) {
    201        let container = document.getElementById(id);
    202        Array.from(container.getElementsByClassName("wrapper"))
    203            .forEach(element => element.style.contain = value);
    204    }
    205 
    206    promise_test(async () => {
    207        await document.fonts.ready;
    208        verifyLayoutContainment("none", /* applied=*/false);
    209    }, "contain: none");
    210 
    211    promise_test(async () => {
    212        await document.fonts.ready;
    213        verifyLayoutContainment("layout", /* applied=*/true);
    214    }, "contain: layout");
    215 
    216    promise_test(async () => {
    217        await document.fonts.ready;
    218        setContain("none_to_layout", "layout");
    219        verifyLayoutContainment("none_to_layout", /* applied=*/true)
    220    }, "switching contain from none to layout");
    221 
    222    promise_test(async () => {
    223        await document.fonts.ready;
    224        setContain("layout_to_none", "none");
    225        verifyLayoutContainment("layout_to_none", /* applied=*/false);
    226    }, "switching contain from layout to none");
    227  </script>
    228 </body>