adding all weblabels from weblabels.fsf.org
[weblabels.fsf.org.git] / www.fsf.org / 20131028 / files / static.fsf.org / plone2012 / sarissa.js
CommitLineData
5a920362 1
2/* - sarissa.js - */
3/**
4 * ====================================================================
5 * About
6 * ====================================================================
7 * Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs.
8 * The library supports Gecko based browsers like Mozilla and Firefox,
9 * Internet Explorer (5.5+ with MSXML3.0+), Konqueror, Safari and a little of Opera
10 * @version @sarissa.version@
11 * @author: Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net
12 * ====================================================================
13 * Licence
14 * ====================================================================
15 * Sarissa is free software distributed under the GNU GPL version 2 (see <a href="gpl.txt">gpl.txt</a>) or higher,
16 * GNU LGPL version 2.1 (see <a href="lgpl.txt">lgpl.txt</a>) or higher and Apache Software License 2.0 or higher
17 * (see <a href="asl.txt">asl.txt</a>). This means you can choose one of the three and use that if you like. If
18 * you make modifications under the ASL, i would appreciate it if you submitted those.
19 * In case your copy of Sarissa does not include the license texts, you may find
20 * them online in various formats at <a href="http://www.gnu.org">http://www.gnu.org</a> and
21 * <a href="http://www.apache.org">http://www.apache.org</a>.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
23 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
24 * WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE
25 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
26 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
28 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 */
31/**
32 * <p>Sarissa is a utility class. Provides "static" methods for DOMDocument,
33 * DOM Node serialization to XML strings and other utility goodies.</p>
34 * @constructor
35 */
36function Sarissa(){};
37Sarissa.PARSED_OK = "Document contains no parsing errors";
38Sarissa.PARSED_EMPTY = "Document is empty";
39Sarissa.PARSED_UNKNOWN_ERROR = "Not well-formed or other error";
40var _sarissa_iNsCounter = 0;
41var _SARISSA_IEPREFIX4XSLPARAM = "";
42var _SARISSA_HAS_DOM_IMPLEMENTATION = document.implementation && true;
43var _SARISSA_HAS_DOM_CREATE_DOCUMENT = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.createDocument;
44var _SARISSA_HAS_DOM_FEATURE = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.hasFeature;
45var _SARISSA_IS_MOZ = _SARISSA_HAS_DOM_CREATE_DOCUMENT && _SARISSA_HAS_DOM_FEATURE;
46var _SARISSA_IS_SAFARI = (navigator.userAgent && navigator.vendor && (navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1 || navigator.vendor.indexOf("Apple") != -1));
47var _SARISSA_IS_IE = document.all && window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf("msie") > -1 && navigator.userAgent.toLowerCase().indexOf("opera") == -1;
48if(!window.Node || !Node.ELEMENT_NODE){
49 Node = {ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3, CDATA_SECTION_NODE: 4, ENTITY_REFERENCE_NODE: 5, ENTITY_NODE: 6, PROCESSING_INSTRUCTION_NODE: 7, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, NOTATION_NODE: 12};
50};
51
52if( typeof XMLDocument == "undefined" && typeof Document != "undefined"){ XMLDocument = Document; }
53
54// IE initialization
55if(_SARISSA_IS_IE){
56 // for XSLT parameter names, prefix needed by IE
57 _SARISSA_IEPREFIX4XSLPARAM = "xsl:";
58 // used to store the most recent ProgID available out of the above
59 var _SARISSA_DOM_PROGID = "";
60 var _SARISSA_XMLHTTP_PROGID = "";
61 var _SARISSA_DOM_XMLWRITER = "";
62 /**
63 * Called when the Sarissa_xx.js file is parsed, to pick most recent
64 * ProgIDs for IE, then gets destroyed.
65 * @private
66 * @param idList an array of MSXML PROGIDs from which the most recent will be picked for a given object
67 * @param enabledList an array of arrays where each array has two items; the index of the PROGID for which a certain feature is enabled
68 */
69 Sarissa.pickRecentProgID = function (idList){
70 // found progID flag
71 var bFound = false, e;
72 for(var i=0; i < idList.length && !bFound; i++){
73 try{
74 var _ = new ActiveXObject(idList[i]);
75 _ = _;
76 var o2Store = idList[i];
77 bFound = true;
78 }catch (objException){
79 // trap; try next progID
80 e = objException;
81 };
82 };
83 if (!bFound) {
84 throw "Could not retrieve a valid progID of Class: " + idList[idList.length-1]+". (original exception: "+e+")";
85 };
86 idList = null;
87 return o2Store;
88 };
89 // pick best available MSXML progIDs
90 _SARISSA_DOM_PROGID = null;
91 _SARISSA_THREADEDDOM_PROGID = null;
92 _SARISSA_XSLTEMPLATE_PROGID = null;
93 _SARISSA_XMLHTTP_PROGID = null;
94 if(!window.XMLHttpRequest){
95 /**
96 * Emulate XMLHttpRequest
97 * @constructor
98 */
99 XMLHttpRequest = function() {
100 if(!_SARISSA_XMLHTTP_PROGID){
101 _SARISSA_XMLHTTP_PROGID = Sarissa.pickRecentProgID(["Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]);
102 };
103 return new ActiveXObject(_SARISSA_XMLHTTP_PROGID);
104 };
105 };
106 // we dont need this anymore
107 //============================================
108 // Factory methods (IE)
109 //============================================
110 // see non-IE version
111 Sarissa.getDomDocument = function(sUri, sName){
112 if(!_SARISSA_DOM_PROGID){
113 _SARISSA_DOM_PROGID = Sarissa.pickRecentProgID(["Msxml2.DOMDocument.4.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"]);
114 };
115 var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
116 // if a root tag name was provided, we need to load it in the DOM object
117 if (sName){
118 // create an artifical namespace prefix
119 // or reuse existing prefix if applicable
120 var prefix = "";
121 if(sUri){
122 if(sName.indexOf(":") > 1){
123 prefix = sName.substring(0, sName.indexOf(":"));
124 sName = sName.substring(sName.indexOf(":")+1);
125 }else{
126 prefix = "a" + (_sarissa_iNsCounter++);
127 };
128 };
129 // use namespaces if a namespace URI exists
130 if(sUri){
131 oDoc.loadXML('<' + prefix+':'+sName + " xmlns:" + prefix + "=\"" + sUri + "\"" + " />");
132 } else {
133 oDoc.loadXML('<' + sName + " />");
134 };
135 };
136 return oDoc;
137 };
138 // see non-IE version
139 Sarissa.getParseErrorText = function (oDoc) {
140 var parseErrorText = Sarissa.PARSED_OK;
141 if(oDoc.parseError.errorCode != 0){
142 parseErrorText = "XML Parsing Error: " + oDoc.parseError.reason +
143 "\nLocation: " + oDoc.parseError.url +
144 "\nLine Number " + oDoc.parseError.line + ", Column " +
145 oDoc.parseError.linepos +
146 ":\n" + oDoc.parseError.srcText +
147 "\n";
148 for(var i = 0; i < oDoc.parseError.linepos;i++){
149 parseErrorText += "-";
150 };
151 parseErrorText += "^\n";
152 }
153 else if(oDoc.documentElement == null){
154 parseErrorText = Sarissa.PARSED_EMPTY;
155 };
156 return parseErrorText;
157 };
158 // see non-IE version
159 Sarissa.setXpathNamespaces = function(oDoc, sNsSet) {
160 oDoc.setProperty("SelectionLanguage", "XPath");
161 oDoc.setProperty("SelectionNamespaces", sNsSet);
162 };
163 /**
164 * Basic implementation of Mozilla's XSLTProcessor for IE.
165 * Reuses the same XSLT stylesheet for multiple transforms
166 * @constructor
167 */
168 XSLTProcessor = function(){
169 if(!_SARISSA_XSLTEMPLATE_PROGID){
170 _SARISSA_XSLTEMPLATE_PROGID = Sarissa.pickRecentProgID(["Msxml2.XSLTemplate.4.0", "MSXML2.XSLTemplate.3.0"]);
171 };
172 this.template = new ActiveXObject(_SARISSA_XSLTEMPLATE_PROGID);
173 this.processor = null;
174 };
175 /**
176 * Imports the given XSLT DOM and compiles it to a reusable transform
177 * <b>Note:</b> If the stylesheet was loaded from a URL and contains xsl:import or xsl:include elements,it will be reloaded to resolve those
178 * @argument xslDoc The XSLT DOMDocument to import
179 */
180 XSLTProcessor.prototype.importStylesheet = function(xslDoc){
181 if(!_SARISSA_THREADEDDOM_PROGID){
182 _SARISSA_THREADEDDOM_PROGID = Sarissa.pickRecentProgID(["MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
183 _SARISSA_DOM_XMLWRITER = Sarissa.pickRecentProgID(["Msxml2.MXXMLWriter.4.0", "Msxml2.MXXMLWriter.3.0", "MSXML2.MXXMLWriter", "MSXML.MXXMLWriter", "Microsoft.XMLDOM"]);
184 };
185 xslDoc.setProperty("SelectionLanguage", "XPath");
186 xslDoc.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
187 // convert stylesheet to free threaded
188 var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID);
189 // make included/imported stylesheets work if exist and xsl was originally loaded from url
190 if(xslDoc.url && xslDoc.selectSingleNode("//xsl:*[local-name() = 'import' or local-name() = 'include']") != null){
191 converted.async = false;
192 converted.load(xslDoc.url);
193 } else {
194 converted.loadXML(xslDoc.xml);
195 };
196 converted.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
197 var output = converted.selectSingleNode("//xsl:output");
198 this.outputMethod = output ? output.getAttribute("method") : "html";
199 this.template.stylesheet = converted;
200 this.processor = this.template.createProcessor();
201 // (re)set default param values
202 this.paramsSet = [];
203 };
204
205 /**
206 * Transform the given XML DOM and return the transformation result as a new DOM document
207 * @argument sourceDoc The XML DOMDocument to transform
208 * @return The transformation result as a DOM Document
209 */
210 XSLTProcessor.prototype.transformToDocument = function(sourceDoc){
211 // fix for bug 1549749
212 if(_SARISSA_THREADEDDOM_PROGID == "MSXML2.FreeThreadedDOMDocument.3.0"){
213 this.processor.input=sourceDoc;
214
215 var outDoc=new ActiveXObject(_SARISSA_DOM_PROGID);
216
217 this.processor.output=outDoc;
218
219 this.processor.transform();
220
221 return outDoc;
222 }
223 else{
224 this.processor.input = sourceDoc;
225
226 var outDoc = new ActiveXObject(_SARISSA_DOM_XMLWRITER);
227
228 this.processor.output = outDoc;
229
230 this.processor.transform();
231
232 var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
233
234 oDoc.loadXML(outDoc.output+"");
235
236 return oDoc;
237 };
238 };
239
240 /**
241 * Transform the given XML DOM and return the transformation result as a new DOM fragment.
242 * <b>Note</b>: The xsl:output method must match the nature of the owner document (XML/HTML).
243 * @argument sourceDoc The XML DOMDocument to transform
244 * @argument ownerDoc The owner of the result fragment
245 * @return The transformation result as a DOM Document
246 */
247 XSLTProcessor.prototype.transformToFragment = function (sourceDoc, ownerDoc) {
248 this.processor.input = sourceDoc;
249 this.processor.transform();
250 var s = this.processor.output;
251 var f = ownerDoc.createDocumentFragment();
252 if (this.outputMethod == 'text') {
253 f.appendChild(ownerDoc.createTextNode(s));
254 } else if (ownerDoc.body && ownerDoc.body.innerHTML) {
255 var container = ownerDoc.createElement('div');
256 container.innerHTML = s;
257 while (container.hasChildNodes()) {
258 f.appendChild(container.firstChild);
259 }
260 }
261 else {
262 var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
263 if (s.substring(0, 5) == '<?xml') {
264 s = s.substring(s.indexOf('?>') + 2);
265 }
266 var xml = ''.concat('<my>', s, '</my>');
267 oDoc.loadXML(xml);
268 var container = oDoc.documentElement;
269 while (container.hasChildNodes()) {
270 f.appendChild(container.firstChild);
271 }
272 }
273 return f;
274 };
275
276 /**
277 * Set global XSLT parameter of the imported stylesheet
278 * @argument nsURI The parameter namespace URI
279 * @argument name The parameter base name
280 * @argument value The new parameter value
281 */
282 XSLTProcessor.prototype.setParameter = function(nsURI, name, value){
283 /* nsURI is optional but cannot be null */
284 if(nsURI){
285 this.processor.addParameter(name, value, nsURI);
286 }else{
287 this.processor.addParameter(name, value);
288 };
289 /* update updated params for getParameter */
290 if(!this.paramsSet[""+nsURI]){
291 this.paramsSet[""+nsURI] = [];
292 };
293 this.paramsSet[""+nsURI][name] = value;
294 };
295 /**
296 * Gets a parameter if previously set by setParameter. Returns null
297 * otherwise
298 * @argument name The parameter base name
299 * @argument value The new parameter value
300 * @return The parameter value if reviously set by setParameter, null otherwise
301 */
302 XSLTProcessor.prototype.getParameter = function(nsURI, name){
303 nsURI = nsURI || "";
304 if(this.paramsSet[nsURI] && this.paramsSet[nsURI][name]){
305 return this.paramsSet[nsURI][name];
306 }else{
307 return null;
308 };
309 };
310}else{ /* end IE initialization, try to deal with real browsers now ;-) */
311 if(_SARISSA_HAS_DOM_CREATE_DOCUMENT){
312 /**
313 * <p>Ensures the document was loaded correctly, otherwise sets the
314 * parseError to -1 to indicate something went wrong. Internal use</p>
315 * @private
316 */
317 Sarissa.__handleLoad__ = function(oDoc){
318 Sarissa.__setReadyState__(oDoc, 4);
319 };
320 /**
321 * <p>Attached by an event handler to the load event. Internal use.</p>
322 * @private
323 */
324 _sarissa_XMLDocument_onload = function(){
325 Sarissa.__handleLoad__(this);
326 };
327 /**
328 * <p>Sets the readyState property of the given DOM Document object.
329 * Internal use.</p>
330 * @private
331 * @argument oDoc the DOM Document object to fire the
332 * readystatechange event
333 * @argument iReadyState the number to change the readystate property to
334 */
335 Sarissa.__setReadyState__ = function(oDoc, iReadyState){
336 oDoc.readyState = iReadyState;
337 oDoc.readystate = iReadyState;
338 if (oDoc.onreadystatechange != null &&
339 typeof oDoc.onreadystatechange == "function") {
340 oDoc.onreadystatechange();
341 }
342 };
343 Sarissa.getDomDocument = function(sUri, sName){
344 var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null);
345 if(!oDoc.onreadystatechange){
346
347 /**
348 * <p>Emulate IE's onreadystatechange attribute</p>
349 */
350 oDoc.onreadystatechange = null;
351 };
352 if(!oDoc.readyState){
353 /**
354 * <p>Emulates IE's readyState property, which always gives an integer from 0 to 4:</p>
355 * <ul><li>1 == LOADING,</li>
356 * <li>2 == LOADED,</li>
357 * <li>3 == INTERACTIVE,</li>
358 * <li>4 == COMPLETED</li></ul>
359 */
360 oDoc.readyState = 0;
361 };
362 oDoc.addEventListener("load", _sarissa_XMLDocument_onload, false);
363 return oDoc;
364 };
365 if(window.XMLDocument){
366
367 //if(window.XMLDocument) , now mainly for opera
368 }// TODO: check if the new document has content before trying to copynodes, check for error handling in DOM 3 LS
369 else if(_SARISSA_HAS_DOM_FEATURE && (typeof Document != 'undefined') && !Document.prototype.load && document.implementation.hasFeature('LS', '3.0')){
370 //Opera 9 may get the XPath branch which gives creates XMLDocument, therefore it doesn't reach here which is good
371 /**
372 * <p>Factory method to obtain a new DOM Document object</p>
373 * @argument sUri the namespace of the root node (if any)
374 * @argument sUri the local name of the root node (if any)
375 * @returns a new DOM Document
376 */
377 Sarissa.getDomDocument = function(sUri, sName){
378 var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null);
379 return oDoc;
380 };
381 }
382 else {
383 Sarissa.getDomDocument = function(sUri, sName){
384 var oDoc = document.implementation.createDocument(sUri?sUri:null, sName?sName:null, null);
385 // looks like safari does not create the root element for some unknown reason
386 if(oDoc && (sUri || sName) && !oDoc.documentElement){
387 oDoc.appendChild(oDoc.createElementNS(sUri, sName));
388 };
389 return oDoc;
390 };
391 };
392 };//if(_SARISSA_HAS_DOM_CREATE_DOCUMENT)
393};
394//==========================================
395// Common stuff
396//==========================================
397if(!window.DOMParser){
398 if(_SARISSA_IS_SAFARI){
399 /*
400 * DOMParser is a utility class, used to construct DOMDocuments from XML strings
401 * @constructor
402 */
403 DOMParser = function() { };
404 /**
405 * Construct a new DOM Document from the given XMLstring
406 * @param sXml the given XML string
407 * @param contentType the content type of the document the given string represents (one of text/xml, application/xml, application/xhtml+xml).
408 * @return a new DOM Document from the given XML string
409 */
410 DOMParser.prototype.parseFromString = function(sXml, contentType){
411 var xmlhttp = new XMLHttpRequest();
412 xmlhttp.open("GET", "data:text/xml;charset=utf-8," + encodeURIComponent(sXml), false);
413 xmlhttp.send(null);
414 return xmlhttp.responseXML;
415 };
416 }else if(Sarissa.getDomDocument && Sarissa.getDomDocument() && Sarissa.getDomDocument(null, "bar").xml){
417 DOMParser = function() { };
418 DOMParser.prototype.parseFromString = function(sXml, contentType){
419 var doc = Sarissa.getDomDocument();
420 doc.loadXML(sXml);
421 return doc;
422 };
423 };
424};
425
426if(!document.importNode && _SARISSA_IS_IE){
427 try{
428 /**
429 * Implementation of importNode for the context window document in IE
430 * @param oNode the Node to import
431 * @param bChildren whether to include the children of oNode
432 * @returns the imported node for further use
433 */
434 document.importNode = function(oNode, bChildren){
435 var tmp = document.createElement("div");
436 if(bChildren){
437 tmp.innerHTML = oNode.xml ? oNode.xml : oNode.outerHTML;
438 }else{
439 tmp.innerHTML = oNode.xml ? oNode.cloneNode(false).xml : oNode.cloneNode(false).outerHTML;
440 };
441 return tmp.getElementsByTagName("*")[0];
442 };
443 }catch(e){ };
444};
445if(!Sarissa.getParseErrorText){
446 /**
447 * <p>Returns a human readable description of the parsing error. Usefull
448 * for debugging. Tip: append the returned error string in a &lt;pre&gt;
449 * element if you want to render it.</p>
450 * <p>Many thanks to Christian Stocker for the initial patch.</p>
451 * @argument oDoc The target DOM document
452 * @returns The parsing error description of the target Document in
453 * human readable form (preformated text)
454 */
455 Sarissa.getParseErrorText = function (oDoc){
456 var parseErrorText = Sarissa.PARSED_OK;
457 if(!oDoc.documentElement){
458 parseErrorText = Sarissa.PARSED_EMPTY;
459 } else if(oDoc.documentElement.tagName == "parsererror"){
460 parseErrorText = oDoc.documentElement.firstChild.data;
461 parseErrorText += "\n" + oDoc.documentElement.firstChild.nextSibling.firstChild.data;
462 } else if(oDoc.getElementsByTagName("parsererror").length > 0){
463 var parsererror = oDoc.getElementsByTagName("parsererror")[0];
464 parseErrorText = Sarissa.getText(parsererror, true)+"\n";
465 } else if(oDoc.parseError && oDoc.parseError.errorCode != 0){
466 parseErrorText = Sarissa.PARSED_UNKNOWN_ERROR;
467 };
468 return parseErrorText;
469 };
470};
471Sarissa.getText = function(oNode, deep){
472 var s = "";
473 var nodes = oNode.childNodes;
474 for(var i=0; i < nodes.length; i++){
475 var node = nodes[i];
476 var nodeType = node.nodeType;
477 if(nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE){
478 s += node.data;
479 } else if(deep == true &&
480 (nodeType == Node.ELEMENT_NODE ||
481 nodeType == Node.DOCUMENT_NODE ||
482 nodeType == Node.DOCUMENT_FRAGMENT_NODE)){
483 s += Sarissa.getText(node, true);
484 };
485 };
486 return s;
487};
488if(!window.XMLSerializer &&
489 Sarissa.getDomDocument &&
490 Sarissa.getDomDocument("","foo", null).xml){
491 /**
492 * Utility class to serialize DOM Node objects to XML strings
493 * @constructor
494 */
495 XMLSerializer = function(){};
496 /**
497 * Serialize the given DOM Node to an XML string
498 * @param oNode the DOM Node to serialize
499 */
500 XMLSerializer.prototype.serializeToString = function(oNode) {
501 return oNode.xml;
502 };
503};
504
505/**
506 * strips tags from a markup string
507 */
508Sarissa.stripTags = function (s) {
509 return s.replace(/<[^>]+>/g,"");
510};
511/**
512 * <p>Deletes all child nodes of the given node</p>
513 * @argument oNode the Node to empty
514 */
515Sarissa.clearChildNodes = function(oNode) {
516 // need to check for firstChild due to opera 8 bug with hasChildNodes
517 while(oNode.firstChild) {
518 oNode.removeChild(oNode.firstChild);
519 };
520};
521/**
522 * <p> Copies the childNodes of nodeFrom to nodeTo</p>
523 * <p> <b>Note:</b> The second object's original content is deleted before
524 * the copy operation, unless you supply a true third parameter</p>
525 * @argument nodeFrom the Node to copy the childNodes from
526 * @argument nodeTo the Node to copy the childNodes to
527 * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is false
528 */
529Sarissa.copyChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {
530 if((!nodeFrom) || (!nodeTo)){
531 throw "Both source and destination nodes must be provided";
532 };
533 if(!bPreserveExisting){
534 Sarissa.clearChildNodes(nodeTo);
535 };
536 var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;
537 var nodes = nodeFrom.childNodes;
538 if(typeof(ownerDoc.importNode) != "undefined") {
539 for(var i=0;i < nodes.length;i++) {
540 nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));
541 };
542 } else {
543 for(var i=0;i < nodes.length;i++) {
544 nodeTo.appendChild(nodes[i].cloneNode(true));
545 };
546 };
547};
548
549/**
550 * <p> Moves the childNodes of nodeFrom to nodeTo</p>
551 * <p> <b>Note:</b> The second object's original content is deleted before
552 * the move operation, unless you supply a true third parameter</p>
553 * @argument nodeFrom the Node to copy the childNodes from
554 * @argument nodeTo the Node to copy the childNodes to
555 * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is
556 */
557Sarissa.moveChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {
558 if((!nodeFrom) || (!nodeTo)){
559 throw "Both source and destination nodes must be provided";
560 };
561 if(!bPreserveExisting){
562 Sarissa.clearChildNodes(nodeTo);
563 };
564 var nodes = nodeFrom.childNodes;
565 // if within the same doc, just move, else copy and delete
566 if(nodeFrom.ownerDocument == nodeTo.ownerDocument){
567 while(nodeFrom.firstChild){
568 nodeTo.appendChild(nodeFrom.firstChild);
569 };
570 } else {
571 var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;
572 if(ownerDoc.importNode) {
573 for(var i=0;i < nodes.length;i++) {
574 nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));
575 };
576 }else{
577 for(var i=0;i < nodes.length;i++) {
578 nodeTo.appendChild(nodes[i].cloneNode(true));
579 };
580 };
581 Sarissa.clearChildNodes(nodeFrom);
582 };
583};
584
585/**
586 * <p>Serialize any object to an XML string. All properties are serialized using the property name
587 * as the XML element name. Array elements are rendered as <code>array-item</code> elements,
588 * using their index/key as the value of the <code>key</code> attribute.</p>
589 * @argument anyObject the object to serialize
590 * @argument objectName a name for that object
591 * @return the XML serializationj of the given object as a string
592 */
593Sarissa.xmlize = function(anyObject, objectName, indentSpace){
594 indentSpace = indentSpace?indentSpace:'';
595 var s = indentSpace + '<' + objectName + '>';
596 var isLeaf = false;
597 if(!(anyObject instanceof Object) || anyObject instanceof Number ||
598 anyObject instanceof String || anyObject instanceof Boolean ||
599 anyObject instanceof Date){
600 s += Sarissa.escape(""+anyObject);
601 isLeaf = true;
602 }else{
603 s += "\n";
604 var isArrayItem = anyObject instanceof Array;
605 for(var name in anyObject){
606 s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + " ");
607 };
608 s += indentSpace;
609 };
610 return (s += (objectName.indexOf(' ')!=-1?"</array-item>\n":"</" + objectName + ">\n"));
611};
612
613/**
614 * Escape the given string chacters that correspond to the five predefined XML entities
615 * @param sXml the string to escape
616 */
617Sarissa.escape = function(sXml){
618 return sXml.replace(/&/g, "&amp;").
619 replace(/</g, "&lt;").
620 replace(/>/g, "&gt;").
621 replace(/"/g, "&quot;").
622 replace(/'/g, "&apos;");
623};
624
625/**
626 * Unescape the given string. This turns the occurences of the predefined XML
627 * entities to become the characters they represent correspond to the five predefined XML entities
628 * @param sXml the string to unescape
629 */
630Sarissa.unescape = function(sXml){
631 return sXml.replace(/&apos;/g,"'").
632 replace(/&quot;/g,"\"").
633 replace(/&gt;/g,">").
634 replace(/&lt;/g,"<").
635 replace(/&amp;/g,"&");
636};
637// EOF
638