Skip to content

Commit ffdde10

Browse files
namusyakanigeltao
authored andcommitted
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Nigel Tao <[email protected]>
1 parent 72fef5d commit ffdde10

File tree

3 files changed

+593
-23
lines changed

3 files changed

+593
-23
lines changed

html/parse.go

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,28 +2136,31 @@ func parseForeignContent(p *parser) bool {
21362136
Data: p.tok.Data,
21372137
})
21382138
case StartTagToken:
2139-
b := breakout[p.tok.Data]
2140-
if p.tok.DataAtom == a.Font {
2141-
loop:
2142-
for _, attr := range p.tok.Attr {
2143-
switch attr.Key {
2144-
case "color", "face", "size":
2145-
b = true
2146-
break loop
2139+
if !p.fragment {
2140+
b := breakout[p.tok.Data]
2141+
if p.tok.DataAtom == a.Font {
2142+
loop:
2143+
for _, attr := range p.tok.Attr {
2144+
switch attr.Key {
2145+
case "color", "face", "size":
2146+
b = true
2147+
break loop
2148+
}
21472149
}
21482150
}
2149-
}
2150-
if b {
2151-
for i := len(p.oe) - 1; i >= 0; i-- {
2152-
n := p.oe[i]
2153-
if n.Namespace == "" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {
2154-
p.oe = p.oe[:i+1]
2155-
break
2151+
if b {
2152+
for i := len(p.oe) - 1; i >= 0; i-- {
2153+
n := p.oe[i]
2154+
if n.Namespace == "" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {
2155+
p.oe = p.oe[:i+1]
2156+
break
2157+
}
21562158
}
2159+
return false
21572160
}
2158-
return false
21592161
}
2160-
switch p.top().Namespace {
2162+
current := p.adjustedCurrentNode()
2163+
switch current.Namespace {
21612164
case "math":
21622165
adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
21632166
case "svg":
@@ -2172,7 +2175,7 @@ func parseForeignContent(p *parser) bool {
21722175
panic("html: bad parser state: unexpected namespace")
21732176
}
21742177
adjustForeignAttributes(p.tok.Attr)
2175-
namespace := p.top().Namespace
2178+
namespace := current.Namespace
21762179
p.addElement()
21772180
p.top().Namespace = namespace
21782181
if namespace != "" {
@@ -2201,12 +2204,20 @@ func parseForeignContent(p *parser) bool {
22012204
return true
22022205
}
22032206

2207+
// Section 12.2.4.2.
2208+
func (p *parser) adjustedCurrentNode() *Node {
2209+
if len(p.oe) == 1 && p.fragment && p.context != nil {
2210+
return p.context
2211+
}
2212+
return p.oe.top()
2213+
}
2214+
22042215
// Section 12.2.6.
22052216
func (p *parser) inForeignContent() bool {
22062217
if len(p.oe) == 0 {
22072218
return false
22082219
}
2209-
n := p.oe[len(p.oe)-1]
2220+
n := p.adjustedCurrentNode()
22102221
if n.Namespace == "" {
22112222
return false
22122223
}
@@ -2364,14 +2375,18 @@ func ParseFragmentWithOptions(r io.Reader, context *Node, opts ...ParseOption) (
23642375
contextTag = context.DataAtom.String()
23652376
}
23662377
p := &parser{
2367-
tokenizer: NewTokenizerFragment(r, contextTag),
23682378
doc: &Node{
23692379
Type: DocumentNode,
23702380
},
23712381
scripting: true,
23722382
fragment: true,
23732383
context: context,
23742384
}
2385+
if context != nil && context.Namespace != "" {
2386+
p.tokenizer = NewTokenizer(r)
2387+
} else {
2388+
p.tokenizer = NewTokenizerFragment(r, contextTag)
2389+
}
23752390

23762391
for _, f := range opts {
23772392
f(p)

html/parse_test.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,10 +307,15 @@ func testParseCase(text, want, context string, opts ...ParseOption) (err error)
307307
return err
308308
}
309309
} else {
310+
namespace := ""
311+
if i := strings.IndexByte(context, ' '); i >= 0 {
312+
namespace, context = context[:i], context[i+1:]
313+
}
310314
contextNode := &Node{
311-
Type: ElementNode,
312-
DataAtom: atom.Lookup([]byte(context)),
313-
Data: context,
315+
Data: context,
316+
DataAtom: atom.Lookup([]byte(context)),
317+
Namespace: namespace,
318+
Type: ElementNode,
314319
}
315320
nodes, err := ParseFragmentWithOptions(strings.NewReader(text), contextNode, opts...)
316321
if err != nil {

0 commit comments

Comments
 (0)