Skip to content

Commit

Permalink
html: implement adjusted current node and make parser support foreign…
Browse files Browse the repository at this point in the history
… 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>
  • Loading branch information
namusyaka authored and nigeltao committed Nov 25, 2019
1 parent 72fef5d commit ffdde10
Show file tree
Hide file tree
Showing 3 changed files with 593 additions and 23 deletions.
55 changes: 35 additions & 20 deletions html/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand All @@ -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 != "" {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -2364,14 +2375,18 @@ func ParseFragmentWithOptions(r io.Reader, context *Node, opts ...ParseOption) (
contextTag = context.DataAtom.String()
}
p := &parser{
tokenizer: NewTokenizerFragment(r, contextTag),
doc: &Node{
Type: DocumentNode,
},
scripting: true,
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)
Expand Down
11 changes: 8 additions & 3 deletions html/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit ffdde10

Please sign in to comment.