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