MDL-31901: filemanger: fixed bug with switching to treeview in empty folder
[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
e709ddd2
MG
45YUI.add('moodle-core_filepicker', function(Y) {
46 /** help function to extract width/height style as a number, not as a string */
47 Y.Node.prototype.getStylePx = function(attr) {
48 var style = this.getStyle(attr);
49 if (''+style == '0' || ''+style == '0px') {
50 return 0;
51 }
52 var matches = style.match(/^([\d\.]+)px$/)
53 if (matches && parseFloat(matches[1])) {
54 return parseFloat(matches[1]);
55 }
56 return null;
57 }
58
59 /** if condition is met, the class is added to the node, otherwise - removed */
60 Y.Node.prototype.addClassIf = function(className, condition) {
61 if (condition) {
62 this.addClass(className);
63 } else {
64 this.removeClass(className);
65 }
66 return this;
67 }
68
69 /** sets the width(height) of the node considering existing minWidth(minHeight) */
70 Y.Node.prototype.setStyleAdv = function(stylename, value) {
71 var stylenameCap = stylename.substr(0,1).toUpperCase() + stylename.substr(1, stylename.length-1).toLowerCase();
72 this.setStyle(stylename, '' + Math.max(value, this.getStylePx('min'+stylenameCap)) + 'px')
73 return this;
74 }
75
76 /**
77 * Displays a list of files (used by filepicker, filemanager) inside the Node
78 *
79 * @param array options
80 * viewmode : 1 - icons, 2 - tree, 3 - table
81 * appendonly : whether fileslist need to be appended instead of replacing the existing content
82 * filenode : Node element that contains template for displaying one file
83 * callback : On click callback. The element of the fileslist array will be passed as argument
84 * rightclickcallback : On right click callback (optional).
85 * callbackcontext : context where callbacks are executed
86 * sortable : whether content may be sortable (in table mode)
87 * dynload : allow dynamic load for tree view
88 * filepath : for pre-building of tree view - the path to the current directory in filepicker format
6c2367cc
MG
89 * treeview_dynload : callback to function to dynamically load the folder in tree view
90 * classnamecallback : callback to function that returns the class name for an element
e709ddd2
MG
91 * @param array fileslist array of files to show, each array element may have attributes:
92 * title or fullname : file name
93 * shorttitle (optional) : display file name
94 * thumbnail : url of image
95 * icon : url of icon image
96 * thumbnail_width : width of thumbnail, default 90
97 * thumbnail_height : height of thumbnail, default 90
98 * thumbnail_alt : TODO not needed!
99 * description or thumbnail_title : alt text
100 * @param array lazyloading : reference to the array with lazy loading images
101 */
102 Y.Node.prototype.fp_display_filelist = function(options, fileslist, lazyloading) {
103 var viewmodeclassnames = {1:'fp-iconview', 2:'fp-treeview', 3:'fp-tableview'};
104 var classname = viewmodeclassnames[options.viewmode];
105 var scope = this;
106 /** return whether file is a folder (different attributes in FileManager and FilePicker) */
107 var file_is_folder = function(node) {
108 if (node.children) {return true;}
109 if (node.type && node.type == 'folder') {return true;}
110 return false;
111 };
112 /** return the name of the file (different attributes in FileManager and FilePicker) */
113 var file_get_filename = function(node) {
114 return node.title ? node.title : node.fullname;
115 }
116 /** return display name of the file (different attributes in FileManager and FilePicker) */
117 var file_get_displayname = function(node) {
118 return node.shorttitle ? node.shorttitle : file_get_filename(node);
119 }
120 /** return file description (different attributes in FileManager and FilePicker) */
121 var file_get_description = function(node) {
122 return node.description ? node.description : (node.thumbnail_title ? node.thumbnail_title : file_get_filename(node));
123 }
124 /** help funciton for tree view */
125 var build_tree = function(node, level) {
126 // prepare file name with icon
127 var el = Y.Node.create('<div/>');
128 el.appendChild(options.filenode.cloneNode(true));
129
130 el.one('.fp-filename').setContent(file_get_displayname(node));
131 // TODO add tooltip with node.title or node.thumbnail_title
6c2367cc
MG
132 var tmpnodedata = {className:options.classnamecallback(node)};
133 el.get('children').addClass(tmpnodedata.className);
e709ddd2
MG
134 if (node.icon) {
135 el.one('.fp-icon').appendChild(Y.Node.create('<img/>').set('src', node.icon));
136 if (node.realicon) {
137 lazyloading[el.one('.fp-icon img').generateID()] = node.realicon;
138 }
139 }
140 // create node
23b83009
MG
141 tmpnodedata.html = el.getContent();
142 var tmpNode = new YAHOO.widget.HTMLNode(tmpnodedata, level, false);
e709ddd2
MG
143 if (node.dynamicLoadComplete) {
144 tmpNode.dynamicLoadComplete = true;
145 }
146 tmpNode.fileinfo = node;
147 tmpNode.isLeaf = !file_is_folder(node);
148 if (!tmpNode.isLeaf) {
149 if(node.expanded) {
150 tmpNode.expand();
151 }
152 tmpNode.path = node.path ? node.path : (node.filepath ? node.filepath : '');
153 for(var c in node.children) {
154 build_tree(node.children[c], tmpNode);
155 }
156 }
157 };
158 /** initialize tree view */
159 var initialize_tree_view = function() {
160 var parentid = scope.one('.'+classname).get('id');
23b83009 161 // TODO MDL-32736 use YUI3 gallery TreeView
e709ddd2
MG
162 scope.treeview = new YAHOO.widget.TreeView(parentid);
163 if (options.dynload) {
164 scope.treeview.setDynamicLoad(Y.bind(options.treeview_dynload, options.callbackcontext), 1);
165 }
166 scope.treeview.singleNodeHighlight = true;
167 if (options.filepath && options.filepath.length) {
168 // we just jumped from icon/details view, we need to show all parents
169 // we extract as much information as possible from filepath and filelist
170 // and send additional requests to retrieve siblings for parent folders
171 var mytree = {};
172 var mytreeel = null;
173 for (var i in options.filepath) {
174 if (mytreeel == null) {
175 mytreeel = mytree;
176 } else {
177 mytreeel.children = [{}];
178 mytreeel = mytreeel.children[0];
179 }
180 var pathelement = options.filepath[i];
181 mytreeel.path = pathelement.path;
182 mytreeel.title = pathelement.name;
183 mytreeel.dynamicLoadComplete = true; // we will call it manually
184 mytreeel.expanded = true;
185 }
186 mytreeel.children = fileslist;
187 build_tree(mytree, scope.treeview.getRoot());
188 // manually call dynload for parent elements in the tree so we can load other siblings
189 if (options.dynload) {
190 var root = scope.treeview.getRoot();
191 while (root && root.children && root.children.length) {
192 root = root.children[0];
193 if (root.path == mytreeel.path) {
194 root.origpath = options.filepath;
195 root.origlist = fileslist;
196 } else if (!root.isLeaf && root.expanded) {
197 Y.bind(options.treeview_dynload, options.callbackcontext)(root, null);
198 }
199 }
200 }
201 } else {
202 // there is no path information, just display all elements as a list, without hierarchy
203 for(k in fileslist) {
204 build_tree(fileslist[k], scope.treeview.getRoot());
205 }
206 }
207 scope.treeview.subscribe('clickEvent', function(e){
208 e.node.highlight(false);
23b83009
MG
209 var callback = options.callback;
210 if (options.rightclickcallback && e.event.target &&
211 Y.Node(e.event.target).ancestor('.fp-treeview .fp-contextmenu', true)) {
212 callback = options.rightclickcallback;
213 }
214 Y.bind(callback, options.callbackcontext)(e, e.node.fileinfo);
215 YAHOO.util.Event.stopEvent(e.event)
e709ddd2 216 });
23b83009
MG
217 // TODO MDL-32736 support right click
218 /*if (options.rightclickcallback) {
219 scope.treeview.subscribe('dblClickEvent', function(e){
e709ddd2 220 e.node.highlight(false);
23b83009 221 Y.bind(options.rightclickcallback, options.callbackcontext)(e, e.node.fileinfo);
e709ddd2 222 });
23b83009 223 }*/
e709ddd2
MG
224 scope.treeview.draw();
225 };
226 /** formatting function for table view */
227 var formatValue = function (o){
228 if (o.data[''+o.column.key+'_f_s']) {return o.data[''+o.column.key+'_f_s'];}
229 else if (o.data[''+o.column.key+'_f']) {return o.data[''+o.column.key+'_f'];}
230 else if (o.value) {return o.value;}
231 else {return '';}
232 };
233 /** formatting function for table view */
234 var formatTitle = function(o) {
235 var el = Y.Node.create('<div/>');
236 el.appendChild(options.filenode.cloneNode(true)); // TODO not node but string!
6c2367cc 237 el.get('children').addClass(o.data['classname']);
e709ddd2
MG
238 el.one('.fp-filename').setContent(o.value);
239 if (o.data['icon']) {
240 el.one('.fp-icon').appendChild(Y.Node.create('<img/>').set('src', o.data['icon']));
241 if (o.data['realicon']) {
242 lazyloading[el.one('.fp-icon img').generateID()] = o.data['realicon'];
243 }
244 }
23b83009
MG
245 if (options.rightclickcallback) {
246 el.get('children').addClass('fp-hascontextmenu');
247 }
e709ddd2
MG
248 // TODO add tooltip with o.data['title'] (o.value) or o.data['thumbnail_title']
249 return el.getContent();
250 }
251 /** sorting function for table view */
252 var sortFoldersFirst = function(a, b, desc) {
253 if (a.get('isfolder') && !b.get('isfolder')) {return -1;}
254 if (!a.get('isfolder') && b.get('isfolder')) {return 1;}
255 var aa = a.get(this.key), bb = b.get(this.key), dir = desc?-1:1;
256 return (aa > bb) ? dir : ((aa < bb) ? -dir : 0);
257 }
258 /** initialize table view */
259 var initialize_table_view = function() {
260 var parentid = scope.one('.'+classname).get('id');
261 var cols = [
262 {key: "displayname", label: M.str.moodle.name, allowHTML: true, formatter: formatTitle,
263 sortable: true, sortFn: sortFoldersFirst},
264 {key: "datemodified", label: M.str.moodle.lastmodified, allowHTML: true, formatter: formatValue,
265 sortable: true, sortFn: sortFoldersFirst},
266 {key: "size", label: M.str.repository.size, allowHTML: true, formatter: formatValue,
267 sortable: true, sortFn: sortFoldersFirst},
268 {key: "mimetype", label: M.str.repository.type, allowHTML: true,
269 sortable: true, sortFn: sortFoldersFirst}
270 ];
271 scope.tableview = new Y.DataTable({columns: cols});
272 scope.tableview.render('#'+parentid);
273 scope.tableview.delegate('click', function (e, tableview) {
274 var record = tableview.getRecord(e.currentTarget.get('id'));
23b83009
MG
275 if (record) {
276 var callback = options.callback;
277 if (options.rightclickcallback && e.target.ancestor('.fp-tableview .fp-contextmenu', true)) {
278 callback = options.rightclickcallback;
279 }
280 Y.bind(callback, this)(e, record.getAttrs());
281 }
e709ddd2
MG
282 }, 'tr', options.callbackcontext, scope.tableview);
283 if (options.rightclickcallback) {
284 scope.tableview.delegate('contextmenu', function (e, tableview) {
285 var record = tableview.getRecord(e.currentTarget.get('id'));
286 if (record) { Y.bind(options.rightclickcallback, this)(e, record.getAttrs()); }
287 }, 'tr', options.callbackcontext, scope.tableview);
288 }
289 }
290 /** append items in table view mode */
291 var append_files_table = function() {
292 for (var k in fileslist) {
293 // to speed up sorting and formatting
294 fileslist[k].displayname = file_get_displayname(fileslist[k]);
295 fileslist[k].isfolder = file_is_folder(fileslist[k]);
6c2367cc 296 fileslist[k].classname = options.classnamecallback(fileslist[k]);
e709ddd2
MG
297 }
298 scope.tableview.addRows(fileslist);
299 scope.tableview.sortable = options.sortable ? true : false;
300 };
301 /** append items in tree view mode */
302 var append_files_tree = function() {
303 if (options.appendonly) {
304 var parentnode = scope.treeview.getRoot();
305 if (scope.treeview.getHighlightedNode()) {
306 parentnode = scope.treeview.getHighlightedNode();
307 if (parentnode.isLeaf) {parentnode = parentnode.parent;}
308 }
309 for (var k in fileslist) {
310 build_tree(fileslist[k], parentnode);
311 }
312 scope.treeview.draw();
313 } else {
314 // otherwise files were already added in initialize_tree_view()
315 }
316 }
317 /** append items in icon view mode */
318 var append_files_icons = function() {
319 parent = scope.one('.'+classname);
320 for (var k in fileslist) {
321 var node = fileslist[k];
322 var element = options.filenode.cloneNode(true);
323 parent.appendChild(element);
6c2367cc 324 element.addClass(options.classnamecallback(node));
e709ddd2
MG
325 var filenamediv = element.one('.fp-filename');
326 filenamediv.setContent(file_get_displayname(node));
327 var imgdiv = element.one('.fp-thumbnail'), width, height, src;
328 if (node.thumbnail) {
329 width = node.thumbnail_width ? node.thumbnail_width : 90;
330 height = node.thumbnail_height ? node.thumbnail_height : 90;
331 src = node.thumbnail;
332 } else {
333 width = 16;
334 height = 16;
335 src = node.icon;
336 }
337 filenamediv.setStyleAdv('width', width);
338 imgdiv.setStyleAdv('width', width).setStyleAdv('height', height);
339 var img = Y.Node.create('<img/>').setAttrs({
340 src: src,
341 title: file_get_description(node),
342 alt: node.thumbnail_alt ? node.thumbnail_alt : file_get_filename(node)}).
343 setStyle('maxWidth', ''+width+'px').
344 setStyle('maxHeight', ''+height+'px');
345 if (node.realthumbnail) {
346 lazyloading[img.generateID()] = node.realthumbnail;
347 }
348 imgdiv.appendChild(img);
23b83009
MG
349 element.on('click', function(e, nd) {
350 if (options.rightclickcallback && e.target.ancestor('.fp-iconview .fp-contextmenu', true)) {
351 Y.bind(options.rightclickcallback, this)(e, nd);
352 } else {
353 Y.bind(options.callback, this)(e, nd);
354 }
355 }, options.callbackcontext, node);
e709ddd2
MG
356 if (options.rightclickcallback) {
357 element.on('contextmenu', options.rightclickcallback, options.callbackcontext, node);
358 }
359 }
360 }
361
362 // initialize files view
363 if (!options.appendonly) {
364 var parent = Y.Node.create('<div/>').addClass(classname);
365 this.setContent('').appendChild(parent);
366 parent.generateID();
367 if (options.viewmode == 2) {
368 initialize_tree_view();
369 } else if (options.viewmode == 3) {
370 initialize_table_view();
371 } else {
372 // nothing to initialize for icon view
373 }
374 }
375
376 // append files to the list
377 if (options.viewmode == 2) {
378 append_files_tree();
379 } else if (options.viewmode == 3) {
380 append_files_table();
381 } else {
382 append_files_icons();
383 }
384
385 }
386}, '@VERSION@', {
4325db53 387 requires:['base', 'node', 'yui2-treeview', 'panel', 'cookie', 'datatable', 'datatable-sort']
e709ddd2
MG
388});
389
4c508047 390M.core_filepicker = M.core_filepicker || {};
99eaca9d 391
4c508047
PS
392/**
393 * instances of file pickers used on page
394 */
395M.core_filepicker.instances = M.core_filepicker.instances || {};
539d4041 396M.core_filepicker.active_filepicker = null;
4c508047 397
b5e7b638
MG
398/**
399 * HTML Templates to use in FilePicker
400 */
401M.core_filepicker.templates = M.core_filepicker.templates || {};
402
4c508047
PS
403/**
404 * Init and show file picker
405 */
406M.core_filepicker.show = function(Y, options) {
407 if (!M.core_filepicker.instances[options.client_id]) {
8cbef19e 408 M.core_filepicker.init(Y, options);
99eaca9d 409 }
4c508047
PS
410 M.core_filepicker.instances[options.client_id].show();
411};
412
d1d18691
MG
413M.core_filepicker.set_templates = function(Y, templates) {
414 for (var templid in templates) {
415 M.core_filepicker.templates[templid] = templates[templid];
416 }
417}
b92241f2 418
4c508047
PS
419/**
420 * Add new file picker to current instances
421 */
422M.core_filepicker.init = function(Y, options) {
423 var FilePickerHelper = function(options) {
424 FilePickerHelper.superclass.constructor.apply(this, arguments);
8cbef19e 425 };
4c508047
PS
426
427 FilePickerHelper.NAME = "FilePickerHelper";
428 FilePickerHelper.ATTRS = {
99eaca9d
DC
429 options: {},
430 lang: {}
431 };
4c508047
PS
432
433 Y.extend(FilePickerHelper, Y.Base, {
9598d578 434 api: M.cfg.wwwroot+'/repository/repository_ajax.php',
7f9358fc 435 cached_responses: {},
4c508047
PS
436
437 initializer: function(options) {
438 this.options = options;
392d5fd4
DC
439 if (!this.options.savepath) {
440 this.options.savepath = '/';
441 }
99eaca9d 442 },
4c508047 443
99eaca9d
DC
444 destructor: function() {
445 },
4c508047 446
99eaca9d 447 request: function(args, redraw) {
3a1e425b 448 var api = (args.api?args.api:this.api) + '?action='+args.action;
99eaca9d 449 var params = {};
3a1e425b 450 var scope = args['scope']?args['scope']:this;
99eaca9d
DC
451 params['repo_id']=args.repository_id;
452 params['p'] = args.path?args.path:'';
453 params['page'] = args.page?args.page:'';
454 params['env']=this.options.env;
455 // the form element only accept certain file types
456 params['accepted_types']=this.options.accepted_types;
e35194be 457 params['sesskey'] = M.cfg.sesskey;
99eaca9d 458 params['client_id'] = args.client_id;
0c4edaa2 459 params['itemid'] = this.options.itemid?this.options.itemid:0;
8a3e6a56 460 params['maxbytes'] = this.options.maxbytes?this.options.maxbytes:-1;
be85f7ab
DC
461 if (this.options.context && this.options.context.id) {
462 params['ctx_id'] = this.options.context.id;
463 }
99eaca9d
DC
464 if (args['params']) {
465 for (i in args['params']) {
466 params[i] = args['params'][i];
467 }
468 }
64654e78
DC
469 if (args.action == 'upload') {
470 var list = [];
471 for(var k in params) {
472 var value = params[k];
473 if(value instanceof Array) {
474 for(var i in value) {
475 list.push(k+'[]='+value[i]);
476 }
477 } else {
478 list.push(k+'='+value);
479 }
480 }
481 params = list.join('&');
482 } else {
483 params = build_querystring(params);
484 }
99eaca9d
DC
485 var cfg = {
486 method: 'POST',
487 on: {
488 complete: function(id,o,p) {
489 if (!o) {
b5e7b638 490 // TODO
99eaca9d
DC
491 alert('IO FATAL');
492 return;
493 }
4c508047
PS
494 var data = null;
495 try {
496 data = Y.JSON.parse(o.responseText);
497 } catch(e) {
879b4f9a 498 scope.print_msg(M.str.repository.invalidjson, 'error');
b5e7b638 499 scope.display_error(M.str.repository.invalidjson+'<pre>'+stripHTML(o.responseText)+'</pre>', 'invalidjson')
c26855ff 500 return;
4c508047 501 }
1dce6261 502 // error checking
e35194be
DC
503 if (data && data.error) {
504 scope.print_msg(data.error, 'error');
a5159b86
MG
505 if (args.onerror) {
506 args.onerror(id,data,p);
507 } else {
3a1e425b 508 this.fpnode.one('.fp-content').setContent('');
a5159b86 509 }
1dce6261 510 return;
f392caba
DC
511 } else if (data && data.event) {
512 switch (data.event) {
513 case 'fileexists':
514 scope.process_existing_file(data);
515 break;
516 default:
517 break;
518 }
1dce6261 519 } else {
879b4f9a
DC
520 if (data.msg) {
521 scope.print_msg(data.msg, 'info');
522 }
7f9358fc
MG
523 // cache result if applicable
524 if (args.action != 'upload' && data.allowcaching) {
525 scope.cached_responses[params] = data;
526 }
527 // invoke callback
1dce6261
DC
528 args.callback(id,data,p);
529 }
99eaca9d
DC
530 }
531 },
532 arguments: {
533 scope: scope
534 },
535 headers: {
bd2db41a 536 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
99eaca9d 537 },
64654e78 538 data: params,
4c508047 539 context: this
99eaca9d
DC
540 };
541 if (args.form) {
542 cfg.form = args.form;
543 }
7f9358fc
MG
544 // check if result of the same request has been already cached. If not, request it
545 // (never applicable in case of form submission and/or upload action):
546 if (!args.form && args.action != 'upload' && scope.cached_responses[params]) {
547 args.callback(null, scope.cached_responses[params], {scope: scope})
548 } else {
549 Y.io(api, cfg);
550 if (redraw) {
b5e7b638 551 this.wait();
7f9358fc 552 }
99eaca9d
DC
553 }
554 },
b5e7b638 555 /** displays the dialog and processes rename/overwrite if there is a file with the same name in the same filearea*/
f392caba
DC
556 process_existing_file: function(data) {
557 var scope = this;
b5e7b638 558 var handleOverwrite = function(e) {
f392caba 559 // overwrite
b5e7b638
MG
560 e.preventDefault();
561 var data = this.process_dlg.dialogdata;
f392caba
DC
562 var params = {}
563 params['existingfilename'] = data.existingfile.filename;
564 params['existingfilepath'] = data.existingfile.filepath;
565 params['newfilename'] = data.newfile.filename;
566 params['newfilepath'] = data.newfile.filepath;
b5e7b638
MG
567 this.hide_header();
568 this.request({
f392caba 569 'params': params,
b5e7b638 570 'scope': this,
f392caba
DC
571 'action':'overwrite',
572 'path': '',
b5e7b638
MG
573 'client_id': this.options.client_id,
574 'repository_id': this.active_repo.id,
f392caba 575 'callback': function(id, o, args) {
f392caba
DC
576 scope.hide();
577 // editor needs to update url
578 // filemanager do nothing
c8ad2c12
SH
579 if (scope.options.editor_target && scope.options.env == 'editor') {
580 scope.options.editor_target.value = data.existingfile.url;
f392caba 581 scope.options.editor_target.onchange();
1ae299f5 582 } else if (scope.options.env === 'filepicker') {
b5e7b638 583 var fileinfo = {'client_id':scope.options.client_id,
913b3cb3
JP
584 'url':data.existingfile.url,
585 'file':data.existingfile.filename};
586 scope.options.formcallback.apply(scope, [fileinfo]);
f392caba
DC
587 }
588 }
589 }, true);
590 }
b5e7b638
MG
591 var handleRename = function(e) {
592 // inserts file with the new name
593 e.preventDefault();
594 var scope = this;
595 var data = this.process_dlg.dialogdata;
c8ad2c12
SH
596 if (scope.options.editor_target && scope.options.env == 'editor') {
597 scope.options.editor_target.value = data.newfile.url;
f392caba
DC
598 scope.options.editor_target.onchange();
599 }
f392caba 600 scope.hide();
f392caba
DC
601 var formcallback_scope = null;
602 if (scope.options.magicscope) {
603 formcallback_scope = scope.options.magicscope;
604 } else {
605 formcallback_scope = scope;
606 }
b5e7b638 607 var fileinfo = {'client_id':scope.options.client_id,
794cc7e1
JP
608 'url':data.newfile.url,
609 'file':data.newfile.filename};
610 scope.options.formcallback.apply(formcallback_scope, [fileinfo]);
f392caba 611 }
b5e7b638 612 var handleCancel = function(e) {
f392caba 613 // Delete tmp file
b5e7b638 614 e.preventDefault();
f392caba 615 var params = {};
b5e7b638
MG
616 params['newfilename'] = this.process_dlg.dialogdata.newfile.filename;
617 params['newfilepath'] = this.process_dlg.dialogdata.newfile.filepath;
618 this.request({
f392caba 619 'params': params,
b5e7b638 620 'scope': this,
f392caba
DC
621 'action':'deletetmpfile',
622 'path': '',
b5e7b638
MG
623 'client_id': this.options.client_id,
624 'repository_id': this.active_repo.id,
f392caba 625 'callback': function(id, o, args) {
b5e7b638 626 // let it be in background, from user point of view nothing is happenning
f392caba 627 }
b5e7b638
MG
628 }, false);
629 this.process_dlg.hide();
630 this.selectui.hide();
f392caba 631 }
b5e7b638
MG
632 if (!this.process_dlg) {
633 var node = Y.Node.create(M.core_filepicker.templates.processexistingfile);
634 this.fpnode.appendChild(node);
635 this.process_dlg = new Y.Panel({
636 srcNode : node,
637 headerContent: M.str.repository.fileexistsdialogheader,
638 zIndex : 800000,
639 centered : true,
640 modal : true,
641 visible : false,
642 render : true,
643 buttons : {}
644 });
645 node.one('.fp-dlg-butoverwrite').on('click', handleOverwrite, this);
646 node.one('.fp-dlg-butrename').on('click', handleRename, this);
647 node.one('.fp-dlg-butcancel').on('click', handleCancel, this);
648 if (this.options.env == 'editor') {
649 node.one('.fp-dlg-text').setContent(M.str.repository.fileexistsdialog_editor);
650 } else {
651 node.one('.fp-dlg-text').setContent(M.str.repository.fileexistsdialog_filemanager);
652 }
f392caba 653 }
3a1e425b 654 this.fpnode.one('.fp-select').removeClass('loading');
b5e7b638
MG
655 this.process_dlg.dialogdata = data;
656 this.fpnode.one('.fp-dlg .fp-dlg-butrename').setContent(M.util.get_string('renameto', 'repository', data.newfile.filename));
657 this.process_dlg.show();
658 },
659 /** displays error instead of filepicker contents */
660 display_error: function(errortext, errorcode) {
661 this.fpnode.one('.fp-content').setContent(M.core_filepicker.templates.error);
662 this.fpnode.one('.fp-content .fp-error').
663 addClass(errorcode).
664 setContent(errortext);
f392caba 665 },
b5e7b638 666 /** displays message in a popup */
879b4f9a 667 print_msg: function(msg, type) {
b5e7b638
MG
668 var header = M.str.moodle.error;
669 if (type != 'error') {
670 type = 'info'; // one of only two types excepted
671 header = M.str.moodle.info;
879b4f9a
DC
672 }
673 if (!this.msg_dlg) {
b5e7b638
MG
674 var node = Y.Node.create(M.core_filepicker.templates.message);
675 this.fpnode.appendChild(node);
676
677 this.msg_dlg = new Y.Panel({
678 srcNode : node,
679 zIndex : 800000,
680 centered : true,
681 modal : true,
682 visible : false,
683 render : true
684 });
685 node.one('.fp-msg-butok').on('click', function(e) {
686 e.preventDefault();
687 this.msg_dlg.hide();
688 }, this);
879b4f9a 689 }
b5e7b638
MG
690
691 this.msg_dlg.set('headerContent', header);
692 this.fpnode.one('.fp-msg').removeClass('fp-msg-info').removeClass('fp-msg-error').addClass('fp-msg-'+type)
693 this.fpnode.one('.fp-msg .fp-msg-text').setContent(msg);
879b4f9a 694 this.msg_dlg.show();
879b4f9a 695 },
7ccf18a6 696 view_files: function(appenditems) {
b92241f2
MG
697 this.viewbar_set_enabled(true);
698 this.print_path();
e709ddd2
MG
699 /*if ((appenditems == null) && (!this.filelist || !this.filelist.length) && !this.active_repo.hasmorepages) {
700 // TODO do it via classes and adjust for each view mode!
701 // If there are no items and no next page, just display status message and quit
702 this.display_error(M.str.repository.nofilesavailable, 'nofilesavailable');
703 return;
704 }*/
b92241f2 705 if (this.viewmode == 2) {
7ccf18a6 706 this.view_as_list(appenditems);
b92241f2 707 } else if (this.viewmode == 3) {
7ccf18a6 708 this.view_as_table(appenditems);
99eaca9d 709 } else {
7ccf18a6
MG
710 this.view_as_icons(appenditems);
711 }
712 // display/hide the link for requesting next page
713 if (!appenditems && this.active_repo.hasmorepages) {
714 if (!this.fpnode.one('.fp-content .fp-nextpage')) {
715 this.fpnode.one('.fp-content').append(M.core_filepicker.templates.nextpage);
716 }
717 this.fpnode.one('.fp-content .fp-nextpage').one('a,button').on('click', function(e) {
718 e.preventDefault();
719 this.fpnode.one('.fp-content .fp-nextpage').addClass('loading');
720 this.request_next_page();
721 }, this);
722 }
723 if (!this.active_repo.hasmorepages && this.fpnode.one('.fp-content .fp-nextpage')) {
724 this.fpnode.one('.fp-content .fp-nextpage').remove();
725 }
726 if (this.fpnode.one('.fp-content .fp-nextpage')) {
727 this.fpnode.one('.fp-content .fp-nextpage').removeClass('loading');
99eaca9d 728 }
ce3eeb98
MG
729 this.content_scrolled();
730 },
731 content_scrolled: function(e) {
732 setTimeout(Y.bind(function() {
733 if (this.processingimages) {return;}
734 this.processingimages = true;
735 var scope = this,
736 fpcontent = this.fpnode.one('.fp-content'),
737 fpcontenty = fpcontent.getY(),
738 fpcontentheight = fpcontent.getStylePx('height'),
739 nextpage = fpcontent.one('.fp-nextpage'),
740 is_node_visible = function(node) {
741 var offset = node.getY()-fpcontenty;
742 if (offset <= fpcontentheight && (offset >=0 || offset+node.getStylePx('height')>=0)) {
743 return true;
744 }
745 return false;
746 };
747 // automatically load next page when 'more' link becomes visible
748 if (nextpage && !nextpage.hasClass('loading') && is_node_visible(nextpage)) {
749 nextpage.one('a,button').simulate('click');
750 }
751 // replace src for visible images that need to be lazy-loaded
752 if (scope.lazyloading) {
753 fpcontent.all('img').each( function(node) {
754 if (node.get('id') && scope.lazyloading[node.get('id')] && is_node_visible(node)) {
755 node.set('src', scope.lazyloading[node.get('id')]);
756 delete scope.lazyloading[node.get('id')];
757 }
758 });
759 }
760 this.processingimages = false;
761 }, this), 200)
99eaca9d 762 },
1fb0173e 763 treeview_dynload: function(node, cb) {
2f6749f4
MG
764 var retrieved_children = {};
765 if (node.children) {
766 for (var i in node.children) {
767 retrieved_children[node.children[i].path] = node.children[i];
768 }
769 }
e709ddd2 770 this.request({
1fb0173e 771 action:'list',
e709ddd2
MG
772 client_id: this.options.client_id,
773 repository_id: this.active_repo.id,
1fb0173e
DC
774 path:node.path?node.path:'',
775 page:node.page?args.page:'',
e709ddd2 776 scope:this,
1fb0173e 777 callback: function(id, obj, args) {
1fb0173e 778 var list = obj.list;
e709ddd2 779 var scope = args.scope;
2f6749f4
MG
780 // check that user did not leave the view mode before recieving this response
781 if (!(scope.active_repo.id == obj.repo_id && scope.viewmode == 2 && node && node.getChildrenEl())) {
782 return;
783 }
784 if (cb != null) { // (in manual mode do not update current path)
785 scope.viewbar_set_enabled(true);
786 scope.parse_repository_options(obj);
787 }
e709ddd2 788 node.highlight(false);
2f6749f4
MG
789 node.origlist = obj.list?obj.list:null;
790 node.origpath = obj.path?obj.path:null;
791 node.children = [];
1fb0173e 792 for(k in list) {
2f6749f4
MG
793 if (list[k].children && retrieved_children[list[k].path]) {
794 // if this child is a folder and has already been retrieved
795 node.children[node.children.length] = retrieved_children[list[k].path];
796 } else {
e709ddd2
MG
797 // append new file to the list
798 scope.view_as_list([list[k]]);
2f6749f4
MG
799 }
800 }
801 if (cb == null) {
802 node.refresh();
803 } else {
e709ddd2 804 // invoke callback requested by TreeView component
2f6749f4 805 cb();
1fb0173e 806 }
ce3eeb98 807 scope.content_scrolled();
1fb0173e
DC
808 }
809 }, false);
810 },
7ccf18a6
MG
811 /** displays list of files in tree (list) view mode. If param appenditems is specified,
812 * appends those items to the end of the list. Otherwise (default behaviour)
813 * clears the contents and displays the items from this.filelist */
814 view_as_list: function(appenditems) {
e709ddd2
MG
815 var list = (appenditems != null) ? appenditems : this.filelist;
816 this.viewmode = 2;
817 if (!this.filelist || this.filelist.length==0 && (!this.filepath || !this.filepath.length)) {
b5e7b638 818 this.display_error(M.str.repository.nofilesavailable, 'nofilesavailable');
4adecd7b
MG
819 return;
820 }
879b4f9a 821
e709ddd2
MG
822 var element_template = Y.Node.create(M.core_filepicker.templates.listfilename);
823 var options = {
824 viewmode : this.viewmode,
825 appendonly : (appenditems != null),
826 filenode : element_template,
827 callbackcontext : this,
828 callback : function(e, node) {
23b83009 829 // TODO MDL-32736 e is not an event here but an object with properties 'event' and 'node'
e709ddd2
MG
830 if (!node.children) {
831 if (e.node.parent && e.node.parent.origpath) {
832 // set the current path
833 this.filepath = e.node.parent.origpath;
834 this.filelist = e.node.parent.origlist;
835 this.print_path();
2f6749f4 836 }
e709ddd2
MG
837 this.select_file(node);
838 } else {
839 // save current path and filelist (in case we want to jump to other viewmode)
840 this.filepath = e.node.origpath;
841 this.filelist = e.node.origlist;
842 this.print_path();
843 this.content_scrolled();
2f6749f4 844 }
e709ddd2 845 },
6c2367cc
MG
846 classnamecallback : function(node) {
847 return node.children ? 'fp-folder' : '';
848 },
e709ddd2
MG
849 dynload : this.active_repo.dynload,
850 filepath : this.filepath,
851 treeview_dynload : this.treeview_dynload
852 };
853 this.fpnode.one('.fp-content').fp_display_filelist(options, list, this.lazyloading);
99eaca9d 854 },
7ccf18a6
MG
855 /** displays list of files in icon view mode. If param appenditems is specified,
856 * appends those items to the end of the list. Otherwise (default behaviour)
857 * clears the contents and displays the items from this.filelist */
858 view_as_icons: function(appenditems) {
99eaca9d 859 this.viewmode = 1;
e709ddd2
MG
860 var list = (appenditems != null) ? appenditems : this.filelist;
861 var element_template = Y.Node.create(M.core_filepicker.templates.iconfilename);
862 if ((appenditems == null) && (!this.filelist || !this.filelist.length)) {
863 this.display_error(M.str.repository.nofilesavailable, 'nofilesavailable');
864 return;
879b4f9a 865 }
e709ddd2
MG
866 var options = {
867 viewmode : this.viewmode,
868 appendonly : (appenditems != null),
869 filenode : element_template,
870 callbackcontext : this,
871 callback : function(e, node) {
23b83009 872 if (e.preventDefault) {e.preventDefault();}
e709ddd2
MG
873 if(node.children) {
874 if (this.active_repo.dynload) {
875 this.list({'path':node.path});
876 } else {
877 this.filepath = node.path;
878 this.filelist = node.children;
99eaca9d
DC
879 this.view_files();
880 }
e709ddd2
MG
881 } else {
882 this.select_file(node);
883 }
6c2367cc
MG
884 },
885 classnamecallback : function(node) {
886 return node.children ? 'fp-folder' : '';
99eaca9d 887 }
e709ddd2
MG
888 };
889 this.fpnode.one('.fp-content').fp_display_filelist(options, list, this.lazyloading);
99eaca9d 890 },
7ccf18a6
MG
891 /** displays list of files in table view mode. If param appenditems is specified,
892 * appends those items to the end of the list. Otherwise (default behaviour)
893 * clears the contents and displays the items from this.filelist */
894 view_as_table: function(appenditems) {
5bdf63cc 895 this.viewmode = 3;
e709ddd2
MG
896 var list = (appenditems != null) ? appenditems : this.filelist;
897 if (!appenditems && (!this.filelist || this.filelist.length==0) && !this.active_repo.hasmorepages) {
5bdf63cc
MG
898 this.display_error(M.str.repository.nofilesavailable, 'nofilesavailable');
899 return;
900 }
e709ddd2
MG
901 var element_template = Y.Node.create(M.core_filepicker.templates.listfilename);
902 var options = {
903 viewmode : this.viewmode,
904 appendonly : (appenditems != null),
905 filenode : element_template,
906 callbackcontext : this,
907 sortable : !this.active_repo.hasmorepages,
908 callback : function(e, node) {
23b83009 909 if (e.preventDefault) {e.preventDefault();}
e709ddd2 910 if (node.children) {
7ccf18a6 911 if (this.active_repo.dynload) {
e709ddd2 912 this.list({'path':node.path});
7ccf18a6 913 } else {
e709ddd2
MG
914 this.filepath = node.path;
915 this.filelist = node.children;
7ccf18a6 916 this.view_files();
5bdf63cc 917 }
7ccf18a6 918 } else {
e709ddd2 919 this.select_file(node);
5bdf63cc 920 }
6c2367cc
MG
921 },
922 classnamecallback : function(node) {
923 return node.children ? 'fp-folder' : '';
7ccf18a6 924 }
e709ddd2
MG
925 };
926 this.fpnode.one('.fp-content').fp_display_filelist(options, list, this.lazyloading);
7ccf18a6
MG
927 },
928 /** If more than one page available, requests and displays the files from the next page */
929 request_next_page: function() {
930 if (!this.active_repo.hasmorepages || this.active_repo.nextpagerequested) {
931 // nothing to load
932 return;
933 }
934 this.active_repo.nextpagerequested = true;
935 var nextpage = this.active_repo.page+1;
936 var args = {page:nextpage, repo_id:this.active_repo.id, path:this.active_repo.path};
937 var action = this.active_repo.issearchresult ? 'search' : 'list';
938 this.request({
939 scope: this,
940 action: action,
941 client_id: this.options.client_id,
942 repository_id: args.repo_id,
943 params: args,
944 callback: function(id, obj, args) {
945 var scope = args.scope;
946 // check that we are still in the same repository and are expecting this page
947 if (scope.active_repo.hasmorepages && obj.list && obj.page &&
948 obj.repo_id == scope.active_repo.id &&
949 obj.page == scope.active_repo.page+1 && obj.path == scope.path) {
950 scope.parse_repository_options(obj, true);
951 scope.view_files(obj.list)
952 }
953 }
954 }, false);
5bdf63cc 955 },
99eaca9d 956 select_file: function(args) {
b5e7b638 957 this.selectui.show();
99eaca9d 958 var client_id = this.options.client_id;
b5e7b638 959 var selectnode = this.fpnode.one('.fp-select');
b92241f2 960 var return_types = this.options.repositories[this.active_repo.id].return_types;
3a1e425b 961 selectnode.removeClass('loading');
b92241f2
MG
962 selectnode.one('.fp-saveas input').set('value', args.title);
963 selectnode.one('.fp-setauthor input').set('value', this.options.author);
99eaca9d 964
ce3eeb98
MG
965 var imgnode = Y.Node.create('<img/>').
966 set('src', args.realthumbnail ? args.realthumbnail : args.thumbnail).
967 setStyle('maxHeight', ''+(args.thumbnail_height ? args.thumbnail_height : 90)+'px').
968 setStyle('maxWidth', ''+(args.thumbnail_width ? args.thumbnail_width : 90)+'px');
b92241f2 969 selectnode.one('.fp-thumbnail').setContent('').appendChild(imgnode);
b5e7b638 970
b92241f2
MG
971 selectnode.one('.fp-linkexternal input').set('checked', ''); // default to unchecked
972 if ((this.options.externallink && this.options.env == 'editor' && return_types == 3)) {
973 // support both internal and external links, enable checkbox 'Link external'
974 selectnode.one('.fp-linkexternal input').set('disabled', '');
975 selectnode.all('.fp-linkexternal').removeClass('uneditable')
b5e7b638
MG
976 } else {
977 // disable checkbox 'Link external'
b92241f2
MG
978 selectnode.one('.fp-linkexternal input').set('disabled', 'disabled');
979 selectnode.all('.fp-linkexternal').addClass('uneditable')
980 if (return_types == 1) {
b5e7b638 981 // support external links only
b92241f2 982 selectnode.one('.fp-linkexternal input').set('checked', 'checked');
b5e7b638 983 }
99eaca9d 984 }
1dce6261 985
b5e7b638 986 if (args.hasauthor) {
b92241f2
MG
987 selectnode.one('.fp-setauthor input').set('disabled', 'disabled');
988 selectnode.all('.fp-setauthor').addClass('uneditable')
b5e7b638 989 } else {
b92241f2
MG
990 selectnode.one('.fp-setauthor input').set('disabled', '');
991 selectnode.all('.fp-setauthor').removeClass('uneditable')
1dce6261
DC
992 }
993
994 if (!args.haslicense) {
995 // the license of the file
b92241f2
MG
996 selectnode.one('.fp-setlicense select').set('disabled', '');
997 selectnode.one('.fp-setlicense').removeClass('uneditable');
b5e7b638 998 } else {
b92241f2
MG
999 selectnode.one('.fp-setlicense select').set('disabled', 'disabled');
1000 selectnode.one('.fp-setlicense').addClass('uneditable');
1dce6261 1001 }
b92241f2 1002
b5e7b638 1003 selectnode.one('form #filesource-'+client_id).set('value', args.source);
b92241f2
MG
1004
1005 // display static information about a file (when known)
1006 var attrs = ['datemodified','datecreated','size','license','author','dimensions'];
1007 for (var i in attrs) {
1008 if (selectnode.one('.fp-'+attrs[i])) {
1009 var value = (args[attrs[i]+'_f']) ? args[attrs[i]+'_f'] : (args[attrs[i]] ? args[attrs[i]] : '');
1010 selectnode.one('.fp-'+attrs[i]).addClassIf('fp-unknown', ''+value == '')
1011 .one('.fp-value').setContent(value);
1012 }
1013 }
b5e7b638
MG
1014 },
1015 setup_select_file: function() {
1016 var client_id = this.options.client_id;
1017 var selectnode = this.fpnode.one('.fp-select');
b92241f2
MG
1018 var getfile = selectnode.one('.fp-select-confirm');
1019 // bind labels with corresponding inputs
1020 selectnode.all('.fp-saveas,.fp-linkexternal,.fp-setauthor,.fp-setlicense').each(function (node) {
1021 node.all('label').set('for', node.one('input,select').generateID());
1022 });
1023 this.populate_licenses_select(selectnode.one('.fp-setlicense select'));
1024 // register event on clicking submit button
99eaca9d 1025 getfile.on('click', function(e) {
b5e7b638 1026 e.preventDefault();
99eaca9d
DC
1027 var client_id = this.options.client_id;
1028 var scope = this;
1029 var repository_id = this.active_repo.id;
b92241f2 1030 var title = selectnode.one('.fp-saveas input').get('value');
b5e7b638 1031 var filesource = selectnode.one('form #filesource-'+client_id).get('value');
14469892 1032 var params = {'title':title, 'source':filesource, 'savepath': this.options.savepath};
b92241f2 1033 var license = selectnode.one('.fp-setlicense select');
1dce6261
DC
1034 if (license) {
1035 params['license'] = license.get('value');
b5e7b638 1036 Y.Cookie.set('recentlicense', license.get('value'));
1dce6261 1037 }
b92241f2 1038 params['author'] = selectnode.one('.fp-setauthor input').get('value');
99eaca9d 1039
400d228e 1040 if (this.options.externallink && this.options.env == 'editor') {
392d5fd4
DC
1041 // in editor, images are stored in '/' only
1042 params.savepath = '/';
766514a0 1043 // when image or media button is clicked
b92241f2
MG
1044 var return_types = this.options.repositories[this.active_repo.id].return_types;
1045 if ( return_types != 1 ) {
1046 var linkexternal = selectnode.one('.fp-linkexternal input');
400d228e 1047 if (linkexternal && linkexternal.get('checked')) {
766514a0
DC
1048 params['linkexternal'] = 'yes';
1049 }
1050 } else {
1051 // when link button in editor clicked
99eaca9d
DC
1052 params['linkexternal'] = 'yes';
1053 }
766514a0
DC
1054 }
1055
1056 if (this.options.env == 'url') {
99eaca9d
DC
1057 params['linkexternal'] = 'yes';
1058 }
1059
3a1e425b 1060 selectnode.addClass('loading');
99eaca9d 1061 this.request({
840912d5
DC
1062 action:'download',
1063 client_id: client_id,
1064 repository_id: repository_id,
1065 'params': params,
a5159b86 1066 onerror: function(id, obj, args) {
3a1e425b 1067 selectnode.removeClass('loading');
b5e7b638 1068 scope.selectui.hide();
a5159b86 1069 },
840912d5 1070 callback: function(id, obj, args) {
3a1e425b 1071 selectnode.removeClass('loading');
e0b85db4 1072 if (scope.options.editor_target && scope.options.env=='editor') {
840912d5
DC
1073 scope.options.editor_target.value=obj.url;
1074 scope.options.editor_target.onchange();
1075 }
1076 scope.hide();
1077 obj.client_id = client_id;
1078 var formcallback_scope = null;
411caa63 1079 if (args.scope.options.magicscope) {
840912d5
DC
1080 formcallback_scope = args.scope.options.magicscope;
1081 } else {
1082 formcallback_scope = args.scope;
99eaca9d 1083 }
840912d5
DC
1084 scope.options.formcallback.apply(formcallback_scope, [obj]);
1085 }
b5e7b638 1086 }, false);
99eaca9d 1087 }, this);
b5e7b638 1088 var elform = selectnode.one('form');
3a1e425b
MG
1089 elform.appendChild(Y.Node.create('<input/>').
1090 setAttrs({type:'hidden',id:'filesource-'+client_id}));
e0b85db4
DC
1091 elform.on('keydown', function(e) {
1092 if (e.keyCode == 13) {
1093 getfile.simulate('click');
8cbef19e 1094 e.preventDefault();
e0b85db4
DC
1095 }
1096 }, this);
b92241f2 1097 var cancel = selectnode.one('.fp-select-cancel');
99eaca9d 1098 cancel.on('click', function(e) {
b5e7b638
MG
1099 e.preventDefault();
1100 this.selectui.hide();
99eaca9d 1101 }, this);
99eaca9d 1102 },
b5e7b638
MG
1103 wait: function() {
1104 this.fpnode.one('.fp-content').setContent(M.core_filepicker.templates.loading);
1105 },
1106 viewbar_set_enabled: function(mode) {
1107 var viewbar = this.fpnode.one('.fp-viewbar')
1108 if (viewbar) {
1109 if (mode) {
1110 viewbar.addClass('enabled').removeClass('disabled')
1111 } else {
1112 viewbar.removeClass('enabled').addClass('disabled')
1113 }
99eaca9d 1114 }
b5e7b638
MG
1115 this.fpnode.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').removeClass('checked')
1116 var modes = {1:'icons', 2:'tree', 3:'details'};
1117 this.fpnode.all('.fp-vb-'+modes[this.viewmode]).addClass('checked');
1118 },
1119 viewbar_clicked: function(e) {
1120 e.preventDefault();
1121 var viewbar = this.fpnode.one('.fp-viewbar')
1122 if (!viewbar || !viewbar.hasClass('disabled')) {
1123 if (e.currentTarget.hasClass('fp-vb-tree')) {
1124 this.viewmode = 2;
1125 } else if (e.currentTarget.hasClass('fp-vb-details')) {
1126 this.viewmode = 3;
1127 } else {
1128 this.viewmode = 1;
1129 }
1130 this.viewbar_set_enabled(true)
1131 this.view_files();
1132 Y.Cookie.set('recentviewmode', this.viewmode);
99eaca9d
DC
1133 }
1134 },
1135 render: function() {
1136 var client_id = this.options.client_id;
b92241f2
MG
1137 this.fpnode = Y.Node.create(M.core_filepicker.templates.generallayout).
1138 set('id', 'filepicker-'+client_id);
1139 var fpselectnode = Y.Node.create(M.core_filepicker.templates.selectlayout);
b5e7b638 1140 Y.one(document.body).appendChild(this.fpnode);
b5e7b638
MG
1141 this.mainui = new Y.Panel({
1142 srcNode : this.fpnode,
1143 headerContent: M.str.repository.filepicker,
1144 zIndex : 500000,
1145 centered : true,
1146 modal : true,
1147 visible : false,
e88d5641
BR
1148 minWidth : this.fpnode.getStylePx('minWidth'),
1149 minHeight : this.fpnode.getStylePx('minHeight'),
1150 maxWidth : this.fpnode.getStylePx('maxWidth'),
1151 maxHeight : this.fpnode.getStylePx('maxHeight'),
b92241f2 1152 render : true
99eaca9d 1153 });
b92241f2
MG
1154 // allow to move the panel dragging it by it's header:
1155 this.mainui.plug(Y.Plugin.Drag,{handles:['.yui3-widget-hd']});
b5e7b638 1156 this.mainui.show();
6c2367cc 1157 if (this.mainui.get('y')<0) {this.mainui.set('y', 0);}
b92241f2 1158 // create panel for selecting a file (initially hidden)
6c2367cc 1159 this.fpnode.appendChild(fpselectnode);
b5e7b638
MG
1160 this.selectui = new Y.Panel({
1161 srcNode : fpselectnode,
1162 zIndex : 600000,
1163 centered : true,
1164 modal : true,
1165 close : true,
1166 render : true
99eaca9d 1167 });
b5e7b638 1168 this.selectui.hide();
ce3eeb98
MG
1169 // event handler for lazy loading of thumbnails and next page
1170 this.fpnode.one('.fp-content').on(['scroll','resize'], this.content_scrolled, this);
b5e7b638
MG
1171 // save template for one path element and location of path bar
1172 if (this.fpnode.one('.fp-path-folder')) {
1173 this.pathnode = this.fpnode.one('.fp-path-folder');
1174 this.pathbar = this.pathnode.get('parentNode');
1175 this.pathbar.removeChild(this.pathnode);
1176 }
1177 // assign callbacks for view mode switch buttons
1178 this.fpnode.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').
1179 on('click', this.viewbar_clicked, this);
1180 // assign callbacks for toolbar links
1181 this.setup_toolbar();
1182 this.setup_select_file();
3a1e425b 1183 this.hide_header();
934291d6 1184
99eaca9d 1185 // processing repository listing
b5e7b638
MG
1186 // Resort the repositories by sortorder
1187 var sorted_repositories = []
1188 for (var i in this.options.repositories) {
1189 sorted_repositories[i] = this.options.repositories[i]
1190 }
1191 sorted_repositories.sort(function(a,b){return a.sortorder-b.sortorder})
1192 // extract one repository template and repeat it for all repositories available,
1193 // set name and icon and assign callbacks
1194 var reponode = this.fpnode.one('.fp-repo');
1195 if (reponode) {
1196 var list = reponode.get('parentNode');
1197 list.removeChild(reponode);
1198 for (i in sorted_repositories) {
1199 var repository = sorted_repositories[i]
1200 var node = reponode.cloneNode(true);
1201 list.appendChild(node);
1202 node.
1203 set('id', 'fp-repo-'+client_id+'-'+repository.id).
1204 on('click', function(e, repository_id) {
1205 e.preventDefault();
1206 Y.Cookie.set('recentrepository', repository_id);
1207 this.hide_header();
1208 this.list({'repo_id':repository_id});
1209 }, this /*handler running scope*/, repository.id/*second argument of handler*/);
1210 node.one('.fp-repo-name').setContent(repository.name)
1211 node.one('.fp-repo-icon').set('src', repository.icon)
1212 if (i==0) {node.addClass('first');}
1213 if (i==sorted_repositories.length-1) {node.addClass('last');}
1214 if (i%2) {node.addClass('even');} else {node.addClass('odd');}
99eaca9d 1215 }
b5e7b638
MG
1216 }
1217 // display error if no repositories found
1218 if (sorted_repositories.length==0) {
3a1e425b 1219 this.display_error(M.str.repository.norepositoriesavailable, 'norepositoriesavailable')
b5e7b638
MG
1220 }
1221 // display repository that was used last time
1222 this.show_recent_repository();
99eaca9d 1223 },
7ccf18a6
MG
1224 parse_repository_options: function(data, appendtolist) {
1225 if (appendtolist) {
1226 if (data.list) {
1227 if (!this.filelist) { this.filelist = []; }
1228 for (var i in data.list) {
1229 this.filelist[this.filelist.length] = data.list[i];
1230 }
1231 }
1232 } else {
1233 this.filelist = data.list?data.list:null;
ce3eeb98 1234 this.lazyloading = {};
7ccf18a6 1235 }
99eaca9d
DC
1236 this.filepath = data.path?data.path:null;
1237 this.active_repo = {};
4adecd7b 1238 this.active_repo.issearchresult = data.issearchresult?true:false;
98b15580 1239 this.active_repo.dynload = data.dynload?data.dynload:false;
99eaca9d
DC
1240 this.active_repo.pages = Number(data.pages?data.pages:null);
1241 this.active_repo.page = Number(data.page?data.page:null);
7ccf18a6 1242 this.active_repo.hasmorepages = (this.active_repo.pages && this.active_repo.page && (this.active_repo.page < this.active_repo.pages || this.active_repo.pages == -1))
99eaca9d 1243 this.active_repo.id = data.repo_id?data.repo_id:null;
b5e7b638
MG
1244 this.active_repo.nosearch = (data.login || data.nosearch); // this is either login form or 'nosearch' attribute set
1245 this.active_repo.norefresh = (data.login || data.norefresh); // this is either login form or 'norefresh' attribute set
1246 this.active_repo.nologin = (data.login || data.nologin); // this is either login form or 'nologin' attribute is set
fdfb9cbe 1247 this.active_repo.logouttext = data.logouttext?data.logouttext:null;
99eaca9d
DC
1248 this.active_repo.help = data.help?data.help:null;
1249 this.active_repo.manage = data.manage?data.manage:null;
b5e7b638 1250 this.print_header();
99eaca9d
DC
1251 },
1252 print_login: function(data) {
97b151ea 1253 this.parse_repository_options(data);
99eaca9d
DC
1254 var client_id = this.options.client_id;
1255 var repository_id = data.repo_id;
1256 var l = this.logindata = data.login;
1257 var loginurl = '';
3a1e425b 1258 var action = data['login_btn_action'] ? data['login_btn_action'] : 'login';
99eaca9d 1259 var form_id = 'fp-form-'+client_id;
99eaca9d 1260
5ce13292
MG
1261 var loginform_node = Y.Node.create(M.core_filepicker.templates.loginform);
1262 loginform_node.one('form').set('id', form_id);
1263 this.fpnode.one('.fp-content').setContent('').appendChild(loginform_node);
1264 var templates = {
1265 'popup' : loginform_node.one('.fp-login-popup'),
1266 'textarea' : loginform_node.one('.fp-login-textarea'),
1267 'select' : loginform_node.one('.fp-login-select'),
1268 'text' : loginform_node.one('.fp-login-text'),
3a1e425b 1269 'radio' : loginform_node.one('.fp-login-radiogroup'),
5ce13292
MG
1270 'checkbox' : loginform_node.one('.fp-login-checkbox'),
1271 'input' : loginform_node.one('.fp-login-input')
1272 };
1273 var container;
1274 for (var i in templates) {
1275 if (templates[i]) {
1276 container = templates[i].get('parentNode');
1277 container.removeChild(templates[i])
1278 }
1279 }
1280
1281 for(var k in l) {
1282 if (templates[l[k].type]) {
1283 var node = templates[l[k].type].cloneNode(true);
1284 } else {
1285 node = templates['input'].cloneNode(true);
1286 }
1287 if (l[k].type == 'popup') {
3a1e425b 1288 // submit button
2f6749f4 1289 loginurl = l[k].url;
3a1e425b
MG
1290 var popupbutton = node.one('button');
1291 popupbutton.on('click', function(e){
1292 M.core_filepicker.active_filepicker = this;
1293 window.open(loginurl, 'repo_auth', 'location=0,status=0,width=500,height=300,scrollbars=yes');
1294 e.preventDefault();
1295 }, this);
1296 loginform_node.one('form').on('keydown', function(e) {
1297 if (e.keyCode == 13) {
1298 popupbutton.simulate('click');
1299 e.preventDefault();
1300 }
1301 }, this);
5ce13292
MG
1302 loginform_node.all('.fp-login-submit').remove();
1303 action = 'popup';
1304 }else if(l[k].type=='textarea') {
1305 // textarea element
1306 if (node.one('label')) { node.one('label').set('for', l[k].id).setContent(l[k].label) }
3a1e425b 1307 node.one('textarea').setAttrs({id:l[k].id, name:l[k].name});
5ce13292
MG
1308 }else if(l[k].type=='select') {
1309 // select element
1310 if (node.one('label')) { node.one('label').set('for', l[k].id).setContent(l[k].label) }
3a1e425b 1311 node.one('select').setAttrs({id:l[k].id, name:l[k].name}).setContent('');
5ce13292
MG
1312 for (i in l[k].options) {
1313 node.one('select').appendChild(
1314 Y.Node.create('<option/>').
1315 set('value', l[k].options[i].value).
1316 setContent(l[k].options[i].label))
1317 }
1318 }else if(l[k].type=='radio') {
1319 // radio input element
3a1e425b
MG
1320 node.all('label').setContent(l[k].label);
1321 var list = l[k].value.split('|');
1322 var labels = l[k].value_label.split('|');
1323 var radionode = null;
1324 for(var item in list) {
1325 if (radionode == null) {
1326 radionode = node.one('.fp-login-radio');
1327 radionode.one('input').set('checked', 'checked');
1328 } else {
1329 var x = radionode.cloneNode(true);
1330 radionode.insert(x, 'after');
1331 radionode = x;
1332 radionode.one('input').set('checked', '');
1333 }
1334 radionode.one('input').setAttrs({id:''+l[k].id+item, name:l[k].name,
1335 type:l[k].type, value:list[item]});
1336 radionode.all('label').setContent(labels[item]).set('for', ''+l[k].id+item)
1337 }
1338 if (radionode == null) {
1339 node.one('.fp-login-radio').remove();
1340 }
5ce13292
MG
1341 }else {
1342 // input element
1343 if (node.one('label')) { node.one('label').set('for', l[k].id).setContent(l[k].label) }
1344 node.one('input').
1345 set('type', l[k].type).
1346 set('id', l[k].id).
1347 set('name', l[k].name).
1348 set('value', l[k].value?l[k].value:'')
1349 }
1350 container.appendChild(node);
1351 }
3a1e425b
MG
1352 // custom label text for submit button
1353 if (data['login_btn_label']) {
1354 loginform_node.all('.fp-login-submit').setContent(data['login_btn_label'])
99eaca9d 1355 }
3a1e425b
MG
1356 // register button action for login and search
1357 if (action == 'login' || action == 'search') {
1358 loginform_node.one('.fp-login-submit').on('click', function(e){
5ce13292 1359 e.preventDefault();
b5e7b638 1360 this.hide_header();
99eaca9d 1361 this.request({
3a1e425b
MG
1362 'scope': this,
1363 'action':(action == 'search') ? 'search' : 'signin',
99eaca9d
DC
1364 'path': '',
1365 'client_id': client_id,
1366 'repository_id': repository_id,
3a1e425b 1367 'form': {id:form_id, upload:false, useDisabled:true},
4adecd7b 1368 'callback': this.display_response
99eaca9d
DC
1369 }, true);
1370 }, this);
1371 }
3a1e425b
MG
1372 // if 'Enter' is pressed in the form, simulate the button click
1373 if (loginform_node.one('.fp-login-submit')) {
1374 loginform_node.one('form').on('keydown', function(e) {
1375 if (e.keyCode == 13) {
1376 loginform_node.one('.fp-login-submit').simulate('click')
1377 e.preventDefault();
99eaca9d 1378 }
99eaca9d
DC
1379 }, this);
1380 }
99eaca9d 1381 },
4adecd7b
MG
1382 display_response: function(id, obj, args) {
1383 var scope = args.scope
1384 // highlight the current repository in repositories list
b5e7b638
MG
1385 scope.fpnode.all('.fp-repo.active').removeClass('active');
1386 scope.fpnode.all('#fp-repo-'+scope.options.client_id+'-'+obj.repo_id).addClass('active')
5ce13292
MG
1387 // add class repository_REPTYPE to the filepicker (for repository-specific styles)
1388 for (var i in scope.options.repositories) {
1389 scope.fpnode.removeClass('repository_'+scope.options.repositories[i].type)
1390 }
1391 if (obj.repo_id && scope.options.repositories[obj.repo_id]) {
1392 scope.fpnode.addClass('repository_'+scope.options.repositories[obj.repo_id].type)
1393 }
4adecd7b
MG
1394 // display response
1395 if (obj.login) {
b5e7b638 1396 scope.viewbar_set_enabled(false);
4adecd7b
MG
1397 scope.print_login(obj);
1398 } else if (obj.upload) {
b5e7b638 1399 scope.viewbar_set_enabled(false);
4adecd7b
MG
1400 scope.parse_repository_options(obj);
1401 scope.create_upload_form(obj);
1402 } else if (obj.iframe) {
99eaca9d 1403
4adecd7b 1404 } else if (obj.list) {
b5e7b638 1405 scope.viewbar_set_enabled(true);
4adecd7b
MG
1406 scope.parse_repository_options(obj);
1407 scope.view_files();
99eaca9d 1408 }
99eaca9d
DC
1409 },
1410 list: function(args) {
99eaca9d
DC
1411 if (!args) {
1412 args = {};
1413 }
1414 if (!args.repo_id) {
4adecd7b 1415 args.repo_id = this.active_repo.id;
99eaca9d 1416 }
4adecd7b
MG
1417 this.request({
1418 action: 'list',
1419 client_id: this.options.client_id,
99eaca9d 1420 repository_id: args.repo_id,
4adecd7b
MG
1421 path: args.path,
1422 page: args.page,
1423 scope: this,
1424 callback: this.display_response
99eaca9d
DC
1425 }, true);
1426 },
b5e7b638
MG
1427 populate_licenses_select: function(node) {
1428 if (!node) {
1429 return;
e35194be 1430 }
b5e7b638 1431 node.setContent('');
1dce6261 1432 var licenses = this.options.licenses;
b5e7b638 1433 var recentlicense = Y.Cookie.get('recentlicense');
a756cb37
DC
1434 if (recentlicense) {
1435 this.options.defaultlicense=recentlicense;
1436 }
1dce6261 1437 for (var i in licenses) {
b5e7b638
MG
1438 var option = Y.Node.create('<option/>').
1439 set('selected', (this.options.defaultlicense==licenses[i].shortname)).
1440 set('value', licenses[i].shortname).
1441 setContent(licenses[i].fullname);
1442 node.appendChild(option)
1dce6261 1443 }
b5e7b638
MG
1444 },
1445 create_upload_form: function(data) {
1446 var client_id = this.options.client_id;
1447 var id = data.upload.id+'_'+client_id;
b92241f2
MG
1448 var content = this.fpnode.one('.fp-content');
1449 content.setContent(M.core_filepicker.templates.uploadform);
b5e7b638 1450
b92241f2
MG
1451 content.all('.fp-file,.fp-saveas,.fp-setauthor,.fp-setlicense').each(function (node) {
1452 node.all('label').set('for', node.one('input,select').generateID());
1453 });
1454 content.one('form').set('id', id);
1455 content.one('.fp-file input').set('name', 'repo_upload_file');
1456 content.one('.fp-saveas input').set('name', 'title');
1457 content.one('.fp-setauthor input').setAttrs({name:'author', value:this.options.author});
1458 content.one('.fp-setlicense select').set('name', 'license');
1459 this.populate_licenses_select(content.one('.fp-setlicense select'))
1460 // append hidden inputs to the upload form
1461 content.one('form').appendChild(Y.Node.create('<input/>').
3a1e425b 1462 setAttrs({type:'hidden',name:'itemid',value:this.options.itemid}));
b5e7b638
MG
1463 var types = this.options.accepted_types;
1464 for (var i in types) {
b92241f2 1465 content.one('form').appendChild(Y.Node.create('<input/>').
3a1e425b 1466 setAttrs({type:'hidden',name:'accepted_types[]',value:types[i]}));
b5e7b638
MG
1467 }
1468
99eaca9d 1469 var scope = this;
b92241f2 1470 content.one('.fp-upload-btn').on('click', function(e) {
8cbef19e 1471 e.preventDefault();
b92241f2 1472 var license = content.one('.fp-setlicense select');
b5e7b638 1473 Y.Cookie.set('recentlicense', license.get('value'));
b92241f2 1474 if (!content.one('.fp-file input').get('value')) {
ce6297d2 1475 scope.print_msg(M.str.repository.nofilesattached, 'error');
2a03b97b
DC
1476 return false;
1477 }
b5e7b638 1478 this.hide_header();
9d753c38
PS
1479 scope.request({
1480 scope: scope,
1481 action:'upload',
1482 client_id: client_id,
1483 params: {'savepath':scope.options.savepath},
1484 repository_id: scope.active_repo.id,
1485 form: {id: id, upload:true},
a5159b86
MG
1486 onerror: function(id, o, args) {
1487 scope.create_upload_form(data);
1488 },
9d753c38
PS
1489 callback: function(id, o, args) {
1490 if (scope.options.editor_target&&scope.options.env=='editor') {
1491 scope.options.editor_target.value=o.url;
1492 scope.options.editor_target.onchange();
0c4edaa2 1493 }
9d753c38
PS
1494 scope.hide();
1495 o.client_id = client_id;
1496 var formcallback_scope = null;
1497 if (args.scope.options.magicscope) {
1498 formcallback_scope = args.scope.options.magicscope;
1499 } else {
1500 formcallback_scope = args.scope;
1501 }
1502 scope.options.formcallback.apply(formcallback_scope, [o]);
1503 }
1504 }, true);
99eaca9d
DC
1505 }, this);
1506 },
b5e7b638
MG
1507 /** setting handlers and labels for elements in toolbar. Called once during the initial render of filepicker */
1508 setup_toolbar: function() {
99eaca9d 1509 var client_id = this.options.client_id;
b92241f2
MG
1510 var toolbar = this.fpnode.one('.fp-toolbar');
1511 toolbar.one('.fp-tb-logout').one('a,button').on('click', function(e) {
b5e7b638
MG
1512 e.preventDefault();
1513 if (!this.active_repo.nologin) {
1514 this.hide_header();
1515 this.request({
1516 action:'logout',
1517 client_id: this.options.client_id,
1518 repository_id: this.active_repo.id,
1519 path:'',
1520 callback: this.display_response
1521 }, true);
1522 }
1523 }, this);
b92241f2 1524 toolbar.one('.fp-tb-refresh').one('a,button').on('click', function(e) {
b5e7b638
MG
1525 e.preventDefault();
1526 if (!this.active_repo.norefresh) {
1527 this.list();
1528 }
1529 }, this);
b92241f2 1530 toolbar.one('.fp-tb-search form').
b5e7b638 1531 set('method', 'POST').
b92241f2 1532 set('id', 'fp-tb-search-'+client_id).
b5e7b638 1533 on('submit', function(e) {
4adecd7b 1534 e.preventDefault();
b5e7b638
MG
1535 if (!this.active_repo.nosearch) {
1536 this.request({
1537 scope: this,
1538 action:'search',
1539 client_id: this.options.client_id,
1540 repository_id: this.active_repo.id,
1541 form: {id: 'fp-tb-search-'+client_id, upload:false, useDisabled:true},
1542 callback: this.display_response
1543 }, true);
1544 }
1545 }, this);
99eaca9d 1546
b92241f2 1547 // it does not matter what kind of element is .fp-tb-manage, we create a dummy <a>
b5e7b638 1548 // element and use it to open url on click event
3a1e425b
MG
1549 var managelnk = Y.Node.create('<a/>').
1550 setAttrs({id:'fp-tb-manage-'+client_id+'-link', target:'_blank'}).
1551 setStyle('display', 'none');
b92241f2
MG
1552 toolbar.append(managelnk);
1553 toolbar.one('.fp-tb-manage').one('a,button').
1554 on('click', function(e) {
1555 e.preventDefault();
1556 managelnk.simulate('click')
1557 });
99eaca9d 1558
b92241f2 1559 // same with .fp-tb-help
3a1e425b
MG
1560 var helplnk = Y.Node.create('<a/>').
1561 setAttrs({id:'fp-tb-help-'+client_id+'-link', target:'_blank'}).
1562 setStyle('display', 'none');
b92241f2
MG
1563 toolbar.append(helplnk);
1564 toolbar.one('.fp-tb-manage').one('a,button').
1565 on('click', function(e) {
1566 e.preventDefault();
1567 helplnk.simulate('click')
1568 });
b5e7b638
MG
1569 },
1570 hide_header: function() {
b92241f2
MG
1571 if (this.fpnode.one('.fp-toolbar')) {
1572 this.fpnode.one('.fp-toolbar').addClass('empty');
b5e7b638 1573 }
3a1e425b
MG
1574 if (this.pathbar) {
1575 this.pathbar.setContent('').addClass('empty');
1576 }
b5e7b638
MG
1577 },
1578 print_header: function() {
1579 var r = this.active_repo;
1580 var scope = this;
1581 var client_id = this.options.client_id;
2f6749f4 1582 this.hide_header();
b92241f2
MG
1583 this.print_path();
1584 var toolbar = this.fpnode.one('.fp-toolbar');
1585 if (!toolbar) { return; }
99eaca9d 1586
b92241f2
MG
1587 var enable_tb_control = function(node, enabled) {
1588 if (!node) { return; }
1589 node.addClassIf('disabled', !enabled).addClassIf('enabled', enabled)
1590 if (enabled) {
1591 toolbar.removeClass('empty');
b5e7b638
MG
1592 }
1593 }
99eaca9d 1594
b5e7b638 1595 // TODO 'back' permanently disabled for now. Note, flickr_public uses 'Logout' for it!
b92241f2 1596 enable_tb_control(toolbar.one('.fp-tb-back'), false);
99eaca9d 1597
b5e7b638 1598 // search form
b92241f2 1599 enable_tb_control(toolbar.one('.fp-tb-search'), !r.nosearch);
b5e7b638 1600 if(!r.nosearch) {
b92241f2
MG
1601 var searchform = toolbar.one('.fp-tb-search form');
1602 searchform.setContent('');
b5e7b638
MG
1603 this.request({
1604 scope: this,
1605 action:'searchform',
1606 repository_id: this.active_repo.id,
1607 callback: function(id, obj, args) {
1608 if (obj.repo_id == scope.active_repo.id && obj.form) {
1609 // if we did not jump to another repository meanwhile
b92241f2 1610 searchform.setContent(obj.form);
99eaca9d 1611 }
b5e7b638
MG
1612 }
1613 }, false);
99eaca9d 1614 }
b5e7b638
MG
1615
1616 // refresh button
99eaca9d 1617 // weather we use cache for this instance, this button will reload listing anyway
b92241f2 1618 enable_tb_control(toolbar.one('.fp-tb-refresh'), !r.norefresh);
b5e7b638
MG
1619
1620 // login button
b92241f2 1621 enable_tb_control(toolbar.one('.fp-tb-logout'), !r.nologin);
99eaca9d 1622 if(!r.nologin) {
fdfb9cbe 1623 var label = r.logouttext?r.logouttext:M.str.repository.logout;
b92241f2 1624 toolbar.one('.fp-tb-logout').one('a,button').setContent(label)
99eaca9d
DC
1625 }
1626
b5e7b638 1627 // manage url
b92241f2 1628 enable_tb_control(toolbar.one('.fp-tb-manage'), r.manage);
b5e7b638
MG
1629 Y.one('#fp-tb-manage-'+client_id+'-link').set('href', r.manage);
1630
1631 // help url
b92241f2 1632 enable_tb_control(toolbar.one('.fp-tb-help'), r.help);
b5e7b638 1633 Y.one('#fp-tb-help-'+client_id+'-link').set('href', r.help);
99eaca9d 1634 },
99eaca9d 1635 print_path: function() {
b5e7b638 1636 if (!this.pathbar) { return; }
3a1e425b 1637 this.pathbar.setContent('').addClass('empty');
99eaca9d 1638 var p = this.filepath;
2f6749f4 1639 if (p && p.length!=0 && this.viewmode != 2) {
99eaca9d 1640 for(var i = 0; i < p.length; i++) {
b5e7b638
MG
1641 var el = this.pathnode.cloneNode(true);
1642 this.pathbar.appendChild(el);
1643 if (i == 0) {el.addClass('first');}
1644 if (i == p.length-1) {el.addClass('last');}
1645 if (i%2) {el.addClass('even');} else {el.addClass('odd');}
1646 el.all('.fp-path-folder-name').setContent(p[i].name);
1647 el.on('click',
1648 function(e, path) {
1649 e.preventDefault();
1650 this.list({'path':path});
1651 },
1652 this, p[i].path);
99eaca9d 1653 }
b5e7b638 1654 this.pathbar.removeClass('empty');
99eaca9d
DC
1655 }
1656 },
1657 hide: function() {
b5e7b638
MG
1658 this.selectui.hide();
1659 if (this.process_dlg) {
1660 this.process_dlg.hide();
1661 }
1662 if (this.msg_dlg) {
1663 this.msg_dlg.hide();
1664 }
99eaca9d
DC
1665 this.mainui.hide();
1666 },
1667 show: function() {
b5e7b638
MG
1668 if (this.fpnode) {
1669 this.hide();
99eaca9d 1670 this.mainui.show();
a756cb37 1671 this.show_recent_repository();
99eaca9d
DC
1672 } else {
1673 this.launch();
1674 }
1675 },
1676 launch: function() {
7b42e81a 1677 this.render();
a756cb37
DC
1678 },
1679 show_recent_repository: function() {
b5e7b638
MG
1680 this.hide_header();
1681 this.viewbar_set_enabled(false);
1682 var repository_id = Y.Cookie.get('recentrepository');
1683 this.viewmode = Y.Cookie.get('recentviewmode', Number);
5bdf63cc 1684 if (this.viewmode != 2 && this.viewmode != 3) {
b5e7b638
MG
1685 this.viewmode = 1;
1686 }
a756cb37
DC
1687 if (this.options.repositories[repository_id]) {
1688 this.list({'repo_id':repository_id});
1689 }
99eaca9d
DC
1690 }
1691 });
bb496de7
DC
1692 var loading = Y.one('#filepicker-loading-'+options.client_id);
1693 if (loading) {
1694 loading.setStyle('display', 'none');
1695 }
4c508047
PS
1696 M.core_filepicker.instances[options.client_id] = new FilePickerHelper(options);
1697};