Mercurial > judyates
comparison e2gallerypro/e2upload/Source/FileManager.js @ 3:3f6b44aa6b35 judyates
[svn r4] added ability to buy stuff, from a Prints page, but it doesn't work well with the css, and it also has not been fitted into the perl make system.
author | rlm |
---|---|
date | Mon, 22 Feb 2010 08:02:39 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:670229c4eb4b | 3:3f6b44aa6b35 |
---|---|
1 /* | |
2 Script: FileManager.js | |
3 MooTools FileManager | |
4 | |
5 License: | |
6 MIT-style license. | |
7 | |
8 Version: | |
9 1.0rc1 | |
10 | |
11 Copyright: | |
12 Copyright (c) 2009 [Christoph Pojer](http://og5.net/christoph). | |
13 | |
14 Dependencies: | |
15 - MooTools Core 1.2.2 | |
16 - MooTools More 1.2.2.1 or newer: Drag.js, Drag.Move.js, Tips.js, Asset.js | |
17 - Additions.js | |
18 | |
19 Todo: | |
20 - Add Scroller.js (optional) for Drag&Drop in the Filelist | |
21 | |
22 Inspiration: | |
23 - Loosely based on a Script by [Yannick Croissant](http://dev.k1der.net/dev/brooser-un-browser-de-fichier-pour-mootools/) | |
24 | |
25 Options: | |
26 - url: (string) The base url to the Backend FileManager, without QueryString | |
27 - assetBasePath: (string) The path to all images and swf files | |
28 - selectable: (boolean, defaults to *false*) If true, provides a button to select a file | |
29 - language: (string, defaults to *en*) The language used for the FileManager | |
30 - hideOnClick: (boolean, defaults to *false*) When true, hides the FileManager when the area outside of it is clicked | |
31 - directory: (string) Can be used to load a subfolder instead of the base folder | |
32 | |
33 Events: | |
34 - onComplete(path, file): fired when a file gets selected via the "Select file" button | |
35 - onModify(file): fired when a file gets renamed/deleted or modified in another way | |
36 - onShow: fired when the FileManager opens | |
37 - onHide: event fired when FileManager closes | |
38 */ | |
39 | |
40 var FileManager = new Class({ | |
41 | |
42 Implements: [Options, Events], | |
43 | |
44 Request: null, | |
45 Directory: null, | |
46 Current: null, | |
47 | |
48 options: { | |
49 /*onComplete: $empty, | |
50 onModify: $empty, | |
51 onShow: $empty, | |
52 onHide: $empty,*/ | |
53 directory: '', | |
54 url: null, | |
55 assetBasePath: null, | |
56 selectable: false, | |
57 hideOnClick: false, | |
58 language: 'en' | |
59 }, | |
60 | |
61 hooks: { | |
62 show: {}, | |
63 cleanup: {} | |
64 }, | |
65 | |
66 initialize: function(options){ | |
67 this.setOptions(options); | |
68 this.options.assetBasePath = this.options.assetBasePath.replace(/(\/|\\)*$/, '/'); | |
69 this.droppables = []; | |
70 this.Directory = this.options.directory; | |
71 | |
72 this.language = FileManager.Language[this.options.language] || FileManager.Language.en; | |
73 this.container = new Element('div', {'class': 'filemanager-container filemanager-engine-'+Browser.Engine.name+(Browser.Engine.trident ? Browser.Engine.version : '')}); | |
74 this.el = new Element('div', {'class': 'filemanager'}).inject(this.container); | |
75 this.menu = new Element('div', {'class': 'filemanager-menu'}).inject(this.el); | |
76 this.loader = new Element('div', {'class': 'loader', opacity: 0, tween: {duration: 200}}).inject(this.menu); | |
77 this.browser = new Element('ul', {'class': 'filemanager-browser'}).addEvents({ | |
78 click: (function(e){ | |
79 if(e.target.match('ul')) return this.deselect(); | |
80 | |
81 if(!e.target || !e.target.getParent('li')) return; | |
82 var el = e.target.getParent('li').getElement('span'); | |
83 if(!el) return; | |
84 | |
85 e.stop(); | |
86 var file = el.retrieve('file'); | |
87 if(el.retrieve('block')){ | |
88 el.eliminate('block'); | |
89 return; | |
90 }else if(file.mime=='text/directory'){ | |
91 el.addClass('selected'); | |
92 this.load(this.Directory+'/'+file.name); | |
93 return; | |
94 } | |
95 | |
96 this.fillInfo(file); | |
97 if(this.Current) this.Current.removeClass('selected'); | |
98 this.Current = el.addClass('selected'); | |
99 | |
100 this.switchButton(); | |
101 }).bind(this) | |
102 }).inject(this.el); | |
103 | |
104 | |
105 if(this.options.selectable) this.addMenuButton('open'); | |
106 this.addMenuButton('create'); | |
107 | |
108 this.info = new Element('div', {'class': 'filemanager-infos', opacity: 0}).inject(this.el); | |
109 | |
110 var head = new Element('div', {'class': 'filemanager-head'}).adopt([ | |
111 new Element('img', {'class': 'filemanager-icon'}), | |
112 new Element('h1') | |
113 ]); | |
114 | |
115 this.info.adopt([head, new Element('h2', {text: this.language.information})]); | |
116 | |
117 var list = new Element('dl').adopt([ | |
118 new Element('dt', {text: this.language.modified}), | |
119 new Element('dd', {'class': 'filemanager-modified'}), | |
120 new Element('dt', {text: this.language.type}), | |
121 new Element('dd', {'class': 'filemanager-type'}), | |
122 new Element('dt', {text: this.language.size}), | |
123 new Element('dd', {'class': 'filemanager-size'}), | |
124 new Element('dt', {text: this.language.dir}), | |
125 new Element('dd', {'class': 'filemanager-dir'}) | |
126 ]).inject(this.info); | |
127 | |
128 this.preview = new Element('div', {'class': 'filemanager-preview'}); | |
129 this.info.adopt([ | |
130 new Element('h2', {'class': 'filemanager-headline', text: this.language.preview}), | |
131 this.preview | |
132 ]); | |
133 | |
134 this.closeIcon = new Element('div', { | |
135 'class': 'filemanager-close', | |
136 title: this.language.close, | |
137 events: {click: this.hide.bind(this)} | |
138 }).adopt(new Asset.image(this.options.assetBasePath+'destroy.png')).inject(this.el); | |
139 new FileManager.Tips(this.closeIcon.appearOn(this.closeIcon, [1, 0.8]).appearOn(this.el, 0.8)); | |
140 | |
141 this.imageadd = new Asset.image(this.options.assetBasePath+'add.png', { | |
142 'class': 'browser-add' | |
143 }).set('opacity', 0).inject(this.container); | |
144 | |
145 this.container.inject(document.body); | |
146 this.overlay = new Overlay(this.options.hideOnClick ? { | |
147 events: {click: this.hide.bind(this)} | |
148 } : null); | |
149 this.bound = { | |
150 keydown: (function(e){ | |
151 if(e.control) this.imageadd.fade(1); | |
152 }).bind(this), | |
153 keyup: (function(){ | |
154 this.imageadd.fade(0); | |
155 }).bind(this), | |
156 keyesc: (function(e){ | |
157 if(e.key=='esc') this.hide(); | |
158 }).bind(this), | |
159 scroll: (function(){ | |
160 this.el.center(this.offsets); | |
161 this.fireEvent('scroll'); | |
162 }).bind(this) | |
163 }; | |
164 }, | |
165 | |
166 show: function(e){ | |
167 if(e) e.stop(); | |
168 | |
169 this.load(this.Directory); | |
170 this.overlay.show(); | |
171 | |
172 this.info.set('opacity', 0); | |
173 | |
174 (function(){ | |
175 this.container.setStyles({ | |
176 opacity: 0, | |
177 display: 'block' | |
178 }); | |
179 | |
180 this.el.center(this.offsets); | |
181 this.fireEvent('show'); | |
182 this.container.set('opacity', 1); | |
183 this.fireHooks('show'); | |
184 | |
185 window.addEvents({ | |
186 scroll: this.bound.scroll, | |
187 resize: this.bound.scroll, | |
188 keyup: this.bound.keyesc | |
189 }); | |
190 }).delay(500, this); | |
191 }, | |
192 | |
193 hide: function(e){ | |
194 if(e) e.stop(); | |
195 | |
196 this.overlay.hide(); | |
197 this.browser.empty(); | |
198 this.container.setStyle('display', 'none'); | |
199 | |
200 this.fireHooks('cleanup').fireEvent('hide'); | |
201 window.removeEvent('scroll', this.bound.scroll).removeEvent('resize', this.bound.scroll).removeEvent('keyup', this.bound.keyesc); | |
202 }, | |
203 | |
204 open: function(e){ | |
205 e.stop(); | |
206 | |
207 if(!this.Current) return false; | |
208 | |
209 this.fireEvent('complete', [ | |
210 this.normalize(this.Directory+'/'+this.Current.retrieve('file').name), | |
211 this.Current.retrieve('file') | |
212 ]); | |
213 this.hide(); | |
214 }, | |
215 | |
216 create: function(e){ | |
217 e.stop(); | |
218 | |
219 var self = this; | |
220 new Dialog(this.language.createdir, { | |
221 language: { | |
222 confirm: this.language.create, | |
223 decline: this.language.cancel | |
224 }, | |
225 content: [ | |
226 new Element('input', {'class': 'createDirectory'}) | |
227 ], | |
228 onOpen: this.onDialogOpen.bind(this), | |
229 onClose: this.onDialogClose.bind(this), | |
230 onShow: function(){ | |
231 var self = this; | |
232 this.el.getElement('input').addEvent('keyup', function(e){ | |
233 if(e.key=='enter') self.el.getElement('button-confirm').fireEvent('click'); | |
234 }).focus(); | |
235 }, | |
236 onConfirm: function(){ | |
237 new FileManager.Request({ | |
238 url: self.options.url+'?event=create', | |
239 onSuccess: self.fill.bind(self), | |
240 data: { | |
241 file: this.el.getElement('input').get('value'), | |
242 directory: self.Directory | |
243 } | |
244 }, self).post(); | |
245 } | |
246 }); | |
247 }, | |
248 | |
249 deselect: function(el){ | |
250 if(el && this.Current!=el) return; | |
251 | |
252 if(el) this.fillInfo(); | |
253 if(this.Current) this.Current.removeClass('selected'); | |
254 this.Current = null; | |
255 | |
256 this.switchButton(); | |
257 }, | |
258 | |
259 load: function(dir, nofade){ | |
260 this.deselect(); | |
261 if(!nofade) this.info.fade(0); | |
262 | |
263 if(this.Request) this.Request.cancel(); | |
264 | |
265 this.Request = new FileManager.Request({ | |
266 url: this.options.url, | |
267 onSuccess: (function(j){ | |
268 this.fill(j, nofade); | |
269 }).bind(this), | |
270 data: { | |
271 directory: dir | |
272 } | |
273 }, this).post(); | |
274 }, | |
275 | |
276 destroy: function(e, file){ | |
277 e.stop(); | |
278 | |
279 var self = this; | |
280 new Dialog(this.language.destroyfile, { | |
281 language: { | |
282 confirm: this.language.destroy, | |
283 decline: this.language.cancel | |
284 }, | |
285 onOpen: this.onDialogOpen.bind(this), | |
286 onClose: this.onDialogClose.bind(this), | |
287 onConfirm: function(){ | |
288 new FileManager.Request({ | |
289 url: self.options.url+'?event=destroy', | |
290 data: { | |
291 file: file.name, | |
292 directory: self.Directory | |
293 }, | |
294 onSuccess: function(j){ | |
295 if(!j || j.content!='destroyed'){ | |
296 new Dialog(self.language.nodestroy, {language: {confirm: self.language.ok}, buttons: ['confirm']}); | |
297 return; | |
298 } | |
299 | |
300 self.fireEvent('modify', [$unlink(file)]); | |
301 file.element.getParent().fade(0).get('tween').chain(function(){ | |
302 self.deselect(file.element); | |
303 this.element.destroy(); | |
304 }); | |
305 } | |
306 }, self).post(); | |
307 } | |
308 }); | |
309 | |
310 }, | |
311 | |
312 rename: function(e, file){ | |
313 e.stop(); | |
314 | |
315 var name = file.name; | |
316 if(file.mime!='text/directory') name = name.replace(/\..*$/, ''); | |
317 | |
318 var self = this; | |
319 new Dialog(this.language.renamefile, { | |
320 language: { | |
321 confirm: this.language.rename, | |
322 decline: this.language.cancel | |
323 }, | |
324 content: [ | |
325 new Element('input', {'class': 'rename', value: name}) | |
326 ], | |
327 onOpen: this.onDialogOpen.bind(this), | |
328 onClose: this.onDialogClose.bind(this), | |
329 onShow: function(){ | |
330 var self = this; | |
331 this.el.getElement('input').addEvent('keyup', function(e){ | |
332 if(e.key=='enter') self.el.getElement('button-confirm').fireEvent('click'); | |
333 }).focus(); | |
334 }, | |
335 onConfirm: function(){ | |
336 new FileManager.Request({ | |
337 url: self.options.url+'?event=move', | |
338 onSuccess: (function(j){ | |
339 if(!j || !j.name) return; | |
340 | |
341 self.fireEvent('modify', [$unlink(file)]); | |
342 | |
343 file.element.getElement('span').set('text', j.name); | |
344 file.name = j.name; | |
345 self.fillInfo(file); | |
346 }).bind(this), | |
347 data: { | |
348 file: file.name, | |
349 name: this.el.getElement('input').get('value'), | |
350 directory: self.Directory | |
351 } | |
352 }, self).post(); | |
353 } | |
354 }); | |
355 }, | |
356 | |
357 fill: function(j, nofade){ | |
358 this.Directory = j.path; | |
359 this.CurrentDir = j.dir; | |
360 if(!nofade) this.fillInfo(j.dir); | |
361 this.browser.empty(); | |
362 | |
363 if(!j.files) return; | |
364 | |
365 var els = [[], []]; | |
366 $each(j.files, function(file){ | |
367 file.dir = j.path; | |
368 var el = file.element = new Element('span', {'class': 'fi', href: '#'}).adopt( | |
369 new Asset.image(this.options.assetBasePath+'Icons/'+file.icon+'.png'), | |
370 new Element('span', {text: file.name}) | |
371 ).store('file', file); | |
372 | |
373 var icons = []; | |
374 if(file.mime!='text/directory') | |
375 icons.push(new Asset.image(this.options.assetBasePath+'disk.png', {title: this.language.download}).addClass('browser-icon').addEvent('click', (function(e){ | |
376 e.stop(); | |
377 window.open(this.normalize(this.Directory+'/'+file.name)); | |
378 }).bind(this)).inject(el, 'top')); | |
379 | |
380 if(file.name!='..') | |
381 ['rename', 'destroy'].each(function(v){ | |
382 icons.push(new Asset.image(this.options.assetBasePath+v+'.png', {title: this.language[v]}).addClass('browser-icon').addEvent('click', this[v].bindWithEvent(this, [file])).injectTop(el)); | |
383 }, this); | |
384 | |
385 els[file.mime=='text/directory' ? 1 : 0].push(el); | |
386 if(file.name=='..') el.set('opacity', 0.7); | |
387 el.inject(new Element('li').inject(this.browser)); | |
388 icons = $$(icons.map(function(icon){ return icon.appearOn(icon, [1, 0.7]); })).appearOn(el.getParent('li'), 0.7); | |
389 }, this); | |
390 | |
391 var self = this; | |
392 $$(els[0]).makeDraggable({ | |
393 droppables: $$(this.droppables, els[1]), | |
394 | |
395 onDrag: function(el, e){ | |
396 self.imageadd.setStyles(Hash.getValues(e.page).map(function(v){ return v+15; }).associate(['left', 'top'])); | |
397 }, | |
398 | |
399 onBeforeStart: function(el){ | |
400 el.setStyles({left: '0', top: '0'}); | |
401 }, | |
402 | |
403 onStart: function(el){ | |
404 self.onDragStart(el, this); | |
405 | |
406 el.set('opacity', 0.7); | |
407 document.addEvents({ | |
408 keydown: self.bound.keydown, | |
409 keyup: self.bound.keyup | |
410 }); | |
411 }, | |
412 | |
413 onEnter: function(el, droppable){ | |
414 droppable.addClass('droppable'); | |
415 }, | |
416 | |
417 onLeave: function(el, droppable){ | |
418 droppable.removeClass('droppable'); | |
419 }, | |
420 | |
421 onDrop: function(el, droppable, e){ | |
422 document.removeEvents('keydown', self.bound.keydown).removeEvents('keyup', self.bound.keydown); | |
423 | |
424 self.imageadd.fade(0); | |
425 el.set('opacity', 1).store('block', true); | |
426 if(e.control || !droppable) | |
427 el.setStyles({left: '0', top: '0'}); | |
428 | |
429 if(!droppable && !e.control) | |
430 return; | |
431 | |
432 var dir; | |
433 if(droppable){ | |
434 droppable.addClass('selected'); | |
435 (function(){ droppable.removeClass('droppable').removeClass('selected'); }).delay(300); | |
436 | |
437 if(self.onDragComplete(el, droppable)) | |
438 return; | |
439 | |
440 dir = droppable.retrieve('file'); | |
441 } | |
442 var file = el.retrieve('file'); | |
443 | |
444 new FileManager.Request({ | |
445 url: self.options.url+'?event=move', | |
446 data: { | |
447 file: file.name, | |
448 directory: self.Directory, | |
449 newDirectory: dir ? dir.dir+'/'+dir.name : self.Directory, | |
450 copy: e.control ? 1 : 0 | |
451 }, | |
452 onSuccess: function(){ | |
453 if(!dir) self.load(self.Directory); | |
454 } | |
455 }, self).post(); | |
456 | |
457 self.fireEvent('modify', [$unlink(file)]); | |
458 | |
459 if(!e.control) | |
460 el.fade(0).get('tween').chain(function(){ | |
461 self.deselect(el); | |
462 el.getParent().destroy(); | |
463 }); | |
464 } | |
465 }); | |
466 $$(els).setStyles({left: '0', top: '0'}); | |
467 var tips = new FileManager.Tips(this.browser.getElements('img.browser-icon')); | |
468 | |
469 tips.tip.removeClass('tip-base'); | |
470 }, | |
471 | |
472 fillInfo: function(file, path){ | |
473 if(!file) file = this.CurrentDir; | |
474 if(!path) path = this.Directory; | |
475 | |
476 if(!file) return; | |
477 var size = this.size(file.size); | |
478 | |
479 this.info.fade(1).getElement('img').set({ | |
480 src: this.options.assetBasePath+'Icons/'+file.icon+'.png', | |
481 alt: file.mime | |
482 }); | |
483 | |
484 this.fireHooks('cleanup'); | |
485 this.preview.empty(); | |
486 | |
487 this.info.getElement('h1').set('text', file.name); | |
488 this.info.getElement('dd.filemanager-modified').set('text', file.date); | |
489 this.info.getElement('dd.filemanager-type').set('text', file.mime); | |
490 this.info.getElement('dd.filemanager-size').set('text', !size[0] && size[1]=='Bytes' ? '-' : (size.join(' ')+(size[1]!='Bytes' ? ' ('+file.size+' Bytes)' : ''))); | |
491 this.info.getElement('h2.filemanager-headline').setStyle('display', file.mime=='text/directory' ? 'none' : 'block'); | |
492 | |
493 var text = [], pre = []; | |
494 | |
495 path.split('/').each(function(v){ | |
496 if(!v) return; | |
497 | |
498 pre.push(v); | |
499 text.push(new Element('a', { | |
500 'class': 'icon', | |
501 href: '#', | |
502 text: v | |
503 }).addEvent('click', (function(e, dir){ | |
504 e.stop(); | |
505 | |
506 this.load(dir); | |
507 }).bindWithEvent(this, [pre.join('/')])) | |
508 ); | |
509 text.push(new Element('span', {text: ' / '})); | |
510 }, this); | |
511 | |
512 text.pop(); | |
513 text[text.length-1].addClass('selected').removeEvents('click').addEvent('click', function(e){ e.stop(); }); | |
514 | |
515 this.info.getElement('dd.filemanager-dir').empty().adopt(new Element('span', {text: '/ '}), text); | |
516 | |
517 if(file.mime=='text/directory') return; | |
518 | |
519 if(this.Request) this.Request.cancel(); | |
520 | |
521 this.Request = new FileManager.Request({ | |
522 url: this.options.url+'?event=detail', | |
523 onSuccess: (function(j){ | |
524 var prev = this.preview.removeClass('filemanager-loading').set('html', j && j.content ? j.content.substitute(this.language, /\\?\$\{([^{}]+)\}/g) : '').getElement('img.prev'); | |
525 if(prev) prev.addEvent('load', function(){ | |
526 this.setStyle('background', 'none'); | |
527 }); | |
528 | |
529 var els = this.preview.getElements('button'); | |
530 if(els) els.addEvent('click', function(e){ | |
531 e.stop(); | |
532 window.open(this.get('value')); | |
533 }); | |
534 }).bind(this), | |
535 data: { | |
536 directory: this.Directory, | |
537 file: file.name | |
538 } | |
539 }, this).post(); | |
540 }, | |
541 | |
542 size: function(size){ | |
543 var tab = ['Bytes', 'KB', 'MB', 'GB', 'TB']; | |
544 for(var i = 0; size > 1024; i++) | |
545 size = size/1024; | |
546 | |
547 return [Math.round(size), tab[i]]; | |
548 }, | |
549 | |
550 normalize: function(str){ | |
551 return str.replace(/\/+/g, '/'); | |
552 }, | |
553 | |
554 switchButton: function(){ | |
555 var chk = !!this.Current; | |
556 var el = this.menu.getElement('button.filemanager-open'); | |
557 if(el) el.set('disabled', !chk)[(chk ? 'remove' : 'add')+'Class']('disabled'); | |
558 }, | |
559 | |
560 addMenuButton: function(name){ | |
561 var el = new Element('button', { | |
562 'class': 'filemanager-'+name, | |
563 text: this.language[name] | |
564 }).inject(this.menu); | |
565 if(this[name]) el.addEvent('click', this[name].bind(this)); | |
566 return el; | |
567 }, | |
568 | |
569 fireHooks: function(hook){ | |
570 var args = Array.slice(arguments, 1); | |
571 for(var key in this.hooks[hook]) this.hooks[hook][key].apply(this, args); | |
572 return this; | |
573 }, | |
574 | |
575 onRequest: function(){ this.loader.set('opacity', 1); }, | |
576 onComplete: function(){ this.loader.fade(0); }, | |
577 onDialogOpen: $empty, | |
578 onDialogClose: $empty, | |
579 | |
580 onDragStart: $empty, | |
581 onDragComplete: $lambda(false) | |
582 | |
583 }); | |
584 | |
585 FileManager.Language = {}; |