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