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 /** 19 * @class 20 * @name Xhr1 21 * @memberOf myfaces._impl.xhrCore.engine 22 * @extends myfaces._impl.xhrCore.engine.BaseRequest 23 * @description 24 * 25 * wrapper for an xhr level1 object with all its differences 26 * it emulates the xhr level2 api which is way simpler than the level1 api 27 */ 28 29 _MF_CLS(_PFX_XHR + "engine.Xhr1", myfaces._impl.xhrCore.engine.BaseRequest, /** @lends myfaces._impl.xhrCore.engine.Xhr1.prototype */ { 30 31 _xhrObject: null, 32 _timeoutTimer: null, 33 34 constructor_: function(params) { 35 //the constructor is empty due to the original xhr object not having anything 36 37 this._callSuper("constructor_", params); 38 this._initDefaultFinalizableFields(); 39 40 this._XHRConst = myfaces._impl.xhrCore.engine.XhrConst; 41 this._Lang.applyArgs(this, params); 42 }, 43 44 // void open(DOMString method, DOMString url, boolean async); 45 open: function(method, url, async) { 46 47 var xhr = this._xhrObject; 48 xhr.onreadystatechange = this._Lang.hitch(this, this.onreadystatechange); 49 this.method = method || this.method; 50 this.url = url || this.url; 51 this.async = ('undefined' != typeof async) ? async : this.async; 52 xhr.open(this.method, this.url, this.async); 53 }, 54 55 send: function(formData) { 56 57 var myevt = {}; 58 59 this._addProgressAttributes(myevt, 20, 100); 60 this.onloadstart(myevt); 61 this.onprogress(myevt); 62 this._startTimeout(); 63 this._xhrObject.send(formData); 64 }, 65 66 setRequestHeader: function(key, value) { 67 this._xhrObject.setRequestHeader(key, value); 68 }, 69 70 abort: function() { 71 72 this._xhrObject.abort(); 73 this.onabort({}); 74 }, 75 76 _addProgressAttributes: function(evt, percent, total) { 77 //http://www.w3.org/TR/progress-events/#progressevent 78 evt.lengthComputable = true; 79 evt.loaded = percent; 80 evt.total = total; 81 82 }, 83 84 onreadystatechange: function(evt) { 85 var myevt = evt || {}; 86 //we have to simulate the attributes as well 87 var xhr = this._xhrObject; 88 var XHRConst = this._XHRConst; 89 try { 90 this.readyState = xhr.readyState; 91 this.status = ""+xhr.status; 92 } catch(e) { 93 //IE 6 has an internal error 94 } 95 96 switch (this.readyState) { 97 98 case XHRConst.READY_STATE_OPENED: 99 this._addProgressAttributes(myevt, 10, 100); 100 101 this.onprogress(myevt); 102 break; 103 104 case XHRConst.READY_STATE_HEADERS_RECEIVED: 105 this._addProgressAttributes(myevt, 25, 100); 106 107 this.onprogress(myevt); 108 break; 109 110 case XHRConst.READY_STATE_LOADING: 111 if (this._loadingCalled) break; 112 this._loadingCalled = true; 113 this._addProgressAttributes(myevt, 50, 100); 114 115 this.onprogress(myevt); 116 break; 117 118 case XHRConst.READY_STATE_DONE: 119 this._addProgressAttributes(myevt, 100, 100); 120 //xhr level1 does not have timeout handler 121 if (this._timeoutTimer) { 122 //normally the timeout should not cause anything anymore 123 //but just to make sure 124 window.clearTimeout(this._timeoutTimer); 125 this._timeoutTimer = null; 126 } 127 this._transferRequestValues(); 128 this.onprogress(myevt); 129 try { 130 var status = xhr.status; 131 if (status >= XHRConst.STATUS_OK_MINOR && status < XHRConst.STATUS_OK_MAJOR) { 132 this.onload(myevt); 133 } else { 134 myevt.type = "error"; 135 this.onerror(myevt); 136 } 137 } finally { 138 //remove for xhr level2 support 139 this.onloadend(myevt); 140 } 141 } 142 }, 143 144 _transferRequestValues: function() { 145 //this._Lang.mixMaps(this, this._xhrObject, true, null, 146 // {responseText:1,responseXML:1,status:1,statusText:1,response:1}); 147 var UDEF = "undefined"; 148 var xhr = this._xhrObject; 149 150 this.responseText = (UDEF != typeof xhr.responseText)?xhr.responseText: null; 151 this.responseXML = (UDEF != typeof xhr.responseXML)?xhr.responseXML: null; 152 this.status = (UDEF != typeof xhr.status)?xhr.status: null; 153 this.statusText = (UDEF != typeof xhr.statusText)?xhr.statusText: null; 154 this.response = (UDEF != typeof xhr.response)?xhr.response: null; 155 }, 156 157 _startTimeout: function() { 158 if (this.timeout == 0) return; 159 160 var xhr = this._xhrObject; 161 //some browsers have timeouts in their xhr level 1.x objects implemented 162 //we leverage them whenever they exist 163 try { 164 if ('undefined' != typeof xhr.timeout) { 165 xhr.timeout = this.timeout; 166 xhr.ontimeout = this.ontimeout; 167 return; 168 } 169 } catch (e) { 170 //firefox 12 has a bug here 171 } 172 173 174 this._timeoutTimer = setTimeout(this._Lang.hitch(this, function() { 175 if (xhr.readyState != this._XHRConst.READY_STATE_DONE) { 176 177 xhr.onreadystatechange = function() { 178 }; 179 clearTimeout(this._timeoutTimer); 180 xhr.abort(); 181 this.ontimeout({}); 182 } 183 }), this.timeout); 184 }, 185 186 getXHRObject: function() { 187 return this._xhrObject; 188 } 189 190 191 });