diff options
| -rw-r--r-- | dom/css_class.go | 43 | ||||
| -rw-r--r-- | dom/html.go | 26 |
2 files changed, 63 insertions, 6 deletions
diff --git a/dom/css_class.go b/dom/css_class.go new file mode 100644 index 0000000..633869e --- /dev/null +++ b/dom/css_class.go @@ -0,0 +1,43 @@ +package dom + +type ClassList map[string]struct{} + +func (cl ClassList) set(e Element) Element { + if len(cl) == 0 { + return e + } + classes := "" + for k := range cl { + classes += k + " " + } + classes = classes[:len(cl)-1] + return e.SetAttribute("class", classes) +} + +func (cl ClassList) Has(v string) bool { + _, ok := cl[v] + return ok +} + +func (cl ClassList) Add(v string) ClassList { + cl[v] = struct{}{} + return cl +} + +func (cl ClassList) Remove(v string) ClassList { + delete(cl, v) + return cl +} + +func (cl ClassList) Toggle(v string) ClassList { + if cl.Has(v) { + cl.Remove(v) + } else { + cl.Add(v) + } + return cl +} + +func NewClassList() ClassList { + return ClassList(make(map[string]struct{})) +} diff --git a/dom/html.go b/dom/html.go index f43526c..360a33b 100644 --- a/dom/html.go +++ b/dom/html.go @@ -22,6 +22,7 @@ type Element interface { HasAttribute(string) bool SetAttribute(string, string) Element RemoveAttribute(string) Element + ClassList() ClassList } type LiteralElement struct { @@ -44,6 +45,10 @@ func (e LiteralElement) RemoveAttribute(string) Element { return e } +func (e LiteralElement) ClassList() ClassList { + return nil +} + func NewLiteralElement(s string) LiteralElement { return LiteralElement{s} } @@ -51,9 +56,11 @@ func NewLiteralElement(s string) LiteralElement { type VoidElement struct { Tag string attributes map[string]string + cl ClassList } func (e VoidElement) Render() template.HTML { + e = e.cl.set(e).(VoidElement) return render(e.Tag, e.attributes, true) } @@ -72,8 +79,12 @@ func (e VoidElement) RemoveAttribute(k string) Element { return e } +func (e VoidElement) ClassList() ClassList { + return e.cl +} + func NewVoidElement(tag string) VoidElement { - return VoidElement{tag, make(map[string]string)} + return VoidElement{tag, make(map[string]string), NewClassList()} } func NewImg(src, alt string) Element { @@ -82,19 +93,22 @@ func NewImg(src, alt string) Element { type ContentElement struct { VoidElement - Content Element + Contents []Element } func (e ContentElement) Render() template.HTML { + e = e.cl.set(e).(ContentElement) base := render(e.Tag, e.attributes, false) - base += e.Content.Render() + for _, el := range e.Contents { + base += el.Render() + } return base + template.HTML(fmt.Sprintf(`</%s>`, e.VoidElement.Tag)) } -func NewContentElement(tag string, content Element) ContentElement { - return ContentElement{NewVoidElement(tag), content} +func NewContentElement(tag string, contents []Element) ContentElement { + return ContentElement{NewVoidElement(tag), contents} } func NewParagraph(content string) Element { - return NewContentElement("p", NewLiteralElement(content)) + return NewContentElement("p", []Element{NewLiteralElement(content)}) } |
