// 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 html import ( "template/parse" ) // clone clones a template Node. func clone(n parse.Node) parse.Node { switch t := n.(type) { case *parse.ActionNode: return cloneAction(t) case *parse.IfNode: b := new(parse.IfNode) copyBranch(&b.BranchNode, &t.BranchNode) return b case *parse.ListNode: return cloneList(t) case *parse.RangeNode: b := new(parse.RangeNode) copyBranch(&b.BranchNode, &t.BranchNode) return b case *parse.TemplateNode: return cloneTemplate(t) case *parse.TextNode: return cloneText(t) case *parse.WithNode: b := new(parse.WithNode) copyBranch(&b.BranchNode, &t.BranchNode) return b } panic("cloning " + n.String() + " is unimplemented") } // cloneAction returns a deep clone of n. func cloneAction(n *parse.ActionNode) *parse.ActionNode { // We use keyless fields because they won't compile if a field is added. return &parse.ActionNode{n.NodeType, n.Line, clonePipe(n.Pipe)} } // cloneList returns a deep clone of n. func cloneList(n *parse.ListNode) *parse.ListNode { if n == nil { return nil } // We use keyless fields because they won't compile if a field is added. c := parse.ListNode{n.NodeType, make([]parse.Node, len(n.Nodes))} for i, child := range n.Nodes { c.Nodes[i] = clone(child) } return &c } // clonePipe returns a shallow clone of n. // The escaper does not modify pipe descendants in place so there's no need to // clone deeply. func clonePipe(n *parse.PipeNode) *parse.PipeNode { if n == nil { return nil } // We use keyless fields because they won't compile if a field is added. return &parse.PipeNode{n.NodeType, n.Line, n.Decl, n.Cmds} } // cloneTemplate returns a deep clone of n. func cloneTemplate(n *parse.TemplateNode) *parse.TemplateNode { // We use keyless fields because they won't compile if a field is added. return &parse.TemplateNode{n.NodeType, n.Line, n.Name, clonePipe(n.Pipe)} } // cloneText clones the given node sharing its []byte. func cloneText(n *parse.TextNode) *parse.TextNode { // We use keyless fields because they won't compile if a field is added. return &parse.TextNode{n.NodeType, n.Text} } // copyBranch clones src into dst. func copyBranch(dst, src *parse.BranchNode) { // We use keyless fields because they won't compile if a field is added. *dst = parse.BranchNode{ src.NodeType, src.Line, clonePipe(src.Pipe), cloneList(src.List), cloneList(src.ElseList), } }