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