fix(attributes): limit insensitive comparisons to ASCII
[data-foo="ä" i] currently matches data-foo="Ä". The same non-ASCII folding affects all insensitive comparison operators and attributes whose default comparison is insensitive. Selectors require ASCII case-insensitive comparison, so these distinct non-ASCII characters must remain distinct.
Restrict folding to A–Z in string comparisons. Build explicit ASCII character pairs for regex-based comparisons instead of using JavaScript's Unicode-aware i flag. Regex metacharacters remain escaped. Existing ASCII-insensitive behavior is retained.
Validation: eight new cases fail before the fix. npm test passes 226 tests with one existing skipped test, including ESLint, TypeScript and Biome. Tests cover all operators, implicit HTML attribute comparison, exact non-ASCII matches, and literal regex characters. npm run build and git diff --check pass.
Prepared and tested with OpenAI Codex assistance.
Summary by CodeRabbit
- Bug Fixes
- Case-insensitive attribute selectors now match ASCII letters without treating non-ASCII uppercase and lowercase characters as equivalent. This applies across equality, prefix, suffix, substring, word, and hyphen-prefix matching, including negated equality and implicit
typematching. - Attribute values containing regex metacharacters are now matched literally by substring and word selectors. Case-sensitive matching remains unchanged.
- Case-insensitive attribute selectors now match ASCII letters without treating non-ASCII uppercase and lowercase characters as equivalent. This applies across equality, prefix, suffix, substring, word, and hyphen-prefix matching, including negated equality and implicit