Match nothing for empty-value substring attribute selectors - #298
Merged
Conversation
`[attr^=""]`, `[attr$=""]`, and `[attr*=""]` currently match every element that merely has the attribute, because the empty value compiles to `^.*` / `.*?$` / `.*?.*`. Per CSS Selectors Level 4 substring matching, an empty substring value must not represent anything. The sibling `~=` operator already special-cases the empty value to a never-match sentinel; this extends the same handling to the three substring operators. Signed-off-by: chuenchen309 <48723787+chuenchen309@users.noreply.github.com>
Owner
|
Please add to the changelog that this was done by Claude and the user for clarity. |
Owner
|
Scratch that last statement. Such a request doesn't seem to be used widely, so we'll just move forward with the changelog as is. |
Owner
|
@gir-bot lgtm |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The substring attribute selectors
[attr^=""],[attr$=""], and[attr*=""]currently match every element that merely has the attribute, when they should match nothing if the value is empty.Per CSS Selectors Level 4 §6.2 (Substring matching attribute selectors):
Browsers agree:
document.querySelectorAll('[href^=""]')returns an emptyNodeList.Root cause
In
parse_attribute_selector, an empty value compiles to^.*/.*?$/.*?.*, which matches any value. The sibling~=operator already special-cases the empty value to the never-match sentinel[^\s\S]— this PR extends the identical handling to the three substring operators (self-consistency).Reproduction
[href^=""]['1', '2'][][href$=""]['1', '2'][][href*=""]['1', '2'][][href~=""][](already correct)[]Non-empty values (
[href^=f]→['1']) and the case-insensitiveiflag are unaffected.Verification
tests/test_level3/test_attribute.py(styled on the existing~=empty-value test) fail on the unfixed tree, pass after the fix.Related history: closed issue #30 introduced the
~=empty-value handling — confirming this exact spec point is treated as a real bug; the substring operators were simply missed.This PR was authored by an AI coding agent (Claude Code) running on this account: the AI found the bug, ran the repro, wrote the tests, and wrote this description. The human account holder reviews every change and is accountable for it. The verification above is real and re-runnable from the diff. If this isn't the kind of contribution you want, say so and I'll close it.