Commit a369004e authored by Nigel Tao's avatar Nigel Tao

html: handle end tags in foreign objects.

I'm not 100% sure I get all the corner cases right, for end tags, but
I'll let the test suite smoke it out.

Pass tests10.dat, test 1:
<!DOCTYPE html><svg></svg><![CDATA[a]]>

| <!DOCTYPE html>
| <html>
|   <head>
|   <body>
|     <svg svg>
|     <!-- [CDATA[a]] -->

Also pass tests through test 5:
<!DOCTYPE html><body><table><svg></svg></table>

R=andybalholm
CC=golang-dev
https://golang.org/cl/5495044
parent 9f65e99a
...@@ -7,7 +7,7 @@ package html ...@@ -7,7 +7,7 @@ package html
// Section 12.2.3.2 of the HTML5 specification says "The following elements // Section 12.2.3.2 of the HTML5 specification says "The following elements
// have varying levels of special parsing rules". // have varying levels of special parsing rules".
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-stack-of-open-elements // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-stack-of-open-elements
var isSpecialElement = map[string]bool{ var isSpecialElementMap = map[string]bool{
"address": true, "address": true,
"applet": true, "applet": true,
"area": true, "area": true,
...@@ -88,3 +88,13 @@ var isSpecialElement = map[string]bool{ ...@@ -88,3 +88,13 @@ var isSpecialElement = map[string]bool{
"wbr": true, "wbr": true,
"xmp": true, "xmp": true,
} }
func isSpecialElement(element *Node) bool {
switch element.Namespace {
case "", "html":
return isSpecialElementMap[element.Data]
case "svg":
return element.Data == "foreignObject"
}
return false
}
...@@ -705,7 +705,7 @@ func inBodyIM(p *parser) bool { ...@@ -705,7 +705,7 @@ func inBodyIM(p *parser) bool {
case "address", "div", "p": case "address", "div", "p":
continue continue
default: default:
if !isSpecialElement[node.Data] { if !isSpecialElement(node) {
continue continue
} }
} }
...@@ -723,7 +723,7 @@ func inBodyIM(p *parser) bool { ...@@ -723,7 +723,7 @@ func inBodyIM(p *parser) bool {
case "address", "div", "p": case "address", "div", "p":
continue continue
default: default:
if !isSpecialElement[node.Data] { if !isSpecialElement(node) {
continue continue
} }
} }
...@@ -895,7 +895,7 @@ func (p *parser) inBodyEndTagFormatting(tag string) { ...@@ -895,7 +895,7 @@ func (p *parser) inBodyEndTagFormatting(tag string) {
// Steps 5-6. Find the furthest block. // Steps 5-6. Find the furthest block.
var furthestBlock *Node var furthestBlock *Node
for _, e := range p.oe[feIndex:] { for _, e := range p.oe[feIndex:] {
if isSpecialElement[e.Data] { if isSpecialElement(e) {
furthestBlock = e furthestBlock = e
break break
} }
...@@ -988,7 +988,7 @@ func (p *parser) inBodyEndTagOther(tag string) { ...@@ -988,7 +988,7 @@ func (p *parser) inBodyEndTagOther(tag string) {
p.oe = p.oe[:i] p.oe = p.oe[:i]
break break
} }
if isSpecialElement[p.oe[i].Data] { if isSpecialElement(p.oe[i]) {
break break
} }
} }
...@@ -1606,7 +1606,18 @@ func inForeignContentIM(p *parser) bool { ...@@ -1606,7 +1606,18 @@ func inForeignContentIM(p *parser) bool {
// TODO: adjust foreign attributes. // TODO: adjust foreign attributes.
p.addElement(p.tok.Data, p.tok.Attr) p.addElement(p.tok.Data, p.tok.Attr)
case EndTagToken: case EndTagToken:
// TODO. for i := len(p.oe) - 1; i >= 0; i-- {
if p.oe[i].Namespace == "" {
inBodyIM(p)
break
}
if strings.EqualFold(p.oe[i].Data, p.tok.Data) {
p.oe = p.oe[:i]
break
}
}
p.resetInsertionMode()
return true
default: default:
// Ignore the token. // Ignore the token.
} }
......
...@@ -173,6 +173,7 @@ func TestParser(t *testing.T) { ...@@ -173,6 +173,7 @@ func TestParser(t *testing.T) {
{"tests4.dat", -1}, {"tests4.dat", -1},
{"tests5.dat", -1}, {"tests5.dat", -1},
{"tests6.dat", 36}, {"tests6.dat", 36},
{"tests10.dat", 6},
} }
for _, tf := range testFiles { for _, tf := range testFiles {
f, err := os.Open("testdata/webkit/" + tf.filename) f, err := os.Open("testdata/webkit/" + tf.filename)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment