node.go 5.3 KB

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