diff --git a/src/attributes.ts b/src/attributes.ts index a8d6ef77..1c57559a 100644 --- a/src/attributes.ts +++ b/src/attributes.ts @@ -146,7 +146,12 @@ export const attributeRules: Record< element(next, data, options) { const { adapter } = options; const { name, value } = data; - if (whitespaceRe.test(value)) { + /* + * An empty value (or one containing whitespace, which can never be a + * single token) matches nothing — same as `^=`/`$=`/`*=` with an empty + * value. See https://www.w3.org/TR/selectors-4/#attribute-representation + */ + if (value === "" || whitespaceRe.test(value)) { return boolbase.falseFunc; } diff --git a/test/attributes.ts b/test/attributes.ts index 5f4419d8..4b268d04 100644 --- a/test/attributes.ts +++ b/test/attributes.ts @@ -91,6 +91,12 @@ describe("Attributes", () => { ); }); + it("should for ~= with an empty value", () => { + expect(CSSselect._compileUnsafe("[foo~='']")).toBe( + boolbase.falseFunc, + ); + }); + it("should for $=", () => { expect(CSSselect._compileUnsafe("[foo$='']")).toBe( boolbase.falseFunc,