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 evt.type = "error"; 135 this.onerror(myevt); 136 } 137 } finally { 138 this.onloadend(myevt); 139 } 140 } 141 }, 142 143 _transferRequestValues: function() { 144 this._Lang.mixMaps(this, this._xhrObject, true, null, 145 ["responseText","responseXML","status","statusText","response"]); 146 }, 147 148 _startTimeout: function() { 149 150 var xhr = this._xhrObject; 151 //some browsers have timeouts in their xhr level 1.x objects implemented 152 //we leverage them whenever they exist 153 if ('undefined' != typeof xhr.timeout) { 154 xhr.timeout = this.timeout; 155 xhr.ontimeout = this.ontimeout; 156 return; 157 } 158 159 if (this.timeout == 0) return; 160 this._timeoutTimer = setTimeout(this._Lang.hitch(this, function() { 161 if (xhr.readyState != this._XHRConst.READY_STATE_DONE) { 162 163 xhr.onreadystatechange = function() { 164 }; 165 clearTimeout(this._timeoutTimer); 166 xhr.abort(); 167 this.ontimeout({}); 168 } 169 }), this.timeout); 170 }, 171 172 getXHRObject: function() { 173 return this._xhrObject; 174 } 175 176 177 });