1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
7 // A NodeType is the type of a Node.
11 ErrorNode NodeType = iota
20 // Section 11.2.3.3 says "scope markers are inserted when entering applet
21 // elements, buttons, object elements, marquees, table cells, and table
22 // captions, and are used to prevent formatting from 'leaking'".
23 var scopeMarker = Node{Type: scopeMarkerNode}
25 // A Node consists of a NodeType and some Data (tag name for element nodes,
26 // content for text) and are part of a tree of Nodes. Element nodes may also
27 // contain a slice of Attributes. Data is unescaped, so that it looks like
28 // "a<b" rather than "a<b".
37 // Add adds a node as a child of n.
38 // It will panic if the child's parent is not nil.
39 func (n *Node) Add(child *Node) {
40 if child.Parent != nil {
41 panic("html: Node.Add called for a child Node that already has a parent")
44 n.Child = append(n.Child, child)
47 // Remove removes a node as a child of n.
48 // It will panic if the child's parent is not n.
49 func (n *Node) Remove(child *Node) {
50 if child.Parent == n {
52 for i, m := range n.Child {
54 copy(n.Child[i:], n.Child[i+1:])
62 panic("html: Node.Remove called for a non-child Node")
65 // reparentChildren reparents all of src's child nodes to dst.
66 func reparentChildren(dst, src *Node) {
67 for _, n := range src.Child {
69 panic("html: nodes have an inconsistent parent/child relationship")
73 dst.Child = append(dst.Child, src.Child...)
77 // clone returns a new node with the same type, data and attributes.
78 // The clone has no parent and no children.
79 func (n *Node) clone() *Node {
83 Attr: make([]Attribute, len(n.Attr)),
89 // nodeStack is a stack of nodes.
90 type nodeStack []*Node
92 // pop pops the stack. It will panic if s is empty.
93 func (s *nodeStack) pop() *Node {
100 // top returns the most recently pushed node, or nil if s is empty.
101 func (s *nodeStack) top() *Node {
102 if i := len(*s); i > 0 {
108 // index returns the index of the top-most occurence of n in the stack, or -1
109 // if n is not present.
110 func (s *nodeStack) index(n *Node) int {
111 for i := len(*s) - 1; i >= 0; i-- {
119 // insert inserts a node at the given index.
120 func (s *nodeStack) insert(i int, n *Node) {
121 (*s) = append(*s, nil)
122 copy((*s)[i+1:], (*s)[i:])
126 // remove removes a node from the stack. It is a no-op if n is not present.
127 func (s *nodeStack) remove(n *Node) {
132 copy((*s)[i:], (*s)[i+1:])
138 // TODO(nigeltao): forTag no longer used. Should it be deleted?
140 // forTag returns the top-most element node with the given tag.
141 func (s *nodeStack) forTag(tag string) *Node {
142 for i := len(*s) - 1; i >= 0; i-- {
144 if n.Type == ElementNode && n.Data == tag {