Skip to content

Commit 0acb81f

Browse files
byung-woochromium-wpt-export-bot
authored andcommitted
Preserve invalid selectors in :is() and :where()
As per the resolution in w3c/csswg-drafts/issues/8356 [1], forgiving selector lists (argument of :is(), :where()) need to preserve invalid arguments for serialization, even though they never match anything. Use the existing pseudo type kPseudoUnparsed with kNone nesting type to keep an invalid selector text and change the css selector parser so it creates the placeholder for the failed-parsing complex selector. To keep the current First()/Next() behavior of CSSSelectorList, the methods skip the unparsed-invalid selector. FirstIncludingUnparsedInvalid() and NextIncludingUnparsedInvalid() are added in CSSSelectorList to serialize with the unparsed-invalid selectors. Add a private method IsInvalidWithoutUnparsed() to CSSSelectorList to distinguish an empty list (CSSSelectorList::Empty()) from an invalid list that has unparsed-invalid selectors. Replace the IsValid() checks that meant "empty" with it (e.g. in Copy() and ComputeLength()), so the methods can handle the preserved unparsed invalid selectors. The invalid selector serialization works behind the experimental feature SerializeInvalidSelectorsInForgivingSelectorList. [1] w3c/csswg-drafts#8356 Bug: 40277472 Change-Id: I5d350d815153fbf846ed8763707d0938a2327376 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8068106 Commit-Queue: Byungwoo Lee <blee@igalia.com> Reviewed-by: Rune Lillesveen <futhark@chromium.org> Cr-Commit-Position: refs/heads/main@{#1669314}
1 parent f857cad commit 0acb81f

2 files changed

Lines changed: 13 additions & 3 deletions

File tree

css/selectors/parsing/parse-is-where.html

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
if (valid) {
1717
test_valid_selector(selector, expected_selector);
1818
} else {
19-
test_valid_forgiving_selector(selector);
19+
test_valid_forgiving_selector(selector, expected_selector);
2020
}
2121
}
2222
}
@@ -43,6 +43,15 @@
4343

4444
assert_valid(true, ":not({}(div))", null, "Nested inside :not, without combinators");
4545
assert_valid(true, ":not({}(div .foo))", null, "Nested inside :not, with combinators");
46+
47+
assert_valid(false, "{}(,,,)", "{}(, , , )", "Empty text, whitespace after comma");
48+
assert_valid(false, ":host({}(,,,))", ":host({}(, , , ))", "Empty text, whitespace after comma");
49+
50+
assert_valid(false, ":host({}(.a, .b+.c, .d))", null, "Nested inside :host, serialize invalid selector as-is");
51+
assert_valid(false, "{}(::before:HOVER, .a)", null, "Pseudo-element inside, serialize invalid selector as-is");
52+
assert_valid(false, ":has({}(:has(.a+.b)))", null, "Nested has, serialize invalid selector as-is");
53+
54+
assert_valid(false, "{}(::before:HOVER )", "{}(::before:HOVER)", "Invalid selector, trim trailing whitepaces");
4655
// This should be invalid even with the forgiving behavior because
4756
// `<any-value>` doesn't allow bad tokens:
4857
// https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value

css/support/parsing-testcommon.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ function test_invalid_value(property, value) {
5050
}, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value");
5151
}
5252

53-
function test_valid_forgiving_selector(selector) {
54-
test_valid_selector(selector, selector, { onlyWhenForgiving: true });
53+
function test_valid_forgiving_selector(selector, serializedValue = null) {
54+
test_valid_selector(selector, serializedValue ? serializedValue : selector,
55+
{onlyWhenForgiving: true});
5556
}
5657

5758
// serializedSelector can be the expected serialization of selector,

0 commit comments

Comments
 (0)