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 * An implementation of an xhr request object 19 * with partial page submit functionality, and jsf 20 * ppr request and timeout handling capabilities 21 * 22 * Author: Ganesh Jung (latest modification by $Author: ganeshpuri $) 23 * Version: $Revision: 1.4 $ $Date: 2009/05/31 09:16:44 $ 24 */ 25 26 /** 27 * @class 28 * @name _AjaxRequest 29 * @memberOf myfaces._impl.xhrCore 30 * @extends myfaces._impl.xhrCore._BaseRequest 31 */ 32 myfaces._impl.core._Runtime.extendClass("myfaces._impl.xhrCore._AjaxRequest", myfaces._impl.xhrCore._BaseRequest, 33 /** myfaces._impl.xhrCore._AjaxRequest.prototype */ 34 { 35 /** 36 * Constructor 37 * <p /> 38 * note there is a load of common properties 39 * inherited by the base class which define the corner 40 * parameters and the general internal behavior 41 * like _onError etc... 42 * @param {Map} an arguments map which an override any of the given protected 43 * instance variables, by a simple name value pair combination 44 */ 45 constructor_: function(arguments) { 46 47 try { 48 this._callSuper("constructor", arguments); 49 /*namespace remapping for readability*/ 50 //we fetch in the standard arguments 51 //and apply them to our protected attributes 52 this._Lang.applyArgs(this, arguments); 53 54 //if our response handler is not set 55 if (!this._response) { 56 this._response = new myfaces._impl.xhrCore._AjaxResponse(this._onException, this._onWarning); 57 } 58 59 this._ajaxUtil = new myfaces._impl.xhrCore._AjaxUtils(this._onException, this._onWarning); 60 } catch (e) { 61 //_onError 62 this._onException(this._xhr, this._context, "myfaces._impl.xhrCore._AjaxRequest", "constructor", e); 63 } 64 }, 65 66 /** 67 * Sends an Ajax request 68 */ 69 send : function() { 70 try { 71 //we have to encode at send time, otherwise 72 //we pick up old viewstates 73 this._initRequestParams(); 74 this._startXHR(); 75 this._startTimeout(); 76 } catch (e) { 77 //_onError//_onError 78 this._onException(this._xhr, this._context, "myfaces._impl.xhrCore._AjaxRequest", "send", e); 79 } 80 }, 81 82 83 /** 84 * gets the ViewState including all now passed in sideconstraints 85 */ 86 _initRequestParams: function() { 87 this._requestParameters = this.getViewState(); 88 for (var key in this._passThrough) { 89 this._requestParameters.append(key, this._passThrough[key]); 90 } 91 }, 92 93 /** 94 * starts the asynchronous xhr request 95 */ 96 _startXHR: function() { 97 this._preCreateXHR(); 98 this._xhr = myfaces._impl.core._Runtime.getXHRObject(); 99 this._postCreateXHR(); 100 101 var targetURL; 102 if (typeof this._sourceForm.elements["javax.faces.encodedURL"] == 'undefined') { 103 targetURL = this._sourceForm.action; 104 } else { 105 targetURL = this._sourceForm.elements["javax.faces.encodedURL"].value; 106 } 107 108 this._xhr.open(this._ajaxType, targetURL + 109 ((this._ajaxType == "GET") ? "?" + this._requestParameters.makeFinal() : "") 110 , true); 111 112 var contentType = this._contentType; 113 if (this._encoding) { 114 contentType = contentType + "; charset:" + this._encoding; 115 } 116 117 this._xhr.setRequestHeader(this._CONTENT_TYPE, this._contentType); 118 this._xhr.setRequestHeader(this._HEAD_FACES_REQ, this._VAL_AJAX); 119 120 this._xhr.onreadystatechange = this._Lang.hitch(this, this.callback); 121 var _Impl = this._getImpl(); 122 _Impl.sendEvent(this._xhr, this._context, _Impl.BEGIN); 123 124 this._preSend(); 125 126 try { 127 this._xhr.send((this._ajaxType != "GET") ? this._requestParameters.makeFinal() : null); 128 } finally { 129 this._postSend(); 130 } 131 }, 132 133 134 135 /** 136 * starts the timeout 137 * which is able to terminate the xhr upfront early 138 */ 139 _startTimeout: function() { 140 if (this._timeout && this._onTimeout) { 141 var _req = this._xhr; 142 var _context = this._context; 143 if (this._timeoutId) { 144 window.clearTimeout(this._timeoutId); 145 this._timeoutId = null; 146 } 147 this._timeoutId = window.setTimeout( 148 //we unify the api, there must be always a request passed to the external function 149 //and always a context, no matter what 150 this._Lang.hitch(this, 151 function() { 152 //the hitch has to be done due to the setTimeout refocusing the scope of this 153 //to window 154 try { 155 _req.onreadystatechange = function() { 156 }; 157 158 //to avoid malformed whatever, we have 159 //the timeout covered already on the _onTimeout function 160 _req.abort(); 161 this._onTimeout(_req, _context); 162 } catch (e) { 163 alert(e); 164 } finally { 165 } 166 }) 167 , this._timeout); 168 } 169 }, 170 171 /** 172 * Callback method to process the Ajax response 173 * triggered by RequestQueue 174 */ 175 callback : function() { 176 177 try { 178 var _Impl = this._getImpl(); 179 180 if (this._xhr.readyState == this._READY_STATE_DONE) { 181 if (this._timeoutId) { 182 //normally the timeout should not cause anything anymore 183 //but just to make sure 184 window.clearTimeout(this._timeoutId); 185 this._timeoutId = null; 186 } 187 this._onDone(this); 188 if (this._xhr.status >= this._STATUS_OK_MINOR && this._xhr.status < this._STATUS_OK_MAJOR) { 189 this._onSuccess(); 190 } else { 191 this._onError(); 192 } 193 } 194 } catch (e) { 195 this._onException(this._xhr, this._context, "myfaces._impl.xhrCore._AjaxRequest", "callback", e); 196 } finally { 197 //final cleanup to terminate everything 198 this._Lang.clearExceptionProcessed(); 199 200 //this._context.source; 201 if (this._xhr.readyState == this._READY_STATE_DONE) { 202 this._callSuper("_finalize"); 203 } 204 205 } 206 }, 207 208 209 210 211 212 /* 213 * various lifecycle callbacks which can be used by differing AjaxRequest impls 214 * (namely level 1.5 (Mozilla XHR) and level 2 (html5 xhr) to run special initialisation code 215 **/ 216 _preCreateXHR : function() { 217 //called after the xhr object has been created 218 }, 219 220 _postCreateXHR : function() { 221 //called after the xhr object has been created 222 }, 223 _preSend : function() { 224 //called before the xhr object is sent 225 }, 226 _postSend : function() { 227 //called after the xhr object is sent for cleanup purposes 228 } 229 230 }); 231 232