Move AffectedBySubjectHas flag to HasInvalidationFlags.

:has() invalidation doesn't work properly when the :has() pseudo
class is in the subject position and the 'display' property of the
:has() anchor element is 'none' since the 'AffectedBySubjectHas'
flag is in the computed style extra fields.

To fix the bug, this CL moves the AffectedBySubjectHas flag to the
HasInvalidationFlags so that the flag can be stored in the element
rare data.

Like the other :has() related flags in HasInvalidationFlags, the
AffectedBySubjectHas flag will not be cleared after the flag is set.

Bug: 1347181
Change-Id: I98d68c87433f7c1a9a169ea1c471993336216f1d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3787517
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Commit-Queue: Byungwoo Lee <blee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#1029123}
diff --git a/css/selectors/invalidation/subject-has-invalidation-with-display-none-anchor-element.html b/css/selectors/invalidation/subject-has-invalidation-with-display-none-anchor-element.html
new file mode 100644
index 0000000..6c87560
--- /dev/null
+++ b/css/selectors/invalidation/subject-has-invalidation-with-display-none-anchor-element.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>CSS Selectors Invalidation: subject :has() invalidation with display: none anchor element</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>
+  #target:has(~ input:checked) { display: none; }
+</style>
+<p>Click checkbox</p>
+<div id="target">PASS</div>
+<input type="checkbox" id="checkme">
+<label for="checkme">Check me!</label>
+<script>
+  test(function() {
+    checkme.checked = false;
+    assert_equals(getComputedStyle(target).display, "block",
+                  "target display should be empty");
+
+    checkme.checked = true;
+    assert_equals(getComputedStyle(target).display, "none",
+                  "target display should be none");
+
+    checkme.checked = false;
+    assert_equals(getComputedStyle(target).display, "block",
+                  "target display should be empty again");
+  });
+</script>