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/08/13 15:59:09 UTC
svn commit: r985204 - 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/
Author: werpu
Date: Fri Aug 13 13:59:08 2010
New Revision: 985204
URL: http://svn.apache.org/viewvc?rev=985204&view=rev
Log:
https://issues.apache.org/jira/browse/MYFACES-2878
sIEve detected leak fixes for IE
Added:
myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_FinalizeableObj.js
Modified:
myfaces/core/trunk/api/src/assembler/jsfscripts-compiler.xml
myfaces/core/trunk/api/src/assembler/jsfscripts-uncompressed-full-compiler.xml
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/_util/_Lang.js
myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/jsf-uncompressed.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
myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxUtils.js
myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_BaseRequest.js
myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_IFrameRequest.js
myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_Transports.js
Modified: myfaces/core/trunk/api/src/assembler/jsfscripts-compiler.xml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/assembler/jsfscripts-compiler.xml?rev=985204&r1=985203&r2=985204&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/assembler/jsfscripts-compiler.xml (original)
+++ myfaces/core/trunk/api/src/assembler/jsfscripts-compiler.xml Fri Aug 13 13:59:08 2010
@@ -46,14 +46,16 @@
<include>**/_impl/_util/_ListenerQueue.js</include>
<include>**/_impl/_util/_Dom.js</include>
<include>**/_impl/_util/_HtmlStripper.js</include>
+
+ <include>**/_impl/xhrCore/_FinalizeableObj.js</include>
<include>**/_impl/xhrCore/_AjaxUtils.js</include>
<include>**/_impl/xhrCore/_AjaxRequestQueue.js</include>
<include>**/_impl/xhrCore/_BaseRequest.js</include>
<include>**/_impl/xhrCore/_AjaxRequest.js</include>
- <!-- not yet used so we comment it out this is pure 2.1 functionality -->
+ <!-- this is pure 2.1 functionality -->
<include>**/_impl/xhrCore/_IFrameRequest.js</include>
-
+
<include>**/_impl/xhrCore/_AjaxResponse.js</include>
<include>**/_impl/xhrCore/_Transports.js</include>
<include>**/_impl/core/Impl.js</include>
Modified: myfaces/core/trunk/api/src/assembler/jsfscripts-uncompressed-full-compiler.xml
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/assembler/jsfscripts-uncompressed-full-compiler.xml?rev=985204&r1=985203&r2=985204&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/assembler/jsfscripts-uncompressed-full-compiler.xml (original)
+++ myfaces/core/trunk/api/src/assembler/jsfscripts-uncompressed-full-compiler.xml Fri Aug 13 13:59:08 2010
@@ -47,6 +47,9 @@
<include>**/_impl/_util/_ListenerQueue.js</include>
<include>**/_impl/_util/_Dom.js</include>
<include>**/_impl/_util/_HtmlStripper.js</include>
+
+ <include>**/_impl/xhrCore/_FinalizeableObj.js</include>
+
<include>**/_impl/xhrCore/_AjaxUtils.js</include>
<include>**/_impl/xhrCore/_AjaxRequestQueue.js</include>
<include>**/_impl/xhrCore/_BaseRequest.js</include>
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=985204&r1=985203&r2=985204&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 Fri Aug 13 13:59:08 2010
@@ -60,6 +60,7 @@ myfaces._impl.core._Runtime.singletonExt
},
_Lang:myfaces._impl._util._Lang,
+ _RT:myfaces._impl.core._Runtime,
constructor_: function() {
//we have to trigger it upfront because mozilla runs the eval
@@ -67,12 +68,12 @@ myfaces._impl.core._Runtime.singletonExt
//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(window, function() {
+ this._RT.addOnLoad(window, function() {
myfaces._impl._util._Dom.isManualScriptEval();
});
//safety fallback if the window onload handler is overwritten and not chained
if (document.body) {
- myfaces._impl.core._Runtime.addOnLoad(document.body, function() {
+ this._RT.addOnLoad(document.body, function() {
myfaces._impl._util._Dom.isManualScriptEval();
});
}
@@ -100,10 +101,10 @@ myfaces._impl.core._Runtime.singletonExt
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"));
+ this._RT.globalEval(finalScripts.join("\n"));
finalScripts = [];
}
- myfaces._impl.core._Runtime.loadScriptEval(src, item.getAttribute('type'), false, "UTF-8");
+ this._RT.loadScriptEval(src, item.getAttribute('type'), false, "UTF-8");
} else {
// embedded script auto eval
var test = (!xmlData) ? item.text : this._Lang.serializeChilds(item);
@@ -137,7 +138,7 @@ myfaces._impl.core._Runtime.singletonExt
execScrpt(scriptElements[cnt]);
}
if (finalScripts.length) {
- myfaces._impl.core._Runtime.globalEval(finalScripts.join("\n"));
+ this._RT.globalEval(finalScripts.join("\n"));
}
} finally {
//the usual ie6 fix code
@@ -158,7 +159,7 @@ myfaces._impl.core._Runtime.singletonExt
throw Error("_Dom.deleteItem Unknown Html-Component-ID: " + itemIdToReplace);
}
- item.parentNode.removeChild(item);
+ this._removeNode(item, false);
},
/**
@@ -178,44 +179,45 @@ myfaces._impl.core._Runtime.singletonExt
markup = this._Lang.trim(markup);
if (markup !== "") {
- var evalNodes = null;
+ var ret = null;
//w3c compliant browsers with proper contextual fragments
var parentNode;
if (window.Range
&& typeof Range.prototype.createContextualFragment == 'function') {
- evalNodes = this._outerHTMLCompliant(item, markup);
+ ret = this._outerHTMLCompliant(item, markup);
} else {
- evalNodes = this._outerHTMLNonCompliant(item, markup);
+ ret = this._outerHTMLNonCompliant(item, markup);
}
// and remove the old item
//first we have to save the node newly insert for easier access in our eval part
if (this.isManualScriptEval()) {
- var isArr = evalNodes instanceof Array;
- if (isArr && evalNodes.length) {
- for (var cnt = 0; cnt < evalNodes.length; cnt++) {
- this.runScripts(evalNodes[cnt]);
+ var isArr = ret instanceof Array;
+ if (isArr && ret.length) {
+ for (var cnt = 0; cnt < ret.length; cnt++) {
+ this.runScripts(ret[cnt]);
}
} else if (!isArr) {
- this.runScripts(evalNodes);
+ this.runScripts(ret);
}
}
- return evalNodes;
+ return ret;
}
// and remove the old item, in case of an empty newtag and do nothing else
- item.parentNode.removeChild(item);
+ this._removeNode(item, false);
return null;
},
_outerHTMLCompliant: function(item, markup) {
- var b = myfaces._impl.core._Runtime.browser;
+ var b = this._RT.browser;
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;
@@ -224,15 +226,29 @@ myfaces._impl.core._Runtime.singletonExt
var ret = evalNodes[0];
item.parentNode.replaceChild(evalNodes[0], item);
return ret;
- //return this.replaceElement(item, evalNodes[0]);
} else {
- return this.replaceElements(item, evalNodes)
+ return this.replaceElements(item, evalNodes);
}
},
- _outerHTMLNonCompliant: function(item, markup) {
+
+
+ /**
+ * now to the evil browsers
+ * of what we are dealing with is various bugs
+ * first a simple replaceElement leaks memory
+ * secondly embedded scripts can be swallowed upon
+ * innerHTML
+ *
+ * the entire mess is called IE6 and IE7
+ *
+ * @param item
+ * @param markup
+ */
+ _outerHTMLNonCompliant: function(item, markup) {
+ var b = this._RT.browser;
var evalNodes = null;
//now to the non w3c compliant browsers
//http://blogs.perl.org/users/clinton_gormley/2010/02/forcing-ie-to-accept-script-tags-in-innerhtml.html
@@ -240,11 +256,14 @@ myfaces._impl.core._Runtime.singletonExt
var probe = document.createElement("div");
probe.innerHTML = "<table><tbody><tr><td><div></div></td></tr></tbody></table>";
var depth = 0;
- while (probe) {
- probe = probe.childNodes[0];
+ var newProbe = probe;
+ while (newProbe) {
+ newProbe = newProbe.childNodes[0];
depth++;
}
depth--;
+ this._removeNode(probe, false);
+
var dummyPlaceHolder = document.createElement("div");
@@ -264,18 +283,149 @@ myfaces._impl.core._Runtime.singletonExt
//note this is triggered only in htmlunit no other browser
//so we are save here
evalNodes = dummyPlaceHolder.childNodes[0].childNodes;
- delete dummyPlaceHolder;
}
- //ie throws also an error on length requests
- evalNodes = this._Lang.objToArray(evalNodes);
- if (evalNodes.length == 1) {
- item.parentNode.replaceChild(evalNodes[0], item);
- delete item;
- return evalNodes[0];
- //return this.replaceElement(item, evalNodes[0]);
- } else {
- return this.replaceElements(item, evalNodes)
+
+ try {
+ //ie throws also an error on length requests
+ evalNodes = this._Lang.objToArray(evalNodes);
+
+ if (evalNodes.length == 1) {
+ var ret = evalNodes[0];
+ this.replaceElement(item, evalNodes[0]);
+ return ret;
+ } else {
+
+ return this.replaceElements(item, evalNodes);
+ }
+ } finally {
+ //now that Microsoft has finally given
+ //ie a working gc in 8 we can skip the costly operation
+ if (b.isIE && b.isIE < 8) {
+ this._removeNode(dummyPlaceHolder, false);
+ }
+ }
+ },
+
+
+ //now to another nasty issue:
+ //for ie we have to walk recursively over all nodes:
+ //http://msdn.microsoft.com/en-us/library/bb250448%28VS.85%29.aspx
+ //http://weblogs.java.net/blog/driscoll/archive/2009/11/13/ie-memory-management-and-you
+ //http://home.orange.nl/jsrosman/
+ //http://www.quirksmode.org/blog/archives/2005/10/memory_leaks_li.html
+ //http://www.josh-davis.org/node/7
+ _removeNode: function(node, breakEventsOpen) {
+ if (!node) return;
+ var b = this._RT.browser;
+
+ if (!b.isIE || b.isIE >= 8) {
+ //recursive descension only needed for old ie versions
+ //all newer browsers cleanup the garbage just fine without it
+ //thank you
+ if ('undefined' != typeof node.parentNode && null != node.parentNode) //if the node has a parent
+ node.parentNode.removeChild(node);
+ return;
+ }
+
+ //now to the browsers with non working garbage collection
+ this._removeChildNodes(node, breakEventsOpen);
+
+ //outer HTML setting is only possible in earlier IE versions all modern browsers throw an exception here
+ //again to speed things up we precheck first
+
+ if (b.isIE && 'undefined' != typeof node.outerHTML) //ie8+ check done earlier we skip it here
+ node.outerHTML = '';
+ else {
+ if ('undefined' != typeof node.parentNode && null != node.parentNode) //if the node has a parent
+ node.parentNode.removeChild(node);
+ }
+ delete node;
+ },
+
+ /**
+ * recursive delete child nodes
+ * node, this method only makes sense in the context of IE6 + 7 hence
+ * it is not exposed to the public API, modern browsers
+ * can garbage collect the nodes just fine by doing the standard removeNode method
+ * from the dom API!
+ *
+ * @param node the node from which the childnodes have to be deletd
+ * @param breakEventsOpen if set to true a standard events breaking is performed
+ */
+ _removeChildNodes: function(node, breakEventsOpen) {
+ if (!node) return;
+
+ //node types which cannot be cleared up by normal means
+ var disallowedNodes = {
+ "thead": true,
+ "tbody": true,
+ "tr": true,
+ "td": true
+ };
+
+ //for now we do not enable it due to speed reasons
+ //normally the framework has to do some event detection
+ //which we cannot do yet, I will dig for options
+ //to enable it in a speedly manner
+ //ie7 fixes this area anyway
+ //this.breakEvents(node);
+
+ var b = this._RT.browser;
+ if (breakEventsOpen) {
+ this.breakEvents(node);
+ }
+
+ for (var cnt = node.childNodes.length - 1; cnt >= 0; cnt -= 1) {
+ var childNode = node.childNodes[cnt];
+ //we cannot use our generic recursive tree walking due to the needed head recursion
+ //to clean it up bottom up, the tail recursion we were using in the search either would use more time
+ //because we had to walk and then clean bottom up, so we are going for a direct head recusion here
+ if (childNode.hasChildNodes())
+ this._removeChildNodes(childNode);
+ try {
+ var nodeName = (childNode.nodeName) ? childNode.nodeName.toLowerCase() : null;
+ //ie chokes on clearing out table inner elements, this is also covered by our empty
+ //catch block, but to speed things up it makes more sense to precheck that
+ if (!disallowedNodes[nodeName]) {
+ //outer HTML setting is only possible in earlier IE versions all modern browsers throw an exception here
+ //again to speed things up we precheck first
+ if (b.isIE && b.isIE < 8 && 'undefined' != childNode.outerHTML)
+ childNode.outerHTML = '';
+ else {
+ node.removeChild(childNode);
+ }
+ delete childNode;
+ }
+ } catch (e) {
+ //on some elements the outerHTML can fail we skip those in favor
+ //of stability
+
+ }
+ }
+ },
+
+ /**
+ * break the standard events from an existing dom node
+ * (note this method is not yet used, but can be used
+ * by framework authors to get rid of ie circular event references)
+ *
+ * another way probably would be to check all attributes of a node
+ * for a function and if one is present break it by nulling it
+ * I have to do some further investigation on this.
+ *
+ * The final fix is to move away from ie6 at all which is the root cause of
+ * this.
+ *
+ * @param node the node which has to be broken off its events
+ */
+ breakEvents: function(node) {
+ if (!node) return;
+ var evtArr = this.IE_QUIRKS_EVENTS;
+ for (var key in evtArr) {
+ if (key != "onunload" && node[key]) {
+ node[key] = null;
+ }
}
},
@@ -290,9 +440,16 @@ myfaces._impl.core._Runtime.singletonExt
* @param evalNodes
*/
replaceElement: function(item, evalNode) {
- evalNode = item.parentNode.replaceChild(evalNode, item);
- delete item;
- return evalNode;
+ var _Browser = this._RT.browser;
+ if (!_Browser.isIE || _Browser.isIE >= 8) {
+ //standards conform no leaking browser
+ item.parentNode.replaceChild(evalNode, item);
+ } else {
+ //browsers with defect garbage collection
+ item.parentNode.insertBefore(evalNode, item);
+ this._removeNode(item, false);
+ }
+
},
@@ -314,8 +471,7 @@ myfaces._impl.core._Runtime.singletonExt
for (var cnt = 0; cnt < resultArr.length; cnt++) {
if (cnt == 0) {
- parentNode.replaceChild(resultArr[cnt], item);
- delete item;
+ this.replaceElement(item, resultArr[cnt]);
} else {
if (sibling) {
parentNode.insertBefore(resultArr[cnt], sibling);
@@ -324,10 +480,9 @@ myfaces._impl.core._Runtime.singletonExt
}
}
- evalNodes = resultArr;
}
- return evalNodes;
+ return resultArr;
},
/**
@@ -764,7 +919,7 @@ myfaces._impl.core._Runtime.singletonExt
//quirks mode and ie7 mode has the attributes problems ie8 standards mode behaves like
//a good citizen
- var _Browser = myfaces._impl.core._Runtime.browser;
+ var _Browser = this._RT.browser;
if (!_Browser.isIE || _Browser.isIE > 7) {
if (!node.setAttribute) {
return;
@@ -930,7 +1085,7 @@ myfaces._impl.core._Runtime.singletonExt
//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)) {
+ else if (1 == document.forms.length && this._RT.getGlobalConfig("no_portlet_env", false)) {
return document.forms[0];
}
if (!elem) {
@@ -1193,7 +1348,7 @@ myfaces._impl.core._Runtime.singletonExt
isManualScriptEval: function() {
if (!this._Lang.exists(myfaces, "config._autoeval")) {
- var _Browser = myfaces._impl.core._Runtime.browser;
+ var _Browser = this._RT.browser;
//now we rely on the document being processed if called for the first time
var evalDiv = document.createElement("div");
this._Lang.reserveNamespace("myfaces.config._autoeval");
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js?rev=985204&r1=985203&r2=985204&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js Fri Aug 13 13:59:08 2010
@@ -32,7 +32,23 @@
/** @namespace window.console */
myfaces._impl.core._Runtime.singletonDelegateObj("myfaces._impl._util._Lang", myfaces._impl.core._Runtime, {
+ _processedExceptions: {},
+ isExceptionProcessed: function(e) {
+ return !! this._processedExceptions[e.toString()];
+ },
+
+ setExceptionProcessed: function(e) {
+ this._processedExceptions[e.toString()] = true;
+ },
+
+ clearExceptionProcessed: function() {
+ //ie again
+ for(var key in this._processedExceptions) {
+ this._processedExceptions[key] = null;
+ }
+ this._processedExceptions = {};
+ },
fetchNamespace : function(namespace) {
if (!namespace || !this.isString(namespace)) {
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/jsf-uncompressed.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/jsf-uncompressed.js?rev=985204&r1=985203&r2=985204&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/jsf-uncompressed.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/jsf-uncompressed.js Fri Aug 13 13:59:08 2010
@@ -21,6 +21,8 @@ if (!window.jsf) {
myfaces._impl.core._Runtime.loadScript("#{resource['org.apache.myfaces.core.impl.util:_ListenerQueue.js']}", null, null, "UTF-8");
myfaces._impl.core._Runtime.loadScript("#{resource['org.apache.myfaces.core.impl.util:_Dom.js']}", null, null, "UTF-8");
myfaces._impl.core._Runtime.loadScript("#{resource['org.apache.myfaces.core.impl.util:_HtmlStripper.js']}", null, null, "UTF-8");
+
+ myfaces._impl.core._Runtime.loadScript("#{resource['org.apache.myfaces.core.impl.xhrCore:_FinalizeableObj.js']}", null, null, "UTF-8");
myfaces._impl.core._Runtime.loadScript("#{resource['org.apache.myfaces.core.impl.xhrCore:_AjaxUtils.js']}", null, null, "UTF-8");
myfaces._impl.core._Runtime.loadScript("#{resource['org.apache.myfaces.core.impl.xhrCore:_AjaxRequestQueue.js']}", null, null, "UTF-8");
myfaces._impl.core._Runtime.loadScript("#{resource['org.apache.myfaces.core.impl.xhrCore:_BaseRequest.js']}", null, null, "UTF-8");
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=985204&r1=985203&r2=985204&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 Fri Aug 13 13:59:08 2010
@@ -41,10 +41,9 @@ myfaces._impl.core._Runtime.extendClass(
*/
constructor_: function(arguments) {
- if('undefined' == typeof arguments) return;
try {
-
+ this._callSuper("constructor", arguments);
/*namespace remapping for readability*/
//we fetch in the standard arguments
//and apply them to our protected attributes
@@ -58,7 +57,7 @@ myfaces._impl.core._Runtime.extendClass(
} catch (e) {
//_onError
- this._onException(null, this._context, "myfaces._impl.xhrCore._AjaxRequest", "constructor", e);
+ this._onException(this._context, "myfaces._impl.xhrCore._AjaxRequest", "constructor", e);
}
},
@@ -188,9 +187,12 @@ myfaces._impl.core._Runtime.extendClass(
alert(e.toString());
} finally {
//final cleanup to terminate everything
+ this._Lang.clearExceptionProcessed();
+
if(this._xhr.readyState == this._READY_STATE_DONE) {
this._callSuper("_finalize");
}
+
}
},
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=985204&r1=985203&r2=985204&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 Aug 13 13:59:08 2010
@@ -15,7 +15,7 @@
*/
/** @namespace myfaces._impl.xhrCore._AjaxResponse */
-myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._AjaxResponse", Object, {
+myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._AjaxResponse", myfaces._impl.xhrCore._FinalizeableObj, {
/*partial response types*/
RESP_PARTIAL : "partial-response",
@@ -40,8 +40,10 @@ myfaces._impl.core._Runtime.extendClass(
P_VIEWHEAD: "javax.faces.ViewHead",
P_VIEWBODY: "javax.faces.ViewBody",
+
/**
* Constructor
+ * @param {function} base request classed parent object
* @param {function} onException
* @param {function} onWarning
*/
@@ -57,6 +59,7 @@ myfaces._impl.core._Runtime.extendClass(
this._Lang = myfaces._impl._util._Lang;
this._Dom = myfaces._impl._util._Dom;
+
},
/**
* uses response to start Html element replacement
@@ -71,6 +74,7 @@ myfaces._impl.core._Runtime.extendClass(
*
*/
processResponse : function(request, context) {
+
try {
var _Impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
@@ -178,7 +182,7 @@ myfaces._impl.core._Runtime.extendClass(
_appendViewStateElem: function(parent, viewStateVal) {
var element = document.createElement("div");
- element.innerHTML = "<input type='hidden' name='"+this.P_VIEWSTATE+"' value='"+viewStateVal+"' />";
+ element.innerHTML = "<input type='hidden' name='" + this.P_VIEWSTATE + "' value='" + viewStateVal + "' />";
//now we go to proper dom handling after having to deal with another ie screwup
parent.appendChild(element.childNodes[0]);
},
@@ -339,8 +343,7 @@ myfaces._impl.core._Runtime.extendClass(
//to fix up all elements effected by the cycle
}
- else
- {
+ else {
// response may contain several blocks
var cDataBlock = this._Dom.concatCDATABlocks(node);
@@ -381,16 +384,14 @@ myfaces._impl.core._Runtime.extendClass(
_pushOperationResult: function(resultNode) {
var pushSubnode = this._Lang.hitch(this, function(currNode) {
var parentForm = this._Dom.getParent(currNode, "form");
- if (null != parentForm)
- {
+ if (null != parentForm) {
this._updateForms.push(parentForm);
}
- else
- {
+ else {
this._updateElems.push(currNode);
}
});
- var isArr = resultNode instanceof Array;
+ var isArr = 'undefined' != typeof resultNode.length && 'undefined' == typeof resultNode.nodeType;
if (isArr && resultNode.length) {
for (var cnt = 0; cnt < resultNode.length; cnt++) {
pushSubnode(resultNode[cnt]);
@@ -646,8 +647,7 @@ myfaces._impl.core._Runtime.extendClass(
}
var parentForm = this._Dom.getParent(item, "form");
- if (null != parentForm)
- {
+ if (null != parentForm) {
this._updateForms.push(parentForm);
}
this._Dom.deleteItem(item);
@@ -715,6 +715,14 @@ myfaces._impl.core._Runtime.extendClass(
}
return true;
+ },
+ _finalize: function() {
+ delete this._onException;
+ delete this._onWarning;
+ delete this._updateElems;
+ // List of forms to be updated if any inner block is updated
+ delete this._updateForms;
+ delete this.appliedViewState;
}
});
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=985204&r1=985203&r2=985204&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 Aug 13 13:59:08 2010
@@ -14,14 +14,15 @@
* limitations under the License.
*/
/** @namespace myfaces._impl.xhrCore._AjaxUtils */
-myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._AjaxUtils", Object, {
+myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._AjaxUtils", myfaces._impl.xhrCore._FinalizeableObj, {
+ _processedExceptions: {},
+
/**
* Constructor
* @param {function} onException - exception handler
* @param {function} onWarning - warning handler
*/
constructor_ : function(onException, onWarning) {
-
this._onException = onException;
this._onWarning = onWarning;
},
@@ -223,5 +224,11 @@ myfaces._impl.core._Runtime.extendClass(
}
}
+ },
+
+ _finalize: function() {
+ delete this._onException;
+ delete this._onWarning;
}
+
});
\ No newline at end of file
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_BaseRequest.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_BaseRequest.js?rev=985204&r1=985203&r2=985204&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_BaseRequest.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_BaseRequest.js Fri Aug 13 13:59:08 2010
@@ -23,7 +23,7 @@
* Version: $Revision: 1.4 $ $Date: 2009/05/31 09:16:44 $
*/
/** @namespace myfaces._impl.xhrCore._AjaxRequest */
-myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._BaseRequest", Object, {
+myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._BaseRequest", myfaces._impl.xhrCore._FinalizeableObj, {
_Dom: myfaces._impl._util._Dom,
_Lang: myfaces._impl._util._Lang,
@@ -79,42 +79,17 @@ myfaces._impl.core._Runtime.extendClass(
_VAL_AJAX: "partial/ajax",
+
- /**
- * ie6 cleanup
- */
- _finalize: function() {
- if(!this._RT.browser.isIE) {
- //no ie, no broken garbage collector
- return;
- }
- var resultArr = [];
- for(var key in this) {
- if(key != "_finalize" && key != "callback" && key.indexOf("_") == 0) {
- resultArr.push(key);
- }
- }
- //ie has a problem with its gc it cannot cleanup
- //circular references between javascript and com
- //to the worse every xhr object is a com object
- //and some but not all inpucd Tcd cdt elements as well
- //i cannot fix all mem leaks but at least I can
- //reduce them , I cannot help with event handlers set
- //on dom elements replaced, but ie7 gcs them at least
- //during the window unload phase
- for(var cnt = 0; cnt < resultArr.length; cnt++) {
- if(this[resultArr[cnt]])
- delete this[resultArr[cnt]];
- }
-
- },
//abstract methods which have to be implemented
//since we do not have abstract methods we simulate them
//by using empty ones
constructor_: function() {
+ this._callSuper("constructor");
this._Lang = myfaces._impl._util._Lang;
this._Dom = myfaces._impl._util._Dom;
+ this._initDefaultFinalizableFields();
},
/**
@@ -148,4 +123,6 @@ myfaces._impl.core._Runtime.extendClass(
return ret;
}
+
+
});
\ No newline at end of file
Added: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_FinalizeableObj.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_FinalizeableObj.js?rev=985204&view=auto
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_FinalizeableObj.js (added)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_FinalizeableObj.js Fri Aug 13 13:59:08 2010
@@ -0,0 +1,64 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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.
+ */
+
+/**
+ * A helper object which supports IE with its non working garbage collection.
+ *
+ * See also:
+ *
+ * http://msdn.microsoft.com/en-us/library/bb250448%28VS.85%29.aspx
+ * http://weblogs.java.net/blog/driscoll/archive/2009/11/13/ie-memory-management-and-you
+ * http://home.orange.nl/jsrosman/
+ * http://www.quirksmode.org/blog/archives/2005/10/memory_leaks_li.html
+ * http://www.josh-davis.org/node/7
+ *
+ * Author: Werner Punz (latest modification by $Author: werpu $)
+ * Version: $Revision: 1.4 $ $Date: 2009/05/31 09:16:44 $
+ */
+myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._FinalizeableObj", Object, {
+
+ _resettableContent: null,
+
+ constructor_: function() {
+ this._resettableContent={};
+ },
+
+ _initDefaultFinalizableFields: function() {
+ for(var key in this) {
+ //per default we reset everything which is not preinitalized
+ if(null == this[key] && key != "_resettableContent" && key.indexOf("_mf") != 0 && key.indexOf("_") == 0) {
+ this._resettableContent[key]=true;
+ }
+ }
+ },
+
+ /**
+ * ie6 cleanup
+ */
+ _finalize: function() {
+ if (!myfaces._impl.core._Runtime.browser.isIE || !this._resettableContent) {
+ //no ie, no broken garbage collector
+ return;
+ }
+
+ for(var key in this._resettableContent) {
+ if (myfaces._impl.core._Runtime.exists(this[key],"_finalize")) {
+ this[key]._finalize();
+ }
+ delete this[key];
+ }
+ }
+});
\ No newline at end of file
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_IFrameRequest.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_IFrameRequest.js?rev=985204&r1=985203&r2=985204&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_IFrameRequest.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_IFrameRequest.js Fri Aug 13 13:59:08 2010
@@ -44,8 +44,13 @@ myfaces._impl.core._Runtime.extendClass(
constructor_: function(arguments) {
try {
//we fetch in the standard arguments
- this._callSuper("constructor",arguments);
+ this._callSuper("constructor", arguments);
this._Lang.applyArgs(this, arguments);
+
+ if (!this._response) {
+ this._response = new myfaces._impl.xhrCore._AjaxResponse(this._onException, this._onWarning);
+ }
+ this._ajaxUtil = new myfaces._impl.xhrCore._AjaxUtils(this._onException, this._onWarning);
} catch (e) {
//_onError
this._onException(null, this._context, this.CLS_NAME, "constructor", e);
@@ -74,10 +79,7 @@ myfaces._impl.core._Runtime.extendClass(
//ie has a bug, onload is not settable outside of innerHTML on iframes
this._frame.onload_IE = this._Lang.hitch(this, this.callback);
}
-
- if (!this._response) {
- this._response = new myfaces._impl.xhrCore._AjaxResponse(this._onException, this._onWarning);
- }
+
//now to the parameter passing:
_Impl.sendEvent(this._xhr, this._context, _Impl.BEGIN);
@@ -195,10 +197,9 @@ myfaces._impl.core._Runtime.extendClass(
}
var input = document.createElement("input");
//the dom is a singleton nothing can happen by remapping
- var setAttr = this._Dom.setAttribute;
- setAttr(input, "name", key);
- setAttr(input, "style", "display:none");
- setAttr(input, "value", value);
+ this._Dom.setAttribute(input, "name", key);
+ this._Dom.setAttribute(input, "style", "display:none");
+ this._Dom.setAttribute(input, "value", value);
this._sourceForm.appendChild(input);
},
@@ -215,7 +216,6 @@ myfaces._impl.core._Runtime.extendClass(
var frame = document.getElementById(this._FRAME_ID);
//normally this code should not be called
//but just to be sure
- var setAttr = this._Dom.setAttribute;
if (!frame) {
if (!_RT.browser.isIE) {
frame = document.createElement('iframe');
@@ -224,17 +224,17 @@ myfaces._impl.core._Runtime.extendClass(
//but this code is the safe bet it works on all standards
//compliant browsers in a clean manner
- setAttr(frame, "src", "about:blank");
- setAttr(frame, "id", this._FRAME_ID);
- setAttr(frame, "name", this._FRAME_ID);
- setAttr(frame, "type", "content");
- setAttr(frame, "collapsed", "true");
- setAttr(frame, "style", "display:none");
+ this._Dom.setAttribute(frame, "src", "about:blank");
+ this._Dom.setAttribute(frame, "id", this._FRAME_ID);
+ this._Dom.setAttribute(frame, "name", this._FRAME_ID);
+ this._Dom.setAttribute(frame, "type", "content");
+ this._Dom.setAttribute(frame, "collapsed", "true");
+ this._Dom.setAttribute(frame, "style", "display:none");
document.body.appendChild(frame);
} else { //Now to the non compliant browsers
var node = document.createElement("div");
- setAttr(node, "style", "display:none");
+ this._Dom.setAttribute(node, "style", "display:none");
//we are dealing with two well known iframe ie bugs here
//first the iframe has to be set via innerHTML to be present
//secondly the onload handler is immutable on ie, we have to
Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_Transports.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_Transports.js?rev=985204&r1=985203&r2=985204&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_Transports.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_Transports.js Fri Aug 13 13:59:08 2010
@@ -401,8 +401,15 @@ myfaces._impl.core._Runtime.extendClass(
*/
_stdErrorHandler: function(request, context, sourceClass, func, exception) {
this._loadImpl();
+ var _Lang = myfaces._impl._util._Lang;
+ var exProcessed = _Lang.isExceptionProcessed(exception);
try {
- if (this._threshold == "ERROR" && !exception._processed) {
+ //newer browsers do not allow to hold additional values on native objects like exceptions
+ //we hence capsule it into the request, which is gced automatically
+ //on ie as well, since the stdErrorHandler usually is called between requests
+ //this is a valid approach
+
+ if (this._threshold == "ERROR" && !exProcessed) {
this._Impl.sendError(request, context, this._Impl.CLIENT_ERROR, exception.name,
"MyFaces ERROR:" + this._Lang.createErrorMsg(sourceClass, func, exception));
}
@@ -410,7 +417,13 @@ myfaces._impl.core._Runtime.extendClass(
this._q.cleanup();
//we forward the exception, just in case so that the client
//will receive it in any way
- exception._processed = true;
+ try {
+ if(!exProcessed) {
+ _Lang.setExceptionProcessed(exception);
+ }
+ } catch(e) {
+
+ }
throw exception;
}
},