1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
From d26f9f9a57f3fab6a695bec0d84433c2c50f8bbf Mon Sep 17 00:00:00 2001
From: Kunpei Sakai <namusyaka@gmail.com>
Date: Tue, 25 Sep 2018 22:55:50 +0900
Subject: [PATCH] html: update inSelectIM and inSelectInTableIM for the latest
spec
Fixes golang/go#27842
Change-Id: I06eb3c0c18be3566bd30a29fca5f3f7e6791d2cc
Reviewed-on: https://go-review.googlesource.com/c/137275
Run-TryBot: Kunpei Sakai <namusyaka@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
---
html/parse.go | 28 ++++++++++++++++++++++------
html/parse_test.go | 3 ++-
html/testdata/go/select.dat | 12 ++++++++++++
3 files changed, 36 insertions(+), 7 deletions(-)
create mode 100644 html/testdata/go/select.dat
diff --git a/html/parse.go b/html/parse.go
index 64a57937..488e8d3c 100644
--- a/html/parse.go
+++ b/html/parse.go
@@ -1719,8 +1719,12 @@ func inSelectIM(p *parser) bool {
}
p.addElement()
case a.Select:
- p.tok.Type = EndTagToken
- return false
+ if p.popUntil(selectScope, a.Select) {
+ p.resetInsertionMode()
+ } else {
+ // Ignore the token.
+ return true
+ }
case a.Input, a.Keygen, a.Textarea:
if p.elementInScope(selectScope, a.Select) {
p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
@@ -1750,6 +1754,9 @@ func inSelectIM(p *parser) bool {
case a.Select:
if p.popUntil(selectScope, a.Select) {
p.resetInsertionMode()
+ } else {
+ // Ignore the token.
+ return true
}
case a.Template:
return inHeadIM(p)
@@ -1775,13 +1782,22 @@ func inSelectInTableIM(p *parser) bool {
case StartTagToken, EndTagToken:
switch p.tok.DataAtom {
case a.Caption, a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr, a.Td, a.Th:
- if p.tok.Type == StartTagToken || p.elementInScope(tableScope, p.tok.DataAtom) {
- p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
- return false
- } else {
+ if p.tok.Type == EndTagToken && !p.elementInScope(tableScope, p.tok.DataAtom) {
// Ignore the token.
return true
}
+ // This is like p.popUntil(selectScope, a.Select), but it also
+ // matches <math select>, not just <select>. Matching the MathML
+ // tag is arguably incorrect (conceptually), but it mimics what
+ // Chromium does.
+ for i := len(p.oe) - 1; i >= 0; i-- {
+ if n := p.oe[i]; n.DataAtom == a.Select {
+ p.oe = p.oe[:i]
+ break
+ }
+ }
+ p.resetInsertionMode()
+ return false
}
}
return inSelectIM(p)
diff --git a/html/parse_test.go b/html/parse_test.go
index 1c232c71..9bba918c 100644
--- a/html/parse_test.go
+++ b/html/parse_test.go
@@ -367,7 +367,8 @@ var renderTestBlacklist = map[string]bool{
`<script><!--<script </s`: true,
// Reconstructing the active formatting elements results in a <plaintext>
// element that contains an <a> element.
- `<!doctype html><p><a><plaintext>b`: true,
+ `<!doctype html><p><a><plaintext>b`: true,
+ `<table><math><select><mi><select></table>`: true,
}
func TestNodeConsistency(t *testing.T) {
diff --git a/html/testdata/go/select.dat b/html/testdata/go/select.dat
new file mode 100644
index 00000000..684554c8
--- /dev/null
+++ b/html/testdata/go/select.dat
@@ -0,0 +1,12 @@
+#data
+<table><math><select><mi><select></table>
+#errors
+#document
+| <html>
+| <head>
+| <body>
+| <math math>
+| <math select>
+| <math mi>
+| <select>
+| <table>
|