-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbase_element.go
120 lines (106 loc) · 2.59 KB
/
base_element.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
package compton
import (
"bytes"
"github.com/boggydigital/compton/consts/attr"
"golang.org/x/net/html/atom"
"io"
)
type BaseElement struct {
Attributes
ClassList
Children []Element
TagName atom.Atom
MarkupProvider
}
type MarkupProvider interface {
GetMarkup() ([]byte, error)
}
func (be *BaseElement) Append(children ...Element) {
be.Children = append(be.Children, children...)
}
func (be *BaseElement) HasChildren() bool {
return len(be.Children) > 0
}
func (be *BaseElement) Write(w io.Writer) error {
if be.MarkupProvider == nil {
return be.WriteFragment(ContentToken, w)
}
mup, err := be.MarkupProvider.GetMarkup()
if err != nil {
return err
}
return WriteContents(bytes.NewReader(mup), w, be.WriteFragment)
}
func (be *BaseElement) WriteFragment(t string, w io.Writer) error {
switch t {
case ContentToken:
for _, child := range be.Children {
if err := child.Write(w); err != nil {
return err
}
}
case AttributesToken:
// set class attribute
if be.Attributes.attributes == nil {
be.Attributes.attributes = make(map[string]string)
}
if len(be.ClassList.classList) > 0 {
be.Attributes.attributes[attr.Class] = be.ClassList.String()
}
if err := be.Attributes.Write(w); err != nil {
return err
}
default:
return ErrUnknownToken(t)
}
return nil
}
func (be *BaseElement) SetId(id string) {
be.SetAttribute(attr.Id, id)
}
func (be *BaseElement) GetTagName() atom.Atom {
return be.TagName
}
func (be *BaseElement) GetElementById(id string) Element {
for _, child := range be.Children {
if cid := child.GetAttribute(attr.Id); cid == id {
return child
}
if el := child.GetElementById(id); el != nil {
return el
}
}
return nil
}
func (be *BaseElement) GetElementsByTagName(tagName atom.Atom) []Element {
matches := make([]Element, 0)
for _, child := range be.Children {
if child.GetTagName() == tagName {
matches = append(matches, child)
}
matches = append(matches, child.GetElementsByTagName(tagName)...)
}
return matches
}
func (be *BaseElement) GetFirstElementByTagName(tagName atom.Atom) Element {
if matches := be.GetElementsByTagName(tagName); len(matches) > 0 {
return matches[0]
}
return nil
}
func (be *BaseElement) GetElementsByClassName(names ...string) []Element {
matches := make([]Element, 0)
for _, child := range be.Children {
if child.HasClass(names...) {
matches = append(matches, child)
}
matches = append(matches, child.GetElementsByClassName(names...)...)
}
return matches
}
func NewElement(a atom.Atom, mp MarkupProvider) *BaseElement {
return &BaseElement{
TagName: a,
MarkupProvider: mp,
}
}