/
htmlutil.go
68 lines (59 loc) · 1.21 KB
/
htmlutil.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
package main
import "exp/html"
type Matcher func(n *html.Node) bool
func All() Matcher {
return func(*html.Node) bool { return true }
}
func Tag(name string) Matcher {
return func(n *html.Node) bool {
return n.Type == html.ElementNode && n.Data == name
}
}
func (m Matcher) Walk(n *html.Node, fn func(n *html.Node)) {
for _, c := range n.Child {
m.Walk(c, fn)
}
if m(n) {
fn(n)
}
}
func (m Matcher) Find(n *html.Node) (nodes []*html.Node) {
for _, c := range n.Child {
nodes = append(nodes, m.Find(c)...)
}
if m(n) {
nodes = append(nodes, n)
}
return nodes
}
func InsertBefore(n *html.Node, nodes ...*html.Node) {
i := childIndex(n)
p := n.Parent
c := make([]*html.Node, len(p.Child)+len(nodes))
copy(c, p.Child[:i])
copy(c[i:], nodes)
copy(c[i+len(nodes):], p.Child[i:])
for _, n := range nodes {
n.Parent.Remove(n)
n.Parent = p
}
p.Child = c
}
func childIndex(n *html.Node) int {
p := n.Parent
for i := range p.Child {
if p.Child[i] == n {
return i
}
}
panic("Node's Parent doesn't list it as a Child")
}
func RemoveAttr(n *html.Node, key string) {
for i, a := range n.Attr {
if a.Key == key {
copy(n.Attr[i:], n.Attr[i+1:])
n.Attr = n.Attr[:len(n.Attr)-1]
return
}
}
}