src/cm/media/js/lib/yui/yui3-3.15.0/build/uploader-flash/uploader-flash-debug.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 YUI.add('uploader-flash', function (Y, NAME) {
       
     2 
       
     3 /**
       
     4 * This module provides a UI for file selection and multiple file upload capability using
       
     5 * Flash as a transport engine.
       
     6 * The supported features include: automatic upload queue management, upload progress
       
     7 * tracking, file filtering, server response retrieval and error reporting.
       
     8 *
       
     9 * @module uploader-flash
       
    10 * @deprecated
       
    11 */
       
    12 
       
    13 // Shorthands for external modules
       
    14 var substitute            = Y.Lang.sub,
       
    15     UploaderQueue         = Y.Uploader.Queue;
       
    16 
       
    17 
       
    18 /**
       
    19  * Embed a Flash applications in a standard manner and communicate with it
       
    20  * via External Interface.
       
    21  * @module swf
       
    22  */
       
    23 
       
    24     var Event = Y.Event,
       
    25         SWFDetect = Y.SWFDetect,
       
    26         Lang = Y.Lang,
       
    27         uA = Y.UA,
       
    28         Node = Y.Node,
       
    29         Escape = Y.Escape,
       
    30 
       
    31         // private
       
    32         FLASH_CID = "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000",
       
    33         FLASH_TYPE = "application/x-shockwave-flash",
       
    34         FLASH_VER = "10.0.22",
       
    35         EXPRESS_INSTALL_URL = "http://fpdownload.macromedia.com/pub/flashplayer/update/current/swf/autoUpdater.swf?" + Math.random(),
       
    36         EVENT_HANDLER = "SWF.eventHandler",
       
    37         possibleAttributes = {align:"", allowFullScreen:"", allowNetworking:"", allowScriptAccess:"", base:"", bgcolor:"", loop:"", menu:"", name:"", play: "", quality:"", salign:"", scale:"", tabindex:"", wmode:""};
       
    38 
       
    39         /**
       
    40          * The SWF utility is a tool for embedding Flash applications in HTML pages.
       
    41          * @module swf
       
    42          * @title SWF Utility
       
    43          * @requires event-custom, node, swfdetect
       
    44          */
       
    45 
       
    46         /**
       
    47          * Creates the SWF instance and keeps the configuration data
       
    48          *
       
    49          * @class SWF
       
    50          * @uses Y.Event.Target
       
    51          * @constructor
       
    52          * @param {String|HTMLElement} id The id of the element, or the element itself that the SWF will be inserted into.
       
    53          *        The width and height of the SWF will be set to the width and height of this container element.
       
    54          * @param {String} swfURL The URL of the SWF to be embedded into the page.
       
    55          * @param {Object} p_oAttributes (optional) Configuration parameters for the Flash application and values for Flashvars
       
    56          *        to be passed to the SWF. The p_oAttributes object allows the following additional properties:
       
    57          *        <dl>
       
    58          *          <dt>version : String</dt>
       
    59          *          <dd>The minimum version of Flash required on the user's machine.</dd>
       
    60          *          <dt>fixedAttributes : Object</dt>
       
    61          *          <dd>An object literal containing one or more of the following String keys and their values: <code>align,
       
    62          *              allowFullScreen, allowNetworking, allowScriptAccess, base, bgcolor, menu, name, quality, salign, scale,
       
    63          *              tabindex, wmode.</code> event from the thumb</dd>
       
    64          *        </dl>
       
    65          */
       
    66 
       
    67 function SWF (p_oElement /*:String*/, swfURL /*:String*/, p_oAttributes /*:Object*/ ) {
       
    68 
       
    69     this._id = Y.guid("yuiswf");
       
    70 
       
    71 
       
    72     var _id = this._id;
       
    73     var oElement = Node.one(p_oElement);
       
    74 
       
    75     var p_oAttributes = p_oAttributes || {};
       
    76 
       
    77     var flashVersion = p_oAttributes.version || FLASH_VER;
       
    78 
       
    79     var flashVersionSplit = (flashVersion + '').split(".");
       
    80     var isFlashVersionRight = SWFDetect.isFlashVersionAtLeast(parseInt(flashVersionSplit[0], 10), parseInt(flashVersionSplit[1], 10), parseInt(flashVersionSplit[2], 10));
       
    81     var canExpressInstall = (SWFDetect.isFlashVersionAtLeast(8,0,0));
       
    82     var shouldExpressInstall = canExpressInstall && !isFlashVersionRight && p_oAttributes.useExpressInstall;
       
    83     var flashURL = (shouldExpressInstall)?EXPRESS_INSTALL_URL:swfURL;
       
    84     var objstring = '<object ';
       
    85     var w, h;
       
    86     var flashvarstring = "yId=" + Y.id + "&YUISwfId=" + _id + "&YUIBridgeCallback=" + EVENT_HANDLER + "&allowedDomain=" + document.location.hostname;
       
    87 
       
    88     Y.SWF._instances[_id] = this;
       
    89     if (oElement && (isFlashVersionRight || shouldExpressInstall) && flashURL) {
       
    90         objstring += 'id="' + _id + '" ';
       
    91         if (uA.ie) {
       
    92             objstring += 'classid="' + FLASH_CID + '" ';
       
    93         } else {
       
    94             objstring += 'type="' + FLASH_TYPE + '" data="' + Escape.html(flashURL) + '" ';
       
    95         }
       
    96 
       
    97         w = "100%";
       
    98         h = "100%";
       
    99 
       
   100         objstring += 'width="' + w + '" height="' + h + '">';
       
   101 
       
   102         if (uA.ie) {
       
   103             objstring += '<param name="movie" value="' + Escape.html(flashURL) + '"/>';
       
   104         }
       
   105 
       
   106         for (var attribute in p_oAttributes.fixedAttributes) {
       
   107             if (possibleAttributes.hasOwnProperty(attribute)) {
       
   108                 objstring += '<param name="' + Escape.html(attribute) + '" value="' + Escape.html(p_oAttributes.fixedAttributes[attribute]) + '"/>';
       
   109             }
       
   110         }
       
   111 
       
   112         for (var flashvar in p_oAttributes.flashVars) {
       
   113             var fvar = p_oAttributes.flashVars[flashvar];
       
   114             if (Lang.isString(fvar)) {
       
   115                 flashvarstring += "&" + Escape.html(flashvar) + "=" + Escape.html(encodeURIComponent(fvar));
       
   116             }
       
   117         }
       
   118 
       
   119         if (flashvarstring) {
       
   120             objstring += '<param name="flashVars" value="' + flashvarstring + '"/>';
       
   121         }
       
   122 
       
   123         objstring += "</object>";
       
   124         //using innerHTML as setHTML/setContent causes some issues with ExternalInterface for IE versions of the player
       
   125         oElement.set("innerHTML", objstring);
       
   126 
       
   127         this._swf = Node.one("#" + _id);
       
   128     } else {
       
   129         /**
       
   130          * Fired when the Flash player version on the user's machine is
       
   131          * below the required value.
       
   132          *
       
   133          * @event wrongflashversion
       
   134          */
       
   135         var event = {};
       
   136         event.type = "wrongflashversion";
       
   137         this.publish("wrongflashversion", {fireOnce:true});
       
   138         this.fire("wrongflashversion", event);
       
   139     }
       
   140 }
       
   141 
       
   142 /**
       
   143  * @private
       
   144  * The static collection of all instances of the SWFs on the page.
       
   145  * @property _instances
       
   146  * @type Object
       
   147  */
       
   148 
       
   149 SWF._instances = SWF._instances || {};
       
   150 
       
   151 /**
       
   152  * @private
       
   153  * Handles an event coming from within the SWF and delegate it
       
   154  * to a specific instance of SWF.
       
   155  * @method eventHandler
       
   156  * @param swfid {String} the id of the SWF dispatching the event
       
   157  * @param event {Object} the event being transmitted.
       
   158  */
       
   159 SWF.eventHandler = function (swfid, event) {
       
   160     SWF._instances[swfid]._eventHandler(event);
       
   161 };
       
   162 
       
   163 SWF.prototype = {
       
   164     /**
       
   165      * @private
       
   166      * Propagates a specific event from Flash to JS.
       
   167      * @method _eventHandler
       
   168      * @param event {Object} The event to be propagated from Flash.
       
   169      */
       
   170     _eventHandler: function(event) {
       
   171         if (event.type === "swfReady") {
       
   172             this.publish("swfReady", {fireOnce:true});
       
   173             this.fire("swfReady", event);
       
   174         } else if(event.type === "log") {
       
   175             Y.log(event.message, event.category, this.toString());
       
   176         } else {
       
   177             this.fire(event.type, event);
       
   178         }
       
   179     },
       
   180 
       
   181         /**
       
   182      * Calls a specific function exposed by the SWF's
       
   183      * ExternalInterface.
       
   184      * @method callSWF
       
   185      * @param func {String} the name of the function to call
       
   186      * @param args {Array} the set of arguments to pass to the function.
       
   187      */
       
   188 
       
   189     callSWF: function (func, args)
       
   190     {
       
   191     if (!args) {
       
   192           args= [];
       
   193     }
       
   194         if (this._swf._node[func]) {
       
   195         return(this._swf._node[func].apply(this._swf._node, args));
       
   196         } else {
       
   197         return null;
       
   198         }
       
   199     },
       
   200 
       
   201     /**
       
   202      * Public accessor to the unique name of the SWF instance.
       
   203      *
       
   204      * @method toString
       
   205      * @return {String} Unique name of the SWF instance.
       
   206      */
       
   207     toString: function()
       
   208     {
       
   209         return "SWF " + this._id;
       
   210     }
       
   211 };
       
   212 
       
   213 Y.augment(SWF, Y.EventTarget);
       
   214 
       
   215 Y.SWF = SWF;
       
   216     /**
       
   217      * The FileFlash class provides a wrapper for a file pointer stored in Flash. The File wrapper
       
   218      * also implements the mechanics for uploading a file and tracking its progress.
       
   219      * @module file-flash
       
   220      */
       
   221     /**
       
   222      * The class provides a wrapper for a file pointer in Flash.
       
   223      * @class FileFlash
       
   224      * @extends Base
       
   225      * @constructor
       
   226      * @param {Object} config Configuration object.
       
   227      */
       
   228 
       
   229     var FileFlash = function(o) {
       
   230         FileFlash.superclass.constructor.apply(this, arguments);
       
   231     };
       
   232 
       
   233     Y.extend(FileFlash, Y.Base, {
       
   234 
       
   235        /**
       
   236         * Construction logic executed during FileFlash instantiation.
       
   237         *
       
   238         * @method initializer
       
   239         * @protected
       
   240         */
       
   241         initializer : function (cfg) {
       
   242             if (!this.get("id")) {
       
   243                 this._set("id", Y.guid("file"));
       
   244             }
       
   245         },
       
   246 
       
   247        /**
       
   248         * Handler of events dispatched by the Flash player.
       
   249         *
       
   250         * @method _swfEventHandler
       
   251         * @param {Event} event The event object received from the Flash player.
       
   252         * @protected
       
   253         */
       
   254         _swfEventHandler: function (event) {
       
   255           if (event.id === this.get("id")) {
       
   256           switch (event.type) {
       
   257             /**
       
   258              * Signals that this file's upload has started.
       
   259              *
       
   260              * @event uploadstart
       
   261              * @param event {Event} The event object for the `uploadstart` with the
       
   262              *                      following payload:
       
   263              *  <dl>
       
   264              *      <dt>uploader</dt>
       
   265              *          <dd>The Y.SWF instance of Flash uploader that's handling the upload.</dd>
       
   266              *  </dl>
       
   267              */
       
   268             case "uploadstart":
       
   269                  this.fire("uploadstart", {uploader: this.get("uploader")});
       
   270                  break;
       
   271             case "uploadprogress":
       
   272 
       
   273                   /**
       
   274                    * Signals that progress has been made on the upload of this file.
       
   275                    *
       
   276                    * @event uploadprogress
       
   277                    * @param event {Event} The event object for the `uploadprogress` with the
       
   278                    *                      following payload:
       
   279                    *  <dl>
       
   280                    *      <dt>originEvent</dt>
       
   281                    *          <dd>The original event fired by the Flash uploader instance.</dd>
       
   282                    *      <dt>bytesLoaded</dt>
       
   283                    *          <dd>The number of bytes of the file that has been uploaded.</dd>
       
   284                    *      <dt>bytesTotal</dt>
       
   285                    *          <dd>The total number of bytes in the file (the file size)</dd>
       
   286                    *      <dt>percentLoaded</dt>
       
   287                    *          <dd>The fraction of the file that has been uploaded, out of 100.</dd>
       
   288                    *  </dl>
       
   289                    */
       
   290                  this.fire("uploadprogress", {originEvent: event,
       
   291                                               bytesLoaded: event.bytesLoaded,
       
   292                                               bytesTotal: event.bytesTotal,
       
   293                                               percentLoaded: Math.min(100, Math.round(10000*event.bytesLoaded/event.bytesTotal)/100)
       
   294                                              });
       
   295                  this._set("bytesUploaded", event.bytesLoaded);
       
   296                  break;
       
   297             case "uploadcomplete":
       
   298 
       
   299                   /**
       
   300                    * Signals that this file's upload has completed, but data has not yet been received from the server.
       
   301                    *
       
   302                    * @event uploadfinished
       
   303                    * @param event {Event} The event object for the `uploadfinished` with the
       
   304                    *                      following payload:
       
   305                    *  <dl>
       
   306                    *      <dt>originEvent</dt>
       
   307                    *          <dd>The original event fired by the Flash player instance.</dd>
       
   308                    *  </dl>
       
   309                    */
       
   310                  this.fire("uploadfinished", {originEvent: event});
       
   311                  break;
       
   312             case "uploadcompletedata":
       
   313                 /**
       
   314                  * Signals that this file's upload has completed and data has been received from the server.
       
   315                  *
       
   316                  * @event uploadcomplete
       
   317                  * @param event {Event} The event object for the `uploadcomplete` with the
       
   318                  *                      following payload:
       
   319                  *  <dl>
       
   320                  *      <dt>originEvent</dt>
       
   321                  *          <dd>The original event fired by the Flash player instance.</dd>
       
   322                  *      <dt>data</dt>
       
   323                  *          <dd>The data returned by the server.</dd>
       
   324                  *  </dl>
       
   325                  */
       
   326                  this.fire("uploadcomplete", {originEvent: event,
       
   327                                               data: event.data});
       
   328                  break;
       
   329             case "uploadcancel":
       
   330 
       
   331                 /**
       
   332                  * Signals that this file's upload has been cancelled.
       
   333                  *
       
   334                  * @event uploadcancel
       
   335                  * @param event {Event} The event object for the `uploadcancel` with the
       
   336                  *                      following payload:
       
   337                  *  <dl>
       
   338                  *      <dt>originEvent</dt>
       
   339                  *          <dd>The original event fired by the Flash player instance.</dd>
       
   340                  *  </dl>
       
   341                  */
       
   342                  this.fire("uploadcancel", {originEvent: event});
       
   343                  break;
       
   344             case "uploaderror":
       
   345 
       
   346                 /**
       
   347                  * Signals that this file's upload has encountered an error.
       
   348                  *
       
   349                  * @event uploaderror
       
   350                  * @param event {Event} The event object for the `uploaderror` with the
       
   351                  *                      following payload:
       
   352                  *  <dl>
       
   353                  *      <dt>originEvent</dt>
       
   354                  *          <dd>The original event fired by the Flash player instance.</dd>
       
   355                  *      <dt>status</dt>
       
   356                  *          <dd>The status code reported by the Flash Player. If it's an HTTP error,
       
   357                  *                then this corresponds to the HTTP status code received by the uploader.</dd>
       
   358                  *      <dt>statusText</dt>
       
   359                  *          <dd>The text of the error event reported by the Flash Player.</dd>
       
   360                  *      <dt>source</dt>
       
   361                  *          <dd>Either "http" (if it's an HTTP error), or "io" (if it's a network transmission
       
   362                  *              error.)</dd>
       
   363                  *  </dl>
       
   364                  */
       
   365                  this.fire("uploaderror", {originEvent: event, status: event.status, statusText: event.message, source: event.source});
       
   366 
       
   367           }
       
   368         }
       
   369         },
       
   370 
       
   371        /**
       
   372         * Starts the upload of a specific file.
       
   373         *
       
   374         * @method startUpload
       
   375         * @param url {String} The URL to upload the file to.
       
   376         * @param parameters {Object} (optional) A set of key-value pairs to send as variables along with the file upload HTTP request.
       
   377         * @param fileFieldName {String} (optional) The name of the POST variable that should contain the uploaded file ('Filedata' by default)
       
   378         */
       
   379         startUpload: function(url, parameters, fileFieldName) {
       
   380 
       
   381         if (this.get("uploader")) {
       
   382 
       
   383             var myUploader = this.get("uploader"),
       
   384                 fileField = fileFieldName || "Filedata",
       
   385                 id = this.get("id"),
       
   386                 params = parameters || null;
       
   387 
       
   388             this._set("bytesUploaded", 0);
       
   389 
       
   390             myUploader.on("uploadstart", this._swfEventHandler, this);
       
   391             myUploader.on("uploadprogress", this._swfEventHandler, this);
       
   392             myUploader.on("uploadcomplete", this._swfEventHandler, this);
       
   393             myUploader.on("uploadcompletedata", this._swfEventHandler, this);
       
   394             myUploader.on("uploaderror", this._swfEventHandler, this);
       
   395 
       
   396             myUploader.callSWF("upload", [id, url, params, fileField]);
       
   397          }
       
   398 
       
   399         },
       
   400 
       
   401        /**
       
   402         * Cancels the upload of a specific file, if currently in progress.
       
   403         *
       
   404         * @method cancelUpload
       
   405         */
       
   406         cancelUpload: function () {
       
   407          if (this.get("uploader")) {
       
   408            this.get("uploader").callSWF("cancel", [this.get("id")]);
       
   409            this.fire("uploadcancel");
       
   410          }
       
   411         }
       
   412 
       
   413     }, {
       
   414 
       
   415        /**
       
   416         * The identity of the class.
       
   417         *
       
   418         * @property NAME
       
   419         * @type String
       
   420         * @default 'file'
       
   421         * @readOnly
       
   422         * @protected
       
   423         * @static
       
   424         */
       
   425         NAME: 'file',
       
   426 
       
   427        /**
       
   428         * The type of transport.
       
   429         *
       
   430         * @property TYPE
       
   431         * @type String
       
   432         * @default 'flash'
       
   433         * @readOnly
       
   434         * @protected
       
   435         * @static
       
   436         */
       
   437         TYPE: "flash",
       
   438 
       
   439        /**
       
   440         * Static property used to define the default attribute configuration of
       
   441         * the File.
       
   442         *
       
   443         * @property ATTRS
       
   444         * @type {Object}
       
   445         * @protected
       
   446         * @static
       
   447         */
       
   448         ATTRS: {
       
   449 
       
   450        /**
       
   451         * A String containing the unique id of the file wrapped by the FileFlash instance.
       
   452         * The id is supplied by the Flash player uploader.
       
   453         *
       
   454         * @attribute id
       
   455         * @type {String}
       
   456         * @initOnly
       
   457         */
       
   458         id: {
       
   459             writeOnce: "initOnly",
       
   460             value: null
       
   461         },
       
   462 
       
   463        /**
       
   464         * The size of the file wrapped by FileFlash. This value is supplied by the Flash player uploader.
       
   465         *
       
   466         * @attribute size
       
   467         * @type {Number}
       
   468         * @initOnly
       
   469         */
       
   470         size: {
       
   471             writeOnce: "initOnly",
       
   472             value: 0
       
   473         },
       
   474 
       
   475        /**
       
   476         * The name of the file wrapped by FileFlash. This value is supplied by the Flash player uploader.
       
   477         *
       
   478         * @attribute name
       
   479         * @type {String}
       
   480         * @initOnly
       
   481         */
       
   482         name: {
       
   483             writeOnce: "initOnly",
       
   484             value: null
       
   485         },
       
   486 
       
   487        /**
       
   488         * The date that the file wrapped by FileFlash was created on. This value is supplied by the Flash player uploader.
       
   489         *
       
   490         * @attribute dateCreated
       
   491         * @type {Date}
       
   492         * @initOnly
       
   493         */
       
   494         dateCreated: {
       
   495             writeOnce: "initOnly",
       
   496             value: null
       
   497         },
       
   498 
       
   499        /**
       
   500         * The date that the file wrapped by FileFlash was last modified on. This value is supplied by the Flash player uploader.
       
   501         *
       
   502         * @attribute dateModified
       
   503         * @type {Date}
       
   504         * @initOnly
       
   505         */
       
   506         dateModified: {
       
   507             writeOnce: "initOnly",
       
   508             value: null
       
   509         },
       
   510 
       
   511        /**
       
   512         * The number of bytes of the file that has been uploaded to the server. This value is
       
   513         * non-zero only while a file is being uploaded.
       
   514         *
       
   515         * @attribute bytesUploaded
       
   516         * @type {Date}
       
   517         * @readOnly
       
   518         */
       
   519         bytesUploaded: {
       
   520             readOnly: true,
       
   521             value: 0
       
   522         },
       
   523 
       
   524        /**
       
   525         * The type of the file wrapped by FileFlash. This value is provided by the Flash player
       
   526         * uploader.
       
   527         *
       
   528         * @attribute type
       
   529         * @type {String}
       
   530         * @initOnly
       
   531         */
       
   532         type: {
       
   533             writeOnce: "initOnly",
       
   534             value: null
       
   535         },
       
   536 
       
   537        /**
       
   538         * The instance of Y.SWF wrapping the Flash player uploader associated with this file.
       
   539         *
       
   540         * @attribute uploder
       
   541         * @type {SWF}
       
   542         * @initOnly
       
   543         */
       
   544         uploader: {
       
   545             writeOnce: "initOnly",
       
   546             value: null
       
   547         }
       
   548         }
       
   549     });
       
   550 
       
   551     Y.FileFlash = FileFlash;
       
   552 /**
       
   553 * This module provides a UI for file selection and multiple file upload capability
       
   554 * using Flash as a transport engine.
       
   555 * @class UploaderFlash
       
   556 * @extends Widget
       
   557 * @param {Object} config Configuration object.
       
   558 * @constructor
       
   559 * @deprecated
       
   560 */
       
   561 
       
   562 function UploaderFlash() {
       
   563     UploaderFlash.superclass.constructor.apply ( this, arguments );
       
   564 }
       
   565 
       
   566 
       
   567 
       
   568 Y.UploaderFlash = Y.extend(UploaderFlash, Y.Widget, {
       
   569 
       
   570     /**
       
   571     * Stored value of the current button state (based on
       
   572     * mouse events dispatched by the Flash player)
       
   573     * @property _buttonState
       
   574     * @type {String}
       
   575     * @protected
       
   576     */
       
   577     _buttonState: "up",
       
   578 
       
   579     /**
       
   580     * Stored value of the current button focus state (based
       
   581     * on keyboard and mouse events).
       
   582     * @property _buttonFocus
       
   583     * @type {Boolean}
       
   584     * @protected
       
   585     */
       
   586     _buttonFocus: false,
       
   587 
       
   588     /**
       
   589     * Stored value of the unique id for the container that holds the
       
   590     * Flash uploader.
       
   591     *
       
   592     * @property _swfContainerId
       
   593     * @type {String}
       
   594     * @protected
       
   595     */
       
   596     _swfContainerId: null,
       
   597 
       
   598     /**
       
   599     * Stored reference to the instance of SWF used to host the
       
   600     * Flash uploader.
       
   601     *
       
   602     * @property _swfReference
       
   603     * @type {SWF}
       
   604     * @protected
       
   605     */
       
   606     _swfReference: null,
       
   607 
       
   608     /**
       
   609     * Stored reference to the instance of Uploader.Queue used to manage
       
   610     * the upload process. This is a read-only property that only exists
       
   611     * during an active upload process. Only one queue can be active at
       
   612     * a time; if an upload start is attempted while a queue is active,
       
   613     * it will be ignored.
       
   614     *
       
   615     * @property queue
       
   616     * @type {Uploader.Queue}
       
   617     */
       
   618     queue: null,
       
   619 
       
   620     /**
       
   621     * Stored event bindings for keyboard navigation to and from the uploader.
       
   622     *
       
   623     * @property _tabElementBindings
       
   624     * @type {Object}
       
   625     * @protected
       
   626     */
       
   627     _tabElementBindings: null,
       
   628 
       
   629 
       
   630     /**
       
   631     * Construction logic executed during UploaderFlash instantiation.
       
   632     *
       
   633     * @method initializer
       
   634     * @protected
       
   635     */
       
   636     initializer : function () {
       
   637 
       
   638         // Assign protected variable values
       
   639         this._swfContainerId = Y.guid("uploader");
       
   640         this._swfReference = null;
       
   641         this.queue = null;
       
   642         this._buttonState = "up";
       
   643         this._buttonFocus = null;
       
   644         this._tabElementBindings = null;
       
   645         this._fileList = [];
       
   646 
       
   647         // Publish available events
       
   648 
       
   649         /**
       
   650         * Signals that files have been selected.
       
   651         *
       
   652         * @event fileselect
       
   653         * @param event {Event} The event object for the `fileselect` with the
       
   654         *                      following payload:
       
   655         *  <dl>
       
   656         *      <dt>fileList</dt>
       
   657         *          <dd>An `Array` of files selected by the user, encapsulated
       
   658         *              in Y.FileFlash objects.</dd>
       
   659         *  </dl>
       
   660         */
       
   661         this.publish("fileselect");
       
   662 
       
   663         /**
       
   664         * Signals that an upload of multiple files has been started.
       
   665         *
       
   666         * @event uploadstart
       
   667         * @param event {Event} The event object for the `uploadstart`.
       
   668         */
       
   669         this.publish("uploadstart");
       
   670 
       
   671         /**
       
   672         * Signals that an upload of a specific file has started.
       
   673         *
       
   674         * @event fileuploadstart
       
   675         * @param event {Event} The event object for the `fileuploadstart` with the
       
   676         *                      following payload:
       
   677         *  <dl>
       
   678         *      <dt>file</dt>
       
   679         *          <dd>A reference to the Y.File that dispatched the event.</dd>
       
   680         *      <dt>originEvent</dt>
       
   681         *          <dd>The original event dispatched by Y.File.</dd>
       
   682         *  </dl>
       
   683         */
       
   684         this.publish("fileuploadstart");
       
   685 
       
   686         /**
       
   687         * Reports on upload progress of a specific file.
       
   688         *
       
   689         * @event uploadprogress
       
   690         * @param event {Event} The event object for the `uploadprogress` with the
       
   691         *                      following payload:
       
   692         *  <dl>
       
   693         *      <dt>bytesLoaded</dt>
       
   694         *          <dd>The number of bytes of the file that has been uploaded</dd>
       
   695         *      <dt>bytesTotal</dt>
       
   696         *          <dd>The total number of bytes in the file</dd>
       
   697         *      <dt>percentLoaded</dt>
       
   698         *          <dd>The fraction of the file that has been uploaded, out of 100</dd>
       
   699         *      <dt>originEvent</dt>
       
   700         *          <dd>The original event dispatched by the SWF uploader</dd>
       
   701         *  </dl>
       
   702         */
       
   703         this.publish("uploadprogress");
       
   704 
       
   705         /**
       
   706         * Reports on the total upload progress of the file list.
       
   707         *
       
   708         * @event totaluploadprogress
       
   709         * @param event {Event} The event object for the `totaluploadprogress` with the
       
   710         *                      following payload:
       
   711         *  <dl>
       
   712         *      <dt>bytesLoaded</dt>
       
   713         *          <dd>The number of bytes of the file list that has been uploaded</dd>
       
   714         *      <dt>bytesTotal</dt>
       
   715         *          <dd>The total number of bytes in the file list</dd>
       
   716         *      <dt>percentLoaded</dt>
       
   717         *          <dd>The fraction of the file list that has been uploaded, out of 100</dd>
       
   718         *  </dl>
       
   719         */
       
   720         this.publish("totaluploadprogress");
       
   721 
       
   722         /**
       
   723         * Signals that a single file upload has been completed.
       
   724         *
       
   725         * @event uploadcomplete
       
   726         * @param event {Event} The event object for the `uploadcomplete` with the
       
   727         *                      following payload:
       
   728         *  <dl>
       
   729         *      <dt>file</dt>
       
   730         *          <dd>The pointer to the instance of `Y.File` whose upload has been completed.</dd>
       
   731         *      <dt>originEvent</dt>
       
   732         *          <dd>The original event fired by the SWF Uploader</dd>
       
   733         *      <dt>data</dt>
       
   734         *          <dd>Data returned by the server.</dd>
       
   735         *  </dl>
       
   736         */
       
   737         this.publish("uploadcomplete");
       
   738 
       
   739         /**
       
   740         * Signals that the upload process of the entire file list has been completed.
       
   741         *
       
   742         * @event alluploadscomplete
       
   743         * @param event {Event} The event object for the `alluploadscomplete`.
       
   744         */
       
   745         this.publish("alluploadscomplete");
       
   746 
       
   747         /**
       
   748         * Signals that a error has occurred in a specific file's upload process.
       
   749         *
       
   750         * @event uploaderror
       
   751         * @param event {Event} The event object for the `uploaderror` with the
       
   752         *                      following payload:
       
   753         *  <dl>
       
   754         *      <dt>originEvent</dt>
       
   755         *          <dd>The original error event fired by the SWF Uploader. </dd>
       
   756         *      <dt>file</dt>
       
   757         *          <dd>The pointer at the instance of Y.FileFlash that returned the error.</dd>
       
   758         *      <dt>source</dt>
       
   759         *          <dd>The source of the upload error, either "io" or "http"</dd>
       
   760         *      <dt>message</dt>
       
   761         *          <dd>The message that accompanied the error. Corresponds to the text of
       
   762         *              the error in cases where source is "io", and to the HTTP status for
       
   763                                      cases where source is "http".</dd>
       
   764         *  </dl>
       
   765         */
       
   766         this.publish("uploaderror");
       
   767 
       
   768         /**
       
   769         * Signals that a mouse has begun hovering over the `Select Files` button.
       
   770         *
       
   771         * @event mouseenter
       
   772         * @param event {Event} The event object for the `mouseenter` event.
       
   773         */
       
   774         this.publish("mouseenter");
       
   775 
       
   776         /**
       
   777         * Signals that a mouse has stopped hovering over the `Select Files` button.
       
   778         *
       
   779         * @event mouseleave
       
   780         * @param event {Event} The event object for the `mouseleave` event.
       
   781         */
       
   782         this.publish("mouseleave");
       
   783 
       
   784         /**
       
   785         * Signals that a mouse button has been pressed over the `Select Files` button.
       
   786         *
       
   787         * @event mousedown
       
   788         * @param event {Event} The event object for the `mousedown` event.
       
   789         */
       
   790         this.publish("mousedown");
       
   791 
       
   792         /**
       
   793         * Signals that a mouse button has been released over the `Select Files` button.
       
   794         *
       
   795         * @event mouseup
       
   796         * @param event {Event} The event object for the `mouseup` event.
       
   797         */
       
   798         this.publish("mouseup");
       
   799 
       
   800         /**
       
   801         * Signals that a mouse has been clicked over the `Select Files` button.
       
   802         *
       
   803         * @event click
       
   804         * @param event {Event} The event object for the `click` event.
       
   805         */
       
   806         this.publish("click");
       
   807     },
       
   808 
       
   809     /**
       
   810     * Creates the DOM structure for the UploaderFlash.
       
   811     * UploaderFlash's DOM structure consists of two layers: the base "Select Files"
       
   812     * button that can be replaced by the developer's widget of choice; and a transparent
       
   813     * Flash overlay positoned above the button that captures all input events.
       
   814     * The `position` style attribute of the `boundingBox` of the `Uploader` widget
       
   815     * is forced to be `relative`, in order to accommodate the Flash player overlay
       
   816     * (which is `position`ed `absolute`ly).
       
   817     *
       
   818     * @method renderUI
       
   819     * @protected
       
   820     */
       
   821     renderUI : function () {
       
   822         var boundingBox = this.get("boundingBox"),
       
   823             contentBox = this.get('contentBox'),
       
   824             selFilesButton = this.get("selectFilesButton"),
       
   825             flashContainer = Y.Node.create(substitute(UploaderFlash.FLASH_CONTAINER, {
       
   826                 swfContainerId: this._swfContainerId
       
   827             })),
       
   828             params = {
       
   829                 version: "10.0.45",
       
   830                 fixedAttributes: {
       
   831                     wmode: "transparent",
       
   832                     allowScriptAccess:"always",
       
   833                     allowNetworking:"all",
       
   834                     scale: "noscale"
       
   835                 }
       
   836             };
       
   837 
       
   838         boundingBox.setStyle("position", "relative");
       
   839         selFilesButton.setStyles({width: "100%", height: "100%"});
       
   840         contentBox.append(selFilesButton);
       
   841         contentBox.append(flashContainer);
       
   842 
       
   843         this._swfReference = new Y.SWF(flashContainer, this.get("swfURL"), params);
       
   844     },
       
   845 
       
   846     /**
       
   847     * Binds handlers to the UploaderFlash UI events and propagates attribute
       
   848     * values to the Flash player.
       
   849     * The propagation of initial values is set to occur once the Flash player
       
   850     * instance is ready (as indicated by the `swfReady` event.)
       
   851     *
       
   852     * @method bindUI
       
   853     * @protected
       
   854     */
       
   855     bindUI : function () {
       
   856 
       
   857         this._swfReference.on("swfReady", function () {
       
   858             this._setMultipleFiles();
       
   859             this._setFileFilters();
       
   860             this._triggerEnabled();
       
   861             this._attachTabElements();
       
   862             this.after("multipleFilesChange", this._setMultipleFiles, this);
       
   863             this.after("fileFiltersChange", this._setFileFilters, this);
       
   864             this.after("enabledChange", this._triggerEnabled, this);
       
   865             this.after("tabElementsChange", this._attachTabElements);
       
   866         }, this);
       
   867 
       
   868         this._swfReference.on("fileselect", this._updateFileList, this);
       
   869 
       
   870 
       
   871 
       
   872         // this._swfReference.on("trace", function (ev) {console.log(ev.message);});
       
   873 
       
   874         this._swfReference.on("mouseenter", function () {
       
   875             this.fire("mouseenter");
       
   876             this._setButtonClass("hover", true);
       
   877             if (this._buttonState === "down") {
       
   878                 this._setButtonClass("active", true);
       
   879             }
       
   880         }, this);
       
   881 
       
   882         this._swfReference.on("mouseleave", function () {
       
   883             this.fire("mouseleave");
       
   884             this._setButtonClass("hover", false);
       
   885             this._setButtonClass("active", false);
       
   886         }, this);
       
   887 
       
   888         this._swfReference.on("mousedown", function () {
       
   889             this.fire("mousedown");
       
   890             this._buttonState = "down";
       
   891             this._setButtonClass("active", true);
       
   892         }, this);
       
   893 
       
   894         this._swfReference.on("mouseup", function () {
       
   895             this.fire("mouseup");
       
   896             this._buttonState = "up";
       
   897             this._setButtonClass("active", false);
       
   898         }, this);
       
   899 
       
   900         this._swfReference.on("click", function () {
       
   901             this.fire("click");
       
   902             this._buttonFocus = true;
       
   903             this._setButtonClass("focus", true);
       
   904             Y.one("body").focus();
       
   905             this._swfReference._swf.focus();
       
   906         }, this);
       
   907     },
       
   908 
       
   909     /**
       
   910     * Attaches keyboard bindings to enabling tabbing to and from the instance of the Flash
       
   911     * player in the Uploader widget. If the previous and next elements are specified, the
       
   912     * keyboard bindings enable the user to tab from the `tabElements["from"]` node to the
       
   913     * Flash-powered "Select Files" button, and to the `tabElements["to"]` node.
       
   914     *
       
   915     * @method _attachTabElements
       
   916     * @protected
       
   917     * @param ev {Event} Optional event payload if called as a `tabElementsChange` handler.
       
   918     */
       
   919     _attachTabElements : function () {
       
   920         if (this.get("tabElements") !== null && this.get("tabElements").from !== null && this.get("tabElements").to !== null) {
       
   921 
       
   922             if (this._tabElementBindings !== null) {
       
   923                 this._tabElementBindings.from.detach();
       
   924                 this._tabElementBindings.to.detach();
       
   925                 this._tabElementBindings.tabback.detach();
       
   926                 this._tabElementBindings.tabforward.detach();
       
   927                 this._tabElementBindings.focus.detach();
       
   928                 this._tabElementBindings.blur.detach();
       
   929             }
       
   930             else {
       
   931                 this._tabElementBindings = {};
       
   932             }
       
   933 
       
   934             var fromElement = Y.one(this.get("tabElements").from),
       
   935                 toElement = Y.one(this.get("tabElements").to);
       
   936 
       
   937 
       
   938             this._tabElementBindings.from = fromElement.on("keydown", function (ev) {
       
   939                 if (ev.keyCode === 9 && !ev.shiftKey) {
       
   940                     ev.preventDefault();
       
   941                     this._swfReference._swf.setAttribute("tabindex", 0);
       
   942                     this._swfReference._swf.setAttribute("role", "button");
       
   943                     this._swfReference._swf.setAttribute("aria-label", this.get("selectButtonLabel"));
       
   944                     this._swfReference._swf.focus();
       
   945                 }
       
   946             }, this);
       
   947 
       
   948             this._tabElementBindings.to = toElement.on("keydown", function (ev) {
       
   949                 if (ev.keyCode === 9 && ev.shiftKey) {
       
   950                     ev.preventDefault();
       
   951                     this._swfReference._swf.setAttribute("tabindex", 0);
       
   952                     this._swfReference._swf.setAttribute("role", "button");
       
   953                     this._swfReference._swf.setAttribute("aria-label", this.get("selectButtonLabel"));
       
   954                     this._swfReference._swf.focus();
       
   955                 }
       
   956             }, this);
       
   957 
       
   958             this._tabElementBindings.tabback = this._swfReference.on("tabback", function () {
       
   959                 this._swfReference._swf.blur();
       
   960                 setTimeout(function () {
       
   961                     fromElement.focus();
       
   962                 }, 30);
       
   963             }, this);
       
   964 
       
   965             this._tabElementBindings.tabforward = this._swfReference.on("tabforward", function () {
       
   966                 this._swfReference._swf.blur();
       
   967                 setTimeout(function () {
       
   968                     toElement.focus();
       
   969                 }, 30);
       
   970             }, this);
       
   971 
       
   972             this._tabElementBindings.focus = this._swfReference._swf.on("focus", function () {
       
   973                 this._buttonFocus = true;
       
   974                 this._setButtonClass("focus", true);
       
   975             }, this);
       
   976 
       
   977             this._tabElementBindings.blur = this._swfReference._swf.on("blur", function () {
       
   978                 this._buttonFocus = false;
       
   979                 this._setButtonClass("focus", false);
       
   980             }, this);
       
   981         }
       
   982         else if (this._tabElementBindings !== null) {
       
   983             this._tabElementBindings.from.detach();
       
   984             this._tabElementBindings.to.detach();
       
   985             this._tabElementBindings.tabback.detach();
       
   986             this._tabElementBindings.tabforward.detach();
       
   987             this._tabElementBindings.focus.detach();
       
   988             this._tabElementBindings.blur.detach();
       
   989         }
       
   990     },
       
   991 
       
   992 
       
   993     /**
       
   994     * Adds or removes a specified state CSS class to the underlying uploader button.
       
   995     *
       
   996     * @method _setButtonClass
       
   997     * @protected
       
   998     * @param state {String} The name of the state enumerated in `buttonClassNames` attribute
       
   999     * from which to derive the needed class name.
       
  1000     * @param add {Boolean} A Boolean indicating whether to add or remove the class.
       
  1001     */
       
  1002     _setButtonClass : function (state, add) {
       
  1003         if (add) {
       
  1004             this.get("selectFilesButton").addClass(this.get("buttonClassNames")[state]);
       
  1005         }
       
  1006         else {
       
  1007             this.get("selectFilesButton").removeClass(this.get("buttonClassNames")[state]);
       
  1008         }
       
  1009     },
       
  1010 
       
  1011 
       
  1012     /**
       
  1013     * Syncs the state of the `fileFilters` attribute between the instance of UploaderFlash
       
  1014     * and the Flash player.
       
  1015     *
       
  1016     * @method _setFileFilters
       
  1017     * @private
       
  1018     */
       
  1019     _setFileFilters : function () {
       
  1020         if (this._swfReference && this.get("fileFilters").length > 0) {
       
  1021             this._swfReference.callSWF("setFileFilters", [this.get("fileFilters")]);
       
  1022         }
       
  1023     },
       
  1024 
       
  1025 
       
  1026 
       
  1027     /**
       
  1028     * Syncs the state of the `multipleFiles` attribute between this class
       
  1029     * and the Flash uploader.
       
  1030     *
       
  1031     * @method _setMultipleFiles
       
  1032     * @private
       
  1033     */
       
  1034     _setMultipleFiles : function () {
       
  1035         if (this._swfReference) {
       
  1036             this._swfReference.callSWF("setAllowMultipleFiles", [this.get("multipleFiles")]);
       
  1037         }
       
  1038     },
       
  1039 
       
  1040     /**
       
  1041     * Syncs the state of the `enabled` attribute between this class
       
  1042     * and the Flash uploader.
       
  1043     *
       
  1044     * @method _triggerEnabled
       
  1045     * @private
       
  1046     */
       
  1047     _triggerEnabled : function () {
       
  1048         if (this.get("enabled")) {
       
  1049             this._swfReference.callSWF("enable");
       
  1050             this._swfReference._swf.setAttribute("aria-disabled", "false");
       
  1051             this._setButtonClass("disabled", false);
       
  1052         }
       
  1053         else {
       
  1054             this._swfReference.callSWF("disable");
       
  1055             this._swfReference._swf.setAttribute("aria-disabled", "true");
       
  1056             this._setButtonClass("disabled", true);
       
  1057         }
       
  1058     },
       
  1059 
       
  1060     /**
       
  1061     * Getter for the `fileList` attribute
       
  1062     *
       
  1063     * @method _getFileList
       
  1064     * @private
       
  1065     */
       
  1066     _getFileList : function () {
       
  1067         return this._fileList.concat();
       
  1068     },
       
  1069 
       
  1070     /**
       
  1071     * Setter for the `fileList` attribute
       
  1072     *
       
  1073     * @method _setFileList
       
  1074     * @private
       
  1075     */
       
  1076     _setFileList : function (val) {
       
  1077         this._fileList = val.concat();
       
  1078         return this._fileList.concat();
       
  1079     },
       
  1080 
       
  1081     /**
       
  1082     * Adjusts the content of the `fileList` based on the results of file selection
       
  1083     * and the `appendNewFiles` attribute. If the `appendNewFiles` attribute is true,
       
  1084     * then selected files are appended to the existing list; otherwise, the list is
       
  1085     * cleared and populated with the newly selected files.
       
  1086     *
       
  1087     * @method _updateFileList
       
  1088     * @param ev {Event} The file selection event received from the uploader.
       
  1089     * @private
       
  1090     */
       
  1091     _updateFileList : function (ev) {
       
  1092 
       
  1093         Y.one("body").focus();
       
  1094         this._swfReference._swf.focus();
       
  1095 
       
  1096 
       
  1097         var newfiles = ev.fileList,
       
  1098             fileConfObjects = [],
       
  1099             parsedFiles = [],
       
  1100             swfRef = this._swfReference,
       
  1101             filterFunc = this.get("fileFilterFunction"),
       
  1102             oldfiles;
       
  1103 
       
  1104         Y.each(newfiles, function (value) {
       
  1105             var newFileConf = {};
       
  1106             newFileConf.id = value.fileId;
       
  1107             newFileConf.name = value.fileReference.name;
       
  1108             newFileConf.size = value.fileReference.size;
       
  1109             newFileConf.type = value.fileReference.type;
       
  1110             newFileConf.dateCreated = value.fileReference.creationDate;
       
  1111             newFileConf.dateModified = value.fileReference.modificationDate;
       
  1112             newFileConf.uploader = swfRef;
       
  1113 
       
  1114             fileConfObjects.push(newFileConf);
       
  1115         });
       
  1116 
       
  1117          if (filterFunc) {
       
  1118             Y.each(fileConfObjects, function (value) {
       
  1119                 var newfile = new Y.FileFlash(value);
       
  1120                 if (filterFunc(newfile)) {
       
  1121                     parsedFiles.push(newfile);
       
  1122                 }
       
  1123             });
       
  1124          }
       
  1125          else {
       
  1126             Y.each(fileConfObjects, function (value) {
       
  1127                 parsedFiles.push(new Y.FileFlash(value));
       
  1128             });
       
  1129          }
       
  1130 
       
  1131         if (parsedFiles.length > 0) {
       
  1132             oldfiles = this.get("fileList");
       
  1133 
       
  1134             this.set("fileList",
       
  1135                              this.get("appendNewFiles") ? oldfiles.concat(parsedFiles) : parsedFiles );
       
  1136 
       
  1137             this.fire("fileselect", { fileList: parsedFiles });
       
  1138         }
       
  1139 
       
  1140     },
       
  1141 
       
  1142 
       
  1143 
       
  1144     /**
       
  1145     * Handles and retransmits events fired by `Y.FileFlash` and `Y.Uploader.Queue`.
       
  1146     *
       
  1147     * @method _uploadEventHandler
       
  1148     * @param event The event dispatched during the upload process.
       
  1149     * @private
       
  1150     */
       
  1151     _uploadEventHandler : function (event) {
       
  1152 
       
  1153         switch (event.type) {
       
  1154             case "file:uploadstart":
       
  1155                  this.fire("fileuploadstart", event);
       
  1156                 break;
       
  1157             case "file:uploadprogress":
       
  1158                  this.fire("uploadprogress", event);
       
  1159                 break;
       
  1160             case "uploaderqueue:totaluploadprogress":
       
  1161                  this.fire("totaluploadprogress", event);
       
  1162                 break;
       
  1163             case "file:uploadcomplete":
       
  1164                  this.fire("uploadcomplete", event);
       
  1165                 break;
       
  1166             case "uploaderqueue:alluploadscomplete":
       
  1167                  this.queue = null;
       
  1168                  this.fire("alluploadscomplete", event);
       
  1169                 break;
       
  1170             case "file:uploaderror": //overflow intentional
       
  1171             case "uploaderqueue:uploaderror":
       
  1172                  this.fire("uploaderror", event);
       
  1173                 break;
       
  1174             case "file:uploadcancel": // overflow intentional
       
  1175             case "uploaderqueue:uploadcancel":
       
  1176                  this.fire("uploadcancel", event);
       
  1177             break;
       
  1178         }
       
  1179 
       
  1180     },
       
  1181 
       
  1182 
       
  1183 
       
  1184     /**
       
  1185     * Starts the upload of a specific file.
       
  1186     *
       
  1187     * @method upload
       
  1188     * @param file {FileFlash} Reference to the instance of the file to be uploaded.
       
  1189     * @param url {String} The URL to upload the file to.
       
  1190     * @param [postVars] {Object} A set of key-value pairs to send as variables along with the file upload HTTP request.
       
  1191     *                          If not specified, the values from the attribute `postVarsPerFile` are used instead.
       
  1192     */
       
  1193     upload : function (file, url, postvars) {
       
  1194 
       
  1195         var uploadURL = url || this.get("uploadURL"),
       
  1196             postVars = postvars || this.get("postVarsPerFile"),
       
  1197             fileId = file.get("id");
       
  1198 
       
  1199             postVars = postVars.hasOwnProperty(fileId) ? postVars[fileId] : postVars;
       
  1200 
       
  1201         if (file instanceof Y.FileFlash) {
       
  1202 
       
  1203             file.on("uploadstart", this._uploadEventHandler, this);
       
  1204             file.on("uploadprogress", this._uploadEventHandler, this);
       
  1205             file.on("uploadcomplete", this._uploadEventHandler, this);
       
  1206             file.on("uploaderror", this._uploadEventHandler, this);
       
  1207             file.on("uploadcancel", this._uploadEventHandler, this);
       
  1208 
       
  1209             file.startUpload(uploadURL, postVars, this.get("fileFieldName"));
       
  1210         }
       
  1211     },
       
  1212 
       
  1213     /**
       
  1214     * Starts the upload of all files on the file list, using an automated queue.
       
  1215     *
       
  1216     * @method uploadAll
       
  1217     * @param url {String} The URL to upload the files to.
       
  1218     * @param [postVars] {Object} A set of key-value pairs to send as variables along with the file upload HTTP request.
       
  1219     *                          If not specified, the values from the attribute `postVarsPerFile` are used instead.
       
  1220     */
       
  1221     uploadAll : function (url, postvars) {
       
  1222         this.uploadThese(this.get("fileList"), url, postvars);
       
  1223     },
       
  1224 
       
  1225     /**
       
  1226     * Starts the upload of the files specified in the first argument, using an automated queue.
       
  1227     *
       
  1228     * @method uploadThese
       
  1229     * @param files {Array} The list of files to upload.
       
  1230     * @param url {String} The URL to upload the files to.
       
  1231     * @param [postVars] {Object} A set of key-value pairs to send as variables along with the file upload HTTP request.
       
  1232     *                          If not specified, the values from the attribute `postVarsPerFile` are used instead.
       
  1233     */
       
  1234     uploadThese : function (files, url, postvars) {
       
  1235         if (!this.queue) {
       
  1236             var uploadURL = url || this.get("uploadURL"),
       
  1237                 postVars = postvars || this.get("postVarsPerFile");
       
  1238 
       
  1239             this.queue = new UploaderQueue({
       
  1240                 simUploads: this.get("simLimit"),
       
  1241                 errorAction: this.get("errorAction"),
       
  1242                 fileFieldName: this.get("fileFieldName"),
       
  1243                 fileList: files,
       
  1244                 uploadURL: uploadURL,
       
  1245                 perFileParameters: postVars,
       
  1246                 retryCount: this.get("retryCount")
       
  1247             });
       
  1248 
       
  1249             this.queue.on("uploadstart", this._uploadEventHandler, this);
       
  1250             this.queue.on("uploadprogress", this._uploadEventHandler, this);
       
  1251             this.queue.on("totaluploadprogress", this._uploadEventHandler, this);
       
  1252             this.queue.on("uploadcomplete", this._uploadEventHandler, this);
       
  1253             this.queue.on("alluploadscomplete", this._uploadEventHandler, this);
       
  1254             this.queue.on("alluploadscancelled", function () {this.queue = null;}, this);
       
  1255             this.queue.on("uploaderror", this._uploadEventHandler, this);
       
  1256             this.queue.startUpload();
       
  1257 
       
  1258             this.fire("uploadstart");
       
  1259         }
       
  1260     }
       
  1261 },
       
  1262 
       
  1263 {
       
  1264     /**
       
  1265     * The template for the Flash player container. Since the Flash player container needs
       
  1266     * to completely overlay the &lquot;Select Files&rqot; control, it's positioned absolutely,
       
  1267     * with width and height set to 100% of the parent.
       
  1268     *
       
  1269     * @property FLASH_CONTAINER
       
  1270     * @type {String}
       
  1271     * @static
       
  1272     * @default '<div id="{swfContainerId}" style="position:absolute; top:0px; left: 0px; margin: 0; padding: 0;
       
  1273     *           border: 0; width:100%; height:100%"></div>'
       
  1274     */
       
  1275     FLASH_CONTAINER: '<div id="{swfContainerId}" style="position:absolute; top:0px; left: 0px; margin: 0; ' +
       
  1276                      'padding: 0; border: 0; width:100%; height:100%"></div>',
       
  1277 
       
  1278     /**
       
  1279     * The template for the "Select Files" button.
       
  1280     *
       
  1281     * @property SELECT_FILES_BUTTON
       
  1282     * @type {String}
       
  1283     * @static
       
  1284     * @default "<button type='button' class='yui3-button' tabindex='-1'>{selectButtonLabel}</button>"
       
  1285     */
       
  1286     SELECT_FILES_BUTTON: "<button type='button' class='yui3-button' tabindex='-1'>{selectButtonLabel}</button>",
       
  1287 
       
  1288     /**
       
  1289     * The static property reflecting the type of uploader that `Y.Uploader`
       
  1290     * aliases. The UploaderFlash value is `"flash"`.
       
  1291     *
       
  1292     * @property TYPE
       
  1293     * @type {String}
       
  1294     * @static
       
  1295     */
       
  1296     TYPE: "flash",
       
  1297 
       
  1298     /**
       
  1299     * The identity of the widget.
       
  1300     *
       
  1301     * @property NAME
       
  1302     * @type String
       
  1303     * @default 'uploader'
       
  1304     * @readOnly
       
  1305     * @protected
       
  1306     * @static
       
  1307     */
       
  1308     NAME: "uploader",
       
  1309 
       
  1310     /**
       
  1311     * Static property used to define the default attribute configuration of
       
  1312     * the Widget.
       
  1313     *
       
  1314     * @property ATTRS
       
  1315     * @type {Object}
       
  1316     * @protected
       
  1317     * @static
       
  1318     */
       
  1319     ATTRS: {
       
  1320 
       
  1321         /**
       
  1322         * A Boolean indicating whether newly selected files should be appended
       
  1323         * to the existing file list, or whether they should replace it.
       
  1324         *
       
  1325         * @attribute appendNewFiles
       
  1326         * @type {Boolean}
       
  1327         * @default true
       
  1328         */
       
  1329         appendNewFiles : {
       
  1330             value: true
       
  1331         },
       
  1332 
       
  1333         /**
       
  1334         * The names of CSS classes that correspond to different button states
       
  1335         * of the "Select Files" control. These classes are assigned to the
       
  1336         * "Select Files" control based on the mouse states reported by the
       
  1337         * Flash player. The keys for the class names are:
       
  1338         * <ul>
       
  1339         *   <li> <strong>`hover`</strong>: the class corresponding to mouse hovering over
       
  1340         *      the "Select Files" button.</li>
       
  1341         *   <li> <strong>`active`</strong>: the class corresponding to mouse down state of
       
  1342         *      the "Select Files" button.</li>
       
  1343         *   <li> <strong>`disabled`</strong>: the class corresponding to the disabled state
       
  1344         *      of the "Select Files" button.</li>
       
  1345         *   <li> <strong>`focus`</strong>: the class corresponding to the focused state of
       
  1346         *      the "Select Files" button.</li>
       
  1347         * </ul>
       
  1348         * @attribute buttonClassNames
       
  1349         * @type {Object}
       
  1350         * @default { hover: "yui3-button-hover",
       
  1351         *            active: "yui3-button-active",
       
  1352         *            disabled: "yui3-button-disabled",
       
  1353         *            focus: "yui3-button-selected"
       
  1354         *          }
       
  1355         */
       
  1356         buttonClassNames: {
       
  1357             value: {
       
  1358                 "hover": "yui3-button-hover",
       
  1359                 "active": "yui3-button-active",
       
  1360                 "disabled": "yui3-button-disabled",
       
  1361                 "focus": "yui3-button-selected"
       
  1362             }
       
  1363         },
       
  1364 
       
  1365         /**
       
  1366         * A Boolean indicating whether the uploader is enabled or disabled for user input.
       
  1367         *
       
  1368         * @attribute enabled
       
  1369         * @type {Boolean}
       
  1370         * @default true
       
  1371         */
       
  1372         enabled : {
       
  1373             value: true
       
  1374         },
       
  1375 
       
  1376         /**
       
  1377         * The action  performed when an upload error occurs for a specific file being uploaded.
       
  1378         * The possible values are:
       
  1379         * <ul>
       
  1380         *   <li> <strong>`UploaderQueue.CONTINUE`</strong>: the error is ignored and the upload process is continued.</li>
       
  1381         *   <li> <strong>`UploaderQueue.STOP`</strong>: the upload process is stopped as soon as any other parallel file
       
  1382         *     uploads are finished.</li>
       
  1383         *   <li> <strong>`UploaderQueue.RESTART_ASAP`</strong>: the file is added back to the front of the queue.</li>
       
  1384         *   <li> <strong>`UploaderQueue.RESTART_AFTER`</strong>: the file is added to the back of the queue.</li>
       
  1385         * </ul>
       
  1386         * @attribute errorAction
       
  1387         * @type {String}
       
  1388         * @default UploaderQueue.CONTINUE
       
  1389         */
       
  1390         errorAction: {
       
  1391             value: "continue",
       
  1392             validator: function (val) {
       
  1393                 return (
       
  1394                     val === UploaderQueue.CONTINUE ||
       
  1395                     val === UploaderQueue.STOP ||
       
  1396                     val === UploaderQueue.RESTART_ASAP ||
       
  1397                     val === UploaderQueue.RESTART_AFTER
       
  1398                 );
       
  1399             }
       
  1400         },
       
  1401 
       
  1402         /**
       
  1403         * An array indicating what fileFilters should be applied to the file
       
  1404         * selection dialog. Each element in the array should be an object with
       
  1405         * the following key-value pairs:
       
  1406         * {
       
  1407         *   description : String
       
  1408          extensions: String of the form &lquot;*.ext1;*.ext2;*.ext3;...&rquot;
       
  1409         * }
       
  1410         * @attribute fileFilters
       
  1411         * @type {Array}
       
  1412         * @default []
       
  1413         */
       
  1414         fileFilters: {
       
  1415             value: []
       
  1416         },
       
  1417 
       
  1418         /**
       
  1419         * A filtering function that is applied to every file selected by the user.
       
  1420         * The function receives the `Y.File` object and must return a Boolean value.
       
  1421         * If a `false` value is returned, the file in question is not added to the
       
  1422         * list of files to be uploaded.
       
  1423         * Use this function to put limits on file sizes or check the file names for
       
  1424         * correct extension, but make sure that a server-side check is also performed,
       
  1425         * since any client-side restrictions are only advisory and can be circumvented.
       
  1426         *
       
  1427         * @attribute fileFilterFunction
       
  1428         * @type {Function}
       
  1429         * @default null
       
  1430         */
       
  1431         fileFilterFunction: {
       
  1432             value: null
       
  1433         },
       
  1434 
       
  1435         /**
       
  1436         * A String specifying what should be the POST field name for the file
       
  1437         * content in the upload request.
       
  1438         *
       
  1439         * @attribute fileFieldName
       
  1440         * @type {String}
       
  1441         * @default Filedata
       
  1442         */
       
  1443         fileFieldName: {
       
  1444             value: "Filedata"
       
  1445         },
       
  1446 
       
  1447         /**
       
  1448         * The array of files to be uploaded. All elements in the array
       
  1449         * must be instances of `Y.FileFlash` and be instantiated with a `fileId`
       
  1450         * retrieved from an instance of the uploader.
       
  1451         *
       
  1452         * @attribute fileList
       
  1453         * @type {Array}
       
  1454         * @default []
       
  1455         */
       
  1456         fileList: {
       
  1457             value: [],
       
  1458             getter: "_getFileList",
       
  1459             setter: "_setFileList"
       
  1460         },
       
  1461 
       
  1462         /**
       
  1463         * A Boolean indicating whether multiple file selection is enabled.
       
  1464         *
       
  1465         * @attribute multipleFiles
       
  1466         * @type {Boolean}
       
  1467         * @default false
       
  1468         */
       
  1469         multipleFiles: {
       
  1470             value: false
       
  1471         },
       
  1472 
       
  1473         /**
       
  1474         * An object, keyed by `fileId`, containing sets of key-value pairs
       
  1475         * that should be passed as POST variables along with each corresponding
       
  1476         * file. This attribute is only used if no POST variables are specifed
       
  1477         * in the upload method call.
       
  1478         *
       
  1479         * @attribute postVarsPerFile
       
  1480         * @type {Object}
       
  1481         * @default {}
       
  1482         */
       
  1483         postVarsPerFile: {
       
  1484             value: {}
       
  1485         },
       
  1486 
       
  1487         /**
       
  1488         * The label for the "Select Files" widget. This is the value that replaces the
       
  1489         * `{selectButtonLabel}` token in the `SELECT_FILES_BUTTON` template.
       
  1490         *
       
  1491         * @attribute selectButtonLabel
       
  1492         * @type {String}
       
  1493         * @default "Select Files"
       
  1494         */
       
  1495         selectButtonLabel: {
       
  1496             value: "Select Files"
       
  1497         },
       
  1498 
       
  1499         /**
       
  1500         * The widget that serves as the "Select Files" control for the file uploader
       
  1501         *
       
  1502         *
       
  1503         * @attribute selectFilesButton
       
  1504         * @type {Node | Widget}
       
  1505         * @default A standard HTML button with YUI CSS Button skin.
       
  1506         */
       
  1507         selectFilesButton : {
       
  1508             valueFn: function () {
       
  1509                 return Y.Node.create(substitute(Y.UploaderFlash.SELECT_FILES_BUTTON, {selectButtonLabel: this.get("selectButtonLabel")}));
       
  1510              }
       
  1511         },
       
  1512 
       
  1513         /**
       
  1514         * The number of files that can be uploaded
       
  1515         * simultaneously if the automatic queue management
       
  1516         * is used. This value can be in the range between 2
       
  1517         * and 5.
       
  1518         *
       
  1519         * @attribute simLimit
       
  1520         * @type {Number}
       
  1521         * @default 2
       
  1522         */
       
  1523         simLimit: {
       
  1524             value: 2,
       
  1525             validator: function (val) {
       
  1526                     return (val >= 2 && val <= 5);
       
  1527             }
       
  1528         },
       
  1529 
       
  1530         /**
       
  1531         * The URL to the SWF file of the flash uploader. A copy local to
       
  1532         * the server that hosts the page on which the uploader appears is
       
  1533         * recommended.
       
  1534         *
       
  1535         * @attribute swfURL
       
  1536         * @type {String}
       
  1537         * @default "flashuploader.swf" with a
       
  1538         * random GET parameter for IE (to prevent buggy behavior when the SWF
       
  1539         * is cached).
       
  1540         */
       
  1541         swfURL: {
       
  1542             valueFn: function () {
       
  1543                 var prefix = "flashuploader.swf";
       
  1544 
       
  1545                 if (Y.UA.ie > 0) {
       
  1546                     return (prefix + "?t=" + Y.guid("uploader"));
       
  1547                 }
       
  1548 
       
  1549                 return prefix;
       
  1550             }
       
  1551         },
       
  1552 
       
  1553         /**
       
  1554         * The id's or `Node` references of the DOM elements that precede
       
  1555         * and follow the `Select Files` button in the tab order. Specifying
       
  1556         * these allows keyboard navigation to and from the Flash player
       
  1557         * layer of the uploader.
       
  1558         * The two keys corresponding to the DOM elements are:
       
  1559         <ul>
       
  1560         *   <li> `from`: the id or the `Node` reference corresponding to the
       
  1561         *     DOM element that precedes the `Select Files` button in the tab order.</li>
       
  1562         *   <li> `to`: the id or the `Node` reference corresponding to the
       
  1563         *     DOM element that follows the `Select Files` button in the tab order.</li>
       
  1564         * </ul>
       
  1565         * @attribute tabElements
       
  1566         * @type {Object}
       
  1567         * @default null
       
  1568         */
       
  1569         tabElements: {
       
  1570             value: null
       
  1571         },
       
  1572 
       
  1573         /**
       
  1574         * The URL to which file upload requested are POSTed. Only used if a different url is not passed to the upload method call.
       
  1575         *
       
  1576         * @attribute uploadURL
       
  1577         * @type {String}
       
  1578         * @default ""
       
  1579         */
       
  1580         uploadURL: {
       
  1581             value: ""
       
  1582         },
       
  1583 
       
  1584         /**
       
  1585         * The number of times to try re-uploading a file that failed to upload before
       
  1586         * cancelling its upload.
       
  1587         *
       
  1588         * @attribute retryCount
       
  1589         * @type {Number}
       
  1590         * @default 3
       
  1591         */
       
  1592         retryCount: {
       
  1593             value: 3
       
  1594         }
       
  1595     }
       
  1596 });
       
  1597 
       
  1598 Y.UploaderFlash.Queue = UploaderQueue;
       
  1599 
       
  1600 
       
  1601 }, '@VERSION@', {
       
  1602     "requires": [
       
  1603         "swfdetect",
       
  1604         "escape",
       
  1605         "widget",
       
  1606         "base",
       
  1607         "cssbutton",
       
  1608         "node",
       
  1609         "event-custom",
       
  1610         "uploader-queue"
       
  1611     ]
       
  1612 });