Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('yui2-connectioncore', function(Y) { Y.use('yui2-connection'); }, '3.3.0' ,{"requires": ["yui2-yahoo", "yui2-event"]});
2
YUI.add('yui2-connection', function(Y) {
3
    var YAHOO    = Y.YUI2;
4
    /*
5
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
6
Code licensed under the BSD License:
7
http://developer.yahoo.com/yui/license.html
8
version: 2.9.0
9
*/
10
/**
11
 * The Connection Manager provides a simplified interface to the XMLHttpRequest
12
 * object.  It handles cross-browser instantiantion of XMLHttpRequest, negotiates the
13
 * interactive states and server response, returning the results to a pre-defined
14
 * callback you create.
15
 *
16
 * @namespace YAHOO.util
17
 * @module connection
18
 * @requires yahoo
19
 * @requires event
20
 */
21
 
22
/**
23
 * The Connection Manager singleton provides methods for creating and managing
24
 * asynchronous transactions.
25
 *
26
 * @class YAHOO.util.Connect
27
 */
28
 
29
YAHOO.util.Connect =
30
{
31
  /**
32
   * @description Array of MSFT ActiveX ids for XMLHttpRequest.
33
   * @property _msxml_progid
34
   * @private
35
   * @static
36
   * @type array
37
   */
38
    _msxml_progid:[
39
        'Microsoft.XMLHTTP',
40
        'MSXML2.XMLHTTP.3.0',
41
        'MSXML2.XMLHTTP'
42
        ],
43
 
44
  /**
45
   * @description Object literal of HTTP header(s)
46
   * @property _http_header
47
   * @private
48
   * @static
49
   * @type object
50
   */
51
    _http_headers:{},
52
 
53
  /**
54
   * @description Determines if HTTP headers are set.
55
   * @property _has_http_headers
56
   * @private
57
   * @static
58
   * @type boolean
59
   */
60
    _has_http_headers:false,
61
 
62
 /**
63
  * @description Determines if a default header of
64
  * Content-Type of 'application/x-www-form-urlencoded'
65
  * will be added to any client HTTP headers sent for POST
66
  * transactions.
67
  * @property _use_default_post_header
68
  * @private
69
  * @static
70
  * @type boolean
71
  */
72
    _use_default_post_header:true,
73
 
74
 /**
75
  * @description The default header used for POST transactions.
76
  * @property _default_post_header
77
  * @private
78
  * @static
79
  * @type boolean
80
  */
81
    _default_post_header:'application/x-www-form-urlencoded; charset=UTF-8',
82
 
83
 /**
84
  * @description The default header used for transactions involving the
85
  * use of HTML forms.
86
  * @property _default_form_header
87
  * @private
88
  * @static
89
  * @type boolean
90
  */
91
    _default_form_header:'application/x-www-form-urlencoded',
92
 
93
 /**
94
  * @description Determines if a default header of
95
  * 'X-Requested-With: XMLHttpRequest'
96
  * will be added to each transaction.
97
  * @property _use_default_xhr_header
98
  * @private
99
  * @static
100
  * @type boolean
101
  */
102
    _use_default_xhr_header:true,
103
 
104
 /**
105
  * @description The default header value for the label
106
  * "X-Requested-With".  This is sent with each
107
  * transaction, by default, to identify the
108
  * request as being made by YUI Connection Manager.
109
  * @property _default_xhr_header
110
  * @private
111
  * @static
112
  * @type boolean
113
  */
114
    _default_xhr_header:'XMLHttpRequest',
115
 
116
 /**
117
  * @description Determines if custom, default headers
118
  * are set for each transaction.
119
  * @property _has_default_header
120
  * @private
121
  * @static
122
  * @type boolean
123
  */
124
    _has_default_headers:true,
125
 
126
 /**
127
   * @description Property modified by setForm() to determine if the data
128
   * should be submitted as an HTML form.
129
   * @property _isFormSubmit
130
   * @private
131
   * @static
132
   * @type boolean
133
   */
134
	_isFormSubmit:false,
135
 
136
 /**
137
  * @description Determines if custom, default headers
138
  * are set for each transaction.
139
  * @property _has_default_header
140
  * @private
141
  * @static
142
  * @type boolean
143
  */
144
    _default_headers:{},
145
 
146
 /**
147
  * @description Collection of polling references to the polling mechanism in handleReadyState.
148
  * @property _poll
149
  * @private
150
  * @static
151
  * @type object
152
  */
153
    _poll:{},
154
 
155
 /**
156
  * @description Queue of timeout values for each transaction callback with a defined timeout value.
157
  * @property _timeOut
158
  * @private
159
  * @static
160
  * @type object
161
  */
162
    _timeOut:{},
163
 
164
  /**
165
   * @description The polling frequency, in milliseconds, for HandleReadyState.
166
   * when attempting to determine a transaction's XHR readyState.
167
   * The default is 50 milliseconds.
168
   * @property _polling_interval
169
   * @private
170
   * @static
171
   * @type int
172
   */
173
     _polling_interval:50,
174
 
175
  /**
176
   * @description A transaction counter that increments the transaction id for each transaction.
177
   * @property _transaction_id
178
   * @private
179
   * @static
180
   * @type int
181
   */
182
     _transaction_id:0,
183
 
184
  /**
185
   * @description Custom event that fires at the start of a transaction
186
   * @property startEvent
187
   * @private
188
   * @static
189
   * @type CustomEvent
190
   */
191
    startEvent: new YAHOO.util.CustomEvent('start'),
192
 
193
  /**
194
   * @description Custom event that fires when a transaction response has completed.
195
   * @property completeEvent
196
   * @private
197
   * @static
198
   * @type CustomEvent
199
   */
200
    completeEvent: new YAHOO.util.CustomEvent('complete'),
201
 
202
  /**
203
   * @description Custom event that fires when handleTransactionResponse() determines a
204
   * response in the HTTP 2xx range.
205
   * @property successEvent
206
   * @private
207
   * @static
208
   * @type CustomEvent
209
   */
210
    successEvent: new YAHOO.util.CustomEvent('success'),
211
 
212
  /**
213
   * @description Custom event that fires when handleTransactionResponse() determines a
214
   * response in the HTTP 4xx/5xx range.
215
   * @property failureEvent
216
   * @private
217
   * @static
218
   * @type CustomEvent
219
   */
220
    failureEvent: new YAHOO.util.CustomEvent('failure'),
221
 
222
  /**
223
   * @description Custom event that fires when a transaction is successfully aborted.
224
   * @property abortEvent
225
   * @private
226
   * @static
227
   * @type CustomEvent
228
   */
229
    abortEvent: new YAHOO.util.CustomEvent('abort'),
230
 
231
  /**
232
   * @description A reference table that maps callback custom events members to its specific
233
   * event name.
234
   * @property _customEvents
235
   * @private
236
   * @static
237
   * @type object
238
   */
239
    _customEvents:
240
    {
241
        onStart:['startEvent', 'start'],
242
        onComplete:['completeEvent', 'complete'],
243
        onSuccess:['successEvent', 'success'],
244
        onFailure:['failureEvent', 'failure'],
245
        onUpload:['uploadEvent', 'upload'],
246
        onAbort:['abortEvent', 'abort']
247
    },
248
 
249
  /**
250
   * @description Member to add an ActiveX id to the existing xml_progid array.
251
   * In the event(unlikely) a new ActiveX id is introduced, it can be added
252
   * without internal code modifications.
253
   * @method setProgId
254
   * @public
255
   * @static
256
   * @param {string} id The ActiveX id to be added to initialize the XHR object.
257
   * @return void
258
   */
259
    setProgId:function(id)
260
    {
261
        this._msxml_progid.unshift(id);
262
    },
263
 
264
  /**
265
   * @description Member to override the default POST header.
266
   * @method setDefaultPostHeader
267
   * @public
268
   * @static
269
   * @param {boolean} b Set and use default header - true or false .
270
   * @return void
271
   */
272
    setDefaultPostHeader:function(b)
273
    {
274
        if(typeof b == 'string'){
275
            this._default_post_header = b;
276
			this._use_default_post_header = true;
277
 
278
        }
279
        else if(typeof b == 'boolean'){
280
            this._use_default_post_header = b;
281
        }
282
    },
283
 
284
  /**
285
   * @description Member to override the default transaction header..
286
   * @method setDefaultXhrHeader
287
   * @public
288
   * @static
289
   * @param {boolean} b Set and use default header - true or false .
290
   * @return void
291
   */
292
    setDefaultXhrHeader:function(b)
293
    {
294
        if(typeof b == 'string'){
295
            this._default_xhr_header = b;
296
        }
297
        else{
298
            this._use_default_xhr_header = b;
299
        }
300
    },
301
 
302
  /**
303
   * @description Member to modify the default polling interval.
304
   * @method setPollingInterval
305
   * @public
306
   * @static
307
   * @param {int} i The polling interval in milliseconds.
308
   * @return void
309
   */
310
    setPollingInterval:function(i)
311
    {
312
        if(typeof i == 'number' && isFinite(i)){
313
            this._polling_interval = i;
314
        }
315
    },
316
 
317
  /**
318
   * @description Instantiates a XMLHttpRequest object and returns an object with two properties:
319
   * the XMLHttpRequest instance and the transaction id.
320
   * @method createXhrObject
321
   * @private
322
   * @static
323
   * @param {int} transactionId Property containing the transaction id for this transaction.
324
   * @return object
325
   */
326
    createXhrObject:function(transactionId)
327
    {
328
        var obj,http,i;
329
        try
330
        {
331
            // Instantiates XMLHttpRequest in non-IE browsers and assigns to http.
332
            http = new XMLHttpRequest();
333
            //  Object literal with http and tId properties
334
            obj = { conn:http, tId:transactionId, xhr: true };
335
        }
336
        catch(e)
337
        {
338
            for(i=0; i<this._msxml_progid.length; ++i){
339
                try
340
                {
341
                    // Instantiates XMLHttpRequest for IE and assign to http
342
                    http = new ActiveXObject(this._msxml_progid[i]);
343
                    //  Object literal with conn and tId properties
344
                    obj = { conn:http, tId:transactionId, xhr: true };
345
                    break;
346
                }
347
                catch(e1){}
348
            }
349
        }
350
        finally
351
        {
352
            return obj;
353
        }
354
    },
355
 
356
  /**
357
   * @description This method is called by asyncRequest to create a
358
   * valid connection object for the transaction.  It also passes a
359
   * transaction id and increments the transaction id counter.
360
   * @method getConnectionObject
361
   * @private
362
   * @static
363
   * @return {object}
364
   */
365
    getConnectionObject:function(t)
366
    {
367
        var o, tId = this._transaction_id;
368
 
369
        try
370
        {
371
            if(!t){
372
                o = this.createXhrObject(tId);
373
            }
374
            else{
375
                o = {tId:tId};
376
                if(t==='xdr'){
377
                    o.conn = this._transport;
378
                    o.xdr = true;
379
                }
380
                else if(t==='upload'){
381
                    o.upload = true;
382
                }
383
            }
384
 
385
            if(o){
386
                this._transaction_id++;
387
            }
388
        }
389
        catch(e){}
390
        return o;
391
    },
392
 
393
  /**
394
   * @description Method for initiating an asynchronous request via the XHR object.
395
   * @method asyncRequest
396
   * @public
397
   * @static
398
   * @param {string} method HTTP transaction method
399
   * @param {string} uri Fully qualified path of resource
400
   * @param {callback} callback User-defined callback function or object
401
   * @param {string} postData POST body
402
   * @return {object} Returns the connection object
403
   */
404
    asyncRequest:function(method, uri, callback, postData)
405
    {
406
        var args = callback&&callback.argument?callback.argument:null,
407
            YCM = this,
408
            o, t;
409
 
410
        if(this._isFileUpload){
411
            t = 'upload';
412
        }
413
        else if(callback && callback.xdr){
414
            t = 'xdr';
415
        }
416
 
417
        o = this.getConnectionObject(t);
418
        if(!o){
419
            return null;
420
        }
421
        else{
422
 
423
            // Intialize any transaction-specific custom events, if provided.
424
            if(callback && callback.customevents){
425
                this.initCustomEvents(o, callback);
426
            }
427
 
428
            if(this._isFormSubmit){
429
                if(this._isFileUpload){
430
                    window.setTimeout(function(){YCM.uploadFile(o, callback, uri, postData);}, 10);
431
                    return o;
432
                }
433
 
434
                // If the specified HTTP method is GET, setForm() will return an
435
                // encoded string that is concatenated to the uri to
436
                // create a querystring.
437
                if(method.toUpperCase() == 'GET'){
438
                    if(this._sFormData.length !== 0){
439
                        // If the URI already contains a querystring, append an ampersand
440
                        // and then concatenate _sFormData to the URI.
441
                        uri += ((uri.indexOf('?') == -1)?'?':'&') + this._sFormData;
442
                    }
443
                }
444
                else if(method.toUpperCase() == 'POST'){
445
                    // If POST data exist in addition to the HTML form data,
446
                    // it will be concatenated to the form data.
447
                    postData = postData?this._sFormData + "&" + postData:this._sFormData;
448
                }
449
            }
450
 
451
            if(method.toUpperCase() == 'GET' && (callback && callback.cache === false)){
452
                // If callback.cache is defined and set to false, a
453
                // timestamp value will be added to the querystring.
454
                uri += ((uri.indexOf('?') == -1)?'?':'&') + "rnd=" + new Date().valueOf().toString();
455
            }
456
 
457
            // Each transaction will automatically include a custom header of
458
            // "X-Requested-With: XMLHttpRequest" to identify the request as
459
            // having originated from Connection Manager.
460
            if(this._use_default_xhr_header){
461
                if(!this._default_headers['X-Requested-With']){
462
                    this.initHeader('X-Requested-With', this._default_xhr_header, true);
463
                }
464
            }
465
 
466
            //If the transaction method is POST and the POST header value is set to true
467
            //or a custom value, initalize the Content-Type header to this value.
468
            if((method.toUpperCase() === 'POST' && this._use_default_post_header) && this._isFormSubmit === false){
469
                this.initHeader('Content-Type', this._default_post_header);
470
            }
471
 
472
            if(o.xdr){
473
                this.xdr(o, method, uri, callback, postData);
474
                return o;
475
            }
476
 
477
            o.conn.open(method, uri, true);
478
            //Initialize all default and custom HTTP headers,
479
            if(this._has_default_headers || this._has_http_headers){
480
                this.setHeader(o);
481
            }
482
 
483
            this.handleReadyState(o, callback);
484
            o.conn.send(postData || '');
485
 
486
            // Reset the HTML form data and state properties as
487
            // soon as the data are submitted.
488
            if(this._isFormSubmit === true){
489
                this.resetFormState();
490
            }
491
 
492
            // Fire global custom event -- startEvent
493
            this.startEvent.fire(o, args);
494
 
495
            if(o.startEvent){
496
                // Fire transaction custom event -- startEvent
497
                o.startEvent.fire(o, args);
498
            }
499
 
500
            return o;
501
        }
502
    },
503
 
504
  /**
505
   * @description This method creates and subscribes custom events,
506
   * specific to each transaction
507
   * @method initCustomEvents
508
   * @private
509
   * @static
510
   * @param {object} o The connection object
511
   * @param {callback} callback The user-defined callback object
512
   * @return {void}
513
   */
514
    initCustomEvents:function(o, callback)
515
    {
516
        var prop;
517
        // Enumerate through callback.customevents members and bind/subscribe
518
        // events that match in the _customEvents table.
519
        for(prop in callback.customevents){
520
            if(this._customEvents[prop][0]){
521
                // Create the custom event
522
                o[this._customEvents[prop][0]] = new YAHOO.util.CustomEvent(this._customEvents[prop][1], (callback.scope)?callback.scope:null);
523
 
524
                // Subscribe the custom event
525
                o[this._customEvents[prop][0]].subscribe(callback.customevents[prop]);
526
            }
527
        }
528
    },
529
 
530
  /**
531
   * @description This method serves as a timer that polls the XHR object's readyState
532
   * property during a transaction, instead of binding a callback to the
533
   * onreadystatechange event.  Upon readyState 4, handleTransactionResponse
534
   * will process the response, and the timer will be cleared.
535
   * @method handleReadyState
536
   * @private
537
   * @static
538
   * @param {object} o The connection object
539
   * @param {callback} callback The user-defined callback object
540
   * @return {void}
541
   */
542
 
543
    handleReadyState:function(o, callback)
544
 
545
    {
546
        var oConn = this,
547
            args = (callback && callback.argument)?callback.argument:null;
548
 
549
        if(callback && callback.timeout){
550
            this._timeOut[o.tId] = window.setTimeout(function(){ oConn.abort(o, callback, true); }, callback.timeout);
551
        }
552
 
553
        this._poll[o.tId] = window.setInterval(
554
            function(){
555
                if(o.conn && o.conn.readyState === 4){
556
 
557
                    // Clear the polling interval for the transaction
558
                    // and remove the reference from _poll.
559
                    window.clearInterval(oConn._poll[o.tId]);
560
                    delete oConn._poll[o.tId];
561
 
562
                    if(callback && callback.timeout){
563
                        window.clearTimeout(oConn._timeOut[o.tId]);
564
                        delete oConn._timeOut[o.tId];
565
                    }
566
 
567
                    // Fire global custom event -- completeEvent
568
                    oConn.completeEvent.fire(o, args);
569
 
570
                    if(o.completeEvent){
571
                        // Fire transaction custom event -- completeEvent
572
                        o.completeEvent.fire(o, args);
573
                    }
574
 
575
                    oConn.handleTransactionResponse(o, callback);
576
                }
577
            }
578
        ,this._polling_interval);
579
    },
580
 
581
  /**
582
   * @description This method attempts to interpret the server response and
583
   * determine whether the transaction was successful, or if an error or
584
   * exception was encountered.
585
   * @method handleTransactionResponse
586
   * @private
587
   * @static
588
   * @param {object} o The connection object
589
   * @param {object} callback The user-defined callback object
590
   * @param {boolean} isAbort Determines if the transaction was terminated via abort().
591
   * @return {void}
592
   */
593
    handleTransactionResponse:function(o, callback, isAbort)
594
    {
595
        var httpStatus, responseObject,
596
            args = (callback && callback.argument)?callback.argument:null,
597
            xdrS = (o.r && o.r.statusText === 'xdr:success')?true:false,
598
            xdrF = (o.r && o.r.statusText === 'xdr:failure')?true:false,
599
            xdrA = isAbort;
600
 
601
        try
602
        {
603
            if((o.conn.status !== undefined && o.conn.status !== 0) || xdrS){
604
                // XDR requests will not have HTTP status defined. The
605
                // statusText property will define the response status
606
                // set by the Flash transport.
607
                httpStatus = o.conn.status;
608
            }
609
            else if(xdrF && !xdrA){
610
                // Set XDR transaction failure to a status of 0, which
611
                // resolves as an HTTP failure, instead of an exception.
612
                httpStatus = 0;
613
            }
614
            else{
615
                httpStatus = 13030;
616
            }
617
        }
618
        catch(e){
619
 
620
             // 13030 is a custom code to indicate the condition -- in Mozilla/FF --
621
             // when the XHR object's status and statusText properties are
622
             // unavailable, and a query attempt throws an exception.
623
            httpStatus = 13030;
624
        }
625
 
626
        if((httpStatus >= 200 && httpStatus < 300) || httpStatus === 1223 || xdrS){
627
            responseObject = o.xdr ? o.r : this.createResponseObject(o, args);
628
            if(callback && callback.success){
629
                if(!callback.scope){
630
                    callback.success(responseObject);
631
                }
632
                else{
633
                    // If a scope property is defined, the callback will be fired from
634
                    // the context of the object.
635
                    callback.success.apply(callback.scope, [responseObject]);
636
                }
637
            }
638
 
639
            // Fire global custom event -- successEvent
640
            this.successEvent.fire(responseObject);
641
 
642
            if(o.successEvent){
643
                // Fire transaction custom event -- successEvent
644
                o.successEvent.fire(responseObject);
645
            }
646
        }
647
        else{
648
            switch(httpStatus){
649
                // The following cases are wininet.dll error codes that may be encountered.
650
                case 12002: // Server timeout
651
                case 12029: // 12029 to 12031 correspond to dropped connections.
652
                case 12030:
653
                case 12031:
654
                case 12152: // Connection closed by server.
655
                case 13030: // See above comments for variable status.
656
                    // XDR transactions will not resolve to this case, since the
657
                    // response object is already built in the xdr response.
658
                    responseObject = this.createExceptionObject(o.tId, args, (isAbort?isAbort:false));
659
                    if(callback && callback.failure){
660
                        if(!callback.scope){
661
                            callback.failure(responseObject);
662
                        }
663
                        else{
664
                            callback.failure.apply(callback.scope, [responseObject]);
665
                        }
666
                    }
667
 
668
                    break;
669
                default:
670
                    responseObject = (o.xdr) ? o.response : this.createResponseObject(o, args);
671
                    if(callback && callback.failure){
672
                        if(!callback.scope){
673
                            callback.failure(responseObject);
674
                        }
675
                        else{
676
                            callback.failure.apply(callback.scope, [responseObject]);
677
                        }
678
                    }
679
            }
680
 
681
            // Fire global custom event -- failureEvent
682
            this.failureEvent.fire(responseObject);
683
 
684
            if(o.failureEvent){
685
                // Fire transaction custom event -- failureEvent
686
                o.failureEvent.fire(responseObject);
687
            }
688
 
689
        }
690
 
691
        this.releaseObject(o);
692
        responseObject = null;
693
    },
694
 
695
  /**
696
   * @description This method evaluates the server response, creates and returns the results via
697
   * its properties.  Success and failure cases will differ in the response
698
   * object's property values.
699
   * @method createResponseObject
700
   * @private
701
   * @static
702
   * @param {object} o The connection object
703
   * @param {callbackArg} callbackArg The user-defined argument or arguments to be passed to the callback
704
   * @return {object}
705
   */
706
    createResponseObject:function(o, callbackArg)
707
    {
708
        var obj = {}, headerObj = {},
709
            i, headerStr, header, delimitPos;
710
 
711
        try
712
        {
713
            headerStr = o.conn.getAllResponseHeaders();
714
            header = headerStr.split('\n');
715
            for(i=0; i<header.length; i++){
716
                delimitPos = header[i].indexOf(':');
717
                if(delimitPos != -1){
718
                    headerObj[header[i].substring(0,delimitPos)] = YAHOO.lang.trim(header[i].substring(delimitPos+2));
719
                }
720
            }
721
        }
722
        catch(e){}
723
 
724
        obj.tId = o.tId;
725
        // Normalize IE's response to HTTP 204 when Win error 1223.
726
        obj.status = (o.conn.status == 1223)?204:o.conn.status;
727
        // Normalize IE's statusText to "No Content" instead of "Unknown".
728
        obj.statusText = (o.conn.status == 1223)?"No Content":o.conn.statusText;
729
        obj.getResponseHeader = headerObj;
730
        obj.getAllResponseHeaders = headerStr;
731
        obj.responseText = o.conn.responseText;
732
        obj.responseXML = o.conn.responseXML;
733
 
734
        if(callbackArg){
735
            obj.argument = callbackArg;
736
        }
737
 
738
        return obj;
739
    },
740
 
741
  /**
742
   * @description If a transaction cannot be completed due to dropped or closed connections,
743
   * there may be not be enough information to build a full response object.
744
   * The failure callback will be fired and this specific condition can be identified
745
   * by a status property value of 0.
746
   *
747
   * If an abort was successful, the status property will report a value of -1.
748
   *
749
   * @method createExceptionObject
750
   * @private
751
   * @static
752
   * @param {int} tId The Transaction Id
753
   * @param {callbackArg} callbackArg The user-defined argument or arguments to be passed to the callback
754
   * @param {boolean} isAbort Determines if the exception case is caused by a transaction abort
755
   * @return {object}
756
   */
757
    createExceptionObject:function(tId, callbackArg, isAbort)
758
    {
759
        var COMM_CODE = 0,
760
            COMM_ERROR = 'communication failure',
761
            ABORT_CODE = -1,
762
            ABORT_ERROR = 'transaction aborted',
763
            obj = {};
764
 
765
        obj.tId = tId;
766
        if(isAbort){
767
            obj.status = ABORT_CODE;
768
            obj.statusText = ABORT_ERROR;
769
        }
770
        else{
771
            obj.status = COMM_CODE;
772
            obj.statusText = COMM_ERROR;
773
        }
774
 
775
        if(callbackArg){
776
            obj.argument = callbackArg;
777
        }
778
 
779
        return obj;
780
    },
781
 
782
  /**
783
   * @description Method that initializes the custom HTTP headers for the each transaction.
784
   * @method initHeader
785
   * @public
786
   * @static
787
   * @param {string} label The HTTP header label
788
   * @param {string} value The HTTP header value
789
   * @param {string} isDefault Determines if the specific header is a default header
790
   * automatically sent with each transaction.
791
   * @return {void}
792
   */
793
    initHeader:function(label, value, isDefault)
794
    {
795
        var headerObj = (isDefault)?this._default_headers:this._http_headers;
796
 
797
        headerObj[label] = value;
798
        if(isDefault){
799
            this._has_default_headers = true;
800
        }
801
        else{
802
            this._has_http_headers = true;
803
        }
804
    },
805
 
806
 
807
  /**
808
   * @description Accessor that sets the HTTP headers for each transaction.
809
   * @method setHeader
810
   * @private
811
   * @static
812
   * @param {object} o The connection object for the transaction.
813
   * @return {void}
814
   */
815
    setHeader:function(o)
816
    {
817
        var prop;
818
        if(this._has_default_headers){
819
            for(prop in this._default_headers){
820
                if(YAHOO.lang.hasOwnProperty(this._default_headers, prop)){
821
                    o.conn.setRequestHeader(prop, this._default_headers[prop]);
822
                }
823
            }
824
        }
825
 
826
        if(this._has_http_headers){
827
            for(prop in this._http_headers){
828
                if(YAHOO.lang.hasOwnProperty(this._http_headers, prop)){
829
                    o.conn.setRequestHeader(prop, this._http_headers[prop]);
830
                }
831
            }
832
 
833
            this._http_headers = {};
834
            this._has_http_headers = false;
835
        }
836
    },
837
 
838
  /**
839
   * @description Resets the default HTTP headers object
840
   * @method resetDefaultHeaders
841
   * @public
842
   * @static
843
   * @return {void}
844
   */
845
    resetDefaultHeaders:function(){
846
        this._default_headers = {};
847
        this._has_default_headers = false;
848
    },
849
 
850
  /**
851
   * @description Method to terminate a transaction, if it has not reached readyState 4.
852
   * @method abort
853
   * @public
854
   * @static
855
   * @param {object} o The connection object returned by asyncRequest.
856
   * @param {object} callback  User-defined callback object.
857
   * @param {string} isTimeout boolean to indicate if abort resulted from a callback timeout.
858
   * @return {boolean}
859
   */
860
    abort:function(o, callback, isTimeout)
861
    {
862
        var abortStatus,
863
            args = (callback && callback.argument)?callback.argument:null;
864
            o = o || {};
865
 
866
        if(o.conn){
867
            if(o.xhr){
868
                if(this.isCallInProgress(o)){
869
                    // Issue abort request
870
                    o.conn.abort();
871
 
872
                    window.clearInterval(this._poll[o.tId]);
873
                    delete this._poll[o.tId];
874
 
875
                    if(isTimeout){
876
                        window.clearTimeout(this._timeOut[o.tId]);
877
                        delete this._timeOut[o.tId];
878
                    }
879
 
880
                    abortStatus = true;
881
                }
882
            }
883
            else if(o.xdr){
884
                o.conn.abort(o.tId);
885
                abortStatus = true;
886
            }
887
        }
888
        else if(o.upload){
889
            var frameId = 'yuiIO' + o.tId;
890
            var io = document.getElementById(frameId);
891
 
892
            if(io){
893
                // Remove all listeners on the iframe prior to
894
                // its destruction.
895
                YAHOO.util.Event.removeListener(io, "load");
896
                // Destroy the iframe facilitating the transaction.
897
                document.body.removeChild(io);
898
 
899
                if(isTimeout){
900
                    window.clearTimeout(this._timeOut[o.tId]);
901
                    delete this._timeOut[o.tId];
902
                }
903
 
904
                abortStatus = true;
905
            }
906
        }
907
        else{
908
            abortStatus = false;
909
        }
910
 
911
        if(abortStatus === true){
912
            // Fire global custom event -- abortEvent
913
            this.abortEvent.fire(o, args);
914
 
915
            if(o.abortEvent){
916
                // Fire transaction custom event -- abortEvent
917
                o.abortEvent.fire(o, args);
918
            }
919
 
920
            this.handleTransactionResponse(o, callback, true);
921
        }
922
 
923
        return abortStatus;
924
    },
925
 
926
  /**
927
   * @description Determines if the transaction is still being processed.
928
   * @method isCallInProgress
929
   * @public
930
   * @static
931
   * @param {object} o The connection object returned by asyncRequest
932
   * @return {boolean}
933
   */
934
    isCallInProgress:function(o)
935
    {
936
        o = o || {};
937
        // if the XHR object assigned to the transaction has not been dereferenced,
938
        // then check its readyState status.  Otherwise, return false.
939
        if(o.xhr && o.conn){
940
            return o.conn.readyState !== 4 && o.conn.readyState !== 0;
941
        }
942
        else if(o.xdr && o.conn){
943
            return o.conn.isCallInProgress(o.tId);
944
        }
945
        else if(o.upload === true){
946
            return document.getElementById('yuiIO' + o.tId)?true:false;
947
        }
948
        else{
949
            return false;
950
        }
951
    },
952
 
953
  /**
954
   * @description Dereference the XHR instance and the connection object after the transaction is completed.
955
   * @method releaseObject
956
   * @private
957
   * @static
958
   * @param {object} o The connection object
959
   * @return {void}
960
   */
961
    releaseObject:function(o)
962
    {
963
        if(o && o.conn){
964
            //dereference the XHR instance.
965
            o.conn = null;
966
 
967
 
968
            //dereference the connection object.
969
            o = null;
970
        }
971
    }
972
};
973
 
974
/**
975
  * @for YAHOO.util.Connect
976
  */
977
(function() {
978
	var YCM = YAHOO.util.Connect, _fn = {};
979
 
980
   /**
981
    * @description This method creates and instantiates the Flash transport.
982
    * @method _swf
983
    * @private
984
    * @static
985
    * @param {string} URI to connection.swf.
986
    * @return {void}
987
    */
988
	function _swf(uri) {
989
		var o = '<object id="YUIConnectionSwf" type="application/x-shockwave-flash" data="' +
990
				uri + '" width="0" height="0">' +
991
				'<param name="movie" value="' + uri + '">' +
992
				'<param name="allowScriptAccess" value="always">' +
993
				'</object>',
994
		    c = document.createElement('div');
995
 
996
		document.body.appendChild(c);
997
		c.innerHTML = o;
998
	}
999
 
1000
   /**
1001
    * @description This method calls the public method on the
1002
    * Flash transport to start the XDR transaction.  It is analogous
1003
    * to Connection Manager's asyncRequest method.
1004
    * @method xdr
1005
    * @private
1006
    * @static
1007
    * @param {object} The transaction object.
1008
    * @param {string} HTTP request method.
1009
    * @param {string} URI for the transaction.
1010
    * @param {object} The transaction's callback object.
1011
    * @param {object} The JSON object used as HTTP POST data.
1012
    * @return {void}
1013
    */
1014
	function _xdr(o, m, u, c, d) {
1015
		_fn[parseInt(o.tId)] = { 'o':o, 'c':c };
1016
		if (d) {
1017
			c.method = m;
1018
			c.data = d;
1019
		}
1020
 
1021
		o.conn.send(u, c, o.tId);
1022
	}
1023
 
1024
   /**
1025
    * @description This method instantiates the Flash transport and
1026
    * establishes a static reference to it, used for all XDR requests.
1027
    * @method transport
1028
    * @public
1029
    * @static
1030
    * @param {string} URI to connection.swf.
1031
    * @return {void}
1032
    */
1033
	function _init(uri) {
1034
		_swf(uri);
1035
		YCM._transport = document.getElementById('YUIConnectionSwf');
1036
	}
1037
 
1038
	function _xdrReady() {
1039
		YCM.xdrReadyEvent.fire();
1040
	}
1041
 
1042
   /**
1043
    * @description This method fires the global and transaction start
1044
    * events.
1045
    * @method _xdrStart
1046
    * @private
1047
    * @static
1048
    * @param {object} The transaction object.
1049
    * @param {string} The transaction's callback object.
1050
    * @return {void}
1051
    */
1052
	function _xdrStart(o, cb) {
1053
		if (o) {
1054
			// Fire global custom event -- startEvent
1055
			YCM.startEvent.fire(o, cb.argument);
1056
 
1057
			if(o.startEvent){
1058
				// Fire transaction custom event -- startEvent
1059
				o.startEvent.fire(o, cb.argument);
1060
			}
1061
		}
1062
	}
1063
 
1064
   /**
1065
    * @description This method is the initial response handler
1066
    * for XDR transactions.  The Flash transport calls this
1067
    * function and sends the response payload.
1068
    * @method handleXdrResponse
1069
    * @private
1070
    * @static
1071
    * @param {object} The response object sent from the Flash transport.
1072
    * @return {void}
1073
    */
1074
	function _handleXdrResponse(r) {
1075
		var o = _fn[r.tId].o,
1076
			cb = _fn[r.tId].c;
1077
 
1078
		if (r.statusText === 'xdr:start') {
1079
			_xdrStart(o, cb);
1080
			return;
1081
		}
1082
 
1083
		r.responseText = decodeURI(r.responseText);
1084
		o.r = r;
1085
		if (cb.argument) {
1086
			o.r.argument = cb.argument;
1087
		}
1088
 
1089
		this.handleTransactionResponse(o, cb, r.statusText === 'xdr:abort' ? true : false);
1090
		delete _fn[r.tId];
1091
	}
1092
 
1093
	// Bind the functions to Connection Manager as static fields.
1094
	YCM.xdr = _xdr;
1095
	YCM.swf = _swf;
1096
	YCM.transport = _init;
1097
	YCM.xdrReadyEvent = new YAHOO.util.CustomEvent('xdrReady');
1098
	YCM.xdrReady = _xdrReady;
1099
	YCM.handleXdrResponse = _handleXdrResponse;
1100
})();
1101
 
1102
/**
1103
  * @for YAHOO.util.Connect
1104
  */
1105
(function(){
1106
	var YCM = YAHOO.util.Connect,
1107
		YE = YAHOO.util.Event,
1108
		dM = document.documentMode ? document.documentMode : false;
1109
 
1110
   /**
1111
	* @description Property modified by setForm() to determine if a file(s)
1112
	* upload is expected.
1113
	* @property _isFileUpload
1114
	* @private
1115
	* @static
1116
	* @type boolean
1117
	*/
1118
	YCM._isFileUpload = false;
1119
 
1120
   /**
1121
	* @description Property modified by setForm() to set a reference to the HTML
1122
	* form node if the desired action is file upload.
1123
	* @property _formNode
1124
	* @private
1125
	* @static
1126
	* @type object
1127
	*/
1128
	YCM._formNode = null;
1129
 
1130
   /**
1131
	* @description Property modified by setForm() to set the HTML form data
1132
	* for each transaction.
1133
	* @property _sFormData
1134
	* @private
1135
	* @static
1136
	* @type string
1137
	*/
1138
	YCM._sFormData = null;
1139
 
1140
   /**
1141
	* @description Tracks the name-value pair of the "clicked" submit button if multiple submit
1142
	* buttons are present in an HTML form; and, if YAHOO.util.Event is available.
1143
	* @property _submitElementValue
1144
	* @private
1145
	* @static
1146
	* @type string
1147
	*/
1148
	YCM._submitElementValue = null;
1149
 
1150
   /**
1151
    * @description Custom event that fires when handleTransactionResponse() determines a
1152
    * response in the HTTP 4xx/5xx range.
1153
    * @property failureEvent
1154
    * @private
1155
    * @static
1156
    * @type CustomEvent
1157
    */
1158
	YCM.uploadEvent = new YAHOO.util.CustomEvent('upload');
1159
 
1160
   /**
1161
	* @description Determines whether YAHOO.util.Event is available and returns true or false.
1162
	* If true, an event listener is bound at the document level to trap click events that
1163
	* resolve to a target type of "Submit".  This listener will enable setForm() to determine
1164
	* the clicked "Submit" value in a multi-Submit button, HTML form.
1165
	* @property _hasSubmitListener
1166
	* @private
1167
	* @static
1168
	*/
1169
	YCM._hasSubmitListener = function() {
1170
		if(YE){
1171
			YE.addListener(
1172
				document,
1173
				'click',
1174
				function(e){
1175
					var obj = YE.getTarget(e),
1176
						name = obj.nodeName.toLowerCase();
1177
 
1178
					if((name === 'input' || name === 'button') && (obj.type && obj.type.toLowerCase() == 'submit')){
1179
						YCM._submitElementValue = encodeURIComponent(obj.name) + "=" + encodeURIComponent(obj.value);
1180
					}
1181
				});
1182
			return true;
1183
		}
1184
		return false;
1185
	}();
1186
 
1187
  /**
1188
   * @description This method assembles the form label and value pairs and
1189
   * constructs an encoded string.
1190
   * asyncRequest() will automatically initialize the transaction with a
1191
   * a HTTP header Content-Type of application/x-www-form-urlencoded.
1192
   * @method setForm
1193
   * @public
1194
   * @static
1195
   * @param {string || object} form id or name attribute, or form object.
1196
   * @param {boolean} optional enable file upload.
1197
   * @param {boolean} optional enable file upload over SSL in IE only.
1198
   * @return {string} string of the HTML form field name and value pairs..
1199
   */
1200
	function _setForm(formId, isUpload, secureUri)
1201
	{
1202
		var oForm, oElement, oName, oValue, oDisabled,
1203
			hasSubmit = false,
1204
			data = [], item = 0,
1205
			i,len,j,jlen,opt;
1206
 
1207
		this.resetFormState();
1208
 
1209
		if(typeof formId == 'string'){
1210
			// Determine if the argument is a form id or a form name.
1211
			// Note form name usage is deprecated by supported
1212
			// here for legacy reasons.
1213
			oForm = (document.getElementById(formId) || document.forms[formId]);
1214
		}
1215
		else if(typeof formId == 'object'){
1216
			// Treat argument as an HTML form object.
1217
			oForm = formId;
1218
		}
1219
		else{
1220
			return;
1221
		}
1222
 
1223
		// If the isUpload argument is true, setForm will call createFrame to initialize
1224
		// an iframe as the form target.
1225
		//
1226
		// The argument secureURI is also required by IE in SSL environments
1227
		// where the secureURI string is a fully qualified HTTP path, used to set the source
1228
		// of the iframe, to a stub resource in the same domain.
1229
		if(isUpload){
1230
 
1231
			// Create iframe in preparation for file upload.
1232
			this.createFrame(secureUri?secureUri:null);
1233
 
1234
			// Set form reference and file upload properties to true.
1235
			this._isFormSubmit = true;
1236
			this._isFileUpload = true;
1237
			this._formNode = oForm;
1238
 
1239
			return;
1240
		}
1241
 
1242
		// Iterate over the form elements collection to construct the
1243
		// label-value pairs.
1244
		for (i=0,len=oForm.elements.length; i<len; ++i){
1245
			oElement  = oForm.elements[i];
1246
			oDisabled = oElement.disabled;
1247
			oName     = oElement.name;
1248
 
1249
			// Do not submit fields that are disabled or
1250
			// do not have a name attribute value.
1251
			if(!oDisabled && oName)
1252
			{
1253
				oName  = encodeURIComponent(oName)+'=';
1254
				oValue = encodeURIComponent(oElement.value);
1255
 
1256
				switch(oElement.type)
1257
				{
1258
					// Safari, Opera, FF all default opt.value from .text if
1259
					// value attribute not specified in markup
1260
					case 'select-one':
1261
						if (oElement.selectedIndex > -1) {
1262
							opt = oElement.options[oElement.selectedIndex];
1263
							data[item++] = oName + encodeURIComponent(
1264
								(opt.attributes.value && opt.attributes.value.specified) ? opt.value : opt.text);
1265
						}
1266
						break;
1267
					case 'select-multiple':
1268
						if (oElement.selectedIndex > -1) {
1269
							for(j=oElement.selectedIndex, jlen=oElement.options.length; j<jlen; ++j){
1270
								opt = oElement.options[j];
1271
								if (opt.selected) {
1272
									data[item++] = oName + encodeURIComponent(
1273
										(opt.attributes.value && opt.attributes.value.specified) ? opt.value : opt.text);
1274
								}
1275
							}
1276
						}
1277
						break;
1278
					case 'radio':
1279
					case 'checkbox':
1280
						if(oElement.checked){
1281
							data[item++] = oName + oValue;
1282
						}
1283
						break;
1284
					case 'file':
1285
						// stub case as XMLHttpRequest will only send the file path as a string.
1286
					case undefined:
1287
						// stub case for fieldset element which returns undefined.
1288
					case 'reset':
1289
						// stub case for input type reset button.
1290
					case 'button':
1291
						// stub case for input type button elements.
1292
						break;
1293
					case 'submit':
1294
						if(hasSubmit === false){
1295
							if(this._hasSubmitListener && this._submitElementValue){
1296
								data[item++] = this._submitElementValue;
1297
							}
1298
							hasSubmit = true;
1299
						}
1300
						break;
1301
					default:
1302
						data[item++] = oName + oValue;
1303
				}
1304
			}
1305
		}
1306
 
1307
		this._isFormSubmit = true;
1308
		this._sFormData = data.join('&');
1309
 
1310
 
1311
		this.initHeader('Content-Type', this._default_form_header);
1312
 
1313
		return this._sFormData;
1314
	}
1315
 
1316
   /**
1317
    * @description Resets HTML form properties when an HTML form or HTML form
1318
    * with file upload transaction is sent.
1319
    * @method resetFormState
1320
    * @private
1321
    * @static
1322
    * @return {void}
1323
    */
1324
	function _resetFormState(){
1325
		this._isFormSubmit = false;
1326
		this._isFileUpload = false;
1327
		this._formNode = null;
1328
		this._sFormData = "";
1329
	}
1330
 
1331
 
1332
   /**
1333
    * @description Creates an iframe to be used for form file uploads.  It is remove from the
1334
    * document upon completion of the upload transaction.
1335
    * @method createFrame
1336
    * @private
1337
    * @static
1338
    * @param {string} optional qualified path of iframe resource for SSL in IE.
1339
    * @return {void}
1340
    */
1341
	function _createFrame(secureUri){
1342
 
1343
		// IE does not allow the setting of id and name attributes as object
1344
		// properties via createElement().  A different iframe creation
1345
		// pattern is required for IE.
1346
		var frameId = 'yuiIO' + this._transaction_id,
1347
			ie9 = (dM === 9) ? true : false,
1348
			io;
1349
 
1350
		if(YAHOO.env.ua.ie && !ie9){
1351
			io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
1352
 
1353
			// IE will throw a security exception in an SSL environment if the
1354
			// iframe source is undefined.
1355
			if(typeof secureUri == 'boolean'){
1356
				io.src = 'javascript:false';
1357
			}
1358
		}
1359
		else{
1360
			io = document.createElement('iframe');
1361
			io.id = frameId;
1362
			io.name = frameId;
1363
		}
1364
 
1365
		io.style.position = 'absolute';
1366
		io.style.top = '-1000px';
1367
		io.style.left = '-1000px';
1368
 
1369
		document.body.appendChild(io);
1370
	}
1371
 
1372
   /**
1373
    * @description Parses the POST data and creates hidden form elements
1374
    * for each key-value, and appends them to the HTML form object.
1375
    * @method appendPostData
1376
    * @private
1377
    * @static
1378
    * @param {string} postData The HTTP POST data
1379
    * @return {array} formElements Collection of hidden fields.
1380
    */
1381
	function _appendPostData(postData){
1382
		var formElements = [],
1383
			postMessage = postData.split('&'),
1384
			i, delimitPos;
1385
 
1386
		for(i=0; i < postMessage.length; i++){
1387
			delimitPos = postMessage[i].indexOf('=');
1388
			if(delimitPos != -1){
1389
				formElements[i] = document.createElement('input');
1390
				formElements[i].type = 'hidden';
1391
				formElements[i].name = decodeURIComponent(postMessage[i].substring(0,delimitPos));
1392
				formElements[i].value = decodeURIComponent(postMessage[i].substring(delimitPos+1));
1393
				this._formNode.appendChild(formElements[i]);
1394
			}
1395
		}
1396
 
1397
		return formElements;
1398
	}
1399
 
1400
   /**
1401
    * @description Uploads HTML form, inclusive of files/attachments, using the
1402
    * iframe created in createFrame to facilitate the transaction.
1403
    * @method uploadFile
1404
    * @private
1405
    * @static
1406
    * @param {int} id The transaction id.
1407
    * @param {object} callback User-defined callback object.
1408
    * @param {string} uri Fully qualified path of resource.
1409
    * @param {string} postData POST data to be submitted in addition to HTML form.
1410
    * @return {void}
1411
    */
1412
	function _uploadFile(o, callback, uri, postData){
1413
		// Each iframe has an id prefix of "yuiIO" followed
1414
		// by the unique transaction id.
1415
		var frameId = 'yuiIO' + o.tId,
1416
		    uploadEncoding = 'multipart/form-data',
1417
		    io = document.getElementById(frameId),
1418
		    ie8 = (dM >= 8) ? true : false,
1419
		    oConn = this,
1420
			args = (callback && callback.argument)?callback.argument:null,
1421
            oElements,i,prop,obj, rawFormAttributes, uploadCallback;
1422
 
1423
		// Track original HTML form attribute values.
1424
		rawFormAttributes = {
1425
			action:this._formNode.getAttribute('action'),
1426
			method:this._formNode.getAttribute('method'),
1427
			target:this._formNode.getAttribute('target')
1428
		};
1429
 
1430
		// Initialize the HTML form properties in case they are
1431
		// not defined in the HTML form.
1432
		this._formNode.setAttribute('action', uri);
1433
		this._formNode.setAttribute('method', 'POST');
1434
		this._formNode.setAttribute('target', frameId);
1435
 
1436
		if(YAHOO.env.ua.ie && !ie8){
1437
			// IE does not respect property enctype for HTML forms.
1438
			// Instead it uses the property - "encoding".
1439
			this._formNode.setAttribute('encoding', uploadEncoding);
1440
		}
1441
		else{
1442
			this._formNode.setAttribute('enctype', uploadEncoding);
1443
		}
1444
 
1445
		if(postData){
1446
			oElements = this.appendPostData(postData);
1447
		}
1448
 
1449
		// Start file upload.
1450
		this._formNode.submit();
1451
 
1452
		// Fire global custom event -- startEvent
1453
		this.startEvent.fire(o, args);
1454
 
1455
		if(o.startEvent){
1456
			// Fire transaction custom event -- startEvent
1457
			o.startEvent.fire(o, args);
1458
		}
1459
 
1460
		// Start polling if a callback is present and the timeout
1461
		// property has been defined.
1462
		if(callback && callback.timeout){
1463
			this._timeOut[o.tId] = window.setTimeout(function(){ oConn.abort(o, callback, true); }, callback.timeout);
1464
		}
1465
 
1466
		// Remove HTML elements created by appendPostData
1467
		if(oElements && oElements.length > 0){
1468
			for(i=0; i < oElements.length; i++){
1469
				this._formNode.removeChild(oElements[i]);
1470
			}
1471
		}
1472
 
1473
		// Restore HTML form attributes to their original
1474
		// values prior to file upload.
1475
		for(prop in rawFormAttributes){
1476
			if(YAHOO.lang.hasOwnProperty(rawFormAttributes, prop)){
1477
				if(rawFormAttributes[prop]){
1478
					this._formNode.setAttribute(prop, rawFormAttributes[prop]);
1479
				}
1480
				else{
1481
					this._formNode.removeAttribute(prop);
1482
				}
1483
			}
1484
		}
1485
 
1486
		// Reset HTML form state properties.
1487
		this.resetFormState();
1488
 
1489
		// Create the upload callback handler that fires when the iframe
1490
		// receives the load event.  Subsequently, the event handler is detached
1491
		// and the iframe removed from the document.
1492
		uploadCallback = function() {
1493
			var body, pre, text;
1494
 
1495
			if(callback && callback.timeout){
1496
				window.clearTimeout(oConn._timeOut[o.tId]);
1497
				delete oConn._timeOut[o.tId];
1498
			}
1499
 
1500
			// Fire global custom event -- completeEvent
1501
			oConn.completeEvent.fire(o, args);
1502
 
1503
			if(o.completeEvent){
1504
				// Fire transaction custom event -- completeEvent
1505
				o.completeEvent.fire(o, args);
1506
			}
1507
 
1508
			obj = {
1509
			    tId : o.tId,
1510
			    argument : args
1511
            };
1512
 
1513
			try
1514
			{
1515
				body = io.contentWindow.document.getElementsByTagName('body')[0];
1516
				pre = io.contentWindow.document.getElementsByTagName('pre')[0];
1517
 
1518
				if (body) {
1519
					if (pre) {
1520
						text = pre.textContent?pre.textContent:pre.innerText;
1521
					}
1522
					else {
1523
						text = body.textContent?body.textContent:body.innerText;
1524
					}
1525
				}
1526
				obj.responseText = text;
1527
				// responseText and responseXML will be populated with the same data from the iframe.
1528
				// Since the HTTP headers cannot be read from the iframe
1529
				obj.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
1530
			}
1531
			catch(e){}
1532
 
1533
			if(callback && callback.upload){
1534
				if(!callback.scope){
1535
					callback.upload(obj);
1536
				}
1537
				else{
1538
					callback.upload.apply(callback.scope, [obj]);
1539
				}
1540
			}
1541
 
1542
			// Fire global custom event -- uploadEvent
1543
			oConn.uploadEvent.fire(obj);
1544
 
1545
			if(o.uploadEvent){
1546
				// Fire transaction custom event -- uploadEvent
1547
				o.uploadEvent.fire(obj);
1548
			}
1549
 
1550
			YE.removeListener(io, "load", uploadCallback);
1551
 
1552
			setTimeout(
1553
				function(){
1554
					document.body.removeChild(io);
1555
					oConn.releaseObject(o);
1556
				}, 100);
1557
		};
1558
 
1559
		// Bind the onload handler to the iframe to detect the file upload response.
1560
		YE.addListener(io, "load", uploadCallback);
1561
	}
1562
 
1563
	YCM.setForm = _setForm;
1564
	YCM.resetFormState = _resetFormState;
1565
	YCM.createFrame = _createFrame;
1566
	YCM.appendPostData = _appendPostData;
1567
	YCM.uploadFile = _uploadFile;
1568
})();
1569
 
1570
YAHOO.register("connection", YAHOO.util.Connect, {version: "2.9.0", build: "2800"});
1571
 
1572
}, '2.9.0' ,{"requires": ["yui2-yahoo", "yui2-event"], "supersedes": ["yui2-connectioncore"]});