-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdomnode.go
170 lines (132 loc) · 3.26 KB
/
domnode.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// The UXToolkit Project
// Copyright (c) Wirecog, LLC. All rights reserved.
// Use of this source code is governed by a BSD-style
// license, which can be found in the LICENSE file.
package reconcile
import (
"html"
"strconv"
"honnef.co/go/js/dom"
)
const (
ElementNodeType = iota
CommentNodeType
TextNodeType
)
type Positions struct {
startPosition int
innerStartPosition int
endPosition int
innerEndPosition int
}
type Attribute struct {
Name string
Value string
}
type DOMNode struct {
Positions
NodeType int
Position []int
ParentNode *DOMNode
ChildNodes []*DOMNode
Contents []byte
Name string
Value []byte
IsSelfClosing bool
Attributes []Attribute
tree *ParseTree
}
func NewDOMNode(nodeType int) *DOMNode {
result := &DOMNode{}
result.innerEndPosition = -1
if nodeType == ElementNodeType {
result.NodeType = ElementNodeType
} else if nodeType == CommentNodeType {
result.NodeType = CommentNodeType
} else if nodeType == TextNodeType {
result.NodeType = TextNodeType
}
return result
}
func (dn *DOMNode) Create() dom.Node {
var result dom.Node = nil
d := dom.GetWindow().Document()
if dn.NodeType == CommentNodeType {
element := d.Underlying().Call("createComment", string(dn.Value))
result = dom.WrapNode(element)
} else if dn.NodeType == TextNodeType {
result = d.CreateTextNode(string(dn.Value))
} else if dn.NodeType == ElementNodeType {
element := d.CreateElement(dn.Name)
for _, attribute := range dn.Attributes {
element.SetAttribute(attribute.Name, attribute.Value)
}
element.SetInnerHTML(string(dn.GetHTMLContents(true)))
result = element
}
return result
}
func (dn *DOMNode) Locate(rootElement dom.Element) dom.Node {
result := rootElement.ChildNodes()[dn.Position[0]]
for _, index := range dn.Position[1:] {
result = result.ChildNodes()[index]
}
return result
}
func (dn *DOMNode) IsEqual(b DOMNode) bool {
if dn.NodeType != b.NodeType {
return false
}
if dn.NodeType == TextNodeType || dn.NodeType == CommentNodeType {
if string(dn.Value) != string(b.Value) {
return false
} else {
return true
}
}
if dn.NodeType == ElementNodeType {
if dn.Name != b.Name {
return false
}
attrs := dn.Attributes
otherAttrs := b.Attributes
if len(attrs) != len(otherAttrs) {
return false
}
for i, attr := range attrs {
otherAttr := otherAttrs[i]
if attr != otherAttr {
return false
}
}
return true
}
return false
}
func (dn *DOMNode) GetHTMLContents(innerContentsOnly bool) []byte {
if dn.IsSelfClosing == true {
return nil
} else {
contents := string(dn.tree.src[dn.innerStartPosition:dn.innerEndPosition])
return []byte(html.UnescapeString(contents))
}
}
func (dn *DOMNode) AttributesMap() map[string]string {
var result map[string]string
if dn.NodeType == ElementNodeType {
result = make(map[string]string)
for _, attribute := range dn.Attributes {
result[attribute.Name] = attribute.Value
}
} else {
result = nil
}
return result
}
func (dn *DOMNode) String() string {
s := "### DOMNODE ###\n"
s += "name: " + dn.Name + "\n"
s += "innerStartPosition: " + strconv.Itoa(dn.innerStartPosition) + "\n"
s += "innerEndPosition: " + strconv.Itoa(dn.innerEndPosition) + "\n"
return s
}