content-visibility-auto-relevancy-updates-stop-ticking.html (4690B)
1 <!doctype html> 2 <meta charset="utf-8"> 3 <title>Content Visibility: stop ticking after relevancy updates</title> 4 <!-- 5 Copied from testing/web-platform/tests/css/css-contain/content-visibility/content-visibility-auto-relevancy-updates.html 6 --> 7 <link rel="author" title="Frédéric Wang" href="mailto:fwang@igalia.com"> 8 <link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility"> 9 <link rel="help" href="https://drafts.csswg.org/css-contain/#relevant-to-the-user"> 10 <link rel="help" href="https://drafts.csswg.org/css-contain/#cv-notes"> 11 <meta name="assert" content="Verify relevancy is properly updated for content-visibility: auto elements and refresh driver stops ticking after such update."> 12 13 <script src="/resources/testharness.js"></script> 14 <script src="/resources/testharnessreport.js"></script> 15 16 <style> 17 #spacer { 18 height: 300vh; 19 } 20 #contentVisibilityAuto { 21 content-visibility: auto; 22 border: solid; 23 } 24 </style> 25 <div> 26 <div id="log"></div> 27 <div tabindex="1" id="spacer"></div> 28 <div tabindex="2" id="contentVisibilityAuto"> 29 <span>Hello, World!</span> 30 </div> 31 </div> 32 33 <script> 34 function hasPendingTick() { 35 return SpecialPowers.wrap(window).windowUtils.refreshDriverHasPendingTick; 36 } 37 38 // See comment in layout/base/tests/test_bug1756118.html about why the timeouts 39 // etc. 40 async function expectTicksToStop() { 41 for (let i = 0; i < 100; i++) { 42 await new Promise(r => setTimeout(r, 8)); 43 if(!hasPendingTick()) { 44 break; 45 } 46 } 47 assert_false(hasPendingTick(), "refresh driver should have eventually stopped ticking"); 48 } 49 50 function tick() { 51 return new Promise(r => { 52 requestAnimationFrame(() => requestAnimationFrame(r)); 53 }); 54 } 55 56 function contentVisibilityAutoElementIsRelevant() { 57 // A content-visibility: auto element that is not relevant skips its contents, 58 // which do not contribute to the result of innerText. 59 return contentVisibilityAuto.innerText.length > 0; 60 } 61 62 function clearRelevancyReasons() { 63 window.scrollTo(0, 0); 64 spacer.focus({preventScroll: true}); 65 window.getSelection().empty(); 66 } 67 68 promise_test(async function(t) { 69 // Wait for page load. 70 await new Promise(resolve => { window.addEventListener("load", resolve); }); 71 72 // Register cleanup method to reset relevancy. 73 t.add_cleanup(clearRelevancyReasons); 74 75 // Element should initially not be relevant and ticking should have stopped. 76 await SpecialPowers.pushPrefEnv({'set': 77 [['layout.keep_ticking_after_load_ms', 0]]}); 78 await tick(); 79 await expectTicksToStop(); 80 assert_false(contentVisibilityAutoElementIsRelevant(), "initial relevancy"); 81 82 // Make element close to the viewport. 83 contentVisibilityAuto.firstElementChild.scrollIntoView(); 84 await tick(); 85 await expectTicksToStop(); 86 assert_true(contentVisibilityAutoElementIsRelevant(), "close to viewport"); 87 88 // Scroll away from the element again. 89 window.scrollTo(0, 0); 90 await tick(); 91 await expectTicksToStop(); 92 assert_false(contentVisibilityAutoElementIsRelevant(), "far from viewport"); 93 }, "Relevancy updated after changing proximity to the viewport."); 94 95 promise_test(async function(t) { 96 // Register cleanup method to reset relevancy. 97 t.add_cleanup(clearRelevancyReasons); 98 99 // Element should initially not be relevant and no ticking be in progress. 100 await tick(); 101 await expectTicksToStop(); 102 assert_false(contentVisibilityAutoElementIsRelevant(), "initial relevancy"); 103 104 // Focus the element. 105 contentVisibilityAuto.focus({preventScroll: true}); 106 await tick(); 107 await expectTicksToStop(); 108 assert_true(contentVisibilityAutoElementIsRelevant(), "focused"); 109 110 // Unfocus the element again. 111 spacer.focus({preventScroll: true}); 112 await tick(); 113 await expectTicksToStop(); 114 assert_false(contentVisibilityAutoElementIsRelevant(), "unfocused"); 115 }, "Relevancy updated after being focused/unfocused."); 116 117 promise_test(async function(t) { 118 // Register cleanup method to reset relevancy. 119 t.add_cleanup(clearRelevancyReasons); 120 121 // Element should initially not be relevant and no ticking be in progress. 122 await tick(); 123 await expectTicksToStop(); 124 assert_false(contentVisibilityAutoElementIsRelevant(), "initial relevancy"); 125 126 // Select the contents of the element. 127 window.getSelection().selectAllChildren(contentVisibilityAuto); 128 await tick(); 129 await expectTicksToStop(); 130 assert_true(contentVisibilityAutoElementIsRelevant(), "selected"); 131 132 // Unselect the contents of the element. 133 window.getSelection().empty(); 134 await tick(); 135 await expectTicksToStop(); 136 assert_false(contentVisibilityAutoElementIsRelevant(), "unselected"); 137 }, "Relevancy updated after being selected/unselected."); 138 139 </script>