// Copyright 2011 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package htmlimport ()// A NodeType is the type of a Node.typeNodeTypeuint32const (ErrorNodeNodeType = iotaTextNodeDocumentNodeElementNodeCommentNodeDoctypeNode// RawNode nodes are not returned by the parser, but can be part of the // Node tree passed to func Render to insert raw HTML (without escaping). // If so, this package makes no guarantee that the rendered HTML is secure // (from e.g. Cross Site Scripting attacks) or well-formed.RawNode scopeMarkerNode)// Section 12.2.4.3 says "The markers are inserted when entering applet,// object, marquee, template, td, th, and caption elements, and are used// to prevent formatting from "leaking" into applet, object, marquee,// template, td, th, and caption elements".var scopeMarker = Node{Type: scopeMarkerNode}// A Node consists of a NodeType and some Data (tag name for element nodes,// content for text) and are part of a tree of Nodes. Element nodes may also// have a Namespace and contain a slice of Attributes. Data is unescaped, so// that it looks like "a<b" rather than "a<b". For element nodes, DataAtom// is the atom for Data, or zero if Data is not a known tag name.//// An empty Namespace implies a "http://www.w3.org/1999/xhtml" namespace.// Similarly, "math" is short for "http://www.w3.org/1998/Math/MathML", and// "svg" is short for "http://www.w3.org/2000/svg".typeNodestruct { Parent, FirstChild, LastChild, PrevSibling, NextSibling *Node Type NodeType DataAtom atom.Atom Data string Namespace string Attr []Attribute}// InsertBefore inserts newChild as a child of n, immediately before oldChild// in the sequence of n's children. oldChild may be nil, in which case newChild// is appended to the end of n's children.//// It will panic if newChild already has a parent or siblings.func ( *Node) (, *Node) {if .Parent != nil || .PrevSibling != nil || .NextSibling != nil {panic("html: InsertBefore called for an attached child Node") }var , *Nodeif != nil { , = .PrevSibling, } else { = .LastChild }if != nil { .NextSibling = } else { .FirstChild = }if != nil { .PrevSibling = } else { .LastChild = } .Parent = .PrevSibling = .NextSibling = }// AppendChild adds a node c as a child of n.//// It will panic if c already has a parent or siblings.func ( *Node) ( *Node) {if .Parent != nil || .PrevSibling != nil || .NextSibling != nil {panic("html: AppendChild called for an attached child Node") } := .LastChildif != nil { .NextSibling = } else { .FirstChild = } .LastChild = .Parent = .PrevSibling = }// RemoveChild removes a node c that is a child of n. Afterwards, c will have// no parent and no siblings.//// It will panic if c's parent is not n.func ( *Node) ( *Node) {if .Parent != {panic("html: RemoveChild called for a non-child Node") }if .FirstChild == { .FirstChild = .NextSibling }if .NextSibling != nil { .NextSibling.PrevSibling = .PrevSibling }if .LastChild == { .LastChild = .PrevSibling }if .PrevSibling != nil { .PrevSibling.NextSibling = .NextSibling } .Parent = nil .PrevSibling = nil .NextSibling = nil}// reparentChildren reparents all of src's child nodes to dst.func reparentChildren(, *Node) {for { := .FirstChildif == nil {break } .RemoveChild() .AppendChild() }}// clone returns a new node with the same type, data and attributes.// The clone has no parent, no siblings and no children.func ( *Node) () *Node { := &Node{Type: .Type,DataAtom: .DataAtom,Data: .Data,Attr: make([]Attribute, len(.Attr)), }copy(.Attr, .Attr)return}// nodeStack is a stack of nodes.type nodeStack []*Node// pop pops the stack. It will panic if s is empty.func ( *nodeStack) () *Node { := len(*) := (*)[-1] * = (*)[:-1]return}// top returns the most recently pushed node, or nil if s is empty.func ( *nodeStack) () *Node {if := len(*); > 0 {return (*)[-1] }returnnil}// index returns the index of the top-most occurrence of n in the stack, or -1// if n is not present.func ( *nodeStack) ( *Node) int {for := len(*) - 1; >= 0; -- {if (*)[] == {return } }return -1}// contains returns whether a is within s.func ( *nodeStack) ( atom.Atom) bool {for , := range * {if .DataAtom == && .Namespace == "" {returntrue } }returnfalse}// insert inserts a node at the given index.func ( *nodeStack) ( int, *Node) { (*) = append(*, nil)copy((*)[+1:], (*)[:]) (*)[] = }// remove removes a node from the stack. It is a no-op if n is not present.func ( *nodeStack) ( *Node) { := .index()if == -1 {return }copy((*)[:], (*)[+1:]) := len(*) - 1 (*)[] = nil * = (*)[:]}type insertionModeStack []insertionModefunc ( *insertionModeStack) () ( insertionMode) { := len(*) = (*)[-1] * = (*)[:-1]return}func ( *insertionModeStack) () insertionMode {if := len(*); > 0 {return (*)[-1] }returnnil}
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.