diff options
Diffstat (limited to 'vendor/golang.org/x/net/html/node.go')
| -rw-r--r-- | vendor/golang.org/x/net/html/node.go | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/vendor/golang.org/x/net/html/node.go b/vendor/golang.org/x/net/html/node.go new file mode 100644 index 0000000..1350eef --- /dev/null +++ b/vendor/golang.org/x/net/html/node.go | |||
| @@ -0,0 +1,225 @@ | |||
| 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. | ||
| 4 | |||
| 5 | package html | ||
| 6 | |||
| 7 | import ( | ||
| 8 | "golang.org/x/net/html/atom" | ||
| 9 | ) | ||
| 10 | |||
| 11 | // A NodeType is the type of a Node. | ||
| 12 | type NodeType uint32 | ||
| 13 | |||
| 14 | const ( | ||
| 15 | ErrorNode NodeType = iota | ||
| 16 | TextNode | ||
| 17 | DocumentNode | ||
| 18 | ElementNode | ||
| 19 | CommentNode | ||
| 20 | DoctypeNode | ||
| 21 | // RawNode nodes are not returned by the parser, but can be part of the | ||
| 22 | // Node tree passed to func Render to insert raw HTML (without escaping). | ||
| 23 | // If so, this package makes no guarantee that the rendered HTML is secure | ||
| 24 | // (from e.g. Cross Site Scripting attacks) or well-formed. | ||
| 25 | RawNode | ||
| 26 | scopeMarkerNode | ||
| 27 | ) | ||
| 28 | |||
| 29 | // Section 12.2.4.3 says "The markers are inserted when entering applet, | ||
| 30 | // object, marquee, template, td, th, and caption elements, and are used | ||
| 31 | // to prevent formatting from "leaking" into applet, object, marquee, | ||
| 32 | // template, td, th, and caption elements". | ||
| 33 | var scopeMarker = Node{Type: scopeMarkerNode} | ||
| 34 | |||
| 35 | // A Node consists of a NodeType and some Data (tag name for element nodes, | ||
| 36 | // content for text) and are part of a tree of Nodes. Element nodes may also | ||
| 37 | // have a Namespace and contain a slice of Attributes. Data is unescaped, so | ||
| 38 | // that it looks like "a<b" rather than "a<b". For element nodes, DataAtom | ||
| 39 | // is the atom for Data, or zero if Data is not a known tag name. | ||
| 40 | // | ||
| 41 | // An empty Namespace implies a "http://www.w3.org/1999/xhtml" namespace. | ||
| 42 | // Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML", and | ||
| 43 | // "svg" is short for "http://www.w3.org/2000/svg". | ||
| 44 | type Node struct { | ||
| 45 | Parent, FirstChild, LastChild, PrevSibling, NextSibling *Node | ||
| 46 | |||
| 47 | Type NodeType | ||
| 48 | DataAtom atom.Atom | ||
| 49 | Data string | ||
| 50 | Namespace string | ||
| 51 | Attr []Attribute | ||
| 52 | } | ||
| 53 | |||
| 54 | // InsertBefore inserts newChild as a child of n, immediately before oldChild | ||
| 55 | // in the sequence of n's children. oldChild may be nil, in which case newChild | ||
| 56 | // is appended to the end of n's children. | ||
| 57 | // | ||
| 58 | // It will panic if newChild already has a parent or siblings. | ||
| 59 | func (n *Node) InsertBefore(newChild, oldChild *Node) { | ||
| 60 | if newChild.Parent != nil || newChild.PrevSibling != nil || newChild.NextSibling != nil { | ||
| 61 | panic("html: InsertBefore called for an attached child Node") | ||
| 62 | } | ||
| 63 | var prev, next *Node | ||
| 64 | if oldChild != nil { | ||
| 65 | prev, next = oldChild.PrevSibling, oldChild | ||
| 66 | } else { | ||
| 67 | prev = n.LastChild | ||
| 68 | } | ||
| 69 | if prev != nil { | ||
| 70 | prev.NextSibling = newChild | ||
| 71 | } else { | ||
| 72 | n.FirstChild = newChild | ||
| 73 | } | ||
| 74 | if next != nil { | ||
| 75 | next.PrevSibling = newChild | ||
| 76 | } else { | ||
| 77 | n.LastChild = newChild | ||
| 78 | } | ||
| 79 | newChild.Parent = n | ||
| 80 | newChild.PrevSibling = prev | ||
| 81 | newChild.NextSibling = next | ||
| 82 | } | ||
| 83 | |||
| 84 | // AppendChild adds a node c as a child of n. | ||
| 85 | // | ||
| 86 | // It will panic if c already has a parent or siblings. | ||
| 87 | func (n *Node) AppendChild(c *Node) { | ||
| 88 | if c.Parent != nil || c.PrevSibling != nil || c.NextSibling != nil { | ||
| 89 | panic("html: AppendChild called for an attached child Node") | ||
| 90 | } | ||
| 91 | last := n.LastChild | ||
| 92 | if last != nil { | ||
| 93 | last.NextSibling = c | ||
| 94 | } else { | ||
| 95 | n.FirstChild = c | ||
| 96 | } | ||
| 97 | n.LastChild = c | ||
| 98 | c.Parent = n | ||
| 99 | c.PrevSibling = last | ||
| 100 | } | ||
| 101 | |||
| 102 | // RemoveChild removes a node c that is a child of n. Afterwards, c will have | ||
| 103 | // no parent and no siblings. | ||
| 104 | // | ||
| 105 | // It will panic if c's parent is not n. | ||
| 106 | func (n *Node) RemoveChild(c *Node) { | ||
| 107 | if c.Parent != n { | ||
| 108 | panic("html: RemoveChild called for a non-child Node") | ||
| 109 | } | ||
| 110 | if n.FirstChild == c { | ||
| 111 | n.FirstChild = c.NextSibling | ||
| 112 | } | ||
| 113 | if c.NextSibling != nil { | ||
| 114 | c.NextSibling.PrevSibling = c.PrevSibling | ||
| 115 | } | ||
| 116 | if n.LastChild == c { | ||
| 117 | n.LastChild = c.PrevSibling | ||
| 118 | } | ||
| 119 | if c.PrevSibling != nil { | ||
| 120 | c.PrevSibling.NextSibling = c.NextSibling | ||
| 121 | } | ||
| 122 | c.Parent = nil | ||
| 123 | c.PrevSibling = nil | ||
| 124 | c.NextSibling = nil | ||
| 125 | } | ||
| 126 | |||
| 127 | // reparentChildren reparents all of src's child nodes to dst. | ||
| 128 | func reparentChildren(dst, src *Node) { | ||
| 129 | for { | ||
| 130 | child := src.FirstChild | ||
| 131 | if child == nil { | ||
| 132 | break | ||
| 133 | } | ||
| 134 | src.RemoveChild(child) | ||
| 135 | dst.AppendChild(child) | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | // clone returns a new node with the same type, data and attributes. | ||
| 140 | // The clone has no parent, no siblings and no children. | ||
| 141 | func (n *Node) clone() *Node { | ||
| 142 | m := &Node{ | ||
| 143 | Type: n.Type, | ||
| 144 | DataAtom: n.DataAtom, | ||
| 145 | Data: n.Data, | ||
| 146 | Attr: make([]Attribute, len(n.Attr)), | ||
| 147 | } | ||
| 148 | copy(m.Attr, n.Attr) | ||
| 149 | return m | ||
| 150 | } | ||
| 151 | |||
| 152 | // nodeStack is a stack of nodes. | ||
| 153 | type nodeStack []*Node | ||
| 154 | |||
| 155 | // pop pops the stack. It will panic if s is empty. | ||
| 156 | func (s *nodeStack) pop() *Node { | ||
| 157 | i := len(*s) | ||
| 158 | n := (*s)[i-1] | ||
| 159 | *s = (*s)[:i-1] | ||
| 160 | return n | ||
| 161 | } | ||
| 162 | |||
| 163 | // top returns the most recently pushed node, or nil if s is empty. | ||
| 164 | func (s *nodeStack) top() *Node { | ||
| 165 | if i := len(*s); i > 0 { | ||
| 166 | return (*s)[i-1] | ||
| 167 | } | ||
| 168 | return nil | ||
| 169 | } | ||
| 170 | |||
| 171 | // index returns the index of the top-most occurrence of n in the stack, or -1 | ||
| 172 | // if n is not present. | ||
| 173 | func (s *nodeStack) index(n *Node) int { | ||
| 174 | for i := len(*s) - 1; i >= 0; i-- { | ||
| 175 | if (*s)[i] == n { | ||
| 176 | return i | ||
| 177 | } | ||
| 178 | } | ||
| 179 | return -1 | ||
| 180 | } | ||
| 181 | |||
| 182 | // contains returns whether a is within s. | ||
| 183 | func (s *nodeStack) contains(a atom.Atom) bool { | ||
| 184 | for _, n := range *s { | ||
| 185 | if n.DataAtom == a && n.Namespace == "" { | ||
| 186 | return true | ||
| 187 | } | ||
| 188 | } | ||
| 189 | return false | ||
| 190 | } | ||
| 191 | |||
| 192 | // insert inserts a node at the given index. | ||
| 193 | func (s *nodeStack) insert(i int, n *Node) { | ||
| 194 | (*s) = append(*s, nil) | ||
| 195 | copy((*s)[i+1:], (*s)[i:]) | ||
| 196 | (*s)[i] = n | ||
| 197 | } | ||
| 198 | |||
| 199 | // remove removes a node from the stack. It is a no-op if n is not present. | ||
| 200 | func (s *nodeStack) remove(n *Node) { | ||
| 201 | i := s.index(n) | ||
| 202 | if i == -1 { | ||
| 203 | return | ||
| 204 | } | ||
| 205 | copy((*s)[i:], (*s)[i+1:]) | ||
| 206 | j := len(*s) - 1 | ||
| 207 | (*s)[j] = nil | ||
| 208 | *s = (*s)[:j] | ||
| 209 | } | ||
| 210 | |||
| 211 | type insertionModeStack []insertionMode | ||
| 212 | |||
| 213 | func (s *insertionModeStack) pop() (im insertionMode) { | ||
| 214 | i := len(*s) | ||
| 215 | im = (*s)[i-1] | ||
| 216 | *s = (*s)[:i-1] | ||
| 217 | return im | ||
| 218 | } | ||
| 219 | |||
| 220 | func (s *insertionModeStack) top() insertionMode { | ||
| 221 | if i := len(*s); i > 0 { | ||
| 222 | return (*s)[i-1] | ||
| 223 | } | ||
| 224 | return nil | ||
| 225 | } | ||
