Skip to content
This repository was archived by the owner on May 25, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 1 addition & 23 deletions FUTURE-CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
## v0.0.0-beta.3 <- current

## v0.0.0
Delete deletes the node without connecting sibling nodes.
* Delete

QuerySelector takes attribute name and regexp for the value and returns the first node that matches the regexp.
* QuerySelector

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

## v0.0.1
AddClass add the given class name to the node.
* AddClass

RemoveClass removes the specified class name from the node.
* RemoveClass

HasClass returns a boolean value specifying whether the node has the specified class name or not.
* HasClass

GetClassList returns a map of class names in the specified node.
* GetClassList

## v0.0.2
* GetElementById
* GetElementByClassName
* GetElementByTagName
* GetElementsById
* GetElementsByClassName
* GetElementsByTagName

## v0.0.3
DecodeHeader only serializes only up to head. And return a node with only head and it's child nodes.
* DecodeOnly
* DecodeOnlyByClassName
* DecodeHeader
* GetElementsByTagName
91 changes: 91 additions & 0 deletions classList.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package GoHtml

import (
"strings"
"sync"
)

type ClassList struct {
classes map[string]struct{}
rwMutex *sync.Mutex
}

// NewClassList returns a new empty ClassList.
func NewClassList() ClassList {
classList := ClassList{
classes: make(map[string]struct{}),
rwMutex: &sync.Mutex{},
}

return classList
}

// AppendClass append className to classList. className that contains multiple classes is also a valid className.
func (classList ClassList) AppendClass(className string) {
classList.rwMutex.Lock()
defer classList.rwMutex.Unlock()

classes := strings.SplitSeq(className, " ")
for v := range classes {
classList.classes[strings.TrimSpace(v)] = struct{}{}
}
}

// SetClass append classes in the node to classList.
func (classList ClassList) SetClass(node *Node) {
if node == nil {
return
}
classes, _ := node.GetAttribute("class")
classList.AppendClass(classes)
}

// Contains returns whether the className exists or not.
func (classList ClassList) Contains(className string) bool {
classList.rwMutex.Lock()
defer classList.rwMutex.Unlock()

classes := strings.SplitSeq(className, " ")
for v := range classes {
_, ok := classList.classes[strings.TrimSpace(v)]
if !ok {
return false
}
}

return true
}

// DeleteClass deletes the specified classes in className.
func (classList ClassList) DeleteClass(className string) {
classList.rwMutex.Lock()
defer classList.rwMutex.Unlock()

classes := strings.SplitSeq(className, " ")
for v := range classes {
delete(classList.classes, strings.TrimSpace(v))
}
}

// Encode returns the full className.
func (classList ClassList) Encode() string {
classList.rwMutex.Lock()
defer classList.rwMutex.Unlock()

classes := ""
for v := range classList.classes {
if classes != ""{
classes+=" "
}
classes+=v
}
return classes
}

// EncodeTo encode className for the node.
func (classList ClassList) EncodeTo(node *Node){
if node == nil {
return
}
node.SetAttribute("class", classList.Encode())
}
37 changes: 37 additions & 0 deletions classList_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package GoHtml_test

import(
"testing"
"github.com/udan-jayanith/GoHTML"
)

func TestClasses(t *testing.T){
node := GoHtml.CreateNode("div")
node.SetAttribute("class", "div-container main")

classList := GoHtml.NewClassList()
classList.SetClass(node)
if !classList.Contains("main"){
t.Fatal("")
return
}
classList.DeleteClass("main")
if classList.Contains("main"){
t.Fatal("")
return
}

classList.AppendClass("main-div")
if !classList.Contains("main-div"){
t.Fatal("")
return
}

classList.EncodeTo(node)

className, _ := node.GetAttribute("class")
if className != classList.Encode(){
t.Fatal("")
return
}
}
4 changes: 4 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ func DeepCloneNode(node *Node) *Node{
attributes := node.attributes
node.rwMutex.Unlock()

if node == nil {
return node
}

newNode := Node{
childNode: node.GetChildNode(),
tagName: node.GetTagName(),
Expand Down
7 changes: 6 additions & 1 deletion node-tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ func (node *Node) RemoveNode() {

node.previousNode = nil
node.nextNode = nil
node.parentNode = nil

node.rwMutex.Unlock()

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

if nextNode != nil{
if nextNode != nil && previousNode == nil{
nextNode.setParentNode(parentNode)
}

if parentNode != nil{
parentNode.childNode = nextNode
}
}

// IsTextNode returns a boolean value indicating node is a text node or not.
Expand Down
26 changes: 26 additions & 0 deletions node-tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,30 @@ func TestAppendTextAndInnerText(t *testing.T){
t.Fatal(body.GetInnerText(), " != ", h1.GetChildNode().GetText() + p.GetChildNode().GetText())
}

}

func TestRemoveNode(t *testing.T){
article := GoHtml.CreateNode("article")

h1 := GoHtml.CreateNode("h1")
h1.AppendText("This is a heading.")
article.AppendChild(h1)

article.AppendChild(GoHtml.CreateNode(GoHtml.Br))

p := GoHtml.CreateNode("p")
p.AppendText("this is a paragraph.")
article.AppendChild(p)

h1.RemoveNode()

if article.GetChildNode().GetTagName() != GoHtml.Br{
t.Fatal("Unexpected tag. ", article.GetChildNode().GetTagName())
return
}else if p.GetParent() != article {
t.Fatal("Unexpected parent.")
}

//p.RemoveNode()
//t.Log(GoHtml.NodeTreeToHTML(article))
}