src/cm/media/js/lib/yui/yui_3.10.3/build/file-html5/file-html5.js
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     1 /*
       
     2 YUI 3.10.3 (build 2fb5187)
       
     3 Copyright 2013 Yahoo! Inc. All rights reserved.
       
     4 Licensed under the BSD License.
       
     5 http://yuilibrary.com/license/
       
     6 */
       
     7 
       
     8 YUI.add('file-html5', function (Y, NAME) {
       
     9 
       
    10     /**
       
    11      * The FileHTML5 class provides a wrapper for a file pointer in an HTML5 The File wrapper 
       
    12      * also implements the mechanics for uploading a file and tracking its progress.
       
    13      * @module file-html5
       
    14      */     
       
    15      
       
    16     /**
       
    17      * The class provides a wrapper for a file pointer.
       
    18      * @class FileHTML5
       
    19      * @extends Base
       
    20      * @constructor
       
    21      * @param {Object} config Configuration object.
       
    22      */
       
    23     var Lang = Y.Lang,
       
    24         Bind = Y.bind,
       
    25         Win = Y.config.win;
       
    26 
       
    27     var FileHTML5 = function(o) {
       
    28         
       
    29         var file = null;
       
    30 
       
    31         if (FileHTML5.isValidFile(o)) {
       
    32             file = o;
       
    33         }
       
    34         else if (FileHTML5.isValidFile(o.file)) {
       
    35             file = o.file;
       
    36         }
       
    37         else {
       
    38             file = false;
       
    39         }
       
    40 
       
    41         FileHTML5.superclass.constructor.apply(this, arguments);      
       
    42         
       
    43         if (file && FileHTML5.canUpload()) {
       
    44            if (!this.get("file")) {
       
    45                this._set("file", file);
       
    46            }
       
    47 
       
    48            if (!this.get("name")) {
       
    49            this._set("name", file.name || file.fileName);
       
    50            }
       
    51 
       
    52            if (this.get("size") != (file.size || file.fileSize)) {
       
    53            this._set("size", file.size || file.fileSize);
       
    54            }
       
    55 
       
    56            if (!this.get("type")) {
       
    57            this._set("type", file.type);
       
    58            }
       
    59 
       
    60            if (file.hasOwnProperty("lastModifiedDate") && !this.get("dateModified")) {
       
    61                this._set("dateModified", file.lastModifiedDate);
       
    62            }
       
    63         }
       
    64     };
       
    65 
       
    66 
       
    67     Y.extend(FileHTML5, Y.Base, {
       
    68 
       
    69        /**
       
    70         * Construction logic executed during FileHTML5 instantiation.
       
    71         *
       
    72         * @method initializer
       
    73         * @protected
       
    74         */
       
    75         initializer : function (cfg) {
       
    76             if (!this.get("id")) {
       
    77                 this._set("id", Y.guid("file"));
       
    78             }
       
    79         },
       
    80 
       
    81        /**
       
    82         * Handler of events dispatched by the XMLHTTPRequest.
       
    83         *
       
    84         * @method _uploadEventHandler
       
    85         * @param {Event} event The event object received from the XMLHTTPRequest.
       
    86         * @protected
       
    87         */      
       
    88         _uploadEventHandler: function (event) {
       
    89             var xhr = this.get("xhr");
       
    90 
       
    91             switch (event.type) {
       
    92                 case "progress":
       
    93                   /**
       
    94                    * Signals that progress has been made on the upload of this file. 
       
    95                    *
       
    96                    * @event uploadprogress
       
    97                    * @param event {Event} The event object for the `uploadprogress` with the
       
    98                    *                      following payload:
       
    99                    *  <dl>
       
   100                    *      <dt>originEvent</dt>
       
   101                    *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
       
   102                    *      <dt>bytesLoaded</dt>
       
   103                    *          <dd>The number of bytes of the file that has been uploaded.</dd>
       
   104                    *      <dt>bytesTotal</dt>
       
   105                    *          <dd>The total number of bytes in the file (the file size)</dd>
       
   106                    *      <dt>percentLoaded</dt>
       
   107                    *          <dd>The fraction of the file that has been uploaded, out of 100.</dd>
       
   108                    *  </dl>
       
   109                    */
       
   110                    this.fire("uploadprogress", {originEvent: event,
       
   111                                                bytesLoaded: event.loaded, 
       
   112                                                bytesTotal: this.get("size"), 
       
   113                                                percentLoaded: Math.min(100, Math.round(10000*event.loaded/this.get("size"))/100)
       
   114                                                });
       
   115                    this._set("bytesUploaded", event.loaded);
       
   116                    break;
       
   117 
       
   118                 case "load":
       
   119                   /**
       
   120                    * Signals that this file's upload has completed and data has been received from the server.
       
   121                    *
       
   122                    * @event uploadcomplete
       
   123                    * @param event {Event} The event object for the `uploadcomplete` with the
       
   124                    *                      following payload:
       
   125                    *  <dl>
       
   126                    *      <dt>originEvent</dt>
       
   127                    *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
       
   128                    *      <dt>data</dt>
       
   129                    *          <dd>The data returned by the server.</dd>
       
   130                    *  </dl>
       
   131                    */
       
   132 
       
   133                    if (xhr.status >= 200 && xhr.status <= 299) {
       
   134                         this.fire("uploadcomplete", {originEvent: event,
       
   135                                                      data: event.target.responseText});
       
   136                         var xhrupload = xhr.upload,
       
   137                             boundEventHandler = this.get("boundEventHandler");
       
   138     
       
   139                         xhrupload.removeEventListener ("progress", boundEventHandler);
       
   140                         xhrupload.removeEventListener ("error", boundEventHandler);
       
   141                         xhrupload.removeEventListener ("abort", boundEventHandler);
       
   142                         xhr.removeEventListener ("load", boundEventHandler); 
       
   143                         xhr.removeEventListener ("error", boundEventHandler);
       
   144                         xhr.removeEventListener ("readystatechange", boundEventHandler);
       
   145                         
       
   146                         this._set("xhr", null);
       
   147                    }
       
   148                    else {
       
   149                         this.fire("uploaderror", {originEvent: event,
       
   150                                                   status: xhr.status,
       
   151                                                   statusText: xhr.statusText,
       
   152                                                   source: "http"});
       
   153                    }                   
       
   154                    break;
       
   155 
       
   156                 case "error":
       
   157                   /**
       
   158                    * Signals that this file's upload has encountered an error. 
       
   159                    *
       
   160                    * @event uploaderror
       
   161                    * @param event {Event} The event object for the `uploaderror` with the
       
   162                    *                      following payload:
       
   163                    *  <dl>
       
   164                    *      <dt>originEvent</dt>
       
   165                    *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
       
   166                    *      <dt>status</dt>
       
   167                    *          <dd>The status code reported by the XMLHttpRequest. If it's an HTTP error,
       
   168                                   then this corresponds to the HTTP status code received by the uploader.</dd>
       
   169                    *      <dt>statusText</dt>
       
   170                    *          <dd>The text of the error event reported by the XMLHttpRequest instance</dd>
       
   171                    *      <dt>source</dt>
       
   172                    *          <dd>Either "http" (if it's an HTTP error), or "io" (if it's a network transmission 
       
   173                    *              error.)</dd>
       
   174                    *
       
   175                    *  </dl>
       
   176                    */
       
   177                    this.fire("uploaderror", {originEvent: event,
       
   178                                                   status: xhr.status,
       
   179                                                   statusText: xhr.statusText,
       
   180                                                   source: "io"});
       
   181                    break;
       
   182 
       
   183                 case "abort":
       
   184 
       
   185                   /**
       
   186                    * Signals that this file's upload has been cancelled. 
       
   187                    *
       
   188                    * @event uploadcancel
       
   189                    * @param event {Event} The event object for the `uploadcancel` with the
       
   190                    *                      following payload:
       
   191                    *  <dl>
       
   192                    *      <dt>originEvent</dt>
       
   193                    *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
       
   194                    *  </dl>
       
   195                    */
       
   196                    this.fire("uploadcancel", {originEvent: event});
       
   197                    break;
       
   198 
       
   199                 case "readystatechange":
       
   200 
       
   201                   /**
       
   202                    * Signals that XMLHttpRequest has fired a readystatechange event. 
       
   203                    *
       
   204                    * @event readystatechange
       
   205                    * @param event {Event} The event object for the `readystatechange` with the
       
   206                    *                      following payload:
       
   207                    *  <dl>
       
   208                    *      <dt>readyState</dt>
       
   209                    *          <dd>The readyState code reported by the XMLHttpRequest instance.</dd>
       
   210                    *      <dt>originEvent</dt>
       
   211                    *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
       
   212                    *  </dl>
       
   213                    */
       
   214                    this.fire("readystatechange", {readyState: event.target.readyState,
       
   215                                                   originEvent: event});
       
   216                    break;
       
   217             }
       
   218         },
       
   219 
       
   220        /**
       
   221         * Starts the upload of a specific file.
       
   222         *
       
   223         * @method startUpload
       
   224         * @param url {String} The URL to upload the file to.
       
   225         * @param parameters {Object} (optional) A set of key-value pairs to send as variables along with the file upload HTTP request.
       
   226         * @param fileFieldName {String} (optional) The name of the POST variable that should contain the uploaded file ('Filedata' by default)
       
   227         */
       
   228         startUpload: function(url, parameters, fileFieldName) {
       
   229          
       
   230             this._set("bytesUploaded", 0);
       
   231             
       
   232             this._set("xhr", new XMLHttpRequest());
       
   233             this._set("boundEventHandler", Bind(this._uploadEventHandler, this));
       
   234                          
       
   235             var uploadData = new FormData(),
       
   236                 fileField = fileFieldName || "Filedata",
       
   237                 xhr = this.get("xhr"),
       
   238                 xhrupload = this.get("xhr").upload,
       
   239                 boundEventHandler = this.get("boundEventHandler");
       
   240 
       
   241             Y.each(parameters, function (value, key) {uploadData.append(key, value);});
       
   242             uploadData.append(fileField, this.get("file"));
       
   243 
       
   244 
       
   245 
       
   246 
       
   247             xhr.addEventListener ("loadstart", boundEventHandler, false);
       
   248             xhrupload.addEventListener ("progress", boundEventHandler, false);
       
   249             xhr.addEventListener ("load", boundEventHandler, false);
       
   250             xhr.addEventListener ("error", boundEventHandler, false);
       
   251             xhrupload.addEventListener ("error", boundEventHandler, false);
       
   252             xhrupload.addEventListener ("abort", boundEventHandler, false);
       
   253             xhr.addEventListener ("abort", boundEventHandler, false);
       
   254             xhr.addEventListener ("loadend", boundEventHandler, false); 
       
   255             xhr.addEventListener ("readystatechange", boundEventHandler, false);
       
   256 
       
   257             xhr.open("POST", url, true);
       
   258 
       
   259             xhr.withCredentials = this.get("xhrWithCredentials");
       
   260 
       
   261             Y.each(this.get("xhrHeaders"), function (value, key) {
       
   262                  xhr.setRequestHeader(key, value);
       
   263             });
       
   264 
       
   265             xhr.send(uploadData);
       
   266       
       
   267             /**
       
   268              * Signals that this file's upload has started. 
       
   269              *
       
   270              * @event uploadstart
       
   271              * @param event {Event} The event object for the `uploadstart` with the
       
   272              *                      following payload:
       
   273              *  <dl>
       
   274              *      <dt>xhr</dt>
       
   275              *          <dd>The XMLHttpRequest instance handling the file upload.</dd>
       
   276              *  </dl>
       
   277              */
       
   278              this.fire("uploadstart", {xhr: xhr});
       
   279 
       
   280         },
       
   281 
       
   282        /**
       
   283         * Cancels the upload of a specific file, if currently in progress.
       
   284         *
       
   285         * @method cancelUpload
       
   286         */    
       
   287         cancelUpload: function () {
       
   288             this.get('xhr').abort();
       
   289         }
       
   290 
       
   291 
       
   292     }, {
       
   293 
       
   294        /**
       
   295         * The identity of the class.
       
   296         *
       
   297         * @property NAME
       
   298         * @type String
       
   299         * @default 'file'
       
   300         * @readOnly
       
   301         * @protected
       
   302         * @static
       
   303         */
       
   304         NAME: 'file',
       
   305 
       
   306        /**
       
   307         * The type of transport.
       
   308         *
       
   309         * @property TYPE
       
   310         * @type String
       
   311         * @default 'html5'
       
   312         * @readOnly
       
   313         * @protected
       
   314         * @static
       
   315         */
       
   316         TYPE: 'html5',
       
   317 
       
   318        /**
       
   319         * Static property used to define the default attribute configuration of
       
   320         * the File.
       
   321         *
       
   322         * @property ATTRS
       
   323         * @type {Object}
       
   324         * @protected
       
   325         * @static
       
   326         */
       
   327         ATTRS: {
       
   328 
       
   329        /**
       
   330         * A String containing the unique id of the file wrapped by the FileFlash instance.
       
   331         * The id is supplied by the Flash player uploader.
       
   332         *
       
   333         * @attribute id
       
   334         * @type {String}
       
   335         * @initOnly
       
   336         */
       
   337         id: {
       
   338             writeOnce: "initOnly",
       
   339             value: null
       
   340         },
       
   341 
       
   342        /**
       
   343         * The size of the file wrapped by FileHTML5. This value is supplied by the instance of File().
       
   344         *
       
   345         * @attribute size
       
   346         * @type {Number}
       
   347         * @initOnly
       
   348         */
       
   349         size: {
       
   350             writeOnce: "initOnly",
       
   351             value: 0
       
   352         },
       
   353 
       
   354        /**
       
   355         * The name of the file wrapped by FileHTML5. This value is supplied by the instance of File().
       
   356         *
       
   357         * @attribute name
       
   358         * @type {String}
       
   359         * @initOnly
       
   360         */
       
   361         name: {
       
   362             writeOnce: "initOnly",
       
   363             value: null
       
   364         },
       
   365 
       
   366        /**
       
   367         * The date that the file wrapped by FileHTML5 was created on. This value is supplied by the instance of File().
       
   368         *
       
   369         * @attribute dateCreated
       
   370         * @type {Date}
       
   371         * @initOnly
       
   372         * @default null
       
   373         */
       
   374         dateCreated: {
       
   375             writeOnce: "initOnly",
       
   376             value: null
       
   377         },
       
   378 
       
   379        /**
       
   380         * The date that the file wrapped by FileHTML5 was last modified on. This value is supplied by the instance of File().
       
   381         *
       
   382         * @attribute dateModified
       
   383         * @type {Date}
       
   384         * @initOnly
       
   385         */
       
   386         dateModified: {
       
   387             writeOnce: "initOnly",
       
   388             value: null
       
   389         },
       
   390 
       
   391        /**
       
   392         * The number of bytes of the file that has been uploaded to the server. This value is
       
   393         * non-zero only while a file is being uploaded.
       
   394         *
       
   395         * @attribute bytesUploaded
       
   396         * @type {Date}
       
   397         * @readOnly
       
   398         */
       
   399         bytesUploaded: {
       
   400             readOnly: true,
       
   401             value: 0
       
   402         },
       
   403 
       
   404        /**
       
   405         * The type of the file wrapped by FileHTML. This value is provided by the instance of File()
       
   406         *
       
   407         * @attribute type
       
   408         * @type {String}
       
   409         * @initOnly
       
   410         */
       
   411         type: {
       
   412             writeOnce: "initOnly",
       
   413             value: null
       
   414         },
       
   415 
       
   416        /**
       
   417         * The pointer to the instance of File() wrapped by FileHTML5.
       
   418         *
       
   419         * @attribute file
       
   420         * @type {File}
       
   421         * @initOnly
       
   422         */
       
   423         file: {
       
   424             writeOnce: "initOnly",
       
   425             value: null
       
   426         },
       
   427 
       
   428        /**
       
   429         * The pointer to the instance of XMLHttpRequest used by FileHTML5 to upload the file.
       
   430         *
       
   431         * @attribute xhr
       
   432         * @type {XMLHttpRequest}
       
   433         * @initOnly
       
   434         */
       
   435         xhr: {
       
   436             readOnly: true,
       
   437             value: null
       
   438         },
       
   439 
       
   440        /**
       
   441         * The dictionary of headers that should be set on the XMLHttpRequest object before
       
   442         * sending it.
       
   443         *
       
   444         * @attribute xhrHeaders
       
   445         * @type {Object}
       
   446         * @initOnly
       
   447         */
       
   448         xhrHeaders: {
       
   449             value: {}
       
   450         },
       
   451 
       
   452        /**
       
   453         * A Boolean indicating whether the XMLHttpRequest should be sent with user credentials.
       
   454         * This does not affect same-site requests. 
       
   455         *
       
   456         * @attribute xhrWithCredentials
       
   457         * @type {Boolean}
       
   458         * @initOnly
       
   459         */
       
   460         xhrWithCredentials: {
       
   461             value: true
       
   462         },
       
   463 
       
   464        /**
       
   465         * The bound event handler used to handle events from XMLHttpRequest.
       
   466         *
       
   467         * @attribute boundEventHandler
       
   468         * @type {Function}
       
   469         * @initOnly
       
   470         */
       
   471         boundEventHandler: {
       
   472             readOnly: true,
       
   473             value: null
       
   474         }
       
   475         },
       
   476 
       
   477        /**
       
   478         * Checks whether a specific native file instance is valid
       
   479         *
       
   480         * @method isValidFile
       
   481         * @param file {File} A native File() instance.
       
   482         * @static
       
   483         */
       
   484         isValidFile: function (file) {
       
   485             return (Win && Win.File && file instanceof File);
       
   486         },
       
   487 
       
   488        /**
       
   489         * Checks whether the browser has a native upload capability
       
   490         * via XMLHttpRequest Level 2.
       
   491         *
       
   492         * @method canUpload
       
   493         * @static
       
   494         */
       
   495         canUpload: function () {
       
   496             return (Win && Win.FormData && Win.XMLHttpRequest);
       
   497         }
       
   498     });
       
   499 
       
   500     Y.FileHTML5 = FileHTML5;
       
   501 
       
   502 }, '3.10.3', {"requires": ["base"]});