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/06/20 16:21:15 UTC
svn commit: r956363 - in
/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl:
_util/_Dom.js core/_Runtime.js xhrCore/_AjaxResponse.js
Author: werpu
Date: Sun Jun 20 14:21:15 2010
New Revision: 956363
URL: http://svn.apache.org/viewvc?rev=956363&view=rev
Log:
https://issues.apache.org/jira/browse/MYFACES-2762
Modified:
myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js
myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js
myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js?rev=956363&r1=956362&r2=956363&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js Sun Jun 20 14:21:15 2010
@@ -193,6 +193,15 @@ myfaces._impl.core._Runtime.singletonExt
evalNode = evalNode.childNodes[0];
}
+ if('undefined' == typeof evalNode) {
+ //fallback for htmlunit which should be good enough
+ //to run the tests, maybe we have to wrap it as well
+ dummyPlaceHolder.innerHTML = "<div>" + markup + "</div>";
+ //note this is triggered only in htmlunit no other browser
+ //so we are save here
+ evalNode = dummyPlaceHolder.childNodes[0];
+ }
+
parentNode = item.parentNode;
item.parentNode.replaceChild(evalNode, item);
@@ -732,7 +741,14 @@ myfaces._impl.core._Runtime.singletonExt
fuzzyFormDetection : function(elem) {
if (!document.forms || !document.forms.length) {
return null;
- } else if (1 == document.forms.length) {
+ }
+
+ // This will not work well on portlet case, because we cannot be sure
+ // the returned form is right one.
+ //we can cover that case by simply adding one of our config params
+ //the default is the weaker, but more correct portlet code
+ //you can override it with myfaces_config.no_portlet_env = true globally
+ else if (1 == document.forms.length && myfaces._impl.core._Runtime.getGlobalConfig("no_portlet_env", false)) {
return document.forms[0];
}
if (!elem) {
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js?rev=956363&r1=956362&r2=956363&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js Sun Jun 20 14:21:15 2010
@@ -381,7 +381,10 @@ if (!myfaces._impl.core._Runtime) {
}
holder.appendChild(script);
} catch (e) {
-
+ //webkit based browsers and probably
+ //other standard conforming browsers forbid head manipulation
+ //after the head tag being closed
+ //we fall back to global eval for those cases
return false;
}
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=956363&r1=956362&r2=956363&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 Sun Jun 20 14:21:15 2010
@@ -49,8 +49,10 @@ myfaces._impl.core._Runtime.extendClass(
* @param {function} onWarning
*/
constructor_: function(onException, onWarning) {
-
- this.changeTrace = [];
+ //List of non form elements to be updated (which can have forms embedded)
+ this._updateElems = [];
+ // List of forms to be updated if any inner block is updated
+ this._updateForms = [];
this._onException = onException;
this._onWarning = onWarning;
@@ -155,16 +157,30 @@ myfaces._impl.core._Runtime.extendClass(
/*namespace remapping*/
var _Dom = myfaces._impl._util._Dom;
+ // Now update the forms that were not replaced but forced to be updated, because contains child ajax tags
+ // we should only update forms with view state hidden field. If by some reason, the form was set to be
+ // updated but the form was replaced, it does not have hidden view state, so later in changeTrace processing the
+ // view state is updated.
+ for (var cnt = 0; cnt < this._updateForms.length; cnt ++) {
+ var formToUpdate = this._updateForms[cnt];
+ var viewStateField = _Dom.findFormElement(formToUpdate, this.P_VIEWSTATE);
+ if (null != viewStateField) {
+ _Dom.setAttribute(viewStateField, "value", this.appliedViewState);
+ }
+ }
+
//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];
+ for (var cnt = 0; cnt < this._updateElems.length; cnt ++) {
+ var replacementElem = this._updateElems[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, this.P_VIEWSTATE);
+ //we have to add the viewstate field in case it is not rendered
+ //otherwise those forms cannot issue another submit
if (null == viewStateField) {
var element = document.createElement("input");
_Dom.setAttribute(element, "type", "hidden");
@@ -262,14 +278,37 @@ myfaces._impl.core._Runtime.extendClass(
processUpdate : function(request, context, node) {
/*local namespace remapping*/
var _Dom = myfaces._impl._util._Dom;
-
+ var _Lang = myfaces._impl._util._Lang;
if (node.getAttribute('id') == this.P_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);
+ var sourceForm = _Dom.fuzzyFormDetection(context.source);
+
+ // TODO: After some tests, it was found sourceForm could point to a detached instance, but
+ // there is no harm if we update it. Below there is a code that check if the node has been
+ // detached or not to prevent manipulation. I'm not sure if that code works in all browser
+ // so to prevent introduce bugs, I let it commented with the hope somebody check if let this
+ // code is safe or if it is worth. If it is not detached, without this code we could update
+ // the same input hidden view state twice.
+ //if (null != sourceForm) {
+ // Check if sourceForm is inside the document, or in other words, it was not detached.
+ // We have to walk to the parent node
+ //var _Lang = myfaces._impl._util._Lang;
+ //var searchClosure = function(parentItem) {
+ // return parentItem && (parentItem == document);
+ //};
+ //var sourceFormAncestor = _Dom.getFilteredParent(sourceForm, searchClosure);
+ //Is not on the document?
+ //if (null == sourceFormAncestor)
+ //{
+ // Let fixViewStates do the job, because after the blocks are processed, we register
+ // the target forms to be updated if any.
+ //sourceForm = null;
+ //}
+ //}
//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
@@ -306,8 +345,18 @@ myfaces._impl.core._Runtime.extendClass(
switch (node.getAttribute('id')) {
case this.P_VIEWROOT:
- this._replaceBody(request, context, cDataBlock);
-
+ var resultNode = this._replaceBody(request, context, cDataBlock);
+ if (resultNode) {
+ var parentForm = _Dom.getParent(resultNode,"form");
+ if (null != parentForm)
+ {
+ this._updateForms.push(parentForm);
+ }
+ else
+ {
+ this._updateElems.push(resultNode);
+ }
+ }
break;
case this.P_VIEWHEAD:
//we cannot replace the head, almost no browser allows this, some of them throw errors
@@ -317,13 +366,32 @@ myfaces._impl.core._Runtime.extendClass(
break;
case this.P_VIEWBODY:
//we assume the cdata block is our body including the tag
- this._replaceBody(request, context, cDataBlock);
+ var resultNode = this._replaceBody(request, context, cDataBlock);
+ if (resultNode) {
+ var parentForm = _Dom.getParent(resultNode,"form");
+ if (null != parentForm)
+ {
+ this._updateForms.push(parentForm);
+ }
+ else
+ {
+ this._updateElems.push(resultNode);
+ }
+ }
break;
default:
var resultNode = this._replaceElement(request, context, node.getAttribute('id'), cDataBlock);
- if ('undefined' != typeof resultNode && null != resultNode) {
- this.changeTrace.push(resultNode);
+ if (resultNode) {
+ var parentForm = _Dom.getParent(resultNode,"form");
+ if (null != parentForm)
+ {
+ this._updateForms.push(parentForm);
+ }
+ else
+ {
+ this._updateElems.push(resultNode);
+ }
}
break;
}
@@ -362,12 +430,13 @@ myfaces._impl.core._Runtime.extendClass(
//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);
+ var returnedElement = this._replaceElement(request, context, placeHolder, bodyData);
for (var key in parser.tagAttributes) {
var value = parser.tagAttributes[key];
_Dom.setAttribute(newBody, key, value);
}
+ return returnedElement;
}
,
@@ -471,7 +540,15 @@ myfaces._impl.core._Runtime.extendClass(
nodeHolder, cDataBlock, null);
if (replacementFragment) {
- this.changeTrace.push(replacementFragment);
+ var parentForm = _Dom.getParent(replacementFragment,"form");
+ if (parentForm)
+ {
+ this._updateForms.push(parentForm);
+ }
+ else
+ {
+ this._updateElems.push(replacementFragment);
+ }
}
} else {
@@ -490,7 +567,15 @@ myfaces._impl.core._Runtime.extendClass(
nodeHolder, cDataBlock, null);
if (replacementFragment) {
- this.changeTrace.push(replacementFragment);
+ var parentForm = _Dom.getParent(replacementFragment,"form");
+ if (null != parentForm)
+ {
+ this._updateForms.push(parentForm);
+ }
+ else
+ {
+ this._updateElems.push(replacementFragment);
+ }
}
}
@@ -508,8 +593,18 @@ myfaces._impl.core._Runtime.extendClass(
_Impl.MALFORMEDXML, "Error in delete, id not in xml markup");
return false;
}
-
- _Dom.deleteItem(deleteId);
+
+ var item = _Dom.byId(deleteId);
+ if (!item) {
+ throw Error("_AjaxResponse.processDelete Unknown Html-Component-ID: " + deleteId);
+ }
+
+ var parentForm = _Dom.getParent(item,"form");
+ if (null != parentForm)
+ {
+ this._updateForms.push(parentForm);
+ }
+ _Dom.deleteItem(item);
return true;
}