view e2gallerypro/e2upload/Source/Uploader/Swiff.Uploader.js @ 7:3f89d9a017e2 judyates

[svn r8] try this shit
author rlm
date Mon, 22 Feb 2010 11:34:16 -0500
parents 3f6b44aa6b35
children
line wrap: on
line source
1 /**
2 * Swiff.Uploader - Flash FileReference Control
3 *
4 * @version 3.0 rc1
5 *
6 * @license MIT License
7 *
8 * @author Harald Kirschner <mail [at] digitarald [dot] de>
9 * @copyright Authors
10 */
12 Swiff.Uploader = new Class({
14 Extends: Swiff,
16 Implements: Events,
18 options: {
19 path: 'Swiff.Uploader.swf',
21 target: null,
22 zIndex: 9999,
24 height: 30,
25 width: 100,
26 callBacks: null,
27 params: {
28 wMode: 'opaque',
29 menu: 'false',
30 allowScriptAccess: 'always'
31 },
33 typeFilter: null,
34 multiple: true,
35 queued: true,
36 verbose: false,
38 url: null,
39 method: null,
40 data: null,
41 mergeData: true,
42 fieldName: null,
44 fileSizeMin: 1,
45 fileSizeMax: null, // Official limit is 100 MB for FileReference!
46 allowDuplicates: false,
48 buttonImage: null,
50 fileListMax: 0,
51 fileListSizeMax: 0,
53 instantStart: false,
54 appendCookieData: false,
56 fileClass: null
57 /*
58 onLoad: $empty,
59 onFail: $empty,
60 onStart: $empty,
61 onQueue: $empty,
62 onComplete: $empty,
63 onBrowse: $empty,
64 onDisabledBrowse: $empty,
65 onCancel: $empty,
66 onSelect: $empty,
67 onSelectSuccess: $empty,
68 onSelectFail: $empty,
70 onButtonEnter: $empty,
71 onButtonLeave: $empty,
72 onButtonDown: $empty,
73 onButtonDisable: $empty,
75 onFileStart: $empty,
76 onFileStop: $empty,
77 onFileRequeue: $empty,
78 onFileOpen: $empty,
79 onFileProgress: $empty,
80 onFileComplete: $empty,
81 onFileRemove: $empty
82 */
83 },
85 initialize: function(options) {
86 // protected events to control the class, added
87 // before setting options (which adds own events)
88 this.addEvent('load', this.initializeSwiff, true)
89 .addEvent('select', this.processFiles, true)
90 .addEvent('complete', this.update, true)
91 .addEvent('fileRemove', function(file) {
92 this.fileList.erase(file);
93 }.bind(this), true);
95 this.setOptions(options);
97 // callbacks are no longer in the options, every callback
98 // is fired as event, this is just compat
99 if (this.options.callBacks) {
100 Hash.each(this.options.callBacks, function(fn, name) {
101 this.addEvent(name, fn);
102 }, this);
103 }
105 this.options.callBacks = {
106 fireCallback: this.fireCallback.bind(this)
107 };
109 var path = this.options.path;
110 if (!path.contains('?')) path += '?noCache=' + $time(); // cache in IE
112 // container options for Swiff class
113 this.options.container = this.box = new Element('span', {'class': 'swiff-uploader-box'}).inject($(this.options.container) || document.body);
115 // target
116 this.target = $(this.options.target);
117 if (this.target) {
118 var scroll = window.getScroll();
119 this.box.setStyles({
120 position: 'absolute',
121 visibility: 'visible',
122 zIndex: this.options.zIndex,
123 overflow: 'hidden',
124 height: 1, width: 1,
125 top: scroll.y, left: scroll.x
126 });
128 // we force wMode to transparent for the overlay effect
129 this.parent(path, {
130 params: {
131 wMode: 'transparent'
132 },
133 height: '100%',
134 width: '100%'
135 });
137 this.target.addEvent('mouseenter', this.reposition.bind(this, []));
139 // button interactions, relayed to to the target
140 this.addEvents({
141 buttonEnter: this.targetRelay.bind(this, ['mouseenter']),
142 buttonLeave: this.targetRelay.bind(this, ['mouseleave']),
143 buttonDown: this.targetRelay.bind(this, ['mousedown']),
144 buttonDisable: this.targetRelay.bind(this, ['disable'])
145 });
147 this.reposition();
148 window.addEvent('resize', this.reposition.bind(this, []));
149 } else {
150 this.parent(path);
151 }
153 this.inject(this.box);
155 this.fileList = [];
157 this.size = this.uploading = this.bytesLoaded = this.percentLoaded = 0;
159 if (Browser.Plugins.Flash.version < 9) {
160 this.fireEvent('fail', ['flash']);
161 } else {
162 this.verifyLoad.delay(500, this);
163 }
164 },
166 verifyLoad: function() {
167 if (this.loaded) return;
168 if (!this.object.parentNode) {
169 this.fireEvent('fail', ['disabled']);
170 } else if (this.object.style.display == 'none') {
171 this.fireEvent('fail', ['hidden']);
172 } else if (!this.object.offsetWidth) {
173 this.fireEvent('fail', ['empty']);
174 }
175 },
177 fireCallback: function(name, args) {
178 // file* callbacks are relayed to the specific file
179 if (name.substr(0, 4) == 'file') {
180 // updated queue data is the second argument
181 if (args.length > 1) this.update(args[1]);
182 var data = args[0];
184 var file = this.findFile(data.id);
185 this.fireEvent(name, file || data, 5);
186 if (file) {
187 var fire = name.replace(/^file([A-Z])/, function($0, $1) {
188 return $1.toLowerCase();
189 });
190 file.update(data).fireEvent(fire, [data], 10);
191 }
192 } else {
193 this.fireEvent(name, args, 5);
194 }
195 },
197 update: function(data) {
198 // the data is saved right to the instance
199 $extend(this, data);
200 this.fireEvent('queue', [this], 10);
201 return this;
202 },
204 findFile: function(id) {
205 for (var i = 0; i < this.fileList.length; i++) {
206 if (this.fileList[i].id == id) return this.fileList[i];
207 }
208 return null;
209 },
211 initializeSwiff: function() {
212 // extracted options for the swf
213 this.remote('initialize', {
214 width: this.options.width,
215 height: this.options.height,
216 typeFilter: this.options.typeFilter,
217 multiple: this.options.multiple,
218 queued: this.options.queued,
219 url: this.options.url,
220 method: this.options.method,
221 data: this.options.data,
222 mergeData: this.options.mergeData,
223 fieldName: this.options.fieldName,
224 verbose: this.options.verbose,
225 fileSizeMin: this.options.fileSizeMin,
226 fileSizeMax: this.options.fileSizeMax,
227 allowDuplicates: this.options.allowDuplicates,
228 buttonImage: this.options.buttonImage
229 });
231 this.loaded = true;
233 this.appendCookieData();
234 },
236 targetRelay: function(name) {
237 if (this.target) this.target.fireEvent(name);
238 },
240 reposition: function(coords) {
241 // update coordinates, manual or automatically
242 coords = coords || (this.target && this.target.offsetHeight)
243 ? this.target.getCoordinates(this.box.getOffsetParent())
244 : {top: window.getScrollTop(), left: 0, width: 40, height: 40}
245 this.box.setStyles(coords);
246 this.fireEvent('reposition', [coords, this.box, this.target]);
247 },
249 setOptions: function(options) {
250 if (options) {
251 if (options.url) options.url = Swiff.Uploader.qualifyPath(options.url);
252 if (options.buttonImage) options.buttonImage = Swiff.Uploader.qualifyPath(options.buttonImage);
253 this.parent(options);
254 if (this.loaded) this.remote('setOptions', options);
255 }
256 return this;
257 },
259 setEnabled: function(status) {
260 this.remote('setEnabled', status);
261 },
263 start: function() {
264 this.remote('start');
265 },
267 stop: function() {
268 this.remote('stop');
269 },
271 remove: function() {
272 this.remote('remove');
273 },
275 fileStart: function(file) {
276 this.remote('fileStart', file.id);
277 },
279 fileStop: function(file) {
280 this.remote('fileStop', file.id);
281 },
283 fileRemove: function(file) {
284 this.remote('fileRemove', file.id);
285 },
287 fileRequeue: function(file) {
288 this.remote('fileRequeue', file.id);
289 },
291 appendCookieData: function() {
292 var append = this.options.appendCookieData;
293 if (!append) return;
295 var hash = {};
296 document.cookie.split(/;\s*/).each(function(cookie) {
297 cookie = cookie.split('=');
298 if (cookie.length == 2) {
299 hash[decodeURIComponent(cookie[0])] = decodeURIComponent(cookie[1]);
300 }
301 });
303 var data = this.options.data || {};
304 if ($type(append) == 'string') data[append] = hash;
305 else $extend(data, hash);
307 this.setOptions({data: data});
308 },
310 processFiles: function(successraw, failraw, queue) {
311 var cls = this.options.fileClass || Swiff.Uploader.File;
313 var fail = [], success = [];
315 if (successraw) {
316 successraw.each(function(data) {
317 var ret = new cls(this, data);
318 if (!ret.validate()) {
319 ret.remove.delay(10, ret);
320 fail.push(ret);
321 } else {
322 this.size += data.size;
323 this.fileList.push(ret);
324 success.push(ret);
325 ret.render();
326 }
327 }, this);
329 this.fireEvent('selectSuccess', [success], 10);
330 }
332 if (failraw || fail.length) {
333 fail.extend((failraw) ? failraw.map(function(data) {
334 return new cls(this, data);
335 }, this) : []).each(function(file) {
336 file.invalidate().render();
337 });
339 this.fireEvent('selectFail', [fail], 10);
340 }
342 this.update(queue);
344 if (this.options.instantStart && success.length) this.start();
345 }
347 });
349 $extend(Swiff.Uploader, {
351 STATUS_QUEUED: 0,
352 STATUS_RUNNING: 1,
353 STATUS_ERROR: 2,
354 STATUS_COMPLETE: 3,
355 STATUS_STOPPED: 4,
357 log: function() {
358 if (window.console && console.info) console.info.apply(console, arguments);
359 },
361 unitLabels: {
362 b: [{min: 1, unit: 'B'}, {min: 1024, unit: 'kB'}, {min: 1048576, unit: 'MB'}, {min: 1073741824, unit: 'GB'}],
363 s: [{min: 1, unit: 's'}, {min: 60, unit: 'm'}, {min: 3600, unit: 'h'}, {min: 86400, unit: 'd'}]
364 },
366 formatUnit: function(base, type, join) {
367 var labels = Swiff.Uploader.unitLabels[(type == 'bps') ? 'b' : type];
368 var append = (type == 'bps') ? '/s' : '';
369 var i, l = labels.length, value;
371 if (base < 1) return '0 ' + labels[0].unit + append;
373 if (type == 's') {
374 var units = [];
376 for (i = l - 1; i >= 0; i--) {
377 value = Math.floor(base / labels[i].min);
378 if (value) {
379 units.push(value + ' ' + labels[i].unit);
380 base -= value * labels[i].min;
381 if (!base) break;
382 }
383 }
385 return (join === false) ? units : units.join(join || ', ');
386 }
388 for (i = l - 1; i >= 0; i--) {
389 value = labels[i].min;
390 if (base >= value) break;
391 }
393 return (base / value).toFixed(1) + ' ' + labels[i].unit + append;
394 }
396 });
398 Swiff.Uploader.qualifyPath = (function() {
400 var anchor;
402 return function(path) {
403 (anchor || (anchor = new Element('a'))).href = path;
404 return anchor.href;
405 };
407 })();
409 Swiff.Uploader.File = new Class({
411 Implements: Events,
413 initialize: function(base, data) {
414 this.base = base;
415 this.update(data);
416 },
418 update: function(data) {
419 return $extend(this, data);
420 },
422 validate: function() {
423 var options = this.base.options;
425 if (options.fileListMax && this.base.fileList.length >= options.fileListMax) {
426 this.validationError = 'fileListMax';
427 return false;
428 }
430 if (options.fileListSizeMax && (this.base.size + this.size) > options.fileListSizeMax) {
431 this.validationError = 'fileListSizeMax';
432 return false;
433 }
435 return true;
436 },
438 invalidate: function() {
439 this.invalid = true;
440 this.base.fireEvent('fileInvalid', this, 10);
441 return this.fireEvent('invalid', this, 10);
442 },
444 render: function() {
445 return this;
446 },
448 setOptions: function(options) {
449 if (options) {
450 if (options.url) options.url = Swiff.Uploader.qualifyPath(options.url);
451 this.base.remote('fileSetOptions', this.id, options);
452 this.options = $merge(this.options, options);
453 }
454 return this;
455 },
457 start: function() {
458 this.base.fileStart(this);
459 return this;
460 },
462 stop: function() {
463 this.base.fileStop(this);
464 return this;
465 },
467 remove: function() {
468 this.base.fileRemove(this);
469 return this;
470 },
472 requeue: function() {
473 this.base.fileRequeue(this);
474 }
476 });