2 Copyright (c) 2001-2005 World Wide Web Consortium,
3 (Massachusetts Institute of Technology, European Research Consortium
4 for Informatics and Mathematics, Keio University). All
5 Rights Reserved. This work is distributed under the W3C(r) Software License [1] in the
6 hope that it will be useful, but WITHOUT ANY WARRANTY; without even
7 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9 [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
12 /* Begin additions for WebKit layout test framework. */
13 if (window.testRunner)
14 testRunner.dumpAsText();
15 /* End additions for WebKit layout test framework. */
17 function assertSize(descr, expected, actual) {
19 actualSize = actual.length;
20 assertEquals(descr, expected, actualSize);
23 function assertEqualsAutoCase(context, descr, expected, actual) {
24 if (builder.contentType == "text/html") {
25 if(context == "attribute") {
26 assertEquals(descr, expected.toLowerCase(), actual.toLowerCase());
28 assertEquals(descr, expected.toUpperCase(), actual);
31 assertEquals(descr, expected, actual);
35 function assertEqualsCollectionAutoCase(context, descr, expected, actual) {
37 // if they aren't the same size, they aren't equal
38 assertEquals(descr, expected.length, actual.length);
41 // if there length is the same, then every entry in the expected list
42 // must appear once and only once in the actual list
43 var expectedLen = expected.length;
45 var actualLen = actual.length;
49 for(i = 0; i < expectedLen; i++) {
51 expectedValue = expected[i];
52 for(j = 0; j < actualLen; j++) {
53 if (builder.contentType == "text/html") {
54 if (context == "attribute") {
55 if (expectedValue.toLowerCase() == actual[j].toLowerCase()) {
59 if (expectedValue.toUpperCase() == actual[j]) {
64 if(expectedValue == actual[j]) {
70 assert(descr + ": No match found for " + expectedValue,false);
73 assert(descr + ": Multiple matches found for " + expectedValue, false);
78 function assertEqualsCollection(descr, expected, actual) {
80 // if they aren't the same size, they aren't equal
81 assertEquals(descr, expected.length, actual.length);
83 // if there length is the same, then every entry in the expected list
84 // must appear once and only once in the actual list
85 var expectedLen = expected.length;
87 var actualLen = actual.length;
91 for(i = 0; i < expectedLen; i++) {
93 expectedValue = expected[i];
94 for(j = 0; j < actualLen; j++) {
95 if(expectedValue == actual[j]) {
100 assert(descr + ": No match found for " + expectedValue,false);
103 assert(descr + ": Multiple matches found for " + expectedValue, false);
108 function assertEqualsListAutoCase(context, descr, expected, actual) {
109 var minLength = expected.length;
110 if (actual.length < minLength) {
111 minLength = actual.length;
114 for(var i = 0; i < minLength; i++) {
115 assertEqualsAutoCase(context, descr, expected[i], actual[i]);
118 // if they aren't the same size, they aren't equal
119 assertEquals(descr, expected.length, actual.length);
122 function assertEqualsList(descr, expected, actual) {
123 var minLength = expected.length;
124 if (actual.length < minLength) {
125 minLength = actual.length;
128 for(var i = 0; i < minLength; i++) {
129 if(expected[i] != actual[i]) {
130 assertEquals(descr, expected[i], actual[i]);
134 // if they aren't the same size, they aren't equal
135 assertEquals(descr, expected.length, actual.length);
138 function assertInstanceOf(descr, type, obj) {
140 assertEquals(descr,2,obj.nodeType);
141 var specd = obj.specified;
145 function assertSame(descr, expected, actual) {
146 if(expected != actual) {
147 assertEquals(descr, expected.nodeType, actual.nodeType);
148 assertEquals(descr, expected.nodeValue, actual.nodeValue);
152 function assertURIEquals(assertID, scheme, path, host, file, name, query, fragment, isAbsolute, actual) {
154 // URI must be non-null
155 assertNotNull(assertID, actual);
159 var lastPound = actual.lastIndexOf("#");
160 var actualFragment = "";
161 if(lastPound != -1) {
163 // substring before pound
165 uri = actual.substring(0,lastPound);
166 actualFragment = actual.substring(lastPound+1);
168 if(fragment != null) assertEquals(assertID,fragment, actualFragment);
170 var lastQuestion = uri.lastIndexOf("?");
171 var actualQuery = "";
172 if(lastQuestion != -1) {
174 // substring before pound
176 uri = actual.substring(0,lastQuestion);
177 actualQuery = actual.substring(lastQuestion+1);
179 if(query != null) assertEquals(assertID, query, actualQuery);
181 var firstColon = uri.indexOf(":");
182 var firstSlash = uri.indexOf("/");
183 var actualPath = uri;
184 var actualScheme = "";
185 if(firstColon != -1 && firstColon < firstSlash) {
186 actualScheme = uri.substring(0,firstColon);
187 actualPath = uri.substring(firstColon + 1);
191 assertEquals(assertID, scheme, actualScheme);
195 assertEquals(assertID, path, actualPath);
200 if(actualPath.substring(0,2) == "//") {
201 var termSlash = actualPath.substring(2).indexOf("/") + 2;
202 actualHost = actualPath.substring(0,termSlash);
204 assertEquals(assertID, host, actualHost);
207 if(file != null || name != null) {
208 var actualFile = actualPath;
209 var finalSlash = actualPath.lastIndexOf("/");
210 if(finalSlash != -1) {
211 actualFile = actualPath.substring(finalSlash+1);
214 assertEquals(assertID, file, actualFile);
217 var actualName = actualFile;
218 var finalDot = actualFile.lastIndexOf(".");
219 if (finalDot != -1) {
220 actualName = actualName.substring(0, finalDot);
222 assertEquals(assertID, name, actualName);
226 if(isAbsolute != null) {
227 assertEquals(assertID, isAbsolute, actualPath.substring(0,1) == "/");
231 // size() used by assertSize element
232 function size(collection)
234 return collection.length;
237 function same(expected, actual)
239 return expected === actual;
242 function getSuffix(contentType) {
246 function equalsAutoCase(context, expected, actual) {
247 if (builder.contentType == "text/html") {
248 if (context == "attribute") {
249 return expected.toLowerCase() == actual;
251 return expected.toUpperCase() == actual;
253 return expected == actual;
256 function createTempURI(scheme) {
257 if (scheme == "http") {
258 return "http://localhost:8080/webdav/tmp" + Math.floor(Math.random() * 100000) + ".xml";
260 return "file:///tmp/domts" + Math.floor(Math.random() * 100000) + ".xml";
263 function EventMonitor() {
264 this.atEvents = new Array();
265 this.bubbledEvents = new Array();
266 this.capturedEvents = new Array();
267 this.allEvents = new Array();
270 EventMonitor.prototype.handleEvent = function(evt) {
271 switch(evt.eventPhase) {
273 monitor.capturedEvents[monitor.capturedEvents.length] = evt;
277 monitor.atEvents[monitor.atEvents.length] = evt;
281 monitor.bubbledEvents[monitor.bubbledEvents.length] = evt;
284 monitor.allEvents[monitor.allEvents.length] = evt;
287 function DOMErrorImpl(err) {
288 this.severity = err.severity;
289 this.message = err.message;
290 this.type = err.type;
291 this.relatedException = err.relatedException;
292 this.relatedData = err.relatedData;
293 this.location = err.location;
296 function DOMErrorMonitor() {
297 this.allErrors = new Array();
300 DOMErrorMonitor.prototype.handleError = function(err) {
301 errorMonitor.allErrors[errorMonitor.allErrors.length] = new DOMErrorImpl(err);
304 DOMErrorMonitor.prototype.assertLowerSeverity = function(id, severity) {
306 for (i = 0; i < this.allErrors.length; i++) {
307 if (this.allErrors[i].severity >= severity) {
308 assertEquals(id, severity - 1, this.allErrors[i].severity);
313 function UserDataNotification(operation, key, data, src, dst) {
314 this.operation = operation;
321 function UserDataMonitor() {
322 this.allNotifications = new Array();
325 UserDataMonitor.prototype.handle = function(operation, key, data, src, dst) {
326 userDataMonitor.allNotifications[userDataMonitor.allNotifications.length] =
327 new UserDataNotification(operation, key, data, src, dst);
330 function toLowerArray(src) {
331 var newArray = new Array();
333 for (i = 0; i < src.length; i++) {
334 newArray[i] = src[i].toLowerCase();
339 function SVGBuilder() {
340 this.contentType = "image/svg+xml";
341 this.supportedContentTypes = [ "image/svg+xml" ];
343 this.supportsAsyncChange = false;
345 this.fixedAttributeNames = [
346 "validating", "expandEntityReferences", "coalescing",
347 "signed", "hasNullString", "ignoringElementContentWhitespace", "namespaceAware", "ignoringComments", "schemaValidating"];
349 this.fixedAttributeValues = [false, true, false, true, true , false, true, false, false ];
350 this.configurableAttributeNames = [ ];
351 this.configurableAttributeValues = [ ];
352 this.initializationError = null;
353 this.initializationFatalError = null;
354 this.skipIncompatibleTests = true;
355 this.documentURLs = new Array();
356 this.documentVarnames = new Array();
359 SVGBuilder.prototype.hasFeature = function(feature, version) {
360 return document.implementation.hasFeature(feature, version);
363 SVGBuilder.prototype.getImplementation = function() {
364 return document.implementation;
367 SVGBuilder.prototype.preload = function(frame, varname, url) {
369 this.documentVarnames[this.documentVarnames.length] = varname;
370 this.documentURLs[this.documentURLs.length] = url;
372 if (this.documentURLs.length > 1) {
374 // if all the urls are not the same
376 for (i = 1; i < this.documentURLs.length; i++) {
377 if (this.documentURLs[i] != this.documentURLs[0]) {
378 throw "Tests with multiple loads of different documents are not currently supported";
386 SVGBuilder.prototype.cloneNode = function(srcNode, doc) {
388 switch(srcNode.nodeType) {
392 clone = doc.createElementNS(srcNode.namespaceURI, srcNode.nodeName);
393 var attrs = srcNode.attributes;
394 for(var i = 0; i < attrs.length; i++) {
395 var srcAttr = attrs.item(i);
396 clone.setAttributeNS(srcAttr.namespaceURI, srcAttr.nodeName, srcAttr.nodeValue);
398 var srcChild = srcNode.firstChild;
399 while(srcChild != null) {
400 var cloneChild = this.cloneNode(srcChild, doc);
401 if (cloneChild != null) {
402 clone.appendChild(cloneChild);
404 srcChild = srcChild.nextSibling;
409 clone = doc.createTextNode(srcNode.nodeValue);
413 clone = doc.createCDATASection(srcNode.nodeValue);
417 clone = doc.createEntityReference(srcNode.nodeName);
421 clone = doc.createProcessingInstruction(srcNode.target, srcNode.data);
425 clone = doc.createComment(srcNode.nodeValue);
432 SVGBuilder.prototype.load = function(frame, varname, url) {
433 req = new XMLHttpRequest;
434 req.open("GET", "resources/" + url + ".xml", false);
436 return req.responseXML;
439 SVGBuilder.prototype.getImplementationAttribute = function(attr) {
440 for (var i = 0; i < this.fixedAttributeNames.length; i++) {
441 if (this.fixedAttributeNames[i] == attr) {
442 return this.fixedAttributeValues[i];
445 throw "Unrecognized implementation attribute: " + attr;
448 SVGBuilder.prototype.setImplementationAttribute = function(attribute, value) {
449 var supported = this.getImplementationAttribute(attribute);
450 if (supported != value) {
451 this.initializationError = "SVG loader does not support " + attribute + "=" + value;
455 SVGBuilder.prototype.canSetImplementationAttribute = function(attribute, value) {
456 var supported = this.getImplementationAttribute(attribute);
457 return (supported == value);
460 function createConfiguredBuilder() {
461 return new SVGBuilder();
464 function catchInitializationError(buildr, ex) {
465 buildr.initializationError = ex;
466 buildr.initializationFatalError = ex;
469 function checkFeature(feature, version)
471 if (!builder.hasFeature(feature, version))
474 // don't throw exception so that users can select to ignore the precondition
476 builder.initializationError = "builder does not support feature " + feature + " version " + version;
480 function changeColor(color) {
481 document.getElementsByTagName("rect").item(0).setAttribute("style", "fill:" + color);
484 function addMessage(x, y, msg) {
485 var textElem = document.createElementNS("http://www.w3.org/2000/svg", "text");
486 textElem.setAttributeNS(null, "x", x);
487 textElem.setAttributeNS(null, "y", y);
488 textElem.appendChild(document.createTextNode(msg));
489 document.documentElement.appendChild(textElem);
492 function checkInitialization(buildr, testname) {
493 if (buildr.initializationError != null) {
494 addMessage("0", "160", buildr.initializationError);
495 changeColor("yellow");
497 return buildr.initializationError;
500 function preload(docRef, varname, href) {
501 return builder.preload(docRef, varname, href);
504 function load(docRef, varname, href) {
505 return builder.load(docRef, varname, href);
508 function getImplementationAttribute(attr) {
509 return builder.getImplementationAttribute(attr);
512 function setImplementationAttribute(attribute, value) {
513 builder.setImplementationAttribute(attribute, value);
516 function createXPathEvaluator(doc) {
520 function getImplementation() {
521 return builder.getImplementation();
524 function assertEquals(id, expected, actual) {
526 if (expected != actual) {
528 if (actual == null) {
531 throw id + ": assertEquals failed, actual " + actual + ", expected " + expected + ".";
535 function assertNull(id, actual) {
536 if (actual != null) {
537 throw id + ": assertNull failed, actual " + actual;
541 function assertTrue(id, actual) {
543 throw id + ": assertTrue failed";
547 function assert(id, actual) {
549 throw id + ": assert failed";
553 function assertFalse(id, actual) {
555 throw id + ": assertFalse failed";
559 function assertNotNull(id, actual) {
560 if (actual == null) {
561 throw id + ": assertNotNull failed";
569 function getSuffix(contentType) {
570 switch(contentType) {
574 case "application/xhtml+xml":
577 case "image/svg+xml":
586 function getResourceURI(name, scheme, contentType) {
587 var base = document.documentURI;
591 base = base.substring(0, base.lastIndexOf('/') + 1) + "files/";
593 return base + name + getSuffix(contentType);
596 function onloadHandler() {
604 if (builder.initializationError == null) {
605 changeColor("green");
606 addMessage("0", "120", exposeTestFunctionNames()[0] + ": Success");
608 addMessage("0", "120", exposeTestFunctionNames()[0]);
611 addMessage("0", "120", exposeTestFunctionNames()[0]);
613 addMessage("0", "140", ex);
617 window.addEventListener('load', onloadHandler, false)