node.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. package domquery
  2. import (
  3. "strings"
  4. )
  5. type Node struct {
  6. token string
  7. Children []*Node
  8. Parent *Node
  9. }
  10. func (node *Node) TagName() string {
  11. return getTagName(node.token)
  12. }
  13. func (node *Node) OuterHTML() string {
  14. str := node.token
  15. str += node.InnerHTML()
  16. str += getCloseNode(node).token
  17. return str
  18. }
  19. func (node *Node) SetOuterHTML(str string) {
  20. closeTag := getCloseNode(node)
  21. closeTag.token = ""
  22. //use the token to insert str
  23. node.token = str
  24. node.Children = []*Node{}
  25. // regen parent
  26. tokList := getTokenList(node.Parent.InnerHTML())
  27. tree := buildTree(tokList)
  28. node.Parent.Children = tree.Children
  29. }
  30. func (node *Node) InnerHTML() string {
  31. str := ""
  32. for _, child := range node.Children {
  33. str += child.token
  34. str += child.InnerHTML()
  35. //fmt.Println(child.token)
  36. }
  37. return str
  38. }
  39. func (node *Node) SetInnerHTML(str string) {
  40. tokList := getTokenList(str)
  41. document := buildTree(tokList)
  42. node.Children = document.Children
  43. }
  44. func (node *Node) QuerySelector(str string) *Node {
  45. found := &Node{}
  46. for _, child := range node.Children {
  47. if matchSelector(child, str) {
  48. return child
  49. }
  50. found := child.QuerySelector(str)
  51. if found.token != "" {
  52. return found
  53. }
  54. }
  55. return found
  56. }
  57. func (node *Node) QuerySelectorAll(str string) []*Node {
  58. found := []*Node{}
  59. for _, child := range node.Children {
  60. if getTagName(child.token) == str && (getTokType(child.token) == "open" || getTokType(child.token) == "selfclosing") {
  61. found = append(found, child)
  62. }
  63. if str == "*" && (getTokType(child.token) == "open" || getTokType(child.token) == "selfclosing") {
  64. found = append(found, child)
  65. }
  66. found = append(found, child.QuerySelectorAll(str)...)
  67. }
  68. return found
  69. }
  70. func (node *Node) GetAttribute(str string) string {
  71. for key, val := range node.AttributeList() {
  72. if key == str {
  73. return val
  74. }
  75. }
  76. return ""
  77. }
  78. func (node *Node) HasAttribute(str string) bool {
  79. for key := range node.AttributeList() {
  80. if key == str {
  81. return true
  82. }
  83. }
  84. return false
  85. }
  86. func (node *Node) SetAttribute(attr string, val string) {
  87. attributes := node.AttributeList()
  88. attributes[attr] = val
  89. attrStr := ""
  90. for key, val := range attributes {
  91. attrStr += key
  92. if val != "" {
  93. attrStr += "=" + "\"" + val + "\""
  94. }
  95. attrStr += " "
  96. }
  97. attrStr = strings.Trim(attrStr, " ")
  98. node.token = "<" + getTagName(node.token) + " " + attrStr + ">"
  99. }
  100. func (node *Node) RemoveAttribute(attr string) {
  101. attributes := node.AttributeList()
  102. attrStr := ""
  103. for key, val := range attributes {
  104. if key == attr {
  105. continue
  106. }
  107. attrStr += key
  108. if val != "" {
  109. attrStr += "=" + "\"" + val + "\""
  110. }
  111. attrStr += " "
  112. }
  113. attrStr = strings.Trim(attrStr, " ")
  114. node.token = "<" + getTagName(node.token) + " " + attrStr + ">"
  115. }
  116. func (node *Node) AttributeList() map[string]string {
  117. attributesList := make(map[string]string)
  118. if getTokType(node.token) != "open" && getTokType(node.token) != "selfclosing" {
  119. return attributesList
  120. }
  121. attrStr := strings.Replace(node.token, "<"+getTagName(node.token), "", 1)
  122. attrStr = strings.Trim(attrStr, "<> ")
  123. tok := ""
  124. state := "key"
  125. strKey := ""
  126. for i := 0; i < len(attrStr); i++ {
  127. chr := string(attrStr[i])
  128. if state == "key" {
  129. if i == len(attrStr)-1 {
  130. tok += chr
  131. strKey = strings.Trim(tok, " ")
  132. attributesList[strKey] = ""
  133. continue
  134. }
  135. if chr == "=" {
  136. strKey = strings.Trim(tok, " ")
  137. state = "qual"
  138. tok = ""
  139. continue
  140. }
  141. if chr == " " {
  142. strKey = strings.Trim(tok, " ")
  143. if strKey != "" {
  144. attributesList[strKey] = ""
  145. }
  146. strKey = ""
  147. tok = ""
  148. continue
  149. }
  150. }
  151. if state == "qual" {
  152. if chr == "\"" {
  153. state = "val"
  154. tok = ""
  155. continue
  156. }
  157. }
  158. if state == "val" {
  159. if chr == "\"" {
  160. attributesList[strKey] = strings.Trim(tok, " ")
  161. state = "key"
  162. tok = ""
  163. continue
  164. }
  165. }
  166. tok += chr
  167. }
  168. return attributesList
  169. }
  170. func (node *Node) ClassList() []string {
  171. classStr := node.GetAttribute("class")
  172. classList := strings.Split(classStr, " ")
  173. return classList
  174. }
  175. func (node *Node) ClassListAdd(classStr string) {
  176. classList := append(node.ClassList(), classStr)
  177. str := strings.Join(classList, " ")
  178. str = strings.Trim(str, " ")
  179. node.SetAttribute("class", str)
  180. }
  181. func (node *Node) ClassListRemove(classStr string) {
  182. classList := []string{}
  183. for _, class := range node.ClassList() {
  184. if class != classStr {
  185. classList = append(classList, class)
  186. }
  187. }
  188. str := strings.Join(classList, " ")
  189. str = strings.Trim(str, " ")
  190. node.SetAttribute("class", str)
  191. }
  192. func (node *Node) Remove() {
  193. closeNode := getCloseNode(node)
  194. i := 0
  195. for _, n := range node.Parent.Children {
  196. if n == closeNode {
  197. node.Parent.Children = append(node.Parent.Children[:i], node.Parent.Children[i+1:]...)
  198. break
  199. }
  200. i++
  201. }
  202. i = 0
  203. for _, n := range node.Parent.Children {
  204. if n == node {
  205. node.Parent.Children = append(node.Parent.Children[:i], node.Parent.Children[i+1:]...)
  206. break
  207. }
  208. i++
  209. }
  210. }
  211. func (node *Node) CreateElement(tagName string) *Node {
  212. newNode := &Node{}
  213. newNode.token = "<" + tagName + ">"
  214. return newNode
  215. }
  216. func (node *Node) Append(newNode *Node) {
  217. newNode.Parent = node
  218. node.Children = append(node.Children, newNode)
  219. if getTokType(newNode.token) != "selfclosing" {
  220. closeNode := &Node{}
  221. closeNode.token = "</" + getTagName(newNode.token) + ">"
  222. node.Children = append(node.Children, closeNode)
  223. }
  224. }