Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /**
7 * A test suite that runs WHATWG HTML parser tests.
8 * The tests are from html5lib.
9 *
10 * http://html5lib.googlecode.com/
11 */
13 /**
14 * A few utility functions.
15 */
16 function log(entry) {
18 }
20 function startsWith(s, s2) {
21 return s.indexOf(s2)==0;
22 }
24 function trimString(s) {
25 return(s.replace(/^\s+/,'').replace(/\s+$/,''));
26 }
28 /**
29 * Parses an individual testcase into an array containing the input
30 * string, a string representing the expected tree (DOM), and a list
31 * of error messages.
32 *
33 * @param A string containing a single testcase
34 */
35 function parseTestcase(testcase) {
36 var lines = testcase.split("\n");
38 /* check that the first non-empty, non-comment line is #data */
39 for each (var line in lines) {
40 if (!line || startsWith(line, "##")) {
41 continue;
42 }
43 if (line == "#data")
44 break;
45 log(lines);
46 throw "Unknown test format."
47 }
49 var input = [];
50 var output = [];
51 var errors = [];
52 var fragment = [];
53 var currentList = input;
54 for each (var line in lines) {
55 if (startsWith(line, "##todo")) {
56 todo(false, line.substring(6));
57 continue;
58 }
59 if (!(startsWith(line, "#error") ||
60 startsWith(line, "#document") ||
61 startsWith(line, "#document-fragment") ||
62 startsWith(line, "#data"))) {
63 currentList.push(line);
64 } else if (line == "#errors") {
65 currentList = errors;
66 } else if (line == "#document") {
67 currentList = output;
68 } else if (line == "#document-fragment") {
69 currentList = fragment;
70 }
71 }
72 while (!output[output.length - 1]) {
73 output.pop(); // zap trailing blank lines
74 }
75 //logger.log(input.length, output.length, errors.length);
76 return [input.join("\n"), output.join("\n"), errors, fragment[0]];
77 }
79 /**
80 * A generator function that accepts a list of strings. Each list
81 * member corresponds to the contents of a ".dat" file from the
82 * html5lib test suite.
83 *
84 * @param The list of strings
85 */
86 function test_parser(testlist) {
87 for each (var testgroup in testlist) {
88 var tests = testgroup.split("#data\n");
89 tests = ["#data\n" + test for each(test in tests) if (test)];
90 for each (var test in tests) {
91 yield parseTestcase(test);
92 }
93 }
94 }
96 /**
97 * Transforms a DOM document to a string matching the format in
98 * the test cases.
99 *
100 * @param the DOM document
101 */
102 function docToTestOutput(doc) {
103 var walker = doc.createTreeWalker(doc, NodeFilter.SHOW_ALL, null);
104 return addLevels(walker, "", "| ").slice(0,-1); // remove the last newline
105 }
107 /**
108 * Creates a walker for a fragment that skips over the root node.
109 *
110 * @param an element
111 */
112 function createFragmentWalker(elt) {
113 return elt.ownerDocument.createTreeWalker(elt, NodeFilter.SHOW_ALL,
114 function (node) {
115 return elt == node ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT;
116 });
117 }
119 /**
120 * Transforms the descendants of an element to a string matching the format
121 * in the test cases.
122 *
123 * @param an element
124 */
125 function fragmentToTestOutput(elt) {
126 var walker = createFragmentWalker(elt);
127 return addLevels(walker, "", "| ").slice(0,-1); // remove the last newline
128 }
130 function addLevels(walker, buf, indent) {
131 if(walker.firstChild()) {
132 do {
133 buf += indent;
134 switch (walker.currentNode.nodeType) {
135 case Node.ELEMENT_NODE:
136 buf += "<"
137 var ns = walker.currentNode.namespaceURI;
138 if ("http://www.w3.org/1998/Math/MathML" == ns) {
139 buf += "math ";
140 } else if ("http://www.w3.org/2000/svg" == ns) {
141 buf += "svg ";
142 } else if ("http://www.w3.org/1999/xhtml" != ns) {
143 buf += "otherns ";
144 }
145 buf += walker.currentNode.localName + ">";
146 if (walker.currentNode.hasAttributes()) {
147 var valuesByName = {};
148 var attrs = walker.currentNode.attributes;
149 for (var i = 0; i < attrs.length; ++i) {
150 var localName = attrs[i].localName;
151 var name;
152 var attrNs = attrs[i].namespaceURI;
153 if (null == attrNs) {
154 name = localName;
155 } else if ("http://www.w3.org/XML/1998/namespace" == attrNs) {
156 name = "xml " + localName;
157 } else if ("http://www.w3.org/1999/xlink" == attrNs) {
158 name = "xlink " + localName;
159 } else if ("http://www.w3.org/2000/xmlns/" == attrNs) {
160 name = "xmlns " + localName;
161 } else {
162 name = "otherns " + localName;
163 }
164 valuesByName[name] = attrs[i].value;
165 }
166 var keys = Object.keys(valuesByName).sort();
167 for (var i = 0; i < keys.length; ++i) {
168 buf += "\n" + indent + " " + keys[i] +
169 "=\"" + valuesByName[keys[i]] +"\"";
170 }
171 }
172 break;
173 case Node.DOCUMENT_TYPE_NODE:
174 buf += "<!DOCTYPE " + walker.currentNode.name;
175 if (walker.currentNode.publicId || walker.currentNode.systemId) {
176 buf += " \"";
177 buf += walker.currentNode.publicId;
178 buf += "\" \"";
179 buf += walker.currentNode.systemId;
180 buf += "\"";
181 }
182 buf += ">";
183 break;
184 case Node.COMMENT_NODE:
185 buf += "<!-- " + walker.currentNode.nodeValue + " -->";
186 break;
187 case Node.TEXT_NODE:
188 buf += "\"" + walker.currentNode.nodeValue + "\"";
189 break;
190 }
191 buf += "\n";
192 // In the case of template elements, children do not get inserted as
193 // children of the template element, instead they are inserted
194 // as children of the template content (which is a document fragment).
195 if (walker.currentNode instanceof HTMLTemplateElement) {
196 buf += indent + " content\n";
197 // Walk through the template content.
198 var templateWalker = createFragmentWalker(walker.currentNode.content);
199 buf = addLevels(templateWalker, buf, indent + " ");
200 }
201 buf = addLevels(walker, buf, indent + " ");
202 } while(walker.nextSibling());
203 walker.parentNode();
204 }
205 return buf;
206 }