Skip to content
This repository was archived by the owner on May 25, 2026. It is now read-only.

Commit 899dc28

Browse files
Merge pull request #8 from udan-jayanith/classList
Class list
2 parents 474da7e + 65b2181 commit 899dc28

6 files changed

Lines changed: 165 additions & 24 deletions

File tree

FUTURE-CHANGELOG.md

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
## v0.0.0-beta.3 <- current
22

33
## v0.0.0
4-
Delete deletes the node without connecting sibling nodes.
5-
* Delete
6-
74
QuerySelector takes attribute name and regexp for the value and returns the first node that matches the regexp.
85
* QuerySelector
96

@@ -13,29 +10,10 @@ QuerySelectorAll takes two regexps and returns all nodes that matches the regexp
1310
Closest returns the closest node that matches the className.
1411
* Closest
1512

16-
## v0.0.1
17-
AddClass add the given class name to the node.
18-
* AddClass
19-
20-
RemoveClass removes the specified class name from the node.
21-
* RemoveClass
22-
23-
HasClass returns a boolean value specifying whether the node has the specified class name or not.
24-
* HasClass
25-
26-
GetClassList returns a map of class names in the specified node.
27-
* GetClassList
28-
2913
## v0.0.2
3014
* GetElementById
3115
* GetElementByClassName
3216
* GetElementByTagName
3317
* GetElementsById
3418
* GetElementsByClassName
35-
* GetElementsByTagName
36-
37-
## v0.0.3
38-
DecodeHeader only serializes only up to head. And return a node with only head and it's child nodes.
39-
* DecodeOnly
40-
* DecodeOnlyByClassName
41-
* DecodeHeader
19+
* GetElementsByTagName

classList.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package GoHtml
2+
3+
import (
4+
"strings"
5+
"sync"
6+
)
7+
8+
type ClassList struct {
9+
classes map[string]struct{}
10+
rwMutex *sync.Mutex
11+
}
12+
13+
// NewClassList returns a new empty ClassList.
14+
func NewClassList() ClassList {
15+
classList := ClassList{
16+
classes: make(map[string]struct{}),
17+
rwMutex: &sync.Mutex{},
18+
}
19+
20+
return classList
21+
}
22+
23+
// AppendClass append className to classList. className that contains multiple classes is also a valid className.
24+
func (classList ClassList) AppendClass(className string) {
25+
classList.rwMutex.Lock()
26+
defer classList.rwMutex.Unlock()
27+
28+
classes := strings.SplitSeq(className, " ")
29+
for v := range classes {
30+
classList.classes[strings.TrimSpace(v)] = struct{}{}
31+
}
32+
}
33+
34+
// SetClass append classes in the node to classList.
35+
func (classList ClassList) SetClass(node *Node) {
36+
if node == nil {
37+
return
38+
}
39+
classes, _ := node.GetAttribute("class")
40+
classList.AppendClass(classes)
41+
}
42+
43+
// Contains returns whether the className exists or not.
44+
func (classList ClassList) Contains(className string) bool {
45+
classList.rwMutex.Lock()
46+
defer classList.rwMutex.Unlock()
47+
48+
classes := strings.SplitSeq(className, " ")
49+
for v := range classes {
50+
_, ok := classList.classes[strings.TrimSpace(v)]
51+
if !ok {
52+
return false
53+
}
54+
}
55+
56+
return true
57+
}
58+
59+
// DeleteClass deletes the specified classes in className.
60+
func (classList ClassList) DeleteClass(className string) {
61+
classList.rwMutex.Lock()
62+
defer classList.rwMutex.Unlock()
63+
64+
classes := strings.SplitSeq(className, " ")
65+
for v := range classes {
66+
delete(classList.classes, strings.TrimSpace(v))
67+
}
68+
}
69+
70+
// Encode returns the full className.
71+
func (classList ClassList) Encode() string {
72+
classList.rwMutex.Lock()
73+
defer classList.rwMutex.Unlock()
74+
75+
classes := ""
76+
for v := range classList.classes {
77+
if classes != ""{
78+
classes+=" "
79+
}
80+
classes+=v
81+
}
82+
return classes
83+
}
84+
85+
// EncodeTo encode className for the node.
86+
func (classList ClassList) EncodeTo(node *Node){
87+
if node == nil {
88+
return
89+
}
90+
node.SetAttribute("class", classList.Encode())
91+
}

classList_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package GoHtml_test
2+
3+
import(
4+
"testing"
5+
"github.com/udan-jayanith/GoHTML"
6+
)
7+
8+
func TestClasses(t *testing.T){
9+
node := GoHtml.CreateNode("div")
10+
node.SetAttribute("class", "div-container main")
11+
12+
classList := GoHtml.NewClassList()
13+
classList.SetClass(node)
14+
if !classList.Contains("main"){
15+
t.Fatal("")
16+
return
17+
}
18+
classList.DeleteClass("main")
19+
if classList.Contains("main"){
20+
t.Fatal("")
21+
return
22+
}
23+
24+
classList.AppendClass("main-div")
25+
if !classList.Contains("main-div"){
26+
t.Fatal("")
27+
return
28+
}
29+
30+
classList.EncodeTo(node)
31+
32+
className, _ := node.GetAttribute("class")
33+
if className != classList.Encode(){
34+
t.Fatal("")
35+
return
36+
}
37+
}

main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ func DeepCloneNode(node *Node) *Node{
3737
attributes := node.attributes
3838
node.rwMutex.Unlock()
3939

40+
if node == nil {
41+
return node
42+
}
43+
4044
newNode := Node{
4145
childNode: node.GetChildNode(),
4246
tagName: node.GetTagName(),

node-tree.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ func (node *Node) RemoveNode() {
229229

230230
node.previousNode = nil
231231
node.nextNode = nil
232+
node.parentNode = nil
232233

233234
node.rwMutex.Unlock()
234235

@@ -239,9 +240,13 @@ func (node *Node) RemoveNode() {
239240
nextNode.SetPreviousNode(previousNode)
240241
}
241242

242-
if nextNode != nil{
243+
if nextNode != nil && previousNode == nil{
243244
nextNode.setParentNode(parentNode)
244245
}
246+
247+
if parentNode != nil{
248+
parentNode.childNode = nextNode
249+
}
245250
}
246251

247252
// IsTextNode returns a boolean value indicating node is a text node or not.

node-tree_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,30 @@ func TestAppendTextAndInnerText(t *testing.T){
8686
t.Fatal(body.GetInnerText(), " != ", h1.GetChildNode().GetText() + p.GetChildNode().GetText())
8787
}
8888

89+
}
90+
91+
func TestRemoveNode(t *testing.T){
92+
article := GoHtml.CreateNode("article")
93+
94+
h1 := GoHtml.CreateNode("h1")
95+
h1.AppendText("This is a heading.")
96+
article.AppendChild(h1)
97+
98+
article.AppendChild(GoHtml.CreateNode(GoHtml.Br))
99+
100+
p := GoHtml.CreateNode("p")
101+
p.AppendText("this is a paragraph.")
102+
article.AppendChild(p)
103+
104+
h1.RemoveNode()
105+
106+
if article.GetChildNode().GetTagName() != GoHtml.Br{
107+
t.Fatal("Unexpected tag. ", article.GetChildNode().GetTagName())
108+
return
109+
}else if p.GetParent() != article {
110+
t.Fatal("Unexpected parent.")
111+
}
112+
113+
//p.RemoveNode()
114+
//t.Log(GoHtml.NodeTreeToHTML(article))
89115
}

0 commit comments

Comments
 (0)