...
1
2
3
4
5 package html
6
7 import (
8 "golang.org/x/net/html/atom"
9 )
10
11
12 type NodeType uint32
13
14 const (
15 ErrorNode NodeType = iota
16 TextNode
17 DocumentNode
18 ElementNode
19 CommentNode
20 DoctypeNode
21
22
23
24
25 RawNode
26 scopeMarkerNode
27 )
28
29
30
31
32
33 var scopeMarker = Node{Type: scopeMarkerNode}
34
35
36
37
38
39
40
41
42
43
44 type Node struct {
45 Parent, FirstChild, LastChild, PrevSibling, NextSibling *Node
46
47 Type NodeType
48 DataAtom atom.Atom
49 Data string
50 Namespace string
51 Attr []Attribute
52 }
53
54
55
56
57
58
59 func (n *Node) InsertBefore(newChild, oldChild *Node) {
60 if newChild.Parent != nil || newChild.PrevSibling != nil || newChild.NextSibling != nil {
61 panic("html: InsertBefore called for an attached child Node")
62 }
63 var prev, next *Node
64 if oldChild != nil {
65 prev, next = oldChild.PrevSibling, oldChild
66 } else {
67 prev = n.LastChild
68 }
69 if prev != nil {
70 prev.NextSibling = newChild
71 } else {
72 n.FirstChild = newChild
73 }
74 if next != nil {
75 next.PrevSibling = newChild
76 } else {
77 n.LastChild = newChild
78 }
79 newChild.Parent = n
80 newChild.PrevSibling = prev
81 newChild.NextSibling = next
82 }
83
84
85
86
87 func (n *Node) AppendChild(c *Node) {
88 if c.Parent != nil || c.PrevSibling != nil || c.NextSibling != nil {
89 panic("html: AppendChild called for an attached child Node")
90 }
91 last := n.LastChild
92 if last != nil {
93 last.NextSibling = c
94 } else {
95 n.FirstChild = c
96 }
97 n.LastChild = c
98 c.Parent = n
99 c.PrevSibling = last
100 }
101
102
103
104
105
106 func (n *Node) RemoveChild(c *Node) {
107 if c.Parent != n {
108 panic("html: RemoveChild called for a non-child Node")
109 }
110 if n.FirstChild == c {
111 n.FirstChild = c.NextSibling
112 }
113 if c.NextSibling != nil {
114 c.NextSibling.PrevSibling = c.PrevSibling
115 }
116 if n.LastChild == c {
117 n.LastChild = c.PrevSibling
118 }
119 if c.PrevSibling != nil {
120 c.PrevSibling.NextSibling = c.NextSibling
121 }
122 c.Parent = nil
123 c.PrevSibling = nil
124 c.NextSibling = nil
125 }
126
127
128 func reparentChildren(dst, src *Node) {
129 for {
130 child := src.FirstChild
131 if child == nil {
132 break
133 }
134 src.RemoveChild(child)
135 dst.AppendChild(child)
136 }
137 }
138
139
140
141 func (n *Node) clone() *Node {
142 m := &Node{
143 Type: n.Type,
144 DataAtom: n.DataAtom,
145 Data: n.Data,
146 Attr: make([]Attribute, len(n.Attr)),
147 }
148 copy(m.Attr, n.Attr)
149 return m
150 }
151
152
153 type nodeStack []*Node
154
155
156 func (s *nodeStack) pop() *Node {
157 i := len(*s)
158 n := (*s)[i-1]
159 *s = (*s)[:i-1]
160 return n
161 }
162
163
164 func (s *nodeStack) top() *Node {
165 if i := len(*s); i > 0 {
166 return (*s)[i-1]
167 }
168 return nil
169 }
170
171
172
173 func (s *nodeStack) index(n *Node) int {
174 for i := len(*s) - 1; i >= 0; i-- {
175 if (*s)[i] == n {
176 return i
177 }
178 }
179 return -1
180 }
181
182
183 func (s *nodeStack) contains(a atom.Atom) bool {
184 for _, n := range *s {
185 if n.DataAtom == a && n.Namespace == "" {
186 return true
187 }
188 }
189 return false
190 }
191
192
193 func (s *nodeStack) insert(i int, n *Node) {
194 (*s) = append(*s, nil)
195 copy((*s)[i+1:], (*s)[i:])
196 (*s)[i] = n
197 }
198
199
200 func (s *nodeStack) remove(n *Node) {
201 i := s.index(n)
202 if i == -1 {
203 return
204 }
205 copy((*s)[i:], (*s)[i+1:])
206 j := len(*s) - 1
207 (*s)[j] = nil
208 *s = (*s)[:j]
209 }
210
211 type insertionModeStack []insertionMode
212
213 func (s *insertionModeStack) pop() (im insertionMode) {
214 i := len(*s)
215 im = (*s)[i-1]
216 *s = (*s)[:i-1]
217 return im
218 }
219
220 func (s *insertionModeStack) top() insertionMode {
221 if i := len(*s); i > 0 {
222 return (*s)[i-1]
223 }
224 return nil
225 }
226
View as plain text