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