From a369004e2318ad0f139f967c764918bd939980ce Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Fri, 16 Dec 2011 09:36:50 +1100 Subject: [PATCH] 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: | | | | | | Also pass tests through test 5:
R=andybalholm CC=golang-dev https://golang.org/cl/5495044 --- src/pkg/html/const.go | 12 +++++++++++- src/pkg/html/parse.go | 21 ++++++++++++++++----- src/pkg/html/parse_test.go | 1 + 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/pkg/html/const.go b/src/pkg/html/const.go index 832e9dbc09..d7cc8bb9a9 100644 --- a/src/pkg/html/const.go +++ b/src/pkg/html/const.go @@ -7,7 +7,7 @@ package html // Section 12.2.3.2 of the HTML5 specification says "The following elements // have varying levels of special parsing rules". // 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, "applet": true, "area": true, @@ -88,3 +88,13 @@ var isSpecialElement = map[string]bool{ "wbr": 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 +} diff --git a/src/pkg/html/parse.go b/src/pkg/html/parse.go index 4cb246969e..104adc1b7b 100644 --- a/src/pkg/html/parse.go +++ b/src/pkg/html/parse.go @@ -705,7 +705,7 @@ func inBodyIM(p *parser) bool { case "address", "div", "p": continue default: - if !isSpecialElement[node.Data] { + if !isSpecialElement(node) { continue } } @@ -723,7 +723,7 @@ func inBodyIM(p *parser) bool { case "address", "div", "p": continue default: - if !isSpecialElement[node.Data] { + if !isSpecialElement(node) { continue } } @@ -895,7 +895,7 @@ func (p *parser) inBodyEndTagFormatting(tag string) { // Steps 5-6. Find the furthest block. var furthestBlock *Node for _, e := range p.oe[feIndex:] { - if isSpecialElement[e.Data] { + if isSpecialElement(e) { furthestBlock = e break } @@ -988,7 +988,7 @@ func (p *parser) inBodyEndTagOther(tag string) { p.oe = p.oe[:i] break } - if isSpecialElement[p.oe[i].Data] { + if isSpecialElement(p.oe[i]) { break } } @@ -1606,7 +1606,18 @@ func inForeignContentIM(p *parser) bool { // TODO: adjust foreign attributes. p.addElement(p.tok.Data, p.tok.Attr) 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: // Ignore the token. } diff --git a/src/pkg/html/parse_test.go b/src/pkg/html/parse_test.go index e887631c63..f501915759 100644 --- a/src/pkg/html/parse_test.go +++ b/src/pkg/html/parse_test.go @@ -173,6 +173,7 @@ func TestParser(t *testing.T) { {"tests4.dat", -1}, {"tests5.dat", -1}, {"tests6.dat", 36}, + {"tests10.dat", 6}, } for _, tf := range testFiles { f, err := os.Open("testdata/webkit/" + tf.filename)