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
// 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.
"io"
"os"
"path/filepath"
+ "sort"
"strings"
"testing"
)
}
}
+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 {
} 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)
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>"
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"
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/>"
-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"
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 "<"
PASS "<body foo='bar'><body foo='baz' yo='mama'>"