Repository navigation
Fix class helpers splitting non-ASCII whitespace class names - #612
Merged
mna merged 2 commits intoOct 5, 2026
Merged
Conversation
HTML class tokens are separated by ASCII whitespace only (WHATWG HTML 2.3.7); any other character is part of the token. PuerkitoBio#552 switched getClassesSlice to strings.Fields, which also splits on Unicode whitespace, so a single class name containing NBSP/EM SPACE/NARROW NBSP was read as several tokens by Add/Remove/ToggleClass while HasClass and the class-attribute normalization treat those characters as token content. The result: AddClass re-appends the split pieces as new classes, RemoveClass and ToggleClass cannot remove the name, and setClasses trimmed Unicode whitespace from attribute edges. Restore ASCII-only boundaries: getClassesSlice uses FieldsFunc over the five ASCII whitespace characters, and the entry/exit trimming in the helpers and setClasses trims the same set so Unicode whitespace at attribute edges is preserved verbatim. Form feed stays a separator, and the tokenizer change keeps the no-empty-entries behavior of PuerkitoBio#552. Benchmarks (darwin/arm64, Go 1.26.4, -count=3 means vs master): AddClass 27279 -> 28776 ns/op (+5.5%), RemoveClass 28166 -> 29047 ns/op (+3.1%); B/op and allocs/op unchanged (7024/1776 B, 374 allocs). Signed-off-by: sergioperezcheco <checo520@outlook.com>
Cover Add/Remove/ToggleClass over class names containing NBSP, EM SPACE, NARROW NBSP and vertical tab, mid-name and at attribute edges, plus direct tokenizer expectations that only the five ASCII whitespace characters split tokens. Attribute round-trips verify the stored value byte-for-byte. These cases fail on master after PuerkitoBio#552 and pass with the preceding change. Signed-off-by: sergioperezcheco <checo520@outlook.com>
Contributor
Author
|
The workflow run for head 36c04bf is marked |
Member
|
Thanks for the fix! |
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.
Single class names containing non-ASCII whitespace (NBSP, EM SPACE,
NARROW NBSP) are broken by the class helpers since #552: AddClass
re-appends the name split into pieces as extra classes, RemoveClass
cannot remove it, and ToggleClass behaves wrongly, while HasClass and
the class-attribute normalization treat those characters as part of the
token.
Root cause
HTML class tokens are separated by ASCII whitespace only (WHATWG HTML
standard 2.3.7); any other character is part of the token. #552 changed
getClassesSlice from an ASCII replacer plus strings.Split to
strings.Fields, which also splits on Unicode whitespace. HasClass and
getClassesAndAttr still normalize with the ASCII-only
classTrimReplacer, so the tokenizers now disagree:
a\u00a0b a ba\u00a0b keepleaveskeep(fails) and ona\u00a0balone clears the whole attributea binstead of toggling the nameFix
characters (keeps the no-empty-entries behavior of perf: replace regex+Split with strings.Fields in getClassesSlice #552)
trim only ASCII whitespace, preserving Unicode whitespace at attribute
edges verbatim
Verification
master 0ac7142 and pass with this change; attribute round-trips are
byte-for-byte.
AddClass 27279 -> 28776 ns/op (+5.5%), RemoveClass 28166 -> 29047
ns/op (+3.1%); B/op and allocs/op unchanged. FieldsFunc keeps the
allocation win that motivated perf: replace regex+Split with strings.Fields in getClassesSlice #552.
AI-assisted contribution, disclosed per the Hermes automation workflow;
DCO sign-off included.