]> Cypherpunks repositories - gostls13.git/commitdiff
html: parse <body>, <base>, <link>, <meta>, and <title> tags inside page body
authorAndrew Balholm <andybalholm@gmail.com>
Tue, 8 Nov 2011 06:55:17 +0000 (17:55 +1100)
committerNigel Tao <nigeltao@golang.org>
Tue, 8 Nov 2011 06:55:17 +0000 (17:55 +1100)
Pass tests1.dat, test 87:
<body><body><base><link><meta><title><p></title><body><p></body>

| <html>
|   <head>
|   <body>
|     <base>
|     <link>
|     <meta>
|     <title>
|       "<p>"
|     <p>

Handling the last <body> tag requires correcting the original insertion mode in useTheRulesFor.

Also pass test 88:
<textarea><p></textarea>

R=nigeltao
CC=golang-dev
https://golang.org/cl/5364047

src/pkg/html/parse.go
src/pkg/html/parse_test.go

index fae0975d376cab67a70d6a4f604574f83634cb86..c6c96e50e0d1465180799edab83b5fdfbe3012f9 100644 (file)
@@ -275,7 +275,9 @@ type insertionMode func(*parser) (insertionMode, bool)
 // Section 11.2.3.1, "using the rules for".
 func useTheRulesFor(p *parser, actual, delegate insertionMode) (insertionMode, bool) {
        im, consumed := delegate(p)
-       // TODO: do we need to update p.originalMode if it equals delegate?
+       if p.originalIM == delegate {
+               p.originalIM = actual
+       }
        if im != delegate {
                return im, consumed
        }
@@ -537,6 +539,23 @@ func afterHeadIM(p *parser) (insertionMode, bool) {
        return inBodyIM, !implied
 }
 
+// copyAttributes copies attributes of src not found on dst to dst.
+func copyAttributes(dst *Node, src Token) {
+       if len(src.Attr) == 0 {
+               return
+       }
+       attr := map[string]string{}
+       for _, a := range dst.Attr {
+               attr[a.Key] = a.Val
+       }
+       for _, a := range src.Attr {
+               if _, ok := attr[a.Key]; !ok {
+                       dst.Attr = append(dst.Attr, a)
+                       attr[a.Key] = a.Val
+               }
+       }
+}
+
 // Section 11.2.5.4.7.
 func inBodyIM(p *parser) (insertionMode, bool) {
        switch p.tok.Type {
@@ -622,6 +641,16 @@ func inBodyIM(p *parser) (insertionMode, bool) {
                        }
                        p.reconstructActiveFormattingElements()
                        p.addElement(p.tok.Data, p.tok.Attr)
+               case "body":
+                       if len(p.oe) >= 2 {
+                               body := p.oe[1]
+                               if body.Type == ElementNode && body.Data == "body" {
+                                       p.framesetOK = false
+                                       copyAttributes(body, p.tok)
+                               }
+                       }
+               case "base", "basefont", "bgsound", "command", "link", "meta", "noframes", "script", "style", "title":
+                       return useTheRulesFor(p, inBodyIM, inHeadIM)
                default:
                        // TODO.
                        p.addElement(p.tok.Data, p.tok.Attr)
index c938cb9e697ca14859758fa9d81aa403bde02e72..1f4ffa9564bcd48b86d039016e1e9d5bc18bc4f2 100644 (file)
@@ -133,7 +133,7 @@ func TestParser(t *testing.T) {
                n int
        }{
                // TODO(nigeltao): Process all the test cases from all the .dat files.
-               {"tests1.dat", 87},
+               {"tests1.dat", 89},
                {"tests2.dat", 0},
                {"tests3.dat", 0},
        }