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

Commit 474da7e

Browse files
Merge pull request #7 from udan-jayanith/patches-and-tests
Patches and tests
2 parents 1bf9fa5 + a07c3e4 commit 474da7e

5 files changed

Lines changed: 73 additions & 69 deletions

File tree

FUTURE-CHANGELOG.md

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

33
## v0.0.0
4-
Delete deletes the branch without connecting sibling nodes.
4+
Delete deletes the node without connecting sibling nodes.
55
* Delete
66

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

main.go

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func DeepCloneNode(node *Node) *Node{
4949
return &newNode
5050
}
5151

52-
//CloneNode copy the node.
52+
//CloneNode copy the node. But have one way connections to it's parent, next and previous nodes.
5353
func CloneNode(node *Node) *Node{
5454
newNode := DeepCloneNode(node)
5555
newNode.setParentNode(node.getParentNode())
@@ -59,21 +59,6 @@ func CloneNode(node *Node) *Node{
5959
return newNode
6060
}
6161

62-
//ApplySaveChanges replaces the nodes previous and parent node with the given node.
63-
func ApplySaveChanges(node *Node){
64-
previousNode := node.GetPreviousNode()
65-
if previousNode != nil{
66-
previousNode.SetNextNode(node)
67-
}
68-
69-
parentNode := node.getParentNode()
70-
if parentNode != nil{
71-
parentNode.rwMutex.Lock()
72-
parentNode.childNode = node
73-
parentNode.rwMutex.Unlock()
74-
}
75-
}
76-
7762
func isQuote(chr string) bool {
7863
return chr == `"` || chr == `'` || chr == "`"
7964
}

node-tree.go

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"sync"
66
)
77

8-
//The DOM Node struct is an abstract base class upon which many other DOM API objects are based, thus letting
8+
// The DOM Node struct is an abstract base class upon which many other DOM API objects are based, thus letting
99
// those object types to be used similarly and often interchangeably.
1010
type Node struct {
1111
nextNode *Node
@@ -16,136 +16,137 @@ type Node struct {
1616
tagName string
1717
attributes map[string]string
1818
text string
19-
rwMutex sync.Mutex
19+
rwMutex sync.Mutex
2020
}
2121

22-
//GetNextNode returns node next to the node.
23-
func (node *Node) GetNextNode() *Node{
22+
// GetNextNode returns node next to the node.
23+
func (node *Node) GetNextNode() *Node {
2424
node.rwMutex.Lock()
2525
defer node.rwMutex.Unlock()
2626

2727
return node.nextNode
2828
}
2929

30-
//SetNextNode make nodes next node as nextNode.
31-
func (node *Node) SetNextNode(nextNode *Node){
30+
// SetNextNode make nodes next node as nextNode.
31+
func (node *Node) SetNextNode(nextNode *Node) {
3232
node.rwMutex.Lock()
3333
defer node.rwMutex.Unlock()
3434

3535
node.nextNode = nextNode
3636
}
3737

38-
//GetPreviousNode returns the previous node.
39-
func (node *Node) GetPreviousNode() *Node{
38+
// GetPreviousNode returns the previous node.
39+
func (node *Node) GetPreviousNode() *Node {
4040
node.rwMutex.Lock()
4141
defer node.rwMutex.Unlock()
4242

4343
return node.previousNode
4444
}
4545

46-
//SetPreviousNode sets nodes previous node to previousNode.
47-
func (node *Node) SetPreviousNode(previousNode *Node){
46+
// SetPreviousNode sets nodes previous node to previousNode.
47+
func (node *Node) SetPreviousNode(previousNode *Node) {
4848
node.rwMutex.Lock()
4949
defer node.rwMutex.Unlock()
5050

5151
node.previousNode = previousNode
5252
}
5353

54-
//GetChildNode returns the first child elements of this node.
55-
func (node *Node) GetChildNode() *Node{
54+
// GetChildNode returns the first child elements of this node.
55+
func (node *Node) GetChildNode() *Node {
5656
node.rwMutex.Lock()
5757
defer node.rwMutex.Unlock()
5858

5959
return node.childNode
6060
}
6161

62-
//getParentNode returns parent node.
63-
func (node *Node) getParentNode() *Node{
62+
// getParentNode returns parent node.
63+
func (node *Node) getParentNode() *Node {
6464
node.rwMutex.Lock()
6565
defer node.rwMutex.Unlock()
6666

6767
return node.parentNode
6868
}
6969

70-
func (node *Node) setParentNode(parentNode *Node){
70+
func (node *Node) setParentNode(parentNode *Node) {
7171
node.rwMutex.Lock()
7272
defer node.rwMutex.Unlock()
7373

7474
node.parentNode = parentNode
7575
}
7676

77-
//Returns a string with the name of the tag for the given node.
78-
func (node *Node) GetTagName() string{
77+
// Returns a string with the name of the tag for the given node.
78+
func (node *Node) GetTagName() string {
7979
node.rwMutex.Lock()
8080
defer node.rwMutex.Unlock()
8181

82-
if strings.ToUpper(node.tagName) == DOCTYPEDTD{
82+
if strings.ToUpper(node.tagName) == DOCTYPEDTD {
8383
return strings.ToUpper(node.tagName)
8484
}
8585

8686
return node.tagName
8787
}
8888

89-
//SetTagName changes the html tag name to the tagName.
90-
func (node *Node) SetTagName(tagName string){
89+
// SetTagName changes the html tag name to the tagName.
90+
func (node *Node) SetTagName(tagName string) {
9191
node.rwMutex.Lock()
9292
defer node.rwMutex.Unlock()
9393

9494
node.tagName = strings.TrimSpace(strings.ToLower(tagName))
9595
}
9696

97-
//GetAttribute returns the specified attribute value form the node.
98-
func (node *Node) GetAttribute(attributeName string) (string, bool){
97+
// GetAttribute returns the specified attribute value form the node. If the specified attribute doesn't exists GetAttribute returns a empty string and false.
98+
func (node *Node) GetAttribute(attributeName string) (string, bool) {
9999
node.rwMutex.Lock()
100100
defer node.rwMutex.Unlock()
101101

102102
v, ok := node.attributes[attributeName]
103103
return v, ok
104104
}
105105

106-
//RemoveAttribute remove or delete the specified attribute.
107-
func (node *Node) RemoveAttribute(attributeName string){
106+
// RemoveAttribute remove or delete the specified attribute.
107+
func (node *Node) RemoveAttribute(attributeName string) {
108108
node.rwMutex.Lock()
109109
defer node.rwMutex.Unlock()
110110

111111
delete(node.attributes, attributeName)
112112
}
113113

114-
//IterateAttributes calls callback at every attribute in the node by passing attribute and value of the each node to the callback.
115-
func (node *Node) IterateAttributes(callback func(attribute, value string)){
114+
// IterateAttributes calls callback at every attribute in the node by passing attribute and value of the node.
115+
func (node *Node) IterateAttributes(callback func(attribute, value string)) {
116116
node.rwMutex.Lock()
117-
defer node.rwMutex.Unlock()
117+
attributes := node.attributes
118+
node.rwMutex.Unlock()
118119

119-
for k, v := range node.attributes{
120+
for k, v := range attributes {
120121
callback(k, v)
121122
}
122123
}
123124

124-
//SetAttribute add a attribute to the node.
125-
func (node *Node) SetAttribute(attribute, value string){
125+
// SetAttribute add a attribute to the node.
126+
func (node *Node) SetAttribute(attribute, value string) {
126127
node.rwMutex.Lock()
127128
defer node.rwMutex.Unlock()
128129

129130
node.attributes[strings.TrimSpace(attribute)] = strings.TrimSpace(value)
130131
}
131132

132-
//GetText returns text on the node. This does not returns text on it's child nodes. If you also wants child nodes text use GetInnerText method on the node.
133-
func (node *Node) GetText() string{
133+
// GetText returns text on the node. This does not returns text on it's child nodes. If you also wants child nodes text use GetInnerText method on the node.
134+
func (node *Node) GetText() string {
134135
node.rwMutex.Lock()
135136
defer node.rwMutex.Unlock()
136137

137138
return node.text
138139
}
139140

140-
//SetText add text to the node.
141-
func (node *Node) SetText(text string){
141+
// SetText add text to the node.
142+
func (node *Node) SetText(text string) {
142143
node.rwMutex.Lock()
143144
defer node.rwMutex.Unlock()
144145

145146
node.text = text
146147
}
147148

148-
//The AppendChild() method of the Node adds a node to the end of the list of children of a specified parent node.
149+
// The AppendChild() method of the Node adds a node to the end of the list of children of a specified parent node.
149150
func (node *Node) AppendChild(childNode *Node) {
150151
if node.GetChildNode() == nil {
151152
node.rwMutex.Lock()
@@ -161,50 +162,50 @@ func (node *Node) AppendChild(childNode *Node) {
161162
lastNode.SetNextNode(childNode)
162163
}
163164

164-
//Append inserts the newNode to end of the node chain.
165+
// Append inserts the newNode to end of the node chain.
165166
func (node *Node) Append(newNode *Node) {
166167
lastNode := node.GetLastNode()
167168
newNode.SetPreviousNode(lastNode)
168169
lastNode.SetNextNode(newNode)
169170
}
170171

171-
//GetParent returns a pointer to the parent node.
172+
// GetParent returns a pointer to the parent node.
172173
func (node *Node) GetParent() *Node {
173174
return node.GetFirstNode().getParentNode()
174175
}
175176

176-
//GetLastNode returns the last node in the node branch.
177-
func (node *Node) GetLastNode() *Node{
177+
// GetLastNode returns the last node in the node branch.
178+
func (node *Node) GetLastNode() *Node {
178179
traverser := GetTraverser(node)
179180
for traverser.GetCurrentNode().GetNextNode() != nil {
180181
traverser.Next()
181182
}
182183
return traverser.GetCurrentNode()
183184
}
184185

185-
//GetFirstNode returns the first node of the node branch.
186-
func (node *Node) GetFirstNode() *Node{
186+
// GetFirstNode returns the first node of the node branch.
187+
func (node *Node) GetFirstNode() *Node {
187188
traverser := GetTraverser(node)
188-
for traverser.GetCurrentNode().GetPreviousNode() != nil{
189+
for traverser.GetCurrentNode().GetPreviousNode() != nil {
189190
traverser.Previous()
190191
}
191192
return traverser.GetCurrentNode()
192193
}
193194

194-
//AppendText add text to the node.
195-
func (node *Node) AppendText(text string){
195+
// AppendText append text to the node.
196+
func (node *Node) AppendText(text string) {
196197
textNode := CreateNode("")
197198
textNode.SetText(text)
198199

199-
if node.GetTagName() == "" || IsVoidTag(node.GetTagName()){
200+
if node.GetTagName() == "" || IsVoidTag(node.GetTagName()) {
200201
node.GetLastNode().Append(textNode)
201202
return
202203
}
203204
node.GetLastNode().AppendChild(textNode)
204205
}
205206

206-
//GetInnerText returns all of the text inside the node.
207-
func (node *Node) GetInnerText() string{
207+
// GetInnerText returns all of the text inside the node.
208+
func (node *Node) GetInnerText() string {
208209
text := ""
209210
traverser := GetTraverser(node.childNode)
210211
traverser.Walkthrough(func(node *Node) TraverseCondition {
@@ -218,25 +219,32 @@ func (node *Node) GetInnerText() string{
218219
return text
219220
}
220221

221-
//RemoveNode removes the node from the branch safely.
222-
func (node *Node) RemoveNode(){
222+
// RemoveNode removes the node from the branch safely by connecting sibling nodes.
223+
func (node *Node) RemoveNode() {
223224
node.rwMutex.Lock()
224-
defer node.rwMutex.Unlock()
225225

226226
previousNode := node.previousNode
227227
nextNode := node.nextNode
228+
parentNode := node.parentNode
228229

229230
node.previousNode = nil
230231
node.nextNode = nil
231232

233+
node.rwMutex.Unlock()
234+
232235
if previousNode != nil {
233236
previousNode.SetNextNode(nextNode)
234237
}
235238
if nextNode != nil {
236239
nextNode.SetPreviousNode(previousNode)
237240
}
241+
242+
if nextNode != nil{
243+
nextNode.setParentNode(parentNode)
244+
}
238245
}
239246

247+
// IsTextNode returns a boolean value indicating node is a text node or not.
240248
func (node *Node) IsTextNode() bool {
241249
return node.GetTagName() == ""
242250
}

test-files/3.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Simple Page</title>
6+
</head>
7+
<body>
8+
<h1>Hello, World!</h1>
9+
<p>This is a simple HTML page.</p>
10+
</body>
11+
</html>

traverser.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ const (
5454
ContinueWalkthrough TraverseCondition = false
5555
)
5656

57-
//TODO: use a linked stack
58-
//Walkthrough traverse the node tree from the current node to the end of the node tree by visiting every node. If callback returned StopWalkthrough walkthrough function will stop else if it returned ContinueWalkthrough it continues walkthrough until every node is visited.
57+
//Walkthrough traverse the node tree from the current node to the end of the node tree by visiting every node. If callback returned StopWalkthrough walkthrough function will stop else if it returned ContinueWalkthrough it advanced to the next node.
58+
//Walkthrough calls callback at every node and pass that node. Walkthrough traverse the node tree similar to DFS without visiting visited nodes iteratively.
5959
func (t *Traverser) Walkthrough(callback func(node *Node) TraverseCondition) {
6060
stack := linkedliststack.New()
6161
stack.Push(t.GetCurrentNode())

0 commit comments

Comments
 (0)