Annotation of 2001/DOM-Test-Suite/ecmascript/DOMTestCase.js, revision 1.44
1.42 dom-ts-4 1: /*
1.43 carnold 2: Copyright (c) 2001-2005 World Wide Web Consortium,
1.42 dom-ts-4 3: (Massachusetts Institute of Technology, Institut National de
4: Recherche en Informatique et en Automatique, Keio University). All
5: Rights Reserved. This program is distributed under the W3C's Software
6: Intellectual Property License. This program is distributed in the
7: hope that it will be useful, but WITHOUT ANY WARRANTY; without even
8: the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9: PURPOSE.
10: See W3C License http://www.w3.org/Consortium/Legal/ for more details.
11: */
12: function assertSize(descr, expected, actual) {
13: var actualSize;
14: assertNotNull(descr, actual);
15: actualSize = actual.length;
16: assertEquals(descr, expected, actualSize);
17: }
18:
19: function assertEqualsAutoCase(context, descr, expected, actual) {
20: if (builder.contentType == "text/html") {
21: if(context == "attribute") {
22: assertEquals(descr, expected.toLowerCase(), actual.toLowerCase());
23: } else {
24: assertEquals(descr, expected.toUpperCase(), actual);
25: }
26: } else {
27: assertEquals(descr, expected, actual);
28: }
29: }
30:
31:
32: function assertEqualsCollectionAutoCase(context, descr, expected, actual) {
33: //
34: // if they aren't the same size, they aren't equal
35: assertEquals(descr, expected.length, actual.length);
36:
37: //
38: // if there length is the same, then every entry in the expected list
39: // must appear once and only once in the actual list
40: var expectedLen = expected.length;
41: var expectedValue;
42: var actualLen = actual.length;
43: var i;
44: var j;
45: var matches;
46: for(i = 0; i < expectedLen; i++) {
47: matches = 0;
48: expectedValue = expected[i];
49: for(j = 0; j < actualLen; j++) {
50: if (builder.contentType == "text/html") {
51: if (context == "attribute") {
52: if (expectedValue.toLowerCase() == actual[j].toLowerCase()) {
53: matches++;
54: }
55: } else {
56: if (expectedValue.toUpperCase() == actual[j]) {
57: matches++;
58: }
59: }
60: } else {
61: if(expectedValue == actual[j]) {
62: matches++;
63: }
64: }
65: }
66: if(matches == 0) {
67: assert(descr + ": No match found for " + expectedValue,false);
68: }
69: if(matches > 1) {
70: assert(descr + ": Multiple matches found for " + expectedValue, false);
71: }
72: }
73: }
74:
75: function assertEqualsCollection(descr, expected, actual) {
76: //
77: // if they aren't the same size, they aren't equal
78: assertEquals(descr, expected.length, actual.length);
79: //
80: // if there length is the same, then every entry in the expected list
81: // must appear once and only once in the actual list
82: var expectedLen = expected.length;
83: var expectedValue;
84: var actualLen = actual.length;
85: var i;
86: var j;
87: var matches;
88: for(i = 0; i < expectedLen; i++) {
89: matches = 0;
90: expectedValue = expected[i];
91: for(j = 0; j < actualLen; j++) {
92: if(expectedValue == actual[j]) {
93: matches++;
94: }
95: }
96: if(matches == 0) {
97: assert(descr + ": No match found for " + expectedValue,false);
98: }
99: if(matches > 1) {
100: assert(descr + ": Multiple matches found for " + expectedValue, false);
101: }
102: }
103: }
104:
105:
106: function assertEqualsListAutoCase(context, descr, expected, actual) {
107: var minLength = expected.length;
108: if (actual.length < minLength) {
109: minLength = actual.length;
110: }
111: //
112: for(var i = 0; i < minLength; i++) {
113: assertEqualsAutoCase(context, descr, expected[i], actual[i]);
114: }
115: //
116: // if they aren't the same size, they aren't equal
117: assertEquals(descr, expected.length, actual.length);
118: }
119:
120:
121: function assertEqualsList(descr, expected, actual) {
122: var minLength = expected.length;
123: if (actual.length < minLength) {
124: minLength = actual.length;
125: }
126: //
127: for(var i = 0; i < minLength; i++) {
128: if(expected[i] != actual[i]) {
129: assertEquals(descr, expected[i], actual[i]);
130: }
131: }
132: //
133: // if they aren't the same size, they aren't equal
134: assertEquals(descr, expected.length, actual.length);
135: }
136:
137: function assertInstanceOf(descr, type, obj) {
138: if(type == "Attr") {
139: assertEquals(descr,2,obj.nodeType);
140: var specd = obj.specified;
141: }
142: }
143:
144: function assertSame(descr, expected, actual) {
145: if(expected != actual) {
146: assertEquals(descr, expected.nodeType, actual.nodeType);
147: assertEquals(descr, expected.nodeValue, actual.nodeValue);
148: }
149: }
150:
151: function assertURIEquals(assertID, scheme, path, host, file, name, query, fragment, isAbsolute, actual) {
152: //
153: // URI must be non-null
154: assertNotNull(assertID, actual);
155:
156: var uri = actual;
157:
158: var lastPound = actual.lastIndexOf("#");
159: var actualFragment = "";
160: if(lastPound != -1) {
161: //
162: // substring before pound
163: //
164: uri = actual.substring(0,lastPound);
165: actualFragment = actual.substring(lastPound+1);
166: }
167: if(fragment != null) assertEquals(assertID,fragment, actualFragment);
168:
169: var lastQuestion = uri.lastIndexOf("?");
170: var actualQuery = "";
171: if(lastQuestion != -1) {
172: //
173: // substring before pound
174: //
175: uri = actual.substring(0,lastQuestion);
176: actualQuery = actual.substring(lastQuestion+1);
177: }
178: if(query != null) assertEquals(assertID, query, actualQuery);
179:
180: var firstColon = uri.indexOf(":");
181: var firstSlash = uri.indexOf("/");
182: var actualPath = uri;
183: var actualScheme = "";
184: if(firstColon != -1 && firstColon < firstSlash) {
185: actualScheme = uri.substring(0,firstColon);
186: actualPath = uri.substring(firstColon + 1);
187: }
188:
189: if(scheme != null) {
190: assertEquals(assertID, scheme, actualScheme);
191: }
192:
193: if(path != null) {
194: assertEquals(assertID, path, actualPath);
195: }
196:
197: if(host != null) {
198: var actualHost = "";
199: if(actualPath.substring(0,2) == "//") {
200: var termSlash = actualPath.substring(2).indexOf("/") + 2;
201: actualHost = actualPath.substring(0,termSlash);
202: }
203: assertEquals(assertID, host, actualHost);
204: }
205:
206: if(file != null || name != null) {
207: var actualFile = actualPath;
208: var finalSlash = actualPath.lastIndexOf("/");
209: if(finalSlash != -1) {
210: actualFile = actualPath.substring(finalSlash+1);
211: }
212: if (file != null) {
213: assertEquals(assertID, file, actualFile);
214: }
215: if (name != null) {
216: var actualName = actualFile;
217: var finalDot = actualFile.lastIndexOf(".");
218: if (finalDot != -1) {
219: actualName = actualName.substring(0, finalDot);
220: }
221: assertEquals(assertID, name, actualName);
222: }
223: }
224:
225: if(isAbsolute != null) {
226: assertEquals(assertID, isAbsolute, actualPath.substring(0,1) == "/");
227: }
228: }
229:
230:
231: // size() used by assertSize element
232: function size(collection)
233: {
234: return collection.length;
235: }
236:
237: function same(expected, actual)
238: {
239: return expected === actual;
240: }
241:
242: function getSuffix(contentType) {
243: switch(contentType) {
244: case "text/html":
245: return ".html";
246:
247: case "text/xml":
248: return ".xml";
249:
250: case "application/xhtml+xml":
251: return ".xhtml";
252:
253: case "image/svg+xml":
254: return ".svg";
255:
256: case "text/mathml":
257: return ".mml";
258: }
259: return ".html";
260: }
261:
262: function equalsAutoCase(context, expected, actual) {
263: if (builder.contentType == "text/html") {
264: if (context == "attribute") {
265: return expected.toLowerCase() == actual;
266: }
267: return expected.toUpperCase() == actual;
268: }
269: return expected == actual;
270: }
271:
272: function catchInitializationError(blder, ex) {
1.43 carnold 273: if (blder == null) {
274: alert(ex);
275: } else {
276: blder.initializationError = ex;
277: blder.initializationFatalError = ex;
278: }
1.42 dom-ts-4 279: }
280:
281: function checkInitialization(blder, testname) {
282: if (blder.initializationError != null) {
283: if (blder.skipIncompatibleTests) {
284: info(testname + " not run:" + blder.initializationError);
285: return blder.initializationError;
286: } else {
287: //
288: // if an exception was thrown
289: // rethrow it and do not run the test
290: if (blder.initializationFatalError != null) {
291: throw blder.initializationFatalError;
292: } else {
293: //
294: // might be recoverable, warn but continue the test
295: warn(testname + ": " + blder.initializationError);
296: }
297: }
298: }
299: return null;
300: }
301: function createTempURI(scheme) {
302: if (scheme == "http") {
303: return "http://localhost:8080/webdav/tmp" + Math.floor(Math.random() * 100000) + ".xml";
304: }
305: return "file:///tmp/domts" + Math.floor(Math.random() * 100000) + ".xml";
306: }
307:
308:
309: function EventMonitor() {
310: this.atEvents = new Array();
311: this.bubbledEvents = new Array();
312: this.capturedEvents = new Array();
313: this.allEvents = new Array();
314: }
315:
316: EventMonitor.prototype.handleEvent = function(evt) {
317: switch(evt.eventPhase) {
318: case 1:
319: monitor.capturedEvents[monitor.capturedEvents.length] = evt;
320: break;
321:
322: case 2:
323: monitor.atEvents[monitor.atEvents.length] = evt;
324: break;
325:
326: case 3:
327: monitor.bubbledEvents[monitor.bubbledEvents.length] = evt;
328: break;
329: }
330: monitor.allEvents[monitor.allEvents.length] = evt;
331: }
332:
333: function DOMErrorImpl(err) {
334: this.severity = err.severity;
335: this.message = err.message;
336: this.type = err.type;
337: this.relatedException = err.relatedException;
338: this.relatedData = err.relatedData;
339: this.location = err.location;
340: }
341:
342:
343:
344: function DOMErrorMonitor() {
345: this.allErrors = new Array();
346: }
347:
348: DOMErrorMonitor.prototype.handleError = function(err) {
349: errorMonitor.allErrors[errorMonitor.allErrors.length] = new DOMErrorImpl(err);
350: }
351:
352: DOMErrorMonitor.prototype.assertLowerSeverity = function(id, severity) {
353: var i;
354: for (i = 0; i < errorMonitor.allErrors.length; i++) {
355: if (errorMonitor.allErrors[i].severity >= severity) {
356: assertEquals(id, severity - 1, errorMonitor.allErrors[i].severity);
357: }
358: }
359: }
360:
361: function UserDataNotification(operation, key, data, src, dst) {
362: this.operation = operation;
363: this.key = key;
364: this.data = data;
365: this.src = src;
366: this.dst = dst;
367: }
368:
369: function UserDataMonitor() {
370: this.allNotifications = new Array();
371: }
372:
373: UserDataMonitor.prototype.handle = function(operation, key, data, src, dst) {
374: userDataMonitor.allNotifications[this.allNotifications.length] =
375: new UserDataNotification(operation, key, data, src, dst);
376: }
377:
378:
379:
380: function IFrameBuilder() {
381: this.contentType = "text/html";
382: this.supportedContentTypes = [ "text/html",
383: "text/xml",
384: "image/svg+xml",
385: "application/xhtml+xml" ];
386:
387: this.supportsAsyncChange = false;
388: this.async = true;
389: this.fixedAttributeNames = [
390: "validating", "expandEntityReferences", "coalescing",
391: "signed", "hasNullString", "ignoringElementContentWhitespace", "namespaceAware", "ignoringComments", "schemaValidating"];
392:
393: this.fixedAttributeValues = [false, true, false, true, true , false, false, true, false ];
394: this.configurableAttributeNames = [ ];
395: this.configurableAttributeValues = [ ];
396: this.initializationError = null;
397: this.initializationFatalError = null;
398: this.skipIncompatibleTests = false;
399: }
400:
401: IFrameBuilder.prototype.hasFeature = function(feature, version) {
402: return document.implementation.hasFeature(feature, version);
403: }
404:
405: IFrameBuilder.prototype.getImplementation = function() {
406: return document.implementation;
407: }
408:
409: IFrameBuilder.prototype.setContentType = function(contentType) {
410: this.contentType = contentType;
411: if (contentType == "text/html") {
412: this.fixedAttributeValues[6] = false;
413: } else {
414: this.fixedAttributeValues[6] = true;
415: }
416: }
417:
418:
419:
420: IFrameBuilder.prototype.preload = function(frame, varname, url) {
421: if (this.contentType == "text/html" || this.contentType == "application/xhtml+xml") {
422: if (url.substring(0,5) == "staff" || url == "nodtdstaff" || url == "datatype_normalization") {
423: throw "Tests using staff or nodtdstaff are not supported by HTML processors";
424: }
425: }
426: var iframe = document.createElement("iframe");
427: var srcname = url + getSuffix(this.contentType);
428: iframe.setAttribute("name", srcname);
429: iframe.setAttribute("src", fileBase + srcname);
430: //
431: // HTML and XHTML have onload attributes that will invoke loadComplete
432: //
433: if (this.contentType != "text/html" && this.contentType != "application/xhtml+xml") {
434: iframe.addEventListener("load", loadComplete, false);
435: }
436: document.getElementsByTagName("body").item(0).appendChild(iframe);
437: return 0;
438: }
439:
440: IFrameBuilder.prototype.load = function(frame, varname, url) {
441: if (this.contentType == "text/html") {
442: return frame.document;
443: }
444: var name = url + getSuffix(this.contentType);
445: var iframes = document.getElementsByTagName("iframe");
446: for(var i = 0; i < iframes.length; i++) {
447: if (iframes.item(i).getAttribute("name") == name) {
448: var item = iframes.item(i);
449: if (typeof(item.contentDocument) != 'undefined') {
450: return item.contentDocument;
451: }
452: if (typeof(item.document) != 'undefined') {
453: return item.document;
454: }
455: return null;
456: }
457: }
458: return null;
459: }
460:
461: IFrameBuilder.prototype.getImplementationAttribute = function(attr) {
462: for (var i = 0; i < this.fixedAttributeNames.length; i++) {
463: if (this.fixedAttributeNames[i] == attr) {
464: return this.fixedAttributeValues[i];
465: }
466: }
467: throw "Unrecognized implementation attribute: " + attr;
468: }
469:
470:
471:
472: IFrameBuilder.prototype.setImplementationAttribute = function(attribute, value) {
473: var supported = this.getImplementationAttribute(attribute);
474: if (supported != value) {
475: this.initializationError = "IFrame loader does not support " + attribute + "=" + value;
476: }
477: }
478:
479:
480: IFrameBuilder.prototype.canSetImplementationAttribute = function(attribute, value) {
481: var supported = this.getImplementationAttribute(attribute);
482: return (supported == value);
483: }
484:
485:
486:
487: function SVGPluginBuilder() {
488: this.contentType = "image/svg+xml";
489: this.supportedContentTypes = [ "image/svg+xml" ];
490:
491: this.supportsAsyncChange = false;
492: this.async = true;
493: this.fixedAttributeNames = [
494: "validating", "expandEntityReferences", "coalescing",
495: "signed", "hasNullString", "ignoringElementContentWhitespace", "namespaceAware", "ignoringComments" , "schemaValidating"];
496:
497: this.fixedAttributeValues = [false, true, false, true, true , false, true, false, false ];
498: this.configurableAttributeNames = [ ];
499: this.configurableAttributeValues = [ ];
500: this.initializationError = null;
501: this.initializationFatalError = null;
502: this.skipIncompatibleTests = false;
503: }
504:
505: SVGPluginBuilder.prototype.hasFeature = function(feature, version) {
506: if (feature == "XML") {
507: if (version == null || version == "1.0" || version == "2.0") {
508: return true;
509: }
510: }
511: return false;
512: }
513:
514: SVGPluginBuilder.prototype.setContentType = function(contentType) {
515: this.contentType = contentType;
516: }
517:
518: SVGPluginBuilder.prototype.getImplementation = function() {
519: var embed = document.createElement("embed");
520: embed.src = fileBase + url + getSuffix(this.contentType);
521: embed.height = 100;
522: embed.width = 100;
523: embed.type = "image/svg+xml";
524: embed.id = varname;
525: var child = document.documentElement.firstChild;
526: while(child != null) {
527: if (child.nodeName != null && child.nodeName.toUpperCase() == "BODY") {
528: child.appendChild(embed);
529: return child.getSVGDocument.implementation;
530: }
531: child = child.nextSibling;
532: }
533: return null;
534: }
535:
536: var svgloadcount = 0;
537: function SVGPluginBuilder_pollreadystate() {
538: var newCount = 0;
539: var child = document.documentElement.firstChild;
540: while(child != null) {
541: if (child.nodeName != null && child.nodeName.toUpperCase() == "BODY") {
542: var grand = child.firstChild;
543: while (grand != null) {
544: if (grand.nodeName.toUpperCase() == 'EMBED' && grand.readystate == 4) {
545: newCount++;
546: }
547: grand = grand.nextSibling;
548: }
549: break;
550: }
551: child = child.nextSibling;
552: }
553: if (newCount > svgloadcount) {
554: svgloadcount++;
555: loadComplete();
556: if (setUpPageStatus == 'complete') {
557: return;
558: }
559: }
560: setTimeout(SVGPluginBuilder_pollreadystate, 100);
561: }
562:
563: SVGPluginBuilder.prototype.preload = function(frame, varname, url) {
564: var embed = document.createElement("embed");
565: embed.src = fileBase + url + getSuffix(this.contentType);
566: embed.height = 100;
567: embed.width = 100;
568: embed.type = "image/svg+xml";
569: embed.id = varname;
570: var child = document.documentElement.firstChild;
571: while(child != null) {
572: if (child.nodeName != null && child.nodeName.toUpperCase() == "BODY") {
573: child.appendChild(embed);
574: break;
575: }
576: child = child.nextSibling;
577: }
578: //
579: // if unable to monitor ready state change then
580: // check if load is complete every in 0.1 second
581: setTimeout(SVGPluginBuilder_pollreadystate , 100);
582: return 0;
583: }
584:
585: SVGPluginBuilder.prototype.load = function(frame, varname, url) {
586: var child = document.documentElement.firstChild;
587: while(child != null) {
588: if (child.nodeName != null && child.nodeName.toUpperCase() == "BODY") {
589: var grand = child.firstChild;
590: while (grand != null) {
591: if (grand.id == varname) {
592: return grand.getSVGDocument();
593: }
594: grand = grand.nextSibling;
595: }
596: }
597: child = child.nextSibling;
598: }
599: return null;
600: }
601:
602: SVGPluginBuilder.prototype.getImplementationAttribute = function(attr) {
603: for (var i = 0; i < this.fixedAttributeNames.length; i++) {
604: if (this.fixedAttributeNames[i] == attr) {
605: return this.fixedAttributeValues[i];
606: }
607: }
608: throw "Unrecognized implementation attribute: " + attr;
609: }
610:
611:
612: SVGPluginBuilder.prototype.setImplementationAttribute = function(attribute, value) {
613: var supported = this.getImplementationAttribute(attribute);
614: if (supported != value) {
615: this.initializationError = "SVG Plugin loader does not support " + attribute + "=" + value;
616: }
617: }
618:
619: SVGPluginBuilder.prototype.canSetImplementationAttribute = function(attribute, value) {
620: var supported = this.getImplementationAttribute(attribute);
621: return (supported == value);
622: }
623:
624:
625:
626:
627: function MSXMLBuilder(progID) {
628: this.progID = progID;
629: this.configurableAttributeNames = [
630: "validating", "ignoringElementContentWhitespace"];
631: this.configurableAttributeValues = [ false, false ];
632: this.fixedAttributeNames = [ "signed", "hasNullString",
633: "expandEntityReferences", "coalescing", "namespaceAware", "ignoringComments", "schemaValidating" ];
634: this.fixedAttributeValues = [ true, true, false, false, false, false, false ];
635:
636: this.contentType = "text/xml";
637: this.supportedContentTypes = [
638: "text/xml",
639: "image/svg+xml",
640: "application/xhtml+xml",
641: "text/mathml" ];
642:
643: this.async = false;
644: this.supportsAsyncChange = true;
645: this.parser = null;
646: this.initializationError = null;
647: this.initializationFatalError = null;
648: this.skipIncompatibleTests = false;
649: }
650:
651: MSXMLBuilder.prototype.createMSXML = function() {
652: var parser = new ActiveXObject(this.progID);
653: parser.async = this.async;
654: parser.preserveWhiteSpace = !this.configurableAttributeValues[1];
655: parser.validateOnParse = this.configurableAttributeValues[0];
656: return parser;
657: }
658:
659: MSXMLBuilder.prototype.setContentType = function(contentType) {
660: this.contentType = contentType;
661: }
662:
663:
664: MSXMLBuilder.prototype.preload = function(frame, varname, url) {
665: if (this.async) {
666: this.parser = this.createMSXML();
667: parser.async = true;
668: parser.onreadystatechange = MSXMLBuilder_onreadystatechange;
669: parser.load(fileBase + url + getSuffix(this.contentType));
670: if (parser.readystate != 4) {
671: return 0;
672: }
673: }
674: return 1;
675: }
676:
677: MSXMLBuilder.prototype.load = function(frame, varname, url) {
678: var parser = this.createMSXML();
679: if(!parser.load(fileBase + url + getSuffix(this.contentType))) {
680: throw parser.parseError.reason;
681: }
682: //
683: // if the first child of the document is a PI representing
684: // the XML Declaration, remove it from the tree.
685: //
686: // According to the DOM FAQ, this behavior is not wrong,
687: // but the tests are written assuming that it is not there.
688: //
689: var xmlDecl = parser.firstChild;
690: if(xmlDecl != null && xmlDecl.nodeType == 7 && xmlDecl.target.toLowerCase() == "xml") {
691: parser.removeChild(xmlDecl);
692: }
693: return parser;
694: }
695:
696: MSXMLBuilder.prototype.getImplementationAttribute = function(attr) {
697: var i;
698: for (i = 0; i < this.fixedAttributeNames.length; i++) {
699: if (this.fixedAttributeNames[i] == attr) {
700: return this.fixedAttributeValues[i];
701: }
702: }
703:
704: for (i = 0; i < this.configurableAttributeNames.length; i++) {
705: if (this.configurableAttributeNames[i] == attr) {
706: return this.configurableAttributeValues[i];
707: }
708: }
709:
710: throw "Unrecognized implementation attribute: " + attr;
711: }
712:
713:
714: MSXMLBuilder.prototype.setImplementationAttribute = function(attribute, value) {
715: var i;
716: for (i = 0; i < this.fixedAttributeNames.length; i++) {
717: if (this.fixedAttributeNames[i] == attribute) {
718: if (this.fixedAttributeValues[i] != value) {
719: this.initializationError = "MSXML does not support " + attribute + "=" + value;
720: }
721: return;
722: }
723: }
724: for (i = 0; i < this.configurableAttributeNames.length; i++) {
725: if (this.configurableAttributeNames[i] == attribute) {
726: this.configurableAttributeValues[i] = value;
727: return;
728: }
729: }
730: this.initializationError = "Unrecognized implementation attribute: " + attr;
731: }
732:
733:
734: MSXMLBuilder.prototype.canSetImplementationAttribute = function(attribute, value) {
735: var i;
736: for (i = 0; i < this.fixedAttributeNames.length; i++) {
737: if (this.fixedAttributeNames[i] == attribute) {
738: return (this.fixedAttributeValues[i] == value);
739: }
740: }
741: for (i = 0; i < this.configurableAttributeNames.length; i++) {
742: if (this.configurableAttributeNames[i] == attribute) {
743: return true;
744: }
745: }
746: return false;
747: }
748:
749:
750: MSXMLBuilder.prototype.getImplementation = function() {
751: var doc = this.CreateMSXML();
752: return doc.implementation;
753: }
754:
755: //
756: // Only used to select tests compatible with implementation
757: // not used on tests that actually test hasFeature()
758: //
759: MSXMLBuilder.prototype.hasFeature = function(feature, version) {
760: //
761: // MSXML will take null, unfortunately
762: // there is no way to get it to there from script
763: // without a type mismatch error
764: if(version == null) {
765: switch(feature.toUpperCase()) {
766: case "XML":
767: case "CORE":
768: return true;
769:
770: case "HTML":
771: case "ORG.W3C.DOM":
772: return false;
773: }
774: if(this.getDOMImplementation().hasFeature(feature,"1.0")) {
775: return true;
776: }
777: if(this.getDOMImplementation().hasFeature(feature,"2.0")) {
778: return true;
779: }
780: if(this.getDOMImplementation().hasFeature(feature,"3.0")) {
781: return true;
782: }
783: }
784: return this.getDOMImplementation().hasFeature(feature,version);
785: }
786:
787:
788:
789: function MozillaXMLBuilder() {
790: this.contentType = "text/xml";
791:
792: this.configurableAttributeNames = [ ];
793: this.configurableAttributeValues = [ ];
794: this.fixedAttributeNames = [ "validating", "ignoringElementContentWhitespace", "signed",
795: "hasNullString", "expandEntityReferences", "coalescing", "namespaceAware", "ignoringComments", "schemaValidating" ];
796: this.fixedAttributeValues = [ false, false, true, true, false, false, false, false, false ];
797:
798: this.contentType = "text/xml";
799: this.supportedContentTypes = [
800: "text/xml",
801: "image/svg+xml",
802: "application/xhtml+xml",
803: "text/mathml" ];
804:
805: this.async = true;
806: this.supportsAsyncChange = false;
807:
808: this.docs = new Array();
809: this.docnames = new Array();
810: this.initializationError = null;
811: this.initializationFatalError = null;
812: this.skipIncompatibleTests = false;
813: }
814:
815: MozillaXMLBuilder.prototype.getImplementation = function() {
816: return document.implementation;
817: }
818:
819: MozillaXMLBuilder.prototype.setContentType = function(contentType) {
820: this.contentType = contentType;
821: }
822:
823:
824:
825: MozillaXMLBuilder.prototype.preload = function(frame, varname, url) {
826: var domimpl = document.implementation;
827: var doc = domimpl.createDocument("", "temp", null);
828: doc.addEventListener("load", loadComplete, false);
829: doc.load(fileBase + url + getSuffix(this.contentType));
830: this.docs[this.docs.length] = doc;
831: this.docnames[this.docnames.length] = varname;
832: return 0;
833: }
834:
835: MozillaXMLBuilder.prototype.load = function(frame, varname, url) {
836: for(i = 0; i < this.docnames.length; i++) {
837: if (this.docnames[i] == varname) {
838: return this.docs[i];
839: }
840: }
841: return null;
842: }
843:
844:
845: MozillaXMLBuilder.prototype.getImplementationAttribute = function(attr) {
846: for (var i = 0; i < this.fixedAttributeNames.length; i++) {
847: if (this.fixedAttributeNames[i] == attr) {
848: return this.fixedAttributeValues[i];
849: }
850: }
851: return false;
852: }
853:
854:
855: MozillaXMLBuilder.prototype.hasFeature = function(feature, version)
856: {
857: return this.getImplementation().hasFeature(feature, version);
858: }
859:
860: MozillaXMLBuilder.prototype.setImplementationAttribute = function(attribute, value) {
861: var supported = this.getImplementationAttribute(attribute);
862: if (supported != value) {
863: this.initializationError = "Mozilla XML loader does not support " + attribute + "=" + value;
864: }
865: }
866:
867:
868: MozillaXMLBuilder.prototype.canSetImplementationAttribute = function(attribute, value) {
869: var supported = this.getImplementationAttribute(attribute);
870: return (supported == value);
871: }
872:
873: function DOM3LSBuilder() {
874: this.contentType = "text/xml";
875:
1.43 carnold 876: this.fixedAttributeNames = [ "signed", "hasNullString" ];
1.42 dom-ts-4 877: this.fixedAttributeValues = [ true, true ];
878: this.configurableAttributeNames = [ "validating", "ignoringElementContentWhitespace",
879: "expandEntityReferences", "coalescing", "namespaceAware", "ignoringComments", "schemaValidating" ];
880: this.configurableAttributeValues = [ false, false, true, true, false, false, true, false, false ];
881: this.domConfigNames = [ "validate", "element-content-whitespace",
882: "entities", "cdata-sections", "namespaces", "comments", "validate" ];
883: this.domConfigSense = [ true, false, false, false, true, false, true ];
884:
885: this.contentType = "text/xml";
886: this.supportedContentTypes = [
887: "text/xml",
888: "image/svg+xml",
889: "application/xhtml+xml",
890: "text/mathml" ];
891:
892: this.async = false;
893: this.supportsAsyncChange = true;
894:
895: this.docs = new Array();
896: this.docnames = new Array();
897: this.initializationError = null;
898: this.initializationFatalError = null;
899: this.skipIncompatibleTests = false;
1.43 carnold 900: var domimpl = document.implementation;
901: this.lsparser = domimpl.createLSParser(2, null);
1.42 dom-ts-4 902: }
903:
904: DOM3LSBuilder.prototype.getImplementation = function() {
905: return document.implementation;
906: }
907:
908:
909: DOM3LSBuilder.prototype.setContentType = function(contentType) {
910: this.contentType = contentType;
911: }
912:
913: DOM3LSBuilder.prototype.preload = function(frame, varname, url) {
914: if (!this.async) {
915: return 1;
916: }
917: var domimpl = document.implementation;
918: this.lsparser.addEventListener("load", loadComplete, false);
919: var uri = fileBase + url + getSuffix(this.contentType);
920: var doc = this.lsparser.parseURI(uri);
921: this.docs[this.docs.length] = doc;
922: this.docnames[this.docnames.length] = varname;
923: return 0;
924: }
925:
926: DOM3LSBuilder.prototype.load = function(frame, varname, url) {
927: if (this.async) {
928: for(i = 0; i < this.docnames.length; i++) {
929: if (this.docnames[i] == varname) {
930: return this.docs[i];
931: }
932: }
933: return null;
934: }
935: this.lsparser = document.implementation.createLSParser(1, null);
936: var uri = fileBase + url + getSuffix(this.contentType);
937: return this.lsparser.parseURI(uri);
938: }
939:
940:
941: DOM3LSBuilder.prototype.getImplementationAttribute = function(attr) {
942: if (attr == "schemaValidating") {
943: return (this.lsparser.domConfig.getParameter("validate") &&
944: this.lsparser.domConfig.getParameter("schema-type") ==
945: "http://www.w3.org/2001/XMLSchema");
946: }
947: var i;
948: for (i = 0; i < this.fixedAttributeNames.length; i++) {
949: if (this.fixedAttributeNames[i] == attr) {
950: return this.fixedAttributeValues[i];
951: }
952: }
953: for (i = 0; i < this.configurableAttributeNames.length; i++) {
954: if (this.configurableAttributeNames[i] == attr) {
955: if(this.lsparser.domConfig.getParameter(this.domConfigNames[i])) {
956: return this.domConfigSense[i];
957: } else {
958: return !this.domConfigSense[i];
959: }
960: }
961: }
962: throw "unrecognized implementation attribute " + att;
963: }
964:
965: DOM3LSBuilder.prototype.hasFeature = function(feature, version) {
966: return document.implementation.hasFeature(feature, version);
967: }
968:
969:
970: DOM3LSBuilder.prototype.setImplementationAttribute = function(attr, value) {
971: if (attr == "schemaValidating") {
972: this.lsparser.domConfig.setParameter("validate", true);
973: this.lsparser.domConfig.setParameter("schema-type",
974: "http://www.w3.org/2001/XMLSchema");
975: return;
976: }
977: var i;
978: for (i = 0; i < this.fixedAttributeNames.length; i++) {
979: if (this.fixedAttributeNames[i] == attr) {
980: if (value != this.fixedAttributeValue) {
981: this.initializationError = "DOM3LS does not support " + attribute + " = " + value;
982: return;
983: }
984: }
985: }
986: for (i = 0; i < this.configurableAttributeNames.length; i++) {
987: if (this.configurableAttributeNames[i] == attr) {
1.43 carnold 988: var paramValue = value;
989: if (!this.domConfigSense[i]) {
990: paramValue = !value;
991: }
992: var oldValue = this.lsparser.domConfig.getParameter(this.domConfigNames[i]);
993: if (paramValue != oldValue) {
994: if (this.lsparser.domConfig.canSetParameter(this.domConfigNames[i], paramValue)) {
995: this.lsparser.domConfig.setParameter(this.domConfigNames[i], paramValue);
996: }
1.42 dom-ts-4 997: }
998: return;
999: }
1000: }
1001: throw "Unrecognized configuration attribute " + attr;
1002: }
1003:
1004:
1.43 carnold 1005: DOM3LSBuilder.prototype.canSetImplementationAttribute = function(attr, value) {
1006: for (i = 0; i < this.configurableAttributeNames.length; i++) {
1007: if (this.configurableAttributeNames[i] == attr) {
1008: var paramValue = value;
1009: if (!this.domConfigSense[i]) {
1010: paramValue = !value;
1011: }
1012: return this.lsparser.domConfig.canSetParameter(this.domConfigNames[i], paramValue);
1013: }
1014: }
1015: return false;
1016: }
1017:
1.42 dom-ts-4 1018:
1.44 ! carnold 1019: function XMLHttpRequestBuilder() {
! 1020: this.contentType = "text/xml";
! 1021:
! 1022: this.fixedAttributeNames = [ "signed", "hasNullString",
! 1023: "validating", "ignoringElementContentWhitespace",
! 1024: "expandEntityReferences", "coalescing", "namespaceAware", "ignoringComments", "schemaValidating" ];
! 1025: this.fixedAttributeValues = [ true, true, false, false,
! 1026: true, true, false, false, true, false, false ];
! 1027: this.configurableAttributeNames = [ ];
! 1028: this.configurableAttributeValues = [ ];
! 1029:
! 1030: this.supportedContentTypes = [
! 1031: "text/xml",
! 1032: "image/svg+xml",
! 1033: "application/xhtml+xml",
! 1034: "text/mathml" ];
! 1035:
! 1036: this.async = false;
! 1037: this.supportsAsyncChange = true;
! 1038:
! 1039: this.docs = new Array();
! 1040: this.docnames = new Array();
! 1041: this.initializationError = null;
! 1042: this.initializationFatalError = null;
! 1043: this.skipIncompatibleTests = false;
! 1044: }
! 1045:
! 1046: XMLHttpRequestBuilder.prototype.getImplementation = function() {
! 1047: return this.req.responseXML.implementation;
! 1048: }
! 1049:
! 1050:
! 1051: XMLHttpRequestBuilder.prototype.setContentType = function(contentType) {
! 1052: this.contentType = contentType;
! 1053: }
! 1054:
! 1055: XMLHttpRequestBuilder.prototype.createParser = function() {
! 1056: var req = false;
! 1057: if (window.XMLHttpRequest) {
! 1058: try {
! 1059: req = new XMLHttpRequest();
! 1060: } catch(e) {
! 1061: req = false;
! 1062: }
! 1063: } else if(window.ActiveXObject) {
! 1064: try {
! 1065: req = new ActiveXObject("Msxml2.XMLHTTP");
! 1066: } catch(e) {
! 1067: try {
! 1068: req = new ActiveXObject("Microsoft.XMLHTTP");
! 1069: } catch(e) {
! 1070: req = false;
! 1071: }
! 1072: }
! 1073: }
! 1074: return req;
! 1075: }
! 1076:
! 1077: XMLHttpRequestBuilder.prototype.preload = function(frame, varname, url) {
! 1078: if (!this.async) {
! 1079: return 1;
! 1080: }
! 1081: var uri = fileBase + url + getSuffix(this.contentType);
! 1082: var req = this.createParser();
! 1083: req.onreadystatechange = MSXMLBuilder_onreadystatechange;
! 1084: req.open("GET", uri, true);
! 1085: req.send("");
! 1086: this.docs[this.docs.length] = req;
! 1087: this.docnames[this.docnames.length] = varname;
! 1088: return 0;
! 1089: }
! 1090:
! 1091: XMLHttpRequestBuilder.prototype.load = function(frame, varname, url) {
! 1092: if (this.async) {
! 1093: for(i = 0; i < this.docnames.length; i++) {
! 1094: if (this.docnames[i] == varname) {
! 1095: return this.docs[i];
! 1096: }
! 1097: }
! 1098: return null;
! 1099: }
! 1100: var req = this.createParser();
! 1101: var uri = fileBase + url + getSuffix(this.contentType);
! 1102: req.open("GET", uri, false);
! 1103: req.send("");
! 1104: return req.responseXML;
! 1105: }
! 1106:
! 1107:
! 1108: XMLHttpRequestBuilder.prototype.getImplementationAttribute = function(attr) {
! 1109: var i;
! 1110: for (i = 0; i < this.fixedAttributeNames.length; i++) {
! 1111: if (this.fixedAttributeNames[i] == attr) {
! 1112: return this.fixedAttributeValues[i];
! 1113: }
! 1114: }
! 1115: throw "unrecognized implementation attribute " + att;
! 1116: }
! 1117:
! 1118: XMLHttpRequestBuilder.prototype.hasFeature = function(feature, version) {
! 1119: if (feature == "XML" ||
! 1120: (feature.length == 3 && feature.toUpperCase() == "XML")) {
! 1121: return true;
! 1122: }
! 1123: return document.implementation.hasFeature(feature, version);
! 1124: }
! 1125:
! 1126:
! 1127: XMLHttpRequestBuilder.prototype.setImplementationAttribute = function(attr, value) {
! 1128: throw "Unrecognized configuration attribute " + attr;
! 1129: }
! 1130:
! 1131:
! 1132: XMLHttpRequestBuilder.prototype.canSetImplementationAttribute = function(attr, value) {
! 1133: return false;
! 1134: }
! 1135:
! 1136:
! 1137:
1.42 dom-ts-4 1138: function createBuilder(implementation) {
1139: if (implementation == null) {
1140: return new IFrameBuilder();
1141: }
1142: switch(implementation) {
1143: case "msxml3":
1144: return new MSXMLBuilder("Msxml2.DOMDocument.3.0");
1145:
1146: case "msxml4":
1147: return new MSXMLBuilder("Msxml2.DOMDocument.4.0");
1148:
1149: case "mozillaXML":
1150: return new MozillaXMLBuilder();
1151:
1152: case "svgplugin":
1153: return new SVGPluginBuilder();
1154:
1155: case "dom3ls":
1156: return new DOM3LSBuilder();
1157:
1158: case "iframe":
1159: return new IFrameBuilder();
1.44 ! carnold 1160:
! 1161: case "xmlhttprequest":
! 1162: return new XMLHttpRequestBuilder();
1.42 dom-ts-4 1163:
1164: default:
1165: alert ("unrecognized implementation " + implementation);
1166: }
1167: return new IFrameBuilder();
1168: }
1169:
1170: function checkFeature(feature, version)
1171: {
1172: if (!builder.hasFeature(feature, version))
1173: {
1174: //
1175: // don't throw exception so that users can select to ignore the precondition
1176: //
1177: builder.initializationError = "builder does not support feature " + feature + " version " + version;
1178: }
1179: }
1180:
1181: function createConfiguredBuilder() {
1182: var builder = null;
1183: var contentType = null;
1184: var i;
1185: var contentTypeSet = false;
1186: var parm = null;
1187: if (top && typeof(top.jsUnitParmHash) != 'undefined') {
1188: builder = createBuilder(top.jsUnitGetParm('implementation'));
1189:
1190: parm = top.jsUnitGetParm("skipincompatibletests");
1191: if (parm) {
1192: if (parm == 'true') {
1193: builder.skipIncompatibleTests = true;
1194: } else {
1195: builder.skipIncompatibleTests = false;
1196: }
1197: }
1198:
1199: if (top.jsUnitGetParm('asynchronous') == 'true' && builder.supportAsync) {
1200: builder.async = true;
1201: }
1202: if (top.jsUnitGetParm('expandentityreferences')) {
1203: if (top.jsUnitGetParm('expandEntityReferences') == 'true') {
1204: builder.setImplementationAttribute('expandEntityReferences', true);
1205: } else {
1206: builder.setImplementationAttribute('expandEntityReferences', false);
1207: }
1208: }
1209: if (top.jsUnitGetParm('ignoringelementcontentwhitespace')) {
1210: if (top.jsUnitGetParm('ignoringElementContentWhitespace') == 'true') {
1211: builder.setImplementationAttribute('ignoringElementContentWhitespace', true);
1212: } else {
1213: builder.setImplementationAttribute('ignoringElementContentWhitespace', false);
1214: }
1215: }
1216: if (top.jsUnitGetParm('validating')) {
1217: if (top.jsUnitGetParm('validating') == 'true') {
1218: builder.setImplementationAttribute('validating', true);
1219: } else {
1220: builder.setImplementationAttribute('validating', false);
1221: }
1222: }
1223: if (top.jsUnitGetParm('coalescing')) {
1224: if (top.jsUnitGetParm('coalescing') == 'true') {
1225: builder.setImplementationAttribute('coalescing', true);
1226: } else {
1227: builder.setImplementationAttribute('coalescing', false);
1228: }
1229: }
1230: if (top.jsUnitGetParm('namespaceaware')) {
1231: if (top.jsUnitGetParm('namespaceaware') == 'true') {
1232: builder.setImplementationAttribute('namespaceAware', true);
1233: } else {
1234: builder.setImplementationAttribute('namespaceAware', false);
1235: }
1236: }
1237: contentType = top.jsUnitGetParm('contenttype');
1238: if (contentType != null) {
1239: contentTypeSet = false;
1240: for (i = 0; i < builder.supportedContentTypes.length; i++) {
1241: if (builder.supportedContentTypes[i] == contentType) {
1242: builder.setContentType(contentType);
1243: contentTypeSet = true;
1244: break;
1245: }
1246: }
1247: if (!contentTypeSet) {
1248: this.exception = "Builder does not support content type " + contentType;
1249: }
1250: }
1251: if (top.jsUnitGetParm('ignoringcomments')) {
1252: if (top.jsUnitGetParm('ignoringcomments') == 'true') {
1253: builder.setImplementationAttribute('ignoringComments', true);
1254: } else {
1255: builder.setImplementationAttribute('ignoringComments', false);
1256: }
1257: }
1258: } else {
1259: builder = new IFrameBuilder();
1260: }
1261: return builder;
1262: }
1263:
1264:
1265: function preload(frame, varname, url) {
1266: return builder.preload(frame, varname, url);
1267: }
1268:
1269: function load(frame, varname, url) {
1270: return builder.load(frame, varname, url);
1271: }
1272:
1273: function getImplementationAttribute(attr) {
1274: return builder.getImplementationAttribute(attr);
1275: }
1276:
1277:
1278: function setImplementationAttribute(attribute, value) {
1279: builder.setImplementationAttribute(attribute, value);
1280: }
1281:
1.44 ! carnold 1282: function setAsynchronous(value) {
! 1283: if (builder.supportsAsyncChange) {
! 1284: builder.async = value;
! 1285: } else {
! 1286: update();
! 1287: }
! 1288: }
! 1289:
! 1290:
1.42 dom-ts-4 1291: function createXPathEvaluator(doc) {
1292: try {
1293: return doc.getFeature("XPath", null);
1294: }
1295: catch(ex) {
1296: }
1297: return doc;
1298: }
1299:
1300: function toLowerArray(src) {
1301: var newArray = new Array();
1302: var i;
1303: for (i = 0; i < src.length; i++) {
1304: newArray[i] = src[i].toLowerCase();
1305: }
1306: return newArray;
1307: }
1308:
1309: function MSXMLBuilder_onreadystatechange() {
1310: if (builder.parser.readyState == 4) {
1311: loadComplete();
1312: }
1313: }
1314:
1315:
1.44 ! carnold 1316:
1.42 dom-ts-4 1317: var fileBase = location.href;
1318: if (fileBase.indexOf('?') != -1) {
1319: fileBase = fileBase.substring(0, fileBase.indexOf('?'));
1320: }
1321: fileBase = fileBase.substring(0, fileBase.lastIndexOf('/') + 1) + "files/";
1322:
1.43 carnold 1323: function getResourceURI(name, scheme, contentType) {
1324: return fileBase + name + getSuffix(contentType);
1325: }
1326:
1327:
1.42 dom-ts-4 1328: function getImplementation() {
1329: return builder.getImplementation();
1330: }
1331:
Webmaster