summaryrefslogtreecommitdiffstats
path: root/dom/xslt/tests/buster
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/xslt/tests/buster
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/xslt/tests/buster')
-rw-r--r--dom/xslt/tests/buster/DiffDOM.js103
-rw-r--r--dom/xslt/tests/buster/DumpDOM.js85
-rw-r--r--dom/xslt/tests/buster/ReadMe22
-rw-r--r--dom/xslt/tests/buster/buster-files.js81
-rw-r--r--dom/xslt/tests/buster/buster-handlers.js37
-rw-r--r--dom/xslt/tests/buster/buster-statics.js87
-rw-r--r--dom/xslt/tests/buster/buster-test.js356
-rw-r--r--dom/xslt/tests/buster/buster-view.js193
-rw-r--r--dom/xslt/tests/buster/buster.css20
-rw-r--r--dom/xslt/tests/buster/buster.xul196
-rw-r--r--dom/xslt/tests/buster/helper/generate-rdf.pl95
-rw-r--r--dom/xslt/tests/buster/install.js17
-rw-r--r--dom/xslt/tests/buster/jar.mn18
-rw-r--r--dom/xslt/tests/buster/result-inspector.xul37
-rw-r--r--dom/xslt/tests/buster/result-view.css16
-rw-r--r--dom/xslt/tests/buster/result-view.js105
-rw-r--r--dom/xslt/tests/buster/result-view.xul46
-rw-r--r--dom/xslt/tests/buster/xslt-qa-overlay.js10
-rw-r--r--dom/xslt/tests/buster/xslt-qa-overlay.xul12
19 files changed, 1536 insertions, 0 deletions
diff --git a/dom/xslt/tests/buster/DiffDOM.js b/dom/xslt/tests/buster/DiffDOM.js
new file mode 100644
index 000000000..587214ff3
--- /dev/null
+++ b/dom/xslt/tests/buster/DiffDOM.js
@@ -0,0 +1,103 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// ----------------------
+// DiffDOM(node1,node2)
+// ----------------------
+
+var isHTML = false;
+
+function DiffDOM(node1, node2, aIsHTML)
+{
+ isHTML = aIsHTML;
+ return DiffNodeAndChildren(node1, node2);
+}
+
+
+// namespace attributes in the second node are ignored
+const nsreg = /^xmlns[|:\w]/;
+
+// This function does the work of DiffDOM by recursively calling
+// itself to explore the tree
+function DiffNodeAndChildren(node1, node2)
+{
+ if (!node1 && !node2)
+ return true;
+ if (!node1 || !node2)
+ return ErrorUp("One of the nodes is null", node1, node2);
+ if (node1.type!=node2.type)
+ return ErrorUp("Different node types", node1, node2);
+
+ var attributes = node2.attributes;
+ if (attributes && attributes.length) {
+ var item, name, ns, value, otherValue;
+ for (var index = 0; index < attributes.length; index++) {
+ item = attributes.item(index);
+ ns = item.namespaceURI;
+ if (ns) {
+ name = item.localName;
+ otherValue = node2.getAttributeNS(ns, name);
+ }
+ else {
+ name = item.nodeName;
+ otherValue = node2.getAttribute(name);
+ }
+ value = item.nodeValue;
+ if (!nsreg.test(name) && otherValue!=value) {
+ return ErrorUp("Different values for attribute", node1, node2);
+ }
+ }
+ }
+ else if (node1.attributes && node1.attributes.length) {
+ return ErrorUp("Different number of attributes", node1, node2);
+ }
+
+ if (isHTML) {
+ if (node1.nodeName.toLowerCase()!=node2.nodeName.toLowerCase())
+ return ErrorUp("Different node names", node1, node2);
+ }
+ else {
+ if (node1.nodeName!=node2.nodeName)
+ return ErrorUp("Different node names", node1, node2);
+ }
+ if (node1.nodeValue!=node2.nodeValue)
+ return ErrorUp("Different node values", node1, node2);
+ if (!isHTML)
+ if (node1.namespaceURI!=node2.namespaceURI)
+ return ErrorUp("Different namespace", node1, node2);
+ if (node1.hasChildNodes() != node2.hasChildNodes())
+ return ErrorUp("Different children", node1, node2);
+ if (node1.childNodes) {
+ if (node1.childNodes.length != node2.childNodes.length)
+ return ErrorUp("Different number of children", node1, node2);
+ for (var child = 0; child < node1.childNodes.length; child++) {
+ if (!DiffNodeAndChildren(node1.childNodes[child],
+ node2.childNodes[child])) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+function ErrorUp(errMsg, node1, node2)
+{
+ dump("Error: "+errMsg+"\n");
+ if (node1) {
+ dump("Node 1: "+node1+", ");
+ if (node1.nodeType == Node.TEXT_NODE)
+ dump("nodeValue: "+node1.nodeValue+"\n");
+ else
+ dump("nodeName: "+node1.namespaceURI+":"+node1.nodeName+"\n");
+ }
+ if (node2) {
+ dump("Node 2: "+node2+", ");
+ if (node2.nodeType == Node.TEXT_NODE)
+ dump("nodeValue: "+node2.nodeValue+"\n");
+ else
+ dump("nodeName: "+node2.namespaceURI+":"+node2.nodeName+"\n");
+ }
+ return false;
+}
diff --git a/dom/xslt/tests/buster/DumpDOM.js b/dom/xslt/tests/buster/DumpDOM.js
new file mode 100644
index 000000000..0a90ce9d0
--- /dev/null
+++ b/dom/xslt/tests/buster/DumpDOM.js
@@ -0,0 +1,85 @@
+// ----------------------
+// DumpDOM(node)
+//
+// Call this function to dump the contents of the DOM starting at the specified node.
+// Use node = document.documentElement to dump every element of the current document.
+// Use node = top.window.document.documentElement to dump every element.
+//
+// 8-13-99 Updated to dump almost all attributes of every node. There are still some attributes
+// that are purposely skipped to make it more readable.
+// ----------------------
+function DumpDOM(node)
+{
+ dump("--------------------- DumpDOM ---------------------\n");
+
+ DumpNodeAndChildren(node, "");
+
+ dump("------------------- End DumpDOM -------------------\n");
+}
+
+
+// This function does the work of DumpDOM by recursively calling itself to explore the tree
+function DumpNodeAndChildren(node, prefix)
+{
+ dump(prefix + "<" + node.nodeName);
+
+ var attributes = node.attributes;
+
+ if ( attributes && attributes.length )
+ {
+ var item, name, value;
+
+ for ( var index = 0; index < attributes.length; index++ )
+ {
+ item = attributes.item(index);
+ name = item.nodeName;
+ value = item.nodeValue;
+
+ if ( (name == 'lazycontent' && value == 'true') ||
+ (name == 'xulcontentsgenerated' && value == 'true') ||
+ (name == 'id') ||
+ (name == 'instanceOf') )
+ {
+ // ignore these
+ }
+ else
+ {
+ dump(" " + name + "=\"" + value + "\"");
+ }
+ }
+ }
+
+ if ( node.nodeType == 1 )
+ {
+ // id
+ var text = node.getAttribute('id');
+ if ( text && text[0] != '$' )
+ dump(" id=\"" + text + "\"");
+ }
+
+ if ( node.nodeType == Node.TEXT_NODE )
+ dump(" = \"" + node.data + "\"");
+
+ dump(">\n");
+
+ // dump IFRAME && FRAME DOM
+ if ( node.nodeName == "IFRAME" || node.nodeName == "FRAME" )
+ {
+ if ( node.name )
+ {
+ var wind = top.frames[node.name];
+ if ( wind && wind.document && wind.document.documentElement )
+ {
+ dump(prefix + "----------- " + node.nodeName + " -----------\n");
+ DumpNodeAndChildren(wind.document.documentElement, prefix + " ");
+ dump(prefix + "--------- End " + node.nodeName + " ---------\n");
+ }
+ }
+ }
+ // children of nodes (other than frames)
+ else if ( node.childNodes )
+ {
+ for ( var child = 0; child < node.childNodes.length; child++ )
+ DumpNodeAndChildren(node.childNodes[child], prefix + " ");
+ }
+}
diff --git a/dom/xslt/tests/buster/ReadMe b/dom/xslt/tests/buster/ReadMe
new file mode 100644
index 000000000..82ad04d96
--- /dev/null
+++ b/dom/xslt/tests/buster/ReadMe
@@ -0,0 +1,22 @@
+The buster is a XUL interface to the conformance tests shipped as part of
+Xalan. For information about Xalan, please see http://xml.apache.org/.
+For your convenience we provide a packed distribution of all needed files
+in http://www.axel.pike.org/mozilla/xalan.tar.gz. Please see the included
+LICENSE.txt or http://xml.apache.org/dist/LICENSE.txt for terms of
+distributing those files.
+
+To use the buster, open buster.xul with an XSLT enabled Mozilla.
+Open the rdf index file shipped with the test package into the
+"Xalan index", and the available tests will show up as a tree.
+Once you have selected the tests you're interested in, press the button
+"run checked tests", and all the tests will be run.
+You can save the results into an rdf, and load it for comparison and
+regression hunting.
+
+DiffDOM tries to find out, which tests failed, and will DumpDOM both the
+result and the reference solution. Not all reference solutions load
+properly, those need manual love.
+
+Good luck and fun
+
+Axel Hecht <axel@pike.org>
diff --git a/dom/xslt/tests/buster/buster-files.js b/dom/xslt/tests/buster/buster-files.js
new file mode 100644
index 000000000..cbdb8bdd2
--- /dev/null
+++ b/dom/xslt/tests/buster/buster-files.js
@@ -0,0 +1,81 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const kFileOutStreamCID = "@mozilla.org/network/file-output-stream;1";
+const nsIFileOutputStream = Components.interfaces.nsIFileOutputStream;
+
+var cmdFileController =
+{
+ supportsCommand: function(aCommand)
+ {
+ switch(aCommand) {
+ case 'cmd_fl_save':
+ case 'cmd_fl_import':
+ return true;
+ default:
+ }
+ return false;
+ },
+ isCommandEnabled: function(aCommand)
+ {
+ return this.supportsCommand(aCommand);
+ },
+ doCommand: function(aCommand)
+ {
+ switch(aCommand) {
+ case 'cmd_fl_save':
+ var sink = new Object;
+ sink.write = function(aContent, aCount)
+ {
+ // replace NC:succ with NC:orig_succ,
+ // so the rdf stuff differs
+ var content = aContent.replace(/NC:succ/g,"NC:orig_succ");
+ content = content.replace(/NC:failCount/g,"NC:orig_failCount");
+ this.mSink.write(content, content.length);
+ return aCount;
+ };
+ var fp = doCreateRDFFP('Xalan results',
+ nsIFilePicker.modeSave);
+ var res = fp.show();
+
+ if (res == nsIFilePicker.returnOK ||
+ res == nsIFilePicker.returnReplace) {
+ var serial = doCreate(kRDFXMLSerializerID,
+ nsIRDFXMLSerializer);
+ serial.init(view.mResultDS);
+ serial.QueryInterface(nsIRDFXMLSource);
+ var fl = fp.file;
+ var fstream = doCreate(kFileOutStreamCID,
+ nsIFileOutputStream);
+ fstream.init(fl, 26, 420, 0);
+ sink.mSink = fstream;
+ serial.Serialize(sink);
+ }
+ break;
+ case 'cmd_fl_import':
+ var fp = doCreateRDFFP('Previous Xalan results',
+ nsIFilePicker.modeLoad);
+ var res = fp.show();
+
+ if (res == nsIFilePicker.returnOK) {
+ var fl = fp.file;
+ if (view.mPreviousResultDS) {
+ view.database.RemoveDataSource(view.mPreviousResultDS);
+ view.mPreviousResultDS = null;
+ }
+ view.mPreviousResultDS = kRDFSvc.GetDataSource(fp.fileURL.spec);
+ view.database.AddDataSource(view.mPreviousResultDS);
+ }
+
+ document.getElementById('obs_orig_success')
+ .setAttribute('hidden','false');
+ break;
+ default:
+ alert('Unknown Command'+aCommand);
+ }
+ }
+};
+
+registerController(cmdFileController);
diff --git a/dom/xslt/tests/buster/buster-handlers.js b/dom/xslt/tests/buster/buster-handlers.js
new file mode 100644
index 000000000..4e6f85fcc
--- /dev/null
+++ b/dom/xslt/tests/buster/buster-handlers.js
@@ -0,0 +1,37 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var xalan_field;
+
+function onLoad()
+{
+ view.tree = document.getElementById('out');
+ view.boxObject = view.tree.boxObject;
+ {
+ view.mIframe = document.getElementById('hiddenHtml');
+ view.mIframe.webNavigation.allowPlugins = false;
+ view.mIframe.webNavigation.allowJavascript = false;
+ view.mIframe.webNavigation.allowMetaRedirects = false;
+ view.mIframe.webNavigation.allowImages = false;
+ }
+ view.database = view.tree.database;
+ view.builder = view.tree.builder.QueryInterface(nsIXULTemplateBuilder);
+ view.builder.QueryInterface(nsIXULTreeBuilder);
+ runItem.prototype.kDatabase = view.database;
+ xalan_field = document.getElementById("xalan_rdf");
+ var persistedUrl = xalan_field.getAttribute('url');
+ if (persistedUrl) {
+ view.xalan_url = persistedUrl;
+ xalan_field.value = persistedUrl;
+ }
+ view.setDataSource();
+ return true;
+}
+
+function onUnload()
+{
+ if (xalan_field)
+ xalan_field.setAttribute('url', xalan_field.value);
+}
diff --git a/dom/xslt/tests/buster/buster-statics.js b/dom/xslt/tests/buster/buster-statics.js
new file mode 100644
index 000000000..b70cef511
--- /dev/null
+++ b/dom/xslt/tests/buster/buster-statics.js
@@ -0,0 +1,87 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// helper function to shortcut component creation
+function doCreate(aContract, aInterface)
+{
+ return Components.classes[aContract].createInstance(aInterface);
+}
+
+// for the items, loading a text file
+const IOSERVICE_CTRID = "@mozilla.org/network/io-service;1";
+const nsIIOService = Components.interfaces.nsIIOService;
+const SIS_CTRID = "@mozilla.org/scriptableinputstream;1"
+const nsISIS = Components.interfaces.nsIScriptableInputStream;
+
+// rdf foo, onload handler
+const kRDFSvcContractID = "@mozilla.org/rdf/rdf-service;1";
+const kRDFInMemContractID =
+ "@mozilla.org/rdf/datasource;1?name=in-memory-datasource";
+const kRDFContUtilsID = "@mozilla.org/rdf/container-utils;1";
+const kRDFXMLSerializerID = "@mozilla.org/rdf/xml-serializer;1";
+const kIOSvcContractID = "@mozilla.org/network/io-service;1";
+const kStandardURL = Components.classes["@mozilla.org/network/standard-url;1"];
+const nsIURL = Components.interfaces.nsIURL;
+const nsIStandardURL = Components.interfaces.nsIStandardURL;
+const nsIFilePicker = Components.interfaces.nsIFilePicker;
+const nsIXULTreeBuilder = Components.interfaces.nsIXULTreeBuilder;
+const nsIXULTemplateBuilder = Components.interfaces.nsIXULTemplateBuilder;
+const kIOSvc = Components.classes[kIOSvcContractID]
+ .getService(Components.interfaces.nsIIOService);
+const nsIRDFService = Components.interfaces.nsIRDFService;
+const nsIRDFDataSource = Components.interfaces.nsIRDFDataSource;
+const nsIRDFRemoteDataSource = Components.interfaces.nsIRDFRemoteDataSource;
+const nsIRDFPurgeableDataSource =
+ Components.interfaces.nsIRDFPurgeableDataSource;
+const nsIRDFResource = Components.interfaces.nsIRDFResource;
+const nsIRDFLiteral = Components.interfaces.nsIRDFLiteral;
+const nsIRDFInt = Components.interfaces.nsIRDFInt;
+const nsIRDFContainerUtils = Components.interfaces.nsIRDFContainerUtils;
+const nsIRDFXMLSerializer = Components.interfaces.nsIRDFXMLSerializer;
+const nsIRDFXMLSource = Components.interfaces.nsIRDFXMLSource;
+const kRDFSvc =
+ Components.classes[kRDFSvcContractID].getService(nsIRDFService);
+const krTypeCat = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#category");
+const krTypeFailCount = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#failCount");
+const krTypeName = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#name");
+const krTypeSucc = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#succ");
+const krTypeOrigSucc = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#orig_succ");
+const krTypeOrigFailCount = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#orig_failCount");
+const krTypeOrigSuccCount = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#orig_succCount");
+const krTypePath = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#path");
+const krTypeParent = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#parent");
+const krTypePurp = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#purp");
+const krTypeSuccCount = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#succCount");
+const kGood = kRDFSvc.GetLiteral("yes");
+const kBad = kRDFSvc.GetLiteral("no");
+const kMixed = kRDFSvc.GetLiteral("+-");
+const kContUtils = doCreate(kRDFContUtilsID, nsIRDFContainerUtils);
+
+function doCreateRDFFP(aTitle, aMode)
+{
+ var fp = doCreate("@mozilla.org/filepicker;1", nsIFilePicker);
+ fp.init(window, aTitle, aMode);
+ fp.appendFilter('*.rdf', '*.rdf');
+ fp.appendFilters(nsIFilePicker.filterAll);
+ return fp;
+}
+
+function goDoCommand(aCommand)
+{
+ try {
+ var controller =
+ top.document.commandDispatcher.getControllerForCommand(aCommand);
+ if (controller && controller.isCommandEnabled(aCommand))
+ controller.doCommand(aCommand);
+ }
+ catch(e) {
+ dump("An error "+e+" occurred executing the "+aCommand+" command\n");
+ }
+}
+
+function registerController(aController)
+{
+ top.controllers.appendController(aController);
+}
diff --git a/dom/xslt/tests/buster/buster-test.js b/dom/xslt/tests/buster/buster-test.js
new file mode 100644
index 000000000..2cc838685
--- /dev/null
+++ b/dom/xslt/tests/buster/buster-test.js
@@ -0,0 +1,356 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+Components.utils.import("resource://gre/modules/NetUtil.jsm");
+
+var parser = new DOMParser();
+var methodExpr = (new XPathEvaluator).createExpression("xsl:output/@method",
+ {
+ lookupNamespaceURI: function(aPrefix)
+ {
+ if (aPrefix == "xsl")
+ return "http://www.w3.org/1999/XSL/Transform";
+ return "";
+ }
+ });
+
+const nsIWebProgListener = Components.interfaces.nsIWebProgressListener;
+
+var runQueue =
+{
+ mArray : new Array(),
+ push : function(aRunItem)
+ {
+ this.mArray.push(aRunItem);
+ },
+ observe : function(aSubject, aTopic, aData)
+ {
+ var item = this.mArray.shift();
+ if (item) {
+ item.run(this);
+ }
+ },
+ run : function()
+ {
+ this.observe(null,'','');
+ }
+}
+
+var itemCache =
+{
+ mArray : new Array(),
+ getItem : function(aResource)
+ {
+ // Directory selected
+ if (kContUtils.IsSeq(runItem.prototype.kDatabase, aResource)) {
+ var aSeq = kContUtils.MakeSeq(runItem.prototype.kDatabase, aResource);
+ dump("sequence: "+aSeq+" with "+aSeq.GetCount()+" elements\n");
+ var child, children = aSeq.GetElements();
+ var m = 0, first;
+ while (children.hasMoreElements()) {
+ m += 1;
+ child = children.getNext();
+ child.QueryInterface(nsIRDFResource);
+ if (!first)
+ first = itemCache.getItem(child);
+ else
+ itemCache.getItem(child);
+ }
+ return first;
+ }
+ if (aResource.Value in this.mArray) {
+ return this.mArray[aResource.Value];
+ }
+ var retItem = new runItem(aResource);
+ this.mArray[aResource.Value] = retItem;
+ runQueue.push(retItem);
+ return retItem;
+ },
+ rerunItem : function(aResource, aObserver)
+ {
+ var anItem = new runItem(aResource);
+ this.mArray[aResource.Value] = anItem;
+ anItem.run(aObserver);
+ },
+ observe : function(aSubject, aTopic, aData)
+ {
+ this.mRun += 1;
+ if (aTopic == "success") {
+ if (aData == "yes") {
+ this.mGood += 1;
+ }
+ else {
+ this.mFalse +=1;
+ }
+ }
+ }
+}
+
+function runItem(aResource)
+{
+ this.mResource = aResource;
+ // Directory selected
+ if (kContUtils.IsSeq(this.kDatabase,this.mResource)) {
+ var aSeq = kContUtils.MakeSeq(this.kDatabase,this.mResource);
+ dump("THIS SHOULDN'T HAPPEN\n");
+ var child, children = aSeq.GetElements();
+ var m = 0;
+ while (children.hasMoreElements()) {
+ m += 1;
+ child = children.getNext();
+ child.QueryInterface(nsIRDFResource);
+ itemCache.getItem(child);
+ }
+ }
+}
+
+runItem.prototype =
+{
+ // RDF resource associated with this test
+ mResource : null,
+ // XML documents for the XSLT transformation
+ mSourceDoc : null,
+ mStyleDoc : null,
+ mResDoc : null,
+ // XML or plaintext document for the reference
+ mRefDoc : null,
+ // bitfield signaling the loaded documents
+ mLoaded : 0,
+ kSource : 1,
+ kStyle : 2,
+ kReference : 4,
+ // a observer, potential argument to run()
+ mObserver : null,
+ mSuccess : null,
+ mMethod : 'xml',
+ // XSLTProcessor, shared by the instances
+ kProcessor : new XSLTProcessor(),
+ kXalan : kStandardURL.createInstance(nsIURL),
+ kDatabase : null,
+ kObservers : new Array(),
+
+ run : function(aObserver)
+ {
+ if (aObserver && typeof(aObserver)=='function' ||
+ (typeof(aObserver)=='object' &&
+ typeof(aObserver.observe)=='function')) {
+ this.mObserver=aObserver;
+ }
+ var name = this.kDatabase.GetTarget(this.mResource, krTypeName, true);
+ if (name) {
+ var cat = this.kDatabase.GetTarget(this.mResource, krTypeCat, true);
+ var path = this.kDatabase.GetTarget(this.mResource, krTypePath, true);
+ cat = cat.QueryInterface(nsIRDFLiteral);
+ name = name.QueryInterface(nsIRDFLiteral);
+ path = path.QueryInterface(nsIRDFLiteral);
+ var xalan_fl = this.kXalan.resolve(cat.Value+"/"+path.Value);
+ var xalan_ref = this.kXalan.resolve(cat.Value+"-gold/"+path.Value);
+ this.mRefURL =
+ this.kXalan.resolve(cat.Value + "-gold/" + path.Value + ".out");
+ dump(name.Value+" links to "+xalan_fl+"\n");
+ }
+ // Directory selected
+ if (kContUtils.IsSeq(this.kDatabase,this.mResource)) {
+ return;
+ var aSeq = kContUtils.MakeSeq(this.kDatabase,this.mResource);
+ dump("sequence: "+aSeq+" with "+aSeq.GetCount()+" elements\n");
+ var child, children = aSeq.GetElements();
+ var m = 0;
+ while (children.hasMoreElements()) {
+ m += 1;
+ child = children.getNext();
+ child.QueryInterface(nsIRDFResource);
+ }
+ }
+ this.mSourceDoc = document.implementation.createDocument('', '', null);
+ this.mSourceDoc.addEventListener("load",this.onload(1),false);
+ this.mSourceDoc.load(xalan_fl+".xml");
+ this.mStyleDoc = document.implementation.createDocument('', '', null);
+ this.mStyleDoc.addEventListener("load",this.styleLoaded(),false);
+ this.mStyleDoc.load(xalan_fl+".xsl");
+ },
+
+ // nsIWebProgressListener
+ QueryInterface: function(aIID)
+ {
+ return this;
+ },
+ onStateChange: function(aProg, aRequest, aFlags, aStatus)
+ {
+ if ((aFlags & nsIWebProgListener.STATE_STOP) &&
+ (aFlags & nsIWebProgListener.STATE_IS_DOCUMENT)) {
+ aProg.removeProgressListener(this);
+ this.mRefDoc = document.getElementById('hiddenHtml').contentDocument;
+ this.fileLoaded(4);
+ }
+ },
+ onProgressChange: function(aProg, b,c,d,e,f)
+ {
+ },
+ onLocationChange: function(aProg, aRequest, aURI, aFlags)
+ {
+ },
+ onStatusChange: function(aProg, aRequest, aStatus, aMessage)
+ {
+ },
+ onSecurityChange: function(aWebProgress, aRequest, aState)
+ {
+ },
+
+ // onload handler helper
+ onload : function(file)
+ {
+ var self = this;
+ return function(e)
+ {
+ return self.fileLoaded(file);
+ };
+ },
+
+ styleLoaded : function()
+ {
+ var self = this;
+ return function(e)
+ {
+ return self.styleLoadedHelper();
+ };
+ },
+ styleLoadedHelper : function()
+ {
+ var method = methodExpr.evaluate(this.mStyleDoc.documentElement, 2,
+ null).stringValue;
+ var refContent;
+ if (!method) {
+ // implicit method, guess from result
+ refContent = this.loadTextFile(this.mRefURL);
+ if (refContent.match(/^\s*<html/gi)) {
+ method = 'html';
+ }
+ else {
+ method = 'xml';
+ }
+ }
+ this.mMethod = method;
+
+ switch (method) {
+ case 'xml':
+ if (!refContent) {
+ refContent = this.loadTextFile(this.mRefURL);
+ }
+ this.mRefDoc = parser.parseFromString(refContent, 'application/xml');
+ this.mLoaded += 4;
+ break;
+ case 'html':
+ view.loadHtml(this.mRefURL, this);
+ break;
+ case 'text':
+ if (!refContent) {
+ refContent = this.loadTextFile(this.mRefURL);
+ }
+ const ns = 'http://www.mozilla.org/TransforMiix';
+ const qn = 'transformiix:result';
+ this.mRefDoc =
+ document.implementation.createDocument(ns, qn, null);
+ var txt = this.mRefDoc.createTextNode(refContent);
+ this.mRefDoc.documentElement.appendChild(txt);
+ this.mLoaded += 4;
+ break;
+ default:
+ throw "unkown XSLT output method";
+ }
+ this.fileLoaded(2)
+ },
+
+ fileLoaded : function(mask)
+ {
+ this.mLoaded += mask;
+ if (this.mLoaded < 7) {
+ return;
+ }
+ this.doTransform();
+ },
+
+ doTransform : function()
+ {
+ this.kProcessor.reset();
+ try {
+ this.kProcessor.importStylesheet(this.mStyleDoc);
+ this.mResDoc =
+ this.kProcessor.transformToDocument(this.mSourceDoc);
+ this.mRefDoc.normalize();
+ isGood = DiffDOM(this.mResDoc.documentElement,
+ this.mRefDoc.documentElement,
+ this.mMethod == 'html');
+ } catch (e) {
+ isGood = false;
+ };
+ dump("This succeeded. "+isGood+"\n");
+ isGood = isGood.toString();
+ for (var i=0; i<this.kObservers.length; i++) {
+ var aObs = this.kObservers[i];
+ if (typeof(aObs)=='object' && typeof(aObs.observe)=='function') {
+ aObs.observe(this.mResource, 'success', isGood);
+ }
+ else if (typeof(aObs)=='function') {
+ aObs(this.mResource, 'success', isGood);
+ }
+ }
+ if (this.mObserver) {
+ if (typeof(this.mObserver)=='object') {
+ this.mObserver.observe(this.mResource, 'success', isGood);
+ }
+ else {
+ this.mObserver(this.mResource, 'success', isGood);
+ }
+ }
+ },
+
+ loadTextFile : function(url)
+ {
+ var chan = NetUtil.newChannel({
+ uri: url,
+ loadUsingSystemPrincipal: true
+ });
+ var instream = doCreate(SIS_CTRID, nsISIS);
+ instream.init(chan.open2());
+
+ return instream.read(instream.available());
+ }
+}
+
+runItem.prototype.kXalan.QueryInterface(nsIStandardURL);
+
+var cmdTestController =
+{
+ supportsCommand: function(aCommand)
+ {
+ switch(aCommand) {
+ case 'cmd_tst_run':
+ case 'cmd_tst_runall':
+ return true;
+ default:
+ }
+ return false;
+ },
+ isCommandEnabled: function(aCommand)
+ {
+ return this.supportsCommand(aCommand);
+ },
+ doCommand: function(aCommand)
+ {
+ switch(aCommand) {
+ case 'cmd_tst_run':
+ dump("cmd_tst_run\n");
+ break;
+ case 'cmd_tst_runall':
+ dump("cmd_tst_runall\n");
+ var tst_run = document.getElementById('cmd_tst_run');
+ tst_run.doCommand();
+ default:
+ }
+ }
+};
+
+registerController(cmdTestController);
diff --git a/dom/xslt/tests/buster/buster-view.js b/dom/xslt/tests/buster/buster-view.js
new file mode 100644
index 000000000..3ee4af28c
--- /dev/null
+++ b/dom/xslt/tests/buster/buster-view.js
@@ -0,0 +1,193 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var view =
+{
+ onRun : function()
+ {
+ runQueue.mArray = new Array();
+ var sels = this.boxObject.view.selection,a=new Object(),b=new Object(),k;
+ var rowResource, name, path;
+ for (k=0;k<sels.getRangeCount();k++){
+ sels.getRangeAt(k,a,b);
+ for (var l=a.value;l<=b.value;l++) {
+ rowResource = this.builder.getResourceAtIndex(l);
+ itemCache.getItem(rowResource);
+ }
+ }
+ runQueue.run();
+ },
+ displayTest : function()
+ {
+ var current = this.boxObject.view.selection.currentIndex;
+ var rowResource = this.builder.getResourceAtIndex(current);
+ var item = itemCache.getItem(rowResource);
+ },
+ browseForRDF : function()
+ {
+ var fp = doCreateRDFFP('Xalan Description File',
+ nsIFilePicker.modeOpen);
+ var res = fp.show();
+
+ if (res == nsIFilePicker.returnOK) {
+ var furl = fp.fileURL;
+ this.setDataSource(fp.fileURL.spec);
+ }
+ },
+ dump_Good : function()
+ {
+ var enumi = this.mResultDS.GetSources(krTypeSucc, kGood, true);
+ var k = 0;
+ while (enumi.hasMoreElements()) {
+ k += 1;
+ dump(enumi.getNext().QueryInterface(nsIRDFResource).Value+"\n");
+ }
+ dump("found "+k+" good tests\n");
+ },
+ prune_ds : function()
+ {
+ if (this.mResultDS) {
+ this.mResultDS.QueryInterface(nsIRDFPurgeableDataSource).Sweep();
+ }
+ regressionStats.init()
+ itemCache.mArray = new Array();
+ },
+ setDataSource : function(aSpec)
+ {
+ var baseSpec;
+ if (aSpec) {
+ baseSpec = aSpec;
+ }
+ else {
+ baseSpec = document.getElementById("xalan_rdf").value;
+ }
+ if (this.mXalanDS && this.mXalanDS.URI == baseSpec) {
+ this.mXalanDS.QueryInterface(nsIRDFRemoteDataSource);
+ this.mXalanDS.Refresh(true);
+ }
+ else {
+ if (this.mXalanDS) {
+ this.database.RemoveDataSource(view.mXalanDS);
+ }
+ this.mXalanDS = kRDFSvc.GetDataSourceBlocking(baseSpec);
+ if (!this.mXalanDS) {
+ alert("Unable do load DataSource: "+baseSpec);
+ return;
+ }
+ this.database.AddDataSource(this.mXalanDS);
+ }
+ regressionStats.init();
+ if (!this.mResultDS) {
+ this.mResultDS = doCreate(kRDFInMemContractID,
+ nsIRDFDataSource);
+ this.database.AddDataSource(view.mResultDS);
+ if (!this.mResultDS) {
+ alert("Unable to create result InMemDatasource");
+ return;
+ }
+ }
+
+ this.builder.rebuild();
+ document.getElementById("xalan_rdf").value = baseSpec;
+ runItem.prototype.kXalan.init(runItem.prototype.kXalan.URLTYPE_STANDARD,
+ 0, baseSpec, null, null);
+ },
+ loadHtml : function(aUrl, aListener)
+ {
+ const nsIIRequestor = Components.interfaces.nsIInterfaceRequestor;
+ const nsIWebProgress = Components.interfaces.nsIWebProgress;
+ var req = this.mIframe.webNavigation.QueryInterface(nsIIRequestor);
+ var prog = req.getInterface(nsIWebProgress);
+ prog.addProgressListener(aListener, nsIWebProgress.NOTIFY_ALL);
+ this.mIframe.webNavigation.loadURI(aUrl, 0,null,null,null);
+ },
+ fillItemContext : function()
+ {
+ var index = view.boxObject.view.selection.currentIndex;
+ var res = view.builder.getResourceAtIndex(index);
+ var purp = view.mXalanDS.GetTarget(res, krTypePurp, true);
+ return (purp != null);
+ }
+}
+
+regressionStats =
+{
+ observe: function(aSubject, aTopic, aData)
+ {
+ if (aTopic != 'success') {
+ return;
+ }
+ var arc = (aData == "true") ? krTypeSuccCount : krTypeFailCount;
+ this.assertNewCount(aSubject, arc, 1);
+ },
+ init: function()
+ {
+ if (this.mRegressionDS) {
+ this.mRegressionDS.QueryInterface(nsIRDFPurgeableDataSource).Sweep();
+ }
+ else {
+ this.mRegressionDS =
+ doCreate(kRDFInMemContractID, nsIRDFDataSource);
+ view.database.AddDataSource(this.mRegressionDS);
+ }
+ },
+ getParent: function(aDS, aSource)
+ {
+ // parent chached?
+ var parent = this.mRegressionDS.GetTarget(aSource, krTypeParent, true);
+ if (!parent) {
+ var labels = view.mXalanDS.ArcLabelsIn(aSource);
+ while (labels.hasMoreElements()) {
+ var arc = labels.getNext().QueryInterface(nsIRDFResource);
+ if (arc.Value.match(this.mChildRE)) {
+ parent = view.mXalanDS.GetSource(arc, aSource, true);
+ // cache the parent
+ this.mRegressionDS.Assert(aSource, krTypeParent,
+ parent, true);
+ }
+ }
+ }
+ return parent;
+ },
+ assertNewCount: function(aSource, aArc, aIncrement)
+ {
+ var root = kRDFSvc.GetResource('urn:root');
+ var count = 0;
+ // parent chached?
+ var parent = this.getParent(view.XalanDS, aSource);
+ while (parent && !parent.EqualsNode(root)) {
+ var countRes = view.mResultDS.GetTarget(parent, aArc, true);
+ if (countRes) {
+ count = countRes.QueryInterface(nsIRDFInt).Value;
+ }
+ var newCountRes = kRDFSvc.GetIntLiteral(count + aIncrement);
+ if (!newCountRes) {
+ return;
+ }
+
+ if (countRes) {
+ view.mResultDS.Change(parent, aArc, countRes, newCountRes);
+ }
+ else {
+ view.mResultDS.Assert(parent, aArc, newCountRes, true);
+ }
+ parent = this.getParent(view.XalanDS, parent);
+ }
+ },
+ mRegressionDS: 0,
+ mChildRE: /http:\/\/www\.w3\.org\/1999\/02\/22-rdf-syntax-ns#_/
+}
+
+function rdfObserve(aSubject, aTopic, aData)
+{
+ if (aTopic == "success") {
+ var target = (aData == "true") ? kGood : kBad;
+ view.mResultDS.Assert(aSubject, krTypeSucc, target, true);
+
+ regressionStats.observe(aSubject, aTopic, aData);
+ }
+}
+
+runItem.prototype.kObservers.push(rdfObserve);
diff --git a/dom/xslt/tests/buster/buster.css b/dom/xslt/tests/buster/buster.css
new file mode 100644
index 000000000..fe11c10d9
--- /dev/null
+++ b/dom/xslt/tests/buster/buster.css
@@ -0,0 +1,20 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+label.head {
+ padding: 5px;
+ font-size: medium;
+ font-weight: bold;
+}
+
+treechildren::-moz-tree-cell(success yes)
+{
+ background-color: green ;
+}
+
+treechildren::-moz-tree-cell(success no)
+{
+ background-color: red ;
+}
diff --git a/dom/xslt/tests/buster/buster.xul b/dom/xslt/tests/buster/buster.xul
new file mode 100644
index 000000000..7191dff4e
--- /dev/null
+++ b/dom/xslt/tests/buster/buster.xul
@@ -0,0 +1,196 @@
+<?xml version="1.0"?><!-- -*- Mode: xml; tab-width: 2; indent-tabs-mode: nil -*- -->
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
+<?xml-stylesheet href="buster.css" type="text/css"?>
+
+<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
+<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
+
+<window id="XalanBuster"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="onLoad()" onunload="onUnload()"
+ title="Xalan testcase harness"
+ persist="width,height"
+ width="800"
+ height="600"
+ orient="vertical">
+<script type="application/x-javascript" src="buster-statics.js" />
+<script type="application/x-javascript" src="buster-test.js" />
+<script type="application/x-javascript" src="buster-view.js" />
+<script type="application/x-javascript" src="buster-handlers.js" />
+<script type="application/x-javascript" src="result-view.js" />
+<script type="application/x-javascript" src="buster-files.js" />
+<script type="application/x-javascript" src="DumpDOM.js" />
+<script type="application/x-javascript" src="DiffDOM.js" />
+
+<commands id="busterKing">
+ <commandset id="buster_file_cmds">
+ <command id="cmd_fl_save" oncommand="goDoCommand('cmd_fl_save')" />
+ <command id="cmd_fl_import" oncommand="goDoCommand('cmd_fl_import')"/>
+ </commandset>
+ <commandset id="buster_test_cmds">
+ <command id="cmd_tst_run" oncommand="goDoCommand('cmd_tst_run')" />
+ <command id="cmd_tst_runall" oncommand="goDoCommand('cmd_tst_runall')" />
+ </commandset>
+ <commandset id="commands">
+ <command id="cmd_quit"/>
+ <command id="cmd_close" oncommand="window.close();"/>
+ </commandset>
+</commands>
+
+<keyset>
+ <key id="key_quit"/>
+ <key id="key_close"/>
+</keyset>
+
+<broadcasterset>
+ <broadcaster id="obs_orig_success" hidden="true"/>
+ <broadcaster id="not_yet" disabled="true"/>
+</broadcasterset>
+
+
+<menubar>
+ <menu id="menu_File" label="File" accesskey="f">
+ <menupopup id="menu_FilePopup">
+ <menuitem label="Save results ..." accesskey="s"
+ observes="cmd_fl_save"/>
+ <menuitem label="Import results ..." accesskey="i"
+ observes="cmd_fl_import"/>
+ <menuitem id="menu_close"/>
+ </menupopup>
+ </menu>
+ <menu id="busterTests" label="Tests" accesskey="t">
+ <menupopup id="tests-popup">
+ <menuitem label="run a test" accesskey="r"
+ observes="cmd_tst_run"/>
+ <menuitem label="run all tests" accesskey="a"
+ observes="cmd_tst_runall"/>
+ </menupopup>
+ </menu>
+</menubar>
+
+<popupset>
+ <popup id="itemcontext" onpopupshowing="return view.fillItemContext();">
+ <menuitem label="View Test" oncommand="onNewResultView(event)"/>
+ </popup>
+</popupset>
+
+<hbox>
+ <button label="check all" oncommand="check(true)" observes="not_yet"/>
+ <button label="uncheck all" oncommand="check(false)" observes="not_yet"/>
+ <button label="reset success" oncommand="view.prune_ds()" />
+ <button label="run checked tests" oncommand="view.onRun()" />
+</hbox>
+<hbox>
+ <label value="Xalan index: " class="head"/>
+ <textbox id="xalan_rdf" persist="url" crop="end" size="40"/>
+ <button label="browse..." oncommand="view.browseForRDF()" />
+</hbox>
+<hbox>
+<groupbox orient="horizontal"><caption label="search" />
+ <button label="Search for " oncommand="select()" observes="not_yet"/>
+ <textbox style="width: 10em;" id="search-name" persist="value" /><label value=" in " />
+ <menulist id="search-field" persist="data" observes="not_yet">
+ <menupopup>
+ <menuitem value="1" label="Name" />
+ <menuitem value="2" label="Purpose" />
+ <menuitem value="3" label="Comment" />
+ </menupopup>
+ </menulist>
+</groupbox>
+<spacer flex="1" /></hbox>
+
+<tree id="out" flex="1" flags="dont-build-content" hidecolumnpicker="true"
+ datasources="rdf:null" ref="urn:root" context="itemcontext">
+ <treecols>
+ <treecol id="NameColumn" flex="1" label="Name" sort="?name"
+ primary="true" />
+ <splitter class="tree-splitter" />
+ <treecol id="PurpsColumn" flex="2" label="Purpose" sort="?purp" />
+ <splitter class="tree-splitter" />
+ <treecol id="SuccessColumn" flex="0" label="Success" />
+ <splitter class="tree-splitter" observes="obs_orig_success" />
+ <treecol id="OrigSuccessColumn" flex="0" label="Previously"
+ observes="obs_orig_success" />
+ </treecols>
+ <template>
+ <rule>
+ <conditions>
+ <content uri="?uri" />
+ <member container="?uri" child="?subheading" />
+ <triple subject="?subheading"
+ predicate="http://home.netscape.com/NC-rdf#purp"
+ object="?purp" />
+ </conditions>
+
+ <bindings>
+ <binding subject="?subheading"
+ predicate="http://home.netscape.com/NC-rdf#name"
+ object="?name" />
+ <binding subject="?subheading"
+ predicate="http://home.netscape.com/NC-rdf#succ"
+ object="?succ" />
+ <binding subject="?subheading"
+ predicate="http://home.netscape.com/NC-rdf#orig_succ"
+ object="?orig_succ" />
+ </bindings>
+
+ <action>
+ <treechildren>
+ <treeitem uri="?subheading">
+ <treerow>
+ <treecell ref="NameColumn" label="?name" />
+ <treecell ref="PurpsColumn" label="?purp" />
+ <treecell ref="SuccessColumn" label="?succ"
+ properties="success ?succ"/>
+ <treecell ref="OrigSuccessColumn" label="?orig_succ"
+ properties="success ?orig_succ" />
+ </treerow>
+ </treeitem>
+ </treechildren>
+ </action>
+ </rule>
+ <rule>
+ <conditions>
+ <content uri="?uri" />
+ <member container="?uri" child="?subheading" />
+ </conditions>
+
+ <bindings>
+ <binding subject="?subheading"
+ predicate="http://home.netscape.com/NC-rdf#dir"
+ object="?dir" />
+ <binding subject="?subheading"
+ predicate="http://home.netscape.com/NC-rdf#succCount"
+ object="?succ" />
+ <binding subject="?subheading"
+ predicate="http://home.netscape.com/NC-rdf#failCount"
+ object="?fail" />
+ <binding subject="?subheading"
+ predicate="http://home.netscape.com/NC-rdf#orig_succCount"
+ object="?orig_succ" />
+ <binding subject="?subheading"
+ predicate="http://home.netscape.com/NC-rdf#orig_failCount"
+ object="?orig_fail" />
+ </bindings>
+
+ <action>
+ <treechildren>
+ <treeitem uri="?subheading">
+ <treerow>
+ <treecell ref="NameColumn" label="?dir" />
+ <treecell ref="PurpsColumn" label="" />
+ <treecell ref="SuccessColumn" label="?succ / ?fail" />
+ <treecell ref="OrigSuccessColumn" label="?orig_succ / ?orig_fail" />
+ </treerow>
+ </treeitem>
+ </treechildren>
+ </action>
+ </rule>
+ </template>
+</tree>
+<iframe style="visibility:hidden; height:0px;" id="hiddenHtml" />
+</window>
diff --git a/dom/xslt/tests/buster/helper/generate-rdf.pl b/dom/xslt/tests/buster/helper/generate-rdf.pl
new file mode 100644
index 000000000..c2bdc7b92
--- /dev/null
+++ b/dom/xslt/tests/buster/helper/generate-rdf.pl
@@ -0,0 +1,95 @@
+use File::Spec;
+
+my(@chunks, @list, $entry, $main_cats, $spacing);
+@list = ('conf', 'perf');
+foreach $entry (@list) {
+ $main_cats .= " <rdf:li><rdf:Description about=\"urn:x-buster:$entry\" nc:dir=\"$entry\" /></rdf:li>\n";
+ go_in($entry, '', $entry);
+}
+if ($ARGV[0]) {
+ open OUTPUT, ">$ARGV[0]";
+}
+else {
+ open OUTPUT, ">xalan.rdf";
+};
+select(OUTPUT);
+print '<?xml version="1.0"?>
+
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:nc="http://home.netscape.com/NC-rdf#">
+ <rdf:Seq about="urn:root">
+' . $main_cats . ' </rdf:Seq>
+';
+print join('',@chunks);
+print '</rdf:RDF>
+';
+exit 0;
+
+sub go_in {
+ my($current, $about, $cat) = @_;
+ my (@list, $entry, @subdirs, @files, @purps, $rdf);
+ chdir $current;
+ @list = <*>;
+
+ LOOP: foreach $entry (@list) {
+ next LOOP if $entry=~/^CVS$/;
+ if (! -d $entry) {
+ if ($entry=~/^($current.*)\.xsl$/) {
+ local $source = $entry;
+ $source=~s/xsl$/xml/;
+ next LOOP if ! -f $source;
+ $entry=~/^($current.*)\.xsl$/;
+ push(@files, $1);
+ local ($purp, $purp_open);
+ open STYLE, $entry;
+ $purp_open = 0;
+ while (<STYLE>) {
+ if (/<!--\s+purpose: (.+)\s*-->/i) {
+ $purp .= $1;
+ }
+ elsif (/<!--\s+purpose: (.+)\s*$/i) {
+ $purp_open = 1;
+ $purp .= $1;
+ }
+ elsif ($purp_open) {
+ if (/\s*(\s.+)\s*-->/) {
+ $purp_open = 0;
+ $purp .= $1;
+ }
+ elsif (/\s*(\s.+)\s*$/) {
+ $purp .= $1;
+ }
+ }
+ }
+ $purp=~s/"/'/g; $purp=~s/&/&amp;/g; $purp=~s/</&lt;/g;
+ $purp=~s/\r/ /g; $purp=~s/\s\s/ /g; $purp=~s/\s$//g;
+ push(@purps, $purp);
+ }
+ }
+ else {
+ push(@subdirs, $entry);
+ }
+ }
+
+ if (@subdirs > 0 || @files > 0) {
+ my $topic = $about.$current; $topic=~s/\///g;
+ $rdf = ' <rdf:Seq about="urn:x-buster:'.$topic."\">\n";
+ foreach $entry (@subdirs) {
+ if (go_in($entry, $about.$current.'/', $cat)) {
+ my $id = 'urn:x-buster:'.$about.$current.$entry; $id=~s/\///g;
+ $rdf .= " <rdf:li><rdf:Description about=\"$id\" nc:dir=\"$entry\" /></rdf:li>\n";
+ }
+ }
+ for (my $i=0; $i < @files; $i++) {
+ my $uri = $about.$current.'/'.$files[$i];
+ $uri=~s/[^\/]+\///;
+ my $id = $uri; $id=~s/\///g;
+ $rdf .= " <rdf:li><rdf:Description about=\"urn:x-buster:$files[$i]\" nc:name=\"$files[$i]\" nc:purp=\"$purps[$i]\" nc:path=\"$uri\" nc:category=\"$cat\" /></rdf:li>\n";
+ }
+ $rdf .= " </rdf:Seq>\n";
+ push(@chunks, $rdf);
+ }
+
+ chdir File::Spec->updir;
+ return (@subdirs > 0 || @files > 0);
+}
diff --git a/dom/xslt/tests/buster/install.js b/dom/xslt/tests/buster/install.js
new file mode 100644
index 000000000..0306db692
--- /dev/null
+++ b/dom/xslt/tests/buster/install.js
@@ -0,0 +1,17 @@
+const X_APP = "Buster";
+const X_VER = "2.0"
+const X_JAR_FILE = "xslt-qa.jar";
+
+var err = initInstall("Install " + X_APP, X_APP, X_VER);
+logComment("initInstall: " + err);
+logComment( "Installation started ..." );
+addFile("We're on our way ...", X_JAR_FILE, getFolder("chrome"), "");
+registerChrome(CONTENT|DELAYED_CHROME, getFolder("chrome", X_JAR_FILE), "content/xslt-qa/");
+err = getLastError();
+if (err == SUCCESS) {
+ performInstall();
+ alert("Please restart Mozilla");
+}
+else {
+ cancelInstall();
+}
diff --git a/dom/xslt/tests/buster/jar.mn b/dom/xslt/tests/buster/jar.mn
new file mode 100644
index 000000000..af7e395f0
--- /dev/null
+++ b/dom/xslt/tests/buster/jar.mn
@@ -0,0 +1,18 @@
+xslt-qa.jar:
+% content xslt-qa %content/xslt-qa/
+% overlay chrome://communicator/content/tasksOverlay.xul chrome://xslt-qa/content/xslt-qa-overlay.xul
+ content/xslt-qa/xslt-qa-overlay.xul
+ content/xslt-qa/xslt-qa-overlay.js
+ content/xslt-qa/buster/buster.xul
+ content/xslt-qa/buster/buster.css
+ content/xslt-qa/buster/buster-statics.js
+ content/xslt-qa/buster/buster-handlers.js
+ content/xslt-qa/buster/buster-files.js
+ content/xslt-qa/buster/buster-test.js
+ content/xslt-qa/buster/buster-view.js
+ content/xslt-qa/buster/result-view.xul
+ content/xslt-qa/buster/result-inspector.xul
+ content/xslt-qa/buster/result-view.css
+ content/xslt-qa/buster/result-view.js
+ content/xslt-qa/buster/DumpDOM.js
+ content/xslt-qa/buster/DiffDOM.js
diff --git a/dom/xslt/tests/buster/result-inspector.xul b/dom/xslt/tests/buster/result-inspector.xul
new file mode 100644
index 000000000..77c3ce180
--- /dev/null
+++ b/dom/xslt/tests/buster/result-inspector.xul
@@ -0,0 +1,37 @@
+<?xml version="1.0"?><!-- -*- Mode: xml; tab-width: 2; indent-tabs-mode: nil -*- -->
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!DOCTYPE window [
+ <!ENTITY % dtd1 SYSTEM "chrome://inspector/locale/inspector.dtd"> %dtd1;
+ <!ENTITY % dtd2 SYSTEM "chrome://inspector/content/util.dtd"> %dtd2;
+]>
+
+<?xul-overlay href="chrome://inspector/content/commandOverlay.xul"?>
+<?xul-overlay href="chrome://inspector/content/keysetOverlay.xul"?>
+<?xul-overlay href="chrome://inspector/content/popupOverlay.xul"?>
+
+<?xml-stylesheet href="chrome://inspector/skin/inspectorWindow.css"?>
+
+<window class="color-dialog"
+ title="&Inspector.title;"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/x-javascript" src="chrome://inspector/content/ViewerRegistry.js"/>
+ <script type="application/x-javascript" src="chrome://inspector/content/utils.js"/>
+ <script type="application/x-javascript" src="chrome://inspector/content/jsutil/xpcom/XPCU.js"/>
+ <script type="application/x-javascript" src="chrome://inspector/content/jsutil/rdf/RDFU.js"/>
+ <script type="application/x-javascript" src="chrome://inspector/content/jsutil/rdf/RDFArray.js"/>
+ <script type="application/x-javascript" src="chrome://inspector/content/jsutil/events/ObserverManager.js"/>
+ <script type="application/x-javascript" src="chrome://inspector/content/jsutil/xul/FrameExchange.js"/>
+
+ <commandset id="cmdsGlobalCommands"/>
+ <keyset id="ksGlobalKeyset"/>
+ <popupset id="ppsViewerPopupset"/>
+
+ <domi-panelset id="bxPanelSet" flex="1" viewercommandset="cmdsGlobalCommands">
+ <domi-panel title="&bxDocPanel.title;" flex="1"/>
+ </domi-panelset>
+
+</window>
diff --git a/dom/xslt/tests/buster/result-view.css b/dom/xslt/tests/buster/result-view.css
new file mode 100644
index 000000000..b869cc12b
--- /dev/null
+++ b/dom/xslt/tests/buster/result-view.css
@@ -0,0 +1,16 @@
+label.heading {
+ font-size: medium;
+ font-weight: bold;
+}
+
+button.close {
+ font-size: small;
+}
+
+iframe {
+ padding-left: 10px;
+}
+
+vbox.hidden {
+ display: none;
+}
diff --git a/dom/xslt/tests/buster/result-view.js b/dom/xslt/tests/buster/result-view.js
new file mode 100644
index 000000000..de1b8c881
--- /dev/null
+++ b/dom/xslt/tests/buster/result-view.js
@@ -0,0 +1,105 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function onNewResultView(event)
+{
+ dump("onNewResultView\n");
+ const db = runItem.prototype.kDatabase;
+ const kXalan = runItem.prototype.kXalan;
+ var index = view.boxObject.view.selection.currentIndex;
+ var res = view.builder.getResourceAtIndex(index);
+ var name = db.GetTarget(res, krTypeName, true);
+ if (!name) {
+ return false;
+ }
+ var cat = db.GetTarget(res, krTypeCat, true);
+ var path = db.GetTarget(res, krTypePath, true);
+ cat = cat.QueryInterface(nsIRDFLiteral);
+ name = name.QueryInterface(nsIRDFLiteral);
+ path = path.QueryInterface(nsIRDFLiteral);
+ xalan_fl = kXalan.resolve(cat.Value+"/"+path.Value);
+ xalan_ref = kXalan.resolve(cat.Value+"-gold/"+path.Value);
+ var currentResultItem = new Object();
+ currentResultItem.testpath = xalan_fl;
+ currentResultItem.refpath = xalan_ref;
+ var currentRunItem = itemCache.getItem(res);
+ // XXX todo, keep a list of these windows, so that we can close them.
+ resultWin = window.openDialog('result-view.xul','_blank',
+ 'chrome,resizable,dialog=no',
+ currentResultItem, currentRunItem);
+ return true;
+}
+
+var refInspector;
+var resInspector;
+
+function onResultViewLoad(event)
+{
+ dump("onResultViewLoad\n");
+ aResultItem = window.arguments[0];
+ aRunItem = window.arguments[1];
+ var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_NONE;
+ document.getElementById('src').webNavigation.loadURI('view-source:'+
+ aResultItem.testpath+'.xml', loadFlags, null, null, null);
+ document.getElementById('style').webNavigation.loadURI('view-source:'+
+ aResultItem.testpath+'.xsl', loadFlags, null, null, null);
+
+ if (aRunItem && aRunItem.mRefDoc && aRunItem.mResDoc) {
+ document.getElementById("refSourceBox").setAttribute("class", "hidden");
+ refInspector = new ObjectApp();
+ refInspector.initialize("refInsp", aRunItem.mRefDoc);
+ resInspector = new ObjectApp();
+ resInspector.initialize("resInsp", aRunItem.mResDoc);
+ }
+ else {
+ document.getElementById("inspectorBox").setAttribute("class", "hidden");
+ document.getElementById('ref').webNavigation.loadURI('view-source:'+
+ aResultItem.refpath+'.out', loadFlags, null, null, null);
+ }
+ return true;
+}
+
+function onResultViewUnload(event)
+{
+ dump("onResultUnload\n");
+}
+
+function ObjectApp()
+{
+}
+
+ObjectApp.prototype =
+{
+ mDoc: null,
+ mPanelSet: null,
+
+ initialize: function(aId, aDoc)
+ {
+ this.mDoc = aDoc;
+ this.mPanelSet = document.getElementById(aId).contentDocument.getElementById("bxPanelSet");
+ this.mPanelSet.addObserver("panelsetready", this, false);
+ this.mPanelSet.initialize();
+ },
+
+ doViewerCommand: function(aCommand)
+ {
+ this.mPanelSet.execCommand(aCommand);
+ },
+
+ getViewer: function(aUID)
+ {
+ return this.mPanelSet.registry.getViewerByUID(aUID);
+ },
+
+ onEvent: function(aEvent)
+ {
+ switch (aEvent.type) {
+ case "panelsetready":
+ {
+ this.mPanelSet.getPanel(0).subject = this.mDoc;
+ }
+ }
+ }
+};
diff --git a/dom/xslt/tests/buster/result-view.xul b/dom/xslt/tests/buster/result-view.xul
new file mode 100644
index 000000000..e402067aa
--- /dev/null
+++ b/dom/xslt/tests/buster/result-view.xul
@@ -0,0 +1,46 @@
+<?xml version="1.0"?><!-- -*- Mode: xml; tab-width: 2; indent-tabs-mode: nil -*- -->
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
+<?xml-stylesheet href="result-view.css" type="text/css"?>
+
+<window id="buster-result-view" title="Xalan testcase details"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ orient="vertical" persist="width height"
+ onload="onResultViewLoad()" onunload="onResultViewUnload()">
+ <script type="application/x-javascript" src="DumpDOM.js" />
+ <script type="application/x-javascript" src="buster-statics.js" />
+ <script type="application/x-javascript" src="buster-test.js" />
+ <script type="application/x-javascript" src="result-view.js" />
+
+ <hbox>
+ <button class="close" label="close this window"
+ oncommand="window.close()" />
+ </hbox>
+ <vbox flex="1">
+ <label class="heading" value="XML Source:" />
+ <iframe flex="1" id="src" />
+ </vbox>
+ <vbox flex="1">
+ <label class="heading" value="XSL Source:" />
+ <iframe flex="1" id="style" />
+ </vbox>
+ <vbox flex="1" id="refSourceBox">
+ <label class="heading" value="Reference Source:" />
+ <iframe flex="1" id="ref" />
+ </vbox>
+ <vbox flex="2" id="inspectorBox">
+ <hbox flex="1">
+ <vbox flex="1">
+ <label class="heading" value="Reference" />
+ <iframe flex="1" id="refInsp" src="result-inspector.xul" />
+ </vbox>
+ <vbox flex="1">
+ <label class="heading" value="Result" />
+ <iframe flex="1" id="resInsp" src="result-inspector.xul" />
+ </vbox>
+ </hbox>
+ </vbox>
+</window>
diff --git a/dom/xslt/tests/buster/xslt-qa-overlay.js b/dom/xslt/tests/buster/xslt-qa-overlay.js
new file mode 100644
index 000000000..41bd764a5
--- /dev/null
+++ b/dom/xslt/tests/buster/xslt-qa-overlay.js
@@ -0,0 +1,10 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function onStartBuster()
+{
+ window.open('chrome://xslt-qa/content/buster/buster.xul',
+ 'buster', 'chrome,resizable');
+}
diff --git a/dom/xslt/tests/buster/xslt-qa-overlay.xul b/dom/xslt/tests/buster/xslt-qa-overlay.xul
new file mode 100644
index 000000000..294d27f92
--- /dev/null
+++ b/dom/xslt/tests/buster/xslt-qa-overlay.xul
@@ -0,0 +1,12 @@
+<?xml version="1.0"?><!-- -*- Mode: xml; tab-width: 2; indent-tabs-mode: nil -*- -->
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<overlay id="xsltToolsMenuID"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script src="xslt-qa-overlay.js" />
+ <menupopup id="toolsPopup">
+ <menuitem label="Xalan Tests" oncommand="onStartBuster()"/>
+ </menupopup>
+</overlay>