You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2010/05/14 12:54:34 UTC
svn commit: r944200 [3/3] - in /myfaces/core/trunk/api/src: assembler/
main/javascript/META-INF/resources/myfaces/_impl/_util/
main/javascript/META-INF/resources/myfaces/_impl/core/
main/javascript/META-INF/resources/myfaces/_impl/xhrCore/ main/javascr...
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js?rev=944200&r1=944199&r2=944200&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js Fri May 14 10:54:32 2010
@@ -1,513 +1,555 @@
-/*
- * Copyright 2009 Ganesh Jung
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Ganesh Jung (latest modification by $Author: ganeshpuri $)
- * Version: $Revision: 1.2 $ $Date: 2009/05/30 17:54:57 $
- *
- */
-
-_reserveMyfacesNamespaces();
-
-if (!myfaces._impl._util._LangUtils.exists(myfaces._impl.xhrCore, "_AjaxResponse")) {
-
-
- /**
- * Constructor
- * @param {String} alarmThreshold
- */
- myfaces._impl.xhrCore._AjaxResponse = function(alarmThreshold) {
- this.alarmThreshold = alarmThreshold;
- this.m_exception = new myfaces._impl.xhrCore._Exception("myfaces._impl.xhrCore._AjaxResponse", this.alarmThreshold);
- //change tracer for post changes operations
- this.changeTrace = [];
- this.appliedViewState = null;
- };
-
- /*partial response types*/
- myfaces._impl.xhrCore._AjaxResponse.prototype._RESPONSE_PARTIAL = "partial-response";
- myfaces._impl.xhrCore._AjaxResponse.prototype._RESPONSETYPE_ERROR = "error";
- /*TODO: -=Leonardo Uribe=- Does this response type really exists? really from server comes a partial-response with redirect command*/
- /*This really exists, it is for cases where a button issues a command and the server wants to redirect after processing the ajax request*/
- myfaces._impl.xhrCore._AjaxResponse.prototype._RESPONSETYPE_REDIRECT = "redirect";
- myfaces._impl.xhrCore._AjaxResponse.prototype._RESPONSETYPE_REDIRECT = "changes";
-
- /*partial commands*/
- myfaces._impl.xhrCore._AjaxResponse.prototype._PCMD_CHANGES = "changes";
- myfaces._impl.xhrCore._AjaxResponse.prototype._PCMD_UPDATE = "update";
- myfaces._impl.xhrCore._AjaxResponse.prototype._PCMD_DELETE = "delete";
- myfaces._impl.xhrCore._AjaxResponse.prototype._PCMD_INSERT = "insert";
- myfaces._impl.xhrCore._AjaxResponse.prototype._PCMD_EVAL = "eval";
- myfaces._impl.xhrCore._AjaxResponse.prototype._PCMD_ERROR = "error";
- myfaces._impl.xhrCore._AjaxResponse.prototype._PCMD_ATTRIBUTES = "attributes";
- myfaces._impl.xhrCore._AjaxResponse.prototype._PCMD_EXTENSION = "extension";
- myfaces._impl.xhrCore._AjaxResponse.prototype._PCMD_REDIRECT = "redirect";
- /**
- * uses response to start Html element replacement
- *
- * @param {Object} request - xhr request object
- * @param {Map} context - AJAX context
- *
- * A special handling has to be added to the update cycle
- * according to the JSDoc specs if the CDATA block contains html tags the outer rim must be stripped
- * if the CDATA block contains a head section the document head must be replaced
- * and if the CDATA block contains a body section the document body must be replaced!
- *
- */
- myfaces._impl.xhrCore._AjaxResponse.prototype.processResponse = function(request, context) {
- try {
- // TODO:
- // Solution from
- // http://www.codingforums.com/archive/index.php/t-47018.html
- // to solve IE error 1072896658 when a Java server sends iso88591
- // istead of ISO-8859-1
- if ('undefined' == typeof(request) || null == request) {
- throw Exception("jsf.ajaxResponse: The response cannot be null or empty!");
- }
-
- if (!myfaces._impl._util._LangUtils.exists(request, "responseXML")) {
- myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl._ERROR_EMPTY_RESPONSE);
- return;
- }
-
- var xmlContent = request.responseXML;
- if (xmlContent.firstChild.tagName == "parsererror") {
- myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl._ERROR_MALFORMEDXML);
- return;
- }
- var partials = xmlContent.childNodes[0];
- if ('undefined' == typeof partials || partials == null) {
- myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl._ERROR_MALFORMEDXML);
- return;
- } else {
- if (partials.tagName != this._RESPONSE_PARTIAL) {
- // IE 8 sees XML Header as first sibling ...
- partials = partials.nextSibling;
- if ('undefined' == typeof partials || partials == null || partials.tagName != this._RESPONSE_PARTIAL) {
- myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl._ERROR_MALFORMEDXML);
- return;
- }
- }
- }
-
- var childNodesLength = partials.childNodes.length;
-
- for (var loop = 0; loop < childNodesLength; loop++) {
- var childNode = partials.childNodes[loop];
- var tagName = childNode.tagName;
-
- /**
- * <eval>
- * <![CDATA[javascript]]>
- * </eval>
- */
-
- //this ought to be enough for eval
- //however the run scripts still makes sense
- //in the update and insert area for components
- //which do not use the response writer properly
- //we might add this one as custom option in update and
- //insert!
- if (tagName == this._PCMD_ERROR) {
- this.processError(request, context, childNode);
- return;
- } else if (tagName == this._PCMD_REDIRECT) {
- if (!this.processRedirect(request, context, childNode)) return;
- } else if (tagName == this._PCMD_CHANGES) {
- if (!this.processChanges(request, context, childNode)) return;
- }
- }
-
- //fixup missing viewStates due to spec deficiencies
- this.fixViewStates();
- } catch (e) {
- this.m_exception.throwError(request, context, "processResponse", e);
- }
- };
-
- myfaces._impl.xhrCore._AjaxResponse.prototype.fixViewStates = function() {
- if(null == this.appliedViewState) {
- return;
- }
- /*namespace remapping*/
- var _Utils = myfaces._impl._util._Utils;
-
- //note the spec here says clearly it is done, but mojarra not and there is a corner case
- //regarding cross form submits, hence we should check all processed items for embedded forms
- for (var cnt = 0; cnt < this.changeTrace.length; cnt ++) {
- var replacementElem = this.changeTrace[cnt];
- var replacedForms = myfaces._impl._util._Utils.findHtmlTypeFromFragment(replacementElem, "form", false);
- for (var formCnt = 0; formCnt < replacedForms.length; formCnt++) {
- //we first have to fetch the real form element because the fragment
- //might be detached in some browser implementations
- var appliedReplacedFrom = document.getElementById(replacedForms[formCnt].id);
- var viewStateField = myfaces._impl._util._Utils.findFormElement(appliedReplacedFrom, "javax.faces.ViewState");
- if (null == viewStateField) {
- var element = document.createElement("input");
- _Utils.setAttribute(element, "type", "hidden");
- _Utils.setAttribute(element, "name", "javax.faces.ViewState");
- appliedReplacedFrom.appendChild(element);
-
- _Utils.setAttribute(element, "value", this.appliedViewState);
- }
- }
- }
- };
-
- myfaces._impl.xhrCore._AjaxResponse.prototype.processError = function(request, context, node) {
- /**
- * <error>
- * <error-name>String</error-name>
- * <error-message><![CDATA[message]]></error-message>
- * <error>
- */
- var errorName = node.firstChild.textContent;
- var errorMessage = node.childNodes[1].firstChild.data;
-
- if ('undefined' == typeof errorName || null == errorName) {
- errorName = "";
- }
- if ('undefined' == typeof errorMessage || null == errorMessage) {
- errorMessage = "";
- }
- myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl._ERROR_SERVER_ERROR, errorName, errorMessage);
- };
-
- myfaces._impl.xhrCore._AjaxResponse.prototype.processRedirect = function(request, context, node) {
- /**
- * <redirect url="url to redirect" />
- */
- var redirectUrl = node.getAttribute("url");
- if ('undefined' == typeof redirectUrl || null == redirectUrl) {
- myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl._ERROR_MALFORMEDXML, myfaces._impl.core._jsfImpl._ERROR_MALFORMEDXML, "Redirect without url");
- return false;
- }
- redirectUrl = myfaces._impl._util._LangUtils.trim(redirectUrl);
- if (redirectUrl == "") {
- return false;
- }
- window.location = redirectUrl;
- return true;
- };
-
- myfaces._impl.xhrCore._AjaxResponse.prototype.processChanges = function(request, context, node) {
-
- var _Utils = myfaces._impl._util._Utils;
-
- var changes = node.childNodes;
-
- //note we need to trace the changes which could affect our insert update or delete
- //se that we can realign our ViewStates afterwards
- //the realignment must happen post change processing
-
- for (var i = 0; i < changes.length; i++) {
- if (changes[i].tagName == "update") {
- if (!this.processUpdate(request, context, changes[i])) return false;
- } else if (changes[i].tagName == this._PCMD_EVAL) {
- //eval is always in CDATA blocks
- _Utils.globalEval(changes[i].firstChild.data);
- } else if (changes[i].tagName == this._PCMD_INSERT) {
- if (!this.processInsert(request, context, changes[i])) return false;
- } else if (changes[i].tagName == this._PCMD_DELETE) {
- if (!this.processDelete(request, context, changes[i])) return false;
- } else if (changes[i].tagName == this._PCMD_ATTRIBUTES) {
- if (!this.processAttributes(request, context, changes[i])) return false;
- } else if (changes[i].tagName == this._PCMD_EXTENSION) {
- //DO nothing we do not have any implementation specifics for now!
- //but if you need some implementation specific stuff
- //you have to insert it here
- // this._responseHandler.doExtension(childNode);
- } else {
- myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl._ERROR_MALFORMEDXML);
- return false;
- }
- }
- //second step we step over all updates which have identifiers to check whether there are lost
- // viewStates
-
- return true;
- };
-
- myfaces._impl.xhrCore._AjaxResponse.prototype.processUpdate = function(request, context, node) {
- /*local namespace remapping*/
- var _Utils = myfaces._impl._util._Utils;
-
- if (node.getAttribute('id') == "javax.faces.ViewState") {
- //update the submitting forms viewstate to the new value
- // The source form has to be pulled out of the CURRENT document first because the context object
- // may refer to an invalid document if an update of the entire body has occurred before this point.
- var viewStateValue = node.firstChild.nodeValue;
- var sourceForm = myfaces._impl._util._Utils.fuzzyFormDetection(null, context, context.source);
-
- //the source form could be determined absolutely by either the form, the identifier of the node, or the name
- //if only one element is given
- if (null != sourceForm) {
- /*we check for an element and include a namesearch, but only within the bounds of the committing form*/
- var element = myfaces._impl._util._Utils.getElementFromForm(request, context, "javax.faces.ViewState", sourceForm, true, true);
- if (null == element) {//no element found we have to append a hidden field
- element = document.createElement("input");
- _Utils.setAttribute(element, "type", "hidden");
- _Utils.setAttribute(element, "name", "javax.faces.ViewState");
- sourceForm.appendChild(element);
- }
- //viewstate cannot have split cdata blocks so we can skip the costlier operation
-
- _Utils.setAttribute(element, "value", viewStateValue);
- }
- this.appliedViewState = viewStateValue;
- } else {
- // response may contain several blocks
- var cDataBlock = myfaces._impl._util._Utils.concatCDATABlocks(node);
-
- switch (node.getAttribute('id')) {
- case "javax.faces.ViewRoot":
- this._replaceBody(request, context, cDataBlock);
-
- break;
- case "javax.faces.ViewHead":
- //we cannot replace the head, almost no browser allows this, some of them throw errors
- //others simply ignore it or replace it and destroy the dom that way!
- throw new Error("Head cannot be replaced, due to browser deficiencies!");
-
- break;
- case "javax.faces.ViewBody":
- //we assume the cdata block is our body including the tag
- this._replaceBody(request, context, cDataBlock);
- break;
-
- default:
- var resultNode = this._replaceElement(request, context, node.getAttribute('id'), cDataBlock);
- if ('undefined' != typeof resultNode && null != resultNode) {
- this.changeTrace.push(resultNode);
- }
- break;
- }
- }
- return true;
- };
-
- /**
- * special method to handle the body dom manipulation,
- * replacing the entire body does not work fully by simply adding a second body
- * and by creating a range instead we have to work around that by dom creating a second
- * body and then filling it properly!
- *
- * @param {Object} request our request object
- * @param {Map} context the response context
- * @param {String} newData the markup which replaces the old dom node!
- */
- myfaces._impl.xhrCore._AjaxResponse.prototype._replaceBody = function(request, context, newData) {
-
- var _Utils = myfaces._impl._util._Utils;
-
- var parser = myfaces.ajax._impl = new (myfaces._impl._util._Utils.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();
-
- var oldBody = document.getElementsByTagName("body")[0];
- var newBody = document.createElement("body");
- var placeHolder = document.createElement("div");
- placeHolder.id = "myfaces_bodyplaceholder";
- var bodyParent = oldBody.parentNode;
-
- newBody.appendChild(placeHolder);
-
- //the contextualFragment trick does not work on the body tag instead we have to generate a manual body
- //element and then add a child which then is the replacement holder for our fragment!
-
- //TODO we probably should try to offload this to the browser first via the integrated xml parsing
- //and if it fails revert to our internal parser
- var bodyData = parser.parse(newData, "body");
- bodyParent.replaceChild(newBody, oldBody);
- this._replaceElement(request, context, placeHolder, bodyData);
-
- for (var key in parser.tagAttributes) {
- var value = parser.tagAttributes[key];
- _Utils.setAttribute(newBody, key, value);
- }
- };
-
- /**
- * Helper method to avoid duplicate code
- * @param {Object} request our request object
- * @param {Map} context the response context
- * @param {DomNode} oldElement the element to be replaced
- * @param {String} newData the markup which replaces the old dom node!
- */
- myfaces._impl.xhrCore._AjaxResponse.prototype._replaceElement = function(request, context, oldElement, newData) {
- return myfaces._impl._util._Utils.replaceHtmlItem(request, context,
- oldElement, newData, this.m_htmlFormElement);
- };
-
- /*insert, three attributes can be present
- * id = insert id
- * before = before id
- * after = after id
- *
- * the insert id is the id of the node to be inserted
- * the before is the id if set which the component has to be inserted before
- * the after is the id if set which the component has to be inserted after
- **/
- myfaces._impl.xhrCore._AjaxResponse.prototype.processInsert = function(request, context, node) {
-
- /*remapping global namespaces for speed and readability reasons*/
- var _LangUtils = myfaces._impl._util._LangUtils;
- var _Utils = myfaces._impl._util._Utils;
- var _JSFImpl = myfaces._impl.core._jsfImpl;
-
-
- var insertId = node.getAttribute('id');
- var beforeId = node.getAttribute('before');
- var afterId = node.getAttribute('after');
-
- var insertSet = 'undefined' != typeof insertId && null != insertId && _LangUtils.trim(insertId) != "";
- var beforeSet = 'undefined' != typeof beforeId && null != beforeId && _LangUtils.trim(beforeId) != "";
- var afterSet = 'undefined' != typeof afterId && null != afterId &&_LangUtils.trim(afterId) != "";
-
- if (!insertSet) {
- myfaces.ajax.sendError(request, context, _JSFImpl._ERROR_MALFORMEDXML, _JSFImpl._ERROR_MALFORMEDXML, "Error in PPR Insert, id must be present");
- return false;
- }
- if (!(beforeSet || afterSet)) {
- myfaces.ajax.sendError(request, context, _JSFImpl._ERROR_MALFORMEDXML, _JSFImpl._ERROR_MALFORMEDXML, "Error in PPR Insert, before id or after id must be present");
- return false;
- }
- //either before or after but not two at the same time
- var nodeHolder = null;
- var parentNode = null;
-
- var cDataBlock = _Utils.concatCDATABlocks(node);
-
- if (beforeSet) {
- beforeId =_LangUtils.trim(beforeId);
- var beforeNode = document.getElementById(beforeId);
- if ('undefined' == typeof beforeNode || null == beforeNode) {
- myfaces.ajax.sendError(request, context, _JSFImpl._ERROR_MALFORMEDXML, _JSFImpl._ERROR_MALFORMEDXML, "Error in PPR Insert, before node of id " + beforeId + " does not exist in document");
- return false;
- }
- /**
- *we generate a temp holder
- *so that we can use innerHTML for
- *generating the content upfront
- *before inserting it"
- **/
- nodeHolder = document.createElement("div");
- parentNode = beforeNode.parentNode;
- parentNode.insertBefore(nodeHolder, beforeNode);
-
- var replacementFragment = _Utils.replaceHtmlItem(request, context,
- nodeHolder, cDataBlock, null);
-
- if ('undefined' != typeof replacementFragment && null != replacementFragment) {
- this.changeTrace.push(replacementFragment);
- }
-
- } else {
- afterId =_LangUtils.trim(afterId);
- var afterNode = document.getElementById(afterId);
- if ('undefined' == typeof afterNode || null == afterNode) {
- myfaces.ajax.sendError(request, context, _JSFImpl._ERROR_MALFORMEDXML, _JSFImpl._ERROR_MALFORMEDXML, "Error in PPR Insert, after node of id " + after + " does not exist in document");
- return false;
- }
-
- nodeHolder = document.createElement("div");
- parentNode = afterNode.parentNode;
- parentNode.insertBefore(nodeHolder, afterNode.nextSibling);
-
- var replacementFragment = _Utils.replaceHtmlItem(request, context,
- nodeHolder, cDataBlock, null);
-
- if ('undefined' != typeof replacementFragment && null != replacementFragment) {
- this.changeTrace.push(replacementFragment);
- }
-
- }
- return true;
- };
-
- myfaces._impl.xhrCore._AjaxResponse.prototype.processDelete = function(request, context, node) {
- var _JSFImpl = myfaces._impl.core._jsfImpl;
-
- var deleteId = node.getAttribute('id');
- if ('undefined' == typeof deleteId || null == deleteId) {
- myfaces.ajax.sendError(request, context, _JSFImpl._ERROR_MALFORMEDXML,
- _JSFImpl._ERROR_MALFORMEDXML, "Error in delete, id not in xml markup");
- return false;
- }
-
- myfaces._impl._util._Utils.deleteItem(request, context, deleteId, "", "");
- return true;
- };
-
- myfaces._impl.xhrCore._AjaxResponse.prototype.processAttributes = function(request, context, node) {
- //we now route into our attributes function to bypass
- //IE quirks mode incompatibilities to the biggest possible extent
- //most browsers just have to do a setAttributes but IE
- //behaves as usual not like the official standard
- //myfaces._impl._util._Utils.setAttribute(domNode, attribute, value;
-
- var _Utils = myfaces._impl._util._Utils;
- var _JSFImpl = myfaces._impl.core._jsfImpl;
-
- //<attributes id="id of element"> <attribute name="attribute name" value="attribute value" />* </attributes>
- var attributesRoot = node;
- var elementId = attributesRoot.getAttribute('id');
- if ('undefined' == typeof elementId || null == elementId) {
- myfaces.ajax.sendError(request, context, _JSFImpl._ERROR_MALFORMEDXML
- , _JSFImpl._ERROR_MALFORMEDXML, "Error in attributes, id not in xml markup");
- return false;
- }
- var childs = attributesRoot.childNodes;
-
- if ('undefined' == typeof childs || null == childs) {
- return false;
- }
- for (var loop2 = 0; loop2 < childs.length; loop2++) {
- var attributesNode = childs[loop2];
-
- var attributeName = attributesNode.getAttribute("name");
- var attributeValue = attributesNode.getAttribute("value");
-
- if ('undefined' == typeof attributeName || null == attributeName) {
- continue;
- }
-
- attributeName = myfaces._impl._util._LangUtils.trim(attributeName);
- /*no value means reset*/
- if ('undefined' == typeof attributeValue || null == attributeValue) {
- attributeValue = "";
- }
-
- switch (elementId) {
- case "javax.faces.ViewRoot":
- throw new Error("Changing of viewRoot attributes is not supported");
- break;
-
- case "javax.faces.ViewHead":
- throw new Error("Changing of head attributes is not supported");
- break;
-
- case "javax.faces.ViewBody":
- var element = document.getElementsByTagName("body")[0];
- _Utils.setAttribute(element, attributeName, attributeValue);
- break;
-
- default:
- _Utils.setAttribute(document.getElementById(elementId), attributeName, attributeValue);
- break;
- }
-
- }
- return true;
- };
-
-}
+/*
+ * Copyright 2009 Ganesh Jung
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Ganesh Jung (latest modification by $Author: ganeshpuri $)
+ * Version: $Revision: 1.2 $ $Date: 2009/05/30 17:54:57 $
+ *
+ */
+
+myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._AjaxResponse",Object, {
+
+
+ /**
+ * Constructor
+ * @param {String} alarmThreshold
+ */
+ constructor_: function(alarmThreshold) {
+ this.alarmThreshold = alarmThreshold;
+ this.m_exception = new myfaces._impl.xhrCore._Exception("myfaces._impl.xhrCore._AjaxResponse", this.alarmThreshold);
+ //change tracer for post changes operations
+ this.changeTrace = [];
+ this.appliedViewState = null;
+ },
+
+ /*partial response types*/
+ _RESPONSE_PARTIAL : "partial-response",
+ _RESPONSETYPE_ERROR : "error",
+ /*TODO: -=Leonardo Uribe=- Does this response type really exists? really from server comes a partial-response with redirect command*/
+ /*This really exists, it is for cases where a button issues a command and the server wants to redirect after processing the ajax request*/
+ _RESPONSETYPE_REDIRECT : "redirect",
+ _RESPONSETYPE_CHANGES : "changes",
+
+ /*partial commands*/
+ _PCMD_CHANGES : "changes",
+ _PCMD_UPDATE : "update",
+ _PCMD_DELETE : "delete",
+ _PCMD_INSERT : "insert",
+ _PCMD_EVAL : "eval",
+ _PCMD_ERROR : "error",
+ _PCMD_ATTRIBUTES : "attributes",
+ _PCMD_EXTENSION : "extension",
+ _PCMD_REDIRECT : "redirect",
+ /**
+ * uses response to start Html element replacement
+ *
+ * @param {Object} request (xhrRequest) - xhr request object
+ * @param {Ojbect} context (Map) - AJAX context
+ *
+ * A special handling has to be added to the update cycle
+ * according to the JSDoc specs if the CDATA block contains html tags the outer rim must be stripped
+ * if the CDATA block contains a head section the document head must be replaced
+ * and if the CDATA block contains a body section the document body must be replaced!
+ *
+ */
+ processResponse : function(request, context) {
+ try {
+ var _Lang = myfaces._impl._util._Lang;
+ // TODO:
+ // Solution from
+ // http://www.codingforums.com/archive/index.php/t-47018.html
+ // to solve IE error 1072896658 when a Java server sends iso88591
+ // istead of ISO-8859-1
+ if ('undefined' == typeof(request) || null == request) {
+ throw Exception("jsf.ajaxResponse: The response cannot be null or empty!");
+ }
+
+ if (!_Lang.exists(request, "responseXML")) {
+ myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl.prototype._ERROR_EMPTY_RESPONSE);
+ return;
+ }
+
+ var xmlContent = request.responseXML;
+ //ie6+ keeps the parsing response under xmlContent.parserError
+ //while the rest of the world keeps it as element under the first node
+ var parseError
+
+
+ if ((_Lang.exists(xmlContent,"parseError.errorCode") && xmlContent.parseError.errorCode != 0) || _Lang.equalsIgnoreCase(xmlContent.firstChild.tagName, "parsererror")) {
+ //TODO improve error name and message sending here
+
+ myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl.prototype._ERROR_MALFORMEDXML);
+ return;
+ }
+ var partials = xmlContent.childNodes[0];
+ if ('undefined' == typeof partials || partials == null) {
+ myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl.prototype._ERROR_MALFORMEDXML);
+ return;
+ } else {
+ if (partials.tagName != this._RESPONSE_PARTIAL) {
+ // IE 8 sees XML Header as first sibling ...
+ partials = partials.nextSibling;
+ if ('undefined' == typeof partials || partials == null || partials.tagName != this._RESPONSE_PARTIAL) {
+ myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl.prototype._ERROR_MALFORMEDXML);
+ return;
+ }
+ }
+ }
+
+ var childNodesLength = partials.childNodes.length;
+
+ for (var loop = 0; loop < childNodesLength; loop++) {
+ var childNode = partials.childNodes[loop];
+ var tagName = childNode.tagName;
+
+ /**
+ * <eval>
+ * <![CDATA[javascript]]>
+ * </eval>
+ */
+
+ //this ought to be enough for eval
+ //however the run scripts still makes sense
+ //in the update and insert area for components
+ //which do not use the response writer properly
+ //we might add this one as custom option in update and
+ //insert!
+ if (tagName == this._PCMD_ERROR) {
+ this.processError(request, context, childNode);
+ return;
+ } else if (tagName == this._PCMD_REDIRECT) {
+ if (!this.processRedirect(request, context, childNode)) return;
+ } else if (tagName == this._PCMD_CHANGES) {
+ if (!this.processChanges(request, context, childNode)) return;
+ }
+ }
+
+ //fixup missing viewStates due to spec deficiencies
+ this.fixViewStates();
+ } catch (e) {
+ this.m_exception.throwError(request, context, "processResponse", e);
+ }
+ },
+
+ fixViewStates : function() {
+ if(null == this.appliedViewState) {
+ return;
+ }
+ /*namespace remapping*/
+ var _Dom = myfaces._impl._util._Dom;
+
+ //note the spec here says clearly it is done, but mojarra not and there is a corner case
+ //regarding cross form submits, hence we should check all processed items for embedded forms
+ for (var cnt = 0; cnt < this.changeTrace.length; cnt ++) {
+ var replacementElem = this.changeTrace[cnt];
+ var replacedForms = myfaces._impl._util._Dom.findByTagName(replacementElem, "form", false);
+ for (var formCnt = 0; formCnt < replacedForms.length; formCnt++) {
+ //we first have to fetch the real form element because the fragment
+ //might be detached in some browser implementations
+ var appliedReplacedFrom = document.getElementById(replacedForms[formCnt].id);
+ var viewStateField = myfaces._impl._util._Dom.findFormElement(appliedReplacedFrom, "javax.faces.ViewState");
+ if (null == viewStateField) {
+ var element = document.createElement("input");
+ _Dom.setAttribute(element, "type", "hidden");
+ _Dom.setAttribute(element, "name", "javax.faces.ViewState");
+ appliedReplacedFrom.appendChild(element);
+
+ _Dom.setAttribute(element, "value", this.appliedViewState);
+ }
+ }
+ }
+ },
+
+ processError : function(request, context, node) {
+ /**
+ * <error>
+ * <error-name>String</error-name>
+ * <error-message><![CDATA[message]]></error-message>
+ * <error>
+ */
+ var errorName = node.firstChild.textContent;
+ var errorMessage = node.childNodes[1].firstChild.data;
+
+ if ('undefined' == typeof errorName || null == errorName) {
+ errorName = "";
+ }
+ if ('undefined' == typeof errorMessage || null == errorMessage) {
+ errorMessage = "";
+ }
+ myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl.prototype._ERROR_SERVER_ERROR, errorName, errorMessage);
+ },
+
+ processRedirect : function(request, context, node) {
+ /**
+ * <redirect url="url to redirect" />
+ */
+ var redirectUrl = node.getAttribute("url");
+ if ('undefined' == typeof redirectUrl || null == redirectUrl) {
+ myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl.prototype._ERROR_MALFORMEDXML, myfaces._impl.core._jsfImpl._ERROR_MALFORMEDXML, "Redirect without url");
+ return false;
+ }
+ redirectUrl = myfaces._impl._util._Lang.trim(redirectUrl);
+ if (redirectUrl == "") {
+ return false;
+ }
+ window.location = redirectUrl;
+ return true;
+ },
+
+ /**
+ * main entry point for processing the changes
+ * it deals with the <changes> node of the
+ * response
+ *
+ * @param request the xhr request object
+ * @param context the context map
+ * @param node the changes node to be processed
+ */
+ processChanges : function(request, context, node) {
+
+ var _Lang = myfaces._impl._util._Lang;
+
+ var changes = node.childNodes;
+
+ //note we need to trace the changes which could affect our insert update or delete
+ //se that we can realign our ViewStates afterwards
+ //the realignment must happen post change processing
+
+ for (var i = 0; i < changes.length; i++) {
+ if (changes[i].tagName == "update") {
+ if (!this.processUpdate(request, context, changes[i])) return false;
+ } else if (changes[i].tagName == this._PCMD_EVAL) {
+ //eval is always in CDATA blocks
+ _Lang.globalEval(changes[i].firstChild.data);
+ } else if (changes[i].tagName == this._PCMD_INSERT) {
+ if (!this.processInsert(request, context, changes[i])) return false;
+ } else if (changes[i].tagName == this._PCMD_DELETE) {
+ if (!this.processDelete(request, context, changes[i])) return false;
+ } else if (changes[i].tagName == this._PCMD_ATTRIBUTES) {
+ if (!this.processAttributes(request, context, changes[i])) return false;
+ } else if (changes[i].tagName == this._PCMD_EXTENSION) {
+ //DO nothing we do not have any implementation specifics for now!
+ //but if you need some implementation specific stuff
+ //you have to insert it here
+ // this._responseHandler.doExtension(childNode);
+ } else {
+ myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl.prototype._ERROR_MALFORMEDXML);
+ return false;
+ }
+ }
+ //second step we step over all updates which have identifiers to check whether there are lost
+ // viewStates
+
+ return true;
+ },
+
+ processUpdate : function(request, context, node) {
+ /*local namespace remapping*/
+ var _Dom = myfaces._impl._util._Dom;
+
+ if (node.getAttribute('id') == "javax.faces.ViewState") {
+ //update the submitting forms viewstate to the new value
+ // The source form has to be pulled out of the CURRENT document first because the context object
+ // may refer to an invalid document if an update of the entire body has occurred before this point.
+ var viewStateValue = node.firstChild.nodeValue;
+ var sourceForm = myfaces._impl._util._Dom.fuzzyFormDetection(context.source);
+
+ //the source form could be determined absolutely by either the form, the identifier of the node, or the name
+ //if only one element is given
+ if (null != sourceForm) {
+ /*we check for an element and include a namesearch, but only within the bounds of the committing form*/
+ var element = _Dom.getElementFromForm(request, context, "javax.faces.ViewState", sourceForm, true, true);
+ if (null == element) {//no element found we have to append a hidden field
+ element = document.createElement("input");
+ _Dom.setAttribute(element, "type", "hidden");
+ _Dom.setAttribute(element, "name", "javax.faces.ViewState");
+ sourceForm.appendChild(element);
+ }
+ //viewstate cannot have split cdata blocks so we can skip the costlier operation
+
+ _Dom.setAttribute(element, "value", viewStateValue);
+ }
+ this.appliedViewState = viewStateValue;
+ } else {
+ // response may contain several blocks
+ var cDataBlock = myfaces._impl._util._Dom.concatCDATABlocks(node);
+
+ switch (node.getAttribute('id')) {
+ case "javax.faces.ViewRoot":
+ this._replaceBody(request, context, cDataBlock);
+
+ break;
+ case "javax.faces.ViewHead":
+ //we cannot replace the head, almost no browser allows this, some of them throw errors
+ //others simply ignore it or replace it and destroy the dom that way!
+ throw new Error("Head cannot be replaced, due to browser deficiencies!");
+
+ break;
+ case "javax.faces.ViewBody":
+ //we assume the cdata block is our body including the tag
+ this._replaceBody(request, context, cDataBlock);
+ break;
+
+ default:
+ var resultNode = this._replaceElement(request, context, node.getAttribute('id'), cDataBlock);
+ if ('undefined' != typeof resultNode && null != resultNode) {
+ this.changeTrace.push(resultNode);
+ }
+ break;
+ }
+ }
+ return true;
+ },
+
+ /**
+ * special method to handle the body dom manipulation,
+ * replacing the entire body does not work fully by simply adding a second body
+ * and by creating a range instead we have to work around that by dom creating a second
+ * body and then filling it properly!
+ *
+ * @param {Object} request our request object
+ * @param {Object} context (Map) the response context
+ * @param {String} newData the markup which replaces the old dom node!
+ */
+ _replaceBody : function(request, context, newData) {
+
+ var _Dom = myfaces._impl._util._Dom;
+
+ var parser = myfaces.ajax._impl = new (myfaces._impl.core._Runtime.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();
+
+ var oldBody = document.getElementsByTagName("body")[0];
+ var newBody = document.createElement("body");
+ var placeHolder = document.createElement("div");
+ placeHolder.id = "myfaces_bodyplaceholder";
+ var bodyParent = oldBody.parentNode;
+
+ newBody.appendChild(placeHolder);
+
+ //the contextualFragment trick does not work on the body tag instead we have to generate a manual body
+ //element and then add a child which then is the replacement holder for our fragment!
+
+ //TODO we probably should try to offload this to the browser first via the integrated xml parsing
+ //and if it fails revert to our internal parser
+ var bodyData = parser.parse(newData, "body");
+ bodyParent.replaceChild(newBody, oldBody);
+ this._replaceElement(request, context, placeHolder, bodyData);
+
+ for (var key in parser.tagAttributes) {
+ var value = parser.tagAttributes[key];
+ _Dom.setAttribute(newBody, key, value);
+ }
+ },
+
+ /**
+ * Helper method to avoid duplicate code
+ * @param {Object} request our request object
+ * @param {Object} context (Map) the response context
+ * @param {Node} oldElement the element to be replaced
+ * @param {String} newData the markup which replaces the old dom node!
+ */
+ _replaceElement : function(request, context, oldElement, newData) {
+ return this.replaceHtmlItem(request, context,
+ oldElement, newData, this.m_htmlFormElement);
+ },
+
+
+ /**
+ * Replaces HTML elements through others and handle errors if the occur in the replacement part
+ *
+ * @param {Object} request (xhrRequest)
+ * @param {Object} context (Map)
+ * @param {Object} itemIdToReplace (String|Node) - ID of the element to replace
+ * @param {String} markup - the new tag
+ * @param {Node} form - form element that is parent of the element
+ */
+ replaceHtmlItem : function(request, context, itemIdToReplace, markup, form) {
+ try {
+
+ // (itemIdToReplace instanceof Node) is NOT compatible with IE8
+ var item = (typeof itemIdToReplace == "object") ? itemIdToReplace :
+ myfaces._impl._util._Dom.getElementFromForm(request, context, itemIdToReplace, form);
+ if('undefined' == typeof item || null == item) {
+ throw Error("myfaces._impl.xhrCore._AjaxResponse.prototype.replaceHtmlItem: item could not be found");
+ }
+ return myfaces._impl._util._Dom.outerHTML(item, markup);
+
+ } catch (e) {
+ myfaces._impl._util._Lang.throwNewError(request, context, "Utils", "replaceHTMLItem", e);
+ }
+ return null;
+ },
+
+ /*insert, three attributes can be present
+ * id = insert id
+ * before = before id
+ * after = after id
+ *
+ * the insert id is the id of the node to be inserted
+ * the before is the id if set which the component has to be inserted before
+ * the after is the id if set which the component has to be inserted after
+ **/
+ processInsert : function(request, context, node) {
+
+ /*remapping global namespaces for speed and readability reasons*/
+ var _Lang = myfaces._impl._util._Lang;
+ var _Dom = myfaces._impl._util._Dom;
+ var _JSFImpl = myfaces._impl.core._jsfImpl;
+
+
+ var insertId = node.getAttribute('id');
+ var beforeId = node.getAttribute('before');
+ var afterId = node.getAttribute('after');
+
+ var insertSet = 'undefined' != typeof insertId && null != insertId && _Lang.trim(insertId) != "";
+ var beforeSet = 'undefined' != typeof beforeId && null != beforeId && _Lang.trim(beforeId) != "";
+ var afterSet = 'undefined' != typeof afterId && null != afterId &&_Lang.trim(afterId) != "";
+
+ if (!insertSet) {
+ myfaces.ajax.sendError(request, context, _JSFImpl.prototype._ERROR_MALFORMEDXML, _JSFImpl.prototype._ERROR_MALFORMEDXML, "Error in PPR Insert, id must be present");
+ return false;
+ }
+ if (!(beforeSet || afterSet)) {
+ myfaces.ajax.sendError(request, context, _JSFImpl.prototype._ERROR_MALFORMEDXML, _JSFImpl.prototype._ERROR_MALFORMEDXML, "Error in PPR Insert, before id or after id must be present");
+ return false;
+ }
+ //either before or after but not two at the same time
+ var nodeHolder = null;
+ var parentNode = null;
+
+ var cDataBlock = _Dom.concatCDATABlocks(node);
+ var replacementFragment;
+ if (beforeSet) {
+ beforeId =_Lang.trim(beforeId);
+ var beforeNode = document.getElementById(beforeId);
+ if ('undefined' == typeof beforeNode || null == beforeNode) {
+ myfaces.ajax.sendError(request, context, _JSFImpl.prototype._ERROR_MALFORMEDXML, _JSFImpl.prototype._ERROR_MALFORMEDXML, "Error in PPR Insert, before node of id " + beforeId + " does not exist in document");
+ return false;
+ }
+ /**
+ *we generate a temp holder
+ *so that we can use innerHTML for
+ *generating the content upfront
+ *before inserting it"
+ **/
+ nodeHolder = document.createElement("div");
+ parentNode = beforeNode.parentNode;
+ parentNode.insertBefore(nodeHolder, beforeNode);
+
+ replacementFragment = this.replaceHtmlItem(request, context,
+ nodeHolder, cDataBlock, null);
+
+ if ('undefined' != typeof replacementFragment && null != replacementFragment) {
+ this.changeTrace.push(replacementFragment);
+ }
+
+ } else {
+ afterId =_Lang.trim(afterId);
+ var afterNode = document.getElementById(afterId);
+ if ('undefined' == typeof afterNode || null == afterNode) {
+ myfaces.ajax.sendError(request, context, _JSFImpl.prototype._ERROR_MALFORMEDXML, _JSFImpl.prototype._ERROR_MALFORMEDXML, "Error in PPR Insert, after node of id " + after + " does not exist in document");
+ return false;
+ }
+
+ nodeHolder = document.createElement("div");
+ parentNode = afterNode.parentNode;
+ parentNode.insertBefore(nodeHolder, afterNode.nextSibling);
+
+ replacementFragment = this.replaceHtmlItem(request, context,
+ nodeHolder, cDataBlock, null);
+
+ if ('undefined' != typeof replacementFragment && null != replacementFragment) {
+ this.changeTrace.push(replacementFragment);
+ }
+
+ }
+ return true;
+ },
+
+ processDelete : function(request, context, node) {
+ var _JSFImpl = myfaces._impl.core._jsfImpl;
+ var _Dom = myfaces._impl._util._Dom;
+
+ var deleteId = node.getAttribute('id');
+ if ('undefined' == typeof deleteId || null == deleteId) {
+ myfaces.ajax.sendError(request, context, _JSFImpl.prototype._ERROR_MALFORMEDXML,
+ _JSFImpl.prototype._ERROR_MALFORMEDXML, "Error in delete, id not in xml markup");
+ return false;
+ }
+
+ _Dom.deleteItem(request, context, deleteId, "", "");
+ return true;
+ },
+
+ processAttributes : function(request, context, node) {
+ //we now route into our attributes function to bypass
+ //IE quirks mode incompatibilities to the biggest possible extent
+ //most browsers just have to do a setAttributes but IE
+ //behaves as usual not like the official standard
+ //myfaces._impl._util._Dom.setAttribute(domNode, attribute, value;
+
+ var _Dom = myfaces._impl._util._Dom;
+ var _JSFImpl = myfaces._impl.core._jsfImpl;
+
+ //<attributes id="id of element"> <attribute name="attribute name" value="attribute value" />* </attributes>
+ var elementId = node.getAttribute('id');
+ if ('undefined' == typeof elementId || null == elementId) {
+ myfaces.ajax.sendError(request, context, _JSFImpl.prototype._ERROR_MALFORMEDXML
+ , _JSFImpl.prototype._ERROR_MALFORMEDXML, "Error in attributes, id not in xml markup");
+ return false;
+ }
+ var childNodes = node.childNodes;
+
+ if ('undefined' == typeof childNodes || null == childNodes) {
+ return false;
+ }
+ for (var loop2 = 0; loop2 < childNodes.length; loop2++) {
+ var attributesNode = childNodes[loop2];
+
+ var attributeName = attributesNode.getAttribute("name");
+ var attributeValue = attributesNode.getAttribute("value");
+
+ if ('undefined' == typeof attributeName || null == attributeName) {
+ continue;
+ }
+
+ attributeName = myfaces._impl._util._Lang.trim(attributeName);
+ /*no value means reset*/
+ if ('undefined' == typeof attributeValue || null == attributeValue) {
+ attributeValue = "";
+ }
+
+ switch (elementId) {
+ case "javax.faces.ViewRoot":
+ throw new Error("Changing of viewRoot attributes is not supported");
+ break;
+
+ case "javax.faces.ViewHead":
+ throw new Error("Changing of head attributes is not supported");
+ break;
+
+ case "javax.faces.ViewBody":
+ var element = document.getElementsByTagName("body")[0];
+ _Dom.setAttribute(element, attributeName, attributeValue);
+ break;
+
+ default:
+ _Dom.setAttribute(document.getElementById(elementId), attributeName, attributeValue);
+ break;
+ }
+
+ }
+ return true;
+ }
+
+});
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxUtils.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxUtils.js?rev=944200&r1=944199&r2=944200&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxUtils.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxUtils.js Fri May 14 10:54:32 2010
@@ -1,183 +1,178 @@
-/*
- * Copyright 2009 Ganesh Jung
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Ganesh Jung (latest modification by $Author: ganeshpuri $)
- * Version: $Revision: 1.1 $ $Date: 2009/05/26 21:24:42 $
- *
- */
-
-_reserveMyfacesNamespaces();
-
-if (!myfaces._impl._util._LangUtils.exists(myfaces._impl.xhrCore, "_AjaxUtils")) {
-
- /**
- * Constructor
- * @param {String} alarmThreshold - Error Level
- */
- myfaces._impl.xhrCore._AjaxUtils = function(alarmThreshold) {
- // Exception Objekt
- this.alarmThreshold = alarmThreshold;
- this.m_exception = new myfaces._impl.xhrCore._Exception("myfaces._impl.xhrCore._AjaxUtils", this.alarmThreshold);
- };
-
- /**
- * determines fields to submit
- * @param {Object} request the xhr request object
- * @param {Map} context
- * @param {HtmlElement} item - item that triggered the event
- * @param {HtmlElement} parentItem - form element item is nested in
- * @param {Array} partialIds - ids fo PPS
- */
- myfaces._impl.xhrCore._AjaxUtils.prototype.processUserEntries = function(request, context, item,
- parentItem, partialIds) {
- try {
- var form = parentItem;
-
- if (form == null) {
- this.m_exception.throwWarning(request, context, "processUserEntries",
- "Html-Component is not nested in a Form-Tag");
- return null;
- }
-
- var stringBuffer = new Array();
-
- if (partialIds != null && partialIds.length > 0) {
- // recursivly check items
- this.addNodes(form, false, partialIds, stringBuffer);
- } else {
- // add all nodes
- var eLen = form.elements.length;
- for ( var e = 0; e < eLen; e++) {
- this.addField(form.elements[e], stringBuffer);
- } // end of for (formElements)
- }
-
- // if triggered by a Button send it along
- if ('undefined' != typeof item && null != item && item.type != null && item.type.toLowerCase() == "submit") {
- stringBuffer[stringBuffer.length] = encodeURIComponent(item.name);
- stringBuffer[stringBuffer.length] = "=";
- stringBuffer[stringBuffer.length] = encodeURIComponent(item.value);
- stringBuffer[stringBuffer.length] = "&";
- }
-
- return stringBuffer.join("");
- } catch (e) {
- this.m_exception.throwError(request, context, "processUserEntries", e);
- }
- };
-
- /**
- * checks recursively if contained in PPS
- * @param {} node -
- * @param {} insideSubmittedPart -
- * @param {} partialIds -
- * @param {} stringBuffer -
- */
- myfaces._impl.xhrCore._AjaxUtils.prototype.addNodes = function(node, insideSubmittedPart,
- partialIds, stringBuffer) {
- if (node != null && node.childNodes != null) {
- var nLen = node.childNodes.length;
- for ( var i = 0; i < nLen; i++) {
- var child = node.childNodes[i];
- var id = child.id;
- var elementName = child.name;
- if (child.nodeType == 1) {
- var isPartialSubmitContainer = ((id != null)
- && myfaces._impl._util._LangUtils.arrayContains(partialIds, id));
- if (insideSubmittedPart
- || isPartialSubmitContainer
- || (elementName != null
- && elementName == myfaces._impl.core._jsfImpl._PROP_VIEWSTATE)) {
- // node required for PPS
- this.addField(child, stringBuffer);
- if (insideSubmittedPart || isPartialSubmitContainer) {
- // check for further children
- this.addNodes(child, true, partialIds, stringBuffer);
- }
- } else {
- // check for further children
- this.addNodes(child, false, partialIds, stringBuffer);
- }
- }
- }
- }
- }
-
- /**
- * add a single field to stringbuffer for param submission
- * @param {HtmlElement} element -
- * @param {} stringBuffer -
- */
- myfaces._impl.xhrCore._AjaxUtils.prototype.addField = function(element, stringBuffer) {
- var elementName = element.name;
- var elementTagName = element.tagName.toLowerCase();
- var elementType = element.type;
- if (elementType != null) {
- elementType = elementType.toLowerCase();
- }
-
- // routine for all elements
- // rules:
- // - process only inputs, textareas and selects
- // - elements muest have attribute "name"
- // - elements must not be disabled
- if (((elementTagName == "input" || elementTagName == "textarea" || elementTagName == "select") &&
- (elementName != null && elementName != "")) && element.disabled == false) {
-
- // routine for select elements
- // rules:
- // - if select-one and value-Attribute exist => "name=value"
- // (also if value empty => "name=")
- // - if select-one and value-Attribute don't exist =>
- // "name=DisplayValue"
- // - if select multi and multple selected => "name=value1&name=value2"
- // - if select and selectedIndex=-1 don't submit
- if (elementTagName == "select") {
- // selectedIndex must be >= 0 sein to be submittet
- if (element.selectedIndex >= 0) {
- var uLen = element.options.length;
- for ( var u = 0; u < uLen; u++) {
- // find all selected options
- if (element.options[u].selected == true) {
- var elementOption = element.options[u];
- stringBuffer[stringBuffer.length] = encodeURIComponent(elementName);
- stringBuffer[stringBuffer.length] = "=";
- if (elementOption.getAttribute("value") != null) {
- stringBuffer[stringBuffer.length] = encodeURIComponent(elementOption.value);
- } else {
- stringBuffer[stringBuffer.length] = encodeURIComponent(elementOption.text);
- }
- stringBuffer[stringBuffer.length] = "&";
- }
- }
- }
- }
-
- // routine for remaining elements
- // rules:
- // - don't submit no selects (processed above), buttons, reset buttons, submit buttons,
- // - submit checkboxes and radio inputs only if checked
- if ((elementTagName != "select" && elementType != "button"
- && elementType != "reset" && elementType != "submit" && elementType != "image")
- && ((elementType != "checkbox" && elementType != "radio") || element.checked)) {
- stringBuffer[stringBuffer.length] = encodeURIComponent(elementName);
- stringBuffer[stringBuffer.length] = "=";
- stringBuffer[stringBuffer.length] = encodeURIComponent(element.value);
- stringBuffer[stringBuffer.length] = "&";
- }
-
- }
- }
-}
\ No newline at end of file
+/*
+ * Copyright 2009 Ganesh Jung
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Ganesh Jung (latest modification by $Author: ganeshpuri $)
+ * Version: $Revision: 1.1 $ $Date: 2009/05/26 21:24:42 $
+ *
+ */
+
+myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._AjaxUtils", Object, {
+ /**
+ * Constructor
+ * @param {String} alarmThreshold - Error Level
+ */
+ constructor_ : function(alarmThreshold) {
+ // Exception Objekt
+ this.alarmThreshold = alarmThreshold;
+ this.m_exception = new myfaces._impl.xhrCore._Exception("myfaces._impl.xhrCore._AjaxUtils", this.alarmThreshold);
+ },
+
+ /**
+ * determines fields to submit
+ * @param {Object} request the xhr request object
+ * @param {Object} context (Map)
+ * @param {Node} item - item that triggered the event
+ * @param {Node} parentItem - form element item is nested in
+ * @param {Array} partialIds - ids fo PPS
+ */
+ processUserEntries : function(request, context, item,
+ parentItem, partialIds) {
+ try {
+ if (parentItem == null) {
+ this.m_exception.throwWarning(request, context, "processUserEntries",
+ "Html-Component is not nested in a Form-Tag");
+ return null;
+ }
+
+ var stringBuffer = new Array();
+
+ if (partialIds != null && partialIds.length > 0) {
+ // recursivly check items
+ this.addNodes(parentItem, false, partialIds, stringBuffer);
+ } else {
+ // add all nodes
+ var eLen = parentItem.elements.length;
+ for (var e = 0; e < eLen; e++) {
+ this.addField(parentItem.elements[e], stringBuffer);
+ } // end of for (formElements)
+ }
+
+ // if triggered by a Button send it along
+ if ('undefined' != typeof item && null != item && item.type != null && item.type.toLowerCase() == "submit") {
+ stringBuffer[stringBuffer.length] = encodeURIComponent(item.name);
+ stringBuffer[stringBuffer.length] = "=";
+ stringBuffer[stringBuffer.length] = encodeURIComponent(item.value);
+ stringBuffer[stringBuffer.length] = "&";
+ }
+
+ return stringBuffer.join("");
+ } catch (e) {
+ this.m_exception.throwError(request, context, "processUserEntries", e);
+ }
+ },
+
+ /**
+ * checks recursively if contained in PPS
+ * @param {} node -
+ * @param {} insideSubmittedPart -
+ * @param {} partialIds -
+ * @param {} stringBuffer -
+ */
+ addNodes : function(node, insideSubmittedPart,
+ partialIds, stringBuffer) {
+ if (node != null && node.childNodes != null) {
+ var nLen = node.childNodes.length;
+ for (var i = 0; i < nLen; i++) {
+ var child = node.childNodes[i];
+ var id = child.id;
+ var elementName = child.name;
+ if (child.nodeType == 1) {
+ var isPartialSubmitContainer = ((id != null)
+ && myfaces._impl._util._Lang.arrayContains(partialIds, id));
+ if (insideSubmittedPart
+ || isPartialSubmitContainer
+ || (elementName != null
+ && elementName == myfaces._impl.core._jsfImpl.prototype._PROP_VIEWSTATE)) {
+ // node required for PPS
+ this.addField(child, stringBuffer);
+ if (insideSubmittedPart || isPartialSubmitContainer) {
+ // check for further children
+ this.addNodes(child, true, partialIds, stringBuffer);
+ }
+ } else {
+ // check for further children
+ this.addNodes(child, false, partialIds, stringBuffer);
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * add a single field to stringbuffer for param submission
+ * @param {Node} element -
+ * @param {} stringBuffer -
+ */
+ addField : function(element, stringBuffer) {
+ var elementName = element.name;
+ var elementTagName = element.tagName.toLowerCase();
+ var elementType = element.type;
+ if (elementType != null) {
+ elementType = elementType.toLowerCase();
+ }
+
+ // routine for all elements
+ // rules:
+ // - process only inputs, textareas and selects
+ // - elements muest have attribute "name"
+ // - elements must not be disabled
+ if (((elementTagName == "input" || elementTagName == "textarea" || elementTagName == "select") &&
+ (elementName != null && elementName != "")) && !element.disabled) {
+
+ // routine for select elements
+ // rules:
+ // - if select-one and value-Attribute exist => "name=value"
+ // (also if value empty => "name=")
+ // - if select-one and value-Attribute don't exist =>
+ // "name=DisplayValue"
+ // - if select multi and multple selected => "name=value1&name=value2"
+ // - if select and selectedIndex=-1 don't submit
+ if (elementTagName == "select") {
+ // selectedIndex must be >= 0 sein to be submittet
+ if (element.selectedIndex >= 0) {
+ var uLen = element.options.length;
+ for (var u = 0; u < uLen; u++) {
+ // find all selected options
+ if (element.options[u].selected) {
+ var elementOption = element.options[u];
+ stringBuffer[stringBuffer.length] = encodeURIComponent(elementName);
+ stringBuffer[stringBuffer.length] = "=";
+ if (elementOption.getAttribute("value") != null) {
+ stringBuffer[stringBuffer.length] = encodeURIComponent(elementOption.value);
+ } else {
+ stringBuffer[stringBuffer.length] = encodeURIComponent(elementOption.text);
+ }
+ stringBuffer[stringBuffer.length] = "&";
+ }
+ }
+ }
+ }
+
+ // routine for remaining elements
+ // rules:
+ // - don't submit no selects (processed above), buttons, reset buttons, submit buttons,
+ // - submit checkboxes and radio inputs only if checked
+ if ((elementTagName != "select" && elementType != "button"
+ && elementType != "reset" && elementType != "submit" && elementType != "image")
+ && ((elementType != "checkbox" && elementType != "radio") || element.checked)) {
+ stringBuffer[stringBuffer.length] = encodeURIComponent(elementName);
+ stringBuffer[stringBuffer.length] = "=";
+ stringBuffer[stringBuffer.length] = encodeURIComponent(element.value);
+ stringBuffer[stringBuffer.length] = "&";
+ }
+
+ }
+ }
+});
\ No newline at end of file
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_Exception.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_Exception.js?rev=944200&r1=944199&r2=944200&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_Exception.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_Exception.js Fri May 14 10:54:32 2010
@@ -1,94 +1,71 @@
-/*
- * Copyright 2009 Ganesh Jung
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Ganesh Jung (latest modification by $Author: ganeshpuri $)
- * Version: $Revision: 1.2 $ $Date: 2009/05/30 17:54:57 $
- *
- */
-
-_reserveMyfacesNamespaces();
-
-
-if (!myfaces._impl._util._LangUtils.exists(myfaces._impl.xhrCore, "_Exception")) {
-
-
- myfaces._impl.xhrCore._Exception = function(sourceClass, threshold) {
- this.m_class = sourceClass
- this.m_threshold = threshold
- };
-
- /**
- * [STATIC]
- * static method used by static methods that throw errors
- */
- myfaces._impl.xhrCore._Exception.throwNewError = function(request, context, sourceClass, func, exception) {
- var newException = new myfaces._impl.xhrCore._Exception(request, context, sourceClass, "ERROR");
- newException.throwError(request, context, func, exception);
- };
-
- /**
- * [STATIC]
- * static method used by static methods that throw warnings
- */
- myfaces._impl.xhrCore._Exception.throwNewWarning = function(request, context, sourceClass, func, message){
- var newException = new myfaces._impl.xhrCore._Exception(request, context, sourceClass, "WARNING");
- newException.throwWarning(request, context, func, message);
- };
-
- /**
- * throws errors
- */
- myfaces._impl.xhrCore._Exception.prototype.throwError = function(request, context, func, exception) {
- if (this.m_threshold == "ERROR") {
- myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl._ERROR_CLIENT_ERROR, exception.name,
- "MyFaces ERROR\n"
- + "Affected Class: " + this.m_class + "\n"
- + "Affected Method: " + func + "\n"
- + "Error name: " + exception.name + "\n"
- + "Error message: " + exception.message + "\n"
- + "Error description: " + exception.description + "\n"
- + "Error number: " + exception.number + "\n"
- + "Error line number: " + exception.lineNumber);
- }
- this.destroy();
- //client exceptions should not be swallowed they have to be delegated to the client itself!
- //TODO check if we are even allowed to issue client errors via the ajax API!
- throw exception;
- };
-
- /**
- * throws warnings
- */
- myfaces._impl.xhrCore._Exception.prototype.throwWarning = function(request, context, func, message) {
- if (this.m_threshold == "WARNING" || this.m_threshold == "ERROR") {
- myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl._ERROR_CLIENT_ERROR, exception.name,
- "MyFaces WARNING\n[" + this.m_class + "::" + func + "]\n\n"
- + message);
- }
- this.destroy();
- };
-
- /**
- * cleanup activities if an error occurs
- */
- myfaces._impl.xhrCore._Exception.prototype.destroy = function() {
- if (myfaces._impl.xhrCore._AjaxRequestQueue.queue &&
- myfaces._impl.xhrCore._AjaxRequestQueue.queue != null) {
- // clear RequestQueue when an exception occurs
- myfaces._impl.xhrCore._AjaxRequestQueue.queue.clearQueue();
- }
- };
-
-}
\ No newline at end of file
+/*
+ * Copyright 2009 Ganesh Jung
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Ganesh Jung (latest modification by $Author: ganeshpuri $)
+ * Version: $Revision: 1.2 $ $Date: 2009/05/30 17:54:57 $
+ *
+ */
+
+myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._Exception", Object, {
+
+ constructor_: function(sourceClass, threshold) {
+ this.m_class = sourceClass;
+ this.m_threshold = threshold;
+ },
+ /**
+ * throws errors
+ */
+ throwError : function(request, context, func, exception) {
+ if (this.m_threshold == "ERROR") {
+ myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl.prototype._ERROR_CLIENT_ERROR, exception.name,
+ "MyFaces ERROR\n"
+ + "Affected Class: " + this.m_class + "\n"
+ + "Affected Method: " + func + "\n"
+ + "Error name: " + exception.name + "\n"
+ + "Error message: " + exception.message + "\n"
+ + "Error description: " + exception.description + "\n"
+ + "Error number: " + exception.number + "\n"
+ + "Error line number: " + exception.lineNumber);
+ }
+ this.destroy();
+ //client exceptions should not be swallowed they have to be delegated to the client itself!
+ //TODO check if we are even allowed to issue client errors via the ajax API!
+ throw exception;
+ },
+
+ /**
+ * throws warnings
+ */
+ throwWarning : function(request, context, func, message) {
+ if (this.m_threshold == "WARNING" || this.m_threshold == "ERROR") {
+ myfaces.ajax.sendError(request, context, myfaces._impl.core._jsfImpl.prototype._ERROR_CLIENT_ERROR, exception.name,
+ "MyFaces WARNING\n[" + this.m_class + "::" + func + "]\n\n"
+ + message);
+ }
+ this.destroy();
+ },
+
+ /**
+ * cleanup activities if an error occurs
+ */
+ destroy : function() {
+ if (myfaces._impl.xhrCore._AjaxRequestQueue.queue &&
+ myfaces._impl.xhrCore._AjaxRequestQueue.queue != null) {
+ // clear RequestQueue when an exception occurs
+ myfaces._impl.xhrCore._AjaxRequestQueue.queue.clearQueue();
+ }
+ }
+
+});
\ No newline at end of file
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_xhrCoreAdapter.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_xhrCoreAdapter.js?rev=944200&r1=944199&r2=944200&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_xhrCoreAdapter.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_xhrCoreAdapter.js Fri May 14 10:54:32 2010
@@ -17,40 +17,32 @@
* Version: $Revision: 1.1 $ $Date: 2009/05/26 21:24:42 $
*
*/
+if (myfaces._impl.core._Runtime.reserveNamespace("myfaces._impl.xhrCore._Ajax")) {
-_reserveMyfacesNamespaces();
-
-if (!myfaces._impl._util._LangUtils.exists(myfaces._impl.xhrCore, "_Ajax")) {
-
-
- /**
- * Constructor
- */
- myfaces._impl.xhrCore._Ajax = function() {}
-
-
-
- /**
- * mapped options already have the exec and view properly in place
- * myfaces specifics can be found under mappedOptions.myFaces
- * @param {DomNode} source the source of this call
- * @param {HTMLForm} sourceForm the html form which is the source of this call
- * @param {Map} context the internal pass through context
- * @param {Map} passThroughValues values to be passed through
- **/
- myfaces._impl.xhrCore._Ajax.prototype._ajaxRequest = function(source, sourceForm, context, passThroughValues ) {
- myfaces._impl.xhrCore._AjaxRequestQueue.queue.queueRequest(
- new myfaces._impl.xhrCore._AjaxRequest(source, sourceForm, context, passThroughValues));
- }
-
- /**
- * Spec. 13.3.3
- * Examining the response markup and updating the DOM tree
- * @param {XmlHttpRequest} request - the ajax request
- * @param {XmlHttpRequest} context - the ajax context
- */
- myfaces._impl.xhrCore._Ajax.prototype._ajaxResponse = function(request, context) {
- myfaces._impl.xhrCore._AjaxRequestQueue.queue.m_request.m_response.processResponse(request, context);
- }
+ myfaces._impl.xhrCore._Ajax = myfaces._impl.core._Runtime.extendClass(function() {
+ }, Object, {
+ /**
+ * mapped options already have the exec and view properly in place
+ * myfaces specifics can be found under mappedOptions.myFaces
+ * @param {DomNode} source the source of this call
+ * @param {HTMLForm} sourceForm the html form which is the source of this call
+ * @param {Map} context the internal pass through context
+ * @param {Map} passThroughValues values to be passed through
+ **/
+ _ajaxRequest : function(source, sourceForm, context, passThroughValues) {
+ myfaces._impl.xhrCore._AjaxRequestQueue.queue.queueRequest(
+ new myfaces._impl.xhrCore._AjaxRequest(source, sourceForm, context, passThroughValues));
+ },
+
+ /**
+ * Spec. 13.3.3
+ * Examining the response markup and updating the DOM tree
+ * @param {XmlHttpRequest} request - the ajax request
+ * @param {XmlHttpRequest} context - the ajax context
+ */
+ _ajaxResponse : function(request, context) {
+ myfaces._impl.xhrCore._AjaxRequestQueue.queue.m_request.m_response.processResponse(request, context);
+ }
+ });
}
\ No newline at end of file
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/api/jsf.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/api/jsf.js?rev=944200&r1=944199&r2=944200&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/api/jsf.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/api/jsf.js Fri May 14 10:54:32 2010
@@ -55,7 +55,7 @@ if ('undefined' == typeof jsf || null ==
* javax.faces.application.Application.getProjectStage()
*/
jsf.getProjectStage = function() {
- var impl = myfaces._impl._util._Utils.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
+ var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
return impl.getProjectStage();
};
@@ -69,7 +69,7 @@ if ('undefined' == typeof jsf || null ==
*/
jsf.getViewState = function(formElement) {
/*we are not allowed to add the impl on a global scope so we have to inline the code*/
- var impl = myfaces._impl._util._Utils.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
+ var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
return impl.getViewState(formElement);
};
}
@@ -104,17 +104,17 @@ if ('undefined' == typeof jsf.ajax || nu
options = {};
}
/*we are not allowed to add the impl on a global scope so we have to inline the code*/
- var impl = myfaces._impl._util._Utils.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
+ var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
return impl.request(element, event, options);
};
jsf.ajax.addOnError = function(/*function*/errorListener) {
- var impl = myfaces._impl._util._Utils.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
+ var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
return impl.addOnError(errorListener);
}
jsf.ajax.addOnEvent = function(/*function*/eventListener) {
- var impl = myfaces._impl._util._Utils.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
+ var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
return impl.addOnEvent(eventListener);
}
@@ -124,7 +124,7 @@ if ('undefined' == typeof jsf.ajax || nu
* @param context the ajax context!
*/
jsf.ajax.response = function(/*xhr request object*/request, context) {
- var impl = myfaces._impl._util._Utils.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
+ var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
return impl.response(request, context);
};
}
@@ -143,7 +143,7 @@ if ('undefined' == typeof jsf.util || nu
*
*/
jsf.util.chain = function(source, event) {
- var impl = myfaces._impl._util._Utils.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
+ var impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces.ajax);
return impl.chain.apply(jsf.ajax._impl, arguments);
}
}
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/api/readme.txt
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/api/readme.txt?rev=944200&r1=944199&r2=944200&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/api/readme.txt (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/api/readme.txt Fri May 14 10:54:32 2010
@@ -6,7 +6,7 @@ if you want to include the files manuall
<script type="text/javascript" src="./_impl/_util/_LangUtils.js"></script>
<script type="text/javascript" src="./_impl/_util/_ListenerQueue.js"></script>
<script type="text/javascript" src="./_impl/_util/_Logger.js"></script>
-<script type="text/javascript" src="./_impl/_util/_Utils.js"></script>
+<script type="text/javascript" src="./_impl/_util/_Dom.js"></script>
<script type="text/javascript" src="./_impl/xhrCore/_Exception.js"></script>
<script type="text/javascript" src="./_impl/xhrCore/_AjaxUtils.js"></script>
<script type="text/javascript" src="./_impl/xhrCore/_AjaxRequestQueue.js"></script>