Project

General

Profile

1
if(!IS_IE && !self.XSLTProcessor) XSLTProcessor = _Javeline_XSLTProcessor;
2
	
3
function _Javeline_XSLTProcessor(){
4
	this.templates = {};
5
	this.paramsSet={};
6
	this.currentTemplate="global";
7
	
8
	// list of function xsl
9
	this.p = {
10
	
11
		"value-of" : function(context, xslNode, childStack, result){   
12
		 
13
		  var expression = this.lookforVariable(xslNode.getAttribute("select"));
14
		  var xmlNode = context.selectNodes(expression)[0];// + "[0]"
15
		  if(xmlNode != null)
16
		  {
17
		   if(xmlNode == null ) value = "";
18
		   else if(xmlNode.nodeType == 1) value = xmlNode.firstChild ? xmlNode.firstChild.nodeValue : "";
19
		   else value = typeof xmlNode == "object" ? xmlNode.nodeValue : xmlNode;
20
		  }
21
		  else
22
		  {
23
		   value = expression;
24
		  }
25
		  result.appendChild(this.xmlDoc.createTextNode(value));
26
		},
27
		
28
		"copy-of" : function(context, xslNode, childStack, result){
29
			var xmlNode = XPath.selectNodes(this.lookforVariable(xslNode.getAttribute("select")), context)[0];// + "[0]"
30
			if(xmlNode) result.appendChild(!IS_IE ? result.ownerDocument.importNode(xmlNode, true) : xmlNode.cloneNode(true));
31
		},
32
		
33
		"if" : function(context, xslNode, childStack, result){
34
		var test = this.lookforVariable(xslNode.getAttribute("test"));
35
		
36
		   if(XPath.selectNodes(test, context)[0]){// + "[0]"
37
				this.parseChildren(context, xslNode, childStack, result);
38
			}
39
		},
40
		
41
		"for-each" : function(context, xslNode, childStack, result){
42
			var nodes = XPath.selectNodes(this.lookforVariable(xslNode.getAttribute("select")), context);
43
			for(var i=0;i<nodes.length;i++){
44
				this.parseChildren(nodes[i], xslNode, childStack, result);
45
			}
46
		},
47
		
48
		"attribute" : function(context, xslNode, childStack, result){
49
			var nres = this.xmlDoc.createDocumentFragment();
50
			this.parseChildren(context, xslNode, childStack, nres);
51
			result.setAttribute(xslNode.getAttribute("name"), nres.xml);
52
		},
53
		
54
		"choose" : function(context, xslNode, childStack, result){
55
		   
56
			var nodes = xslNode.childNodes;
57
			for(var i=0;i<nodes.length;i++){
58
				if(!nodes[i].tagName) continue;
59
				if(nodes[i][TAGNAME] == "when")
60
				{
61
				 var node = context.selectNodes(this.lookforVariable(nodes[i].getAttribute("test")))[0];
62
				 if(node == "undefined") return;//safari bug
63
				}
64
				if(nodes[i][TAGNAME] == "otherwise" || (nodes[i][TAGNAME] == "when" && node))
65
					return this.parseChildren(context, nodes[i], childStack[i][2], result);
66
			}
67
		},
68
		"text" : function(context, xslNode, childStack, result)
69
		{
70
		   if(xmlNode == null ) value = "";
71
		   else if(xmlNode.nodeType == 1) value = xmlNode.firstChild ? xmlNode.firstChild.nodeValue : "";
72
		   else value = typeof xmlNode == "object" ? xmlNode.nodeValue : xmlNode;
73
		   value = expression;
74
		   result.appendChild(this.xmlDoc.createTextNode(value));
75
		   
76
		},
77
		"call-template" : function(context, xslNode, childStack, result)
78
		{
79
		 var t = this.templates[xslNode.getAttribute("name")];
80
		 this.currentTemplate=t;
81
		 if(t){
82
		  
83
		  this.parseChildren(context, t[0], t[1], result);
84
		  this.withparams(xslNode); 
85
		  this.currentTemplate=t;
86
		  this.paramsSet[this.currentTemplate]= new Array();
87
		  }
88
		},
89
		"apply-templates" : function(context, xslNode, childStack, result)
90
		{
91
		//try if context is a node document else take is child
92
		if(!xslNode){
93
		       var childContext = context.childNodes[0];
94
	           var tagname = childContext.tagName;
95
	           var test = this.lookforTemplate(tagname);
96
	           if(test == 0 ) test="/";
97
	           t = this.templates[test];
98
			   if(t) {
99
				this.p["apply-templates"].call(this, context, t[0], t[1], result);
100
				}
101
			}else{
102
		var aux = xslNode.getAttribute("match") || xslNode.getAttribute("select");
103
		 aux = this.lookforVariable(aux);
104
		var template = "";
105
		if(this.templates[aux]) template =aux;
106
		else
107
		 template = this.lookforTemplate2(aux);
108
		if(aux)
109
		{
110
	     this.currentTemplate=template;
111
		 var t = this.templates[template];
112
		 if(t)
113
		 {
114
		  //if(aux == "/") return alert("Something went wrong. The / template was executed as a normal template");
115
		  var nodes = context.selectNodes(aux);
116
		  var tabIndex;
117
		  this.withparams(xslNode); 
118
		  if(xslNode.firstChild[TAGNAME] == "sort")
119
		  this.xslSort( xslNode.firstChild, nodes, tabIndex);
120
		  if(!nodes[0]) return;
121
		  for(var i=0;i<nodes.length;i++)
122
		  { 
123
		   if(xslNode.firstChild[TAGNAME] == "sort")
124
		   this.parseChildren(nodes[tabIndex[i]], t[0], t[1], result);
125
		   else
126
		   this.parseChildren(i , t[0], t[1], result);
127
		   this.currentTemplate=template;
128
		   this.paramsSet[this.currentTemplate]= new Array(); 
129
		  }
130
		 }
131
		}
132
		else if(xslNode.getAttribute("name"))
133
		{
134
		 var t = this.templates[xslNode.getAttribute("name")];
135
		 this.currentTemplate=t;
136
		 if(t){
137
		  this.withparams(xslNode); 
138
		  this.parseChildren(context, t[0], t[1], result);
139
		  this.currentTemplate=t;
140
		  this.paramsSet[this.currentTemplate]= new Array();
141
		  }
142
		}
143
		else
144
		{
145
				//Copy context
146
				var ncontext = context.cloneNode(true); //importnode here??
147
				var nres = this.xmlDoc.createDocumentFragment();
148
				
149
				var nodes = ncontext.childNodes;
150
				if(!nodes[0]) return;
151
				for(var tName, i=nodes.length-1;i>=0;i--){
152
					if(nodes[i].nodeType == 3 || nodes[i].nodeType == 4){
153
						//result.appendChild(this.xmlDoc.createTextNode(nodes[i].nodeValue));
154
						continue;
155
					}
156
					if(!nodes[i].nodeType == 1) continue;
157
					var n = nodes[i];
158

    
159
					//Loop through all templates
160
					for(tName in this.templates){
161
						if(tName == "/") continue;
162
						var t = this.templates[tName];
163
						
164
						var snodes = n.selectNodes("self::" + tName);
165
						for(var j=snodes.length-1;j>=0;j--){
166
							var s = snodes[j], p = s.parentNode;
167
							
168
							this.parseChildren(s, t[0], t[1], nres);
169
							this.paramsSet[this.currentTemplate]= new Array();
170
							 
171
		  
172
							if(nres.childNodes){
173
								for(var k=nres.childNodes.length-1;k>=0;k--){
174
									p.insertBefore(nres.childNodes[k], s);
175
								}
176
							}
177
							p.removeChild(s);
178
						}
179
					}
180
					
181
					if(n.parentNode){
182
						var p = n.parentNode;
183
						this.p["apply-templates"].call(this, n, xslNode, childStack, nres);
184
						if(nres.childNodes){
185
							for(var k=nres.childNodes.length-1;k>=0;k--){
186
								p.insertBefore(nres.childNodes[k], n);
187
							}
188
						}
189
						p.removeChild(n);
190
					}
191
				}
192
				
193
				for(var i=ncontext.childNodes.length-1;i>=0;i--){
194
					result.insertBefore(ncontext.childNodes[i], result.firstChild);
195
				}
196
			}
197
			}
198
		},
199
		
200
		cache : {},
201
		
202
		"import" : function(context, xslNode, childStack, result){
203
			var file = xslNode.getAttribute("href");
204
			if(!this.cache[file]){
205
				var data = new HTTP().get(file, false, true);
206
				this.cache[file] = data;
207
			}
208
			
209
			//compile
210
			//parseChildren
211
		},
212
		
213
		"include" : function(context, xslNode, childStack, result){
214
			
215
		},
216
		
217
		"element" : function(context, xslNode, childStack, result){
218
		    var element = this.xmlDoc.createElement(xslNode.getAttribute("name"));
219
			this.parseChildren(context, xslNode, childStack,element);
220
			result.appendChild(element);
221
		},
222
		
223
		"param" : function(context, xslNode, childStack, result){
224
		  var namePram = xslNode.getAttribute("name");
225
		  if(!this.paramsSet["params"][namePram] && xslNode.firstChild)
226
		  {
227
		  var aux = getNodeValue(xslNode);
228
		  if(aux == "undefined") aux= false;
229
		  this.paramsSet["params"][namePram] = aux;
230
		  }
231
		},
232
		"with-param" : function(context, xslNode, childStack, result){
233
			
234
		},
235
		"variable" : function(context, xslNode, childStack, result){
236
		 var namePram = xslNode.getAttribute("name");
237
		 var tempValue="";
238
		 if(!this.paramsSet[this.currentTemplate])//init variable
239
		 this.paramsSet[this.currentTemplate] = new Array();
240
		 if(!this.paramsSet[this.currentTemplate][namePram])
241
		 {
242
		  var nres = this.xmlDoc.createDocumentFragment();
243
		  this.parseChildren(context,xslNode,childStack,nres);
244
		  var nodes = nres.childNodes;//refactorize it
245
		  var select=xslNode.getAttribute("select");
246
		  if(select)
247
		  {
248
		  select = this.lookforVariable(select);
249
		  try{
250
		  var nodeSelect = context.selectNodes(select)[0];
251
	      if(!nodeSelect) tempValue = "";
252
		  else if(nodeSelect.nodeType == 1) tempValue = nodeSelect.firstChild ? nodeSelect.firstChild.nodeValue : "";
253
		  else tempValue = typeof nodeSelect == "object" ? nodeSelect.nodeValue : nodeSelect;
254
		  if(typeof nodeSelect == "number") tempValue=""+nodeSelect;
255
		  
256
		  }
257
		  catch(e){
258
		  
259
		  }
260
		  }
261
		  else
262
		  for(var i = 0; i < nodes.length;i++)
263
		  {
264
		  var temp2 = getNodeValue(nodes[i]);
265
		   if(temp2 != "undefined")
266
		   tempValue+=temp2;
267
		  }
268
		  tempValue = tempValue.replace(/\s/g,"");//maybe need to fix it
269
		  this.paramsSet[this.currentTemplate][namePram] =tempValue;
270
		 
271
		 }
272
		},
273
		
274
		"when" : function(){},
275
		
276
		"otherwise" : function(){},
277
		
278
		"sort" : function(){},
279
		
280
		"copy-clone" : function(context, xslNode, childStack, result){
281
		
282
			result = result.appendChild(!IS_IE ? result.ownerDocument.importNode(xslNode, false) : xslNode.cloneNode(false));
283
			if(result.nodeType == 1){
284
				for(var i=0;i<result.attributes.length;i++){
285
					var blah = result.attributes[i].nodeValue; //stupid Safari shit
286

    
287
					if(!IS_SAFARI && result.attributes[i].nodeName.match(/^xmlns/)) continue;
288
					result.attributes[i].nodeValue = this.variable(result.attributes[i].nodeValue);
289
					result.attributes[i].nodeValue = result.attributes[i].nodeValue.replace(/\{([^\}]+)\}/g, function(m, xpath){
290
						var xmlNode = XPath.selectNodes(xpath, context)[0];
291
						
292
						if(!xmlNode) value = "";
293
						else if(xmlNode.nodeType == 1) value = xmlNode.firstChild ? xmlNode.firstChild.nodeValue : "";
294
						else value = typeof xmlNode == "object" ? xmlNode.nodeValue : xmlNode;
295
						
296
						return value;
297
					});
298
					
299
					result.attributes[i].nodeValue; //stupid Safari shit
300
				}
301
			}
302
			
303
			this.parseChildren(context, xslNode, childStack, result);
304
			
305
		}
306
	}
307
	/**
308
     * xslSort , threat the stack
309
     * 
310
     * @argument xsl node which transformes
311
     * @argument Stack from compile
312
     * @argument the code html
313
     * @return return the text with the value  from variable or not change the text
314
     */
315
	this.xslSort = function( xslsort, nodeSort, tabIndex){
316
		
317
		var select = xslsort.getAttribute("select");
318
		var tabIndex = new Array;
319
		var tabIndex2 = new Array;
320
		for(var i=0;i<nodeSort.length;i++)
321
		{
322
		  var temp = nodeSort[i].selectNodes(select);
323
		  tabIndex[i]= temp;
324
		  tabIndex2[temp]=i;
325
		}
326
		tabIndex.sort();
327
		var tabIndex3 = new Array;
328
		for(var i=0;i<tabIndex.length;i++)
329
		{
330
		  tabIndex3[tabIndex2[tabIndex[i]]] = i;
331
		}
332
		tabIndex = tabIndex3;
333
		
334
	}
335
	/**
336
     * parseChidren , threat the stack
337
     * 
338
     * @argument the xml node which will be transformed
339
     * @argument xsl node which transformes
340
     * @argument Stack from compile
341
     * @argument the code html
342
     * @return return the text with the value  from variable or not change the text
343
     */
344
	this.parseChildren = function(context, xslNode, childStack, result){
345
		if(!childStack){ 
346
		alert("stack empty");return;
347
		}
348
		if(childStack.length == 0) return;
349
		for(var i=0;i<childStack.length;i++){
350
			
351
			childStack[i][0].call(this, context, childStack[i][1], childStack[i][2], result);
352
		}
353
	}
354
	/**
355
     * compile xsl 
356
     * 
357
     * @argument xsl node
358
     * @return return the stack
359
     */
360
	this.compile = function(xslNode){
361
		var nodes = xslNode.childNodes;
362
		for(var stack=[],i=0;i<nodes.length;i++)
363
		{
364
		  var nType = nodes[i].nodeType;
365
		  if(nodes[i][TAGNAME] == "template")
366
		  {
367
			this.templates[nodes[i].getAttribute("match") || nodes[i].getAttribute("name")] = [nodes[i], this.compile(nodes[i])];
368
			//stack.push([this.p["apply-templates"], nodes[i], this.compile(nodes[i])]);
369
		  }
370
		  else if(nodes[i][TAGNAME] == "stylesheet")
371
		  {
372
			stack=this.compile(nodes[i])
373
		  }
374
		  else if(nodes[i].prefix == "xsl")
375
		  {
376
		   var func = this.p[nodes[i][TAGNAME]];
377
		   if(!func) alert("xsl:" + nodes[i][TAGNAME] + " is not supported at this time on this platform");
378
		   else stack.push([func, nodes[i], this.compile(nodes[i])]);
379
		  }
380
		  else
381
		  {
382
			if( nType != 8) //comment can not have child and useless
383
			{
384
			  stack.push([this.p["copy-clone"], nodes[i], this.compile(nodes[i])]);
385
			}
386
		  }
387
	    }
388
		return stack;
389
	}
390
	/**
391
     * look for a variable in html node
392
     * 
393
     * @argument text from html node
394
     * @return return the text with the value  from variable or not change the text
395
     */
396
  this.variable = function(string){
397
    if(string.indexOf('$') != -1 )
398
	{
399
	  var result = string.match(/\$(\w)*/g);
400
	  for(var i = 0;i<result.length;i++)
401
	  {
402
	   var aux=result[i].substring(1);
403
	   
404
	   //aux.replace(/\{|\}/,"");
405
	   for(p in this.paramsSet)
406
	   if(this.paramsSet[p][aux])
407
	   string = string.replace("\{"+result[i]+"\}",this.paramsSet[p][aux]);
408
	  }
409
	}
410
	return string;
411
  }
412
  
413
   /**
414
     * withparam function's xsl
415
     * 
416
     * @argument node xsl
417
     */
418
  this.withparams = function(nodexsl)
419
  {
420
  var nodes = nodexsl.childNodes;
421
  for(var i = 0;i< nodes.length;i++)
422
  {
423
   if(nodes[i][TAGNAME] == "with-param" )
424
   {       var name=xslNode.getAttribute("name");
425
          var nodeschild = nodes[i].childNodes;//refactorize it
426
		  var select=xslNode.getAttribute("select");
427
		  if(select)
428
		  {
429
		    select = this.lookforVariable(select);
430
		    try{
431
		    var nodeSelect = context.selectNodes(select)[0];
432
	        if(!nodeSelect) tempValue = "";
433
		    else if(nodeSelect.nodeType == 1) tempValue = nodeSelect.firstChild ? nodeSelect.firstChild.nodeValue : "";
434
		    else tempValue = typeof nodeSelect == "object" ? nodeSelect.nodeValue : nodeSelect;
435
		    if(typeof nodeSelect == "number") tempValue=""+nodeSelect;
436
		  
437
		  }
438
		  catch(e){
439
		  
440
		  }
441
		  }
442
		  else{
443
		  for(var i = 0; i < nodes.length;i++)
444
		  {
445
		    var temp2 = getNodeValue(nodes[i]);
446
		     if(temp2 != "undefined")
447
		     tempValue+=temp2;
448
		  }
449
		  tempValue = tempValue.replace(/\s/g,"");//maybe need to fix it
450
		  this.paramsSet[this.currentTemplate][name] =tempValue;
451
		  
452
   }
453
   }
454
  }
455
  }
456
   /**
457
     * look for a variable in xsl node
458
     * 
459
     * @argument text from xsl node
460
     * @return return the text with the value  from variable or not change the text
461
     */
462
  this.lookforVariable = function(string){
463
    if(string.indexOf('$') != -1 ){
464
	
465
	 var found = 0;
466
	 var result = string.match(/(=)?\$(\w*)/);
467
	 while(result)
468
	  {  
469
	     var aux=RegExp.$2
470
	     
471
	     for(p in this.paramsSet){
472
	     if(this.paramsSet[p][aux]){
473
	     found=1;
474
	     if( RegExp.$1 == "=" )
475
	     string = string.replace("$"+aux,"'"+this.paramsSet[p][aux]+"'");
476
	     else{
477
	     var data = this.paramsSet;
478
	     string = string.replace(/\$(\w*)/,function(d,match){
479
	     if( match == aux ) 
480
	     return data[p][aux];
481
	      else 
482
	      return match;
483
	     
484
	     });
485
	     }
486
         
487
	     }
488
	     }
489
	    if(found == 0)  string = string.replace("$"+aux,false);
490
	   result = string.match(/(=)?\$(\w*)/);
491
	  }
492
	}
493
	return string;
494
  }
495
  this.lookforTemplate = function(string){
496
    
497
    var templat =":"+string;
498
  for(look in this.templates){
499
     if(look.match(new RegExp(templat))){
500
     if(RegExp.rightContext == null)
501
     return look;
502
     }
503
     
504
  }
505
  return 0;
506
  }
507
   this.lookforTemplate2 = function(string){
508
   if(string == "/") return "/";
509
    var temp = string.replace(/\[.*\]/g, "");
510
     temp = temp.split("/");
511
     temp = temp[temp.length - 1];
512
        
513
  for(look in this.templates){
514
     if(look.match(new RegExp(temp))){
515
     if(RegExp.rightContext == null)
516
     return look;
517
     }
518
  }
519
  return 0;
520
  }
521
  
522
  this.importStylesheet = function(xslDoc){
523
    this.xslDoc = xslDoc.nodeType == 9 ? xslDoc.documentElement : xslDoc;
524
	this.xslStack = this.compile(xslDoc);
525
	this.paramsSet = new Array();
526
	this.paramsSet["params"] = new Array();
527
	//var t = this.templates["/"] ? "/" : false;
528
	//if(!t) for(t in this.templates) if(typeof this.templates[t] == "array") break;
529
	//this.xslStack.push([[this.p["apply-templates"], {getAttribute : function(n){if(n=="name") return t}}]]);
530
	this.xslStack.push( [this.p["apply-templates"], null]);
531
  }
532
  this.setParameter = function(nsURI, name, value){
533
   // make value a zero length string if null to allow clearing
534
   value = value ? value : "";
535
   this.paramsSet["params"][name] = value;
536
  };
537
    /**
538
     * Gets a parameter if previously set by setParameter. Returns null
539
     * otherwise
540
     * @argument name The parameter base name
541
     * @argument value The new parameter value
542
     * @return The parameter value if reviously set by setParameter, null otherwise
543
     */
544
    this.getParameter = function(nsURI, name){
545
        nsURI = "" + nsURI;
546
        if(this.paramsSet["params"][name])
547
        {
548
         return this.paramsSet[name];
549
        }
550
        else return null;
551
    };
552
    /**
553
     * Clear parameters (set them to default values as defined in the stylesheet itself)
554
     */
555
    this.clearParameters = function(){
556
        
557
        this.paramsSet = new Array();
558
        this.paramsSet["params"]= new Array();
559
    };
560
	//return nodes
561
	this.transformToFragment = function(doc, newDoc){
562
	   
563
	   this.xmlDoc = newDoc.nodeType != 9 ? newDoc.ownerDocument : newDoc;
564
	   var docfrag = this.xmlDoc.createDocumentFragment();
565
       this.paramsSet["global"]= new Array();
566
	   this.currentTemplate="global";
567
	   var result = this.parseChildren(doc, this.xslDoc, this.xslStack, docfrag);
568
	   return docfrag;
569
	}
570
	
571
}
(3-3/7)