| <!DOCTYPE html> |
| <meta charset="utf-8" /> |
| <title>CSS Selectors Invalidation: :link, :visited :any-link, pseudo-class in :has() argument</title> |
| <link rel="author" title="Byungwoo Lee" href="blee@igalia.com"> |
| <link rel="help" href="https://drafts.csswg.org/selectors/#relational"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <style> |
| #parent { color: blue; } |
| #grandparent { color: blue; } |
| #parent:has(> :not(:link)) { color: grey; } |
| #parent:has(> :link) { color: green; } |
| #parent:has(> :visited) { color: red; } |
| #grandparent:has(:not(:any-link)) { color: grey; } |
| #grandparent:has(:any-link) { color: green; } |
| </style> |
| <div id="grandparent"></div> |
| <script> |
| const BLUE = "rgb(0, 0, 255)"; |
| const GREY = "rgb(128, 128, 128)"; |
| const GREEN = "rgb(0, 128, 0)"; |
| const RED = "rgb(255, 0, 0)"; |
| |
| function checkColor(id, color, target_matches) { |
| let element = document.getElementById(id); |
| let message = ["location.hash ==", location.hash, ": #" + id, "should be", |
| color, (target_matches ? "with" : "without"), |
| ":target"].join(" "); |
| assert_equals(getComputedStyle(element).color, color, message); |
| } |
| |
| promise_test(async () => { |
| assert_equals(getComputedStyle(grandparent).color, BLUE, |
| "grandparent should be blue without any element"); |
| |
| let parent = document.createElement("div"); |
| parent.id = "parent"; |
| grandparent.appendChild(parent); |
| |
| assert_equals(getComputedStyle(grandparent).color, GREY, |
| "grandparent should be grey after parent added"); |
| assert_equals(getComputedStyle(parent).color, BLUE, |
| "parent should be blue without any link"); |
| |
| let div = document.createElement("div"); |
| parent.appendChild(div); |
| |
| assert_equals(getComputedStyle(grandparent).color, GREY, |
| "grandparent should be grey after div added"); |
| assert_equals(getComputedStyle(parent).color, GREY, |
| "parent should be grey after div added"); |
| |
| let visited = document.createElement("a"); |
| visited.href = ""; |
| parent.appendChild(visited); |
| |
| assert_equals(getComputedStyle(grandparent).color, GREEN, |
| "grandparent should be green after visited link added"); |
| assert_equals(getComputedStyle(parent).color, GREEN, |
| "parent should be green after visited link added"); |
| |
| let unvisited = document.createElement("a"); |
| unvisited.href = "unvisited"; |
| parent.appendChild(unvisited); |
| |
| assert_equals(getComputedStyle(grandparent).color, GREEN, |
| "grandparent should be green after unvisited link added"); |
| assert_equals(getComputedStyle(parent).color, GREEN, |
| "parent should be green after unvisited link added"); |
| |
| unvisited.remove(); |
| |
| assert_equals(getComputedStyle(grandparent).color, GREEN, |
| "grandparent should be green after unvisited link removed"); |
| assert_equals(getComputedStyle(parent).color, GREEN, |
| "parent should be blue after unvisited link removed"); |
| |
| visited.remove(); |
| |
| assert_equals(getComputedStyle(grandparent).color, GREY, |
| "grandparent should be grey after visited link removed"); |
| assert_equals(getComputedStyle(parent).color, GREY, |
| "parent should be grey after visited link removed"); |
| |
| div.remove(); |
| |
| assert_equals(getComputedStyle(grandparent).color, GREY, |
| "grandparent should be grey after div removed"); |
| assert_equals(getComputedStyle(parent).color, BLUE, |
| "parent should be blue after div removed"); |
| |
| parent.remove(); |
| |
| assert_equals(getComputedStyle(grandparent).color, BLUE, |
| "grandparent should be blue after parent removed"); |
| }); |
| </script> |