Annotation of kupu/common/sarissa.js, revision 1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>