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/29 12:50:30 UTC

svn commit: r980396 - in /myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl: _util/_Dom.js _util/_Lang.js core/Impl.js core/_Runtime.js xhrCore/_IFrameRequest.js

Author: werpu
Date: Thu Jul 29 10:50:30 2010
New Revision: 980396

URL: http://svn.apache.org/viewvc?rev=980396&view=rev
Log:
https://issues.apache.org/jira/browse/MYFACES-2846
https://issues.apache.org/jira/browse/MYFACES-2845
https://issues.apache.org/jira/browse/MYFACES-2841

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/_util/_Lang.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js
    myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_IFrameRequest.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=980396&r1=980395&r2=980396&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 Thu Jul 29 10:50:30 2010
@@ -1268,6 +1268,21 @@ myfaces._impl.core._Runtime.singletonExt
 
     },
 
+    isMultipartCandidate: function(executes) {
+        if(this._Lang.isString(executes)) {
+            executes = this._Lang.strToArray(executes, "\\s+");
+        }
+
+        for(var exec in executes) {
+            var element = this.byId(executes[exec]);
+            var inputs = this.findByTagName(element, "input", true);
+            for(var key in inputs) {
+                if(this.getAttribute(inputs[key],"type") == "file") return true;
+            }
+        }
+        return false;
+    },
+
 
     byId: function(id) {
         return this._Lang.byId(id);

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=980396&r1=980395&r2=980396&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 Thu Jul 29 10:50:30 2010
@@ -179,7 +179,7 @@ myfaces._impl.core._Runtime.singletonDel
             throw Error("myfaces._impl._util._Lang.strToArray a splitter param must be provided which is either a tring or a regexp");
         }
         var retArr = it.split(splitter);
-        //var len = retArr.length;
+        var len = retArr.length;
         for (var cnt = 0; cnt < len; cnt++) {
             retArr[cnt] = this.trim(retArr[cnt]);
         }
@@ -304,6 +304,7 @@ myfaces._impl.core._Runtime.singletonDel
         var ret = {};
         var keyIdx = {};
         var key = null;
+        var _udef = "undefined";
         for (key in src) {
             /**
              *we always overwrite dest with source
@@ -316,15 +317,15 @@ myfaces._impl.core._Runtime.singletonDel
                  *on all values being non boolean, we would need an elvis
                  *operator in javascript to shorten this :-(
                  */
-                ret[key] = this.exists(dest, key) ? dest[key] : src[key];
+                ret[key] = (_udef != typeof dest[key]) ? dest[key] : src[key];
             } else {
-                ret[key] = this.exists(src, key) ? src[key] : dest[key];
+                ret[key] = (_udef != typeof src[key]) ? src[key] : dest[key];
             }
             keyIdx[key] = true;
         }
         for (key in dest) {
             /*if result.key does not exist we push in dest.key*/
-            ret[key] = this.exists(ret, key) ? ret[key] : dest[key];
+            ret[key] = (_udef != typeof ret[key]) ? ret[key] : dest[key];
         }
         return ret;
     }

Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js?rev=980396&r1=980395&r2=980396&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js Thu Jul 29 10:50:30 2010
@@ -119,6 +119,8 @@ myfaces._impl.core._Runtime.singletonExt
          *all the time
          **/
         var _Lang = myfaces._impl._util._Lang;
+        var _Dom = myfaces._impl._util._Dom;
+
         var elementId = null;
         /**
          * we cross reference statically hence the mapping here
@@ -136,7 +138,7 @@ myfaces._impl.core._Runtime.singletonExt
             //to get a fallback option in case the identifier is not determinable
             // anymore, in case of a framework induced detachment the element.name should
             // be shared if the identifier is not determinable anymore
-            elementId = elem.id || null;
+            elementId = elem.id || elem.name;
             if ((elementId == null || elementId == '') && elem.name) {
                 elementId = elem.name;
             }
@@ -169,21 +171,22 @@ myfaces._impl.core._Runtime.singletonExt
          * ajax pass through context with the source
          * onevent and onerror
          */
-        var context = {};
-        context.source = elem;
-        context.onevent = options.onevent;
-        context.onerror = options.onerror;
+        var context = {
+            source: elem,
+            onevent: options.onevent,
+            onerror: options.onerror
+        };
 
         /**
          * fetch the parent form
          */
 
-        var form = myfaces._impl._util._Dom.fuzzyFormDetection(elem);
+        var form = _Dom.fuzzyFormDetection(elem);
 
         var formErr = "Sourceform could not be determined, either because element is not attached to a form or we have multiple forms with named elements of the same identifier or name, stopping the ajax processing";
 
         if (!form && event) {
-            form = myfaces._impl._util._Dom.fuzzyFormDetection(_Lang.getEventTarget(event));
+            form = _Dom.fuzzyFormDetection(_Lang.getEventTarget(event));
             if (!form) {
                 throw Error(formErr);
             }
@@ -201,26 +204,25 @@ myfaces._impl.core._Runtime.singletonExt
          */
         passThrgh[this.P_AJAX] = true;
 
-        /**
-         * if execute or render exist
-         * we have to pass them down as a blank delimited string representation
-         * of an array of ids!
-         */
-        var exec, none, all, render = null;
-        if (passThrgh.execute) {
-            /*the options must be a blank delimited list of strings*/
-            exec = _Lang.arrToString(passThrgh.execute, ' ');
-            none = exec.indexOf(this.IDENT_NONE) != -1;
-            all = exec.indexOf(this.IDENT_ALL) != -1;
+
+        var _this = this;
+        var transformList = function(target, srcList) {
+            var opList = _Lang.arrToString(srcList, ' '),
+                    none = opList.indexOf(_this.IDENT_NONE) != -1,
+                    all = opList.indexOf(_this.IDENT_ALL) != -1;
             if (!none && !all) {
-                exec = exec.replace(this.IDENT_FORM, form.id);
-                exec = exec.replace(this.IDENT_THIS, elementId);
+                opList = opList.replace(_this.IDENT_FORM, form.id);
+                opList = opList.replace(_this.IDENT_THIS, elementId);
 
-                passThrgh[this.P_EXECUTE] = exec;
+                passThrgh[target] = opList;
             } else if (all) {
-                passThrgh[this.P_EXECUTE] = this.IDENT_ALL;
+                passThrgh[target] = _this.IDENT_ALL;
             }
+        };
 
+        if (passThrgh.execute) {
+            /*the options must be a blank delimited list of strings*/
+            transformList(this.P_EXECUTE, passThrgh.execute);
             passThrgh.execute = null;
             /*remap just in case we have a valid pointer to an existing object*/
             delete passThrgh.execute;
@@ -229,18 +231,8 @@ myfaces._impl.core._Runtime.singletonExt
         }
 
         if (passThrgh.render) {
-            render = _Lang.arrToString(passThrgh.render, ' ');
-            none = render.indexOf(this.IDENT_NONE) != -1;
-            all = render.indexOf(this.IDENT_ALL) != -1;
-            if (!none && !all) {
-                render = render.replace(this.IDENT_FORM, form.id);
-                render = render.replace(this.IDENT_THIS, elementId);
-                passThrgh[this.P_RENDER] = render;
-                passThrgh.render = null;
-            } else if (all) {
-                passThrgh[this.P_RENDER] = this.IDENT_ALL;
-
-            }
+            transformList(this.P_RENDER, passThrgh.render);
+            passThrgh.render = null;
             delete passThrgh.render;
         }
 
@@ -250,6 +242,20 @@ myfaces._impl.core._Runtime.singletonExt
             delete passThrgh.myfaces;
         }
 
+        var getConfig = myfaces._impl.core._Runtime.getLocalOrGlobalConfig;
+
+        /**
+         * if execute or render exist
+         * we have to pass them down as a blank delimited string representation
+         * of an array of ids!
+         */
+        //for now we turn off the transport auto selection, to enable 2.0 backwards compatibility
+        //on protocol level, the file upload only can be turned on if the auto selection is set to true
+        var transportAutoSelection = getConfig(context, "transportAutoSelection", false);
+        var isMultipart = (transportAutoSelection && _Dom.getAttribute(form,"enctype") == "multipart/form-data") ?
+                _Dom.isMultipartCandidate(passThrgh[this.P_EXECUTE]) :
+                false;
+
         /**
          * multiple transports upcoming jsf 2.1 feature currently allowed
          * default (no value) xhrQueuedPost
@@ -262,13 +268,20 @@ myfaces._impl.core._Runtime.singletonExt
          * iframeQueuedPost
          *
          */
-        var transportType = myfaces._impl.core._Runtime.getLocalOrGlobalConfig(context, "transportType", "xhrQueuedPost");
+
+        var transportType = (!isMultipart) ?
+                getConfig(context, "transportType", "xhrQueuedPost") :
+                getConfig(context, "transportType", "iframeQueuedPost");
+
         if (!this._transport[transportType]) {
             throw new Error("Transport type " + transportType + " does not exist");
         }
+
         this._transport[transportType](elem, form, context, passThrgh);
     },
 
+
+
     addOnError : function(/*function*/errorListener) {
         /*error handling already done in the assert of the queue*/
         this._errListeners.enqueue(errorListener);
@@ -322,7 +335,7 @@ myfaces._impl.core._Runtime.singletonExt
         }
 
         /**/
-        if (myfaces._impl._util._Lang.exists(context, "onerror")) {
+        if (context["onerror"]) {
             context.onerror(eventData);
         }
 
@@ -409,25 +422,20 @@ myfaces._impl.core._Runtime.singletonExt
         /* run through all script tags and try to find the one that includes jsf.js */
         var scriptTags = document.getElementsByTagName("script");
         var getConfig = myfaces._impl.core._Runtime.getGlobalConfig;
-        for (var i = 0; i < scriptTags.length; i++)
-        {
-            if (scriptTags[i].src.search(/\/javax\.faces\.resource\/jsf\.js.*ln=javax\.faces/) != -1)
-            {
+        for (var i = 0; i < scriptTags.length; i++) {
+            if (scriptTags[i].src.search(/\/javax\.faces\.resource\/jsf\.js.*ln=javax\.faces/) != -1) {
                 var result = scriptTags[i].src.match(/stage=([^&;]*)/);
-                if (result)
-                {
+                if (result) {
                     // we found stage=XXX
                     // return only valid values of ProjectStage
                     if (result[1] == "Production"
                             || result[1] == "Development"
                             || result[1] == "SystemTest"
-                            || result[1] == "UnitTest")
-                    {
+                            || result[1] == "UnitTest") {
                         return result[1];
                     }
                 }
-                else
-                {
+                else {
                     //we found the script, but there was no stage parameter -- Production
                     //(we also add an override here for testing purposes, the default, however is Production)
                     return getConfig("projectStage", "Production");

Modified: myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js?rev=980396&r1=980395&r2=980396&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js (original)
+++ myfaces/core/trunk/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/_Runtime.js Thu Jul 29 10:50:30 2010
@@ -289,8 +289,12 @@ if (!myfaces._impl.core._Runtime) {
          * @return either the config entry or if none is given the default value
          */
         this.getGlobalConfig = function(configName, defaultValue) {
-            /*use(myfaces._impl._util)*/
-            return (_this.exists(myfaces, "config") && _this.exists(myfaces.config, configName)) ?
+            /**
+             * note we could use exists but this is an heavy operation, since the config name usually
+             * given this function here is called very often
+            * is a single entry without . in between we can do the lighter shortcut
+            */
+            return (myfaces["config"] && 'undefined' !=  typeof myfaces.config[configName] ) ?
                     myfaces.config[configName]
                     :
                     defaultValue;
@@ -309,8 +313,17 @@ if (!myfaces._impl.core._Runtime) {
          */
         this.getLocalOrGlobalConfig = function(localOptions, configName, defaultValue) {
             /*use(myfaces._impl._util)*/
+            var _local =  !!localOptions;
+            var _localResult;
+            if(_local) {
+               //note we also do not use exist here due to performance improvement reasons
+               //not for now we loose the subnamespace capabilities but we do not use them anyway
+               //this code will give us a performance improvement of 2-3%
+               _localResult = (localOptions["myfaces"])?localOptions["myfaces"][configName] : undefined;
+               _local = 'undefined' != typeof _localResult;
+            }
 
-            return (!_this.exists(localOptions, "myfaces." + configName)) ? _this.getGlobalConfig(configName, defaultValue) : localOptions.myfaces[configName];
+            return (!_local) ? _this.getGlobalConfig(configName, defaultValue) : _localResult;
         };
 
         /**
@@ -577,7 +590,28 @@ if (!myfaces._impl.core._Runtime) {
 
                 newCls.prototype._callSuper = function(methodName) {
                     var passThrough = (arguments.length == 1) ? [] : Array.prototype.slice.call(arguments, 1);
-                    this._parentCls[methodName].apply(this, passThrough);
+
+                    //we store the descension level of each method under a mapped
+                    //name to avoid name clashes
+                    //to avoid name clashes with internal methods of array
+                    var _mappedName = ["_",methodName,"_mf_r"].join("");
+                    this._mfClsDescLvl = this._mfClsDescLvl || new Array();
+                    //we have to detect the descension level
+                    //we now check if we are in a super descension for the current method already
+                    //if not we are on this level
+                    var _oldDescLevel =  this._mfClsDescLvl[_mappedName] || this;
+                    //we now step one level down
+                    var _parentCls = _oldDescLevel._parentCls;
+
+
+                    try {
+                        //we now store the level position as new descension level for callSuper
+                        this._mfClsDescLvl[_mappedName] = _parentCls;
+                        //and call the code on this
+                        _parentCls[methodName].apply(this, passThrough);
+                    } finally {
+                        this._mfClsDescLvl[_mappedName] = _oldDescLevel;
+                    }
                 };
             }
 

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=980396&r1=980395&r2=980396&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 Thu Jul 29 10:50:30 2010
@@ -15,11 +15,16 @@
  */
 
 /**
- * Iframe request for communications over Iframes
+ * iframe request for communications over iframe
  *
  * This method can be used by older browsers and if you have
  * a multipart request which includes
  * a fileupload element, fileuploads cannot be handled by
+ * normal xhr requests. The standard html 4+ compliant way to do this
+ * is to use an iframe as submit target for a form.
+ *
+ * Note on almost all browsers this method induces a real asynchronity, the only
+ * exception is firefox 3.6- which blocks the ui, this is resolved in Firefox 4
  */
 myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._IFrameRequest", myfaces._impl.xhrCore._BaseRequest, {
 
@@ -48,25 +53,35 @@ myfaces._impl.core._Runtime.extendClass(
      */
     send: function() {
         var _Impl = myfaces._impl.core._Runtime.getGlobalConfig("jsfAjaxImpl", myfaces._impl.core.Impl);
+        var _RT = myfaces._impl.core._Runtime;
+
         this._frame = this._createTransportFrame();
+
         //we append an onload handler to the frame
         //to cover the starting and loading events,
         //timeouts cannot be covered in a cross browser way
 
-        //we point our onload handler to the frame
-        this._Lang.addOnLoad(this._frame, this._Lang.hitch(this, this.callback));
+        //we point our onload handler to the frame, we do not use addOnLoad
+        //because the frame should not have other onload handlers in place
+        if (!_RT.browser.isIE) {
+            this._frame.onload = this._Lang.hitch(this, this.callback);
+        } else {
+            //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, _Impl.BEGIN);
+        _Impl.sendEvent(this._xhr, this._context, _Impl.BEGIN);
 
         //viewstate should be in our parent form which we will isse we however have to add the execute and
         //render parameters as well as the usual javax.faces.request params to our target
 
         var oldTarget = this._sourceForm.target;
         var oldMethod = this._sourceForm.method;
+        var _progress = 0;
         try {
             this._initAjaxParams();
             this._sourceForm.target = this._frame.name;
@@ -86,14 +101,13 @@ myfaces._impl.core._Runtime.extendClass(
         //now we have to do the processing, for that we have to parse the result, if it is a http 404 then
         //nothing could be delivered and we bomb out with an error anything else has to be parsed
         //via our xml parser
-
         var request = {};
         try {
             //Derived from the YUI library, looking this up saved me some time
-            request.responseText = this._frame.contentWindow.document.body ? this._frame.contentWindow.document.body.innerHTML : this._frame.contentWindow.document.documentElement.textContent;
-            request.responseXML = this._frame.contentWindow.document.XMLDocument ? this._frame.contentWindow.document.XMLDocument : this._frame.contentWindow.document;
-
+            request.responseText = this._getFrameText();
+            request.responseXML = this._getFrameXml();
             request.readyState = this._READY_STATE_DONE;
+
             this._onDone(request, this._context);
 
             if (!this._Lang.isXMLParseError(request.responseXML)) {
@@ -107,11 +121,37 @@ myfaces._impl.core._Runtime.extendClass(
             //_onError
             this._onException(null, this._context, "myfaces._impl.xhrCore._IFrameRequest", "constructor", e);
         } finally {
-            this._frame.parentNode.removeChild(this._frame);
-            delete this._frame;
+            //this closes any hanging or pedning comm channel caused by the iframe
+            //this._frame.src = "about:blank";
+            this._setFrameText("");
+            this._frame = null;
         }
     },
 
+    /**
+     * returns the frame text in a browser independend manner
+     */
+    _getFrameText: function() {
+        return this._frame.contentWindow.document.body ? this._frame.contentWindow.document.body.innerHTML : this._frame.contentWindow.document.documentElement.textContent;
+    },
+
+    /**
+     * sets the frame text in a browser independend manner
+     *
+     * @param text to be set
+     */
+    _setFrameText: function(text) {
+        this._frame.contentWindow.document.body ? (this._frame.contentWindow.document.body.innerHTML = text) : (this._frame.contentWindow.document.documentElement.textContent = text);
+    },
+
+    /**
+     * returns the processed xml from the frame
+     */
+    _getFrameXml: function() {
+        return this._frame.contentWindow.document.XMLDocument ? this._frame.contentWindow.document.XMLDocument : this._frame.contentWindow.document;
+    },
+
+
     _initAjaxParams: function() {
         var _Impl = myfaces._impl.core.Impl;
         //this._appendHiddenValue(_Impl.P_AJAX, "");
@@ -119,6 +159,8 @@ myfaces._impl.core._Runtime.extendClass(
         for (var key in this._passThrough) {
             this._appendHiddenValue(key, this._passThrough[key]);
         }
+        //marker that this is an ajax iframe request
+        this._appendHiddenValue("javax.faces.partial.iframe", "true");
     },
 
     _removeAjaxParams: function(oldTarget) {
@@ -127,6 +169,7 @@ myfaces._impl.core._Runtime.extendClass(
         for (var key in this._passThrough) {
             this._removeHiddenValue(key);
         }
+        this._removeHiddenValue("javax.faces.partial.iframe");
     },
 
     _appendHiddenValue: function(key, value) {
@@ -149,35 +192,46 @@ myfaces._impl.core._Runtime.extendClass(
     },
 
     _createTransportFrame: function() {
+        var _RT = myfaces._impl.core._Runtime;
         var frame = document.getElementById(this._FRAME_ID);
         //normally this code should not be called
         //but just to be sure
-        if (frame) {
-            frame.parentNode.removeChild(frame);
-            delete frame;
-        }
-
-        frame = document.createElement('iframe');
-
-        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");
-
-        //security, we turn everything off
-        //we wont need it
-        if (frame.webNavigation) {
-            frame.webNavigation.allowAuth = false;
-            frame.webNavigation.allowImages = false;
-            frame.webNavigation.allowJavascript = false;
-            frame.webNavigation.allowMetaRedirects = false;
-            frame.webNavigation.allowPlugins = false;
-            frame.webNavigation.allowSubframes = false;
+        if (!frame) {
+            if (!_RT.browser.isIE) {
+                frame = document.createElement('iframe');
+
+                //probably the ie method would work on all browsers
+                //but this code is the safe bet it works on all standards
+                //compliant browsers in a clean manner
+                var setAttr = this._Dom.setAttribute;
+                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");
+
+                document.body.appendChild(frame);
+            } else { //Now to the non compliant browsers
+                var node = document.createElement("div");
+                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
+                //use a dummy onload handler in this case and call that one
+                //from the onload handler
+                node.innerHTML = "<iframe id='" + this._FRAME_ID + "' name='" + this._FRAME_ID + "' style='display:none;' src='about:blank' type='content' onload='this.onload_IE();'  ></iframe>";
+                //avoid the ie open tag problem
+                if (document.body.firstChild) {
+                    document.body.insertBefore(node, document.body.firstChild);
+                } else {
+                    document.body.appendChild(node);
+                }
+            }
         }
-        document.body.appendChild(frame);
-        return frame;
+        //helps to for the onload handlers and innerhtml to be in sync again
+        return document.getElementById(this._FRAME_ID);
+
     }
 
     //TODO pps, the idea behind pps is to generate another form