|
1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 var parser = new DOMParser(); |
|
7 var methodExpr = (new XPathEvaluator).createExpression("xsl:output/@method", |
|
8 { |
|
9 lookupNamespaceURI: function(aPrefix) |
|
10 { |
|
11 if (aPrefix == "xsl") |
|
12 return "http://www.w3.org/1999/XSL/Transform"; |
|
13 return ""; |
|
14 } |
|
15 }); |
|
16 |
|
17 const nsIWebProgListener = Components.interfaces.nsIWebProgressListener; |
|
18 |
|
19 var runQueue = |
|
20 { |
|
21 mArray : new Array(), |
|
22 push : function(aRunItem) |
|
23 { |
|
24 this.mArray.push(aRunItem); |
|
25 }, |
|
26 observe : function(aSubject, aTopic, aData) |
|
27 { |
|
28 var item = this.mArray.shift(); |
|
29 if (item) { |
|
30 item.run(this); |
|
31 } |
|
32 }, |
|
33 run : function() |
|
34 { |
|
35 this.observe(null,'',''); |
|
36 } |
|
37 } |
|
38 |
|
39 var itemCache = |
|
40 { |
|
41 mArray : new Array(), |
|
42 getItem : function(aResource) |
|
43 { |
|
44 // Directory selected |
|
45 if (kContUtils.IsSeq(runItem.prototype.kDatabase, aResource)) { |
|
46 var aSeq = kContUtils.MakeSeq(runItem.prototype.kDatabase, aResource); |
|
47 dump("sequence: "+aSeq+" with "+aSeq.GetCount()+" elements\n"); |
|
48 var child, children = aSeq.GetElements(); |
|
49 var m = 0, first; |
|
50 while (children.hasMoreElements()) { |
|
51 m += 1; |
|
52 child = children.getNext(); |
|
53 child.QueryInterface(nsIRDFResource); |
|
54 if (!first) |
|
55 first = itemCache.getItem(child); |
|
56 else |
|
57 itemCache.getItem(child); |
|
58 } |
|
59 return first; |
|
60 } |
|
61 if (aResource.Value in this.mArray) { |
|
62 return this.mArray[aResource.Value]; |
|
63 } |
|
64 var retItem = new runItem(aResource); |
|
65 this.mArray[aResource.Value] = retItem; |
|
66 runQueue.push(retItem); |
|
67 return retItem; |
|
68 }, |
|
69 rerunItem : function(aResource, aObserver) |
|
70 { |
|
71 var anItem = new runItem(aResource); |
|
72 this.mArray[aResource.Value] = anItem; |
|
73 anItem.run(aObserver); |
|
74 }, |
|
75 observe : function(aSubject, aTopic, aData) |
|
76 { |
|
77 this.mRun += 1; |
|
78 if (aTopic == "success") { |
|
79 if (aData == "yes") { |
|
80 this.mGood += 1; |
|
81 } |
|
82 else { |
|
83 this.mFalse +=1; |
|
84 } |
|
85 } |
|
86 } |
|
87 } |
|
88 |
|
89 function runItem(aResource) |
|
90 { |
|
91 this.mResource = aResource; |
|
92 // Directory selected |
|
93 if (kContUtils.IsSeq(this.kDatabase,this.mResource)) { |
|
94 var aSeq = kContUtils.MakeSeq(this.kDatabase,this.mResource); |
|
95 dump("THIS SHOULDN'T HAPPEN\n"); |
|
96 var child, children = aSeq.GetElements(); |
|
97 var m = 0; |
|
98 while (children.hasMoreElements()) { |
|
99 m += 1; |
|
100 child = children.getNext(); |
|
101 child.QueryInterface(nsIRDFResource); |
|
102 itemCache.getItem(child); |
|
103 } |
|
104 } |
|
105 } |
|
106 |
|
107 runItem.prototype = |
|
108 { |
|
109 // RDF resource associated with this test |
|
110 mResource : null, |
|
111 // XML documents for the XSLT transformation |
|
112 mSourceDoc : null, |
|
113 mStyleDoc : null, |
|
114 mResDoc : null, |
|
115 // XML or plaintext document for the reference |
|
116 mRefDoc : null, |
|
117 // bitfield signaling the loaded documents |
|
118 mLoaded : 0, |
|
119 kSource : 1, |
|
120 kStyle : 2, |
|
121 kReference : 4, |
|
122 // a observer, potential argument to run() |
|
123 mObserver : null, |
|
124 mSuccess : null, |
|
125 mMethod : 'xml', |
|
126 // XSLTProcessor, shared by the instances |
|
127 kProcessor : new XSLTProcessor(), |
|
128 kXalan : kStandardURL.createInstance(nsIURL), |
|
129 kDatabase : null, |
|
130 kObservers : new Array(), |
|
131 |
|
132 run : function(aObserver) |
|
133 { |
|
134 if (aObserver && typeof(aObserver)=='function' || |
|
135 (typeof(aObserver)=='object' && |
|
136 typeof(aObserver.observe)=='function')) { |
|
137 this.mObserver=aObserver; |
|
138 } |
|
139 var name = this.kDatabase.GetTarget(this.mResource, krTypeName, true); |
|
140 if (name) { |
|
141 var cat = this.kDatabase.GetTarget(this.mResource, krTypeCat, true); |
|
142 var path = this.kDatabase.GetTarget(this.mResource, krTypePath, true); |
|
143 cat = cat.QueryInterface(nsIRDFLiteral); |
|
144 name = name.QueryInterface(nsIRDFLiteral); |
|
145 path = path.QueryInterface(nsIRDFLiteral); |
|
146 var xalan_fl = this.kXalan.resolve(cat.Value+"/"+path.Value); |
|
147 var xalan_ref = this.kXalan.resolve(cat.Value+"-gold/"+path.Value); |
|
148 this.mRefURL = |
|
149 this.kXalan.resolve(cat.Value + "-gold/" + path.Value + ".out"); |
|
150 dump(name.Value+" links to "+xalan_fl+"\n"); |
|
151 } |
|
152 // Directory selected |
|
153 if (kContUtils.IsSeq(this.kDatabase,this.mResource)) { |
|
154 return; |
|
155 var aSeq = kContUtils.MakeSeq(this.kDatabase,this.mResource); |
|
156 dump("sequence: "+aSeq+" with "+aSeq.GetCount()+" elements\n"); |
|
157 var child, children = aSeq.GetElements(); |
|
158 var m = 0; |
|
159 while (children.hasMoreElements()) { |
|
160 m += 1; |
|
161 child = children.getNext(); |
|
162 child.QueryInterface(nsIRDFResource); |
|
163 } |
|
164 } |
|
165 this.mSourceDoc = document.implementation.createDocument('', '', null); |
|
166 this.mSourceDoc.addEventListener("load",this.onload(1),false); |
|
167 this.mSourceDoc.load(xalan_fl+".xml"); |
|
168 this.mStyleDoc = document.implementation.createDocument('', '', null); |
|
169 this.mStyleDoc.addEventListener("load",this.styleLoaded(),false); |
|
170 this.mStyleDoc.load(xalan_fl+".xsl"); |
|
171 }, |
|
172 |
|
173 // nsIWebProgressListener |
|
174 QueryInterface: function(aIID) |
|
175 { |
|
176 return this; |
|
177 }, |
|
178 onStateChange: function(aProg, aRequest, aFlags, aStatus) |
|
179 { |
|
180 if ((aFlags & nsIWebProgListener.STATE_STOP) && |
|
181 (aFlags & nsIWebProgListener.STATE_IS_DOCUMENT)) { |
|
182 aProg.removeProgressListener(this); |
|
183 this.mRefDoc = document.getElementById('hiddenHtml').contentDocument; |
|
184 this.fileLoaded(4); |
|
185 } |
|
186 }, |
|
187 onProgressChange: function(aProg, b,c,d,e,f) |
|
188 { |
|
189 }, |
|
190 onLocationChange: function(aProg, aRequest, aURI, aFlags) |
|
191 { |
|
192 }, |
|
193 onStatusChange: function(aProg, aRequest, aStatus, aMessage) |
|
194 { |
|
195 }, |
|
196 onSecurityChange: function(aWebProgress, aRequest, aState) |
|
197 { |
|
198 }, |
|
199 |
|
200 // onload handler helper |
|
201 onload : function(file) |
|
202 { |
|
203 var self = this; |
|
204 return function(e) |
|
205 { |
|
206 return self.fileLoaded(file); |
|
207 }; |
|
208 }, |
|
209 |
|
210 styleLoaded : function() |
|
211 { |
|
212 var self = this; |
|
213 return function(e) |
|
214 { |
|
215 return self.styleLoadedHelper(); |
|
216 }; |
|
217 }, |
|
218 styleLoadedHelper : function() |
|
219 { |
|
220 var method = methodExpr.evaluate(this.mStyleDoc.documentElement, 2, |
|
221 null).stringValue; |
|
222 var refContent; |
|
223 if (!method) { |
|
224 // implicit method, guess from result |
|
225 refContent = this.loadTextFile(this.mRefURL); |
|
226 if (refContent.match(/^\s*<html/gi)) { |
|
227 method = 'html'; |
|
228 } |
|
229 else { |
|
230 method = 'xml'; |
|
231 } |
|
232 } |
|
233 this.mMethod = method; |
|
234 |
|
235 switch (method) { |
|
236 case 'xml': |
|
237 if (!refContent) { |
|
238 refContent = this.loadTextFile(this.mRefURL); |
|
239 } |
|
240 this.mRefDoc = parser.parseFromString(refContent, 'application/xml'); |
|
241 this.mLoaded += 4; |
|
242 break; |
|
243 case 'html': |
|
244 view.loadHtml(this.mRefURL, this); |
|
245 break; |
|
246 case 'text': |
|
247 if (!refContent) { |
|
248 refContent = this.loadTextFile(this.mRefURL); |
|
249 } |
|
250 const ns = 'http://www.mozilla.org/TransforMiix'; |
|
251 const qn = 'transformiix:result'; |
|
252 this.mRefDoc = |
|
253 document.implementation.createDocument(ns, qn, null); |
|
254 var txt = this.mRefDoc.createTextNode(refContent); |
|
255 this.mRefDoc.documentElement.appendChild(txt); |
|
256 this.mLoaded += 4; |
|
257 break; |
|
258 default: |
|
259 throw "unkown XSLT output method"; |
|
260 } |
|
261 this.fileLoaded(2) |
|
262 }, |
|
263 |
|
264 fileLoaded : function(mask) |
|
265 { |
|
266 this.mLoaded += mask; |
|
267 if (this.mLoaded < 7) { |
|
268 return; |
|
269 } |
|
270 this.doTransform(); |
|
271 }, |
|
272 |
|
273 doTransform : function() |
|
274 { |
|
275 this.kProcessor.reset(); |
|
276 try { |
|
277 this.kProcessor.importStylesheet(this.mStyleDoc); |
|
278 this.mResDoc = |
|
279 this.kProcessor.transformToDocument(this.mSourceDoc); |
|
280 this.mRefDoc.normalize(); |
|
281 isGood = DiffDOM(this.mResDoc.documentElement, |
|
282 this.mRefDoc.documentElement, |
|
283 this.mMethod == 'html'); |
|
284 } catch (e) { |
|
285 isGood = false; |
|
286 }; |
|
287 dump("This succeeded. "+isGood+"\n"); |
|
288 isGood = isGood.toString(); |
|
289 for (var i=0; i<this.kObservers.length; i++) { |
|
290 var aObs = this.kObservers[i]; |
|
291 if (typeof(aObs)=='object' && typeof(aObs.observe)=='function') { |
|
292 aObs.observe(this.mResource, 'success', isGood); |
|
293 } |
|
294 else if (typeof(aObs)=='function') { |
|
295 aObs(this.mResource, 'success', isGood); |
|
296 } |
|
297 } |
|
298 if (this.mObserver) { |
|
299 if (typeof(this.mObserver)=='object') { |
|
300 this.mObserver.observe(this.mResource, 'success', isGood); |
|
301 } |
|
302 else { |
|
303 this.mObserver(this.mResource, 'success', isGood); |
|
304 } |
|
305 } |
|
306 }, |
|
307 |
|
308 loadTextFile : function(url) |
|
309 { |
|
310 var serv = Components.classes[IOSERVICE_CTRID]. |
|
311 getService(nsIIOService); |
|
312 if (!serv) { |
|
313 throw Components.results.ERR_FAILURE; |
|
314 } |
|
315 var chan = serv.newChannel(url, null, null); |
|
316 var instream = doCreate(SIS_CTRID, nsISIS); |
|
317 instream.init(chan.open()); |
|
318 |
|
319 return instream.read(instream.available()); |
|
320 } |
|
321 } |
|
322 |
|
323 runItem.prototype.kXalan.QueryInterface(nsIStandardURL); |
|
324 |
|
325 var cmdTestController = |
|
326 { |
|
327 supportsCommand: function(aCommand) |
|
328 { |
|
329 switch(aCommand) { |
|
330 case 'cmd_tst_run': |
|
331 case 'cmd_tst_runall': |
|
332 return true; |
|
333 default: |
|
334 } |
|
335 return false; |
|
336 }, |
|
337 isCommandEnabled: function(aCommand) |
|
338 { |
|
339 return this.supportsCommand(aCommand); |
|
340 }, |
|
341 doCommand: function(aCommand) |
|
342 { |
|
343 switch(aCommand) { |
|
344 case 'cmd_tst_run': |
|
345 dump("cmd_tst_run\n"); |
|
346 break; |
|
347 case 'cmd_tst_runall': |
|
348 dump("cmd_tst_runall\n"); |
|
349 var tst_run = document.getElementById('cmd_tst_run'); |
|
350 tst_run.doCommand(); |
|
351 default: |
|
352 } |
|
353 } |
|
354 }; |
|
355 |
|
356 registerController(cmdTestController); |