From 2f5741f704e062180e3424c1126ba5b30cf6dd07 Mon Sep 17 00:00:00 2001 From: Byungwoo Lee Date: Mon, 18 Sep 2023 18:48:03 -0700 Subject: [PATCH] Fix :has() invalidation bug when removing anchor element's siblings This CL fixes a :has() invalidation bug when the following conditions are met: 1. A style rule uses a :has() pseudo class. The :has() test result is affected by the anchor element's relationship to its sibling element at fixed distance. (e.g. '.a:has(+ .b) {}') 2. The :has() pseudo class was tested on an anchor element and it didn't matched. 3. If a sibling of the anchor element is removed, the :has() will match the anchor element. (e.g. '
') 4. Remove a sibling of the anchor element so that the :has() matches the anchor element. (e.g. 'target.remove();') For the removal, StyleEngine have to schedule :has() invalidation even if the removed element doesn't have any identifier stored in RuleFeatureSet. But it is not efficient to schedule :has() invalidation for every element removal. To avoid unnecessary :has() invalidation, StyleEngine checks whether its parent has the 'ChildrenAffectedByDirectAdjacentRules' flag set or not. Currently, the SelectorChecker sets the flag only when it consumes a direct adjacent combinator(+). This works most cases but it doesn't work in this case (condition #2) because the SelectorChecker stops the :has() argument selector matching before consuming the direct adjacent combinator. Due to this, the parent of the anchor element doesn't have the 'ChildrenAffectedByDirectAdjacentRules' flag set and the StyleEngine doesn't schedule the :has() invalidation for the removal. To fix the error, when the SelectorChecker tests a :has() pseudo class on an anchor element and the :has() is affected by the anchor element's relationship to a sibling at fixed distance, the SelectorChecker sets the flag of the parent to indicate that StyleEngine need to schedule :has() invalidation whenever any child of the element is removed. Bug: 1480643 Change-Id: I5ec2e3c1db2773020368415f68bca1503367e669 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4864627 Commit-Queue: Byungwoo Lee Reviewed-by: Rune Lillesveen Cr-Commit-Position: refs/heads/main@{#1198137} --- .../has-sibling-insertion-removal.html | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 css/selectors/invalidation/has-sibling-insertion-removal.html diff --git a/css/selectors/invalidation/has-sibling-insertion-removal.html b/css/selectors/invalidation/has-sibling-insertion-removal.html new file mode 100644 index 00000000000000..1331a22ad5528b --- /dev/null +++ b/css/selectors/invalidation/has-sibling-insertion-removal.html @@ -0,0 +1,186 @@ + + +:has() invalidation for sibling insertion and removal + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+