]> Cypherpunks repositories - gostls13.git/commitdiff
exp/html: simplify some of the parser's internal methods.
authorNigel Tao <nigeltao@golang.org>
Wed, 13 Jun 2012 00:13:05 +0000 (10:13 +1000)
committerNigel Tao <nigeltao@golang.org>
Wed, 13 Jun 2012 00:13:05 +0000 (10:13 +1000)
benchmark          old ns/op    new ns/op    delta
BenchmarkParser      4006888      3950604   -1.40%

R=r, andybalholm
CC=golang-dev
https://golang.org/cl/6301070

src/pkg/exp/html/parse.go

index 6f09745a10493c86f9e3484a0303ad48ef22cca9..70c26c75f5d0d09e4a1b231ea14ba1b61d1186a0 100644 (file)
@@ -279,21 +279,30 @@ func (p *parser) addText(text string) {
        })
 }
 
-// addElement calls addChild with an element node.
-// TODO: tagAtom, tag and attr are almost always p.tok.DataAtom, p.tok.Data, p.tok.Attr.
-// The common case should be a no-arg addElement method.
-func (p *parser) addElement(tagAtom a.Atom, tag string, attr []Attribute) {
+// addElement adds a child element based on the current token.
+func (p *parser) addElement() {
+       p.addChild(&Node{
+               Type:     ElementNode,
+               DataAtom: p.tok.DataAtom,
+               Data:     p.tok.Data,
+               Attr:     p.tok.Attr,
+       })
+}
+
+// addSyntheticElement adds a child element with the given tag and attributes.
+func (p *parser) addSyntheticElement(tagAtom a.Atom, attr []Attribute) {
        p.addChild(&Node{
                Type:     ElementNode,
                DataAtom: tagAtom,
-               Data:     tag,
+               Data:     tagAtom.String(),
                Attr:     attr,
        })
 }
 
 // Section 12.2.3.3.
-func (p *parser) addFormattingElement(tagAtom a.Atom, tag string, attr []Attribute) {
-       p.addElement(tagAtom, tag, attr)
+func (p *parser) addFormattingElement() {
+       tagAtom, attr := p.tok.DataAtom, p.tok.Attr
+       p.addElement()
 
        // Implement the Noah's Ark clause, but with three per family instead of two.
        identicalElements := 0
@@ -309,7 +318,7 @@ findIdenticalElements:
                if n.Namespace != "" {
                        continue
                }
-               if n.Data != tag {
+               if n.DataAtom != tagAtom {
                        continue
                }
                if len(n.Attr) != len(attr) {
@@ -489,14 +498,14 @@ func beforeHTMLIM(p *parser) bool {
                }
        case StartTagToken:
                if p.tok.DataAtom == a.Html {
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.im = beforeHeadIM
                        return true
                }
        case EndTagToken:
                switch p.tok.DataAtom {
                case a.Head, a.Body, a.Html, a.Br:
-                       p.parseImpliedToken(StartTagToken, a.Html, a.Html.String(), nil)
+                       p.parseImpliedToken(StartTagToken, a.Html, a.Html.String())
                        return false
                default:
                        // Ignore the token.
@@ -509,7 +518,7 @@ func beforeHTMLIM(p *parser) bool {
                })
                return true
        }
-       p.parseImpliedToken(StartTagToken, a.Html, a.Html.String(), nil)
+       p.parseImpliedToken(StartTagToken, a.Html, a.Html.String())
        return false
 }
 
@@ -525,7 +534,7 @@ func beforeHeadIM(p *parser) bool {
        case StartTagToken:
                switch p.tok.DataAtom {
                case a.Head:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.head = p.top()
                        p.im = inHeadIM
                        return true
@@ -535,7 +544,7 @@ func beforeHeadIM(p *parser) bool {
        case EndTagToken:
                switch p.tok.DataAtom {
                case a.Head, a.Body, a.Html, a.Br:
-                       p.parseImpliedToken(StartTagToken, a.Head, a.Head.String(), nil)
+                       p.parseImpliedToken(StartTagToken, a.Head, a.Head.String())
                        return false
                default:
                        // Ignore the token.
@@ -552,7 +561,7 @@ func beforeHeadIM(p *parser) bool {
                return true
        }
 
-       p.parseImpliedToken(StartTagToken, a.Head, a.Head.String(), nil)
+       p.parseImpliedToken(StartTagToken, a.Head, a.Head.String())
        return false
 }
 
@@ -574,12 +583,12 @@ func inHeadIM(p *parser) bool {
                case a.Html:
                        return inBodyIM(p)
                case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.oe.pop()
                        p.acknowledgeSelfClosingTag()
                        return true
                case a.Script, a.Title, a.Noscript, a.Noframes, a.Style:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.setOriginalIM()
                        p.im = textIM
                        return true
@@ -597,7 +606,7 @@ func inHeadIM(p *parser) bool {
                        p.im = afterHeadIM
                        return true
                case a.Body, a.Html, a.Br:
-                       p.parseImpliedToken(EndTagToken, a.Head, a.Head.String(), nil)
+                       p.parseImpliedToken(EndTagToken, a.Head, a.Head.String())
                        return false
                default:
                        // Ignore the token.
@@ -614,7 +623,7 @@ func inHeadIM(p *parser) bool {
                return true
        }
 
-       p.parseImpliedToken(EndTagToken, a.Head, a.Head.String(), nil)
+       p.parseImpliedToken(EndTagToken, a.Head, a.Head.String())
        return false
 }
 
@@ -636,12 +645,12 @@ func afterHeadIM(p *parser) bool {
                case a.Html:
                        return inBodyIM(p)
                case a.Body:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.framesetOK = false
                        p.im = inBodyIM
                        return true
                case a.Frameset:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.im = inFramesetIM
                        return true
                case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
@@ -671,7 +680,7 @@ func afterHeadIM(p *parser) bool {
                return true
        }
 
-       p.parseImpliedToken(StartTagToken, a.Body, a.Body.String(), nil)
+       p.parseImpliedToken(StartTagToken, a.Body, a.Body.String())
        p.framesetOK = true
        return false
 }
@@ -741,28 +750,28 @@ func inBodyIM(p *parser) bool {
                                body.Parent.Remove(body)
                        }
                        p.oe = p.oe[:1]
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.im = inFramesetIM
                        return true
                case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
                        p.popUntil(buttonScope, a.P)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
                        p.popUntil(buttonScope, a.P)
                        switch n := p.top(); n.DataAtom {
                        case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
                                p.oe.pop()
                        }
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                case a.Pre, a.Listing:
                        p.popUntil(buttonScope, a.P)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        // The newline, if any, will be dealt with by the TextToken case.
                        p.framesetOK = false
                case a.Form:
                        if p.form == nil {
                                p.popUntil(buttonScope, a.P)
-                               p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                               p.addElement()
                                p.form = p.top()
                        }
                case a.Li:
@@ -782,7 +791,7 @@ func inBodyIM(p *parser) bool {
                                break
                        }
                        p.popUntil(buttonScope, a.P)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                case a.Dd, a.Dt:
                        p.framesetOK = false
                        for i := len(p.oe) - 1; i >= 0; i-- {
@@ -800,14 +809,14 @@ func inBodyIM(p *parser) bool {
                                break
                        }
                        p.popUntil(buttonScope, a.P)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                case a.Plaintext:
                        p.popUntil(buttonScope, a.P)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                case a.Button:
                        p.popUntil(defaultScope, a.Button)
                        p.reconstructActiveFormattingElements()
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.framesetOK = false
                case a.A:
                        for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {
@@ -819,33 +828,33 @@ func inBodyIM(p *parser) bool {
                                }
                        }
                        p.reconstructActiveFormattingElements()
-                       p.addFormattingElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addFormattingElement()
                case a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
                        p.reconstructActiveFormattingElements()
-                       p.addFormattingElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addFormattingElement()
                case a.Nobr:
                        p.reconstructActiveFormattingElements()
                        if p.elementInScope(defaultScope, a.Nobr) {
                                p.inBodyEndTagFormatting(a.Nobr)
                                p.reconstructActiveFormattingElements()
                        }
-                       p.addFormattingElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addFormattingElement()
                case a.Applet, a.Marquee, a.Object:
                        p.reconstructActiveFormattingElements()
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.afe = append(p.afe, &scopeMarker)
                        p.framesetOK = false
                case a.Table:
                        if !p.quirks {
                                p.popUntil(buttonScope, a.P)
                        }
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.framesetOK = false
                        p.im = inTableIM
                        return true
                case a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:
                        p.reconstructActiveFormattingElements()
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.oe.pop()
                        p.acknowledgeSelfClosingTag()
                        if p.tok.DataAtom == a.Input {
@@ -860,12 +869,12 @@ func inBodyIM(p *parser) bool {
                        }
                        p.framesetOK = false
                case a.Param, a.Source, a.Track:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.oe.pop()
                        p.acknowledgeSelfClosingTag()
                case a.Hr:
                        p.popUntil(buttonScope, a.P)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.oe.pop()
                        p.acknowledgeSelfClosingTag()
                        p.framesetOK = false
@@ -895,24 +904,24 @@ func inBodyIM(p *parser) bool {
                        }
                        p.acknowledgeSelfClosingTag()
                        p.popUntil(buttonScope, a.P)
-                       p.addElement(a.Form, a.Form.String(), nil)
+                       p.addSyntheticElement(a.Form, nil)
                        p.form = p.top()
                        if action != "" {
                                p.form.Attr = []Attribute{{Key: "action", Val: action}}
                        }
-                       p.addElement(a.Hr, a.Hr.String(), nil)
+                       p.addSyntheticElement(a.Hr, nil)
                        p.oe.pop()
-                       p.addElement(a.Label, a.Label.String(), nil)
+                       p.addSyntheticElement(a.Label, nil)
                        p.addText(prompt)
-                       p.addElement(a.Input, a.Input.String(), attr)
+                       p.addSyntheticElement(a.Input, attr)
                        p.oe.pop()
                        p.oe.pop()
-                       p.addElement(a.Hr, a.Hr.String(), nil)
+                       p.addSyntheticElement(a.Hr, nil)
                        p.oe.pop()
                        p.oe.pop()
                        p.form = nil
                case a.Textarea:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.setOriginalIM()
                        p.framesetOK = false
                        p.im = textIM
@@ -920,21 +929,21 @@ func inBodyIM(p *parser) bool {
                        p.popUntil(buttonScope, a.P)
                        p.reconstructActiveFormattingElements()
                        p.framesetOK = false
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.setOriginalIM()
                        p.im = textIM
                case a.Iframe:
                        p.framesetOK = false
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.setOriginalIM()
                        p.im = textIM
                case a.Noembed, a.Noscript:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.setOriginalIM()
                        p.im = textIM
                case a.Select:
                        p.reconstructActiveFormattingElements()
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.framesetOK = false
                        p.im = inSelectIM
                        return true
@@ -943,12 +952,12 @@ func inBodyIM(p *parser) bool {
                                p.oe.pop()
                        }
                        p.reconstructActiveFormattingElements()
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                case a.Rp, a.Rt:
                        if p.elementInScope(defaultScope, a.Ruby) {
                                p.generateImpliedEndTags()
                        }
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                case a.Math, a.Svg:
                        p.reconstructActiveFormattingElements()
                        if p.tok.DataAtom == a.Math {
@@ -957,14 +966,14 @@ func inBodyIM(p *parser) bool {
                                adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)
                        }
                        adjustForeignAttributes(p.tok.Attr)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.top().Namespace = p.tok.Data
                        return true
                case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
                        // Ignore the token.
                default:
                        p.reconstructActiveFormattingElements()
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                }
        case EndTagToken:
                switch p.tok.DataAtom {
@@ -974,7 +983,7 @@ func inBodyIM(p *parser) bool {
                        }
                case a.Html:
                        if p.elementInScope(defaultScope, a.Body) {
-                               p.parseImpliedToken(EndTagToken, a.Body, a.Body.String(), nil)
+                               p.parseImpliedToken(EndTagToken, a.Body, a.Body.String())
                                return false
                        }
                        return true
@@ -992,7 +1001,7 @@ func inBodyIM(p *parser) bool {
                        p.oe.remove(node)
                case a.P:
                        if !p.elementInScope(buttonScope, a.P) {
-                               p.addElement(a.P, a.P.String(), nil)
+                               p.addSyntheticElement(a.P, nil)
                        }
                        p.popUntil(buttonScope, a.P)
                case a.Li:
@@ -1209,24 +1218,24 @@ func inTableIM(p *parser) bool {
                case a.Caption:
                        p.clearStackToContext(tableScope)
                        p.afe = append(p.afe, &scopeMarker)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.im = inCaptionIM
                        return true
                case a.Colgroup:
                        p.clearStackToContext(tableScope)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.im = inColumnGroupIM
                        return true
                case a.Col:
-                       p.parseImpliedToken(StartTagToken, a.Colgroup, a.Colgroup.String(), nil)
+                       p.parseImpliedToken(StartTagToken, a.Colgroup, a.Colgroup.String())
                        return false
                case a.Tbody, a.Tfoot, a.Thead:
                        p.clearStackToContext(tableScope)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.im = inTableBodyIM
                        return true
                case a.Td, a.Th, a.Tr:
-                       p.parseImpliedToken(StartTagToken, a.Tbody, a.Tbody.String(), nil)
+                       p.parseImpliedToken(StartTagToken, a.Tbody, a.Tbody.String())
                        return false
                case a.Table:
                        if p.popUntil(tableScope, a.Table) {
@@ -1240,7 +1249,7 @@ func inTableIM(p *parser) bool {
                case a.Input:
                        for _, t := range p.tok.Attr {
                                if t.Key == "type" && strings.ToLower(t.Val) == "hidden" {
-                                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                                       p.addElement()
                                        p.oe.pop()
                                        return true
                                }
@@ -1251,7 +1260,7 @@ func inTableIM(p *parser) bool {
                                // Ignore the token.
                                return true
                        }
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.form = p.oe.pop()
                case a.Select:
                        p.reconstructActiveFormattingElements()
@@ -1259,7 +1268,7 @@ func inTableIM(p *parser) bool {
                        case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
                                p.fosterParenting = true
                        }
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.fosterParenting = false
                        p.framesetOK = false
                        p.im = inSelectInTableIM
@@ -1314,7 +1323,7 @@ func inCaptionIM(p *parser) bool {
                        }
                case a.Select:
                        p.reconstructActiveFormattingElements()
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.framesetOK = false
                        p.im = inSelectInTableIM
                        return true
@@ -1371,7 +1380,7 @@ func inColumnGroupIM(p *parser) bool {
                case a.Html:
                        return inBodyIM(p)
                case a.Col:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.oe.pop()
                        p.acknowledgeSelfClosingTag()
                        return true
@@ -1404,11 +1413,11 @@ func inTableBodyIM(p *parser) bool {
                switch p.tok.DataAtom {
                case a.Tr:
                        p.clearStackToContext(tableBodyScope)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.im = inRowIM
                        return true
                case a.Td, a.Th:
-                       p.parseImpliedToken(StartTagToken, a.Tr, a.Tr.String(), nil)
+                       p.parseImpliedToken(StartTagToken, a.Tr, a.Tr.String())
                        return false
                case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead:
                        if p.popUntil(tableScope, a.Tbody, a.Thead, a.Tfoot) {
@@ -1456,7 +1465,7 @@ func inRowIM(p *parser) bool {
                switch p.tok.DataAtom {
                case a.Td, a.Th:
                        p.clearStackToContext(tableRowScope)
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.afe = append(p.afe, &scopeMarker)
                        p.im = inCellIM
                        return true
@@ -1486,7 +1495,7 @@ func inRowIM(p *parser) bool {
                        return true
                case a.Tbody, a.Tfoot, a.Thead:
                        if p.elementInScope(tableScope, p.tok.DataAtom) {
-                               p.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String(), nil)
+                               p.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String())
                                return false
                        }
                        // Ignore the token.
@@ -1516,7 +1525,7 @@ func inCellIM(p *parser) bool {
                        return true
                case a.Select:
                        p.reconstructActiveFormattingElements()
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.framesetOK = false
                        p.im = inSelectInTableIM
                        return true
@@ -1565,7 +1574,7 @@ func inSelectIM(p *parser) bool {
                        if p.top().DataAtom == a.Option {
                                p.oe.pop()
                        }
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                case a.Optgroup:
                        if p.top().DataAtom == a.Option {
                                p.oe.pop()
@@ -1573,13 +1582,13 @@ func inSelectIM(p *parser) bool {
                        if p.top().DataAtom == a.Optgroup {
                                p.oe.pop()
                        }
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                case a.Select:
                        p.tok.Type = EndTagToken
                        return false
                case a.Input, a.Keygen, a.Textarea:
                        if p.elementInScope(selectScope, a.Select) {
-                               p.parseImpliedToken(EndTagToken, a.Select, a.Select.String(), nil)
+                               p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
                                return false
                        }
                        // Ignore the token.
@@ -1626,7 +1635,7 @@ func inSelectInTableIM(p *parser) bool {
                switch p.tok.DataAtom {
                case a.Caption, a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr, a.Td, a.Th:
                        if p.tok.Type == StartTagToken || p.elementInScope(tableScope, p.tok.DataAtom) {
-                               p.parseImpliedToken(EndTagToken, a.Select, a.Select.String(), nil)
+                               p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
                                return false
                        } else {
                                // Ignore the token.
@@ -1698,9 +1707,9 @@ func inFramesetIM(p *parser) bool {
                case a.Html:
                        return inBodyIM(p)
                case a.Frameset:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                case a.Frame:
-                       p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+                       p.addElement()
                        p.oe.pop()
                        p.acknowledgeSelfClosingTag()
                case a.Noframes:
@@ -1879,7 +1888,7 @@ func parseForeignContent(p *parser) bool {
                }
                adjustForeignAttributes(p.tok.Attr)
                namespace := p.top().Namespace
-               p.addElement(p.tok.DataAtom, p.tok.Data, p.tok.Attr)
+               p.addElement()
                p.top().Namespace = namespace
                if p.hasSelfClosingToken {
                        p.oe.pop()
@@ -1933,13 +1942,12 @@ func (p *parser) inForeignContent() bool {
 
 // parseImpliedToken parses a token as though it had appeared in the parser's
 // input.
-func (p *parser) parseImpliedToken(t TokenType, dataAtom a.Atom, data string, attr []Attribute) {
+func (p *parser) parseImpliedToken(t TokenType, dataAtom a.Atom, data string) {
        realToken, selfClosing := p.tok, p.hasSelfClosingToken
        p.tok = Token{
                Type:     t,
                DataAtom: dataAtom,
                Data:     data,
-               Attr:     attr,
        }
        p.hasSelfClosingToken = false
        p.parseCurrentToken()
@@ -1965,7 +1973,7 @@ func (p *parser) parseCurrentToken() {
 
        if p.hasSelfClosingToken {
                p.hasSelfClosingToken = false
-               p.parseImpliedToken(EndTagToken, p.tok.DataAtom, p.tok.Data, nil)
+               p.parseImpliedToken(EndTagToken, p.tok.DataAtom, p.tok.Data)
        }
 }