# HG changeset patch # User paulb # Date 1115074320 0 # Node ID 8bbec0abf16e828626fb86193c5afc432cfdbd94 # Parent 4e67c5b5fe17b7da34bbc1134984ae6870794f0d [project @ 2005-05-02 22:52:00 by paulb] Added usage of JavaScript functions to replace document sections dynamically based on "id" attributes. Introduced Sarissa, although the code is necessarily more convoluted than the Sarissa documentation would have one believe. diff -r 4e67c5b5fe17 -r 8bbec0abf16e examples/Common/Configurator/Resources/scripts/XSLForms.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/Common/Configurator/Resources/scripts/XSLForms.js Mon May 02 22:52:00 2005 +0000 @@ -0,0 +1,20 @@ +function requestUpdate(url, elementName, targetName) { + var xmlhttp = Sarissa.getXmlHttpRequest(); + xmlhttp.open("GET", url, false); + xmlhttp.send(null); + //alert(xmlhttp.status); + //alert(xmlhttp.responseText); + var newDocument = Sarissa.getDomDocument(); + newDocument.loadXML(xmlhttp.responseText); + //alert(newDocument); + var newElement = newDocument.getElementById(elementName); + var targetElement = document.getElementById(targetName); + //alert(newElement); + //alert(targetElement); + + if (newElement != null && targetElement != null) { + var importedElement = document.importNode(newElement, true); + targetElement.parentNode.replaceChild(importedElement, targetElement); + //importedElement.setAttribute("style", "background-color:red;"); + } +} diff -r 4e67c5b5fe17 -r 8bbec0abf16e examples/Common/Configurator/Resources/scripts/sarissa.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/Common/Configurator/Resources/scripts/sarissa.js Mon May 02 22:52:00 2005 +0000 @@ -0,0 +1,589 @@ +/** + * ==================================================================== + * About + * ==================================================================== + * Sarissa cross browser XML library + * @version 0.9.5.2 + * @author: Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net + * + * Sarissa is an ECMAScript library acting as a cross-browser wrapper for native XML APIs. + * The library supports Gecko based browsers like Mozilla and Firefox, + * Internet Explorer (5.5+ with MSXML3.0+) and, last but not least, KHTML based browsers like + * Konqueror and Safari. + * + * ==================================================================== + * Licence + * ==================================================================== + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * the GNU Lesser General Public License version 2.1 as published by + * the Free Software Foundation (your choice of the two). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License or GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * or GNU Lesser General Public License along with this program; if not, + * write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * or visit http://www.gnu.org + * + */ +/** + *

Sarissa is a utility class. Provides static methods for DOMDocument and + * XMLHTTP objects, DOM Node serializatrion to XML strings and other goodies.

+ * @constructor + */ +function Sarissa(){}; +/** @private */ +Sarissa.PARSED_OK = "Document contains no parsing errors"; +/** + * Tells you whether transformNode and transformNodeToObject are available. This functionality + * is contained in sarissa_ieemu_xslt.js and is deprecated. If you want to control XSLT transformations + * use the XSLTProcessor + * @deprecated + * @type boolean + */ +Sarissa.IS_ENABLED_TRANSFORM_NODE = false; +/** + * tells you whether XMLHttpRequest (or equivalent) is available + * @type boolean + */ +Sarissa.IS_ENABLED_XMLHTTP = false; +/** + * Deprecated, will be removed in 0.9.6. Check for + * window.XSLTProcessor instead to see if + * XSLTProcessor is available. + * @type boolean + */ +Sarissa.IS_ENABLED_XSLTPROC = false; +/** + * tells you whether selectNodes/selectSingleNode is available + * @type boolean + */ +Sarissa.IS_ENABLED_SELECT_NODES = false; +var _sarissa_iNsCounter = 0; +var _SARISSA_IEPREFIX4XSLPARAM = ""; +var _SARISSA_HAS_DOM_IMPLEMENTATION = document.implementation && true; +var _SARISSA_HAS_DOM_CREATE_DOCUMENT = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.createDocument; +var _SARISSA_HAS_DOM_FEATURE = _SARISSA_HAS_DOM_IMPLEMENTATION && document.implementation.hasFeature; +/** Deprecated, will be removed in 0.9.6. @deprecated */ +var _SARISSA_IS_MOZ = _SARISSA_HAS_DOM_CREATE_DOCUMENT && _SARISSA_HAS_DOM_FEATURE; +/** Deprecated, will be removed in 0.9.6. @deprecated */ +var _SARISSA_IS_IE = document.all && window.ActiveXObject && (navigator.userAgent.toLowerCase().indexOf("msie") > -1); +//========================================== +// Implement Node constants if not available +//========================================== +if(!window.Node || !window.Node.ELEMENT_NODE){ + 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}; +}; +// IE initialization +if(_SARISSA_IS_IE){ + // for XSLT parameter names, prefix needed by IE + _SARISSA_IEPREFIX4XSLPARAM = "xsl:"; + // used to store the most recent ProgID available out of the above + var _SARISSA_DOM_PROGID = ""; + var _SARISSA_XMLHTTP_PROGID = ""; + /** + * Called when the Sarissa_xx.js file is parsed, to pick most recent + * ProgIDs for IE, then gets destroyed. + * @param idList an array of MSXML PROGIDs from which the most recent will be picked for a given object + * @param enabledList an array of arrays where each array has two items; the index of the PROGID for which a certain feature is enabled + */ + function pickRecentProgID(idList, enabledList){ + // found progID flag + var bFound = false; + for(var i=0; i < idList.length && !bFound; i++){ + try{ + var oDoc = new ActiveXObject(idList[i]); + o2Store = idList[i]; + bFound = true; + for(var j=0;j"); + // don't use the same prefix again + ++_sarissa_iNsCounter; + } + else + oDoc.loadXML("<" + sName + "/>"); + }; + return oDoc; + }; + if(!window.XMLHttpRequest){ + /** + * Emulate XMLHttpRequest + * @constructor + */ + function XMLHttpRequest(){ + return new ActiveXObject(_SARISSA_XMLHTTP_PROGID); + }; + }; + // see non-IE version + Sarissa.getParseErrorText = function (oDoc) { + var parseErrorText = Sarissa.PARSED_OK; + if(oDoc.parseError != 0){ + parseErrorText = "XML Parsing Error: " + oDoc.parseError.reason + + "\nLocation: " + oDoc.parseError.url + + "\nLine Number " + oDoc.parseError.line + ", Column " + + oDoc.parseError.linepos + + ":\n" + oDoc.parseError.srcText + + "\n"; + for(var i = 0; i < oDoc.parseError.linepos;i++){ + parseErrorText += "-"; + }; + parseErrorText += "^\n"; + }; + return parseErrorText; + }; + // see non-IE version + Sarissa.setXpathNamespaces = function(oDoc, sNsSet) { + oDoc.setProperty("SelectionLanguage", "XPath"); + oDoc.setProperty("SelectionNamespaces", sNsSet); + }; + /** + * Basic implementation of Mozilla's XSLTProcessor for IE. + * Reuses the same XSLT stylesheet for multiple transforms + * @constructor + */ + function XSLTProcessor(){ + this.template = new ActiveXObject(_SARISSA_XSLTEMPLATE_PROGID); + this.processor = null; + }; + /** + * Impoprts the given XSLT DOM and compiles it to a reusable transform + * @argument xslDoc The XSLT DOMDocument to import + */ + XSLTProcessor.prototype.importStylesheet = function(xslDoc){ + // convert stylesheet to free threaded + var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID); + converted.loadXML(xslDoc.xml); + this.template.stylesheet = converted; + this.processor = this.template.createProcessor(); + // (re)set default param values + this.paramsSet = new Array(); + }; + /** + * Transform the given XML DOM + * @argument sourceDoc The XML DOMDocument to transform + * @return The transformation result as a DOM Document + */ + XSLTProcessor.prototype.transformToDocument = function(sourceDoc){ + this.processor.input = sourceDoc; + var outDoc = new ActiveXObject(_SARISSA_DOM_PROGID); + this.processor.output = outDoc; + this.processor.transform(); + return outDoc; + }; + /** + * Not sure if this works in IE. Maybe this will allow non-well-formed + * transformation results (i.e. with no single root element) + * @argument sourceDoc The XML DOMDocument to transform + * @return The transformation result as a DOM Fragment + */ + XSLTProcessor.prototype.transformToFragment = function(sourceDoc, ownerDocument){ + return this.transformToDocument(sourceDoc); + }; + /** + * Set global XSLT parameter of the imported stylesheet + * @argument nsURI The parameter namespace URI + * @argument name The parameter base name + * @argument value The new parameter value + */ + XSLTProcessor.prototype.setParameter = function(nsURI, name, value){ + /* nsURI is optional but cannot be null */ + if(nsURI){ + this.processor.addParameter(name, value, nsURI); + }else{ + this.processor.addParameter(name, value); + }; + /* update updated params for getParameter */ + if(!this.paramsSet[""+nsURI]){ + this.paramsSet[""+nsURI] = new Array(); + }; + this.paramsSet[""+nsURI][name] = value; + }; + /** + * Gets a parameter if previously set by setParameter. Returns null + * otherwise + * @argument name The parameter base name + * @argument value The new parameter value + * @return The parameter value if reviously set by setParameter, null otherwise + */ + XSLTProcessor.prototype.getParameter = function(nsURI, name){ + if(this.paramsSet[""+nsURI] && this.paramsSet[""+nsURI][name]) + return this.paramsSet[""+nsURI][name]; + else + return null; + }; +} +else{ /* end IE initialization, try to deal with real browsers now ;-) */ + if(_SARISSA_HAS_DOM_CREATE_DOCUMENT){ + if(window.XMLDocument){ + /** + *

Emulate IE's onreadystatechange attribute

+ */ + XMLDocument.prototype.onreadystatechange = null; + /** + *

Emulates IE's readyState property, which always gives an integer from 0 to 4:

+ * + */ + XMLDocument.prototype.readyState = 0; + /** + *

Emulate IE's parseError attribute

+ */ + XMLDocument.prototype.parseError = 0; + + // NOTE: setting async to false will only work with documents + // called over HTTP (meaning a server), not the local file system, + // unless you are using Moz 1.4+. + // BTW the try>catch block is for 1.4; I haven't found a way to check if + // the property is implemented without + // causing an error and I dont want to use user agent stuff for that... + var _SARISSA_SYNC_NON_IMPLEMENTED = false; + try{ + /** + *

Emulates IE's async property for Moz versions prior to 1.4. + * It controls whether loading of remote XML files works + * synchronously or asynchronously.

+ */ + XMLDocument.prototype.async = true; + _SARISSA_SYNC_NON_IMPLEMENTED = true; + }catch(e){/* trap */}; + /** + *

Keeps a handle to the original load() method. Internal use and only + * if Mozilla version is lower than 1.4

+ * @private + */ + XMLDocument.prototype._sarissa_load = XMLDocument.prototype.load; + + /** + *

Overrides the original load method to provide synchronous loading for + * Mozilla versions prior to 1.4, using an XMLHttpRequest object (if + * async is set to false)

+ * @returns the DOM Object as it was before the load() call (may be empty) + */ + XMLDocument.prototype.load = function(sURI) { + var oDoc = document.implementation.createDocument("", "", null); + Sarissa.copyChildNodes(this, oDoc); + this.parseError = 0; + Sarissa.__setReadyState__(this, 1); + try { + if(this.async == false && _SARISSA_SYNC_NON_IMPLEMENTED) { + var tmp = new XMLHttpRequest(); + tmp.open("GET", sURI, false); + tmp.send(null); + Sarissa.__setReadyState__(this, 2); + Sarissa.copyChildNodes(tmp.responseXML, this); + Sarissa.__setReadyState__(this, 3); + } + else { + this._sarissa_load(sURI); + }; + } + catch (objException) { + this.parseError = -1; + } + finally { + if(this.async == false){ + Sarissa.__handleLoad__(this); + }; + }; + return oDoc; + }; + + if(window.DOMParser && !XMLDocument.loadXML){ + /** + *

Parses the String given as parameter to build the document content + * for the object, exactly like IE's loadXML()

+ * @argument strXML The XML String to load as the Document's childNodes + * @returns the old Document structure serialized as an XML String + */ + XMLDocument.prototype.loadXML = function(strXML){ + Sarissa.__setReadyState__(this, 1); + var sOldXML = this.xml; + var oDoc = (new DOMParser()).parseFromString(strXML, "text/xml"); + Sarissa.__setReadyState__(this, 2); + Sarissa.copyChildNodes(oDoc, this); + Sarissa.__setReadyState__(this, 3); + Sarissa.__handleLoad__(this); + return sOldXML; + }; + };//if(window.DOMParser && !XMLDocument.loadXML) + };//if(window.XMLDocument) + + /** + *

Ensures the document was loaded correctly, otherwise sets the + * parseError to -1 to indicate something went wrong. Internal use

+ * @private + */ + Sarissa.__handleLoad__ = function(oDoc){ + if (!oDoc.documentElement || oDoc.documentElement.tagName == "parsererror") + oDoc.parseError = -1; + Sarissa.__setReadyState__(oDoc, 4); + }; + /** + *

Attached by an event handler to the load event. Internal use.

+ * @private + */ + function _sarissa_XMLDocument_onload() { + Sarissa.__handleLoad__(this); + }; + /** + *

Sets the readyState property of the given DOM Document object. + * Internal use.

+ * @private + * @argument oDoc the DOM Document object to fire the + * readystatechange event + * @argument iReadyState the number to change the readystate property to + */ + Sarissa.__setReadyState__ = function(oDoc, iReadyState){ + oDoc.readyState = iReadyState; + if (oDoc.onreadystatechange != null && typeof oDoc.onreadystatechange == "function") + oDoc.onreadystatechange(); + }; + /** + *

Factory method to obtain a new DOM Document object

+ * @argument sUri the namespace of the root node (if any) + * @argument sUri the local name of the root node (if any) + * @returns a new DOM Document + */ + Sarissa.getDomDocument = function(sUri, sName){ + var oDoc = document.implementation.createDocument(sUri?sUri:"", sName?sName:"", null); + oDoc.addEventListener("load", _sarissa_XMLDocument_onload, false); + return oDoc; + }; + };//if(_SARISSA_HAS_DOM_CREATE_DOCUMENT) +}; +//========================================== +// Common stuff +//========================================== +if(window.XMLHttpRequest){ + /** + *

Deprecated, will be removed in 0.9.6. Factory method to obtain a new XMLHTTP Request object

+ * @returns a new XMLHTTP Request object + * @deprecated + */ + Sarissa.getXmlHttpRequest = function() { + return new XMLHttpRequest(); + }; + Sarissa.IS_ENABLED_XMLHTTP = true; +}; +if(!window.document.importNode){ + /** + * Implements importNode for the current window document in IE using innerHTML. + * Testing showed that DOM was multiple times slower than innerHTML for this, + * sorry folks. If you encounter trouble (who knows what IE does behind innerHTML) + * please gimme a call. + * @param oNode the Node to import + * @param bChildren whether to include the children of oNode + * @returns the imported node for further use + */ + window.document.importNode = function(oNode, bChildren){ + var importNode = document.createElement("div"); + if(bChildren) + importNode.innerHTML = Sarissa.serialize(oNode); + else + importNode.innerHTML = Sarissa.serialize(oNode.cloneNode(false)); + return importNode.firstChild; + }; +}; +if(!Sarissa.getParseErrorText){ + /** + *

Returns a human readable description of the parsing error. Usefull + * for debugging. Tip: append the returned error string in a <pre> + * element if you want to render it.

+ *

Many thanks to Christian Stocker for the initial patch.

+ * @argument oDoc The target DOM document + * @returns The parsing error description of the target Document in + * human readable form (preformated text) + */ + Sarissa.getParseErrorText = function (oDoc){ + var parseErrorText = Sarissa.PARSED_OK; + if(oDoc.parseError != 0){ + /*moz*/ + if(oDoc.documentElement.tagName == "parsererror"){ + parseErrorText = oDoc.documentElement.firstChild.data; + parseErrorText += "\n" + oDoc.documentElement.firstChild.nextSibling.firstChild.data; + }/*konq*/ + else if(oDoc.documentElement.tagName == "html"){ + parseErrorText = Sarissa.getText(oDoc.documentElement.getElementsByTagName("h1")[0], false) + "\n"; + parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("body")[0], false) + "\n"; + parseErrorText += Sarissa.getText(oDoc.documentElement.getElementsByTagName("pre")[0], false); + }; + }; + return parseErrorText; + }; +}; +Sarissa.getText = function(oNode, deep){ + var s = ""; + var nodes = oNode.childNodes; + for(var i=0; i < nodes.length; i++){ + var node = nodes[i]; + if(node.nodeType == Node.TEXT_NODE){ + s += node.data; + }else if(deep == true + && (node.nodeType == Node.ELEMENT_NODE + || node.nodeType == Node.DOCUMENT_NODE + || node.nodeType == Node.DOCUMENT_FRAGMENT_NODE)){ + + s += Sarissa.getText(node, true); + }; + }; + return s; +}; +if(window.XMLSerializer){ + /** + *

Factory method to obtain the serialization of a DOM Node

+ * @returns the serialized Node as an XML string + */ + Sarissa.serialize = function(oDoc){ + return (new XMLSerializer()).serializeToString(oDoc); + }; +}else{ + if((Sarissa.getDomDocument("","foo", null)).xml){ + // see non-IE version + Sarissa.serialize = function(oDoc) { + // TODO: check for HTML document and return innerHTML instead + return oDoc.xml; + }; + /** + * Utility class to serialize DOM Node objects to XML strings + * @constructor + */ + XMLSerializer = function(){}; + /** + * Serialize the given DOM Node to an XML string + * @param oNode the DOM Node to serialize + */ + XMLSerializer.prototype.serializeToString = function(oNode) { + return oNode.xml; + }; + }; +}; +if(window.XSLTProcessor){ + Sarissa.IS_ENABLED_XSLTPROC = true; +}; +/** + * strips tags from a markup string + */ +Sarissa.stripTags = function (s) { + return s.replace(/<[^>]+>/g,""); +}; +/** + *

Deletes all child nodes of the given node

+ * @argument oNode the Node to empty + */ +Sarissa.clearChildNodes = function(oNode) { + while(oNode.hasChildNodes()){ + oNode.removeChild(oNode.firstChild); + }; +}; +/** + *

Replaces the childNodes of the toDoc object with the childNodes of + * the fromDoc object

+ *

Note: The second object's original content is deleted before the copy operation

+ * @argument nodeFrom the Node to copy the childNodes from + * @argument nodeTo the Node to copy the childNodes to + */ +Sarissa.copyChildNodes = function(nodeFrom, nodeTo) { + Sarissa.clearChildNodes(nodeTo); + var ownerDoc = nodeTo.nodeType == Node.DOCUMENT_NODE ? nodeTo : nodeTo.ownerDocument; + var nodes = nodeFrom.childNodes; + if(typeof(ownerDoc.importNode) == "function"){ + for(var i=0;i < nodes.length;i++) { + nodeTo.appendChild(ownerDoc.importNode(nodes[i], true)); + }; + } + else{ + for(var i=0;i < nodes.length;i++) { + nodeTo.appendChild(nodes[i].cloneNode(true)); + }; + }; +}; + +/** + *

Serialize any object to an XML string. All properties are serialized using the property name + * as the XML element name. Array elements are rendered as array-item elements, + * using their index/key as the value of the key attribute.

+ * @argument anyObject the object to serialize + * @argument objectName a name for that object + * @return the XML serializationj of the given object as a string + */ +Sarissa.xmlize = function(anyObject, objectName, indentSpace){ + indentSpace = indentSpace?indentSpace:''; + var s = indentSpace + '<' + objectName + '>'; + var isLeaf = false; + if(!(anyObject instanceof Object) || anyObject instanceof Number || anyObject instanceof String + || anyObject instanceof Boolean || anyObject instanceof Date){ + s += Sarissa.escape(""+anyObject); + isLeaf = true; + }else{ + s += "\n"; + var itemKey = ''; + var isArrayItem = anyObject instanceof Array; + for(var name in anyObject){ + s += Sarissa.xmlize(anyObject[name], (isArrayItem?"array-item key=\""+name+"\"":name), indentSpace + " "); + }; + s += indentSpace; + }; + return s += (objectName.indexOf(' ')!=-1?"\n":"\n"); +}; + +/** + * Escape the given string chacters that correspond to the five predefined XML entities + * @param sXml the string to escape + */ +Sarissa.escape = function(sXml){ + return sXml.replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +}; + +/** + * Unescape the given string. This turns the occurences of the predefined XML + * entities to become the characters they represent correspond to the five predefined XML entities + * @param sXml the string to unescape + */ +Sarissa.unescape = function(sXml){ + return sXml.replace(/'/g,"'") + .replace(/"/g,"\"") + .replace(/>/g,">") + .replace(/</g,"<") + .replace(/&/g,"&"); +}; +// EOF