MDL-34117 Correctly pass accepted_types to dnduploader
[moodle.git] / lib / form / filemanager.js
CommitLineData
494bf5c8
DC
1// This file is part of Moodle - http://moodle.org/
2//
3// Moodle is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// Moodle is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
494bf5c8 15/**
494bf5c8 16 *
840912d5
DC
17 * File Manager UI
18 * =====
19 * this.api, stores the URL to make ajax request
20 * this.currentpath
21 * this.filepicker_options
22 * this.movefile_dialog
23 * this.mkdir_dialog
24 * this.rename_dialog
25 * this.client_id
554cd8fc
DC
26 * this.filecount, how many files in this filemanager
27 * this.maxfiles
28 * this.maxbytes
55089a9d
MG
29 * this.filemanager, contains reference to filemanager Node
30 * this.selectnode, contains referenct to select-file Node
31 * this.selectui, YUI Panel to select the file
840912d5
DC
32 *
33 * FileManager options:
34 * =====
35 * this.options.currentpath
36 * this.options.itemid
494bf5c8 37 */
56a7bf68 38
4c508047 39
906e7d89
MG
40M.form_filemanager = {templates:{}};
41
42M.form_filemanager.set_templates = function(Y, templates) {
43 M.form_filemanager.templates = templates;
44}
4c508047
PS
45
46/**
47 * This fucntion is called for each file picker on page.
48 */
49M.form_filemanager.init = function(Y, options) {
50 var FileManagerHelper = function(options) {
51 FileManagerHelper.superclass.constructor.apply(this, arguments);
d3067516 52 };
4c508047
PS
53 FileManagerHelper.NAME = "FileManager";
54 FileManagerHelper.ATTRS = {
840912d5
DC
55 options: {},
56 lang: {}
57 };
4c508047
PS
58
59 Y.extend(FileManagerHelper, Y.Base, {
64f93798 60 api: M.cfg.wwwroot+'/repository/draftfiles_ajax.php',
840912d5 61 menus: {},
4c508047
PS
62 initializer: function(options) {
63 this.options = options;
f45dfeeb 64 if (options.mainfile) {
ac9c14dd 65 this.enablemainfile = options.mainfile;
f45dfeeb 66 }
4c508047 67 this.client_id = options.client_id;
840912d5 68 this.currentpath = '/';
4c508047
PS
69 this.maxfiles = options.maxfiles;
70 this.maxbytes = options.maxbytes;
adce0230 71 this.emptycallback = null; // Used by drag and drop upload
133fd70b
DC
72
73 this.filepicker_options = options.filepicker?options.filepicker:{};
74 this.filepicker_options.client_id = this.client_id;
be85f7ab 75 this.filepicker_options.context = options.context;
133fd70b
DC
76 this.filepicker_options.maxfiles = this.maxfiles;
77 this.filepicker_options.maxbytes = this.maxbytes;
78 this.filepicker_options.env = 'filemanager';
133fd70b
DC
79 this.filepicker_options.itemid = options.itemid;
80
4c508047
PS
81 if (options.filecount) {
82 this.filecount = options.filecount;
554cd8fc
DC
83 } else {
84 this.filecount = 0;
85 }
e709ddd2 86 // prepare filemanager for drag-and-drop upload
906e7d89
MG
87 this.filemanager = Y.one('#filemanager-'+options.client_id);
88 if (this.filemanager.hasClass('filemanager-container') || !this.filemanager.one('.filemanager-container')) {
89 this.dndcontainer = this.filemanager;
90 } else {
91 this.dndcontainer = this.filemanager.one('.filemanager-container');
92 if (!this.dndcontainer.get('id')) {
93 this.dndcontainer.generateID();
94 }
95 }
e709ddd2
MG
96 // save template for one path element and location of path bar
97 if (this.filemanager.one('.fp-path-folder')) {
98 this.pathnode = this.filemanager.one('.fp-path-folder');
99 this.pathbar = this.pathnode.get('parentNode');
100 this.pathbar.removeChild(this.pathnode);
101 }
102 // initialize 'select file' panel
5e117466 103 this.selectnode = Y.Node.createWithFilesSkin(M.form_filemanager.templates.fileselectlayout);
55089a9d 104 this.selectnode.generateID();
e709ddd2 105 this.selectui = new Y.Panel({
55089a9d 106 srcNode : this.selectnode,
e709ddd2
MG
107 zIndex : 600000,
108 centered : true,
109 modal : true,
110 close : true,
111 render : true
112 });
55089a9d 113 this.selectui.plug(Y.Plugin.Drag,{handles:['#'+this.selectnode.get('id')+' .yui3-widget-hd']});
e709ddd2
MG
114 this.selectui.hide();
115 this.setup_select_file();
116 // setup buttons onclick events
840912d5 117 this.setup_buttons();
469a53a0
MG
118 // set event handler for lazy loading of thumbnails
119 this.filemanager.one('.fp-content').on(['scroll','resize'], this.content_scrolled, this);
e709ddd2
MG
120 // display files
121 this.viewmode = 1; // TODO take from cookies?
122 this.filemanager.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').removeClass('checked')
123 this.filemanager.all('.fp-vb-icons').addClass('checked')
910e1ecd 124 this.refresh(this.currentpath); // MDL-31113 get latest list from server
840912d5 125 },
4c508047 126
694beb54 127 wait: function() {
906e7d89 128 this.filemanager.addClass('fm-updating');
403eabd4
DC
129 },
130 request: function(args, redraw) {
840912d5
DC
131 var api = this.api + '?action='+args.action;
132 var params = {};
133 var scope = this;
134 if (args['scope']) {
135 scope = args['scope'];
136 }
4c508047 137 params['sesskey'] = M.cfg.sesskey;
840912d5
DC
138 params['client_id'] = this.client_id;
139 params['filepath'] = this.currentpath;
140 params['itemid'] = this.options.itemid?this.options.itemid:0;
141 if (args['params']) {
142 for (i in args['params']) {
143 params[i] = args['params'][i];
56a7bf68 144 }
56a7bf68 145 }
840912d5
DC
146 var cfg = {
147 method: 'POST',
148 on: {
149 complete: function(id,o,p) {
150 if (!o) {
151 alert('IO FATAL');
152 return;
153 }
e709ddd2
MG
154 var data = null;
155 try {
156 data = Y.JSON.parse(o.responseText);
157 } catch(e) {
694beb54 158 scope.print_msg(M.str.repository.invalidjson, 'error');
83d2700e 159 Y.error(M.str.repository.invalidjson+":\n"+o.responseText);
e709ddd2
MG
160 return;
161 }
162 if (data && data.tree && scope.set_current_tree) {
163 scope.set_current_tree(data.tree);
164 }
840912d5
DC
165 args.callback(id,data,p);
166 }
167 },
168 arguments: {
169 scope: scope
170 },
171 headers: {
172 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
173 'User-Agent': 'MoodleFileManager/3.0'
174 },
175 data: build_querystring(params)
176 };
177 if (args.form) {
178 cfg.form = args.form;
56a7bf68 179 }
840912d5 180 Y.io(api, cfg);
403eabd4 181 if (redraw) {
694beb54 182 this.wait();
403eabd4 183 }
840912d5
DC
184 },
185 filepicker_callback: function(obj) {
554cd8fc 186 this.filecount++;
910e1ecd
DS
187 this.check_buttons();
188 this.refresh(this.currentpath);
a5dd1f4f
SH
189 if (typeof M.core_formchangechecker != 'undefined') {
190 M.core_formchangechecker.set_form_changed();
191 }
910e1ecd
DS
192 },
193 check_buttons: function() {
6a0d7194
DP
194 if (this.filecount>0) {
195 this.filemanager.removeClass('fm-nofiles');
196 } else {
197 this.filemanager.addClass('fm-nofiles');
198 }
199 if (this.filecount >= this.maxfiles && this.maxfiles!=-1) {
200 this.filemanager.addClass('fm-maxfiles');
201 }
202 else {
203 this.filemanager.removeClass('fm-maxfiles');
204 }
840912d5
DC
205 },
206 refresh: function(filepath) {
207 var scope = this;
59eeb81b 208 this.currentpath = filepath;
840912d5
DC
209 if (!filepath) {
210 filepath = this.currentpath;
211 } else {
212 this.currentpath = filepath;
56a7bf68 213 }
840912d5
DC
214 this.request({
215 action: 'list',
216 scope: scope,
217 params: {'filepath':filepath},
218 callback: function(id, obj, args) {
910e1ecd
DS
219 scope.filecount = obj.filecount;
220 scope.check_buttons();
840912d5 221 scope.options = obj;
469a53a0 222 scope.lazyloading = {};
840912d5 223 scope.render(obj);
56a7bf68 224 }
403eabd4 225 }, true);
840912d5 226 },
694beb54
MG
227 /** displays message in a popup */
228 print_msg: function(msg, type) {
229 var header = M.str.moodle.error;
230 if (type != 'error') {
231 type = 'info'; // one of only two types excepted
232 header = M.str.moodle.info;
233 }
234 if (!this.msg_dlg) {
5e117466
MG
235 this.msg_dlg_node = Y.Node.createWithFilesSkin(M.form_filemanager.templates.message);
236 var nodeid = this.msg_dlg_node.generateID();
694beb54
MG
237
238 this.msg_dlg = new Y.Panel({
5e117466 239 srcNode : this.msg_dlg_node,
694beb54
MG
240 zIndex : 800000,
241 centered : true,
242 modal : true,
243 visible : false,
244 render : true
245 });
5e117466
MG
246 this.msg_dlg.plug(Y.Plugin.Drag,{handles:['#'+nodeid+' .yui3-widget-hd']});
247 this.msg_dlg_node.one('.fp-msg-butok').on('click', function(e) {
694beb54
MG
248 e.preventDefault();
249 this.msg_dlg.hide();
250 }, this);
251 }
252
253 this.msg_dlg.set('headerContent', header);
5e117466
MG
254 this.msg_dlg_node.removeClass('fp-msg-info').removeClass('fp-msg-error').addClass('fp-msg-'+type)
255 this.msg_dlg_node.one('.fp-msg-text').setContent(msg);
694beb54
MG
256 this.msg_dlg.show();
257 },
840912d5 258 setup_buttons: function() {
e709ddd2
MG
259 var button_download = this.filemanager.one('.fp-btn-download');
260 var button_create = this.filemanager.one('.fp-btn-mkdir');
261 var button_addfile = this.filemanager.one('.fp-btn-add');
840912d5
DC
262
263 // setup 'add file' button
bc1f298b
DP
264 button_addfile.on('click', this.show_filepicker, this);
265
266 var dndarrow = this.filemanager.one('.dndupload-arrow');
267 if (dndarrow) {
268 dndarrow.on('click', this.show_filepicker, this);
269 }
840912d5
DC
270
271 // setup 'make a folder' button
272 if (this.options.subdirs) {
273 button_create.on('click',function(e) {
906e7d89 274 e.preventDefault();
840912d5
DC
275 var scope = this;
276 // a function used to perform an ajax request
694beb54
MG
277 var perform_action = function(e) {
278 e.preventDefault();
279 var foldername = Y.one('#fm-newname-'+scope.client_id).get('value');
840912d5 280 if (!foldername) {
694beb54 281 scope.mkdir_dialog.hide();
840912d5
DC
282 return;
283 }
284 scope.request({
285 action:'mkdir',
286 params: {filepath:scope.currentpath, newdirname:foldername},
287 callback: function(id, obj, args) {
288 var filepath = obj.filepath;
289 scope.mkdir_dialog.hide();
290 scope.refresh(filepath);
694beb54 291 Y.one('#fm-newname-'+scope.client_id).set('value', '');
a5dd1f4f
SH
292 if (typeof M.core_formchangechecker != 'undefined') {
293 M.core_formchangechecker.set_form_changed();
294 }
840912d5
DC
295 }
296 });
297 }
694beb54 298 if (!this.mkdir_dialog) {
5e117466 299 var node = Y.Node.createWithFilesSkin(M.form_filemanager.templates.mkdir);
694beb54
MG
300 this.mkdir_dialog = new Y.Panel({
301 srcNode : node,
302 zIndex : 800000,
303 centered : true,
304 modal : true,
305 visible : false,
306 render : true
307 });
4325db53 308 this.mkdir_dialog.plug(Y.Plugin.Drag,{handles:['.yui3-widget-hd']});
694beb54
MG
309 node.one('.fp-dlg-butcreate').on('click', perform_action, this);
310 node.one('input').set('id', 'fm-newname-'+this.client_id).
311 on('keydown', function(e){
312 if (e.keyCode == 13) {Y.bind(perform_action, this)(e);}
313 }, this);
314 node.all('.fp-dlg-butcancel').on('click', function(e){e.preventDefault();this.mkdir_dialog.hide();}, this);
315 node.all('.fp-dlg-curpath').set('id', 'fm-curpath-'+this.client_id);
840912d5 316 }
840912d5 317 this.mkdir_dialog.show();
694beb54
MG
318 Y.one('#fm-newname-'+scope.client_id).focus();
319 Y.all('#fm-curpath-'+scope.client_id).setContent(this.currentpath)
840912d5 320 }, this);
56a7bf68 321 } else {
906e7d89 322 this.filemanager.addClass('fm-nomkdir');
56a7bf68 323 }
840912d5
DC
324
325 // setup 'download this folder' button
906e7d89
MG
326 button_download.on('click',function(e) {
327 e.preventDefault();
840912d5
DC
328 var scope = this;
329 // perform downloaddir ajax request
330 this.request({
331 action: 'downloaddir',
332 scope: scope,
333 callback: function(id, obj, args) {
7210e887
DC
334 if (obj) {
335 scope.refresh(obj.filepath);
98d5bad9
FM
336 node = Y.Node.create('<iframe></iframe>').setStyles({
337 visibility : 'hidden',
338 width : '1px',
339 height : '1px'
340 });
341 node.set('src', obj.fileurl);
342 Y.one('body').appendChild(node);
7210e887 343 } else {
694beb54 344 scope.print_msg(M.str.repository.draftareanofiles, 'error');
840912d5
DC
345 }
346 }
347 });
348 }, this);
e709ddd2
MG
349
350 this.filemanager.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').
351 on('click', function(e) {
352 e.preventDefault();
353 var viewbar = this.filemanager.one('.fp-viewbar')
354 if (!viewbar || !viewbar.hasClass('disabled')) {
355 this.filemanager.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').removeClass('checked')
356 if (e.currentTarget.hasClass('fp-vb-tree')) {
357 this.viewmode = 2;
358 } else if (e.currentTarget.hasClass('fp-vb-details')) {
359 this.viewmode = 3;
360 } else {
361 this.viewmode = 1;
362 }
363 e.currentTarget.addClass('checked')
364 this.render();
e709ddd2
MG
365 }
366 }, this);
840912d5 367 },
bc1f298b
DP
368
369 show_filepicker: function (e) {
370 // if maxfiles == -1, the no limit
371 e.preventDefault();
372 var options = this.filepicker_options;
373 options.formcallback = this.filepicker_callback;
374 // XXX: magic here, to let filepicker use filemanager scope
375 options.magicscope = this;
376 options.savepath = this.currentpath;
377 M.core_filepicker.show(Y, options);
378 },
379
e709ddd2
MG
380 print_path: function() {
381 var p = this.options.path;
382 this.pathbar.setContent('').addClass('empty');
383 if (p && p.length!=0 && this.viewmode != 2) {
384 for(var i = 0; i < p.length; i++) {
385 var el = this.pathnode.cloneNode(true);
386 this.pathbar.appendChild(el);
6a0d7194
DP
387
388 if (i == 0) {
389 el.addClass('first');
390 }
391 if (i == p.length-1) {
392 el.addClass('last');
393 }
394
395 if (i%2) {
396 el.addClass('even');
397 } else {
398 el.addClass('odd');
399 }
e709ddd2
MG
400 el.one('.fp-path-folder-name').setContent(p[i].name).
401 on('click', function(e, path) {
402 e.preventDefault();
469a53a0 403 this.refresh(path);
e709ddd2
MG
404 }, this, p[i].path);
405 }
406 this.pathbar.removeClass('empty');
407 }
408 },
409 get_filepath: function(obj) {
410 if (obj.path && obj.path.length) {
411 return obj.path[obj.path.length-1].path;
412 }
413 return '';
414 },
415 treeview_dynload: function(node, cb) {
416 var retrieved_children = {};
417 if (node.children) {
418 for (var i in node.children) {
419 retrieved_children[node.children[i].path] = node.children[i];
420 }
421 }
e0ff0867
MG
422 if (!node.path || node.path == '/') {
423 // this is a root pseudo folder
424 node.fileinfo.filepath = '/';
425 node.fileinfo.type = 'folder';
426 node.fileinfo.fullname = node.fileinfo.title;
427 node.fileinfo.filename = '.';
428 }
e709ddd2
MG
429 this.request({
430 action:'list',
431 params: {filepath:node.path?node.path:''},
432 scope:this,
433 callback: function(id, obj, args) {
434 var list = obj.list;
435 var scope = args.scope;
436 // check that user did not leave the view mode before recieving this response
437 if (!(scope.viewmode == 2 && node && node.getChildrenEl())) {
438 return;
439 }
440 if (cb != null) { // (in manual mode do not update current path)
441 scope.options = obj;
694beb54 442 scope.currentpath = node.path?node.path:'/';
e709ddd2
MG
443 }
444 node.highlight(false);
6a0d7194
DP
445 node.origlist = obj.list ? obj.list : null;
446 node.origpath = obj.path ? obj.path : null;
e709ddd2
MG
447 node.children = [];
448 for(k in list) {
449 if (list[k].type == 'folder' && retrieved_children[list[k].filepath]) {
450 // if this child is a folder and has already been retrieved
c092681b 451 retrieved_children[list[k].filepath].fileinfo = list[k];
e709ddd2
MG
452 node.children[node.children.length] = retrieved_children[list[k].filepath];
453 } else {
454 // append new file to the list
455 scope.view_files([list[k]]);
456 }
457 }
458 if (cb == null) {
459 node.refresh();
840912d5 460 } else {
e709ddd2
MG
461 // invoke callback requested by TreeView component
462 cb();
494bf5c8 463 }
469a53a0 464 scope.content_scrolled();
56a7bf68 465 }
e709ddd2
MG
466 }, false);
467 },
469a53a0
MG
468 content_scrolled: function(e) {
469 setTimeout(Y.bind(function() {
470 if (this.processingimages) {return;}
471 this.processingimages = true;
472 var scope = this,
473 fpcontent = this.filemanager.one('.fp-content'),
474 fpcontenty = fpcontent.getY(),
475 fpcontentheight = fpcontent.getStylePx('height'),
476 is_node_visible = function(node) {
477 var offset = node.getY()-fpcontenty;
478 if (offset <= fpcontentheight && (offset >=0 || offset+node.getStylePx('height')>=0)) {
479 return true;
480 }
481 return false;
482 };
483 // replace src for visible images that need to be lazy-loaded
484 if (scope.lazyloading) {
485 fpcontent.all('img').each( function(node) {
486 if (node.get('id') && scope.lazyloading[node.get('id')] && is_node_visible(node)) {
9213f547 487 node.setImgRealSrc(scope.lazyloading);
469a53a0
MG
488 }
489 });
490 }
491 this.processingimages = false;
492 }, this), 200)
493 },
e709ddd2 494 view_files: function(appendfiles) {
906e7d89 495 this.filemanager.removeClass('fm-updating').removeClass('fm-noitems');
1908ae06 496 if ((appendfiles == null) && (!this.options.list || this.options.list.length == 0) && this.viewmode != 2) {
906e7d89 497 this.filemanager.addClass('fm-noitems');
56a7bf68 498 return;
56a7bf68 499 }
e709ddd2
MG
500 var list = (appendfiles != null) ? appendfiles : this.options.list;
501 var element_template;
502 if (this.viewmode == 2 || this.viewmode == 3) {
503 element_template = Y.Node.create(M.form_filemanager.templates.listfilename);
504 } else {
505 this.viewmode = 1;
506 element_template = Y.Node.create(M.form_filemanager.templates.iconfilename);
507 }
508 var options = {
509 viewmode : this.viewmode,
510 appendonly : appendfiles != null,
511 filenode : element_template,
512 callbackcontext : this,
513 callback : function(e, node) {
23b83009 514 if (e.preventDefault) { e.preventDefault(); }
e709ddd2
MG
515 if (node.type == 'folder') {
516 this.refresh(node.filepath);
517 } else {
518 this.select_file(node);
519 }
520 },
521 rightclickcallback : function(e, node) {
23b83009 522 if (e.preventDefault) { e.preventDefault(); }
e709ddd2 523 this.select_file(node);
6c2367cc
MG
524 },
525 classnamecallback : function(node) {
526 var classname = '';
e0ff0867
MG
527 if (node.type == 'folder' || (!node.type && !node.filename)) {
528 classname = classname + ' fp-folder';
529 }
530 if (node.filename || node.filepath || (node.path && node.path != '/')) {
531 classname = classname + ' fp-hascontextmenu';
532 }
9a62f779
MG
533 if (node.isref) {
534 classname = classname + ' fp-isreference';
535 }
536 if (node.refcount) {
537 classname = classname + ' fp-hasreferences';
538 }
0b2bfbd1
MG
539 if (node.originalmissing) {
540 classname = classname + ' fp-originalmissing';
541 }
6c2367cc
MG
542 if (node.sortorder == 1) { classname = classname + ' fp-mainfile';}
543 return Y.Lang.trim(classname);
ac9c14dd 544 }
e709ddd2
MG
545 };
546 if (this.viewmode == 2) {
547 options.dynload = true;
548 options.filepath = this.options.path;
549 options.treeview_dynload = this.treeview_dynload;
23b83009 550 options.norootrightclick = true;
e709ddd2 551 options.callback = function(e, node) {
23b83009
MG
552 // TODO MDL-32736 e is not an event here but an object with properties 'event' and 'node'
553 if (!node.fullname) {return;}
e709ddd2
MG
554 if (node.type != 'folder') {
555 if (e.node.parent && e.node.parent.origpath) {
556 // set the current path
557 this.options.path = e.node.parent.origpath;
558 this.options.list = e.node.parent.origlist;
559 this.print_path();
560 }
694beb54 561 this.currentpath = node.filepath;
e709ddd2
MG
562 this.select_file(node);
563 } else {
564 // save current path and filelist (in case we want to jump to other viewmode)
565 this.options.path = e.node.origpath;
566 this.options.list = e.node.origlist;
e0ff0867 567 this.currentpath = node.filepath;
e709ddd2
MG
568 this.print_path();
569 //this.content_scrolled();
570 }
571 };
840912d5 572 }
6a0d7194
DP
573 if (!this.lazyloading) {
574 this.lazyloading={};
575 }
e709ddd2 576 this.filemanager.one('.fp-content').fp_display_filelist(options, list, this.lazyloading);
469a53a0 577 this.content_scrolled();
840912d5 578 },
e709ddd2 579 populate_licenses_select: function(node) {
6a0d7194
DP
580 if (!node) {
581 return;
582 }
e709ddd2
MG
583 node.setContent('');
584 var licenses = this.options.licenses;
585 for (var i in licenses) {
586 var option = Y.Node.create('<option/>').
587 set('value', licenses[i].shortname).
588 setContent(licenses[i].fullname);
589 node.appendChild(option)
f45dfeeb 590 }
e709ddd2
MG
591 },
592 set_current_tree: function(tree) {
593 var appendfilepaths = function(list, node) {
594 if (!node || !node.children || !node.children.length) {return;}
595 for (var i in node.children) {
596 list[list.length] = node.children[i].filepath;
597 appendfilepaths(list, node.children[i]);
598 }
f0a163ed 599 }
e709ddd2
MG
600 var list = ['/'];
601 appendfilepaths(list, tree);
55089a9d 602 var selectnode = this.selectnode;
e709ddd2
MG
603 node = selectnode.one('.fp-path select');
604 node.setContent('');
605 for (var i in list) {
606 node.appendChild(Y.Node.create('<option/>').
607 set('value', list[i]).setContent(list[i]))
f45dfeeb 608 }
840912d5 609 },
9a62f779 610 update_file: function(confirmed) {
55089a9d 611 var selectnode = this.selectnode;
e709ddd2
MG
612 var fileinfo = this.selectui.fileinfo;
613
c092681b 614 var newfilename = Y.Lang.trim(selectnode.one('.fp-saveas input').get('value'));
e709ddd2
MG
615 var filenamechanged = (newfilename && newfilename != fileinfo.fullname);
616 var pathselect = selectnode.one('.fp-path select'),
617 pathindex = pathselect.get('selectedIndex'),
618 targetpath = pathselect.get("options").item(pathindex).get('value');
619 var filepathchanged = (targetpath != this.get_parent_folder_name(fileinfo));
c092681b
MG
620 var newauthor = Y.Lang.trim(selectnode.one('.fp-author input').get('value'));
621 var authorchanged = (newauthor != Y.Lang.trim(fileinfo.author));
622 var licenseselect = selectnode.one('.fp-license select'),
623 licenseindex = licenseselect.get('selectedIndex'),
624 newlicense = licenseselect.get("options").item(licenseindex).get('value');
625 var licensechanged = (newlicense != fileinfo.license);
e709ddd2 626
c092681b 627 var params, action;
9a62f779 628 var dialog_options = {callback:this.update_file, callbackargs:[true], scope:this};
c092681b
MG
629 if (fileinfo.type == 'folder') {
630 if (!newfilename) {
631 this.print_msg(M.str.repository.entername, 'error');
632 return;
633 }
634 if (filenamechanged || filepathchanged) {
9a62f779
MG
635 if (!confirmed) {
636 dialog_options.message = M.str.repository.confirmrenamefolder;
637 this.show_confirm_dialog(dialog_options);
638 return;
639 }
c092681b
MG
640 params = {filepath:fileinfo.filepath, newdirname:newfilename, newfilepath:targetpath};
641 action = 'updatedir';
642 }
643 } else {
644 if (!newfilename) {
645 this.print_msg(M.str.repository.enternewname, 'error');
646 return;
647 }
9a62f779
MG
648 if ((filenamechanged || filepathchanged) && !confirmed && fileinfo.refcount) {
649 dialog_options.message = M.util.get_string('confirmrenamefile', 'repository', fileinfo.refcount);
650 this.show_confirm_dialog(dialog_options);
651 return;
652 }
c092681b
MG
653 if (filenamechanged || filepathchanged || licensechanged || authorchanged) {
654 params = {filepath:fileinfo.filepath, filename:fileinfo.fullname,
655 newfilename:newfilename, newfilepath:targetpath,
656 newlicense:newlicense, newauthor:newauthor};
657 action = 'updatefile';
658 }
e709ddd2 659 }
c092681b 660 if (!action) {
e709ddd2
MG
661 // no changes
662 this.selectui.hide();
c092681b 663 return;
e709ddd2 664 }
e709ddd2 665 selectnode.addClass('loading');
c092681b
MG
666 this.request({
667 action: action,
668 scope: this,
669 params: params,
670 callback: function(id, obj, args) {
671 if (obj.error) {
672 selectnode.removeClass('loading');
673 args.scope.print_msg(obj.error, 'error');
674 } else {
e709ddd2
MG
675 args.scope.selectui.hide();
676 args.scope.refresh((obj && obj.filepath) ? obj.filepath : '/');
677 if (typeof M.core_formchangechecker != 'undefined') {
678 M.core_formchangechecker.set_form_changed();
679 }
1a79133b 680 }
c092681b
MG
681 }
682 });
840912d5 683 },
9a62f779
MG
684 /**
685 * Displays a confirmation dialog
686 * Expected attributes in dialog_options: message, callback, callbackargs(optional), scope(optional)
687 */
688 show_confirm_dialog: function(dialog_options) {
689 // instead of M.util.show_confirm_dialog(e, dialog_options);
690 if (!this.confirm_dlg) {
5e117466 691 this.confirm_dlg_node = Y.Node.createWithFilesSkin(M.form_filemanager.templates.confirmdialog);
9a62f779
MG
692 var node = this.confirm_dlg_node;
693 node.generateID();
9a62f779
MG
694 this.confirm_dlg = new Y.Panel({
695 srcNode : node,
696 zIndex : 800000,
697 centered : true,
698 modal : true,
699 visible : false,
700 render : true,
701 buttons : {}
702 });
703 this.confirm_dlg.plug(Y.Plugin.Drag,{handles:['#'+node.get('id')+' .yui3-widget-hd']});
6a0d7194 704 var handle_confirm = function(ev) {
9a62f779
MG
705 var dlgopt = this.confirm_dlg.dlgopt;
706 ev.preventDefault();
707 this.confirm_dlg.hide();
708 if (dlgopt.callback) {
709 if (dlgopt.callbackargs) {
710 dlgopt.callback.apply(dlgopt.scope || this, dlgopt.callbackargs);
711 } else {
712 dlgopt.callback.apply(dlgopt.scope || this);
713 }
714 }
715 }
6a0d7194 716 var handle_cancel = function(ev) {
9a62f779
MG
717 ev.preventDefault();
718 this.confirm_dlg.hide();
719 }
6a0d7194
DP
720 node.one('.fp-dlg-butconfirm').on('click', handle_confirm, this);
721 node.one('.fp-dlg-butcancel').on('click', handle_cancel, this);
9a62f779
MG
722 }
723 this.confirm_dlg.dlgopt = dialog_options;
724 this.confirm_dlg_node.one('.fp-dlg-text').setContent(dialog_options.message);
725 this.confirm_dlg.show();
726 },
e709ddd2 727 setup_select_file: function() {
55089a9d 728 var selectnode = this.selectnode;
e709ddd2
MG
729 // bind labels with corresponding inputs
730 selectnode.all('.fp-saveas,.fp-path,.fp-author,.fp-license').each(function (node) {
731 node.all('label').set('for', node.one('input,select').generateID());
732 });
733 this.populate_licenses_select(selectnode.one('.fp-license select'));
734 // register event on clicking buttons
735 selectnode.one('.fp-file-update').on('click', function(e) {
736 e.preventDefault();
737 this.update_file();
738 }, this);
739 selectnode.one('.fp-file-download').on('click', function(e) {
740 e.preventDefault();
6c2367cc 741 if (this.selectui.fileinfo.type != 'folder') {
e7ae9c26
FM
742 node = Y.Node.create('<iframe></iframe>').setStyles({
743 visibility : 'hidden',
744 width : '1px',
745 height : '1px'
746 });
747 node.set('src', this.selectui.fileinfo.url);
748 Y.one('body').appendChild(node);
6c2367cc 749 }
e709ddd2
MG
750 }, this);
751 selectnode.one('.fp-file-delete').on('click', function(e) {
752 e.preventDefault();
840912d5
DC
753 var dialog_options = {};
754 var params = {};
9a62f779 755 var fileinfo = this.selectui.fileinfo;
840912d5 756 dialog_options.scope = this;
9a62f779
MG
757 params.filepath = fileinfo.filepath;
758 if (fileinfo.type == 'folder') {
840912d5 759 params.filename = '.';
9a62f779 760 dialog_options.message = M.str.repository.confirmdeletefolder;
840912d5 761 } else {
9a62f779
MG
762 params.filename = fileinfo.fullname;
763 if (fileinfo.refcount) {
764 dialog_options.message = M.util.get_string('confirmdeletefilewithhref', 'repository', fileinfo.refcount);
765 } else {
766 dialog_options.message = M.str.repository.confirmdeletefile;
767 }
840912d5 768 }
20fb563e
PS
769 dialog_options.callbackargs = [params];
770 dialog_options.callback = function(params) {
e709ddd2 771 //selectnode.addClass('loading');
840912d5
DC
772 this.request({
773 action: 'delete',
20fb563e 774 scope: this,
840912d5
DC
775 params: params,
776 callback: function(id, obj, args) {
e709ddd2
MG
777 //args.scope.selectui.hide();
778 args.scope.filecount--;
779 args.scope.refresh(obj.filepath);
a5dd1f4f
SH
780 if (typeof M.core_formchangechecker != 'undefined') {
781 M.core_formchangechecker.set_form_changed();
782 }
56a7bf68 783 }
840912d5 784 });
d3067516 785 };
e709ddd2 786 this.selectui.hide(); // TODO remove this after confirm dialog is replaced with YUI3
9a62f779 787 this.show_confirm_dialog(dialog_options);
e709ddd2
MG
788 }, this);
789 selectnode.one('.fp-file-zip').on('click', function(e) {
790 e.preventDefault();
791 var params = {};
792 var fileinfo = this.selectui.fileinfo;
6c2367cc
MG
793 if (fileinfo.type != 'folder') {
794 // this button should not even be shown
795 return;
796 }
e709ddd2
MG
797 params['filepath'] = fileinfo.filepath;
798 params['filename'] = '.';
799 selectnode.addClass('loading');
800 this.request({
801 action: 'zip',
802 scope: this,
803 params: params,
804 callback: function(id, obj, args) {
805 args.scope.selectui.hide();
806 args.scope.refresh(obj.filepath);
840912d5 807 }
e709ddd2
MG
808 });
809 }, this);
810 selectnode.one('.fp-file-unzip').on('click', function(e) {
811 e.preventDefault();
812 var params = {};
813 var fileinfo = this.selectui.fileinfo;
6c2367cc
MG
814 if (fileinfo.type != 'zip') {
815 // this button should not even be shown
816 return;
817 }
e709ddd2
MG
818 params['filepath'] = fileinfo.filepath;
819 params['filename'] = fileinfo.fullname;
820 selectnode.addClass('loading');
821 this.request({
822 action: 'unzip',
823 scope: this,
824 params: params,
825 callback: function(id, obj, args) {
826 args.scope.selectui.hide();
827 args.scope.refresh(obj.filepath);
840912d5 828 }
e709ddd2
MG
829 });
830 }, this);
831 selectnode.one('.fp-file-setmain').on('click', function(e) {
832 e.preventDefault();
833 var params = {};
834 var fileinfo = this.selectui.fileinfo;
247804bc
FM
835 if (!this.enablemainfile || fileinfo.type == 'folder') {
836 // this button should not even be shown for folders or when mainfile is disabled
6c2367cc
MG
837 return;
838 }
e709ddd2
MG
839 params['filepath'] = fileinfo.filepath;
840 params['filename'] = fileinfo.fullname;
841 selectnode.addClass('loading');
842 this.request({
843 action: 'setmainfile',
844 scope: this,
845 params: params,
846 callback: function(id, obj, args) {
847 args.scope.selectui.hide();
6c2367cc 848 args.scope.refresh(fileinfo.filepath);
840912d5 849 }
840912d5 850 });
e709ddd2
MG
851 }, this);
852 selectnode.all('.fp-file-cancel').on('click', function(e) {
853 e.preventDefault();
854 // TODO if changed asked to confirm, the same with close button
855 this.selectui.hide();
856 }, this);
857 },
858 get_parent_folder_name: function(node) {
6a0d7194
DP
859 if (node.type != 'folder' || node.filepath.length < node.fullname.length+1) {
860 return node.filepath;
861 }
e709ddd2
MG
862 var basedir = node.filepath.substr(0, node.filepath.length - node.fullname.length - 1);
863 var lastdir = node.filepath.substr(node.filepath.length - node.fullname.length - 2);
6a0d7194
DP
864 if (lastdir == '/' + node.fullname + '/') {
865 return basedir;
866 }
e709ddd2
MG
867 return node.filepath;
868 },
869 select_file: function(node) {
55089a9d 870 var selectnode = this.selectnode;
e709ddd2
MG
871 selectnode.removeClass('loading').removeClass('fp-folder').
872 removeClass('fp-file').removeClass('fp-zip').removeClass('fp-cansetmain');
6a0d7194
DP
873 if (node.type == 'folder' || node.type == 'zip') {
874 selectnode.addClass('fp-'+node.type);
875 } else {
876 selectnode.addClass('fp-file');
877 }
6c2367cc 878 if (this.enablemainfile && (node.sortorder != 1) && node.type == 'file') {
e709ddd2 879 selectnode.addClass('fp-cansetmain');
840912d5 880 }
e709ddd2
MG
881 this.selectui.fileinfo = node;
882 selectnode.one('.fp-saveas input').set('value', node.fullname);
883 var foldername = this.get_parent_folder_name(node);
5e117466 884 selectnode.all('.fp-author input').set('value', node.author ? node.author : '');
e709ddd2
MG
885 selectnode.all('.fp-license select option[selected]').set('selected', false);
886 selectnode.all('.fp-license select option[value='+node.license+']').set('selected', true);
887 selectnode.all('.fp-path select option[selected]').set('selected', false);
888 selectnode.all('.fp-path select option').each(function(el){
6a0d7194
DP
889 if (el.get('value') == foldername) {
890 el.set('selected', true);
891 }
840912d5 892 });
c092681b 893 selectnode.all('.fp-author input, .fp-license select').set('disabled',(node.type == 'folder')?'disabled':'');
e709ddd2 894 // display static information about a file (when known)
9dbdf31f 895 var attrs = ['datemodified','datecreated','size','dimensions','original','reflist'];
e709ddd2
MG
896 for (var i in attrs) {
897 if (selectnode.one('.fp-'+attrs[i])) {
898 var value = (node[attrs[i]+'_f']) ? node[attrs[i]+'_f'] : (node[attrs[i]] ? node[attrs[i]] : '');
899 selectnode.one('.fp-'+attrs[i]).addClassIf('fp-unknown', ''+value == '')
900 .one('.fp-value').setContent(value);
901 }
902 }
903 // display thumbnail
904 var imgnode = Y.Node.create('<img/>').
905 set('src', node.realthumbnail ? node.realthumbnail : node.thumbnail).
906 setStyle('maxHeight', ''+(node.thumbnail_height ? node.thumbnail_height : 90)+'px').
907 setStyle('maxWidth', ''+(node.thumbnail_width ? node.thumbnail_width : 90)+'px');
908 selectnode.one('.fp-thumbnail').setContent('').appendChild(imgnode);
9a62f779
MG
909 // load original location if applicable
910 if (node.isref && !node.original) {
911 selectnode.one('.fp-original').removeClass('fp-unknown').addClass('fp-loading');
912 this.request({
913 action: 'getoriginal',
914 scope: this,
915 params: {'filepath':node.filepath,'filename':node.fullname},
916 callback: function(id, obj, args) {
9dbdf31f 917 // check if we did not select another file meanwhile
9a62f779
MG
918 var scope = args.scope;
919 if (scope.selectui.fileinfo && node &&
920 scope.selectui.fileinfo.filepath == node.filepath &&
921 scope.selectui.fileinfo.fullname == node.fullname) {
922 selectnode.one('.fp-original').removeClass('fp-loading');
923 if (obj.original) {
924 node.original = obj.original;
925 selectnode.one('.fp-original .fp-value').setContent(node.original);
926 } else {
927 selectnode.one('.fp-original .fp-value').setContent(M.str.repository.unknownsource);
928 }
929 }
930 }
931 }, false);
932 }
9dbdf31f
MG
933 // load references list if applicable
934 selectnode.one('.fp-refcount').setContent(node.refcount ? M.util.get_string('referencesexist', 'repository', node.refcount) : '');
935 if (node.refcount && !node.reflist) {
936 selectnode.one('.fp-reflist').removeClass('fp-unknown').addClass('fp-loading');
937 this.request({
938 action: 'getreferences',
939 scope: this,
940 params: {'filepath':node.filepath,'filename':node.fullname},
941 callback: function(id, obj, args) {
942 // check if we did not select another file meanwhile
943 var scope = args.scope;
944 if (scope.selectui.fileinfo && node &&
945 scope.selectui.fileinfo.filepath == node.filepath &&
946 scope.selectui.fileinfo.fullname == node.fullname) {
947 selectnode.one('.fp-reflist').removeClass('fp-loading');
948 if (obj.references) {
949 node.reflist = '';
950 for (var i in obj.references) {
951 node.reflist += '<li>'+obj.references[i]+'</li>';
952 }
953 selectnode.one('.fp-reflist .fp-value').setContent(node.reflist);
954 } else {
955 selectnode.one('.fp-reflist .fp-value').setContent('');
956 }
957 }
958 }
959 }, false);
960 }
e709ddd2
MG
961 // show panel
962 this.selectui.show();
963 },
964 render: function() {
965 this.print_path();
966 this.view_files();
840912d5
DC
967 }
968 });
4c508047
PS
969
970 // finally init everything needed
906e7d89
MG
971 // hide loading picture, display filemanager interface
972 var filemanager = Y.one('#filemanager-'+options.client_id);
973 filemanager.removeClass('fm-loading').addClass('fm-loaded');
4c508047 974
f08fac7c
DS
975 var manager = new FileManagerHelper(options);
976 var dndoptions = {
977 filemanager: manager,
b2dbfa90 978 acceptedtypes: options.filepicker.accepted_types,
f08fac7c 979 clientid: options.client_id,
140669a9 980 author: options.author,
f08fac7c
DS
981 maxfiles: options.maxfiles,
982 maxbytes: options.maxbytes,
983 itemid: options.itemid,
984 repositories: manager.filepicker_options.repositories,
906e7d89 985 containerid: manager.dndcontainer.get('id')
f08fac7c
DS
986 };
987 M.form_dndupload.init(Y, dndoptions);
4c508047 988};