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;
         }
     },