source: package_branches/invirt-web/cherrypy/code/static/ajaxterm/sarissa.js @ 2427

Last change on this file since 2427 was 2427, checked in by quentin, 15 years ago

Import upstream ajaxterm 0.10

File size: 26.6 KB
Line 
1/**
2 * ====================================================================
3 * About
4 * ====================================================================
5 * Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs.
6 * The library supports Gecko based browsers like Mozilla and Firefox,
7 * Internet Explorer (5.5+ with MSXML3.0+), Konqueror, Safari and a little of Opera
8 * @version 0.9.6.1
9 * @author: Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net
10 * ====================================================================
11 * Licence
12 * ====================================================================
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 or
15 * the GNU Lesser General Public License version 2.1 as published by
16 * the Free Software Foundation (your choice between the two).
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License or GNU Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * or GNU Lesser General Public License along with this program; if not,
25 * write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * or visit http://www.gnu.org
27 *
28 */
29/**
30 * <p>Sarissa is a utility class. Provides "static" methods for DOMDocument and
31 * XMLHTTP objects, DOM Node serializatrion to XML strings and other goodies.</p>
32 * @constructor
33 */
34function Sarissa(){};
35/** @private */
36Sarissa.PARSED_OK = "Document contains no parsing errors";
37/**
38 * Tells you whether transformNode and transformNodeToObject are available. This functionality
39 * is contained in sarissa_ieemu_xslt.js and is deprecated. If you want to control XSLT transformations
40 * use the XSLTProcessor
41 * @deprecated
42 * @type boolean
43 */
44Sarissa.IS_ENABLED_TRANSFORM_NODE = false;
45/**
46 * tells you whether XMLHttpRequest (or equivalent) is available
47 * @type boolean
48 */
49Sarissa.IS_ENABLED_XMLHTTP = false;
50/**
51 * tells you whether selectNodes/selectSingleNode is available
52 * @type boolean
53 */
54Sarissa.IS_ENABLED_SELECT_NODES = false;
55var _sarissa_iNsCounter = 0;
56var _SARISSA_IEPREFIX4XSLPARAM = "";
57var _SARISSA_HAS_DOM_IMPLEMENTATION = document.implementation && true;
58var _SARISSA_HAS_DOM_CREATE_DOCUMENT = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.createDocument;
59var _SARISSA_HAS_DOM_FEATURE = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.hasFeature;
60var _SARISSA_IS_MOZ = _SARISSA_HAS_DOM_CREATE_DOCUMENT && _SARISSA_HAS_DOM_FEATURE;
61var _SARISSA_IS_SAFARI = (navigator.userAgent && navigator.vendor && (navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1 || navigator.vendor.indexOf("Apple") != -1));
62var _SARISSA_IS_IE = document.all && window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf("msie") > -1  && navigator.userAgent.toLowerCase().indexOf("opera") == -1;
63if(!window.Node || !window.Node.ELEMENT_NODE){
64    var 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};
65};
66
67// IE initialization
68if(_SARISSA_IS_IE){
69    // for XSLT parameter names, prefix needed by IE
70    _SARISSA_IEPREFIX4XSLPARAM = "xsl:";
71    // used to store the most recent ProgID available out of the above
72    var _SARISSA_DOM_PROGID = "";
73    var _SARISSA_XMLHTTP_PROGID = "";
74    /**
75     * Called when the Sarissa_xx.js file is parsed, to pick most recent
76     * ProgIDs for IE, then gets destroyed.
77     * @param idList an array of MSXML PROGIDs from which the most recent will be picked for a given object
78     * @param enabledList an array of arrays where each array has two items; the index of the PROGID for which a certain feature is enabled
79     */
80    pickRecentProgID = function (idList, enabledList){
81        // found progID flag
82        var bFound = false;
83        for(var i=0; i < idList.length && !bFound; i++){
84            try{
85                var oDoc = new ActiveXObject(idList[i]);
86                o2Store = idList[i];
87                bFound = true;
88                for(var j=0;j<enabledList.length;j++)
89                    if(i <= enabledList[j][1])
90                        Sarissa["IS_ENABLED_"+enabledList[j][0]] = true;
91            }catch (objException){
92                // trap; try next progID
93            };
94        };
95        if (!bFound)
96            throw "Could not retreive a valid progID of Class: " + idList[idList.length-1]+". (original exception: "+e+")";
97        idList = null;
98        return o2Store;
99    };
100    // pick best available MSXML progIDs
101    _SARISSA_DOM_PROGID = pickRecentProgID(["Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"], [["SELECT_NODES", 2],["TRANSFORM_NODE", 2]]);
102    _SARISSA_XMLHTTP_PROGID = pickRecentProgID(["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"], [["XMLHTTP", 4]]);
103    _SARISSA_THREADEDDOM_PROGID = pickRecentProgID(["Msxml2.FreeThreadedDOMDocument.5.0", "MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
104    _SARISSA_XSLTEMPLATE_PROGID = pickRecentProgID(["Msxml2.XSLTemplate.5.0", "Msxml2.XSLTemplate.4.0", "MSXML2.XSLTemplate.3.0"], [["XSLTPROC", 2]]);
105    // we dont need this anymore
106    pickRecentProgID = null;
107    //============================================
108    // Factory methods (IE)
109    //============================================
110    // see non-IE version
111    Sarissa.getDomDocument = function(sUri, sName){
112        var oDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
113        // if a root tag name was provided, we need to load it in the DOM
114        // object
115        if (sName){
116            // if needed, create an artifical namespace prefix the way Moz
117            // does
118            if (sUri){
119                oDoc.loadXML("<a" + _sarissa_iNsCounter + ":" + sName + " xmlns:a" + _sarissa_iNsCounter + "=\"" + sUri + "\" />");
120                // don't use the same prefix again
121                ++_sarissa_iNsCounter;
122            }
123            else
124                oDoc.loadXML("<" + sName + "/>");
125        };
126        return oDoc;
127    };
128    // see non-IE version   
129    Sarissa.getParseErrorText = function (oDoc) {
130        var parseErrorText = Sarissa.PARSED_OK;
131        if(oDoc.parseError != 0){
132            parseErrorText = "XML Parsing Error: " + oDoc.parseError.reason + 
133                "\nLocation: " + oDoc.parseError.url + 
134                "\nLine Number " + oDoc.parseError.line + ", Column " + 
135                oDoc.parseError.linepos + 
136                ":\n" + oDoc.parseError.srcText +
137                "\n";
138            for(var i = 0;  i < oDoc.parseError.linepos;i++){
139                parseErrorText += "-";
140            };
141            parseErrorText +=  "^\n";
142        };
143        return parseErrorText;
144    };
145    // see non-IE version
146    Sarissa.setXpathNamespaces = function(oDoc, sNsSet) {
147        oDoc.setProperty("SelectionLanguage", "XPath");
148        oDoc.setProperty("SelectionNamespaces", sNsSet);
149    };   
150    /**
151     * Basic implementation of Mozilla's XSLTProcessor for IE.
152     * Reuses the same XSLT stylesheet for multiple transforms
153     * @constructor
154     */
155    XSLTProcessor = function(){
156        this.template = new ActiveXObject(_SARISSA_XSLTEMPLATE_PROGID);
157        this.processor = null;
158    };
159    /**
160     * Impoprts the given XSLT DOM and compiles it to a reusable transform
161     * @argument xslDoc The XSLT DOMDocument to import
162     */
163    XSLTProcessor.prototype.importStylesheet = function(xslDoc){
164        // convert stylesheet to free threaded
165        var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID); 
166        converted.loadXML(xslDoc.xml);
167        this.template.stylesheet = converted;
168        this.processor = this.template.createProcessor();
169        // (re)set default param values
170        this.paramsSet = new Array();
171    };
172    /**
173     * Transform the given XML DOM
174     * @argument sourceDoc The XML DOMDocument to transform
175     * @return The transformation result as a DOM Document
176     */
177    XSLTProcessor.prototype.transformToDocument = function(sourceDoc){
178        this.processor.input = sourceDoc;
179        var outDoc = new ActiveXObject(_SARISSA_DOM_PROGID);
180        this.processor.output = outDoc; 
181        this.processor.transform();
182        return outDoc;
183    };
184    /**
185     * Set global XSLT parameter of the imported stylesheet
186     * @argument nsURI The parameter namespace URI
187     * @argument name The parameter base name
188     * @argument value The new parameter value
189     */
190    XSLTProcessor.prototype.setParameter = function(nsURI, name, value){
191        /* nsURI is optional but cannot be null */
192        if(nsURI){
193            this.processor.addParameter(name, value, nsURI);
194        }else{
195            this.processor.addParameter(name, value);
196        };
197        /* update updated params for getParameter */
198        if(!this.paramsSet[""+nsURI]){
199            this.paramsSet[""+nsURI] = new Array();
200        };
201        this.paramsSet[""+nsURI][name] = value;
202    };
203    /**
204     * Gets a parameter if previously set by setParameter. Returns null
205     * otherwise
206     * @argument name The parameter base name
207     * @argument value The new parameter value
208     * @return The parameter value if reviously set by setParameter, null otherwise
209     */
210    XSLTProcessor.prototype.getParameter = function(nsURI, name){
211        nsURI = nsURI || "";
212        if(nsURI in this.paramsSet && name in this.paramsSet[nsURI]){
213            return this.paramsSet[nsURI][name];
214        }else{
215            return null;
216        };
217    };
218}
219else{ /* end IE initialization, try to deal with real browsers now ;-) */
220    if(_SARISSA_HAS_DOM_CREATE_DOCUMENT){
221        /**
222         * <p>Ensures the document was loaded correctly, otherwise sets the
223         * parseError to -1 to indicate something went wrong. Internal use</p>
224         * @private
225         */
226        Sarissa.__handleLoad__ = function(oDoc){
227            if (!oDoc.documentElement || oDoc.documentElement.tagName == "parsererror")
228                oDoc.parseError = -1;
229            Sarissa.__setReadyState__(oDoc, 4);
230        };
231        /**
232        * <p>Attached by an event handler to the load event. Internal use.</p>
233        * @private
234        */
235        _sarissa_XMLDocument_onload = function(){
236            Sarissa.__handleLoad__(this);
237        };
238        /**
239         * <p>Sets the readyState property of the given DOM Document object.
240         * Internal use.</p>
241         * @private
242         * @argument oDoc the DOM Document object to fire the
243         *          readystatechange event
244         * @argument iReadyState the number to change the readystate property to
245         */
246        Sarissa.__setReadyState__ = function(oDoc, iReadyState){
247            oDoc.readyState = iReadyState;
248            if (oDoc.onreadystatechange != null && typeof oDoc.onreadystatechange == "function")
249                oDoc.onreadystatechange();
250        };
251        Sarissa.getDomDocument = function(sUri, sName){
252            var oDoc = document.implementation.createDocument(sUri?sUri:"", sName?sName:"", null);
253            oDoc.addEventListener("load", _sarissa_XMLDocument_onload, false);
254            return oDoc;
255        };
256        if(window.XMLDocument){
257            /**
258            * <p>Emulate IE's onreadystatechange attribute</p>
259            */
260            XMLDocument.prototype.onreadystatechange = null;
261            /**
262            * <p>Emulates IE's readyState property, which always gives an integer from 0 to 4:</p>
263            * <ul><li>1 == LOADING,</li>
264            * <li>2 == LOADED,</li>
265            * <li>3 == INTERACTIVE,</li>
266            * <li>4 == COMPLETED</li></ul>
267            */
268            XMLDocument.prototype.readyState = 0;
269            /**
270            * <p>Emulate IE's parseError attribute</p>
271            */
272            XMLDocument.prototype.parseError = 0;
273
274            // NOTE: setting async to false will only work with documents
275            // called over HTTP (meaning a server), not the local file system,
276            // unless you are using Moz 1.4+.
277            // BTW the try>catch block is for 1.4; I haven't found a way to check if
278            // the property is implemented without
279            // causing an error and I dont want to use user agent stuff for that...
280            var _SARISSA_SYNC_NON_IMPLEMENTED = false;// ("async" in XMLDocument.prototype) ? false: true;
281            /**
282            * <p>Keeps a handle to the original load() method. Internal use and only
283            * if Mozilla version is lower than 1.4</p>
284            * @private
285            */
286            XMLDocument.prototype._sarissa_load = XMLDocument.prototype.load;
287
288            /**
289            * <p>Overrides the original load method to provide synchronous loading for
290            * Mozilla versions prior to 1.4, using an XMLHttpRequest object (if
291            * async is set to false)</p>
292            * @returns the DOM Object as it was before the load() call (may be  empty)
293            */
294            XMLDocument.prototype.load = function(sURI) {
295                var oDoc = document.implementation.createDocument("", "", null);
296                Sarissa.copyChildNodes(this, oDoc);
297                this.parseError = 0;
298                Sarissa.__setReadyState__(this, 1);
299                try {
300                    if(this.async == false && _SARISSA_SYNC_NON_IMPLEMENTED) {
301                        var tmp = new XMLHttpRequest();
302                        tmp.open("GET", sURI, false);
303                        tmp.send(null);
304                        Sarissa.__setReadyState__(this, 2);
305                        Sarissa.copyChildNodes(tmp.responseXML, this);
306                        Sarissa.__setReadyState__(this, 3);
307                    }
308                    else {
309                        this._sarissa_load(sURI);
310                    };
311                }
312                catch (objException) {
313                    this.parseError = -1;
314                }
315                finally {
316                    if(this.async == false){
317                        Sarissa.__handleLoad__(this);
318                    };
319                };
320                return oDoc;
321            };
322           
323           
324        }//if(window.XMLDocument)
325        else if(document.implementation && document.implementation.hasFeature && document.implementation.hasFeature('LS', '3.0')){
326            Document.prototype.async = true;
327            Document.prototype.onreadystatechange = null;
328            Document.prototype.parseError = 0;
329            Document.prototype.load = function(sURI) {
330                var parser = document.implementation.createLSParser(this.async ? document.implementation.MODE_ASYNCHRONOUS : document.implementation.MODE_SYNCHRONOUS, null);
331                if(this.async){
332                    var self = this;
333                    parser.addEventListener("load", 
334                        function(e) { 
335                            self.readyState = 4;
336                            Sarissa.copyChildNodes(e.newDocument, self.documentElement, false);
337                            self.onreadystatechange.call(); 
338                        }, 
339                        false); 
340                };
341                try {
342                    var oDoc = parser.parseURI(sURI);
343                }
344                catch(e){
345                    this.parseError = -1;
346                };
347                if(!this.async)
348                   Sarissa.copyChildNodes(oDoc, this.documentElement, false);
349                return oDoc;
350            };
351            /**
352            * <p>Factory method to obtain a new DOM Document object</p>
353            * @argument sUri the namespace of the root node (if any)
354            * @argument sUri the local name of the root node (if any)
355            * @returns a new DOM Document
356            */
357            Sarissa.getDomDocument = function(sUri, sName){
358                return document.implementation.createDocument(sUri?sUri:"", sName?sName:"", null);
359            };       
360        };
361    };//if(_SARISSA_HAS_DOM_CREATE_DOCUMENT)
362};
363//==========================================
364// Common stuff
365//==========================================
366if(!window.DOMParser){
367    /*
368    * DOMParser is a utility class, used to construct DOMDocuments from XML strings
369    * @constructor
370    */
371    DOMParser = function() {
372    };
373    if(_SARISSA_IS_SAFARI){
374        /**
375        * Construct a new DOM Document from the given XMLstring
376        * @param sXml the given XML string
377        * @param contentType the content type of the document the given string represents (one of text/xml, application/xml, application/xhtml+xml).
378        * @return a new DOM Document from the given XML string
379        */
380        DOMParser.prototype.parseFromString = function(sXml, contentType){
381            if(contentType.toLowerCase() != "application/xml"){
382                throw "Cannot handle content type: \"" + contentType + "\"";
383            };
384            var xmlhttp = new XMLHttpRequest();
385            xmlhttp.open("GET", "data:text/xml;charset=utf-8," + encodeURIComponent(str), false);
386            xmlhttp.send(null);
387            return xmlhttp.responseXML;
388        };
389    }else if(Sarissa.getDomDocument && Sarissa.getDomDocument() && "loadXML" in Sarissa.getDomDocument()){
390        DOMParser.prototype.parseFromString = function(sXml, contentType){
391            var doc = Sarissa.getDomDocument();
392            doc.loadXML(sXml);
393            return doc;
394        };
395    };
396};
397
398if(window.XMLHttpRequest){
399    Sarissa.IS_ENABLED_XMLHTTP = true;
400}
401else if(_SARISSA_IS_IE){
402    /**
403     * Emulate XMLHttpRequest
404     * @constructor
405     */
406    XMLHttpRequest = function() {
407        return new ActiveXObject(_SARISSA_XMLHTTP_PROGID);
408    };
409    Sarissa.IS_ENABLED_XMLHTTP = true;
410};
411
412if(!window.document.importNode && _SARISSA_IS_IE){
413    try{
414        /**
415        * Implements importNode for the current window document in IE using innerHTML.
416        * Testing showed that DOM was multiple times slower than innerHTML for this,
417        * sorry folks. If you encounter trouble (who knows what IE does behind innerHTML)
418        * please gimme a call.
419        * @param oNode the Node to import
420        * @param bChildren whether to include the children of oNode
421        * @returns the imported node for further use
422        */
423        window.document.importNode = function(oNode, bChildren){
424            var importNode = document.createElement("div");
425            if(bChildren)
426                importNode.innerHTML = Sarissa.serialize(oNode);
427            else
428                importNode.innerHTML = Sarissa.serialize(oNode.cloneNode(false));
429            return importNode.firstChild;
430        };
431        }catch(e){};
432};
433if(!Sarissa.getParseErrorText){
434    /**
435     * <p>Returns a human readable description of the parsing error. Usefull
436     * for debugging. Tip: append the returned error string in a &lt;pre&gt;
437     * element if you want to render it.</p>
438     * <p>Many thanks to Christian Stocker for the initial patch.</p>
439     * @argument oDoc The target DOM document
440     * @returns The parsing error description of the target Document in
441     *          human readable form (preformated text)
442     */
443    Sarissa.getParseErrorText = function (oDoc){
444        var parseErrorText = Sarissa.PARSED_OK;
445        if(oDoc && oDoc.parseError && oDoc.parseError != 0){
446            /*moz*/
447            if(oDoc.documentElement.tagName == "parsererror"){
448                parseErrorText = oDoc.documentElement.firstChild.data;
449                parseErrorText += "\n" +  oDoc.documentElement.firstChild.nextSibling.firstChild.data;
450            }/*konq*/
451            else{
452                parseErrorText = Sarissa.getText(oDoc.documentElement);/*.getElementsByTagName("h1")[0], false) + "\n";
453                parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("body")[0], false) + "\n";
454                parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("pre")[0], false);*/
455            };
456        };
457        return parseErrorText;
458    };
459};
460Sarissa.getText = function(oNode, deep){
461    var s = "";
462    var nodes = oNode.childNodes;
463    for(var i=0; i < nodes.length; i++){
464        var node = nodes[i];
465        var nodeType = node.nodeType;
466        if(nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE){
467            s += node.data;
468        }else if(deep == true
469                    && (nodeType == Node.ELEMENT_NODE
470                        || nodeType == Node.DOCUMENT_NODE
471                        || nodeType == Node.DOCUMENT_FRAGMENT_NODE)){
472            s += Sarissa.getText(node, true);
473        };
474    };
475    return s;
476};
477if(window.XMLSerializer){
478    /**
479     * <p>Factory method to obtain the serialization of a DOM Node</p>
480     * @returns the serialized Node as an XML string
481     */
482    Sarissa.serialize = function(oDoc){
483        var s = null;
484        if(oDoc){
485            s = oDoc.innerHTML?oDoc.innerHTML:(new XMLSerializer()).serializeToString(oDoc);
486        };
487        return s;
488    };
489}else{
490    if(Sarissa.getDomDocument && (Sarissa.getDomDocument("","foo", null)).xml){
491        // see non-IE version
492        Sarissa.serialize = function(oDoc) {
493            var s = null;
494            if(oDoc){
495                s = oDoc.innerHTML?oDoc.innerHTML:oDoc.xml;
496            };
497            return s;
498        };
499        /**
500         * Utility class to serialize DOM Node objects to XML strings
501         * @constructor
502         */
503        XMLSerializer = function(){};
504        /**
505         * Serialize the given DOM Node to an XML string
506         * @param oNode the DOM Node to serialize
507         */
508        XMLSerializer.prototype.serializeToString = function(oNode) {
509            return oNode.xml;
510        };
511    };
512};
513
514/**
515 * strips tags from a markup string
516 */
517Sarissa.stripTags = function (s) {
518    return s.replace(/<[^>]+>/g,"");
519};
520/**
521 * <p>Deletes all child nodes of the given node</p>
522 * @argument oNode the Node to empty
523 */
524Sarissa.clearChildNodes = function(oNode) {
525    // need to check for firstChild due to opera 8 bug with hasChildNodes
526    while(oNode.firstChild){
527        oNode.removeChild(oNode.firstChild);
528    };
529};
530/**
531 * <p> Copies the childNodes of nodeFrom to nodeTo</p>
532 * <p> <b>Note:</b> The second object's original content is deleted before
533 * the copy operation, unless you supply a true third parameter</p>
534 * @argument nodeFrom the Node to copy the childNodes from
535 * @argument nodeTo the Node to copy the childNodes to
536 * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is false
537 */
538Sarissa.copyChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {
539    if((!nodeFrom) || (!nodeTo)){
540        throw "Both source and destination nodes must be provided";
541    };
542    if(!bPreserveExisting){
543        Sarissa.clearChildNodes(nodeTo);
544    };
545    var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;
546    var nodes = nodeFrom.childNodes;
547    if(ownerDoc.importNode && (!_SARISSA_IS_IE)) {
548        for(var i=0;i < nodes.length;i++) {
549            nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));
550        };
551    }
552    else{
553        for(var i=0;i < nodes.length;i++) {
554            nodeTo.appendChild(nodes[i].cloneNode(true));
555        };
556    };
557};
558
559/**
560 * <p> Moves the childNodes of nodeFrom to nodeTo</p>
561 * <p> <b>Note:</b> The second object's original content is deleted before
562 * the move operation, unless you supply a true third parameter</p>
563 * @argument nodeFrom the Node to copy the childNodes from
564 * @argument nodeTo the Node to copy the childNodes to
565 * @argument bPreserveExisting whether to preserve the original content of nodeTo, default is
566 */ 
567Sarissa.moveChildNodes = function(nodeFrom, nodeTo, bPreserveExisting) {
568    if((!nodeFrom) || (!nodeTo)){
569        throw "Both source and destination nodes must be provided";
570    };
571    if(!bPreserveExisting){
572        Sarissa.clearChildNodes(nodeTo);
573    };
574    var nodes = nodeFrom.childNodes;
575    // if within the same doc, just move, else copy and delete
576    if(nodeFrom.ownerDocument == nodeTo.ownerDocument){
577        while(nodeFrom.firstChild){
578            nodeTo.appendChild(nodeFrom.firstChild);
579        };
580    }else{
581        var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument;
582        if(ownerDoc.importNode && (!_SARISSA_IS_IE)) {
583           for(var i=0;i < nodes.length;i++) {
584               nodeTo.appendChild(ownerDoc.importNode(nodes[i], true));
585           };
586        }else{
587           for(var i=0;i < nodes.length;i++) {
588               nodeTo.appendChild(nodes[i].cloneNode(true));
589           };
590        };
591        Sarissa.clearChildNodes(nodeFrom);
592    };
593};
594
595/**
596 * <p>Serialize any object to an XML string. All properties are serialized using the property name
597 * as the XML element name. Array elements are rendered as <code>array-item</code> elements,
598 * using their index/key as the value of the <code>key</code> attribute.</p>
599 * @argument anyObject the object to serialize
600 * @argument objectName a name for that object
601 * @return the XML serializationj of the given object as a string
602 */
603Sarissa.xmlize = function(anyObject, objectName, indentSpace){
604    indentSpace = indentSpace?indentSpace:'';
605    var s = indentSpace  + '<' + objectName + '>';
606    var isLeaf = false;
607    if(!(anyObject instanceof Object) || anyObject instanceof Number || anyObject instanceof String 
608        || anyObject instanceof Boolean || anyObject instanceof Date){
609        s += Sarissa.escape(""+anyObject);
610        isLeaf = true;
611    }else{
612        s += "\n";
613        var itemKey = '';
614        var isArrayItem = anyObject instanceof Array;
615        for(var name in anyObject){
616            s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + "   ");
617        };
618        s += indentSpace;
619    };
620    return s += (objectName.indexOf(' ')!=-1?"</array-item>\n":"</" + objectName + ">\n");
621};
622
623/**
624 * Escape the given string chacters that correspond to the five predefined XML entities
625 * @param sXml the string to escape
626 */
627Sarissa.escape = function(sXml){
628    return sXml.replace(/&/g, "&amp;")
629        .replace(/</g, "&lt;")
630        .replace(/>/g, "&gt;")
631        .replace(/"/g, "&quot;")
632        .replace(/'/g, "&apos;");
633};
634
635/**
636 * Unescape the given string. This turns the occurences of the predefined XML
637 * entities to become the characters they represent correspond to the five predefined XML entities
638 * @param sXml the string to unescape
639 */
640Sarissa.unescape = function(sXml){
641    return sXml.replace(/&apos;/g,"'")
642        .replace(/&quot;/g,"\"")
643        .replace(/&gt;/g,">")
644        .replace(/&lt;/g,"<")
645        .replace(/&amp;/g,"&");
646};
647//   EOF
Note: See TracBrowser for help on using the repository browser.