html: don't ignore the token if the current node is form

See: https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody

Fixes golang/go#25703
Updates golang/go#23071

Change-Id: I09db4c2d07a242cb45c3e37b499c609809dd0b83
Reviewed-on: https://go-review.googlesource.com/120658
Run-TryBot: Kunpei Sakai <namusyaka@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/html/parse.go b/html/parse.go
index d23e05e..7e539b1 100644
--- a/html/parse.go
+++ b/html/parse.go
@@ -860,9 +860,13 @@
 			// The newline, if any, will be dealt with by the TextToken case.
 			p.framesetOK = false
 		case a.Form:
-			if p.oe.contains(a.Template) || p.form == nil {
-				p.popUntil(buttonScope, a.P)
-				p.addElement()
+			if p.form != nil && !p.oe.contains(a.Template) {
+				// Ignore the token
+				return true
+			}
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+			if !p.oe.contains(a.Template) {
 				p.form = p.top()
 			}
 		case a.Li:
@@ -1098,12 +1102,13 @@
 			p.popUntil(defaultScope, p.tok.DataAtom)
 		case a.Form:
 			if p.oe.contains(a.Template) {
-				if !p.oe.contains(a.Form) {
+				i := p.indexOfElementInScope(defaultScope, a.Form)
+				if i == -1 {
 					// Ignore the token.
 					return true
 				}
 				p.generateImpliedEndTags()
-				if p.tok.DataAtom == a.Form {
+				if p.oe[i].DataAtom != a.Form {
 					// Ignore the token.
 					return true
 				}
diff --git a/html/parse_test.go b/html/parse_test.go
index 89d9642..0b72a12 100644
--- a/html/parse_test.go
+++ b/html/parse_test.go
@@ -203,34 +203,36 @@
 	return b.String(), nil
 }
 
-const testDataDir = "testdata/webkit/"
+var testDataDirs = []string{"testdata/webkit/", "testdata/go/"}
 
 func TestParser(t *testing.T) {
-	testFiles, err := filepath.Glob(testDataDir + "*.dat")
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, tf := range testFiles {
-		f, err := os.Open(tf)
+	for _, testDataDir := range testDataDirs {
+		testFiles, err := filepath.Glob(testDataDir + "*.dat")
 		if err != nil {
 			t.Fatal(err)
 		}
-		defer f.Close()
-		r := bufio.NewReader(f)
-
-		for i := 0; ; i++ {
-			text, want, context, err := readParseTest(r)
-			if err == io.EOF {
-				break
-			}
+		for _, tf := range testFiles {
+			f, err := os.Open(tf)
 			if err != nil {
 				t.Fatal(err)
 			}
+			defer f.Close()
+			r := bufio.NewReader(f)
 
-			err = testParseCase(text, want, context)
+			for i := 0; ; i++ {
+				text, want, context, err := readParseTest(r)
+				if err == io.EOF {
+					break
+				}
+				if err != nil {
+					t.Fatal(err)
+				}
 
-			if err != nil {
-				t.Errorf("%s test #%d %q, %s", tf, i, text, err)
+				err = testParseCase(text, want, context)
+
+				if err != nil {
+					t.Errorf("%s test #%d %q, %s", tf, i, text, err)
+				}
 			}
 		}
 	}
diff --git a/html/testdata/go/template.dat b/html/testdata/go/template.dat
new file mode 100644
index 0000000..a0a525b
--- /dev/null
+++ b/html/testdata/go/template.dat
@@ -0,0 +1,13 @@
+#data
+<body><template><yt-icon-button></yt-icon-button><form><paper-input></paper-input></form><style></style></template>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <template>
+|       content
+|         <yt-icon-button>
+|         <form>
+|           <paper-input>
+|         <style>