html: implement adjusted current node and make parser support foreign fragment

This follows up on golang.org/cl/205617

Change-Id: Id94a4fcef6a604936c404f75999ba37321b6c2c0
Reviewed-on: https://go-review.googlesource.com/c/net/+/206121
Run-TryBot: Kunpei Sakai <namusyaka@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
This commit is contained in:
Kunpei Sakai
2019-11-10 04:01:21 +09:00
committed by Nigel Tao
parent 72fef5d5e2
commit ffdde10578
3 changed files with 593 additions and 23 deletions

View File

@@ -2136,28 +2136,31 @@ func parseForeignContent(p *parser) bool {
Data: p.tok.Data,
})
case StartTagToken:
b := breakout[p.tok.Data]
if p.tok.DataAtom == a.Font {
loop:
for _, attr := range p.tok.Attr {
switch attr.Key {
case "color", "face", "size":
b = true
break loop
if !p.fragment {
b := breakout[p.tok.Data]
if p.tok.DataAtom == a.Font {
loop:
for _, attr := range p.tok.Attr {
switch attr.Key {
case "color", "face", "size":
b = true
break loop
}
}
}
}
if b {
for i := len(p.oe) - 1; i >= 0; i-- {
n := p.oe[i]
if n.Namespace == "" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {
p.oe = p.oe[:i+1]
break
if b {
for i := len(p.oe) - 1; i >= 0; i-- {
n := p.oe[i]
if n.Namespace == "" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {
p.oe = p.oe[:i+1]
break
}
}
return false
}
return false
}
switch p.top().Namespace {
current := p.adjustedCurrentNode()
switch current.Namespace {
case "math":
adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
case "svg":
@@ -2172,7 +2175,7 @@ func parseForeignContent(p *parser) bool {
panic("html: bad parser state: unexpected namespace")
}
adjustForeignAttributes(p.tok.Attr)
namespace := p.top().Namespace
namespace := current.Namespace
p.addElement()
p.top().Namespace = namespace
if namespace != "" {
@@ -2201,12 +2204,20 @@ func parseForeignContent(p *parser) bool {
return true
}
// Section 12.2.4.2.
func (p *parser) adjustedCurrentNode() *Node {
if len(p.oe) == 1 && p.fragment && p.context != nil {
return p.context
}
return p.oe.top()
}
// Section 12.2.6.
func (p *parser) inForeignContent() bool {
if len(p.oe) == 0 {
return false
}
n := p.oe[len(p.oe)-1]
n := p.adjustedCurrentNode()
if n.Namespace == "" {
return false
}
@@ -2364,7 +2375,6 @@ func ParseFragmentWithOptions(r io.Reader, context *Node, opts ...ParseOption) (
contextTag = context.DataAtom.String()
}
p := &parser{
tokenizer: NewTokenizerFragment(r, contextTag),
doc: &Node{
Type: DocumentNode,
},
@@ -2372,6 +2382,11 @@ func ParseFragmentWithOptions(r io.Reader, context *Node, opts ...ParseOption) (
fragment: true,
context: context,
}
if context != nil && context.Namespace != "" {
p.tokenizer = NewTokenizer(r)
} else {
p.tokenizer = NewTokenizerFragment(r, contextTag)
}
for _, f := range opts {
f(p)

View File

@@ -307,10 +307,15 @@ func testParseCase(text, want, context string, opts ...ParseOption) (err error)
return err
}
} else {
namespace := ""
if i := strings.IndexByte(context, ' '); i >= 0 {
namespace, context = context[:i], context[i+1:]
}
contextNode := &Node{
Type: ElementNode,
DataAtom: atom.Lookup([]byte(context)),
Data: context,
Data: context,
DataAtom: atom.Lookup([]byte(context)),
Namespace: namespace,
Type: ElementNode,
}
nodes, err := ParseFragmentWithOptions(strings.NewReader(text), contextNode, opts...)
if err != nil {

View File

@@ -0,0 +1,550 @@
#data
<nobr>X
#errors
6: HTML start tag “nobr” in a foreign namespace context.
7: End of file seen and there were open elements.
6: Unclosed element “nobr”.
#document-fragment
svg path
#document
| <svg nobr>
| "X"
#data
<font color></font>X
#errors
12: HTML start tag “font” in a foreign namespace context.
#document-fragment
svg path
#document
| <svg font>
| color=""
| "X"
#data
<font></font>X
#errors
#document-fragment
svg path
#document
| <svg font>
| "X"
#data
<g></path>X
#errors
10: End tag “path” did not match the name of the current open element (“g”).
11: End of file seen and there were open elements.
3: Unclosed element “g”.
#document-fragment
svg path
#document
| <svg g>
| "X"
#data
</path>X
#errors
5: Stray end tag “path”.
#document-fragment
svg path
#document
| "X"
#data
</foreignObject>X
#errors
5: Stray end tag “foreignobject”.
#document-fragment
svg foreignObject
#document
| "X"
#data
</desc>X
#errors
5: Stray end tag “desc”.
#document-fragment
svg desc
#document
| "X"
#data
</title>X
#errors
5: Stray end tag “title”.
#document-fragment
svg title
#document
| "X"
#data
</svg>X
#errors
5: Stray end tag “svg”.
#document-fragment
svg svg
#document
| "X"
#data
</mfenced>X
#errors
5: Stray end tag “mfenced”.
#document-fragment
math mfenced
#document
| "X"
#data
</malignmark>X
#errors
5: Stray end tag “malignmark”.
#document-fragment
math malignmark
#document
| "X"
#data
</math>X
#errors
5: Stray end tag “math”.
#document-fragment
math math
#document
| "X"
#data
</annotation-xml>X
#errors
5: Stray end tag “annotation-xml”.
#document-fragment
math annotation-xml
#document
| "X"
#data
</mtext>X
#errors
5: Stray end tag “mtext”.
#document-fragment
math mtext
#document
| "X"
#data
</mi>X
#errors
5: Stray end tag “mi”.
#document-fragment
math mi
#document
| "X"
#data
</mo>X
#errors
5: Stray end tag “mo”.
#document-fragment
math mo
#document
| "X"
#data
</mn>X
#errors
5: Stray end tag “mn”.
#document-fragment
math mn
#document
| "X"
#data
</ms>X
#errors
5: Stray end tag “ms”.
#document-fragment
math ms
#document
| "X"
#data
<b></b><mglyph/><i></i><malignmark/><u></u><ms/>X
#errors
51: Self-closing syntax (“/>”) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
52: End of file seen and there were open elements.
51: Unclosed element “ms”.
#document-fragment
math ms
#document
| <b>
| <math mglyph>
| <i>
| <math malignmark>
| <u>
| <ms>
| "X"
#data
<malignmark></malignmark>
#errors
#document-fragment
math ms
#document
| <math malignmark>
#data
<div></div>
#errors
#document-fragment
math ms
#document
| <div>
#data
<figure></figure>
#errors
#document-fragment
math ms
#document
| <figure>
#data
<b></b><mglyph/><i></i><malignmark/><u></u><mn/>X
#errors
51: Self-closing syntax (“/>”) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
52: End of file seen and there were open elements.
51: Unclosed element “mn”.
#document-fragment
math mn
#document
| <b>
| <math mglyph>
| <i>
| <math malignmark>
| <u>
| <mn>
| "X"
#data
<malignmark></malignmark>
#errors
#document-fragment
math mn
#document
| <math malignmark>
#data
<div></div>
#errors
#document-fragment
math mn
#document
| <div>
#data
<figure></figure>
#errors
#document-fragment
math mn
#document
| <figure>
#data
<b></b><mglyph/><i></i><malignmark/><u></u><mo/>X
#errors
51: Self-closing syntax (“/>”) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
52: End of file seen and there were open elements.
51: Unclosed element “mo”.
#document-fragment
math mo
#document
| <b>
| <math mglyph>
| <i>
| <math malignmark>
| <u>
| <mo>
| "X"
#data
<malignmark></malignmark>
#errors
#document-fragment
math mo
#document
| <math malignmark>
#data
<div></div>
#errors
#document-fragment
math mo
#document
| <div>
#data
<figure></figure>
#errors
#document-fragment
math mo
#document
| <figure>
#data
<b></b><mglyph/><i></i><malignmark/><u></u><mi/>X
#errors
51: Self-closing syntax (“/>”) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
52: End of file seen and there were open elements.
51: Unclosed element “mi”.
#document-fragment
math mi
#document
| <b>
| <math mglyph>
| <i>
| <math malignmark>
| <u>
| <mi>
| "X"
#data
<malignmark></malignmark>
#errors
#document-fragment
math mi
#document
| <math malignmark>
#data
<div></div>
#errors
#document-fragment
math mi
#document
| <div>
#data
<figure></figure>
#errors
#document-fragment
math mi
#document
| <figure>
#data
<b></b><mglyph/><i></i><malignmark/><u></u><mtext/>X
#errors
51: Self-closing syntax (“/>”) used on a non-void HTML element. Ignoring the slash and treating as a start tag.
52: End of file seen and there were open elements.
51: Unclosed element “mtext”.
#document-fragment
math mtext
#document
| <b>
| <math mglyph>
| <i>
| <math malignmark>
| <u>
| <mtext>
| "X"
#data
<malignmark></malignmark>
#errors
#document-fragment
math mtext
#document
| <math malignmark>
#data
<div></div>
#errors
#document-fragment
math mtext
#document
| <div>
#data
<figure></figure>
#errors
#document-fragment
math mtext
#document
| <figure>
#data
<div></div>
#errors
5: HTML start tag “div” in a foreign namespace context.
#document-fragment
math annotation-xml
#document
| <math div>
#data
<figure></figure>
#errors
#document-fragment
math annotation-xml
#document
| <math figure>
#data
<div></div>
#errors
5: HTML start tag “div” in a foreign namespace context.
#document-fragment
math math
#document
| <math div>
#data
<figure></figure>
#errors
#document-fragment
math math
#document
| <math figure>
#data
<div></div>
#errors
#document-fragment
svg foreignObject
#document
| <div>
#data
<figure></figure>
#errors
#document-fragment
svg foreignObject
#document
| <figure>
#data
<div></div>
#errors
#document-fragment
svg title
#document
| <div>
#data
<figure></figure>
#errors
#document-fragment
svg title
#document
| <figure>
#data
<figure></figure>
#errors
#document-fragment
svg desc
#document
| <figure>
#data
<div><h1>X</h1></div>
#errors
5: HTML start tag “div” in a foreign namespace context.
9: HTML start tag “h1” in a foreign namespace context.
#document-fragment
svg svg
#document
| <svg div>
| <svg h1>
| "X"
#data
<div></div>
#errors
5: HTML start tag “div” in a foreign namespace context.
#document-fragment
svg svg
#document
| <svg div>
#data
<div></div>
#errors
#document-fragment
svg desc
#document
| <div>
#data
<figure></figure>
#errors
#document-fragment
svg desc
#document
| <figure>
#data
<plaintext><foo>
#errors
16: End of file seen and there were open elements.
11: Unclosed element “plaintext”.
#document-fragment
svg desc
#document
| <plaintext>
| "<foo>"
#data
<frameset>X
#errors
6: Stray start tag “frameset”.
#document-fragment
svg desc
#document
| "X"
#data
<head>X
#errors
6: Stray start tag “head”.
#document-fragment
svg desc
#document
| "X"
#data
<body>X
#errors
6: Stray start tag “body”.
#document-fragment
svg desc
#document
| "X"
#data
<html>X
#errors
6: Stray start tag “html”.
#document-fragment
svg desc
#document
| "X"
#data
<html class="foo">X
#errors
6: Stray start tag “html”.
#document-fragment
svg desc
#document
| "X"
#data
<body class="foo">X
#errors
6: Stray start tag “body”.
#document-fragment
svg desc
#document
| "X"