tor-browser

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

content-visibility-size-containment-001.html (9683B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>content-visibility and size containment</title>
      4 <link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
      5 <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1765615">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <script src="/common/rendering-utils.js"></script>
      9 <meta name="assert" content="elements skipping their content change the used value of the contain property to turn on size containment.">
     10 <style>
     11  /* Selectors for content-visibility */
     12  #spacer_for_far_to_viewport {
     13      height: 300vh;
     14  }
     15  .content_visibility {
     16      /* Dynamic modification of content-visibility may change whether style
     17         containment is applied, which in turn may cause drastic invalidations
     18         (e.g. rebuilding counters). Make the test more robust by forcing
     19         style containment to always apply. */
     20      contain: style;
     21  }
     22  #visible .content_visibility {
     23      content-visibility: visible;
     24  }
     25  #hidden .content_visibility {
     26      content-visibility: hidden;
     27  }
     28  #auto_far .content_visibility {
     29      content-visibility: auto;
     30  }
     31  #auto_close .content_visibility {
     32      content-visibility: auto;
     33  }
     34  #visible_to_hidden .content_visibility {
     35      content-visibility: visible;
     36  }
     37  #hidden_to_visible .content_visibility {
     38      content-visibility: hidden;
     39  }
     40  #visible_to_auto_far .content_visibility {
     41      content-visibility: visible;
     42  }
     43  #auto_far_to_visible .content_visibility {
     44      content-visibility: auto;
     45  }
     46  #hidden_to_auto_close .content_visibility {
     47      content-visibility: hidden;
     48  }
     49  #auto_close_to_hidden .content_visibility {
     50      content-visibility: auto;
     51  }
     52  #auto_dynamic_relevancy .content_visibility {
     53      content-visibility: auto;
     54  }
     55 
     56  /* Selectors for testing sizing as empty */
     57  .content_visibility {
     58      display: inline-block;
     59  }
     60  .box {
     61      display: inline-block;
     62      width: 50px;
     63      height: 5px;
     64      background: black;
     65  }
     66 </style>
     67 <body>
     68  <div id="log"></div>
     69 
     70  <div id="visible">
     71    <div class="content_visibility"><div class="box"></div></div>
     72  </div>
     73 
     74  <div id="hidden">
     75    <div class="content_visibility"><div class="box"></div></div>
     76  </div>
     77 
     78  <div id="auto_close">
     79    <div class="content_visibility"><div class="box"></div></div>
     80  </div>
     81 
     82  <div id="visible_to_hidden">
     83    <div class="content_visibility"><div class="box"></div></div>
     84  </div>
     85 
     86  <div id="hidden_to_visible">
     87    <div class="content_visibility"><div class="box"></div></div>
     88  </div>
     89 
     90  <div id="hidden_to_auto">
     91    <div class="content_visibility"><div class="box"></div></div>
     92  </div>
     93 
     94  <div id="auto_to_hidden">
     95    <div class="content_visibility"><div class="box"></div></div>
     96  </div>
     97 
     98  <div id="hidden_to_auto_close">
     99    <div class="content_visibility"><div class="box"></div></div>
    100  </div>
    101 
    102  <div id="auto_close_to_hidden">
    103    <div class="content_visibility"><div class="box"></div></div>
    104  </div>
    105 
    106  <div id="spacer_for_far_to_viewport"></div>
    107 
    108  <div id="auto_far">
    109    <div class="content_visibility"><div class="box"></div></div>
    110  </div>
    111 
    112  <div id="visible_to_auto_far">
    113    <div class="content_visibility"><div class="box"></div></div>
    114  </div>
    115 
    116  <div id="auto_far_to_visible">
    117    <div class="content_visibility"><div class="box"></div></div>
    118  </div>
    119 
    120 
    121  <div id="auto_dynamic_relevancy">
    122    <div tabindex="1"></div>
    123    <div class="content_visibility" tabindex="2"><div class="box"></div></div>
    124  </div>
    125 
    126  <script>
    127    function sizeContainmentApplied(id) {
    128        // To verify size containment, we test the width is zero.
    129        // See contain-size-dynamic-001.html for more details.
    130        let container = document.getElementById(id);
    131        let content_visibility = container.getElementsByClassName("content_visibility")[0];
    132        return content_visibility.getBoundingClientRect().width == 0;
    133    }
    134 
    135    function setContentVisibility(id, value) {
    136        let container = document.getElementById(id);
    137        let content_visibility = container.getElementsByClassName("content_visibility")[0];
    138        content_visibility.style.contentVisibility = value;
    139    }
    140 
    141    promise_test(async () => {
    142        assert_false(sizeContainmentApplied("visible"));
    143    }, "content-visibility: visible");
    144 
    145    promise_test(async () => {
    146        assert_true(sizeContainmentApplied("hidden"));
    147    }, "content-visibility: hidden");
    148 
    149    promise_test(async () => {
    150        await waitForAtLeastOneFrame();
    151        assert_true(sizeContainmentApplied("auto_far"));
    152    }, "content-visibility: auto (far from viewport)");
    153 
    154    promise_test(async () => {
    155        await waitForAtLeastOneFrame();
    156        assert_false(sizeContainmentApplied("auto_close"));
    157    }, "content-visibility: auto (close from viewport)");
    158 
    159    promise_test(async () => {
    160        setContentVisibility("visible_to_hidden", "hidden");
    161        assert_true(sizeContainmentApplied("visible_to_hidden"));
    162    }, "switching content-visibility from visible to hidden");
    163 
    164    promise_test(async () => {
    165        setContentVisibility("hidden_to_visible", "visible");
    166        assert_false(sizeContainmentApplied("hidden_to_visible"));
    167    }, "switching content-visibility from hidden to visible");
    168 
    169    promise_test(async () => {
    170        setContentVisibility("auto_far_to_visible", "visible");
    171        assert_false(sizeContainmentApplied("auto_far_to_visible"));
    172    }, "switching content-visibility from auto (far from viewport) to visible");
    173 
    174    promise_test(async () => {
    175        setContentVisibility("visible_to_auto_far", "auto");
    176        await waitForAtLeastOneFrame();
    177        assert_true(sizeContainmentApplied("visible_to_auto_far"));
    178    }, "switching content-visibility from visible to auto (far from viewport)");
    179 
    180    promise_test(async () => {
    181        setContentVisibility("auto_close_to_hidden", "hidden");
    182        assert_true(sizeContainmentApplied("auto_close_to_hidden"));
    183    }, "switching content-visibility from auto (close from viewport) to hidden");
    184 
    185    promise_test(async () => {
    186        setContentVisibility("hidden_to_auto_close", "auto");
    187        await waitForAtLeastOneFrame();
    188        assert_false(sizeContainmentApplied("hidden_to_auto_close"));
    189    }, "switching content-visibility from hidden to auto (close from viewport)");
    190 
    191 
    192    let contentVisibilityAuto =
    193        document.getElementById("auto_dynamic_relevancy").
    194        getElementsByClassName("content_visibility")[0];
    195 
    196    function clearRelevancyReasons() {
    197        // Scrolling auto_dynamic_relevancy far from the viewport, unfocus it
    198        // and unselect it. Also temporarily set its content-visibility to
    199        // 'hidden' before scrolling to give more chance for browsers to
    200        // re-apply size containment, especially if they fail the corresponding
    201        // tests "going back to initial state" below.
    202        setContentVisibility("auto_dynamic_relevancy", "hidden");
    203        window.scrollTo(0, 0);
    204        document.getElementById("auto_dynamic_relevancy")
    205            .firstElementChild.focus({preventScroll: true});
    206        window.getSelection().empty();
    207        setContentVisibility("auto_dynamic_relevancy", "auto");
    208    }
    209 
    210    promise_test(async (t) => {
    211        t.add_cleanup(clearRelevancyReasons);
    212 
    213        await waitForAtLeastOneFrame();
    214        assert_true(sizeContainmentApplied("auto_dynamic_relevancy"),
    215                    "size containment applied when initially far to the viewport");
    216 
    217        contentVisibilityAuto.scrollIntoView();
    218        await waitForAtLeastOneFrame();
    219        assert_false(sizeContainmentApplied("auto_dynamic_relevancy"),
    220                    "size containment applied when changing from far to close to the viewport");
    221 
    222        window.scrollTo(0, 0);
    223        assert_true(sizeContainmentApplied("auto_dynamic_relevancy"),
    224                    "size containment applied when changing back from close to far to the viewport");
    225    }, "content-visibility: auto, changing proximity to the viewport");
    226 
    227    promise_test(async (t) => {
    228        t.add_cleanup(clearRelevancyReasons);
    229 
    230        await waitForAtLeastOneFrame();
    231        assert_true(sizeContainmentApplied("auto_dynamic_relevancy"),
    232                    "size containment applied when initially unfocused");
    233 
    234        contentVisibilityAuto.focus({preventScroll: true});
    235        await waitForAtLeastOneFrame();
    236        assert_false(sizeContainmentApplied("auto_dynamic_relevancy"),
    237                    "size containment applied after focusing");
    238 
    239        document.getElementById("auto_dynamic_relevancy")
    240            .firstElementChild.focus({preventScroll: true});
    241        assert_true(sizeContainmentApplied("auto_dynamic_relevancy"),
    242                    "size containment applied after unfocusing back");
    243    }, "content-visibility: auto, after being focused/unfocused");
    244 
    245    promise_test(async (t) => {
    246        t.add_cleanup(clearRelevancyReasons);
    247 
    248        await waitForAtLeastOneFrame();
    249        assert_true(sizeContainmentApplied("auto_dynamic_relevancy"),
    250                    "size containment applied when initially unselected");
    251 
    252        window.getSelection().selectAllChildren(contentVisibilityAuto);
    253        await waitForAtLeastOneFrame();
    254        assert_false(sizeContainmentApplied("auto_dynamic_relevancy"),
    255                    "size containment applied when after selecting");
    256 
    257        window.getSelection().empty();
    258        await waitForAtLeastOneFrame();
    259        assert_true(sizeContainmentApplied("auto_dynamic_relevancy"),
    260                    "size containment applied when unselecting back");
    261    }, "content-visibility: auto, after being selected/unselected");
    262 
    263  </script>
    264 </body>