Automatic installer.php lang files by installer_builder (20070726)
[moodle-linuxchix.git] / lib / yui / connection / connection-debug.js
blob78cda4a855c3bdd63815bfeb23ec7f2d3a3a08d4
1 /*
2 Copyright (c) 2006, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
5 version: 0.12.2
6 */
7 /**
8  * The Connection Manager provides a simplified interface to the XMLHttpRequest
9  * object.  It handles cross-browser instantiantion of XMLHttpRequest, negotiates the
10  * interactive states and server response, returning the results to a pre-defined
11  * callback you create.
12  *
13  * @namespace YAHOO.util
14  * @module connection
15  * @requires yahoo
16  */
18 /**
19  * The Connection Manager singleton provides methods for creating and managing
20  * asynchronous transactions.
21  *
22  * @class Connect
23  */
25 YAHOO.util.Connect =
27   /**
28    * @description Array of MSFT ActiveX ids for XMLHttpRequest.
29    * @property _msxml_progid
30    * @private
31    * @static
32    * @type array
33    */
34         _msxml_progid:[
35                 'MSXML2.XMLHTTP.3.0',
36                 'MSXML2.XMLHTTP',
37                 'Microsoft.XMLHTTP'
38                 ],
40   /**
41    * @description Object literal of HTTP header(s)
42    * @property _http_header
43    * @private
44    * @static
45    * @type object
46    */
47         _http_header:{},
49   /**
50    * @description Determines if HTTP headers are set.
51    * @property _has_http_headers
52    * @private
53    * @static
54    * @type boolean
55    */
56         _has_http_headers:false,
58  /**
59   * @description Determines if a default header of
60   * Content-Type of 'application/x-www-form-urlencoded'
61   * will be added to any client HTTP headers sent for POST
62   * transactions.
63   * @property _use_default_post_header
64   * @private
65   * @static
66   * @type boolean
67   */
68     _use_default_post_header:true,
70  /**
71   * @description Determines if a default header of
72   * Content-Type of 'application/x-www-form-urlencoded'
73   * will be added to any client HTTP headers sent for POST
74   * transactions.
75   * @property _default_post_header
76   * @private
77   * @static
78   * @type boolean
79   */
80     _default_post_header:'application/x-www-form-urlencoded',
82  /**
83   * @description Property modified by setForm() to determine if the data
84   * should be submitted as an HTML form.
85   * @property _isFormSubmit
86   * @private
87   * @static
88   * @type boolean
89   */
90     _isFormSubmit:false,
92  /**
93   * @description Property modified by setForm() to determine if a file(s)
94   * upload is expected.
95   * @property _isFileUpload
96   * @private
97   * @static
98   * @type boolean
99   */
100     _isFileUpload:false,
102  /**
103   * @description Property modified by setForm() to set a reference to the HTML
104   * form node if the desired action is file upload.
105   * @property _formNode
106   * @private
107   * @static
108   * @type object
109   */
110     _formNode:null,
112  /**
113   * @description Property modified by setForm() to set the HTML form data
114   * for each transaction.
115   * @property _sFormData
116   * @private
117   * @static
118   * @type string
119   */
120     _sFormData:null,
122  /**
123   * @description Collection of polling references to the polling mechanism in handleReadyState.
124   * @property _poll
125   * @private
126   * @static
127   * @type object
128   */
129     _poll:{},
131  /**
132   * @description Queue of timeout values for each transaction callback with a defined timeout value.
133   * @property _timeOut
134   * @private
135   * @static
136   * @type object
137   */
138     _timeOut:{},
140   /**
141    * @description The polling frequency, in milliseconds, for HandleReadyState.
142    * when attempting to determine a transaction's XHR readyState.
143    * The default is 50 milliseconds.
144    * @property _polling_interval
145    * @private
146    * @static
147    * @type int
148    */
149      _polling_interval:50,
151   /**
152    * @description A transaction counter that increments the transaction id for each transaction.
153    * @property _transaction_id
154    * @private
155    * @static
156    * @type int
157    */
158      _transaction_id:0,
160   /**
161    * @description Member to add an ActiveX id to the existing xml_progid array.
162    * In the event(unlikely) a new ActiveX id is introduced, it can be added
163    * without internal code modifications.
164    * @method setProgId
165    * @public
166    * @static
167    * @param {string} id The ActiveX id to be added to initialize the XHR object.
168    * @return void
169    */
170         setProgId:function(id)
171         {
172                 this._msxml_progid.unshift(id);
173                 YAHOO.log('ActiveX Program Id  ' + id + ' added to _msxml_progid.', 'info', 'Connection');
174         },
176   /**
177    * @description Member to enable or disable the default POST header.
178    * @method setDefaultPostHeader
179    * @public
180    * @static
181    * @param {boolean} b Set and use default header - true or false .
182    * @return void
183    */
184         setDefaultPostHeader:function(b)
185         {
186                 this._use_default_post_header = b;
187                 YAHOO.log('Use default POST header set to  ' + b, 'info', 'Connection');
188         },
190   /**
191    * @description Member to modify the default polling interval.
192    * @method setPollingInterval
193    * @public
194    * @static
195    * @param {int} i The polling interval in milliseconds.
196    * @return void
197    */
198         setPollingInterval:function(i)
199         {
200                 if(typeof i == 'number' && isFinite(i)){
201                         this._polling_interval = i;
202                         YAHOO.log('Default polling interval set to ' + i +'ms', 'info', 'Connection');
203                 }
204         },
206   /**
207    * @description Instantiates a XMLHttpRequest object and returns an object with two properties:
208    * the XMLHttpRequest instance and the transaction id.
209    * @method createXhrObject
210    * @private
211    * @static
212    * @param {int} transactionId Property containing the transaction id for this transaction.
213    * @return object
214    */
215         createXhrObject:function(transactionId)
216         {
217                 var obj,http;
218                 try
219                 {
220                         // Instantiates XMLHttpRequest in non-IE browsers and assigns to http.
221                         http = new XMLHttpRequest();
222                         //  Object literal with http and tId properties
223                         obj = { conn:http, tId:transactionId };
224                         YAHOO.log('XHR object created for transaction ' + transactionId, 'info', 'Connection');
225                 }
226                 catch(e)
227                 {
228                         for(var i=0; i<this._msxml_progid.length; ++i){
229                                 try
230                                 {
231                                         // Instantiates XMLHttpRequest for IE and assign to http.
232                                         http = new ActiveXObject(this._msxml_progid[i]);
233                                         //  Object literal with conn and tId properties
234                                         obj = { conn:http, tId:transactionId };
235                                         YAHOO.log('ActiveX XHR object created for transaction ' + transactionId, 'info', 'Connection');
236                                         break;
237                                 }
238                                 catch(e){}
239                         }
240                 }
241                 finally
242                 {
243                         return obj;
244                 }
245         },
247   /**
248    * @description This method is called by asyncRequest to create a
249    * valid connection object for the transaction.  It also passes a
250    * transaction id and increments the transaction id counter.
251    * @method getConnectionObject
252    * @private
253    * @static
254    * @return {object}
255    */
256         getConnectionObject:function()
257         {
258                 var o;
259                 var tId = this._transaction_id;
261                 try
262                 {
263                         o = this.createXhrObject(tId);
264                         if(o){
265                                 this._transaction_id++;
266                         }
267                 }
268                 catch(e){}
269                 finally
270                 {
271                         return o;
272                 }
273         },
275   /**
276    * @description Method for initiating an asynchronous request via the XHR object.
277    * @method asyncRequest
278    * @public
279    * @static
280    * @param {string} method HTTP transaction method
281    * @param {string} uri Fully qualified path of resource
282    * @param {callback} callback User-defined callback function or object
283    * @param {string} postData POST body
284    * @return {object} Returns the connection object
285    */
286         asyncRequest:function(method, uri, callback, postData)
287         {
288                 var o = this.getConnectionObject();
290                 if(!o){
291                         YAHOO.log('Unable to create connection object.', 'error', 'Connection');
292                         return null;
293                 }
294                 else{
295                         if(this._isFormSubmit){
296                                 if(this._isFileUpload){
297                                         this.uploadFile(o.tId, callback, uri, postData);
298                                         this.releaseObject(o);
300                                         return;
301                                 }
303                                 //If the specified HTTP method is GET, setForm() will return an
304                                 //encoded string that is concatenated to the uri to
305                                 //create a querystring.
306                                 if(method == 'GET'){
307                                         if(this._sFormData.length != 0){
308                                                 // If the URI already contains a querystring, append an ampersand
309                                                 // and then concatenate _sFormData to the URI.
310                                                 uri += ((uri.indexOf('?') == -1)?'?':'&') + this._sFormData;
311                                         }
312                                         else{
313                                                 uri += "?" + this._sFormData;
314                                         }
315                                 }
316                                 else if(method == 'POST'){
317                                         //If POST data exist in addition to the HTML form data,
318                                         //it will be concatenated to the form data.
319                                         postData = postData?this._sFormData + "&" + postData:this._sFormData;
320                                 }
321                         }
323                         o.conn.open(method, uri, true);
325                         if(this._isFormSubmit || (postData && this._use_default_post_header)){
326                                 this.initHeader('Content-Type', this._default_post_header);
327                                 YAHOO.log('Initialize default header Content-Type to application/x-www-form-urlencoded.', 'info', 'Connection');
328                                 if(this._isFormSubmit){
329                                         this.resetFormState();
330                                 }
331                         }
333                         if(this._has_http_headers){
334                                 this.setHeader(o);
335                         }
337                         this.handleReadyState(o, callback);
338                         o.conn.send(postData || null);
340                         return o;
341                 }
342         },
344   /**
345    * @description This method serves as a timer that polls the XHR object's readyState
346    * property during a transaction, instead of binding a callback to the
347    * onreadystatechange event.  Upon readyState 4, handleTransactionResponse
348    * will process the response, and the timer will be cleared.
349    * @method handleReadyState
350    * @private
351    * @static
352    * @param {object} o The connection object
353    * @param {callback} callback The user-defined callback object
354    * @return {void}
355    */
356     handleReadyState:function(o, callback)
357     {
358                 var oConn = this;
360                 if(callback && callback.timeout){
361                         this._timeOut[o.tId] = window.setTimeout(function(){ oConn.abort(o, callback, true); }, callback.timeout);
362                 }
364                 this._poll[o.tId] = window.setInterval(
365                         function(){
366                                 if(o.conn && o.conn.readyState == 4){
367                                         window.clearInterval(oConn._poll[o.tId]);
368                                         delete oConn._poll[o.tId];
370                                         if(callback && callback.timeout){
371                                                 delete oConn._timeOut[o.tId];
372                                         }
374                                         oConn.handleTransactionResponse(o, callback);
375                                 }
376                         }
377                 ,this._polling_interval);
378     },
380   /**
381    * @description This method attempts to interpret the server response and
382    * determine whether the transaction was successful, or if an error or
383    * exception was encountered.
384    * @method handleTransactionResponse
385    * @private
386    * @static
387    * @param {object} o The connection object
388    * @param {object} callback The sser-defined callback object
389    * @param {boolean} isAbort Determines if the transaction was aborted.
390    * @return {void}
391    */
392     handleTransactionResponse:function(o, callback, isAbort)
393     {
394                 // If no valid callback is provided, then do not process any callback handling.
395                 if(!callback){
396                         this.releaseObject(o);
397                         YAHOO.log('No callback object to process. Transaction complete.', 'warn', 'Connection');
398                         return;
399                 }
401                 var httpStatus, responseObject;
403                 try
404                 {
405                         if(o.conn.status !== undefined && o.conn.status != 0){
406                                 httpStatus = o.conn.status;
407                         }
408                         else{
409                                 httpStatus = 13030;
410                         }
411                 }
412                 catch(e){
413                         // 13030 is the custom code to indicate the condition -- in Mozilla/FF --
414                         // when the o object's status and statusText properties are
415                         // unavailable, and a query attempt throws an exception.
416                         httpStatus = 13030;
417                 }
419                 if(httpStatus >= 200 && httpStatus < 300){
420                         responseObject = this.createResponseObject(o, callback.argument);
421                         if(callback.success){
422                                 if(!callback.scope){
423                                         callback.success(responseObject);
424                                         YAHOO.log('Success callback. HTTP code is ' + httpStatus, 'info', 'Connection');
425                                 }
426                                 else{
427                                         // If a scope property is defined, the callback will be fired from
428                                         // the context of the object.
429                                         callback.success.apply(callback.scope, [responseObject]);
430                                         YAHOO.log('Success callback with scope. HTTP code is ' + httpStatus, 'info', 'Connection');
431                                 }
432                         }
433                 }
434                 else{
435                         switch(httpStatus){
436                                 // The following cases are wininet.dll error codes that may be encountered.
437                                 case 12002: // Server timeout
438                                 case 12029: // 12029 to 12031 correspond to dropped connections.
439                                 case 12030:
440                                 case 12031:
441                                 case 12152: // Connection closed by server.
442                                 case 13030: // See above comments for variable status.
443                                         responseObject = this.createExceptionObject(o.tId, callback.argument, (isAbort?isAbort:false));
444                                         if(callback.failure){
445                                                 if(!callback.scope){
446                                                         callback.failure(responseObject);
447                                                         YAHOO.log('Failure callback. Exception detected. Status code is ' + httpStatus, 'warn', 'Connection');
448                                                 }
449                                                 else{
450                                                         callback.failure.apply(callback.scope, [responseObject]);
451                                                         YAHOO.log('Failure callback with scope. Exception detected. Status code is ' + httpStatus, 'warn', 'Connection');
452                                                 }
453                                         }
454                                         break;
455                                 default:
456                                         responseObject = this.createResponseObject(o, callback.argument);
457                                         if(callback.failure){
458                                                 if(!callback.scope){
459                                                         callback.failure(responseObject);
460                                                         YAHOO.log('Failure callback. HTTP status code is ' + httpStatus, 'warn', 'Connection');
461                                                 }
462                                                 else{
463                                                         callback.failure.apply(callback.scope, [responseObject]);
464                                                         YAHOO.log('Failure callback with scope. HTTP status code is ' + httpStatus, 'warn', 'Connection');
465                                                 }
466                                         }
467                         }
468                 }
470                 this.releaseObject(o);
471                 responseObject = null;
472     },
474   /**
475    * @description This method evaluates the server response, creates and returns the results via
476    * its properties.  Success and failure cases will differ in the response
477    * object's property values.
478    * @method createResponseObject
479    * @private
480    * @static
481    * @param {object} o The connection object
482    * @param {callbackArg} callbackArg The user-defined argument or arguments to be passed to the callback
483    * @return {object}
484    */
485     createResponseObject:function(o, callbackArg)
486     {
487                 var obj = {};
488                 var headerObj = {};
490                 try
491                 {
492                         var headerStr = o.conn.getAllResponseHeaders();
493                         var header = headerStr.split('\n');
494                         for(var i=0; i<header.length; i++){
495                                 var delimitPos = header[i].indexOf(':');
496                                 if(delimitPos != -1){
497                                         headerObj[header[i].substring(0,delimitPos)] = header[i].substring(delimitPos+2);
498                                 }
499                         }
500                 }
501                 catch(e){}
503                 obj.tId = o.tId;
504                 obj.status = o.conn.status;
505                 obj.statusText = o.conn.statusText;
506                 obj.getResponseHeader = headerObj;
507                 obj.getAllResponseHeaders = headerStr;
508                 obj.responseText = o.conn.responseText;
509                 obj.responseXML = o.conn.responseXML;
511                 if(typeof callbackArg !== undefined){
512                         obj.argument = callbackArg;
513                 }
515                 return obj;
516     },
518   /**
519    * @description If a transaction cannot be completed due to dropped or closed connections,
520    * there may be not be enough information to build a full response object.
521    * The failure callback will be fired and this specific condition can be identified
522    * by a status property value of 0.
523    *
524    * If an abort was successful, the status property will report a value of -1.
525    *
526    * @method createExceptionObject
527    * @private
528    * @static
529    * @param {int} tId The Transaction Id
530    * @param {callbackArg} callbackArg The user-defined argument or arguments to be passed to the callback
531    * @param {boolean} isAbort Determines if the exception case is caused by a transaction abort
532    * @return {object}
533    */
534     createExceptionObject:function(tId, callbackArg, isAbort)
535     {
536                 var COMM_CODE = 0;
537                 var COMM_ERROR = 'communication failure';
538                 var ABORT_CODE = -1;
539                 var ABORT_ERROR = 'transaction aborted';
541                 var obj = {};
543                 obj.tId = tId;
544                 if(isAbort){
545                         obj.status = ABORT_CODE;
546                         obj.statusText = ABORT_ERROR;
547                 }
548                 else{
549                         obj.status = COMM_CODE;
550                         obj.statusText = COMM_ERROR;
551                 }
553                 if(callbackArg){
554                         obj.argument = callbackArg;
555                 }
557                 return obj;
558     },
560   /**
561    * @description Public method that stores the custom HTTP headers for each transaction.
562    * @method initHeader
563    * @public
564    * @static
565    * @param {string} label The HTTP header label
566    * @param {string} value The HTTP header value
567    * @return {void}
568    */
569         initHeader:function(label,value)
570         {
571                 if(this._http_header[label] === undefined){
572                         this._http_header[label] = value;
573                 }
574                 else{
575                         // Concatenate multiple values, comma-delimited,
576                         // for the same header label,
577                         this._http_header[label] =  value + "," + this._http_header[label];
578                 }
580                 this._has_http_headers = true;
581         },
583   /**
584    * @description Accessor that sets the HTTP headers for each transaction.
585    * @method setHeader
586    * @private
587    * @static
588    * @param {object} o The connection object for the transaction.
589    * @return {void}
590    */
591         setHeader:function(o)
592         {
593                 for(var prop in this._http_header){
594                         if(this._http_header.hasOwnProperty(prop)){
595                                 o.conn.setRequestHeader(prop, this._http_header[prop]);
596                                 YAHOO.log('HTTP header ' + prop + ' set with value of ' + this._http_header[prop], 'info', 'Connection');
597                         }
598                 }
599                 delete this._http_header;
601                 this._http_header = {};
602                 this._has_http_headers = false;
603         },
605   /**
606    * @description This method assembles the form label and value pairs and
607    * constructs an encoded string.
608    * asyncRequest() will automatically initialize the
609    * transaction with a HTTP header Content-Type of
610    * application/x-www-form-urlencoded.
611    * @method setForm
612    * @public
613    * @static
614    * @param {string || object} form id or name attribute, or form object.
615    * @param {string} optional boolean to indicate SSL environment.
616    * @param {string || boolean} optional qualified path of iframe resource for SSL in IE.
617    * @return {string} string of the HTML form field name and value pairs..
618    */
619         setForm:function(formId, isUpload, secureUri)
620         {
621                 this.resetFormState();
622                 var oForm;
623                 if(typeof formId == 'string'){
624                         // Determine if the argument is a form id or a form name.
625                         // Note form name usage is deprecated by supported
626                         // here for legacy reasons.
627                         oForm = (document.getElementById(formId) || document.forms[formId]);
628                 }
629                 else if(typeof formId == 'object'){
630                         // Treat argument as an HTML form object.
631                         oForm = formId;
632                 }
633                 else{
634                         YAHOO.log('Unable to create form object ' + formId, 'warn', 'Connection');
635                         return;
636                 }
638                 // If the isUpload argument is true, setForm will call createFrame to initialize
639                 // an iframe as the form target.
640                 //
641                 // The argument secureURI is also required by IE in SSL environments
642                 // where the secureURI string is a fully qualified HTTP path, used to set the source
643                 // of the iframe, to a stub resource in the same domain.
644                 if(isUpload){
646                         // Create iframe in preparation for file upload.
647                         this.createFrame(secureUri?secureUri:null);
649                         // Set form reference and file upload properties to true.
650                         this._isFormSubmit = true;
651                         this._isFileUpload = true;
652                         this._formNode = oForm;
654                         return;
655                 }
657                 var oElement, oName, oValue, oDisabled;
658                 var hasSubmit = false;
660                 // Iterate over the form elements collection to construct the
661                 // label-value pairs.
662                 for (var i=0; i<oForm.elements.length; i++){
663                         oElement = oForm.elements[i];
664                         oDisabled = oForm.elements[i].disabled;
665                         oName = oForm.elements[i].name;
666                         oValue = oForm.elements[i].value;
668                         // Do not submit fields that are disabled or
669                         // do not have a name attribute value.
670                         if(!oDisabled && oName)
671                         {
672                                 switch (oElement.type)
673                                 {
674                                         case 'select-one':
675                                         case 'select-multiple':
676                                                 for(var j=0; j<oElement.options.length; j++){
677                                                         if(oElement.options[j].selected){
678                                                                 if(window.ActiveXObject){
679                                                                         this._sFormData += encodeURIComponent(oName) + '=' + encodeURIComponent(oElement.options[j].attributes['value'].specified?oElement.options[j].value:oElement.options[j].text) + '&';
680                                                                 }
681                                                                 else{
682                                                                         this._sFormData += encodeURIComponent(oName) + '=' + encodeURIComponent(oElement.options[j].hasAttribute('value')?oElement.options[j].value:oElement.options[j].text) + '&';
683                                                                 }
685                                                         }
686                                                 }
687                                                 break;
688                                         case 'radio':
689                                         case 'checkbox':
690                                                 if(oElement.checked){
691                                                         this._sFormData += encodeURIComponent(oName) + '=' + encodeURIComponent(oValue) + '&';
692                                                 }
693                                                 break;
694                                         case 'file':
695                                                 // stub case as XMLHttpRequest will only send the file path as a string.
696                                         case undefined:
697                                                 // stub case for fieldset element which returns undefined.
698                                         case 'reset':
699                                                 // stub case for input type reset button.
700                                         case 'button':
701                                                 // stub case for input type button elements.
702                                                 break;
703                                         case 'submit':
704                                                 if(hasSubmit == false){
705                                                         this._sFormData += encodeURIComponent(oName) + '=' + encodeURIComponent(oValue) + '&';
706                                                         hasSubmit = true;
707                                                 }
708                                                 break;
709                                         default:
710                                                 this._sFormData += encodeURIComponent(oName) + '=' + encodeURIComponent(oValue) + '&';
711                                                 break;
712                                 }
713                         }
714                 }
716                 this._isFormSubmit = true;
717                 this._sFormData = this._sFormData.substr(0, this._sFormData.length - 1);
719                 YAHOO.log('Form initialized for transaction. HTML form POST message is: ' + this._sFormData, 'info', 'Connection');
721                 return this._sFormData;
722         },
724   /**
725    * @description Resets HTML form properties when an HTML form or HTML form
726    * with file upload transaction is sent.
727    * @method resetFormState
728    * @private
729    * @static
730    * @return {void}
731    */
732         resetFormState:function(){
733                 this._isFormSubmit = false;
734                 this._isFileUpload = false;
735                 this._formNode = null;
736                 this._sFormData = "";
737         },
739   /**
740    * @description Creates an iframe to be used for form file uploads.  It is remove from the
741    * document upon completion of the upload transaction.
742    * @method createFrame
743    * @private
744    * @static
745    * @param {string} optional qualified path of iframe resource for SSL in IE.
746    * @return {void}
747    */
748         createFrame:function(secureUri){
750                 // IE does not allow the setting of id and name attributes as object
751                 // properties via createElement().  A different iframe creation
752                 // pattern is required for IE.
753                 var frameId = 'yuiIO' + this._transaction_id;
754                 if(window.ActiveXObject){
755                         var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
757                         // IE will throw a security exception in an SSL environment if the
758                         // iframe source is undefined.
759                         if(typeof secureUri == 'boolean'){
760                                 io.src = 'javascript:false';
761                         }
762                         else if(typeof secureURI == 'string'){
763                                 // Deprecated
764                                 io.src = secureUri;
765                         }
766                 }
767                 else{
768                         var io = document.createElement('iframe');
769                         io.id = frameId;
770                         io.name = frameId;
771                 }
773                 io.style.position = 'absolute';
774                 io.style.top = '-1000px';
775                 io.style.left = '-1000px';
777                 document.body.appendChild(io);
778                 YAHOO.log('File upload iframe created. Id is:' + frameId, 'info', 'Connection');
779         },
781   /**
782    * @description Parses the POST data and creates hidden form elements
783    * for each key-value, and appends them to the HTML form object.
784    * @method appendPostData
785    * @private
786    * @static
787    * @param {string} postData The HTTP POST data
788    * @return {array} formElements Collection of hidden fields.
789    */
790         appendPostData:function(postData)
791         {
792                 var formElements = [];
793                 var postMessage = postData.split('&');
794                 for(var i=0; i < postMessage.length; i++){
795                         var delimitPos = postMessage[i].indexOf('=');
796                         if(delimitPos != -1){
797                                 formElements[i] = document.createElement('input');
798                                 formElements[i].type = 'hidden';
799                                 formElements[i].name = postMessage[i].substring(0,delimitPos);
800                                 formElements[i].value = postMessage[i].substring(delimitPos+1);
801                                 this._formNode.appendChild(formElements[i]);
802                         }
803                 }
805                 return formElements;
806         },
808   /**
809    * @description Uploads HTML form, including files/attachments, to the
810    * iframe created in createFrame.
811    * @method uploadFile
812    * @private
813    * @static
814    * @param {int} id The transaction id.
815    * @param {object} callback - User-defined callback object.
816    * @param {string} uri Fully qualified path of resource.
817    * @return {void}
818    */
819         uploadFile:function(id, callback, uri, postData){
821                 // Each iframe has an id prefix of "yuiIO" followed
822                 // by the unique transaction id.
823                 var frameId = 'yuiIO' + id;
824                 var io = document.getElementById(frameId);
826                 // Initialize the HTML form properties in case they are
827                 // not defined in the HTML form.
828                 this._formNode.action = uri;
829                 this._formNode.method = 'POST';
830                 this._formNode.target = frameId;
832                 if(this._formNode.encoding){
833                         // IE does not respect property enctype for HTML forms.
834                         // Instead use property encoding.
835                         this._formNode.encoding = 'multipart/form-data';
836                 }
837                 else{
838                         this._formNode.enctype = 'multipart/form-data';
839                 }
842                 if(postData){
843                         var oElements = this.appendPostData(postData);
844                 }
846                 this._formNode.submit();
848                 if(oElements && oElements.length > 0){
849                         for(var i=0; i < oElements.length; i++){
850                                 this._formNode.removeChild(oElements[i]);
851                         }
852                 }
854                 // Reset HTML form status properties.
855                 this.resetFormState();
857                 // Create the upload callback handler that fires when the iframe
858                 // receives the load event.  Subsequently, the event handler is detached
859                 // and the iframe removed from the document.
861                 var uploadCallback = function()
862                 {
863                         var obj = {};
864                         obj.tId = id;
865                         obj.argument = callback.argument;
867                         try
868                         {
869                                 obj.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
870                                 obj.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
871                         }
872                         catch(e){}
874                         if(callback.upload){
875                                 if(!callback.scope){
876                                         callback.upload(obj);
877                                         YAHOO.log('Upload callback.', 'info', 'Connection');
878                                 }
879                                 else{
880                                         callback.upload.apply(callback.scope, [obj]);
881                                         YAHOO.log('Upload callback with scope.', 'info', 'Connection');
882                                 }
883                         }
885                         if(YAHOO.util.Event){
886                                 YAHOO.util.Event.removeListener(io, "load", uploadCallback);
887                         }
888                         else if(window.detachEvent){
889                                 io.detachEvent('onload', uploadCallback);
890                         }
891                         else{
892                                 io.removeEventListener('load', uploadCallback, false);
893                         }
894                         setTimeout(
895                                 function(){
896                                         document.body.removeChild(io);
897                                         YAHOO.log('File upload iframe destroyed. Id is:' + frameId, 'info', 'Connection');
898                                 }, 100);
899                 };
902                 // Bind the onload handler to the iframe to detect the file upload response.
903                 if(YAHOO.util.Event){
904                         YAHOO.util.Event.addListener(io, "load", uploadCallback);
905                 }
906                 else if(window.attachEvent){
907                         io.attachEvent('onload', uploadCallback);
908                 }
909                 else{
910                         io.addEventListener('load', uploadCallback, false);
911                 }
912         },
914   /**
915    * @description Method to terminate a transaction, if it has not reached readyState 4.
916    * @method abort
917    * @public
918    * @static
919    * @param {object} o The connection object returned by asyncRequest.
920    * @param {object} callback  User-defined callback object.
921    * @param {string} isTimeout boolean to indicate if abort was a timeout.
922    * @return {boolean}
923    */
924         abort:function(o, callback, isTimeout)
925         {
926                 if(this.isCallInProgress(o)){
927                         o.conn.abort();
928                         window.clearInterval(this._poll[o.tId]);
929                         delete this._poll[o.tId];
930                         if(isTimeout){
931                                 delete this._timeOut[o.tId];
932                         }
934                         this.handleTransactionResponse(o, callback, true);
935                         YAHOO.log('Transaction ' + o.tId + ' aborted.', 'info', 'Connection');
937                         return true;
938                 }
939                 else{
940                         YAHOO.log('Transaction ' + o.tId + ' abort call failed.', 'warn', 'Connection');
941                         return false;
942                 }
943         },
945   /**
946    * Public method to check if the transaction is still being processed.
947    *
948    * @method isCallInProgress
949    * @public
950    * @static
951    * @param {object} o The connection object returned by asyncRequest
952    * @return {boolean}
953    */
954         isCallInProgress:function(o)
955         {
956                 // if the XHR object assigned to the transaction has not been dereferenced,
957                 // then check its readyState status.  Otherwise, return false.
958                 if(o.conn){
959                         return o.conn.readyState != 4 && o.conn.readyState != 0;
960                 }
961                 else{
962                         //The XHR object has been destroyed.
963                         return false;
964                 }
965         },
967   /**
968    * @description Dereference the XHR instance and the connection object after the transaction is completed.
969    * @method releaseObject
970    * @private
971    * @static
972    * @param {object} o The connection object
973    * @return {void}
974    */
975         releaseObject:function(o)
976         {
977                 //dereference the XHR instance.
978                 o.conn = null;
979                 YAHOO.log('Connection object for transaction ' + o.tId + ' destroyed.', 'info', 'Connection');
980                 //dereference the connection object.
981                 o = null;
982         }