1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to you under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */ 16 17/**
18 * @class
19 * @name IFrame
20 * @memberOf myfaces._impl.xhrCore.engine
21 * @extends myfaces._impl.xhrCore.engine.BaseRequest
22 * @description
23 *
24 * wrapper for an iframe transport object with all its differences
25 * it emulates the xhr level2 api
26 */ 27_MF_CLS(_PFX_XHR+"engine.IFrame",myfaces._impl.xhrCore.engine.BaseRequest, 28/** @lends myfaces._impl.xhrCore.engine.IFrame.prototype */ 29{ 30 31 32 33/*the target frame responsible for the communication*/ 34_frame:null, 35_requestHeader:null, 36_aborted:false, 37 38 39CLS_NAME:"myfaces._impl.xhrCore._IFrameRequest", 40_FRAME_ID:"_mf_comm_frm", 41 42/**
43 * constructor which shifts the arguments
44 * to the protected properties of this clas
45 *
46 * @param arguments
47 */ 48constructor_:function(arguments){ 49//we fetch in the standard arguments 50 51this._callSuper("constructor",arguments); 52 53this._initDefaultFinalizableFields(); 54this._requestHeader={}; 55 56this._XHRConst=myfaces._impl.xhrCore.engine.XhrConst; 57 58this._Lang.applyArgs(this,arguments); 59this.readyState=this._XHRConst.READY_STATE_UNSENT; 60}, 61 62setRequestHeader:function(key,value){ 63this._requestHeader[key]=value; 64}, 65 66open:function(method,url,async){ 67 68this.readyState=this._XHRConst.READY_STATE_OPENED; 69 70var_RT=myfaces._impl.core._Runtime; 71var_Lang=this._Lang; 72 73this._frame=this._createTransportFrame(); 74 75//we append an onload handler to the frame 76//to cover the starting and loading events, 77//timeouts cannot be covered in a cross browser way 78 79//we point our onload handler to the frame, we do not use addOnLoad 80//because the frame should not have other onload handlers in place 81if(!_RT.browser.isIE||this._Dom.isDomCompliant()){ 82this._frame.onload=_Lang.hitch(this,this._callback); 83}else{ 84//ie has a bug, onload is not settable outside of innerHTML on iframes 85this._frame.onload_IE=_Lang.hitch(this,this._callback); 86} 87 88this.method=method||this.method; 89this.url=url||this.url; 90this.async=('undefined'!=typeofasync)?async:this.async; 91 92varmyevt={}; 93this._addProgressAttributes(myevt,10,100); 94this.onprogress(myevt); 95}, 96 97send:function(formData){ 98 99varmyevt={};100this._addProgressAttributes(myevt,20,100);101this.onloadstart(myevt);102this.onprogress(myevt);103104varformDataForm=formData.form,105oldTarget=formDataForm.target,106oldMethod=formDataForm.method,107oldAction=formDataForm.action;108109110try{111//_t._initAjaxParams();112for(varkeyinthis._requestHeader){113formData.append(key,this._requestHeader[key]);114}115116formDataForm.target=this._frame.name;117formDataForm.method=this.method;118if(this.url){119formDataForm.action=this.url;120}121this.readyState=this._XHRConst.READY_STATE_LOADING;122this.onreadystatechange(myevt);123formDataForm.submit();124}finally{125formDataForm.action=oldAction;126formDataForm.target=oldTarget;127formDataForm.method=oldMethod;128129formData._finalize();130}131},132133/*we can implement it, but it will work only on browsers
134 * which have asynchronous iframe loading*/135abort:function(){136this._aborted=true;137this.onabort({});138},139140_addProgressAttributes:function(evt,percent,total){141//http://www.w3.org/TR/progress-events/#progressevent142evt.lengthComputable=true;143evt.loaded=percent;144evt.total=total;145146},147148_callback:function(){149150//aborted no further processing151if(this._aborted)return;152try{153varmyevt={};154155this._addProgressAttributes(myevt,100,100);156this.readyState=this._XHRConst.READY_STATE_DONE;157this.onreadystatechange(myevt);158159this.responseText=this._getFrameText();160this.responseXML=this._getFrameXml();161this.readyState=this._READY_STATE_DONE;162163//TODO status and statusText164165this.onreadystatechange(myevt);166this.onloadend();167168if(!this._Lang.isXMLParseError(this.responseXML)){169this.status=201;170this.onload();171}else{172this.status=0;173//we simulate the request for our xhr call174this.onerror();175}176177}finally{178this._frame=null;179}180},181182/**
183 * returns the frame text in a browser independend manner
184 */185_getFrameDocument:function(){186187//we cover various browsers here, because almost all browsers keep the document in a different188//position189returnthis._frame.contentWindow.document||this._frame.contentDocument||this._frame.document;190},191192_getFrameText:function(){193varframedoc=this._getFrameDocument();194//also ie keeps the body in framedoc.body the rest in documentElement195varbody=framedoc.body||framedoc.documentElement;196returnbody.innerHTML;197},198199_clearFrame:function(){200201varframedoc=this._getFrameDocument();202varbody=framedoc.documentElement||framedoc.body;203//ie8 in 7 mode chokes on the innerHTML method204//direct dom removal is less flakey and works205//over all browsers, but is slower206if(myfaces._impl.core._Runtime.browser.isIE){207this._Dom._removeChildNodes(body,false);208}else{209body.innerHTML="";210}211},212213/**
214 * returns the processed xml from the frame
215 */216_getFrameXml:function(){217varframedoc=this._getFrameDocument();218//same situation here, the xml is hosted either in xmlDocument or219//is located directly under the frame document220returnframedoc.XMLDocument||framedoc;221},222223_createTransportFrame:function(){224225var_FRM_ID=this._FRAME_ID;226varframe=document.getElementById(_FRM_ID);227if(frame)returnframe;228//normally this code should not be called229//but just to be sure230231if(this._Dom.isDomCompliant()){232frame=this._Dom.createElement('iframe',{233"src":"about:blank",234"id":_FRM_ID,235"name":_FRM_ID,236"type":"content",237"collapsed":"true",238"style":"display:none"239});240241//probably the ie method would work on all browsers242//but this code is the safe bet it works on all standards243//compliant browsers in a clean manner244245document.body.appendChild(frame);246}else{//Now to the non compliant browsers247varnode=this._Dom.createElement("div",{248"style":"display:none"249});250251//we are dealing with two well known iframe ie bugs here252//first the iframe has to be set via innerHTML to be present253//secondly the onload handler is immutable on ie, we have to254//use a dummy onload handler in this case and call this one255//from the onload handler256node.innerHTML="<iframe id='"+_FRM_ID+"' name='"+_FRM_ID+"' style='display:none;' src='about:blank' type='content' onload='this.onload_IE();' ></iframe>";257258//avoid the ie open tag problem259varbody=document.body;260if(body.firstChild){261body.insertBefore(node,document.body.firstChild);262}else{263body.appendChild(node);264}265}266267//helps to for the onload handlers and innerhtml to be in sync again268returndocument.getElementById(_FRM_ID);269},270271_startTimeout:function(){272273if(this.timeout==0)return;274this._timeoutTimer=setTimeout(this._Lang.hitch(this,function(){275if(this._xhrObject.readyState!=this._XHRConst.READY_STATE_DONE){276277this._aborted=true;278clearTimeout(this._timeoutTimer);279//we cannot abort an iframe request280this.ontimeout({});281this._timeoutTimer=null;282}283}),this.timeout);284}285});286