123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- package domquery
- import (
- "strings"
- )
- type Node struct {
- token string
- Children []*Node
- Parent *Node
- }
- func (node *Node) TagName() string {
- return getTagName(node.token)
- }
- func (node *Node) OuterHTML() string {
- str := node.token
- str += node.InnerHTML()
- str += getCloseNode(node).token
- return str
- }
- func (node *Node) SetOuterHTML(str string) {
- closeTag := getCloseNode(node)
- closeTag.token = ""
- //use the token to insert str
- node.token = str
- node.Children = []*Node{}
- // regen parent
- tokList := getTokenList(node.Parent.InnerHTML())
- tree := buildTree(tokList)
- node.Parent.Children = tree.Children
- }
- func (node *Node) InnerHTML() string {
- str := ""
- for _, child := range node.Children {
- str += child.token
- str += child.InnerHTML()
- //fmt.Println(child.token)
- }
- return str
- }
- func (node *Node) SetInnerHTML(str string) {
- tokList := getTokenList(str)
- document := buildTree(tokList)
- node.Children = document.Children
- }
- func (node *Node) QuerySelector(str string) *Node {
- found := &Node{}
- for _, child := range node.Children {
- if matchSelector(child, str) {
- return child
- }
- found := child.QuerySelector(str)
- if found.token != "" {
- return found
- }
- }
- return found
- }
- func (node *Node) QuerySelectorAll(str string) []*Node {
- found := []*Node{}
- for _, child := range node.Children {
- if getTagName(child.token) == str && (getTokType(child.token) == "open" || getTokType(child.token) == "selfclosing") {
- found = append(found, child)
- }
- if str == "*" && (getTokType(child.token) == "open" || getTokType(child.token) == "selfclosing") {
- found = append(found, child)
- }
- found = append(found, child.QuerySelectorAll(str)...)
- }
- return found
- }
- func (node *Node) GetAttribute(str string) string {
- for key, val := range node.AttributeList() {
- if key == str {
- return val
- }
- }
- return ""
- }
- func (node *Node) HasAttribute(str string) bool {
- for key := range node.AttributeList() {
- if key == str {
- return true
- }
- }
- return false
- }
- func (node *Node) SetAttribute(attr string, val string) {
- attributes := node.AttributeList()
- attributes[attr] = val
- attrStr := ""
- for key, val := range attributes {
- attrStr += key
- if val != "" {
- attrStr += "=" + "\"" + val + "\""
- }
- attrStr += " "
- }
- attrStr = strings.Trim(attrStr, " ")
- node.token = "<" + getTagName(node.token) + " " + attrStr + ">"
- }
- func (node *Node) RemoveAttribute(attr string) {
- attributes := node.AttributeList()
- attrStr := ""
- for key, val := range attributes {
- if key == attr {
- continue
- }
- attrStr += key
- if val != "" {
- attrStr += "=" + "\"" + val + "\""
- }
- attrStr += " "
- }
- attrStr = strings.Trim(attrStr, " ")
- node.token = "<" + getTagName(node.token) + " " + attrStr + ">"
- }
- func (node *Node) AttributeList() map[string]string {
- attributesList := make(map[string]string)
- if getTokType(node.token) != "open" && getTokType(node.token) != "selfclosing" {
- return attributesList
- }
- attrStr := strings.Replace(node.token, "<"+getTagName(node.token), "", 1)
- attrStr = strings.Trim(attrStr, "<> ")
- tok := ""
- state := "key"
- strKey := ""
- for i := 0; i < len(attrStr); i++ {
- chr := string(attrStr[i])
- if state == "key" {
- if i == len(attrStr)-1 {
- tok += chr
- strKey = strings.Trim(tok, " ")
- attributesList[strKey] = ""
- continue
- }
- if chr == "=" {
- strKey = strings.Trim(tok, " ")
- state = "qual"
- tok = ""
- continue
- }
- if chr == " " {
- strKey = strings.Trim(tok, " ")
- if strKey != "" {
- attributesList[strKey] = ""
- }
- strKey = ""
- tok = ""
- continue
- }
- }
- if state == "qual" {
- if chr == "\"" {
- state = "val"
- tok = ""
- continue
- }
- }
- if state == "val" {
- if chr == "\"" {
- attributesList[strKey] = strings.Trim(tok, " ")
- state = "key"
- tok = ""
- continue
- }
- }
- tok += chr
- }
- return attributesList
- }
- func (node *Node) ClassList() []string {
- classStr := node.GetAttribute("class")
- classList := strings.Split(classStr, " ")
- return classList
- }
- func (node *Node) ClassListAdd(classStr string) {
- classList := append(node.ClassList(), classStr)
- str := strings.Join(classList, " ")
- str = strings.Trim(str, " ")
- node.SetAttribute("class", str)
- }
- func (node *Node) ClassListRemove(classStr string) {
- classList := []string{}
- for _, class := range node.ClassList() {
- if class != classStr {
- classList = append(classList, class)
- }
- }
- str := strings.Join(classList, " ")
- str = strings.Trim(str, " ")
- node.SetAttribute("class", str)
- }
- func (node *Node) Remove() {
- closeNode := getCloseNode(node)
- i := 0
- for _, n := range node.Parent.Children {
- if n == closeNode {
- node.Parent.Children = append(node.Parent.Children[:i], node.Parent.Children[i+1:]...)
- break
- }
- i++
- }
- i = 0
- for _, n := range node.Parent.Children {
- if n == node {
- node.Parent.Children = append(node.Parent.Children[:i], node.Parent.Children[i+1:]...)
- break
- }
- i++
- }
- }
- func (node *Node) CreateElement(tagName string) *Node {
- newNode := &Node{}
- newNode.token = "<" + tagName + ">"
- return newNode
- }
- func (node *Node) Append(newNode *Node) {
- newNode.Parent = node
- node.Children = append(node.Children, newNode)
- if getTokType(newNode.token) != "selfclosing" {
- closeNode := &Node{}
- closeNode.token = "</" + getTagName(newNode.token) + ">"
- node.Children = append(node.Children, closeNode)
- }
- }
|