fix: remove every occurrence of a repeated class

RemoveClass deleted each class with one strings.ReplaceAll pass over the
space-wrapped class list. Two adjacent occurrences share the space
between them, so " a a " holds only one non-overlapping " a " and the
second survived: RemoveClass("a") on class="a a" returned with
HasClass("a") still true. ToggleClass used the same expression and so
toggled such a class the wrong way.

Replace one occurrence at a time, re-scanning from the start, in a helper
shared by both call sites. Whitespace between the remaining classes is
untouched.
This commit is contained in:
dualfroz committed 2026-09-04 07:52:26 +02:00
1 parent 445cd7eabe
commit 048bc98ddf
2 files changed
+81 -4

No files matched your search

+59
View File
@@ -250,3 +250,62 @@ func TestToggleClass(t *testing.T) {
t.Errorf("Expected #nf1 to have no classes, have %q", a)
}
}
func TestRemoveClassRepeatedInSource(t *testing.T) {
cases := []struct {
class string
remove string
expected string
}{
{"a a", "a", ""},
{"a a a", "a", ""},
{"a b a", "a", "b"},
{"a b a b", "a", "b b"},
{"a b a b", "a b", ""},
{"a a b", "a", "b"},
{"b a a", "a", "b"},
}
for _, c := range cases {
doc, err := NewDocumentFromReader(strings.NewReader(`<div id="t" class="` + c.class + `"></div>`))
if err != nil {
t.Fatal(err)
}
sel := doc.Find("#t")
sel.RemoveClass(c.remove)
got, _ := sel.Attr("class")
if got != c.expected {
t.Errorf("class=%q RemoveClass(%q): got class %q, want %q", c.class, c.remove, got, c.expected)
}
for _, removed := range strings.Fields(c.remove) {
if sel.HasClass(removed) {
t.Errorf("class=%q RemoveClass(%q): still has class %q", c.class, c.remove, removed)
}
}
}
}
func TestToggleClassRepeatedInSource(t *testing.T) {
doc, err := NewDocumentFromReader(strings.NewReader(`<div id="t" class="a a b"></div>`))
if err != nil {
t.Fatal(err)
}
sel := doc.Find("#t")
sel.ToggleClass("a")
if sel.HasClass("a") {
t.Error("expected #t to not have class a after toggling it off")
}
if !sel.HasClass("b") {
t.Error("expected #t to keep class b")
}
sel.ToggleClass("a")
if !sel.HasClass("a") {
t.Error("expected #t to have class a after toggling it back on")
}
}