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/07/14 11:43:40 UTC
svn commit: r963991 - in
/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl:
_util/_Dom.js xhrCore/_AjaxRequest.js xhrCore/_AjaxResponse.js
Author: werpu
Date: Wed Jul 14 09:43:39 2010
New Revision: 963991
URL: http://svn.apache.org/viewvc?rev=963991&view=rev
Log:
https://issues.apache.org/jira/browse/MYFACES-2809
https://issues.apache.org/jira/browse/MYFACES-2819
https://issues.apache.org/jira/browse/MYFACES-2820
https://issues.apache.org/jira/browse/MYFACES-2821
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/xhrCore/_AjaxRequest.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=963991&r1=963990&r2=963991&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 Wed Jul 14 09:43:39 2010
@@ -61,6 +61,17 @@ myfaces._impl.core._Runtime.singletonExt
_Lang:myfaces._impl._util._Lang,
+ constructor_: function() {
+ //we have to trigger it upfront because mozilla runs the eval
+ //after the dom updates and hence causes a race conditon if used on demand
+ //under normal circumstances this works, if there are no normal ones
+ //then this also will work at the second time, but the onload handler
+ //should cover 99% of all use cases to avoid a loading race condition
+ myfaces._impl.core._Runtime.addOnLoad(document.body || window, function() {
+ myfaces._impl._util._Dom.isManualScriptEval();
+ });
+ },
+
/**
* Run through the given Html item and execute the inline scripts
* (IE doesn't do this by itself)
@@ -79,13 +90,13 @@ myfaces._impl.core._Runtime.singletonExt
//due to changing the and order instead of relying on left to right
if ((src.indexOf("ln=scripts") == -1 && src.indexOf("ln=javax.faces") == -1) || (src.indexOf("/jsf.js") == -1
&& src.indexOf("/jsf-uncompressed.js") == -1))
- if(finalScripts.length) {
+ if (finalScripts.length) {
//script source means we have to eval the existing
//scripts before running the include
myfaces._impl.core._Runtime.globalEval(finalScripts.join("\n"));
finalScripts = [];
}
- myfaces._impl.core._Runtime.loadScriptEval(src, item.getAttribute('type'), false, "UTF-8");
+ myfaces._impl.core._Runtime.loadScriptEval(src, item.getAttribute('type'), false, "UTF-8");
} else {
// embedded script auto eval
var test = (!xmlData) ? item.text : this._Lang.serializeChilds(item);
@@ -118,8 +129,8 @@ myfaces._impl.core._Runtime.singletonExt
for (var cnt = 0; cnt < scriptElements.length; cnt++) {
execScrpt(scriptElements[cnt]);
}
- if(finalScripts.length) {
- myfaces._impl.core._Runtime.globalEval(finalScripts.join("\n"));
+ if (finalScripts.length) {
+ myfaces._impl.core._Runtime.globalEval(finalScripts.join("\n"));
}
} finally {
//the usual ie6 fix code
@@ -174,11 +185,12 @@ myfaces._impl.core._Runtime.singletonExt
// and remove the old item
//first we have to save the node newly insert for easier access in our eval part
if (this.isManualScriptEval()) {
- if (evalNodes.length) {
+ var isArr = evalNodes instanceof Array;
+ if (isArr && evalNodes.length) {
for (var cnt = 0; cnt < evalNodes.length; cnt++) {
this.runScripts(evalNodes[cnt]);
}
- } else {
+ } else if (!isArr) {
this.runScripts(evalNodes);
}
}
@@ -191,45 +203,52 @@ myfaces._impl.core._Runtime.singletonExt
_outerHTMLCompliant: function(item, markup) {
- var evalNodes = null;
- var dummyPlaceHolder = document.createElement("div");
- dummyPlaceHolder.innerHTML = markup;
- evalNodes = dummyPlaceHolder.childNodes;
- if('undefined' == typeof evalNodes.length) {
- item.parentNode.replaceChild( evalNodes, item);
- return evalNodes;
- //return this.replaceElement(item, evalNodes);
- } else if(evalNodes.length == 1) {
- var ret = evalNodes[0];
- item.parentNode.replaceChild(evalNodes[0], item);
- return ret;
- //return this.replaceElement(item, evalNodes[0]);
- } else {
- return this.replaceElements(item, evalNodes)
- }
+ var b = myfaces._impl.core._Runtime.browser;
+ //most browsers can handle the faster approach
+ // if (!b.isWebKit && !b.isChrome && b.isSafari) {
+ var evalNodes = null;
+ var dummyPlaceHolder = document.createElement("div");
+ dummyPlaceHolder.innerHTML = markup;
+ evalNodes = dummyPlaceHolder.childNodes;
+ if ('undefined' == typeof evalNodes.length) {
+ item.parentNode.replaceChild(evalNodes, item);
+ return evalNodes;
+ //return this.replaceElement(item, evalNodes);
+ } else if (evalNodes.length == 1) {
+ var ret = evalNodes[0];
+ item.parentNode.replaceChild(evalNodes[0], item);
+ return ret;
+ //return this.replaceElement(item, evalNodes[0]);
+ } else {
+ return this.replaceElements(item, evalNodes)
+ }
+ /*} else {
+ //webkit only works properly on contextual ranges
+ //without running into race conditions
+ var evalNodes = null;
+ var range = document.createRange();
+ range.setStartBefore(item);
+ var fragment = range.createContextualFragment(markup);
+ //special case update body, we have to replace the placeholder
+ //with the first element (the place holder is the the only child)
+ //and then append additional elements as additional childs
+ //the body itself then is the root for the eval part!
+ if (item.id == 'myfaces_bodyplaceholder') {
+ parentNode = item.parentNode;
+ parentNode.appendChild(fragment);
+ evalNodes = parentNode;
+ } else {
+ //normal dom node case we replace only the client id fragment!
- /*var evalNodes = null;
- var range = document.createRange();
- range.setStartBefore(item);
- var fragment = range.createContextualFragment(markup);
- //special case update body, we have to replace the placeholder
- //with the first element (the place holder is the the only child)
- //and then append additional elements as additional childs
- //the body itself then is the root for the eval part!
- if (item.id == 'myfaces_bodyplaceholder') {
- parentNode = item.parentNode;
- parentNode.appendChild(fragment);
- evalNodes = parentNode;
- } else {
- //normal dom node case we replace only the client id fragment!
-
- parentNode = item.parentNode;
-
- //evalNode = fragment.childNodes[0];
- evalNodes = (fragment.childNodes) ? this._Lang.objToArray(fragment.childNodes) : fragment;
- parentNode.replaceChild(fragment, item);
- } */
- return evalNodes;
+ parentNode = item.parentNode;
+
+ //evalNode = fragment.childNodes[0];
+ evalNodes = (fragment.childNodes) ? this._Lang.objToArray(fragment.childNodes) : [fragment];
+ parentNode.replaceChild(fragment, item);
+ }
+
+ return evalNodes;
+ } */
},
_outerHTMLNonCompliant: function(item, markup) {
@@ -269,7 +288,7 @@ myfaces._impl.core._Runtime.singletonExt
//ie throws also an error on length requests
evalNodes = this._Lang.objToArray(evalNodes);
- if(evalNodes.length == 1) {
+ if (evalNodes.length == 1) {
item.parentNode.replaceChild(evalNodes[0], item);
delete item;
return evalNodes[0];
@@ -304,8 +323,8 @@ myfaces._impl.core._Runtime.singletonExt
*/
replaceElements: function (item, evalNodes) {
var parentNode = item.parentNode;
- var evalNodesDefined = 'undefined' != typeof evalNodes.length;
- if(!evalNodesDefined) {
+ var evalNodesDefined = 'undefined' != typeof evalNodes.length;
+ if (!evalNodesDefined) {
throw new Error("replaceElements called while evalNodes is not an array");
}
var oldNode = item;
@@ -743,15 +762,8 @@ myfaces._impl.core._Runtime.singletonExt
if (!nameId) {
throw Error("_Dom.findFormElement an element or identifier must be given");
}
-
- var eLen = form.elements.length;
-
- for (var e = 0; e < eLen; e++) {
- var elem = form.elements[e];
- if (elem.name && elem.name === nameId) return elem;
- if (elem.id && elem.id === nameId) return elem;
- } // end of for (formElements)
- return null;
+ if (!form.elements) return null;
+ return form.elements[nameId] || this.findById(form, nameId);
}
,
@@ -771,6 +783,9 @@ myfaces._impl.core._Runtime.singletonExt
//a good citizen
var _Browser = myfaces._impl.core._Runtime.browser;
if (!_Browser.isIE || _Browser.isIE > 7) {
+ if (!node.setAttribute) {
+ return;
+ }
node.setAttribute(attr, val);
return;
}
@@ -946,6 +961,7 @@ myfaces._impl.core._Runtime.singletonExt
if (this._Lang.equalsIgnoreCase(elem.tagName, "form")) {
return elem;
}
+
return this.getParent(elem, "form");
}
@@ -1258,4 +1274,5 @@ myfaces._impl.core._Runtime.singletonExt
}
})
;
-
+
+
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequest.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequest.js?rev=963991&r1=963990&r2=963991&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequest.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxRequest.js Wed Jul 14 09:43:39 2010
@@ -27,10 +27,10 @@ myfaces._impl.core._Runtime.extendClass(
/*
- note there is a load of common properties
- inherited by the base class which define the corner
- parameters and the general internal behavior
- like _onError etc...
+ note there is a load of common properties
+ inherited by the base class which define the corner
+ parameters and the general internal behavior
+ like _onError etc...
*/
@@ -56,13 +56,6 @@ myfaces._impl.core._Runtime.extendClass(
}
this._ajaxUtil = new myfaces._impl.xhrCore._AjaxUtils(this._onException, this._onWarning);
- this._requestParameters = this.getViewState();
-
- for (var key in this._passThrough) {
- this._requestParameters = this._requestParameters +
- "&" + encodeURIComponent(key) +
- "=" + encodeURIComponent(this._passThrough[key]);
- }
} catch (e) {
//_onError
this._onException(null, this._context, "myfaces._impl.xhrCore._AjaxRequest", "constructor", e);
@@ -74,6 +67,16 @@ myfaces._impl.core._Runtime.extendClass(
*/
send : function() {
try {
+ //we have to encode at send time, otherwise
+ //we pick up old viewstates
+ this._requestParameters = this.getViewState();
+
+ for (var key in this._passThrough) {
+ this._requestParameters = this._requestParameters +
+ "&" + encodeURIComponent(key) +
+ "=" + encodeURIComponent(this._passThrough[key]);
+ }
+
this._startXHR();
this._startTimeout();
} catch (e) {
@@ -112,7 +115,7 @@ myfaces._impl.core._Runtime.extendClass(
if (this._timeout && this._onTimeout) {
var _req = this._xhr;
var _context = this._context;
- if(this._timeoutId) {
+ if (this._timeoutId) {
window.clearTimeout(this._timeoutId);
this._timeoutId = null;
}
@@ -124,21 +127,22 @@ myfaces._impl.core._Runtime.extendClass(
//the hitch has to be done due to the setTimeout refocusing the scope of this
//to window
try {
- _req.onreadystatechange = function() {};
+ _req.onreadystatechange = function() {
+ };
- //to avoid malformed whatever, we have
- //the timeout covered already on the _onTimeout function
- _req.abort();
- this._onTimeout(_req, _context);
+ //to avoid malformed whatever, we have
+ //the timeout covered already on the _onTimeout function
+ _req.abort();
+ this._onTimeout(_req, _context);
} catch (e) {
- alert(e);
+ alert(e);
} finally {
}
})
, this._timeout);
}
},
-
+
/**
* Callback method to process the Ajax response
* triggered by RequestQueue
@@ -149,14 +153,14 @@ myfaces._impl.core._Runtime.extendClass(
var _Impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
if (this._xhr.readyState == this._READY_STATE_DONE) {
- if(this._timeoutId) {
+ if (this._timeoutId) {
//normally the timeout should not cause anything anymore
//but just to make sure
window.clearTimeout(this._timeoutId);
this._timeoutId = null;
}
this._onDone(this._xhr, this._context);
- if (this._xhr.status >= this._STATUS_OK_MINOR && this._xhr.status < this._STATUS_OK_MAJOR) {
+ if (this._xhr.status >= this._STATUS_OK_MINOR && this._xhr.status < this._STATUS_OK_MAJOR) {
this._onSuccess(this._xhr, this._context);
} else {
this._onError(this._xhr, this._context);
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=963991&r1=963990&r2=963991&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 Wed Jul 14 09:43:39 2010
@@ -54,7 +54,7 @@ myfaces._impl.core._Runtime.extendClass(
this._onWarning = onWarning;
this.appliedViewState = null;
-
+
this._Lang = myfaces._impl._util._Lang;
this._Dom = myfaces._impl._util._Dom;
},
@@ -90,15 +90,11 @@ myfaces._impl.core._Runtime.extendClass(
}
//check for a parseError under certain browsers
-
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
-
-
-
- if ( this._Lang.isXMLParseError(xmlContent)) {
+ if (this._Lang.isXMLParseError(xmlContent)) {
_Impl.sendError(request, context, myfaces._impl.core.Impl.MALFORMEDXML);
return;
}
@@ -165,15 +161,23 @@ myfaces._impl.core._Runtime.extendClass(
//set the viewstates of all outer forms parents of our updated elements
this._Lang.arrForEach(this._updateForms, this._setVSTOuterForm, 0, this);
-
+
//set the viewstate of all forms within our updated elements
this._Lang.arrForEach(this._updateElems, this._setVSTInnerForms, 0, this);
},
_setVSTOuterForm: function(elem) {
var viewStateField = this._Dom.findFormElement(elem, this.P_VIEWSTATE);
+
if (null != viewStateField) {
- this._Dom.setAttribute(viewStateField,"value", this.appliedViewState);
+ this._Dom.setAttribute(viewStateField, "value", this.appliedViewState);
+ } else {
+ var element = document.createElement("input");
+ this._Dom.setAttribute(element, "type", "hidden");
+ this._Dom.setAttribute(element, "name", this.P_VIEWSTATE);
+ elem.appendChild(element);
+
+ this._Dom.setAttribute(element, "value", this.appliedViewState);
}
},
@@ -199,7 +203,7 @@ myfaces._impl.core._Runtime.extendClass(
appliedReplacedFrom.appendChild(element);
this._Dom.setAttribute(element, "value", this.appliedViewState);
- }
+ } //else form already has a delivered viewstate field
},
processError : function(request, context, node) {
@@ -297,42 +301,28 @@ myfaces._impl.core._Runtime.extendClass(
var viewStateValue = node.firstChild.nodeValue;
var sourceForm = this._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 this._Lang = myfaces._impl._util.this._Lang;
- //var searchClosure = function(parentItem) {
- // return parentItem && (parentItem == document);
- //};
- //var sourceFormAncestor = this._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
+
+ //fixup we need the current form not the maybe already detached instance
+ //the findParent might refer to a detached instance due to its goParent walking algorithm
+ //so we refer here to the one
+ sourceForm = (sourceForm && 'undefined' != typeof sourceForm.id) ? this._Dom.byId(sourceForm.id) : sourceForm;
+ //now we really have the actual current instance of the form if present
+ /*we check for an element and include a namesearch, but only within the bounds of the committing form*/
+ //we now should have the form, if not the viewstate fixup code at the end of the list
+ //will also be able to recover in almost all instances
if (null != sourceForm) {
- /*we check for an element and include a namesearch, but only within the bounds of the committing form*/
var element = null;
try {
- element = this._Dom.getElementFromForm(this.P_VIEWSTATE, sourceForm, true, true);
+ element = this._Dom.findFormElement(sourceForm, this.P_VIEWSTATE);
} catch (e) {
//in case of an error here we try an early recovery but throw an error to our error handler
this._onException(request, context, "_AjaxResponse", "processUpdate('javax.faces.ViewState')", e);
}
- if (null == element) {//no element found we have to append a hidden field
+ if (!element) {//no element found we have to append a hidden field
element = document.createElement("input");
this._Dom.setAttribute(element, "type", "hidden");
this._Dom.setAttribute(element, "name", this.P_VIEWSTATE);
@@ -357,7 +347,7 @@ myfaces._impl.core._Runtime.extendClass(
case this.P_VIEWROOT:
cDataBlock = cDataBlock.substring(cDataBlock.indexOf("<html"));
var parsedData = this._replaceHead(request, context, cDataBlock);
- var resultNode = (parsedData)? this._replaceBody(request, context, cDataBlock, parsedData): this._replaceBody(request, context, cDataBlock);
+ var resultNode = (parsedData) ? this._replaceBody(request, context, cDataBlock, parsedData) : this._replaceBody(request, context, cDataBlock);
if (resultNode) {
this._pushOperationResult(resultNode);
}
@@ -365,7 +355,7 @@ myfaces._impl.core._Runtime.extendClass(
case this.P_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!
- this._replaceHead(request, context, cDataBlock);
+ this._replaceHead(request, context, cDataBlock);
break;
case this.P_VIEWBODY:
@@ -399,11 +389,12 @@ myfaces._impl.core._Runtime.extendClass(
this._updateElems.push(currNode);
}
});
- if (resultNode.length) {
+ var isArr = resultNode instanceof Array;
+ if (isArr && resultNode.length) {
for (var cnt = 0; cnt < resultNode.length; cnt++) {
pushSubnode(resultNode[cnt]);
}
- } else {
+ } else if (!isArr) {
pushSubnode(resultNode);
}
@@ -424,16 +415,16 @@ myfaces._impl.core._Runtime.extendClass(
var _Impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
var doc = this._Lang.parseXML(newData);
var newHead = null;
- if(this._Lang.isXMLParseError(doc)) {
- doc = this._Lang.parseXML(newData.replace(/<!\-\-[\s\n]*<!\-\-/g,"<!--").replace(/\/\/-->[\s\n]\/\/-->/g,"//-->"));
+ if (this._Lang.isXMLParseError(doc)) {
+ doc = this._Lang.parseXML(newData.replace(/<!\-\-[\s\n]*<!\-\-/g, "<!--").replace(/\/\/-->[\s\n]\/\/-->/g, "//-->"));
}
- if(this._Lang.isXMLParseError(doc)) {
+ if (this._Lang.isXMLParseError(doc)) {
//the standard xml parser failed we retry with the stripper
var parser = new (myfaces._impl.core._Runtime.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();
var headData = parser.parse(newData, "head");
- newHead = this._Lang.parseXML("<root>"+headData+"</root>");
- if(this._Lang.isXMLParseError(newHead)) {
+ newHead = this._Lang.parseXML("<root>" + headData + "</root>");
+ if (this._Lang.isXMLParseError(newHead)) {
//we give up no further fallbacks
_Impl.sendError(request, context, _Impl.MALFORMEDXML, _Impl.MALFORMEDXML, "Error in PPR Insert, before id or after id must be present");
return null;
@@ -485,29 +476,31 @@ myfaces._impl.core._Runtime.extendClass(
//and if that fails revert to a hidden iframe
//var bodyData = parser.parse(newData, "body");
var bodyData = null;
- var doc = (arguments.length > 3)? arguments[4]: this._Lang.parseXML(newData);
- if(this._Lang.isXMLParseError(doc)) {
- doc = this._Lang.parseXML(newData.replace(/<!\-\-[\s\n]*<!\-\-/g,"<!--").replace(/\/\/-->[\s\n]\/\/-->/g,"//-->"));
+ var doc = (arguments.length > 3) ? arguments[3] : this._Lang.parseXML(newData);
+ if (this._Lang.isXMLParseError(doc)) {
+ doc = this._Lang.parseXML(newData.replace(/<!\-\-[\s\n]*<!\-\-/g, "<!--").replace(/\/\/-->[\s\n]\/\/-->/g, "//-->"));
}
- if(this._Lang.isXMLParseError(doc)) {
- //the standard xml parser failed we retry with the stripper
- var parser = new (myfaces._impl.core._Runtime.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();
- bodyData = parser.parse(newData, "body");
+ if (this._Lang.isXMLParseError(doc)) {
+ //the standard xml parser failed we retry with the stripper
+ var parser = new (myfaces._impl.core._Runtime.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();
+ bodyData = parser.parse(newData, "body");
} else {
- //parser worked we go on
+ //parser worked we go on
var newBodyData = doc.getElementsByTagName("body")[0];
bodyData = this._Lang.serializeChilds(newBodyData);
for (var cnt = 0; cnt < newBodyData.attributes.length; cnt++) {
var value = newBodyData.attributes[cnt].value;
- if(value)
+ if (value)
this._Dom.setAttribute(newBody, newBodyData.attributes[cnt].name, value);
}
}
bodyParent.replaceChild(newBody, oldBody);
var returnedElement = this._replaceElement(request, context, placeHolder, bodyData);
-
+ if (returnedElement) {
+ this._pushOperationResult(returnedElement);
+ }
return returnedElement;
}
,