-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support relative selector to update the :has tests
Support the relative selector grammar starting with combinator. - https://www.w3.org/TR/selectors-4/#typedef-relative-selector To simplify matching operation, some relation types are added. - kRelativeDescendant : Leftmost descendant combinator - kRelativeChild : Leftmost child combinator - kRelativeDirectAdjacent : Leftmost next-sibling combinator - kRelativeIndirectAdjacent : Leftmost subsequent-sibling combinator The ':scope' dependency in <relative-selector> definition creates too much confusion especially with ':has' as the CSSWG issue describes. - w3c/csswg-drafts#6399 1. ':scope' behavior in ':has' argument is different with usual ':scope' behavior. 2. Explicit ':scope' in a ':has' argument can create performance issues or increase complexity when the ':scope' is not leftmost or compounded with other simple selectors. 3. Absolutizing a relative selector with ':scope' doesn't make sense when the ':has' argument already has explicit ':scope' (e.g. ':has(~ .a :scope .b)' -> ':has(:scope ~ .a :scope .b)' To skip those complexity and ambiguity, this CL removed some logic related with the 'explicit :scope in :has argument', and added TODO comment to handle it later separately. As suggested in the CSSWG issue, this CL always absolutize the <relative-selector> with a dummy pseudo class. - kPseudoRelativeLeftmost The added pseudo class represents any elements that is at the relative position that matches with the leftmost combinator of the relative selector. This CL also includes tentative tests for some cases involving the ':scope' inside ':has' to show the result of the suggestion. By removing the ':scope' dependency from the relative selector, most of the ':scope' inside ':has' will be meaningless. (It will not match or can be changed more simple/efficient expression) Change-Id: I1e0ccf0c190d04b9636d86cb15e1bbb175b7cc30 Bug: 669058
- Loading branch information
1 parent
380dd71
commit 6f5e733
Showing
4 changed files
with
109 additions
and
143 deletions.
There are no files selected for viewing
69 changes: 69 additions & 0 deletions
69
css/selectors/has-argument-with-explicit-scope.tentative.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>:has pseudo class behavior with explicit ':scope' in its argument</title> | ||
<link rel="author" title="Byungwoo Lee" href="mailto:[email protected]"> | ||
<link rel="help" href="https://drafts.csswg.org/selectors/#relational"> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
|
||
<main> | ||
<div id=d01 class="a"> | ||
<div id=scope1 class="b"> | ||
<div id=d02 class="c"> | ||
<div id=d03 class="c"> | ||
<div id=d04 class="d"></div> | ||
</div> | ||
</div> | ||
<div id=d05 class="e"></div> | ||
</div> | ||
</div> | ||
<div id=d06> | ||
<div id=scope2 class="b"> | ||
<div id=d07 class="c"> | ||
<div id=d08 class="c"> | ||
<div id=d09></div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<script> | ||
function formatElements(elements) { | ||
return elements.map(e => e.id).sort().join(); | ||
} | ||
|
||
// Test that |selector| returns the given elements in the given scope element | ||
function test_selector_all(scope, selector, expected) { | ||
test(function() { | ||
let actual = Array.from(scope.querySelectorAll(selector)); | ||
assert_equals(formatElements(actual), formatElements(expected)); | ||
}, `${selector} matches expected elements on ${scope.id}`); | ||
} | ||
|
||
// Test that |selector1| and |selector2| returns same elements in the given scope element | ||
function compare_selector_all(scope, selector1, selector2) { | ||
test(function() { | ||
let result1 = Array.from(scope.querySelectorAll(selector1)); | ||
let result2 = Array.from(scope.querySelectorAll(selector2)); | ||
assert_equals(formatElements(result1), formatElements(result2)); | ||
}, `${selector1} and ${selector2} returns same elements on ${scope.id}`); | ||
} | ||
|
||
// descendants of a scope element cannot have the scope element as its descendant | ||
test_selector_all(scope1, ':has(:scope)', []); | ||
test_selector_all(scope1, ':has(:scope .c)', []); | ||
test_selector_all(scope1, ':has(.a :scope)', []); | ||
|
||
// there can be more simple and efficient alternative for a ':scope' in ':has' | ||
test_selector_all(scope1, '.a:has(:scope) .c', [d02, d03]); | ||
compare_selector_all(scope1, '.a:has(:scope) .c', ':is(.a :scope .c)'); | ||
test_selector_all(scope2, '.a:has(:scope) .c', []); | ||
compare_selector_all(scope2, '.a:has(:scope) .c', ':is(.a :scope .c)'); | ||
test_selector_all(scope1, '.c:has(:is(:scope .d))', [d02, d03]); | ||
compare_selector_all(scope1, '.c:has(:is(:scope .d))', ':scope .c:has(.d)'); | ||
compare_selector_all(scope1, '.c:has(:is(:scope .d))', '.c:has(.d)'); | ||
test_selector_all(scope2, '.c:has(:is(:scope .d))', []); | ||
compare_selector_all(scope2, '.c:has(:is(:scope .d))', ':scope .c:has(.d)'); | ||
compare_selector_all(scope2, '.c:has(:is(:scope .d))', '.c:has(.d)'); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters