Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('file-html5', function (Y, NAME) {
2
 
3
    /**
4
     * The FileHTML5 class provides a wrapper for a file pointer in an HTML5 The File wrapper
5
     * also implements the mechanics for uploading a file and tracking its progress.
6
     * @module file-html5
7
     */
8
 
9
    /**
10
     * The class provides a wrapper for a file pointer.
11
     * @class FileHTML5
12
     * @extends Base
13
     * @constructor
14
     * @param {Object} config Configuration object.
15
     */
16
    var Lang = Y.Lang,
17
        Bind = Y.bind,
18
        Win = Y.config.win;
19
 
20
    var FileHTML5 = function(o) {
21
 
22
        var file = null;
23
 
24
        if (FileHTML5.isValidFile(o)) {
25
            file = o;
26
        }
27
        else if (FileHTML5.isValidFile(o.file)) {
28
            file = o.file;
29
        }
30
        else {
31
            file = false;
32
        }
33
 
34
        FileHTML5.superclass.constructor.apply(this, arguments);
35
 
36
        if (file && FileHTML5.canUpload()) {
37
           if (!this.get("file")) {
38
               this._set("file", file);
39
           }
40
 
41
           if (!this.get("name")) {
42
           this._set("name", file.name || file.fileName);
43
           }
44
 
45
           if (this.get("size") != (file.size || file.fileSize)) {
46
           this._set("size", file.size || file.fileSize);
47
           }
48
 
49
           if (!this.get("type")) {
50
           this._set("type", file.type);
51
           }
52
 
53
           if (file.hasOwnProperty("lastModifiedDate") && !this.get("dateModified")) {
54
               this._set("dateModified", file.lastModifiedDate);
55
           }
56
        }
57
    };
58
 
59
 
60
    Y.extend(FileHTML5, Y.Base, {
61
 
62
       /**
63
        * Construction logic executed during FileHTML5 instantiation.
64
        *
65
        * @method initializer
66
        * @protected
67
        */
68
        initializer : function (cfg) {
69
            if (!this.get("id")) {
70
                this._set("id", Y.guid("file"));
71
            }
72
        },
73
 
74
       /**
75
        * Handler of events dispatched by the XMLHTTPRequest.
76
        *
77
        * @method _uploadEventHandler
78
        * @param {Event} event The event object received from the XMLHTTPRequest.
79
        * @protected
80
        */
81
        _uploadEventHandler: function (event) {
82
            var xhr = this.get("xhr");
83
 
84
            switch (event.type) {
85
                case "progress":
86
                  /**
87
                   * Signals that progress has been made on the upload of this file.
88
                   *
89
                   * @event uploadprogress
90
                   * @param event {Event} The event object for the `uploadprogress` with the
91
                   *                      following payload:
92
                   *  <dl>
93
                   *      <dt>originEvent</dt>
94
                   *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
95
                   *      <dt>bytesLoaded</dt>
96
                   *          <dd>The number of bytes of the file that has been uploaded.</dd>
97
                   *      <dt>bytesTotal</dt>
98
                   *          <dd>The total number of bytes in the file (the file size)</dd>
99
                   *      <dt>percentLoaded</dt>
100
                   *          <dd>The fraction of the file that has been uploaded, out of 100.</dd>
101
                   *  </dl>
102
                   */
103
                   this.fire("uploadprogress", {originEvent: event,
104
                                               bytesLoaded: event.loaded,
105
                                               bytesTotal: this.get("size"),
106
                                               percentLoaded: Math.min(100, Math.round(10000*event.loaded/this.get("size"))/100)
107
                                               });
108
                   this._set("bytesUploaded", event.loaded);
109
                   break;
110
 
111
                case "load":
112
                  /**
113
                   * Signals that this file's upload has completed and data has been received from the server.
114
                   *
115
                   * @event uploadcomplete
116
                   * @param event {Event} The event object for the `uploadcomplete` with the
117
                   *                      following payload:
118
                   *  <dl>
119
                   *      <dt>originEvent</dt>
120
                   *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
121
                   *      <dt>data</dt>
122
                   *          <dd>The data returned by the server.</dd>
123
                   *  </dl>
124
                   */
125
 
126
                   if (xhr.status >= 200 && xhr.status <= 299) {
127
                        this.fire("uploadcomplete", {originEvent: event,
128
                                                     data: event.target.responseText});
129
                        var xhrupload = xhr.upload,
130
                            boundEventHandler = this.get("boundEventHandler");
131
 
132
                        xhrupload.removeEventListener ("progress", boundEventHandler);
133
                        xhrupload.removeEventListener ("error", boundEventHandler);
134
                        xhrupload.removeEventListener ("abort", boundEventHandler);
135
                        xhr.removeEventListener ("load", boundEventHandler);
136
                        xhr.removeEventListener ("error", boundEventHandler);
137
                        xhr.removeEventListener ("readystatechange", boundEventHandler);
138
 
139
                        this._set("xhr", null);
140
                   }
141
                   else {
142
                        this.fire("uploaderror", {originEvent: event,
143
                                                  data: xhr.responseText,
144
                                                  status: xhr.status,
145
                                                  statusText: xhr.statusText,
146
                                                  source: "http"});
147
                   }
148
                   break;
149
 
150
                case "error":
151
                  /**
152
                   * Signals that this file's upload has encountered an error.
153
                   *
154
                   * @event uploaderror
155
                   * @param event {Event} The event object for the `uploaderror` with the
156
                   *                      following payload:
157
                   *  <dl>
158
                   *      <dt>originEvent</dt>
159
                   *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
160
                   *      <dt>data</dt>
161
                   *          <dd>The data returned by the server.</dd>
162
                   *      <dt>status</dt>
163
                   *          <dd>The status code reported by the XMLHttpRequest. If it's an HTTP error,
164
                                  then this corresponds to the HTTP status code received by the uploader.</dd>
165
                   *      <dt>statusText</dt>
166
                   *          <dd>The text of the error event reported by the XMLHttpRequest instance</dd>
167
                   *      <dt>source</dt>
168
                   *          <dd>Either "http" (if it's an HTTP error), or "io" (if it's a network transmission
169
                   *              error.)</dd>
170
                   *
171
                   *  </dl>
172
                   */
173
                   this.fire("uploaderror", {originEvent: event,
174
                                                  data: xhr.responseText,
175
                                                  status: xhr.status,
176
                                                  statusText: xhr.statusText,
177
                                                  source: "io"});
178
                   break;
179
 
180
                case "abort":
181
 
182
                  /**
183
                   * Signals that this file's upload has been cancelled.
184
                   *
185
                   * @event uploadcancel
186
                   * @param event {Event} The event object for the `uploadcancel` with the
187
                   *                      following payload:
188
                   *  <dl>
189
                   *      <dt>originEvent</dt>
190
                   *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
191
                   *  </dl>
192
                   */
193
                   this.fire("uploadcancel", {originEvent: event});
194
                   break;
195
 
196
                case "readystatechange":
197
 
198
                  /**
199
                   * Signals that XMLHttpRequest has fired a readystatechange event.
200
                   *
201
                   * @event readystatechange
202
                   * @param event {Event} The event object for the `readystatechange` with the
203
                   *                      following payload:
204
                   *  <dl>
205
                   *      <dt>readyState</dt>
206
                   *          <dd>The readyState code reported by the XMLHttpRequest instance.</dd>
207
                   *      <dt>originEvent</dt>
208
                   *          <dd>The original event fired by the XMLHttpRequest instance.</dd>
209
                   *  </dl>
210
                   */
211
                   this.fire("readystatechange", {readyState: event.target.readyState,
212
                                                  originEvent: event});
213
                   break;
214
            }
215
        },
216
 
217
       /**
218
        * Starts the upload of a specific file.
219
        *
220
        * @method startUpload
221
        * @param url {String} The URL to upload the file to.
222
        * @param parameters {Object} (optional) A set of key-value pairs to send as variables along with the file upload HTTP request.
223
        * @param fileFieldName {String} (optional) The name of the POST variable that should contain the uploaded file ('Filedata' by default)
224
        */
225
        startUpload: function(url, parameters, fileFieldName) {
226
 
227
            this._set("bytesUploaded", 0);
228
 
229
            this._set("xhr", new XMLHttpRequest());
230
            this._set("boundEventHandler", Bind(this._uploadEventHandler, this));
231
 
232
            var uploadData = new FormData(),
233
                fileField = fileFieldName || "Filedata",
234
                xhr = this.get("xhr"),
235
                xhrupload = this.get("xhr").upload,
236
                boundEventHandler = this.get("boundEventHandler");
237
 
238
            Y.each(parameters, function (value, key) {uploadData.append(key, value);});
239
            uploadData.append(fileField, this.get("file"));
240
 
241
 
242
 
243
 
244
            xhr.addEventListener ("loadstart", boundEventHandler, false);
245
            xhrupload.addEventListener ("progress", boundEventHandler, false);
246
            xhr.addEventListener ("load", boundEventHandler, false);
247
            xhr.addEventListener ("error", boundEventHandler, false);
248
            xhrupload.addEventListener ("error", boundEventHandler, false);
249
            xhrupload.addEventListener ("abort", boundEventHandler, false);
250
            xhr.addEventListener ("abort", boundEventHandler, false);
251
            xhr.addEventListener ("loadend", boundEventHandler, false);
252
            xhr.addEventListener ("readystatechange", boundEventHandler, false);
253
 
254
            xhr.open("POST", url, true);
255
 
256
            xhr.withCredentials = this.get("xhrWithCredentials");
257
 
258
            Y.each(this.get("xhrHeaders"), function (value, key) {
259
                 xhr.setRequestHeader(key, value);
260
            });
261
 
262
            xhr.send(uploadData);
263
 
264
            /**
265
             * Signals that this file's upload has started.
266
             *
267
             * @event uploadstart
268
             * @param event {Event} The event object for the `uploadstart` with the
269
             *                      following payload:
270
             *  <dl>
271
             *      <dt>xhr</dt>
272
             *          <dd>The XMLHttpRequest instance handling the file upload.</dd>
273
             *  </dl>
274
             */
275
             this.fire("uploadstart", {xhr: xhr});
276
 
277
        },
278
 
279
       /**
280
        * Cancels the upload of a specific file, if currently in progress.
281
        *
282
        * @method cancelUpload
283
        */
284
        cancelUpload: function () {
285
            var xhr = this.get('xhr');
286
            if (xhr) {
287
                xhr.abort();
288
            }
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
 
503
}, '3.18.1', {"requires": ["base"]});