Skip to content

Commit

Permalink
Fix :has() invalidation bug on wiping an element by means of innerHTML
Browse files Browse the repository at this point in the history
There is a bug on :has() invalidation when removing both element and
non-element nodes by assigning new text to element.innerHTML because
ChildrenChangeType::kAllChildrenRemoved is not handled in
Element::ChildChanged().

<style>
div:has(span) { color: red }
</style>
<div id="target"> This is a text <span> with span </span></div>
<script>
target.innerHTML = "This is a text";
</script>

Fixed the bug by handling the ChildrenChangeType::kAllChildrenRemoved
in Element::ChildChanged().

Bug: 1366369
Change-Id: Ibe450fcd37005dd892c4939188aa39428a8565c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3910212
Commit-Queue: Byungwoo Lee <[email protected]>
Reviewed-by: Rune Lillesveen <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1050523}
  • Loading branch information
byung-woo authored and chromium-wpt-export-bot committed Sep 23, 2022
1 parent 5e9bd7a commit f46baf3
Showing 1 changed file with 42 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>:has() invalidation for wiping an element by means of innerHTML</title>
<link rel="author" title="Byungwoo Lee" href="mailto:[email protected]">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://drafts.csswg.org/selectors/#relational">
<style>
div, main { color: grey }
.subject:has(.descendant) { color: green}
</style>
<main id=main>
<div id="subject" class="subject"></div>
</main>
<script>
let grey = 'rgb(128, 128, 128)';
let green = 'rgb(0, 128, 0)';

function test_div(test_name, el, color) {
test(function() {
assert_equals(getComputedStyle(el).color, color);
}, test_name + ': div#' + el.id + '.color');
}

test_div('initial color', subject, grey);

subject.innerHTML = "This is a text <div><div class='descendant'></div></div>";

test_div('color after inserting text and div > .descendant', subject, green);

subject.innerHTML = "This is a text";

test_div('color after wiping #child to remove div > .descendant', subject, grey);

subject.innerHTML = "<div id='child'> This is a text <div class='descendant'></div></div>";

test_div('color after inserting text and #child > .descendant', subject, green);

child.innerHTML = "This is a text";

test_div('color after wiping #child to remove .descendant', subject, grey);
</script>

0 comments on commit f46baf3

Please sign in to comment.