| [2427] | 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 | */ | 
|---|
|  | 34 | function Sarissa(){}; | 
|---|
|  | 35 | /** @private */ | 
|---|
|  | 36 | Sarissa.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 | */ | 
|---|
|  | 44 | Sarissa.IS_ENABLED_TRANSFORM_NODE = false; | 
|---|
|  | 45 | /** | 
|---|
|  | 46 | * tells you whether XMLHttpRequest (or equivalent) is available | 
|---|
|  | 47 | * @type boolean | 
|---|
|  | 48 | */ | 
|---|
|  | 49 | Sarissa.IS_ENABLED_XMLHTTP = false; | 
|---|
|  | 50 | /** | 
|---|
|  | 51 | * tells you whether selectNodes/selectSingleNode is available | 
|---|
|  | 52 | * @type boolean | 
|---|
|  | 53 | */ | 
|---|
|  | 54 | Sarissa.IS_ENABLED_SELECT_NODES = false; | 
|---|
|  | 55 | var _sarissa_iNsCounter = 0; | 
|---|
|  | 56 | var _SARISSA_IEPREFIX4XSLPARAM = ""; | 
|---|
|  | 57 | var _SARISSA_HAS_DOM_IMPLEMENTATION = document.implementation && true; | 
|---|
|  | 58 | var _SARISSA_HAS_DOM_CREATE_DOCUMENT = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.createDocument; | 
|---|
|  | 59 | var _SARISSA_HAS_DOM_FEATURE = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.hasFeature; | 
|---|
|  | 60 | var _SARISSA_IS_MOZ = _SARISSA_HAS_DOM_CREATE_DOCUMENT && _SARISSA_HAS_DOM_FEATURE; | 
|---|
|  | 61 | var _SARISSA_IS_SAFARI = (navigator.userAgent && navigator.vendor && (navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1 || navigator.vendor.indexOf("Apple") != -1)); | 
|---|
|  | 62 | var _SARISSA_IS_IE = document.all && window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf("msie") > -1  && navigator.userAgent.toLowerCase().indexOf("opera") == -1; | 
|---|
|  | 63 | if(!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 | 
|---|
|  | 68 | if(_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 | } | 
|---|
|  | 219 | else{ /* 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 | //========================================== | 
|---|
|  | 366 | if(!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 |  | 
|---|
|  | 398 | if(window.XMLHttpRequest){ | 
|---|
|  | 399 | Sarissa.IS_ENABLED_XMLHTTP = true; | 
|---|
|  | 400 | } | 
|---|
|  | 401 | else 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 |  | 
|---|
|  | 412 | if(!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 | }; | 
|---|
|  | 433 | if(!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 <pre> | 
|---|
|  | 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 | }; | 
|---|
|  | 460 | Sarissa.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 | }; | 
|---|
|  | 477 | if(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 | */ | 
|---|
|  | 517 | Sarissa.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 | */ | 
|---|
|  | 524 | Sarissa.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 | */ | 
|---|
|  | 538 | Sarissa.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 | */ | 
|---|
|  | 567 | Sarissa.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 | */ | 
|---|
|  | 603 | Sarissa.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 | */ | 
|---|
|  | 627 | Sarissa.escape = function(sXml){ | 
|---|
|  | 628 | return sXml.replace(/&/g, "&") | 
|---|
|  | 629 | .replace(/</g, "<") | 
|---|
|  | 630 | .replace(/>/g, ">") | 
|---|
|  | 631 | .replace(/"/g, """) | 
|---|
|  | 632 | .replace(/'/g, "'"); | 
|---|
|  | 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 | */ | 
|---|
|  | 640 | Sarissa.unescape = function(sXml){ | 
|---|
|  | 641 | return sXml.replace(/'/g,"'") | 
|---|
|  | 642 | .replace(/"/g,"\"") | 
|---|
|  | 643 | .replace(/>/g,">") | 
|---|
|  | 644 | .replace(/</g,"<") | 
|---|
|  | 645 | .replace(/&/g,"&"); | 
|---|
|  | 646 | }; | 
|---|
|  | 647 | //   EOF | 
|---|