From 9c14184e25ea92354b0e6f4962ad0411b1356b67 Mon Sep 17 00:00:00 2001 From: Andrew Balholm Date: Tue, 29 May 2012 13:39:54 +1000 Subject: [PATCH] exp/html: implement Noah's Ark clause 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 | 41 +++++++++++++++++++++- src/pkg/exp/html/parse_test.go | 27 ++++++++++---- src/pkg/exp/html/testlogs/isindex.dat.log | 2 +- src/pkg/exp/html/testlogs/tests19.dat.log | 6 ++-- src/pkg/exp/html/testlogs/tests23.dat.log | 8 ++--- src/pkg/exp/html/testlogs/webkit01.dat.log | 2 +- 6 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/pkg/exp/html/parse.go b/src/pkg/exp/html/parse.go index fe5f295b762..e1bfcd9aa5c 100644 --- a/src/pkg/exp/html/parse.go +++ b/src/pkg/exp/html/parse.go @@ -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. diff --git a/src/pkg/exp/html/parse_test.go b/src/pkg/exp/html/parse_test.go index f5e96f15a8e..1304f011eb1 100644 --- a/src/pkg/exp/html/parse_test.go +++ b/src/pkg/exp/html/parse_test.go @@ -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) diff --git a/src/pkg/exp/html/testlogs/isindex.dat.log b/src/pkg/exp/html/testlogs/isindex.dat.log index cd2ba3c2502..110068c54ae 100644 --- a/src/pkg/exp/html/testlogs/isindex.dat.log +++ b/src/pkg/exp/html/testlogs/isindex.dat.log @@ -1,3 +1,3 @@ PASS "" -FAIL "" +PASS "" PASS "
" diff --git a/src/pkg/exp/html/testlogs/tests19.dat.log b/src/pkg/exp/html/testlogs/tests19.dat.log index 888ceaa1653..61afadd73dd 100644 --- a/src/pkg/exp/html/testlogs/tests19.dat.log +++ b/src/pkg/exp/html/testlogs/tests19.dat.log @@ -34,8 +34,8 @@ PASS "

" PASS "

" PASS "

" PASS "" -FAIL "" -FAIL "" +PASS "" +PASS "" PASS "" PASS " " PASS "abc" @@ -83,7 +83,7 @@ PASS "

a" PASS "

a" PASS "" PASS "" -FAIL "" +PASS "" PASS "" PASS "" PASS "" diff --git a/src/pkg/exp/html/testlogs/tests23.dat.log b/src/pkg/exp/html/testlogs/tests23.dat.log index 3fcac7b1880..5eab83062e4 100644 --- a/src/pkg/exp/html/testlogs/tests23.dat.log +++ b/src/pkg/exp/html/testlogs/tests23.dat.log @@ -1,5 +1,5 @@ -FAIL "

X" -FAIL "

X" -FAIL "

X" -FAIL "

X" +PASS "

X" +PASS "

X" +PASS "

X" +PASS "

X" PASS "

X

Y" diff --git a/src/pkg/exp/html/testlogs/webkit01.dat.log b/src/pkg/exp/html/testlogs/webkit01.dat.log index 78c5f68e502..08ee7c2763a 100644 --- a/src/pkg/exp/html/testlogs/webkit01.dat.log +++ b/src/pkg/exp/html/testlogs/webkit01.dat.log @@ -11,7 +11,7 @@ PASS "" PASS "" PASS "

" PASS "

TestTest2

" -FAIL "" +PASS "" PASS "test< /A>" PASS "<" PASS ""