MDL-31901: Introducing renderers for filepicker:
[moodle.git] / repository / filepicker.js
CommitLineData
99eaca9d
DC
1// YUI3 File Picker module for moodle
2// Author: Dongsheng Cai <dongsheng@moodle.com>
3
4/**
5 *
6 * File Picker UI
7 * =====
b5e7b638 8 * this.fpnode, contains reference to filepicker Node, non-empty if and only if rendered
99eaca9d 9 * this.api, stores the URL to make ajax request
99eaca9d 10 * this.mainui, YUI Panel
b5e7b638
MG
11 * this.selectui, YUI Panel for selecting particular file
12 * this.msg_dlg, YUI Panel for error or info message
13 * this.process_dlg, YUI Panel for processing existing filename
99eaca9d 14 * this.treeview, YUI Treeview
99eaca9d 15 * this.viewmode, store current view mode
b5e7b638
MG
16 * this.pathbar, reference to the Node with path bar
17 * this.pathnode, a Node element representing one folder in a path bar (not attached anywhere, just used for template)
99eaca9d
DC
18 *
19 * Filepicker options:
20 * =====
99eaca9d
DC
21 * this.options.client_id, the instance id
22 * this.options.contextid
23 * this.options.itemid
24 * this.options.repositories, stores all repositories displaied in file picker
25 * this.options.formcallback
26 *
27 * Active repository options
28 * =====
29 * this.active_repo.id
30 * this.active_repo.nosearch
31 * this.active_repo.norefresh
32 * this.active_repo.nologin
33 * this.active_repo.help
34 * this.active_repo.manage
8cbef19e 35 *
99eaca9d
DC
36 * Server responses
37 * =====
38 * this.filelist, cached filelist
39 * this.pages
40 * this.page
41 * this.filepath, current path
42 * this.logindata, cached login form
43 */
44
4c508047 45M.core_filepicker = M.core_filepicker || {};
99eaca9d 46
4c508047
PS
47/**
48 * instances of file pickers used on page
49 */
50M.core_filepicker.instances = M.core_filepicker.instances || {};
539d4041 51M.core_filepicker.active_filepicker = null;
4c508047 52
b5e7b638
MG
53/**
54 * HTML Templates to use in FilePicker
55 */
56M.core_filepicker.templates = M.core_filepicker.templates || {};
57
4c508047
PS
58/**
59 * Init and show file picker
60 */
61M.core_filepicker.show = function(Y, options) {
62 if (!M.core_filepicker.instances[options.client_id]) {
8cbef19e 63 M.core_filepicker.init(Y, options);
99eaca9d 64 }
4c508047
PS
65 M.core_filepicker.instances[options.client_id].show();
66};
67
68/**
69 * Add new file picker to current instances
70 */
71M.core_filepicker.init = function(Y, options) {
b5e7b638
MG
72 if (options.templates);
73 for (var templid in options.templates) {
74 this.templates[templid] = options.templates[templid];
75 }
76
4c508047
PS
77 var FilePickerHelper = function(options) {
78 FilePickerHelper.superclass.constructor.apply(this, arguments);
8cbef19e 79 };
4c508047
PS
80
81 FilePickerHelper.NAME = "FilePickerHelper";
82 FilePickerHelper.ATTRS = {
99eaca9d
DC
83 options: {},
84 lang: {}
85 };
4c508047
PS
86
87 Y.extend(FilePickerHelper, Y.Base, {
9598d578 88 api: M.cfg.wwwroot+'/repository/repository_ajax.php',
7f9358fc 89 cached_responses: {},
4c508047
PS
90
91 initializer: function(options) {
92 this.options = options;
392d5fd4
DC
93 if (!this.options.savepath) {
94 this.options.savepath = '/';
95 }
99eaca9d 96 },
4c508047 97
99eaca9d
DC
98 destructor: function() {
99 },
4c508047 100
99eaca9d 101 request: function(args, redraw) {
c26855ff 102 var client_id = args.client_id;
f392caba
DC
103 if (!args.api) {
104 var api = this.api + '?action='+args.action;
105 } else {
106 var api = args.api + '?action='+args.action;
107 }
99eaca9d
DC
108 var params = {};
109 var scope = this;
110 if (args['scope']) {
111 scope = args['scope'];
112 }
113 params['repo_id']=args.repository_id;
114 params['p'] = args.path?args.path:'';
115 params['page'] = args.page?args.page:'';
116 params['env']=this.options.env;
117 // the form element only accept certain file types
118 params['accepted_types']=this.options.accepted_types;
e35194be 119 params['sesskey'] = M.cfg.sesskey;
99eaca9d 120 params['client_id'] = args.client_id;
0c4edaa2 121 params['itemid'] = this.options.itemid?this.options.itemid:0;
8a3e6a56 122 params['maxbytes'] = this.options.maxbytes?this.options.maxbytes:-1;
be85f7ab
DC
123 if (this.options.context && this.options.context.id) {
124 params['ctx_id'] = this.options.context.id;
125 }
99eaca9d
DC
126 if (args['params']) {
127 for (i in args['params']) {
128 params[i] = args['params'][i];
129 }
130 }
64654e78
DC
131 if (args.action == 'upload') {
132 var list = [];
133 for(var k in params) {
134 var value = params[k];
135 if(value instanceof Array) {
136 for(var i in value) {
137 list.push(k+'[]='+value[i]);
138 }
139 } else {
140 list.push(k+'='+value);
141 }
142 }
143 params = list.join('&');
144 } else {
145 params = build_querystring(params);
146 }
99eaca9d
DC
147 var cfg = {
148 method: 'POST',
149 on: {
150 complete: function(id,o,p) {
151 if (!o) {
b5e7b638 152 // TODO
99eaca9d
DC
153 alert('IO FATAL');
154 return;
155 }
4c508047
PS
156 var data = null;
157 try {
158 data = Y.JSON.parse(o.responseText);
159 } catch(e) {
879b4f9a 160 scope.print_msg(M.str.repository.invalidjson, 'error');
b5e7b638 161 scope.display_error(M.str.repository.invalidjson+'<pre>'+stripHTML(o.responseText)+'</pre>', 'invalidjson')
c26855ff 162 return;
4c508047 163 }
1dce6261 164 // error checking
e35194be
DC
165 if (data && data.error) {
166 scope.print_msg(data.error, 'error');
a5159b86
MG
167 if (args.onerror) {
168 args.onerror(id,data,p);
169 } else {
170 Y.one(panel_id).set('innerHTML', '');
171 }
1dce6261 172 return;
f392caba
DC
173 } else if (data && data.event) {
174 switch (data.event) {
175 case 'fileexists':
176 scope.process_existing_file(data);
177 break;
178 default:
179 break;
180 }
1dce6261 181 } else {
879b4f9a
DC
182 if (data.msg) {
183 scope.print_msg(data.msg, 'info');
184 }
7f9358fc
MG
185 // cache result if applicable
186 if (args.action != 'upload' && data.allowcaching) {
187 scope.cached_responses[params] = data;
188 }
189 // invoke callback
1dce6261
DC
190 args.callback(id,data,p);
191 }
99eaca9d
DC
192 }
193 },
194 arguments: {
195 scope: scope
196 },
197 headers: {
bd2db41a 198 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
99eaca9d 199 },
64654e78 200 data: params,
4c508047 201 context: this
99eaca9d
DC
202 };
203 if (args.form) {
204 cfg.form = args.form;
205 }
7f9358fc
MG
206 // check if result of the same request has been already cached. If not, request it
207 // (never applicable in case of form submission and/or upload action):
208 if (!args.form && args.action != 'upload' && scope.cached_responses[params]) {
209 args.callback(null, scope.cached_responses[params], {scope: scope})
210 } else {
211 Y.io(api, cfg);
212 if (redraw) {
b5e7b638 213 this.wait();
7f9358fc 214 }
99eaca9d
DC
215 }
216 },
b5e7b638 217 /** displays the dialog and processes rename/overwrite if there is a file with the same name in the same filearea*/
f392caba
DC
218 process_existing_file: function(data) {
219 var scope = this;
b5e7b638 220 var handleOverwrite = function(e) {
f392caba 221 // overwrite
b5e7b638
MG
222 e.preventDefault();
223 var data = this.process_dlg.dialogdata;
f392caba
DC
224 var params = {}
225 params['existingfilename'] = data.existingfile.filename;
226 params['existingfilepath'] = data.existingfile.filepath;
227 params['newfilename'] = data.newfile.filename;
228 params['newfilepath'] = data.newfile.filepath;
b5e7b638
MG
229 this.hide_header();
230 this.request({
f392caba 231 'params': params,
b5e7b638 232 'scope': this,
f392caba
DC
233 'action':'overwrite',
234 'path': '',
b5e7b638
MG
235 'client_id': this.options.client_id,
236 'repository_id': this.active_repo.id,
f392caba 237 'callback': function(id, o, args) {
f392caba
DC
238 scope.hide();
239 // editor needs to update url
240 // filemanager do nothing
c8ad2c12
SH
241 if (scope.options.editor_target && scope.options.env == 'editor') {
242 scope.options.editor_target.value = data.existingfile.url;
f392caba 243 scope.options.editor_target.onchange();
1ae299f5 244 } else if (scope.options.env === 'filepicker') {
b5e7b638 245 var fileinfo = {'client_id':scope.options.client_id,
913b3cb3
JP
246 'url':data.existingfile.url,
247 'file':data.existingfile.filename};
248 scope.options.formcallback.apply(scope, [fileinfo]);
f392caba
DC
249 }
250 }
251 }, true);
252 }
b5e7b638
MG
253 var handleRename = function(e) {
254 // inserts file with the new name
255 e.preventDefault();
256 var scope = this;
257 var data = this.process_dlg.dialogdata;
c8ad2c12
SH
258 if (scope.options.editor_target && scope.options.env == 'editor') {
259 scope.options.editor_target.value = data.newfile.url;
f392caba
DC
260 scope.options.editor_target.onchange();
261 }
f392caba 262 scope.hide();
f392caba
DC
263 var formcallback_scope = null;
264 if (scope.options.magicscope) {
265 formcallback_scope = scope.options.magicscope;
266 } else {
267 formcallback_scope = scope;
268 }
b5e7b638 269 var fileinfo = {'client_id':scope.options.client_id,
794cc7e1
JP
270 'url':data.newfile.url,
271 'file':data.newfile.filename};
272 scope.options.formcallback.apply(formcallback_scope, [fileinfo]);
f392caba 273 }
b5e7b638 274 var handleCancel = function(e) {
f392caba 275 // Delete tmp file
b5e7b638 276 e.preventDefault();
f392caba 277 var params = {};
b5e7b638
MG
278 params['newfilename'] = this.process_dlg.dialogdata.newfile.filename;
279 params['newfilepath'] = this.process_dlg.dialogdata.newfile.filepath;
280 this.request({
f392caba 281 'params': params,
b5e7b638 282 'scope': this,
f392caba
DC
283 'action':'deletetmpfile',
284 'path': '',
b5e7b638
MG
285 'client_id': this.options.client_id,
286 'repository_id': this.active_repo.id,
f392caba 287 'callback': function(id, o, args) {
b5e7b638 288 // let it be in background, from user point of view nothing is happenning
f392caba 289 }
b5e7b638
MG
290 }, false);
291 this.process_dlg.hide();
292 this.selectui.hide();
f392caba 293 }
b5e7b638
MG
294 if (!this.process_dlg) {
295 var node = Y.Node.create(M.core_filepicker.templates.processexistingfile);
296 this.fpnode.appendChild(node);
297 this.process_dlg = new Y.Panel({
298 srcNode : node,
299 headerContent: M.str.repository.fileexistsdialogheader,
300 zIndex : 800000,
301 centered : true,
302 modal : true,
303 visible : false,
304 render : true,
305 buttons : {}
306 });
307 node.one('.fp-dlg-butoverwrite').on('click', handleOverwrite, this);
308 node.one('.fp-dlg-butrename').on('click', handleRename, this);
309 node.one('.fp-dlg-butcancel').on('click', handleCancel, this);
310 if (this.options.env == 'editor') {
311 node.one('.fp-dlg-text').setContent(M.str.repository.fileexistsdialog_editor);
312 } else {
313 node.one('.fp-dlg-text').setContent(M.str.repository.fileexistsdialog_filemanager);
314 }
f392caba 315 }
b5e7b638
MG
316 this.process_dlg.dialogdata = data;
317 this.fpnode.one('.fp-dlg .fp-dlg-butrename').setContent(M.util.get_string('renameto', 'repository', data.newfile.filename));
318 this.process_dlg.show();
319 },
320 /** displays error instead of filepicker contents */
321 display_error: function(errortext, errorcode) {
322 this.fpnode.one('.fp-content').setContent(M.core_filepicker.templates.error);
323 this.fpnode.one('.fp-content .fp-error').
324 addClass(errorcode).
325 setContent(errortext);
f392caba 326 },
b5e7b638 327 /** displays message in a popup */
879b4f9a 328 print_msg: function(msg, type) {
b5e7b638
MG
329 var header = M.str.moodle.error;
330 if (type != 'error') {
331 type = 'info'; // one of only two types excepted
332 header = M.str.moodle.info;
879b4f9a
DC
333 }
334 if (!this.msg_dlg) {
b5e7b638
MG
335 var node = Y.Node.create(M.core_filepicker.templates.message);
336 this.fpnode.appendChild(node);
337
338 this.msg_dlg = new Y.Panel({
339 srcNode : node,
340 zIndex : 800000,
341 centered : true,
342 modal : true,
343 visible : false,
344 render : true
345 });
346 node.one('.fp-msg-butok').on('click', function(e) {
347 e.preventDefault();
348 this.msg_dlg.hide();
349 }, this);
879b4f9a 350 }
b5e7b638
MG
351
352 this.msg_dlg.set('headerContent', header);
353 this.fpnode.one('.fp-msg').removeClass('fp-msg-info').removeClass('fp-msg-error').addClass('fp-msg-'+type)
354 this.fpnode.one('.fp-msg .fp-msg-text').setContent(msg);
879b4f9a 355 this.msg_dlg.show();
879b4f9a 356 },
99eaca9d
DC
357 build_tree: function(node, level) {
358 var client_id = this.options.client_id;
1fb0173e 359 var dynload = this.active_repo.dynload;
99eaca9d
DC
360 var info = {
361 label:node.title,
99eaca9d
DC
362 filename:node.title,
363 source:node.source?node.source:'',
364 thumbnail:node.thumbnail,
365 path:node.path?node.path:[]
366 };
203bbcbe 367 var tmpNode = new YAHOO.widget.TextNode(info, level, false);
99eaca9d
DC
368 if(node.repo_id) {
369 tmpNode.repo_id=node.repo_id;
370 }else{
371 tmpNode.repo_id=this.active_repo.id;
372 }
373 if(node.children) {
374 if(node.expanded) {
375 tmpNode.expand();
376 }
1fb0173e
DC
377 if (dynload) {
378 tmpNode.scope = this;
379 }
99eaca9d
DC
380 tmpNode.isLeaf = false;
381 tmpNode.client_id = client_id;
382 if (node.path) {
383 tmpNode.path = node.path;
384 } else {
385 tmpNode.path = '';
386 }
387 for(var c in node.children) {
388 this.build_tree(node.children[c], tmpNode);
389 }
390 } else {
391 tmpNode.isLeaf = true;
392 }
393 },
4adecd7b 394 view_files: function() {
60a4bf98
DC
395 if (this.active_repo.issearchresult) {
396 // list view is desiged to display treeview
397 // it is not working well with search result
99eaca9d 398 this.view_as_icons();
99eaca9d 399 } else {
b5e7b638 400 this.viewbar_set_enabled(true);
4adecd7b
MG
401 if (this.viewmode == 1) {
402 this.view_as_icons();
403 } else if (this.viewmode == 2) {
404 this.view_as_list();
60a4bf98 405 } else {
4adecd7b 406 this.view_as_icons();
60a4bf98 407 }
99eaca9d
DC
408 }
409 },
1fb0173e
DC
410 treeview_dynload: function(node, cb) {
411 var scope = node.scope;
412 var client_id = scope.options.client_id;
413 var repository_id = scope.active_repo.id;
414 scope.request({
415 action:'list',
416 client_id: client_id,
417 repository_id: repository_id,
418 path:node.path?node.path:'',
419 page:node.page?args.page:'',
420 callback: function(id, obj, args) {
1fb0173e 421 var list = obj.list;
b5e7b638 422 scope.viewbar_set_enabled(true);
1fb0173e 423 scope.parse_repository_options(obj);
1fb0173e
DC
424 for(k in list) {
425 scope.build_tree(list[k], node);
426 }
427 cb();
428 }
429 }, false);
430 },
4adecd7b 431 view_as_list: function() {
b5e7b638 432 // TODO !!!!!!!!!!
1fb0173e 433 var scope = this;
4adecd7b
MG
434 var client_id = scope.options.client_id;
435 var dynload = scope.active_repo.dynload;
436 var list = this.filelist;
4adecd7b 437 scope.viewmode = 2;
4adecd7b 438 if (list && list.length==0) {
b5e7b638 439 this.display_error(M.str.repository.nofilesavailable, 'nofilesavailable');
4adecd7b
MG
440 return;
441 }
879b4f9a 442
b5e7b638
MG
443 var html = '<div class="fp-tree-panel" id="treeview-'+client_id+'"></div>';
444 this.fpnode.one('.fp-content').setContent(html);
445
4adecd7b
MG
446 scope.treeview = new YAHOO.widget.TreeView('treeview-'+client_id);
447 if (dynload) {
448 scope.treeview.setDynamicLoad(scope.treeview_dynload, 1);
449 }
99eaca9d 450
4adecd7b
MG
451 for(k in list) {
452 scope.build_tree(list[k], scope.treeview.getRoot());
453 }
454 scope.treeview.subscribe('clickEvent', function(e){
455 if(e.node.isLeaf){
456 var fileinfo = {};
457 fileinfo['title'] = e.node.data.filename;
458 fileinfo['source'] = e.node.data.source;
459 fileinfo['thumbnail'] = e.node.data.thumbnail;
460 scope.select_file(fileinfo);
99eaca9d 461 }
4adecd7b
MG
462 });
463 scope.treeview.draw();
99eaca9d
DC
464 },
465 view_as_icons: function() {
98b15580 466 var scope = this;
99eaca9d
DC
467 var client_id = this.options.client_id;
468 var list = this.filelist;
99eaca9d 469 this.viewmode = 1;
99eaca9d 470
60a4bf98 471 if (list && list.length==0) {
b5e7b638
MG
472 this.display_error(M.str.repository.nofilesavailable, 'nofilesavailable');
473 return;
879b4f9a 474 }
b5e7b638 475 this.fpnode.one('.fp-content').setContent(M.core_filepicker.templates.iconview);
879b4f9a 476
b5e7b638
MG
477 var element_template = this.fpnode.one('.fp-content').one('.fp-file');
478 var container = element_template.get('parentNode');
479 container.removeChild(element_template);
99eaca9d
DC
480 var count = 0;
481 for(var k in list) {
482 var node = list[k];
b5e7b638
MG
483 var element = element_template.cloneNode(true);
484 container.appendChild(element);
485 /*html = M.core_filepicker.templates.gridelementtemplate.
486 replace(/\{GRIDELEMENTID\}/g, 'fp-grid-'+client_id+'-'+count).
487 replace(/\{IMGID\}/g, 'fp-img-'+client_id+'-'+count).
488 replace(/\{FILENAMEID\}/g, 'fp-filename-'+client_id+'-'+count);*/
489 var filename = node.shorttitle ? node.shorttitle : node.title;
490 var filenamediv = element.one('.fp-filename');
491 filenamediv.setContent(filename);
492 var imgdiv = element.one('.fp-thumbnail');
493 var set_width = function(node, width) {
494 var widthmatches = node.getStyle('minWidth').match(/^(\d+)px$/)
495 if (widthmatches && parseInt(widthmatches[1])>width) {
496 width = parseInt(widthmatches[1]);
497 }
498 node.setStyle('width', '' + width + 'px')
99eaca9d 499 }
b5e7b638
MG
500 var set_height = function(node, height) {
501 var heightmatches = node.getStyle('minHeight').match(/^(\d+)px$/)
502 if (heightmatches && parseInt(heightmatches[1])>height) {
503 height = parseInt(heightmatches[1]);
504 }
505 node.setStyle('height', '' + height + 'px')
99eaca9d 506 }
b5e7b638
MG
507 var width = node.thumbnail_width ? node.thumbnail_width : 90;
508 var height = node.thumbnail_height ? node.thumbnail_height : 90;
509 set_width(filenamediv, width)
510 set_width(imgdiv, width)
511 set_height(imgdiv, height);
512 var img = Y.Node.create('<img/>').
513 set('src', node.thumbnail).
514 set('title', node.title);
99eaca9d 515 if(node.thumbnail_alt) {
b5e7b638 516 img.set('alt', node.thumbnail_alt);
99eaca9d
DC
517 }
518 if(node.thumbnail_title) {
b5e7b638 519 img.set('title', node.thumbnail_title);
99eaca9d 520 }
b5e7b638
MG
521 img.setStyle('maxWidth', ''+width+'px').setStyle('maxHeight', ''+height+'px');
522 imgdiv.appendChild(img)
99eaca9d 523
98b15580 524 var dynload = this.active_repo.dynload;
99eaca9d 525 if(node.children) {
b5e7b638 526 element.on('click', function(e, p) {
4adecd7b 527 e.preventDefault();
98b15580 528 if(dynload) {
98b15580
DC
529 var params = {'path':p.path};
530 scope.list(params);
99eaca9d
DC
531 }else{
532 this.filelist = p.children;
533 this.view_files();
534 }
535 }, this, node);
99eaca9d
DC
536 } else {
537 var fileinfo = {};
538 fileinfo['title'] = list[k].title;
539 fileinfo['source'] = list[k].source;
540 fileinfo['thumbnail'] = list[k].thumbnail;
1dce6261
DC
541 fileinfo['haslicense'] = list[k].haslicense?true:false;
542 fileinfo['hasauthor'] = list[k].hasauthor?true:false;
b5e7b638 543 element.on('click', function(e, args) {
4adecd7b 544 e.preventDefault();
99eaca9d
DC
545 this.select_file(args);
546 }, this, fileinfo);
547 }
548 count++;
549 }
99eaca9d
DC
550 },
551 select_file: function(args) {
b5e7b638 552 this.selectui.show();
99eaca9d 553 var client_id = this.options.client_id;
b5e7b638
MG
554 var selectnode = this.fpnode.one('.fp-select');
555 selectnode.one('#newname-'+client_id).set('value', args.title);
556 selectnode.one('#text-author-'+client_id).set('value', this.options.author);
99eaca9d 557
b5e7b638
MG
558 var imgnode = Y.Node.create('<img/>').set('src', args.thumbnail)
559 selectnode.one('#img-'+client_id).setContent('').appendChild(imgnode);
560
561 selectnode.one('#linkexternal-'+client_id).set('checked', ''); // default to unchecked
4adecd7b 562 if ((this.options.externallink && this.options.env == 'editor' && this.options.return_types != 1)) {
b5e7b638
MG
563 // enable checkbox 'Link external'
564 selectnode.one('#linkexternal-'+client_id).set('disabled', '');
565 selectnode.all('#linkexternal-'+client_id+',#wrap-linkexternal-'+client_id).removeClass('uneditable')
566 } else {
567 // disable checkbox 'Link external'
568 selectnode.one('#linkexternal-'+client_id).set('disabled', 'disabled');
569 selectnode.all('#linkexternal-'+client_id+',#wrap-linkexternal-'+client_id).addClass('uneditable')
570 if (this.options.return_types == 1) {
571 // support external links only
572 selectnode.one('#linkexternal-'+client_id).set('checked', 'checked');
573 }
99eaca9d 574 }
1dce6261 575
b5e7b638
MG
576 if (args.hasauthor) {
577 selectnode.one('#text-author-'+client_id).set('disabled', 'disabled');
578 selectnode.all('#text-author-'+client_id+',#wrap-text-author-'+client_id).addClass('uneditable')
579 } else {
580 selectnode.one('#text-author-'+client_id).set('disabled', '');
581 selectnode.all('#text-author-'+client_id+',#wrap-text-author-'+client_id).removeClass('uneditable')
1dce6261
DC
582 }
583
584 if (!args.haslicense) {
585 // the license of the file
b5e7b638
MG
586 this.populate_licenses_select(selectnode.one('#select-license-'+client_id));
587 selectnode.one('#wrap-select-license-'+client_id).set('disabled', '');
588 selectnode.all('#select-license-'+client_id+'#wrap-select-license-'+client_id).removeClass('uneditable');
589 } else {
590 selectnode.one('#wrap-select-license-'+client_id).set('disabled', 'disabled');
591 selectnode.all('#select-license-'+client_id+'#wrap-select-license-'+client_id).addClass('uneditable');
1dce6261 592 }
b5e7b638
MG
593 selectnode.one('form #filesource-'+client_id).set('value', args.source);
594 },
595 setup_select_file: function() {
596 var client_id = this.options.client_id;
597 var selectnode = this.fpnode.one('.fp-select');
598 var getfile = selectnode.one('#fp-confirm-'+client_id);
99eaca9d 599 getfile.on('click', function(e) {
b5e7b638 600 e.preventDefault();
99eaca9d
DC
601 var client_id = this.options.client_id;
602 var scope = this;
603 var repository_id = this.active_repo.id;
b5e7b638
MG
604 var title = selectnode.one('#newname-'+client_id).get('value');
605 var filesource = selectnode.one('form #filesource-'+client_id).get('value');
14469892 606 var params = {'title':title, 'source':filesource, 'savepath': this.options.savepath};
b5e7b638 607 var license = selectnode.one('#select-license-'+client_id);
1dce6261
DC
608 if (license) {
609 params['license'] = license.get('value');
b5e7b638 610 Y.Cookie.set('recentlicense', license.get('value'));
1dce6261 611 }
b5e7b638 612 var author = selectnode.one('#text-author-'+client_id);
392d5fd4 613 if (author){
1dce6261
DC
614 params['author'] = author.get('value');
615 }
99eaca9d 616
400d228e 617 if (this.options.externallink && this.options.env == 'editor') {
392d5fd4
DC
618 // in editor, images are stored in '/' only
619 params.savepath = '/';
766514a0 620 // when image or media button is clicked
4adecd7b 621 if ( this.options.return_types != 1 ) {
b5e7b638 622 var linkexternal = selectnode.one('#linkexternal-'+client_id);
400d228e 623 if (linkexternal && linkexternal.get('checked')) {
766514a0
DC
624 params['linkexternal'] = 'yes';
625 }
626 } else {
627 // when link button in editor clicked
99eaca9d
DC
628 params['linkexternal'] = 'yes';
629 }
766514a0
DC
630 }
631
632 if (this.options.env == 'url') {
99eaca9d
DC
633 params['linkexternal'] = 'yes';
634 }
635
b5e7b638 636 // TODO show some waiting process here
99eaca9d 637 this.request({
840912d5
DC
638 action:'download',
639 client_id: client_id,
640 repository_id: repository_id,
641 'params': params,
a5159b86 642 onerror: function(id, obj, args) {
b5e7b638 643 scope.selectui.hide();
a5159b86 644 },
840912d5 645 callback: function(id, obj, args) {
e0b85db4 646 if (scope.options.editor_target && scope.options.env=='editor') {
840912d5
DC
647 scope.options.editor_target.value=obj.url;
648 scope.options.editor_target.onchange();
649 }
650 scope.hide();
651 obj.client_id = client_id;
652 var formcallback_scope = null;
411caa63 653 if (args.scope.options.magicscope) {
840912d5
DC
654 formcallback_scope = args.scope.options.magicscope;
655 } else {
656 formcallback_scope = args.scope;
99eaca9d 657 }
840912d5
DC
658 scope.options.formcallback.apply(formcallback_scope, [obj]);
659 }
b5e7b638 660 }, false);
99eaca9d 661 }, this);
b5e7b638
MG
662 var elform = selectnode.one('form');
663 elform.appendChild(Y.Node.create('<input type="hidden"/>').set('id', 'filesource-'+client_id));
e0b85db4
DC
664 elform.on('keydown', function(e) {
665 if (e.keyCode == 13) {
666 getfile.simulate('click');
8cbef19e 667 e.preventDefault();
e0b85db4
DC
668 }
669 }, this);
b5e7b638 670 var cancel = selectnode.one('#fp-cancel-'+client_id);
99eaca9d 671 cancel.on('click', function(e) {
b5e7b638
MG
672 e.preventDefault();
673 this.selectui.hide();
99eaca9d 674 }, this);
99eaca9d 675 },
b5e7b638
MG
676 wait: function() {
677 this.fpnode.one('.fp-content').setContent(M.core_filepicker.templates.loading);
678 },
679 viewbar_set_enabled: function(mode) {
680 var viewbar = this.fpnode.one('.fp-viewbar')
681 if (viewbar) {
682 if (mode) {
683 viewbar.addClass('enabled').removeClass('disabled')
684 } else {
685 viewbar.removeClass('enabled').addClass('disabled')
686 }
99eaca9d 687 }
b5e7b638
MG
688 this.fpnode.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').removeClass('checked')
689 var modes = {1:'icons', 2:'tree', 3:'details'};
690 this.fpnode.all('.fp-vb-'+modes[this.viewmode]).addClass('checked');
691 },
692 viewbar_clicked: function(e) {
693 e.preventDefault();
694 var viewbar = this.fpnode.one('.fp-viewbar')
695 if (!viewbar || !viewbar.hasClass('disabled')) {
696 if (e.currentTarget.hasClass('fp-vb-tree')) {
697 this.viewmode = 2;
698 } else if (e.currentTarget.hasClass('fp-vb-details')) {
699 this.viewmode = 3;
700 } else {
701 this.viewmode = 1;
702 }
703 this.viewbar_set_enabled(true)
704 this.view_files();
705 Y.Cookie.set('recentviewmode', this.viewmode);
99eaca9d
DC
706 }
707 },
708 render: function() {
709 var client_id = this.options.client_id;
b5e7b638
MG
710 var nodecontent = M.core_filepicker.templates.generallayout.
711 replace(/\{TOOLBARID}/g, 'fp-tb-'+client_id).
712 replace(/\{TOOLBACKID}/g, 'fp-tb-back-'+client_id).
713 replace(/\{TOOLSEARCHID}/g, 'fp-tb-search-'+client_id).
714 replace(/\{TOOLREFRESHID}/g, 'fp-tb-refresh-'+client_id).
715 replace(/\{TOOLLOGOUTID}/g, 'fp-tb-logout-'+client_id).
716 replace(/\{TOOLMANAGEID}/g, 'fp-tb-manage-'+client_id).
717 replace(/\{TOOLHELPID}/g, 'fp-tb-help-'+client_id);
718 this.fpnode = Y.Node.create(nodecontent);
719 this.fpnode.set('id', 'filepicker-'+client_id);
720 var fpselectnode = Y.Node.create(M.core_filepicker.templates.selectlayout.
721 replace(/\{IMGID}/g, 'img-'+client_id).
722 replace(/\{NEWNAMEID}/g, 'newname-'+client_id).
723 replace(/\{LINKEXTID}/g, 'linkexternal-'+client_id).
724 replace(/\{AUTHORID}/g, 'text-author-'+client_id).
725 replace(/\{LICENSEID}/g, 'select-license-'+client_id).
726 replace(/\{BUTCONFIRMID}/g, 'fp-confirm-'+client_id).
727 replace(/\{BUTCANCELID}/g, 'fp-cancel-'+client_id)
728 );
729 Y.one(document.body).appendChild(this.fpnode);
730 this.fpnode.appendChild(fpselectnode);
731 this.mainui = new Y.Panel({
732 srcNode : this.fpnode,
733 headerContent: M.str.repository.filepicker,
734 zIndex : 500000,
735 centered : true,
736 modal : true,
737 visible : false,
738 render : true,
739 plugins : [Y.Plugin.Drag]
99eaca9d 740 });
b5e7b638
MG
741 this.mainui.show();
742 this.selectui = new Y.Panel({
743 srcNode : fpselectnode,
744 zIndex : 600000,
745 centered : true,
746 modal : true,
747 close : true,
748 render : true
99eaca9d 749 });
b5e7b638
MG
750 this.selectui.hide();
751 // save template for one path element and location of path bar
752 if (this.fpnode.one('.fp-path-folder')) {
753 this.pathnode = this.fpnode.one('.fp-path-folder');
754 this.pathbar = this.pathnode.get('parentNode');
755 this.pathbar.removeChild(this.pathnode);
756 }
757 // assign callbacks for view mode switch buttons
758 this.fpnode.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').
759 on('click', this.viewbar_clicked, this);
760 // assign callbacks for toolbar links
761 this.setup_toolbar();
762 this.setup_select_file();
934291d6 763
99eaca9d 764 // processing repository listing
b5e7b638
MG
765 // Resort the repositories by sortorder
766 var sorted_repositories = []
767 for (var i in this.options.repositories) {
768 sorted_repositories[i] = this.options.repositories[i]
769 }
770 sorted_repositories.sort(function(a,b){return a.sortorder-b.sortorder})
771 // extract one repository template and repeat it for all repositories available,
772 // set name and icon and assign callbacks
773 var reponode = this.fpnode.one('.fp-repo');
774 if (reponode) {
775 var list = reponode.get('parentNode');
776 list.removeChild(reponode);
777 for (i in sorted_repositories) {
778 var repository = sorted_repositories[i]
779 var node = reponode.cloneNode(true);
780 list.appendChild(node);
781 node.
782 set('id', 'fp-repo-'+client_id+'-'+repository.id).
783 on('click', function(e, repository_id) {
784 e.preventDefault();
785 Y.Cookie.set('recentrepository', repository_id);
786 this.hide_header();
787 this.list({'repo_id':repository_id});
788 }, this /*handler running scope*/, repository.id/*second argument of handler*/);
789 node.one('.fp-repo-name').setContent(repository.name)
790 node.one('.fp-repo-icon').set('src', repository.icon)
791 if (i==0) {node.addClass('first');}
792 if (i==sorted_repositories.length-1) {node.addClass('last');}
793 if (i%2) {node.addClass('even');} else {node.addClass('odd');}
99eaca9d 794 }
b5e7b638
MG
795 }
796 // display error if no repositories found
797 if (sorted_repositories.length==0) {
798 if (this.options.externallink) {
799 list.set('innerHTML', M.str.repository.norepositoriesexternalavailable); // TODO as error
800 } else {
801 list.set('innerHTML', M.str.repository.norepositoriesavailable); // TODO as error
f00340e2 802 }
b5e7b638
MG
803 }
804 // display repository that was used last time
805 this.show_recent_repository();
99eaca9d
DC
806 },
807 parse_repository_options: function(data) {
808 this.filelist = data.list?data.list:null;
809 this.filepath = data.path?data.path:null;
810 this.active_repo = {};
4adecd7b 811 this.active_repo.issearchresult = data.issearchresult?true:false;
98b15580 812 this.active_repo.dynload = data.dynload?data.dynload:false;
99eaca9d
DC
813 this.active_repo.pages = Number(data.pages?data.pages:null);
814 this.active_repo.page = Number(data.page?data.page:null);
815 this.active_repo.id = data.repo_id?data.repo_id:null;
b5e7b638
MG
816 this.active_repo.nosearch = (data.login || data.nosearch); // this is either login form or 'nosearch' attribute set
817 this.active_repo.norefresh = (data.login || data.norefresh); // this is either login form or 'norefresh' attribute set
818 this.active_repo.nologin = (data.login || data.nologin); // this is either login form or 'nologin' attribute is set
fdfb9cbe 819 this.active_repo.logouttext = data.logouttext?data.logouttext:null;
99eaca9d
DC
820 this.active_repo.help = data.help?data.help:null;
821 this.active_repo.manage = data.manage?data.manage:null;
b5e7b638 822 this.print_header();
99eaca9d
DC
823 },
824 print_login: function(data) {
b5e7b638 825 // TODO !!!!
97b151ea 826 this.parse_repository_options(data);
99eaca9d
DC
827 var client_id = this.options.client_id;
828 var repository_id = data.repo_id;
829 var l = this.logindata = data.login;
830 var loginurl = '';
b5e7b638 831 var panel = this.fpnode.one('.fp-content');
99eaca9d
DC
832 var action = 'login';
833 if (data['login_btn_action']) {
834 action=data['login_btn_action'];
835 }
836 var form_id = 'fp-form-'+client_id;
837 var download_button_id = 'fp-form-download-button-'+client_id;
838 var search_button_id = 'fp-form-search-button-'+client_id;
839 var login_button_id = 'fp-form-login-button-'+client_id;
840 var popup_button_id = 'fp-form-popup-button-'+client_id;
841
842 var str = '<div class="fp-login-form">';
843 str += '<form id="'+form_id+'">';
844 var has_pop = false;
845 str +='<table width="100%">';
846 for(var k in l) {
847 str +='<tr>';
848 if(l[k].type=='popup') {
849 // pop element
850 loginurl = l[k].url;
2b728cb5
PS
851 str += '<td colspan="2"><p class="fp-popup">'+M.str.repository.popup+'</p>';
852 str += '<p class="fp-popup"><button id="'+popup_button_id+'">'+M.str.repository.login+'</button>';
99eaca9d
DC
853 str += '</p></td>';
854 action = 'popup';
855 }else if(l[k].type=='textarea') {
856 // textarea element
857 str += '<td colspan="2"><p><textarea id="'+l[k].id+'" name="'+l[k].name+'"></textarea></p></td>';
858 }else if(l[k].type=='select') {
859 // select element
860 str += '<td align="right"><label>'+l[k].label+':</label></td>';
861 str += '<td align="left"><select id="'+l[k].id+'" name="'+l[k].name+'">';
862 for (i in l[k].options) {
863 str += '<option value="'+l[k].options[i].value+'">'+l[k].options[i].label+'</option>';
864 }
865 str += '</select></td>';
866 }else{
867 // input element
868 var label_id = '';
869 var field_id = '';
870 var field_value = '';
871 if(l[k].id) {
872 label_id = ' for="'+l[k].id+'"';
873 field_id = ' id="'+l[k].id+'"';
874 }
875 if (l[k].label) {
876 str += '<td align="right" width="30%" valign="center">';
877 str += '<label'+label_id+'>'+l[k].label+'</label> </td>';
878 } else {
879 str += '<td width="30%"></td>';
880 }
881 if(l[k].value) {
882 field_value = ' value="'+l[k].value+'"';
883 }
884 if(l[k].type=='radio'){
885 var list = l[k].value.split('|');
886 var labels = l[k].value_label.split('|');
887 str += '<td align="left">';
888 for(var item in list) {
889 str +='<input type="'+l[k].type+'"'+' name="'+l[k].name+'"'+
890 field_id+' value="'+list[item]+'" />'+labels[item]+'<br />';
891 }
892 str += '</td>';
893 }else{
894 str += '<td align="left">';
895 str += '<input type="'+l[k].type+'"'+' name="'+l[k].name+'"'+field_value+' '+field_id+' />';
896 str += '</td>';
897 }
898 }
899 str +='</tr>';
900 }
901 str +='</table>';
902 str += '</form>';
903
904 // custom lable text
2b728cb5 905 var btn_label = data['login_btn_label']?data['login_btn_label']:M.str.repository.submit;
99eaca9d
DC
906 if (action != 'popup') {
907 str += '<p><input type="button" id="';
908 switch (action) {
909 case 'search':
910 str += search_button_id;
911 break;
912 case 'download':
913 str += download_button_id;
914 break;
915 default:
916 str += login_button_id;
917 break;
918 }
919 str += '" value="'+btn_label+'" /></p>';
920 }
921
922 str += '</div>';
923
924 // insert login form
925 try {
926 panel.set('innerHTML', str);
927 } catch(e) {
a6b53a7c 928 alert(M.str.repository.xhtmlerror);
99eaca9d
DC
929 }
930 // register buttons
931 // process login action
932 var login_button = Y.one('#'+login_button_id);
933 var scope = this;
934 if (login_button) {
935 login_button.on('click', function(){
936 // collect form data
937 var data = this.logindata;
938 var scope = this;
939 var params = {};
940 for (var k in data) {
941 if(data[k].type!='popup') {
942 var el = Y.one('[name='+data[k].name+']');
943 var type = el.get('type');
944 params[data[k].name] = '';
945 if(type == 'checkbox') {
946 params[data[k].name] = el.get('checked');
947 } else {
948 params[data[k].name] = el.get('value');
949 }
950 }
951 }
952 // start ajax request
b5e7b638 953 this.hide_header();
99eaca9d
DC
954 this.request({
955 'params': params,
956 'scope': scope,
957 'action':'signin',
958 'path': '',
959 'client_id': client_id,
960 'repository_id': repository_id,
4adecd7b 961 'callback': this.display_response
99eaca9d
DC
962 }, true);
963 }, this);
964 }
965 var search_button = Y.one('#'+search_button_id);
966 if (search_button) {
967 search_button.on('click', function(){
968 var data = this.logindata;
969 var params = {};
970
971 for (var k in data) {
972 if(data[k].type!='popup') {
973 var el = document.getElementsByName(data[k].name)[0];
974 params[data[k].name] = '';
975 if(el.type == 'checkbox') {
976 params[data[k].name] = el.checked;
977 } else if(el.type == 'radio') {
978 var tmp = document.getElementsByName(data[k].name);
979 for(var i in tmp) {
980 if (tmp[i].checked) {
981 params[data[k].name] = tmp[i].value;
982 }
983 }
984 } else {
985 params[data[k].name] = el.value;
986 }
987 }
988 }
b5e7b638 989 this.hide_header();
99eaca9d
DC
990 this.request({
991 scope: scope,
992 action:'search',
993 client_id: client_id,
994 repository_id: repository_id,
995 form: {id: 'fp-form-'+scope.options.client_id,upload:false,useDisabled:true},
4adecd7b 996 callback: scope.display_response
99eaca9d
DC
997 }, true);
998 }, this);
999 }
1000 var download_button = Y.one('#'+download_button_id);
1001 if (download_button) {
1002 download_button.on('click', function(){
1003 alert('download');
1004 });
1005 }
1006 var popup_button = Y.one('#'+popup_button_id);
1007 if (popup_button) {
539d4041
DC
1008 popup_button.on('click', function(e){
1009 M.core_filepicker.active_filepicker = this;
5ba5e378 1010 window.open(loginurl, 'repo_auth', 'location=0,status=0,width=500,height=300,scrollbars=yes');
8cbef19e 1011 e.preventDefault();
99eaca9d
DC
1012 }, this);
1013 }
e0b85db4
DC
1014 var elform = Y.one('#'+form_id);
1015 elform.on('keydown', function(e) {
1016 if (e.keyCode == 13) {
1017 switch (action) {
1018 case 'search':
1019 search_button.simulate('click');
1020 break;
1021 default:
1022 login_button.simulate('click');
1023 break;
1024 }
8cbef19e 1025 e.preventDefault();
e0b85db4
DC
1026 }
1027 }, this);
99eaca9d
DC
1028
1029 },
4adecd7b
MG
1030 display_response: function(id, obj, args) {
1031 var scope = args.scope
1032 // highlight the current repository in repositories list
b5e7b638
MG
1033 scope.fpnode.all('.fp-repo.active').removeClass('active');
1034 scope.fpnode.all('#fp-repo-'+scope.options.client_id+'-'+obj.repo_id).addClass('active')
4adecd7b
MG
1035 // display response
1036 if (obj.login) {
b5e7b638 1037 scope.viewbar_set_enabled(false);
4adecd7b
MG
1038 scope.print_login(obj);
1039 } else if (obj.upload) {
b5e7b638 1040 scope.viewbar_set_enabled(false);
4adecd7b
MG
1041 scope.parse_repository_options(obj);
1042 scope.create_upload_form(obj);
1043 } else if (obj.iframe) {
99eaca9d 1044
4adecd7b 1045 } else if (obj.list) {
b5e7b638 1046 scope.viewbar_set_enabled(true);
4adecd7b
MG
1047 scope.parse_repository_options(obj);
1048 scope.view_files();
99eaca9d 1049 }
99eaca9d
DC
1050 },
1051 list: function(args) {
99eaca9d
DC
1052 if (!args) {
1053 args = {};
1054 }
1055 if (!args.repo_id) {
4adecd7b 1056 args.repo_id = this.active_repo.id;
99eaca9d 1057 }
4adecd7b
MG
1058 this.request({
1059 action: 'list',
1060 client_id: this.options.client_id,
99eaca9d 1061 repository_id: args.repo_id,
4adecd7b
MG
1062 path: args.path,
1063 page: args.page,
1064 scope: this,
1065 callback: this.display_response
99eaca9d
DC
1066 }, true);
1067 },
b5e7b638
MG
1068 populate_licenses_select: function(node) {
1069 if (!node) {
1070 return;
e35194be 1071 }
b5e7b638 1072 node.setContent('');
1dce6261 1073 var licenses = this.options.licenses;
b5e7b638 1074 var recentlicense = Y.Cookie.get('recentlicense');
a756cb37
DC
1075 if (recentlicense) {
1076 this.options.defaultlicense=recentlicense;
1077 }
1dce6261 1078 for (var i in licenses) {
b5e7b638
MG
1079 var option = Y.Node.create('<option/>').
1080 set('selected', (this.options.defaultlicense==licenses[i].shortname)).
1081 set('value', licenses[i].shortname).
1082 setContent(licenses[i].fullname);
1083 node.appendChild(option)
1dce6261 1084 }
b5e7b638
MG
1085 },
1086 create_upload_form: function(data) {
1087 var client_id = this.options.client_id;
1088 var id = data.upload.id+'_'+client_id;
1089 var str = M.core_filepicker.templates.uploadform.
1090 replace(/\{UPLOADFORMID}/g, id).
1091 replace(/\{INPUTFILEID}/g, id+'_file').
1092 replace(/\{NEWNAMEID}/g, 'newname-'+client_id).
1093 replace(/\{AUTHORID}/g, 'author-'+client_id).
1094 replace(/\{LICENSEID}/g, 'license-'+client_id).
1095 replace(/\{BUTUPLOADID}/g, id+'_action');
1096 this.fpnode.one('.fp-content').setContent(str);
1097
1098 Y.all('#'+id+'_file').set('name', 'repo_upload_file');
1099 Y.all('#'+'newname-'+client_id).set('name', 'title');
1100 Y.all('#'+'author-'+client_id).set('name', 'author');
1101 Y.all('#'+'author-'+client_id).set('value', this.options.author);
1102 Y.all('#'+'license-'+client_id).set('name', 'license');
1103 this.populate_licenses_select(Y.one('#'+'license-'+client_id))
1104 Y.one('#'+id).append('<input type="hidden" name="itemid" value="'+this.options.itemid+'" />'); // TODO nicer!
1105 var types = this.options.accepted_types;
1106 for (var i in types) {
1107 Y.one('#'+id).append('<input type="hidden" name="accepted_types[]" value="'+types[i]+'" />'); // TODO nicer!
1108 }
1109
99eaca9d 1110 var scope = this;
46325d3e 1111 Y.one('#'+id+'_action').on('click', function(e) {
8cbef19e 1112 e.preventDefault();
b5e7b638
MG
1113 var license = Y.one('#license-'+client_id);
1114 Y.Cookie.set('recentlicense', license.get('value'));
2a03b97b 1115 if (!Y.one('#'+id+'_file').get('value')) {
ce6297d2 1116 scope.print_msg(M.str.repository.nofilesattached, 'error');
2a03b97b
DC
1117 return false;
1118 }
b5e7b638 1119 this.hide_header();
9d753c38
PS
1120 scope.request({
1121 scope: scope,
1122 action:'upload',
1123 client_id: client_id,
1124 params: {'savepath':scope.options.savepath},
1125 repository_id: scope.active_repo.id,
1126 form: {id: id, upload:true},
a5159b86
MG
1127 onerror: function(id, o, args) {
1128 scope.create_upload_form(data);
1129 },
9d753c38
PS
1130 callback: function(id, o, args) {
1131 if (scope.options.editor_target&&scope.options.env=='editor') {
1132 scope.options.editor_target.value=o.url;
1133 scope.options.editor_target.onchange();
0c4edaa2 1134 }
9d753c38
PS
1135 scope.hide();
1136 o.client_id = client_id;
1137 var formcallback_scope = null;
1138 if (args.scope.options.magicscope) {
1139 formcallback_scope = args.scope.options.magicscope;
1140 } else {
1141 formcallback_scope = args.scope;
1142 }
1143 scope.options.formcallback.apply(formcallback_scope, [o]);
1144 }
1145 }, true);
99eaca9d
DC
1146 }, this);
1147 },
b5e7b638
MG
1148 /** setting handlers and labels for elements in toolbar. Called once during the initial render of filepicker */
1149 setup_toolbar: function() {
99eaca9d 1150 var client_id = this.options.client_id;
b5e7b638
MG
1151 Y.one('#fp-tb-logout-'+client_id).on('click', function(e) {
1152 e.preventDefault();
1153 if (!this.active_repo.nologin) {
1154 this.hide_header();
1155 this.request({
1156 action:'logout',
1157 client_id: this.options.client_id,
1158 repository_id: this.active_repo.id,
1159 path:'',
1160 callback: this.display_response
1161 }, true);
1162 }
1163 }, this);
1164 Y.one('#fp-tb-refresh-'+client_id).on('click', function(e) {
1165 e.preventDefault();
1166 if (!this.active_repo.norefresh) {
1167 this.list();
1168 }
1169 }, this);
1170 Y.one('#fp-tb-search-'+client_id).
1171 set('method', 'POST').
1172 on('submit', function(e) {
4adecd7b 1173 e.preventDefault();
b5e7b638
MG
1174 if (!this.active_repo.nosearch) {
1175 this.request({
1176 scope: this,
1177 action:'search',
1178 client_id: this.options.client_id,
1179 repository_id: this.active_repo.id,
1180 form: {id: 'fp-tb-search-'+client_id, upload:false, useDisabled:true},
1181 callback: this.display_response
1182 }, true);
1183 }
1184 }, this);
99eaca9d 1185
b5e7b638
MG
1186 // it does not matter what kind of element is {TOOLMANAGEID}, we create a dummy <a>
1187 // element and use it to open url on click event
1188 var managelnk = Y.Node.create('<a/>');
1189 managelnk.set('id', 'fp-tb-manage-'+client_id+'-link').set('target', '_blank').setStyle('display', 'none');
1190 Y.one('#fp-tb-'+client_id).append(managelnk);
1191 Y.one('#fp-tb-manage-'+client_id).on('click', function(e) {
1192 e.preventDefault();
1193 managelnk.simulate('click')
1194 });
99eaca9d 1195
b5e7b638
MG
1196 // same with {TOOLHELPID}
1197 var helplnk = Y.Node.create('<a/>');
1198 helplnk.set('id', 'fp-tb-help-'+client_id+'-link').set('target', '_blank').setStyle('display', 'none');
1199 Y.one('#fp-tb-'+client_id).append(helplnk);
1200 Y.one('#fp-tb-help-'+client_id).on('click', function(e) {
1201 e.preventDefault();
1202 helplnk.simulate('click')
1203 });
1204 },
1205 hide_header: function() {
1206 var client_id = this.options.client_id;
1207 if (Y.one('#fp-tb-'+client_id)) {
1208 Y.one('#fp-tb-'+client_id).addClass('empty');
1209 }
1210 },
1211 print_header: function() {
1212 var r = this.active_repo;
1213 var scope = this;
1214 var client_id = this.options.client_id;
1215 this.print_paging();
99eaca9d 1216
b5e7b638
MG
1217 this.hide_header();
1218 var enable_tb_control = function(elementid, enabled) {
1219 if (!enabled) {
1220 Y.all('#'+elementid+',#wrap-'+elementid).addClass('disabled').removeClass('enabled')
1221 } else {
1222 Y.all('#'+elementid+',#wrap-'+elementid).removeClass('disabled').addClass('enabled')
1223 Y.one('#fp-tb-'+client_id).removeClass('empty');
1224 }
1225 }
99eaca9d 1226
b5e7b638
MG
1227 // TODO 'back' permanently disabled for now. Note, flickr_public uses 'Logout' for it!
1228 enable_tb_control('fp-tb-back-'+client_id, false);
99eaca9d 1229
b5e7b638
MG
1230 // search form
1231 enable_tb_control('fp-tb-search-'+client_id, !r.nosearch);
1232 if(!r.nosearch) {
1233 Y.all('#fp-tb-search-'+client_id).setContent('');
1234 this.request({
1235 scope: this,
1236 action:'searchform',
1237 repository_id: this.active_repo.id,
1238 callback: function(id, obj, args) {
1239 if (obj.repo_id == scope.active_repo.id && obj.form) {
1240 // if we did not jump to another repository meanwhile
1241 Y.all('#fp-tb-search-'+scope.options.client_id).setContent(obj.form);
99eaca9d 1242 }
b5e7b638
MG
1243 }
1244 }, false);
99eaca9d 1245 }
b5e7b638
MG
1246
1247 // refresh button
99eaca9d 1248 // weather we use cache for this instance, this button will reload listing anyway
b5e7b638
MG
1249 enable_tb_control('fp-tb-refresh-'+client_id, !r.norefresh);
1250
1251 // login button
1252 enable_tb_control('fp-tb-logout-'+client_id, !r.nologin);
99eaca9d 1253 if(!r.nologin) {
fdfb9cbe 1254 var label = r.logouttext?r.logouttext:M.str.repository.logout;
b5e7b638 1255 Y.one('#fp-tb-logout-'+client_id).setContent(label)
99eaca9d
DC
1256 }
1257
b5e7b638
MG
1258 // manage url
1259 enable_tb_control('fp-tb-manage-'+client_id, r.manage);
1260 Y.one('#fp-tb-manage-'+client_id+'-link').set('href', r.manage);
1261
1262 // help url
1263 enable_tb_control('fp-tb-help-'+client_id, r.help);
1264 Y.one('#fp-tb-help-'+client_id+'-link').set('href', r.help);
99eaca9d 1265
ea44dd2e 1266 this.print_path();
99eaca9d
DC
1267 },
1268 get_page_button: function(page) {
1269 var r = this.active_repo;
1270 var css = '';
1271 if (page == r.page) {
1272 css = 'class="cur_page" ';
1273 }
1274 var str = '<a '+css+'href="###" id="repo-page-'+page+'">';
1275 return str;
1276 },
1277 print_paging: function(html_id) {
b5e7b638 1278 // TODO !!!
99eaca9d
DC
1279 var client_id = this.options.client_id;
1280 var scope = this;
1281 var r = this.active_repo;
1282 var str = '';
1283 var action = '';
8ebbe295
EL
1284 var lastpage = r.pages;
1285 var lastpagetext = r.pages;
20ee5084 1286 if (r.pages == -1) {
8ebbe295
EL
1287 lastpage = r.page + 1;
1288 lastpagetext = M.str.moodle.next;
20ee5084 1289 }
8ebbe295 1290 if (lastpage > 1) {
99eaca9d
DC
1291 str += this.get_page_button(1)+'1</a> ';
1292
1293 var span = 5;
1294 var ex = (span-1)/2;
1295
20ee5084
MG
1296 if (r.page+ex>=lastpage) {
1297 var max = lastpage;
99eaca9d
DC
1298 } else {
1299 if (r.page<span) {
1300 var max = span;
1301 } else {
1302 var max = r.page+ex;
1303 }
1304 }
1305
1306 // won't display upper boundary
1307 if (r.page >= span) {
1308 str += ' ... ';
1309 for(var i=r.page-ex; i<max; i++) {
1310 str += this.get_page_button(i);
1311 str += String(i);
1312 str += '</a> ';
1313 }
1314 } else {
1315 // this very first elements
1316 for(var i = 2; i < max; i++) {
1317 str += this.get_page_button(i);
1318 str += String(i);
1319 str += '</a> ';
1320 }
1321 }
1322
1323 // won't display upper boundary
20ee5084
MG
1324 if (max==lastpage) {
1325 str += this.get_page_button(lastpage)+lastpagetext+'</a>';
99eaca9d
DC
1326 } else {
1327 str += this.get_page_button(max)+max+'</a>';
20ee5084 1328 str += ' ... '+this.get_page_button(lastpage)+lastpagetext+'</a>';
99eaca9d 1329 }
99eaca9d 1330 }
b5e7b638
MG
1331 this.fpnode.one('.fp-paging').setContent(str);
1332 this.fpnode.all('.fp-paging a').on('click', function(e) {
4adecd7b 1333 e.preventDefault();
b5e7b638 1334 var id = e.currentTarget.get('id');
99eaca9d
DC
1335 var re = new RegExp("repo-page-(\\d+)", "i");
1336 var result = id.match(re);
1337 var args = {};
1338 args.page = result[1];
1339 if (scope.active_repo.issearchresult) {
1340 scope.request({
1341 scope: scope,
1342 action:'search',
1343 client_id: client_id,
1344 repository_id: r.id,
1345 params: {'page':result[1]},
4adecd7b 1346 callback: scope.display_response
99eaca9d
DC
1347 }, true);
1348
1349 } else {
4adecd7b 1350 scope.list(args);
99eaca9d
DC
1351 }
1352 });
99eaca9d
DC
1353 },
1354 print_path: function() {
b5e7b638
MG
1355 if (!this.pathbar) { return; }
1356 this.pathbar.setContent('');
99eaca9d 1357 var p = this.filepath;
4c508047 1358 if (p && p.length!=0) {
99eaca9d 1359 for(var i = 0; i < p.length; i++) {
b5e7b638
MG
1360 var el = this.pathnode.cloneNode(true);
1361 this.pathbar.appendChild(el);
1362 if (i == 0) {el.addClass('first');}
1363 if (i == p.length-1) {el.addClass('last');}
1364 if (i%2) {el.addClass('even');} else {el.addClass('odd');}
1365 el.all('.fp-path-folder-name').setContent(p[i].name);
1366 el.on('click',
1367 function(e, path) {
1368 e.preventDefault();
1369 this.list({'path':path});
1370 },
1371 this, p[i].path);
99eaca9d 1372 }
b5e7b638
MG
1373 this.pathbar.removeClass('empty');
1374 } else {
1375 this.pathbar.addClass('empty');
99eaca9d
DC
1376 }
1377 },
1378 hide: function() {
b5e7b638
MG
1379 this.selectui.hide();
1380 if (this.process_dlg) {
1381 this.process_dlg.hide();
1382 }
1383 if (this.msg_dlg) {
1384 this.msg_dlg.hide();
1385 }
99eaca9d
DC
1386 this.mainui.hide();
1387 },
1388 show: function() {
b5e7b638
MG
1389 if (this.fpnode) {
1390 this.hide();
99eaca9d 1391 this.mainui.show();
a756cb37 1392 this.show_recent_repository();
99eaca9d
DC
1393 } else {
1394 this.launch();
1395 }
1396 },
1397 launch: function() {
7b42e81a 1398 this.render();
a756cb37
DC
1399 },
1400 show_recent_repository: function() {
b5e7b638
MG
1401 this.hide_header();
1402 this.viewbar_set_enabled(false);
1403 var repository_id = Y.Cookie.get('recentrepository');
1404 this.viewmode = Y.Cookie.get('recentviewmode', Number);
1405 if (this.viewmode != 1 && this.viewmode != 2 && this.viewmode != 3) {
1406 this.viewmode = 1;
1407 }
a756cb37
DC
1408 if (this.options.repositories[repository_id]) {
1409 this.list({'repo_id':repository_id});
1410 }
99eaca9d
DC
1411 }
1412 });
bb496de7
DC
1413 var loading = Y.one('#filepicker-loading-'+options.client_id);
1414 if (loading) {
1415 loading.setStyle('display', 'none');
1416 }
4c508047
PS
1417 M.core_filepicker.instances[options.client_id] = new FilePickerHelper(options);
1418};