src/cm/media/js/lib/yui/yui3-3.15.0/build/uploader-html5/uploader-html5-debug.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 YUI.add('uploader-html5', function (Y, NAME) {
       
     2 
       
     3 /**
       
     4 * This module provides a UI for file selection and multiple file upload capability using
       
     5 * HTML5 XMLHTTPRequest Level 2 as a transport engine.
       
     6 * The supported features include: automatic upload queue management, upload progress
       
     7 * tracking, drag-and-drop support, server response retrieval and error reporting.
       
     8 *
       
     9 * @module uploader-html5
       
    10 */
       
    11 
       
    12 // Shorthands for the external modules
       
    13 var  substitute  = Y.Lang.sub,
       
    14      UploaderQueue = Y.Uploader.Queue;
       
    15 
       
    16 /**
       
    17 * This module provides a UI for file selection and multiple file upload capability using
       
    18 * HTML5 XMLHTTPRequest Level 2 as a transport engine.
       
    19 * @class UploaderHTML5
       
    20 * @extends Widget
       
    21 * @constructor
       
    22 */
       
    23 function UploaderHTML5() {
       
    24     UploaderHTML5.superclass.constructor.apply ( this, arguments );
       
    25 }
       
    26 
       
    27 
       
    28 
       
    29 Y.UploaderHTML5 = Y.extend( UploaderHTML5, Y.Widget, {
       
    30 
       
    31     /**
       
    32     * Stored reference to the instance of the file input field used to
       
    33     * initiate the file selection dialog.
       
    34     *
       
    35     * @property _fileInputField
       
    36     * @type {Node}
       
    37     * @protected
       
    38     */
       
    39     _fileInputField: null,
       
    40 
       
    41     /**
       
    42     * Stored reference to the click event binding of the `Select Files`
       
    43     * button.
       
    44     *
       
    45     * @property _buttonBinding
       
    46     * @type {EventHandle}
       
    47     * @protected
       
    48     */
       
    49     _buttonBinding: null,
       
    50 
       
    51     /**
       
    52     * Stored reference to the instance of Uploader.Queue used to manage
       
    53     * the upload process. This is a read-only property that only exists
       
    54     * during an active upload process. Only one queue can be active at
       
    55     * a time; if an upload start is attempted while a queue is active,
       
    56     * it will be ignored.
       
    57     *
       
    58     * @property queue
       
    59     * @type {Uploader.Queue}
       
    60     */
       
    61     queue: null,
       
    62 
       
    63     // Y.UploaderHTML5 prototype
       
    64 
       
    65     /**
       
    66     * Construction logic executed during UploaderHTML5 instantiation.
       
    67     *
       
    68     * @method initializer
       
    69     * @protected
       
    70     */
       
    71     initializer : function () {
       
    72 
       
    73         this._fileInputField = null;
       
    74         this.queue = null;
       
    75         this._buttonBinding = null;
       
    76         this._fileList = [];
       
    77 
       
    78         // Publish available events
       
    79 
       
    80         /**
       
    81         * Signals that files have been selected.
       
    82         *
       
    83         * @event fileselect
       
    84         * @param event {Event} The event object for the `fileselect` with the
       
    85         *                      following payload:
       
    86         *  <dl>
       
    87         *      <dt>fileList</dt>
       
    88         *          <dd>An `Array` of files selected by the user, encapsulated
       
    89         *              in Y.FileHTML5 objects.</dd>
       
    90         *  </dl>
       
    91         */
       
    92         this.publish("fileselect");
       
    93 
       
    94         /**
       
    95         * Signals that an upload of multiple files has been started.
       
    96         *
       
    97         * @event uploadstart
       
    98         * @param event {Event} The event object for the `uploadstart`.
       
    99         */
       
   100         this.publish("uploadstart");
       
   101 
       
   102         /**
       
   103         * Signals that an upload of a specific file has started.
       
   104         *
       
   105         * @event fileuploadstart
       
   106         * @param event {Event} The event object for the `fileuploadstart` with the
       
   107         *                      following payload:
       
   108         *  <dl>
       
   109         *      <dt>file</dt>
       
   110         *          <dd>A reference to the Y.File that dispatched the event.</dd>
       
   111         *      <dt>originEvent</dt>
       
   112         *          <dd>The original event dispatched by Y.File.</dd>
       
   113         *  </dl>
       
   114         */
       
   115         this.publish("fileuploadstart");
       
   116 
       
   117         /**
       
   118         * Reports on upload progress of a specific file.
       
   119         *
       
   120         * @event uploadprogress
       
   121         * @param event {Event} The event object for the `uploadprogress` with the
       
   122         *                      following payload:
       
   123         *  <dl>
       
   124         *      <dt>file</dt>
       
   125         *          <dd>The pointer to the instance of `Y.File` that dispatched the event.</dd>
       
   126         *      <dt>bytesLoaded</dt>
       
   127         *          <dd>The number of bytes of the file that has been uploaded</dd>
       
   128         *      <dt>bytesTotal</dt>
       
   129         *          <dd>The total number of bytes in the file</dd>
       
   130         *      <dt>percentLoaded</dt>
       
   131         *          <dd>The fraction of the file that has been uploaded, out of 100</dd>
       
   132         *      <dt>originEvent</dt>
       
   133         *          <dd>The original event dispatched by the HTML5 uploader</dd>
       
   134         *  </dl>
       
   135         */
       
   136         this.publish("uploadprogress");
       
   137 
       
   138         /**
       
   139         * Reports on the total upload progress of the file list.
       
   140         *
       
   141         * @event totaluploadprogress
       
   142         * @param event {Event} The event object for the `totaluploadprogress` with the
       
   143         *                      following payload:
       
   144         *  <dl>
       
   145         *      <dt>bytesLoaded</dt>
       
   146         *          <dd>The number of bytes of the file list that has been uploaded</dd>
       
   147         *      <dt>bytesTotal</dt>
       
   148         *          <dd>The total number of bytes in the file list</dd>
       
   149         *      <dt>percentLoaded</dt>
       
   150         *          <dd>The fraction of the file list that has been uploaded, out of 100</dd>
       
   151         *  </dl>
       
   152         */
       
   153         this.publish("totaluploadprogress");
       
   154 
       
   155         /**
       
   156         * Signals that a single file upload has been completed.
       
   157         *
       
   158         * @event uploadcomplete
       
   159         * @param event {Event} The event object for the `uploadcomplete` with the
       
   160         *                      following payload:
       
   161         *  <dl>
       
   162         *      <dt>file</dt>
       
   163         *          <dd>The pointer to the instance of `Y.File` whose upload has been completed.</dd>
       
   164         *      <dt>originEvent</dt>
       
   165         *          <dd>The original event fired by the SWF Uploader</dd>
       
   166         *      <dt>data</dt>
       
   167         *          <dd>Data returned by the server.</dd>
       
   168         *  </dl>
       
   169         */
       
   170         this.publish("uploadcomplete");
       
   171 
       
   172         /**
       
   173         * Signals that the upload process of the entire file list has been completed.
       
   174         *
       
   175         * @event alluploadscomplete
       
   176         * @param event {Event} The event object for the `alluploadscomplete`.
       
   177         */
       
   178         this.publish("alluploadscomplete");
       
   179 
       
   180         /**
       
   181         * Signals that a error has occurred in a specific file's upload process.
       
   182         *
       
   183         * @event uploaderror
       
   184         * @param event {Event} The event object for the `uploaderror` with the
       
   185         *                      following payload:
       
   186         *  <dl>
       
   187         *      <dt>originEvent</dt>
       
   188         *          <dd>The original error event fired by the HTML5 Uploader. </dd>
       
   189         *      <dt>file</dt>
       
   190         *          <dd>The pointer at the instance of Y.File that returned the error.</dd>
       
   191         *      <dt>status</dt>
       
   192         *          <dd>The status reported by the XMLHttpRequest object.</dd>
       
   193         *      <dt>statusText</dt>
       
   194         *          <dd>The statusText reported by the XMLHttpRequest object.</dd>
       
   195         *  </dl>
       
   196         */
       
   197         this.publish("uploaderror");
       
   198 
       
   199         /**
       
   200         * Signals that a dragged object has entered into the uploader's associated drag-and-drop area.
       
   201         *
       
   202         * @event dragenter
       
   203         * @param event {Event} The event object for the `dragenter`.
       
   204         */
       
   205         this.publish("dragenter");
       
   206 
       
   207         /**
       
   208         * Signals that an object has been dragged over the uploader's associated drag-and-drop area.
       
   209         *
       
   210         * @event dragover
       
   211         * @param event {Event} The event object for the `dragover`.
       
   212         */
       
   213         this.publish("dragover");
       
   214 
       
   215         /**
       
   216         * Signals that an object has been dragged off of the uploader's associated drag-and-drop area.
       
   217         *
       
   218         * @event dragleave
       
   219         * @param event {Event} The event object for the `dragleave`.
       
   220         */
       
   221         this.publish("dragleave");
       
   222 
       
   223         /**
       
   224         * Signals that an object has been dropped over the uploader's associated drag-and-drop area.
       
   225         *
       
   226         * @event drop
       
   227         * @param event {Event} The event object for the `drop` with the
       
   228         *                      following payload:
       
   229         *  <dl>
       
   230         *      <dt>fileList</dt>
       
   231         *          <dd>An `Array` of files dropped by the user, encapsulated
       
   232         *              in Y.FileHTML5 objects.</dd>
       
   233         *  </dl>
       
   234         */
       
   235         this.publish("drop");
       
   236 
       
   237     },
       
   238 
       
   239     /**
       
   240     * Create the DOM structure for the UploaderHTML5.
       
   241     * UploaderHTML5's DOM structure consists of a "Select Files" button that can
       
   242     * be replaced by the developer's widget of choice; and a hidden file input field
       
   243     * that is used to instantiate the File Select dialog.
       
   244     *
       
   245     * @method renderUI
       
   246     * @protected
       
   247     */
       
   248     renderUI : function () {
       
   249         var contentBox = this.get('contentBox'),
       
   250             selButton = this.get("selectFilesButton");
       
   251 
       
   252         selButton.setStyles({width:"100%", height:"100%"});
       
   253         contentBox.append(selButton);
       
   254         this._fileInputField = Y.Node.create(UploaderHTML5.HTML5FILEFIELD_TEMPLATE);
       
   255         contentBox.append(this._fileInputField);
       
   256     },
       
   257 
       
   258     /**
       
   259     * Binds to the UploaderHTML5 UI and subscribes to the necessary events.
       
   260     *
       
   261     * @method bindUI
       
   262     * @protected
       
   263     */
       
   264     bindUI : function () {
       
   265 
       
   266         this._bindSelectButton();
       
   267         this._setMultipleFiles();
       
   268         this._setFileFilters();
       
   269         this._bindDropArea();
       
   270         this._triggerEnabled();
       
   271 
       
   272         this.after("multipleFilesChange", this._setMultipleFiles, this);
       
   273         this.after("fileFiltersChange", this._setFileFilters, this);
       
   274         this.after("enabledChange", this._triggerEnabled, this);
       
   275         this.after("selectFilesButtonChange", this._bindSelectButton, this);
       
   276         this.after("dragAndDropAreaChange", this._bindDropArea, this);
       
   277         this.after("tabIndexChange", function () {
       
   278             this.get("selectFilesButton").set("tabIndex", this.get("tabIndex"));
       
   279         }, this);
       
   280         this._fileInputField.on("change", this._updateFileList, this);
       
   281         this._fileInputField.on("click", function(event) {
       
   282             event.stopPropagation();
       
   283         }, this);
       
   284 
       
   285         this.get("selectFilesButton").set("tabIndex", this.get("tabIndex"));
       
   286     },
       
   287 
       
   288 
       
   289     /**
       
   290     * Recreates the file field to null out the previous list of files and
       
   291     * thus allow for an identical file list selection.
       
   292     *
       
   293     * @method _rebindFileField
       
   294     * @protected
       
   295     */
       
   296     _rebindFileField : function () {
       
   297         this._fileInputField.remove(true);
       
   298         this._fileInputField = Y.Node.create(UploaderHTML5.HTML5FILEFIELD_TEMPLATE);
       
   299         this.get("contentBox").append(this._fileInputField);
       
   300         this._fileInputField.on("change", this._updateFileList, this);
       
   301         this._setMultipleFiles();
       
   302         this._setFileFilters();
       
   303     },
       
   304 
       
   305 
       
   306     /**
       
   307     * Binds the specified drop area's drag and drop events to the
       
   308     * uploader's custom handler.
       
   309     *
       
   310     * @method _bindDropArea
       
   311     * @protected
       
   312     */
       
   313     _bindDropArea : function (event) {
       
   314         var ev = event || {prevVal: null},
       
   315             ddArea = this.get("dragAndDropArea");
       
   316 
       
   317         if (ev.prevVal !== null) {
       
   318             ev.prevVal.detach('drop', this._ddEventHandler);
       
   319             ev.prevVal.detach('dragenter', this._ddEventHandler);
       
   320             ev.prevVal.detach('dragover', this._ddEventHandler);
       
   321             ev.prevVal.detach('dragleave', this._ddEventHandler);
       
   322         }
       
   323 
       
   324         if (ddArea !== null) {
       
   325             ddArea.on('drop', this._ddEventHandler, this);
       
   326             ddArea.on('dragenter', this._ddEventHandler, this);
       
   327             ddArea.on('dragover', this._ddEventHandler, this);
       
   328             ddArea.on('dragleave', this._ddEventHandler, this);
       
   329         }
       
   330     },
       
   331 
       
   332     /**
       
   333     * Binds the instantiation of the file select dialog to the current file select
       
   334     * control.
       
   335     *
       
   336     * @method _bindSelectButton
       
   337     * @protected
       
   338     */
       
   339     _bindSelectButton : function () {
       
   340        this._buttonBinding = this.get("selectFilesButton").on("click", this.openFileSelectDialog, this);
       
   341     },
       
   342 
       
   343     /**
       
   344     * Handles the drag and drop events from the uploader's specified drop
       
   345     * area.
       
   346     *
       
   347     * @method _ddEventHandler
       
   348     * @protected
       
   349     */
       
   350     _ddEventHandler : function (event) {
       
   351 
       
   352 
       
   353         event.stopPropagation();
       
   354         event.preventDefault();
       
   355 
       
   356         if (Y.Array.indexOf(event._event.dataTransfer.types, 'Files') > -1) {
       
   357             switch (event.type) {
       
   358                 case "dragenter":
       
   359                     this.fire("dragenter");
       
   360                     break;
       
   361                 case "dragover":
       
   362                     this.fire("dragover");
       
   363                     break;
       
   364                 case "dragleave":
       
   365                     this.fire("dragleave");
       
   366                     break;
       
   367                 case "drop":
       
   368 
       
   369                     var newfiles = event._event.dataTransfer.files,
       
   370                         parsedFiles = [],
       
   371                         filterFunc = this.get("fileFilterFunction"),
       
   372                         oldfiles;
       
   373 
       
   374                     if (filterFunc) {
       
   375                         Y.each(newfiles, function (value) {
       
   376                             var newfile = new Y.FileHTML5(value);
       
   377                             if (filterFunc(newfile)) {
       
   378                                 parsedFiles.push(newfile);
       
   379                             }
       
   380                         });
       
   381                     }
       
   382                     else {
       
   383                         Y.each(newfiles, function (value) {
       
   384                             parsedFiles.push(new Y.FileHTML5(value));
       
   385                         });
       
   386                     }
       
   387 
       
   388                     if (parsedFiles.length > 0) {
       
   389                         oldfiles = this.get("fileList");
       
   390                         this.set("fileList",
       
   391                         this.get("appendNewFiles") ? oldfiles.concat(parsedFiles) : parsedFiles);
       
   392                         this.fire("fileselect", {fileList: parsedFiles});
       
   393                     }
       
   394 
       
   395                     this.fire("drop", {fileList: parsedFiles});
       
   396                     break;
       
   397             }
       
   398         }
       
   399     },
       
   400 
       
   401     /**
       
   402     * Adds or removes a specified state CSS class to the underlying uploader button.
       
   403     *
       
   404     * @method _setButtonClass
       
   405     * @protected
       
   406     * @param state {String} The name of the state enumerated in `buttonClassNames` attribute
       
   407     * from which to derive the needed class name.
       
   408     * @param add {Boolean} A Boolean indicating whether to add or remove the class.
       
   409     */
       
   410     _setButtonClass : function (state, add) {
       
   411         if (add) {
       
   412             this.get("selectFilesButton").addClass(this.get("buttonClassNames")[state]);
       
   413         }
       
   414         else {
       
   415             this.get("selectFilesButton").removeClass(this.get("buttonClassNames")[state]);
       
   416         }
       
   417     },
       
   418 
       
   419     /**
       
   420     * Syncs the state of the `multipleFiles` attribute between this class
       
   421     * and the file input field.
       
   422     *
       
   423     * @method _setMultipleFiles
       
   424     * @protected
       
   425     */
       
   426     _setMultipleFiles : function () {
       
   427         if (this.get("multipleFiles") === true) {
       
   428             this._fileInputField.set("multiple", "multiple");
       
   429         }
       
   430         else {
       
   431             this._fileInputField.set("multiple", "");
       
   432         }
       
   433     },
       
   434 
       
   435     /**
       
   436     * Syncs the state of the `fileFilters` attribute between this class
       
   437     * and the file input field.
       
   438     *
       
   439     * @method _setFileFilters
       
   440     * @protected
       
   441     */
       
   442     _setFileFilters : function () {
       
   443         if (this.get("fileFilters").length > 0) {
       
   444             this._fileInputField.set("accept", this.get("fileFilters").join(","));
       
   445         }
       
   446         else {
       
   447             this._fileInputField.set("accept", "");
       
   448         }
       
   449     },
       
   450 
       
   451 
       
   452     /**
       
   453     * Syncs the state of the `enabled` attribute between this class
       
   454     * and the underlying button.
       
   455     *
       
   456     * @method _triggerEnabled
       
   457     * @private
       
   458     */
       
   459     _triggerEnabled : function () {
       
   460         if (this.get("enabled") && this._buttonBinding === null) {
       
   461             this._bindSelectButton();
       
   462             this._setButtonClass("disabled", false);
       
   463             this.get("selectFilesButton").setAttribute("aria-disabled", "false");
       
   464         }
       
   465         else if (!this.get("enabled") && this._buttonBinding) {
       
   466             this._buttonBinding.detach();
       
   467             this._buttonBinding = null;
       
   468             this._setButtonClass("disabled", true);
       
   469             this.get("selectFilesButton").setAttribute("aria-disabled", "true");
       
   470         }
       
   471     },
       
   472 
       
   473     /**
       
   474     * Getter for the `fileList` attribute
       
   475     *
       
   476     * @method _getFileList
       
   477     * @private
       
   478     */
       
   479     _getFileList : function () {
       
   480         return this._fileList.concat();
       
   481     },
       
   482 
       
   483     /**
       
   484     * Setter for the `fileList` attribute
       
   485     *
       
   486     * @method _setFileList
       
   487     * @private
       
   488     */
       
   489     _setFileList : function (val) {
       
   490         this._fileList = val.concat();
       
   491         return this._fileList.concat();
       
   492     },
       
   493 
       
   494     /**
       
   495     * Adjusts the content of the `fileList` based on the results of file selection
       
   496     * and the `appendNewFiles` attribute. If the `appendNewFiles` attribute is true,
       
   497     * then selected files are appended to the existing list; otherwise, the list is
       
   498     * cleared and populated with the newly selected files.
       
   499     *
       
   500     * @method _updateFileList
       
   501     * @param ev {Event} The file selection event received from the uploader.
       
   502     * @protected
       
   503     */
       
   504     _updateFileList : function (ev) {
       
   505         var newfiles = ev.target.getDOMNode().files,
       
   506             parsedFiles = [],
       
   507             filterFunc = this.get("fileFilterFunction"),
       
   508             oldfiles;
       
   509 
       
   510         if (filterFunc) {
       
   511             Y.each(newfiles, function (value) {
       
   512                 var newfile = new Y.FileHTML5(value);
       
   513                 if (filterFunc(newfile)) {
       
   514                     parsedFiles.push(newfile);
       
   515                 }
       
   516             });
       
   517         }
       
   518         else {
       
   519             Y.each(newfiles, function (value) {
       
   520                 parsedFiles.push(new Y.FileHTML5(value));
       
   521             });
       
   522         }
       
   523 
       
   524         if (parsedFiles.length > 0) {
       
   525             oldfiles = this.get("fileList");
       
   526 
       
   527             this.set("fileList",
       
   528                     this.get("appendNewFiles") ? oldfiles.concat(parsedFiles) : parsedFiles );
       
   529 
       
   530             this.fire("fileselect", {fileList: parsedFiles});
       
   531         }
       
   532 
       
   533         this._rebindFileField();
       
   534     },
       
   535 
       
   536 
       
   537     /**
       
   538     * Handles and retransmits events fired by `Y.File` and `Y.Uploader.Queue`.
       
   539     *
       
   540     * @method _uploadEventHandler
       
   541     * @param event The event dispatched during the upload process.
       
   542     * @protected
       
   543     */
       
   544     _uploadEventHandler : function (event) {
       
   545 
       
   546         switch (event.type) {
       
   547             case "file:uploadstart":
       
   548                 this.fire("fileuploadstart", event);
       
   549                 break;
       
   550             case "file:uploadprogress":
       
   551                 this.fire("uploadprogress", event);
       
   552                 break;
       
   553             case "uploaderqueue:totaluploadprogress":
       
   554                 this.fire("totaluploadprogress", event);
       
   555                 break;
       
   556             case "file:uploadcomplete":
       
   557                 this.fire("uploadcomplete", event);
       
   558                 break;
       
   559             case "uploaderqueue:alluploadscomplete":
       
   560                 this.queue = null;
       
   561                 this.fire("alluploadscomplete", event);
       
   562                 break;
       
   563             case "file:uploaderror": // overflow intentional
       
   564             case "uploaderqueue:uploaderror":
       
   565                 this.fire("uploaderror", event);
       
   566                 break;
       
   567             case "file:uploadcancel": // overflow intentional
       
   568             case "uploaderqueue:uploadcancel":
       
   569                 this.fire("uploadcancel", event);
       
   570                 break;
       
   571         }
       
   572 
       
   573     },
       
   574 
       
   575     /**
       
   576     * Opens the File Selection dialog by simulating a click on the file input field.
       
   577     *
       
   578     * @method openFileSelectDialog
       
   579     */
       
   580     openFileSelectDialog : function () {
       
   581         var fileDomNode = this._fileInputField.getDOMNode();
       
   582         if (fileDomNode.click) {
       
   583             fileDomNode.click();
       
   584         }
       
   585     },
       
   586 
       
   587     /**
       
   588     * Starts the upload of a specific file.
       
   589     *
       
   590     * @method upload
       
   591     * @param file {File} Reference to the instance of the file to be uploaded.
       
   592     * @param url {String} The URL to upload the file to.
       
   593     * @param postVars {Object} (optional) A set of key-value pairs to send as variables along with the file upload HTTP request.
       
   594     *                          If not specified, the values from the attribute `postVarsPerFile` are used instead.
       
   595     */
       
   596     upload : function (file, url, postvars) {
       
   597 
       
   598         var uploadURL = url || this.get("uploadURL"),
       
   599             postVars = postvars || this.get("postVarsPerFile"),
       
   600             fileId = file.get("id");
       
   601 
       
   602         postVars = postVars.hasOwnProperty(fileId) ? postVars[fileId] : postVars;
       
   603 
       
   604         if (file instanceof Y.FileHTML5) {
       
   605 
       
   606             file.on("uploadstart", this._uploadEventHandler, this);
       
   607             file.on("uploadprogress", this._uploadEventHandler, this);
       
   608             file.on("uploadcomplete", this._uploadEventHandler, this);
       
   609             file.on("uploaderror", this._uploadEventHandler, this);
       
   610             file.on("uploadcancel", this._uploadEventHandler, this);
       
   611 
       
   612             file.startUpload(uploadURL, postVars, this.get("fileFieldName"));
       
   613         }
       
   614     },
       
   615 
       
   616    /**
       
   617     * Starts the upload of all files on the file list, using an automated queue.
       
   618     *
       
   619     * @method uploadAll
       
   620     * @param url {String} The URL to upload the files to.
       
   621     * @param [postVars] {Object} A set of key-value pairs to send as variables along with the file upload HTTP request.
       
   622     *                          If not specified, the values from the attribute `postVarsPerFile` are used instead.
       
   623     */
       
   624     uploadAll : function (url, postvars) {
       
   625         this.uploadThese(this.get("fileList"), url, postvars);
       
   626     },
       
   627 
       
   628     /**
       
   629     * Starts the upload of the files specified in the first argument, using an automated queue.
       
   630     *
       
   631     * @method uploadThese
       
   632     * @param files {Array} The list of files to upload.
       
   633     * @param url {String} The URL to upload the files to.
       
   634     * @param [postVars] {Object} A set of key-value pairs to send as variables along with the file upload HTTP request.
       
   635     *                          If not specified, the values from the attribute `postVarsPerFile` are used instead.
       
   636     */
       
   637     uploadThese : function (files, url, postvars) {
       
   638         if (!this.queue) {
       
   639             var uploadURL = url || this.get("uploadURL"),
       
   640                 postVars = postvars || this.get("postVarsPerFile");
       
   641 
       
   642             this.queue = new UploaderQueue({
       
   643                 simUploads: this.get("simLimit"),
       
   644                 errorAction: this.get("errorAction"),
       
   645                 fileFieldName: this.get("fileFieldName"),
       
   646                 fileList: files,
       
   647                 uploadURL: uploadURL,
       
   648                 perFileParameters: postVars,
       
   649                 retryCount: this.get("retryCount"),
       
   650                 uploadHeaders: this.get("uploadHeaders"),
       
   651                 withCredentials: this.get("withCredentials")
       
   652             });
       
   653 
       
   654             this.queue.on("uploadstart", this._uploadEventHandler, this);
       
   655             this.queue.on("uploadprogress", this._uploadEventHandler, this);
       
   656             this.queue.on("totaluploadprogress", this._uploadEventHandler, this);
       
   657             this.queue.on("uploadcomplete", this._uploadEventHandler, this);
       
   658             this.queue.on("alluploadscomplete", this._uploadEventHandler, this);
       
   659             this.queue.on("uploadcancel", this._uploadEventHandler, this);
       
   660             this.queue.on("uploaderror", this._uploadEventHandler, this);
       
   661             this.queue.startUpload();
       
   662 
       
   663             this.fire("uploadstart");
       
   664        }
       
   665        else if (this.queue._currentState === UploaderQueue.UPLOADING) {
       
   666             this.queue.set("perFileParameters", this.get("postVarsPerFile"));
       
   667             Y.each(files, function (file) {
       
   668                 this.queue.addToQueueBottom(file);
       
   669             }, this);
       
   670        }
       
   671     }
       
   672 }, {
       
   673 
       
   674     /**
       
   675     * The template for the hidden file input field container. The file input field will only
       
   676     * accept clicks if its visibility is set to hidden (and will not if it's `display` value
       
   677     * is set to `none`)
       
   678     *
       
   679     * @property HTML5FILEFIELD_TEMPLATE
       
   680     * @type {String}
       
   681     * @static
       
   682     */
       
   683     HTML5FILEFIELD_TEMPLATE: "<input type='file' style='visibility:hidden; width:0px; height: 0px;'>",
       
   684 
       
   685     /**
       
   686     * The template for the "Select Files" button.
       
   687     *
       
   688     * @property SELECT_FILES_BUTTON
       
   689     * @type {String}
       
   690     * @static
       
   691     * @default '<button type="button" class="yui3-button" role="button" aria-label="{selectButtonLabel}"
       
   692     *           tabindex="{tabIndex}">{selectButtonLabel}</button>'
       
   693     */
       
   694     SELECT_FILES_BUTTON: '<button type="button" class="yui3-button" role="button" aria-label="{selectButtonLabel}" ' +
       
   695                          'tabindex="{tabIndex}">{selectButtonLabel}</button>',
       
   696 
       
   697     /**
       
   698     * The static property reflecting the type of uploader that `Y.Uploader`
       
   699     * aliases. The UploaderHTML5 value is `"html5"`.
       
   700     *
       
   701     * @property TYPE
       
   702     * @type {String}
       
   703     * @static
       
   704     */
       
   705     TYPE: "html5",
       
   706 
       
   707     /**
       
   708     * The identity of the widget.
       
   709     *
       
   710     * @property NAME
       
   711     * @type String
       
   712     * @default 'uploader'
       
   713     * @readOnly
       
   714     * @protected
       
   715     * @static
       
   716     */
       
   717     NAME: "uploader",
       
   718 
       
   719     /**
       
   720     * Static property used to define the default attribute configuration of
       
   721     * the Widget.
       
   722     *
       
   723     * @property ATTRS
       
   724     * @type {Object}
       
   725     * @protected
       
   726     * @static
       
   727     */
       
   728     ATTRS: {
       
   729 
       
   730         /**
       
   731         * A Boolean indicating whether newly selected files should be appended
       
   732         * to the existing file list, or whether they should replace it.
       
   733         *
       
   734         * @attribute appendNewFiles
       
   735         * @type {Boolean}
       
   736         * @default true
       
   737         */
       
   738         appendNewFiles : {
       
   739             value: true
       
   740         },
       
   741 
       
   742         /**
       
   743         * The names of CSS classes that correspond to different button states
       
   744         * of the "Select Files" control. These classes are assigned to the
       
   745         * "Select Files" control based on the configuration of the uploader.
       
   746         * Currently, the only class name used is that corresponding to the
       
   747         * `disabled` state of the uploader. Other button states should be managed
       
   748         * directly via CSS selectors.
       
   749         * <ul>
       
   750         *   <li> <strong>`disabled`</strong>: the class corresponding to the disabled state
       
   751         *      of the "Select Files" button.</li>
       
   752         * </ul>
       
   753         * @attribute buttonClassNames
       
   754         * @type {Object}
       
   755         * @default {
       
   756         *            disabled: "yui3-button-disabled"
       
   757         *          }
       
   758         */
       
   759         buttonClassNames: {
       
   760             value: {
       
   761                 "hover": "yui3-button-hover",
       
   762                 "active": "yui3-button-active",
       
   763                 "disabled": "yui3-button-disabled",
       
   764                 "focus": "yui3-button-selected"
       
   765             }
       
   766         },
       
   767 
       
   768         /**
       
   769         * The node that serves as the drop target for files.
       
   770         *
       
   771         * @attribute dragAndDropArea
       
   772         * @type {Node}
       
   773         * @default null
       
   774         */
       
   775         dragAndDropArea: {
       
   776             value: null,
       
   777             setter: function (val) {
       
   778                 return Y.one(val);
       
   779             }
       
   780         },
       
   781 
       
   782         /**
       
   783         * A Boolean indicating whether the uploader is enabled or disabled for user input.
       
   784         *
       
   785         * @attribute enabled
       
   786         * @type {Boolean}
       
   787         * @default true
       
   788         */
       
   789         enabled : {
       
   790             value: true
       
   791         },
       
   792 
       
   793         /**
       
   794         * The action  performed when an upload error occurs for a specific file being uploaded.
       
   795         * The possible values are:
       
   796         * <ul>
       
   797         *   <li> <strong>`UploaderQueue.CONTINUE`</strong>: the error is ignored and the upload process is continued.</li>
       
   798         *   <li> <strong>`UploaderQueue.STOP`</strong>: the upload process is stopped as soon as any other parallel file
       
   799         *     uploads are finished.</li>
       
   800         *   <li> <strong>`UploaderQueue.RESTART_ASAP`</strong>: the file is added back to the front of the queue.</li>
       
   801         *   <li> <strong>`UploaderQueue.RESTART_AFTER`</strong>: the file is added to the back of the queue.</li>
       
   802         * </ul>
       
   803         * @attribute errorAction
       
   804         * @type {String}
       
   805         * @default UploaderQueue.CONTINUE
       
   806         */
       
   807         errorAction: {
       
   808             value: "continue",
       
   809             validator: function (val) {
       
   810                 return (
       
   811                     val === UploaderQueue.CONTINUE ||
       
   812                     val === UploaderQueue.STOP ||
       
   813                     val === UploaderQueue.RESTART_ASAP ||
       
   814                     val === UploaderQueue.RESTART_AFTER
       
   815                 );
       
   816             }
       
   817         },
       
   818 
       
   819         /**
       
   820         * An array indicating what fileFilters should be applied to the file
       
   821         * selection dialog. Each element in the array should be a string
       
   822         * indicating the Media (MIME) type for the files that should be supported
       
   823         * for selection. The Media type strings should be properly formatted
       
   824         * or this parameter will be ignored. Examples of valid strings include:
       
   825         * "audio/*", "video/*", "application/pdf", etc. More information
       
   826         * on valid Media type strings is available here:
       
   827         * http://www.iana.org/assignments/media-types/index.html
       
   828         * @attribute fileFilters
       
   829         * @type {Array}
       
   830         * @default []
       
   831         */
       
   832         fileFilters: {
       
   833             value: []
       
   834         },
       
   835 
       
   836         /**
       
   837         * A filtering function that is applied to every file selected by the user.
       
   838         * The function receives the `Y.File` object and must return a Boolean value.
       
   839         * If a `false` value is returned, the file in question is not added to the
       
   840         * list of files to be uploaded.
       
   841         * Use this function to put limits on file sizes or check the file names for
       
   842         * correct extension, but make sure that a server-side check is also performed,
       
   843         * since any client-side restrictions are only advisory and can be circumvented.
       
   844         *
       
   845         * @attribute fileFilterFunction
       
   846         * @type {Function}
       
   847         * @default null
       
   848         */
       
   849         fileFilterFunction: {
       
   850             value: null
       
   851         },
       
   852 
       
   853         /**
       
   854         * A String specifying what should be the POST field name for the file
       
   855         * content in the upload request.
       
   856         *
       
   857         * @attribute fileFieldName
       
   858         * @type {String}
       
   859         * @default Filedata
       
   860         */
       
   861         fileFieldName: {
       
   862             value: "Filedata"
       
   863         },
       
   864 
       
   865         /**
       
   866         * The array of files to be uploaded. All elements in the array
       
   867         * must be instances of `Y.File` and be instantiated with an instance
       
   868         * of native JavaScript File() class.
       
   869         *
       
   870         * @attribute fileList
       
   871         * @type {Array}
       
   872         * @default []
       
   873         */
       
   874         fileList: {
       
   875             value: [],
       
   876             getter: "_getFileList",
       
   877             setter: "_setFileList"
       
   878         },
       
   879 
       
   880         /**
       
   881         * A Boolean indicating whether multiple file selection is enabled.
       
   882         *
       
   883         * @attribute multipleFiles
       
   884         * @type {Boolean}
       
   885         * @default false
       
   886         */
       
   887         multipleFiles: {
       
   888             value: false
       
   889         },
       
   890 
       
   891         /**
       
   892         * An object, keyed by `fileId`, containing sets of key-value pairs
       
   893         * that should be passed as POST variables along with each corresponding
       
   894         * file. This attribute is only used if no POST variables are specifed
       
   895         * in the upload method call.
       
   896         *
       
   897         * @attribute postVarsPerFile
       
   898         * @type {Object}
       
   899         * @default {}
       
   900         */
       
   901         postVarsPerFile: {
       
   902             value: {}
       
   903         },
       
   904 
       
   905         /**
       
   906         * The label for the "Select Files" widget. This is the value that replaces the
       
   907         * `{selectButtonLabel}` token in the `SELECT_FILES_BUTTON` template.
       
   908         *
       
   909         * @attribute selectButtonLabel
       
   910         * @type {String}
       
   911         * @default "Select Files"
       
   912         */
       
   913         selectButtonLabel: {
       
   914             value: "Select Files"
       
   915         },
       
   916 
       
   917         /**
       
   918         * The widget that serves as the "Select Files control for the file uploader
       
   919         *
       
   920         *
       
   921         * @attribute selectFilesButton
       
   922         * @type {Node | Widget}
       
   923         * @default A standard HTML button with YUI CSS Button skin.
       
   924         */
       
   925         selectFilesButton : {
       
   926             valueFn: function () {
       
   927                 return Y.Node.create(substitute(Y.UploaderHTML5.SELECT_FILES_BUTTON, {
       
   928                     selectButtonLabel: this.get("selectButtonLabel"),
       
   929                     tabIndex: this.get("tabIndex")
       
   930                 }));
       
   931             }
       
   932         },
       
   933 
       
   934         /**
       
   935         * The number of files that can be uploaded
       
   936         * simultaneously if the automatic queue management
       
   937         * is used. This value can be in the range between 2
       
   938         * and 5.
       
   939         *
       
   940         * @attribute simLimit
       
   941         * @type {Number}
       
   942         * @default 2
       
   943         */
       
   944         simLimit: {
       
   945             value: 2,
       
   946             validator: function (val) {
       
   947                 return (val >= 1 && val <= 5);
       
   948             }
       
   949         },
       
   950 
       
   951         /**
       
   952         * The URL to which file upload requested are POSTed. Only used if a different url is not passed to the upload method call.
       
   953         *
       
   954         * @attribute uploadURL
       
   955         * @type {String}
       
   956         * @default ""
       
   957         */
       
   958         uploadURL: {
       
   959             value: ""
       
   960         },
       
   961 
       
   962         /**
       
   963         * Additional HTTP headers that should be included
       
   964         * in the upload request.
       
   965         *
       
   966         *
       
   967         * @attribute uploadHeaders
       
   968         * @type {Object}
       
   969         * @default {}
       
   970         */
       
   971         uploadHeaders: {
       
   972             value: {}
       
   973         },
       
   974 
       
   975         /**
       
   976         * A Boolean that specifies whether the file should be
       
   977         * uploaded with the appropriate user credentials for the
       
   978         * domain.
       
   979         *
       
   980         * @attribute withCredentials
       
   981         * @type {Boolean}
       
   982         * @default true
       
   983         */
       
   984         withCredentials: {
       
   985             value: true
       
   986         },
       
   987 
       
   988         /**
       
   989         * The number of times to try re-uploading a file that failed to upload before
       
   990         * cancelling its upload.
       
   991         *
       
   992         * @attribute retryCount
       
   993         * @type {Number}
       
   994         * @default 3
       
   995         */
       
   996         retryCount: {
       
   997             value: 3
       
   998         }
       
   999     }
       
  1000 });
       
  1001 
       
  1002 Y.UploaderHTML5.Queue = UploaderQueue;
       
  1003 
       
  1004 
       
  1005 
       
  1006 }, '@VERSION@', {"requires": ["widget", "node-event-simulate", "file-html5", "uploader-queue"]});