html: add the RawNode NodeType

Fixes golang/go#36350

Change-Id: Ia11b65940949b7da996b194d48372bc6219d4baa
Reviewed-on: https://go-review.googlesource.com/c/net/+/216800
Reviewed-by: Kunpei Sakai <namusyaka@gmail.com>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
Run-TryBot: Kunpei Sakai <namusyaka@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/html/node.go b/html/node.go
index 633ee15..1350eef 100644
--- a/html/node.go
+++ b/html/node.go
@@ -18,6 +18,11 @@
 	ElementNode
 	CommentNode
 	DoctypeNode
+	// 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
 )
 
diff --git a/html/render.go b/html/render.go
index 8bf47ed..46879c0 100644
--- a/html/render.go
+++ b/html/render.go
@@ -134,6 +134,9 @@
 			}
 		}
 		return w.WriteByte('>')
+	case RawNode:
+		_, err := w.WriteString(n.Data)
+		return err
 	default:
 		return errors.New("html: unknown node type")
 	}
diff --git a/html/render_test.go b/html/render_test.go
index 11da54b..1cd439e 100644
--- a/html/render_test.go
+++ b/html/render_test.go
@@ -89,6 +89,14 @@
 			Type: TextNode,
 			Data: "6",
 		},
+		14: {
+			Type: CommentNode,
+			Data: "comm",
+		},
+		15: {
+			Type: RawNode,
+			Data: "7<pre>8</pre>9",
+		},
 	}
 
 	// Build a tree out of those nodes, based on a textual representation.
@@ -110,6 +118,8 @@
 		11: `.	.	<blockquote>`,
 		12: `.	.	<br>`,
 		13: `.	.	"6"`,
+		14: `.	.	"<!--comm-->"`,
+		15: `.	.	"7<pre>8</pre>9"`,
 	}
 	if len(nodes) != len(treeAsText) {
 		t.Fatal("len(nodes) != len(treeAsText)")
@@ -145,7 +155,7 @@
 
 	want := `<html><head></head><body>0&lt;1<p id="A" foo="abc&#34;def">` +
 		`2<b empty="">3</b><i backslash="\">&amp;4</i></p>` +
-		`5<blockquote></blockquote><br/>6</body></html>`
+		`5<blockquote></blockquote><br/>6<!--comm-->7<pre>8</pre>9</body></html>`
 	b := new(bytes.Buffer)
 	if err := Render(b, nodes[0]); err != nil {
 		t.Fatal(err)