Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
694 steven 1
/**
2
 * jquery.plupload.queue.js
3
 *
4
 * Copyright 2009, Moxiecode Systems AB
5
 * Released under GPL License.
6
 *
7
 * License: http://www.plupload.com/license
8
 * Contributing: http://www.plupload.com/contributing
9
 */
10
 
11
/* global jQuery:true, alert:true */
12
 
13
/**
14
jQuery based implementation of the Plupload API - multi-runtime file uploading API.
15
 
16
To use the widget you must include _jQuery_. It is not meant to be extended in any way and is provided to be
17
used as it is.
18
 
19
@example
20
	<!-- Instantiating: -->
21
	<div id="uploader">
22
		<p>Your browser doesn't have Flash, Silverlight or HTML5 support.</p>
23
	</div>
24
 
25
	<script>
26
		$('#uploader').pluploadQueue({
27
			url : '../upload.php',
28
			filters : [
29
				{title : "Image files", extensions : "jpg,gif,png"}
30
			],
31
			rename: true,
32
			flash_swf_url : '../../js/Moxie.swf',
33
			silverlight_xap_url : '../../js/Moxie.xap',
34
		});
35
	</script>
36
 
37
@example
38
	// Retrieving a reference to plupload.Uploader object
39
	var uploader = $('#uploader').pluploadQueue();
40
 
41
	uploader.bind('FilesAdded', function() {
42
 
43
		// Autostart
44
		setTimeout(uploader.start, 1); // "detach" from the main thread
45
	});
46
 
47
@class pluploadQueue
48
@constructor
49
@param {Object} settings For detailed information about each option check documentation.
50
	@param {String} settings.url URL of the server-side upload handler.
51
	@param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled.
52
	@param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message.
53
	@param {Array} [settings.filters=[]] Set of file type filters, each one defined by hash of title and extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR`
54
	@param {String} [settings.flash_swf_url] URL of the Flash swf.
55
	@param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs.
56
	@param {Number|String} [settings.max_file_size] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`.
57
	@param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event.
58
	@param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message.
59
	@param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload.
60
	@param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog.
61
	@param {Boolean} [settings.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`.
62
	@param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess.
63
	@param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}`
64
		@param {Number} [settings.resize.width] If image is bigger, it will be resized.
65
		@param {Number} [settings.resize.height] If image is bigger, it will be resized.
66
		@param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100).
67
		@param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally.
68
	@param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails.
69
	@param {String} [settings.silverlight_xap_url] URL of the Silverlight xap.
70
	@param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files.
71
 
72
	@param {Boolean} [settings.dragdrop=true] Enable ability to add file to the queue by drag'n'dropping them from the desktop.
73
	@param {Boolean} [settings.rename=false] Enable ability to rename files in the queue.
74
	@param {Boolean} [settings.multiple_queues=true] Re-activate the widget after each upload procedure.
75
*/
76
;(function($, plupload) {
77
	var uploaders = {};
78
 
79
	function _(str) {
80
		return plupload.translate(str) || str;
81
	}
82
 
83
	function renderUI(id, target) {
84
		// Remove all existing non plupload items
85
		target.contents().each(function(i, node) {
86
			node = $(node);
87
 
88
			if (!node.is('.plupload')) {
89
				node.remove();
90
			}
91
		});
92
 
93
		target.prepend(
94
			'<div class="plupload_wrapper plupload_scroll">' +
95
				'<div id="' + id + '_container" class="plupload_container">' +
96
					'<div class="plupload">' +
97
						'<div class="plupload_header">' +
98
							'<div class="plupload_header_content">' +
99
								'<div class="plupload_header_title">' + _('Select files') + '</div>' +
100
								'<div class="plupload_header_text">' + _('Add files to the upload queue and click the start button.') + '</div>' +
101
							'</div>' +
102
						'</div>' +
103
 
104
						'<div class="plupload_content">' +
105
							'<div class="plupload_filelist_header">' +
106
								'<div class="plupload_file_name">' + _('Filename') + '</div>' +
107
								'<div class="plupload_file_action">&nbsp;</div>' +
108
								'<div class="plupload_file_status"><span>' + _('Status') + '</span></div>' +
109
								'<div class="plupload_file_size">' + _('Size') + '</div>' +
110
								'<div class="plupload_clearer">&nbsp;</div>' +
111
							'</div>' +
112
 
113
							'<ul id="' + id + '_filelist" class="plupload_filelist"></ul>' +
114
 
115
							'<div class="plupload_filelist_footer">' +
116
								'<div class="plupload_file_name">' +
117
									'<div class="plupload_buttons">' +
118
										'<a href="#" class="plupload_button plupload_add" id="' + id + '_browse">' + _('Add Files') + '</a>' +
119
										'<a href="#" class="plupload_button plupload_start">' + _('Start Upload') + '</a>' +
120
									'</div>' +
121
									'<span class="plupload_upload_status"></span>' +
122
								'</div>' +
123
								'<div class="plupload_file_action"></div>' +
124
								'<div class="plupload_file_status"><span class="plupload_total_status">0%</span></div>' +
125
								'<div class="plupload_file_size"><span class="plupload_total_file_size">0 b</span></div>' +
126
								'<div class="plupload_progress">' +
127
									'<div class="plupload_progress_container">' +
128
										'<div class="plupload_progress_bar"></div>' +
129
									'</div>' +
130
								'</div>' +
131
								'<div class="plupload_clearer">&nbsp;</div>' +
132
							'</div>' +
133
						'</div>' +
134
					'</div>' +
135
				'</div>' +
136
				'<input type="hidden" id="' + id + '_count" name="' + id + '_count" value="0" />' +
137
			'</div>'
138
		);
139
	}
140
 
141
	$.fn.pluploadQueue = function(settings) {
142
		if (settings) {
143
			this.each(function() {
144
				var uploader, target, id, contents_bak;
145
 
146
				target = $(this);
147
				id = target.attr('id');
148
 
149
				if (!id) {
150
					id = plupload.guid();
151
					target.attr('id', id);
152
				}
153
 
154
				contents_bak = target.html();
155
				renderUI(id, target);
156
 
157
				settings = $.extend({
158
					dragdrop : true,
159
					browse_button : id + '_browse',
160
					container : id
161
				}, settings);
162
 
163
				// Enable drag/drop (see PostInit handler as well)
164
				if (settings.dragdrop) {
165
					settings.drop_element = id + '_filelist';
166
				}
167
 
168
				uploader = new plupload.Uploader(settings);
169
 
170
				uploaders[id] = uploader;
171
 
172
				function handleStatus(file) {
173
					var actionClass;
174
 
175
					if (file.status == plupload.DONE) {
176
						actionClass = 'plupload_done';
177
					}
178
 
179
					if (file.status == plupload.FAILED) {
180
						actionClass = 'plupload_failed';
181
					}
182
 
183
					if (file.status == plupload.QUEUED) {
184
						actionClass = 'plupload_delete';
185
					}
186
 
187
					if (file.status == plupload.UPLOADING) {
188
						actionClass = 'plupload_uploading';
189
					}
190
 
191
					var icon = $('#' + file.id).attr('class', actionClass).find('a').css('display', 'block');
192
					if (file.hint) {
193
						icon.attr('title', file.hint);
194
					}
195
				}
196
 
197
				function updateTotalProgress() {
198
					$('span.plupload_total_status', target).html(uploader.total.percent + '%');
199
					$('div.plupload_progress_bar', target).css('width', uploader.total.percent + '%');
200
					$('span.plupload_upload_status', target).html(
201
						plupload.sprintf(_('Uploaded %d/%d files'), uploader.total.uploaded, uploader.files.length)
202
					);
203
				}
204
 
205
				function updateList() {
206
					var fileList = $('ul.plupload_filelist', target).html(''), inputCount = 0, inputHTML;
207
 
208
					$.each(uploader.files, function(i, file) {
209
						inputHTML = '';
210
 
211
						if (file.status == plupload.DONE) {
212
							if (file.target_name) {
213
								inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_tmpname" value="' + plupload.xmlEncode(file.target_name) + '" />';
214
							}
215
 
216
							inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_name" value="' + plupload.xmlEncode(file.name) + '" />';
217
							inputHTML += '<input type="hidden" name="' + id + '_' + inputCount + '_status" value="' + (file.status == plupload.DONE ? 'done' : 'failed') + '" />';
218
 
219
							inputCount++;
220
 
221
							$('#' + id + '_count').val(inputCount);
222
						}
223
 
224
						fileList.append(
225
							'<li id="' + file.id + '">' +
226
								'<div class="plupload_file_name"><span>' + file.name + '</span></div>' +
227
								'<div class="plupload_file_action"><a href="#"></a></div>' +
228
								'<div class="plupload_file_status">' + file.percent + '%</div>' +
229
								'<div class="plupload_file_size">' + plupload.formatSize(file.size) + '</div>' +
230
								'<div class="plupload_clearer">&nbsp;</div>' +
231
								inputHTML +
232
							'</li>'
233
						);
234
 
235
						handleStatus(file);
236
 
237
						$('#' + file.id + '.plupload_delete a').click(function(e) {
238
							$('#' + file.id).remove();
239
							uploader.removeFile(file);
240
 
241
							e.preventDefault();
242
						});
243
					});
244
 
245
					$('span.plupload_total_file_size', target).html(plupload.formatSize(uploader.total.size));
246
 
247
					if (uploader.total.queued === 0) {
248
						$('span.plupload_add_text', target).html(_('Add Files'));
249
					} else {
250
						$('span.plupload_add_text', target).html(plupload.sprintf(_('%d files queued'), uploader.total.queued));
251
					}
252
 
253
					$('a.plupload_start', target).toggleClass('plupload_disabled', uploader.files.length == (uploader.total.uploaded + uploader.total.failed));
254
 
255
					// Scroll to end of file list
256
					fileList[0].scrollTop = fileList[0].scrollHeight;
257
 
258
					updateTotalProgress();
259
 
260
					// Re-add drag message if there is no files
261
					if (!uploader.files.length && uploader.features.dragdrop && uploader.settings.dragdrop) {
262
						$('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
263
					}
264
				}
265
 
266
				function destroy() {
267
					delete uploaders[id];
268
					uploader.destroy();
269
					target.html(contents_bak);
270
					uploader = target = contents_bak = null;
271
				}
272
 
273
				uploader.bind("UploadFile", function(up, file) {
274
					$('#' + file.id).addClass('plupload_current_file');
275
				});
276
 
277
				uploader.bind('Init', function(up, res) {
278
					// Enable rename support
279
					if (!settings.unique_names && settings.rename) {
280
						target.on('click', '#' + id + '_filelist div.plupload_file_name span', function(e) {
281
							var targetSpan = $(e.target), file, parts, name, ext = "";
282
 
283
							// Get file name and split out name and extension
284
							file = up.getFile(targetSpan.parents('li')[0].id);
285
							name = file.name;
286
							parts = /^(.+)(\.[^.]+)$/.exec(name);
287
							if (parts) {
288
								name = parts[1];
289
								ext = parts[2];
290
							}
291
 
292
							// Display input element
293
							targetSpan.hide().after('<input type="text" />');
294
							targetSpan.next().val(name).focus().blur(function() {
295
								targetSpan.show().next().remove();
296
							}).keydown(function(e) {
297
								var targetInput = $(this);
298
 
299
								if (e.keyCode == 13) {
300
									e.preventDefault();
301
 
302
									// Rename file and glue extension back on
303
									file.name = targetInput.val() + ext;
304
									targetSpan.html(file.name);
305
									targetInput.blur();
306
								}
307
							});
308
						});
309
					}
310
 
311
					$('#' + id + '_container').attr('title', 'Using runtime: ' + res.runtime);
312
 
313
					$('a.plupload_start', target).click(function(e) {
314
						if (!$(this).hasClass('plupload_disabled')) {
315
							uploader.start();
316
						}
317
 
318
						e.preventDefault();
319
					});
320
 
321
					$('a.plupload_stop', target).click(function(e) {
322
						e.preventDefault();
323
						uploader.stop();
324
					});
325
 
326
					$('a.plupload_start', target).addClass('plupload_disabled');
327
				});
328
 
329
				uploader.bind("Error", function(up, err) {
330
					var file = err.file, message;
331
 
332
					if (file) {
333
						message = err.message;
334
 
335
						if (err.details) {
336
							message += " (" + err.details + ")";
337
						}
338
 
339
						if (err.code == plupload.FILE_SIZE_ERROR) {
340
							alert(_("Error: File too large:") + " " + file.name);
341
						}
342
 
343
						if (err.code == plupload.FILE_EXTENSION_ERROR) {
344
							alert(_("Error: Invalid file extension:") + " " + file.name);
345
						}
346
 
347
						file.hint = message;
348
						$('#' + file.id).attr('class', 'plupload_failed').find('a').css('display', 'block').attr('title', message);
349
					}
350
 
351
					if (err.code === plupload.INIT_ERROR) {
352
						setTimeout(function() {
353
							destroy();
354
						}, 1);
355
					}
356
				});
357
 
358
				uploader.bind("PostInit", function(up) {
359
					// features are populated only after input components are fully instantiated
360
					if (up.settings.dragdrop && up.features.dragdrop) {
361
						$('#' + id + '_filelist').append('<li class="plupload_droptext">' + _("Drag files here.") + '</li>');
362
					}
363
				});
364
 
365
				uploader.init();
366
 
367
				uploader.bind('StateChanged', function() {
368
					if (uploader.state === plupload.STARTED) {
369
						$('li.plupload_delete a,div.plupload_buttons', target).hide();
370
						uploader.disableBrowse(true);
371
 
372
						$('span.plupload_upload_status,div.plupload_progress,a.plupload_stop', target).css('display', 'block');
373
						$('span.plupload_upload_status', target).html('Uploaded ' + uploader.total.uploaded + '/' + uploader.files.length + ' files');
374
 
375
						if (settings.multiple_queues) {
376
							$('span.plupload_total_status,span.plupload_total_file_size', target).show();
377
						}
378
					} else {
379
						updateList();
380
						$('a.plupload_stop,div.plupload_progress', target).hide();
381
						$('a.plupload_delete', target).css('display', 'block');
382
 
383
						if (settings.multiple_queues && uploader.total.uploaded + uploader.total.failed == uploader.files.length) {
384
							$(".plupload_buttons,.plupload_upload_status", target).css("display", "inline");
385
							uploader.disableBrowse(false);
386
 
387
							$(".plupload_start", target).addClass("plupload_disabled");
388
							$('span.plupload_total_status,span.plupload_total_file_size', target).hide();
389
						}
390
					}
391
				});
392
 
393
				uploader.bind('FilesAdded', updateList);
394
 
395
				uploader.bind('FilesRemoved', function() {
396
					// since the whole file list is redrawn for every change in the queue
397
					// we need to scroll back to the file removal point to avoid annoying
398
					// scrolling to the bottom bug (see #926)
399
					var scrollTop = $('#' + id + '_filelist').scrollTop();
400
					updateList();
401
					$('#' + id + '_filelist').scrollTop(scrollTop);
402
				});
403
 
404
				uploader.bind('FileUploaded', function(up, file) {
405
					handleStatus(file);
406
				});
407
 
408
				uploader.bind("UploadProgress", function(up, file) {
409
					// Set file specific progress
410
					$('#' + file.id + ' div.plupload_file_status', target).html(file.percent + '%');
411
 
412
					handleStatus(file);
413
					updateTotalProgress();
414
				});
415
 
416
				// Call setup function
417
				if (settings.setup) {
418
					settings.setup(uploader);
419
				}
420
			});
421
 
422
			return this;
423
		} else {
424
			// Get uploader instance for specified element
425
			return uploaders[$(this[0]).attr('id')];
426
		}
427
	};
428
})(jQuery, plupload);