]> Cypherpunks repositories - gostls13.git/commitdiff
exp/html: implement Noah's Ark clause
authorAndrew Balholm <andybalholm@gmail.com>
Tue, 29 May 2012 03:39:54 +0000 (13:39 +1000)
committerNigel Tao <nigeltao@golang.org>
Tue, 29 May 2012 03:39:54 +0000 (13:39 +1000)
Implement the (3-per-family) Noah's Ark clause (i.e. don't put
more than three identical elements on the list of active formatting
elements.

Also, when running tests, sort attributes by name before dumping
them.

Pass 4 additional tests with Noah's Ark clause (including one
that needs attributes to be sorted).

Pass 5 additional, unrelated tests because of sorting attributes.

R=nigeltao, rsc
CC=golang-dev
https://golang.org/cl/6247056

src/pkg/exp/html/parse.go
src/pkg/exp/html/parse_test.go
src/pkg/exp/html/testlogs/isindex.dat.log
src/pkg/exp/html/testlogs/tests19.dat.log
src/pkg/exp/html/testlogs/tests23.dat.log
src/pkg/exp/html/testlogs/webkit01.dat.log

index fe5f295b7626c2160720d7b715c602a457f63d8f..e1bfcd9aa5c02d6a3959f219c8b7634ec2f4e295 100644 (file)
@@ -288,8 +288,47 @@ func (p *parser) addElement(tag string, attr []Attribute) {
 // Section 12.2.3.3.
 func (p *parser) addFormattingElement(tag string, attr []Attribute) {
        p.addElement(tag, attr)
+
+       // Implement the Noah's Ark clause, but with three per family instead of two.
+       identicalElements := 0
+findIdenticalElements:
+       for i := len(p.afe) - 1; i >= 0; i-- {
+               n := p.afe[i]
+               if n.Type == scopeMarkerNode {
+                       break
+               }
+               if n.Type != ElementNode {
+                       continue
+               }
+               if n.Namespace != "" {
+                       continue
+               }
+               if n.Data != tag {
+                       continue
+               }
+               if len(n.Attr) != len(attr) {
+                       continue
+               }
+       compareAttributes:
+               for _, a := range n.Attr {
+                       for _, b := range attr {
+                               if a.Key == b.Key && a.Namespace == b.Namespace && a.Val == b.Val {
+                                       // Found a match for this attribute, continue with the next attribute.
+                                       continue compareAttributes
+                               }
+                       }
+                       // If we get here, there is no attribute that matches a.
+                       // Therefore the element is not identical to the new one.
+                       continue findIdenticalElements
+               }
+
+               identicalElements++
+               if identicalElements >= 3 {
+                       p.afe.remove(n)
+               }
+       }
+
        p.afe = append(p.afe, p.top())
-       // TODO.
 }
 
 // Section 12.2.3.3.
index f5e96f15a8e054ac30ebabc8b719f375fad261c4..1304f011eb10b387b7c030ffcb4bff688b344169 100644 (file)
@@ -13,6 +13,7 @@ import (
        "io"
        "os"
        "path/filepath"
+       "sort"
        "strings"
        "testing"
 )
@@ -104,6 +105,23 @@ func dumpIndent(w io.Writer, level int) {
        }
 }
 
+type sortedAttributes []Attribute
+
+func (a sortedAttributes) Len() int {
+       return len(a)
+}
+
+func (a sortedAttributes) Less(i, j int) bool {
+       if a[i].Namespace != a[j].Namespace {
+               return a[i].Namespace < a[j].Namespace
+       }
+       return a[i].Key < a[j].Key
+}
+
+func (a sortedAttributes) Swap(i, j int) {
+       a[i], a[j] = a[j], a[i]
+}
+
 func dumpLevel(w io.Writer, n *Node, level int) error {
        dumpIndent(w, level)
        switch n.Type {
@@ -117,13 +135,8 @@ func dumpLevel(w io.Writer, n *Node, level int) error {
                } else {
                        fmt.Fprintf(w, "<%s>", n.Data)
                }
-               attr := n.Attr
-               if len(attr) == 2 && attr[0].Namespace == "xml" && attr[1].Namespace == "xlink" {
-                       // Some of the test cases in tests10.dat change the order of adjusted
-                       // foreign attributes, but that behavior is not in the spec, and could
-                       // simply be an implementation detail of html5lib's python map ordering.
-                       attr[0], attr[1] = attr[1], attr[0]
-               }
+               attr := sortedAttributes(n.Attr)
+               sort.Sort(attr)
                for _, a := range attr {
                        io.WriteString(w, "\n")
                        dumpIndent(w, level+1)
index cd2ba3c250245fc322f87f7923f0593ff80a4755..110068c54ae22b163b352eff746f6f34e94985f0 100644 (file)
@@ -1,3 +1,3 @@
 PASS "<isindex>"
-FAIL "<isindex name=\"A\" action=\"B\" prompt=\"C\" foo=\"D\">"
+PASS "<isindex name=\"A\" action=\"B\" prompt=\"C\" foo=\"D\">"
 PASS "<form><isindex>"
index 888ceaa1653326d1a34c7a60a733130a94e2dc76..61afadd73ddddbd98526b873f4242b7aa3d520cf 100644 (file)
@@ -34,8 +34,8 @@ PASS "<!doctype html><p><math><mn><p><h1>"
 PASS "<!doctype html><p><math><ms><p><h1>"
 PASS "<!doctype html><p><math><mtext><p><h1>"
 PASS "<!doctype html><frameset></noframes>"
-FAIL "<!doctype html><html c=d><body></html><html a=b>"
-FAIL "<!doctype html><html c=d><frameset></frameset></html><html a=b>"
+PASS "<!doctype html><html c=d><body></html><html a=b>"
+PASS "<!doctype html><html c=d><frameset></frameset></html><html a=b>"
 PASS "<!doctype html><html><frameset></frameset></html><!--foo-->"
 PASS "<!doctype html><html><frameset></frameset></html>  "
 PASS "<!doctype html><html><frameset></frameset></html>abc"
@@ -83,7 +83,7 @@ PASS "<!doctype html><p><math></p>a"
 PASS "<!doctype html><p><math><mn><span></p>a"
 PASS "<!doctype html><math></html>"
 PASS "<!doctype html><meta charset=\"ascii\">"
-FAIL "<!doctype html><meta http-equiv=\"content-type\" content=\"text/html;charset=ascii\">"
+PASS "<!doctype html><meta http-equiv=\"content-type\" content=\"text/html;charset=ascii\">"
 PASS "<!doctype html><head><!--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--><meta charset=\"utf8\">"
 PASS "<!doctype html><html a=b><head></head><html c=d>"
 PASS "<!doctype html><image/>"
index 3fcac7b1880554b4136ae907be3e264f402848ee..5eab83062e442b7d2c77a8e6cc4e617fa7a10e87 100644 (file)
@@ -1,5 +1,5 @@
-FAIL "<p><font size=4><font color=red><font size=4><font size=4><font size=4><font size=4><font size=4><font color=red><p>X"
-FAIL "<p><font size=4><font size=4><font size=4><font size=4><p>X"
-FAIL "<p><font size=4><font size=4><font size=4><font size=\"5\"><font size=4><p>X"
-FAIL "<p><font size=4 id=a><font size=4 id=b><font size=4><font size=4><p>X"
+PASS "<p><font size=4><font color=red><font size=4><font size=4><font size=4><font size=4><font size=4><font color=red><p>X"
+PASS "<p><font size=4><font size=4><font size=4><font size=4><p>X"
+PASS "<p><font size=4><font size=4><font size=4><font size=\"5\"><font size=4><p>X"
+PASS "<p><font size=4 id=a><font size=4 id=b><font size=4><font size=4><p>X"
 PASS "<p><b id=a><b id=a><b id=a><b><object><b id=a><b id=a>X</object><p>Y"
index 78c5f68e502f05adc8419ccd2cbc26e0fa9c0206..08ee7c2763a76c17ae3f701ac3f042004a68a8e3 100644 (file)
@@ -11,7 +11,7 @@ PASS "<foo></foo bar=\"baz\"><potato></potato quack=\"duck\">"
 PASS "</ tttt>"
 PASS "<div FOO ><img><img></div>"
 PASS "<p>Test</p<p>Test2</p>"
-FAIL "<rdar://problem/6869687>"
+PASS "<rdar://problem/6869687>"
 PASS "<A>test< /A>"
 PASS "&lt;"
 PASS "<body foo='bar'><body foo='baz' yo='mama'>"