document-rules-details-element.https.html (3476B)
1 <!DOCTYPE html> 2 <title>Speculation rules: no crash with selector_matches and details element</title> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script src="../resources/utils.js"></script> 6 7 <body> 8 <script> 9 setup(() => assertSpeculationRulesIsSupported()); 10 11 // This test verifies that using selector_matches with links inside a 12 // <details> element does not cause a crash. This is a regression test for 13 // a bug where forcing style computation on links inside a closed <details> 14 // element would cause DidStyleChildren to incorrectly remove links from 15 // stale_links_, leading to a DCHECK failure in CSSSelectorPredicate::Matches. 16 test(() => { 17 // Create a closed details element with a link inside. 18 const details = document.createElement('details'); 19 document.body.appendChild(details); 20 21 const summary = document.createElement('summary'); 22 summary.textContent = 'Click to expand'; 23 details.appendChild(summary); 24 25 const link = document.createElement('a'); 26 link.href = 'https://example.com/test'; 27 link.className = 'test-link'; 28 link.textContent = 'Link inside details'; 29 details.appendChild(link); 30 31 // Insert a document rule with selector_matches. 32 const script = document.createElement('script'); 33 script.type = 'speculationrules'; 34 script.textContent = JSON.stringify({ 35 prefetch: [{ 36 source: 'document', 37 eagerness: 'immediate', 38 where: { selector_matches: 'a.test-link' } 39 }] 40 }); 41 document.head.appendChild(script); 42 43 // Force style computation on the link. This triggers a forced update 44 // which temporarily allows style computation on display-locked elements. 45 // Before the fix, this would cause a crash when the speculation rules 46 // tried to match the selector against the link. 47 getComputedStyle(link).display; 48 49 // If we get here without crashing, the test passes. 50 assert_true(true, 'No crash occurred'); 51 }, 'selector_matches with link inside closed details should not crash'); 52 53 test(() => { 54 // Create a closed details element with a link inside. 55 const details = document.createElement('details'); 56 document.body.appendChild(details); 57 58 const summary = document.createElement('summary'); 59 summary.textContent = 'Click to expand'; 60 details.appendChild(summary); 61 62 const link = document.createElement('a'); 63 link.href = 'https://example.com/test2'; 64 link.className = 'toggle-link'; 65 link.textContent = 'Link for toggle test'; 66 details.appendChild(link); 67 68 // Insert a document rule with selector_matches. 69 const script = document.createElement('script'); 70 script.type = 'speculationrules'; 71 script.textContent = JSON.stringify({ 72 prefetch: [{ 73 source: 'document', 74 eagerness: 'immediate', 75 where: { selector_matches: 'a.toggle-link' } 76 }] 77 }); 78 document.head.appendChild(script); 79 80 // Rapidly toggle the details element and force style computation. 81 for (let i = 0; i < 10; i++) { 82 details.open = !details.open; 83 getComputedStyle(link).display; 84 } 85 86 // Ensure details is closed at the end. 87 details.open = false; 88 getComputedStyle(link).display; 89 90 // If we get here without crashing, the test passes. 91 assert_true(true, 'No crash occurred during rapid toggling'); 92 }, 'Rapid toggling of details with selector_matches should not crash'); 93 94 </script> 95 </body>