diff options
Diffstat (limited to 'libgo/go/html/parse.go')
-rw-r--r-- | libgo/go/html/parse.go | 87 |
1 files changed, 74 insertions, 13 deletions
diff --git a/libgo/go/html/parse.go b/libgo/go/html/parse.go index 4cb246969e5..6962e643932 100644 --- a/libgo/go/html/parse.go +++ b/libgo/go/html/parse.go @@ -319,10 +319,7 @@ func (p *parser) resetInsertionMode() { case "html": p.im = beforeHeadIM default: - if p.top().Namespace == "" { - continue - } - p.im = inForeignContentIM + continue } return } @@ -705,7 +702,7 @@ func inBodyIM(p *parser) bool { case "address", "div", "p": continue default: - if !isSpecialElement[node.Data] { + if !isSpecialElement(node) { continue } } @@ -723,7 +720,7 @@ func inBodyIM(p *parser) bool { case "address", "div", "p": continue default: - if !isSpecialElement[node.Data] { + if !isSpecialElement(node) { continue } } @@ -814,7 +811,6 @@ func inBodyIM(p *parser) bool { // TODO: adjust foreign attributes. p.addElement(p.tok.Data, p.tok.Attr) p.top().Namespace = namespace - p.im = inForeignContentIM return true case "caption", "col", "colgroup", "frame", "head", "tbody", "td", "tfoot", "th", "thead", "tr": // Ignore the token. @@ -895,7 +891,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 +984,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 } } @@ -1206,6 +1202,13 @@ func inTableBodyIM(p *parser) bool { add = true data = "tr" consumed = false + case "caption", "col", "colgroup", "tbody", "tfoot", "thead": + if !p.popUntil(tableScopeStopTags, "tbody", "thead", "tfoot") { + // Ignore the token. + return true + } + p.im = inTableIM + return false default: // TODO. } @@ -1569,6 +1572,19 @@ func afterAfterFramesetIM(p *parser) bool { Type: CommentNode, Data: p.tok.Data, }) + case TextToken: + // Ignore all text but whitespace. + s := strings.Map(func(c rune) rune { + switch c { + case ' ', '\t', '\n', '\f', '\r': + return c + } + return -1 + }, p.tok.Data) + if s != "" { + p.reconstructActiveFormattingElements() + p.addText(s) + } case StartTagToken: switch p.tok.Data { case "html": @@ -1583,8 +1599,19 @@ func afterAfterFramesetIM(p *parser) bool { } // Section 12.2.5.5. -func inForeignContentIM(p *parser) bool { +func parseForeignContent(p *parser) bool { switch p.tok.Type { + case TextToken: + // TODO: HTML integration points. + if p.top().Namespace == "" { + inBodyIM(p) + p.resetInsertionMode() + return true + } + if p.framesetOK { + p.framesetOK = strings.TrimLeft(p.tok.Data, whitespace) == "" + } + p.addText(p.tok.Data) case CommentToken: p.addChild(&Node{ Type: CommentNode, @@ -1592,7 +1619,14 @@ func inForeignContentIM(p *parser) bool { }) case StartTagToken: if breakout[p.tok.Data] { - // TODO. + for i := len(p.oe) - 1; i >= 0; i-- { + // TODO: HTML, MathML integration points. + if p.oe[i].Namespace == "" { + p.oe = p.oe[:i+1] + break + } + } + return false } switch p.top().Namespace { case "mathml": @@ -1606,13 +1640,36 @@ 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 == "" { + return p.im(p) + } + if strings.EqualFold(p.oe[i].Data, p.tok.Data) { + p.oe = p.oe[:i] + break + } + } + return true default: // Ignore the token. } return true } +// Section 12.2.5. +func (p *parser) inForeignContent() bool { + if len(p.oe) == 0 { + return false + } + n := p.oe[len(p.oe)-1] + if n.Namespace == "" { + return false + } + // TODO: MathML, HTML integration points. + // TODO: MathML's annotation-xml combining with SVG's svg. + return true +} + func (p *parser) parse() error { // Iterate until EOF. Any other error will cause an early return. consumed := true @@ -1625,7 +1682,11 @@ func (p *parser) parse() error { return err } } - consumed = p.im(p) + if p.inForeignContent() { + consumed = parseForeignContent(p) + } else { + consumed = p.im(p) + } } // Loop until the final token (the ErrorToken signifying EOF) is consumed. for { |