element.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package element
  2. import (
  3. "git.nspix.com/golang/pgenr/internal/pool"
  4. "golang.org/x/net/html/atom"
  5. "html"
  6. )
  7. type (
  8. Option func(t *element)
  9. Element interface {
  10. Html() string
  11. }
  12. Attrs map[string]string
  13. element struct {
  14. Name atom.Atom
  15. Attr Attrs
  16. Content string
  17. }
  18. )
  19. func renderTag(tag string, attrs Attrs, content string) string {
  20. br := pool.Get()
  21. defer pool.Put(br)
  22. br.WriteString("<" + tag)
  23. if len(attrs) > 0 {
  24. for k, v := range attrs {
  25. if atom.Lookup([]byte(k)) == 0 {
  26. continue
  27. }
  28. br.WriteString(" " + k + "=\"" + v + "\" ")
  29. }
  30. }
  31. br.WriteString(">")
  32. br.WriteString(content)
  33. br.WriteString("</" + tag + ">")
  34. return br.String()
  35. }
  36. func beginTag(tag string, attrs Attrs) string {
  37. br := pool.Get()
  38. defer pool.Put(br)
  39. br.WriteString("<" + tag)
  40. if len(attrs) > 0 {
  41. for k, v := range attrs {
  42. if atom.Lookup([]byte(k)) == 0 {
  43. continue
  44. }
  45. br.WriteString(" " + k + "=\"" + v + "\" ")
  46. }
  47. }
  48. br.WriteString(">")
  49. return br.String()
  50. }
  51. func endTag(tag string) string {
  52. br := pool.Get()
  53. defer pool.Put(br)
  54. br.WriteString("</" + tag + ">")
  55. return br.String()
  56. }
  57. func WithAttribute(label string, value string) Option {
  58. return func(t *element) {
  59. if t.Attr == nil {
  60. t.Attr = make(map[string]string)
  61. }
  62. t.Attr[label] = value
  63. }
  64. }
  65. func (element *element) Html() string {
  66. return element.String()
  67. }
  68. func (element *element) String() string {
  69. return renderTag(element.Name.String(), element.Attr, html.EscapeString(element.Content))
  70. }
  71. func NewElement(atom atom.Atom, content string, opts ...Option) *element {
  72. e := &element{Name: atom, Content: content}
  73. for _, cb := range opts {
  74. cb(e)
  75. }
  76. return e
  77. }