Merge branch 'MDL-33932_22' of git://github.com/grabs/moodle into MOODLE_22_STABLE
[moodle.git] / repository / filepicker.js
blob9c5ac4003c153e03c632b58442c65a146ff75910
1 // YUI3 File Picker module for moodle
2 // Author: Dongsheng Cai <dongsheng@moodle.com>
4 /**
5  *
6  * File Picker UI
7  * =====
8  * this.rendered, it tracks if YUI Panel rendered
9  * this.api, stores the URL to make ajax request
10  * this.mainui, YUI Panel
11  * this.treeview, YUI Treeview
12  * this.viewbar, a button group to switch view mode
13  * this.viewmode, store current view mode
14  *
15  * Filepicker options:
16  * =====
17  * this.options.client_id, the instance id
18  * this.options.contextid
19  * this.options.itemid
20  * this.options.repositories, stores all repositories displaied in file picker
21  * this.options.formcallback
22  *
23  * Active repository options
24  * =====
25  * this.active_repo.id
26  * this.active_repo.nosearch
27  * this.active_repo.norefresh
28  * this.active_repo.nologin
29  * this.active_repo.help
30  * this.active_repo.manage
31  *
32  * Server responses
33  * =====
34  * this.filelist, cached filelist
35  * this.pages
36  * this.page
37  * this.filepath, current path
38  * this.logindata, cached login form
39  */
41 M.core_filepicker = M.core_filepicker || {};
43 /**
44  * instances of file pickers used on page
45  */
46 M.core_filepicker.instances = M.core_filepicker.instances || {};
47 M.core_filepicker.active_filepicker = null;
49 /**
50  * Init and show file picker
51  */
52 M.core_filepicker.show = function(Y, options) {
53     if (!M.core_filepicker.instances[options.client_id]) {
54         M.core_filepicker.init(Y, options);
55     }
56     M.core_filepicker.instances[options.client_id].show();
59 /**
60  * Add new file picker to current instances
61  */
62 M.core_filepicker.init = function(Y, options) {
63     var FilePickerHelper = function(options) {
64         FilePickerHelper.superclass.constructor.apply(this, arguments);
65     };
67     FilePickerHelper.NAME = "FilePickerHelper";
68     FilePickerHelper.ATTRS = {
69         options: {},
70         lang: {}
71     };
73     Y.extend(FilePickerHelper, Y.Base, {
74         api: M.cfg.wwwroot+'/repository/repository_ajax.php',
76         initializer: function(options) {
77             this.options = options;
78             if (!this.options.savepath) {
79                 this.options.savepath = '/';
80             }
81         },
83         destructor: function() {
84         },
86         request: function(args, redraw) {
87             var client_id = args.client_id;
88             if (!args.api) {
89                 var api = this.api + '?action='+args.action;
90             } else {
91                 var api = args.api + '?action='+args.action;
92             }
93             var params = {};
94             var scope = this;
95             if (args['scope']) {
96                 scope = args['scope'];
97             }
98             params['repo_id']=args.repository_id;
99             params['p'] = args.path?args.path:'';
100             params['page'] = args.page?args.page:'';
101             params['env']=this.options.env;
102             // the form element only accept certain file types
103             params['accepted_types']=this.options.accepted_types;
104             params['sesskey'] = M.cfg.sesskey;
105             params['client_id'] = args.client_id;
106             params['itemid'] = this.options.itemid?this.options.itemid:0;
107             params['maxbytes'] = this.options.maxbytes?this.options.maxbytes:-1;
108             if (this.options.context && this.options.context.id) {
109                 params['ctx_id'] = this.options.context.id;
110             }
111             if (args['params']) {
112                 for (i in args['params']) {
113                     params[i] = args['params'][i];
114                 }
115             }
116             if (args.action == 'upload') {
117                 var list = [];
118                 for(var k in params) {
119                     var value = params[k];
120                     if(value instanceof Array) {
121                         for(var i in value) {
122                             list.push(k+'[]='+value[i]);
123                         }
124                     } else {
125                         list.push(k+'='+value);
126                     }
127                 }
128                 params = list.join('&');
129             } else {
130                 params = build_querystring(params);
131             }
132             var cfg = {
133                 method: 'POST',
134                 on: {
135                     complete: function(id,o,p) {
136                         var panel_id = '#panel-'+client_id;
137                         if (!o) {
138                             alert('IO FATAL');
139                             return;
140                         }
141                         var data = null;
142                         try {
143                             data = Y.JSON.parse(o.responseText);
144                         } catch(e) {
145                             scope.print_msg(M.str.repository.invalidjson, 'error');
146                             Y.one(panel_id).set('innerHTML', 'ERROR: '+M.str.repository.invalidjson+'<pre>'+stripHTML(o.responseText)+'</pre>');
147                             return;
148                         }
149                         // error checking
150                         if (data && data.error) {
151                             scope.print_msg(data.error, 'error');
152                             if (args.onerror) {
153                                 args.onerror(id,data,p);
154                             } else {
155                                 Y.one(panel_id).set('innerHTML', '');
156                             }
157                             return;
158                         } else if (data && data.event) {
159                             switch (data.event) {
160                                 case 'fileexists':
161                                     scope.process_existing_file(data);
162                                     break;
163                                 default:
164                                     break;
165                             }
166                         } else {
167                             if (data.msg) {
168                                 scope.print_msg(data.msg, 'info');
169                             }
170                             args.callback(id,data,p);
171                         }
172                     }
173                 },
174                 arguments: {
175                     scope: scope
176                 },
177                 headers: {
178                     'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
179                 },
180                 data: params,
181                 context: this
182             };
183             if (args.form) {
184                 cfg.form = args.form;
185             }
186             Y.io(api, cfg);
187             if (redraw) {
188                 this.wait('load');
189             }
190         },
191         process_existing_file: function(data) {
192             var scope = this;
193             var repository_id = scope.active_repo.id;
194             var client_id = scope.options.client_id;
195             var handleOverwrite = function() {
196                 // overwrite
197                 var dialog = this;
198                 var params = {}
199                 params['existingfilename'] = data.existingfile.filename;
200                 params['existingfilepath'] = data.existingfile.filepath;
201                 params['newfilename'] = data.newfile.filename;
202                 params['newfilepath'] = data.newfile.filepath;
203                 scope.request({
204                     'params': params,
205                     'scope': scope,
206                     'action':'overwrite',
207                     'path': '',
208                     'client_id': client_id,
209                     'repository_id': repository_id,
210                     'callback': function(id, o, args) {
211                         dialog.cancel();
212                         scope.hide();
213                         // editor needs to update url
214                         // filemanager do nothing
215                         if (scope.options.editor_target && scope.options.env == 'editor') {
216                             scope.options.editor_target.value = data.existingfile.url;
217                             scope.options.editor_target.onchange();
218                         } else if (scope.options.env === 'filepicker') {
219                             var fileinfo = {'client_id':client_id,
220                                     'url':data.existingfile.url,
221                                     'file':data.existingfile.filename};
222                             scope.options.formcallback.apply(scope, [fileinfo]);
223                         }
224                     }
225                 }, true);
226             }
227             var handleRename = function() {
228                 if (scope.options.editor_target && scope.options.env == 'editor') {
229                     scope.options.editor_target.value = data.newfile.url;
230                     scope.options.editor_target.onchange();
231                 }
232                 this.cancel();
233                 scope.hide();
234                 var formcallback_scope = null;
235                 if (scope.options.magicscope) {
236                     formcallback_scope = scope.options.magicscope;
237                 } else {
238                     formcallback_scope = scope;
239                 }
240                 var fileinfo = {'client_id':client_id,
241                                 'url':data.newfile.url,
242                                 'file':data.newfile.filename};
243                 scope.options.formcallback.apply(formcallback_scope, [fileinfo]);
244             }
245             var handleCancel = function() {
246                 // Delete tmp file
247                 var dialog = this;
248                 var params = {};
249                 params['newfilename'] = data.newfile.filename;
250                 params['newfilepath'] = data.newfile.filepath;
251                 scope.request({
252                     'params': params,
253                     'scope': scope,
254                     'action':'deletetmpfile',
255                     'path': '',
256                     'client_id': client_id,
257                     'repository_id': repository_id,
258                     'callback': function(id, o, args) {
259                         scope.hide();
260                         dialog.cancel();
261                     }
262                 }, true);
263             }
264             var dialog = new YAHOO.widget.SimpleDialog("dlg", {
265                 width: "50em",
266                 fixedcenter: true,
267                 close: false,
268                 icon: YAHOO.widget.SimpleDialog.ICON_HELP,
269                 visible: true,
270                 zIndex: 9999993,
271                 draggable: true,
272                 buttons: [{ text: M.str.repository.overwrite, handler: handleOverwrite },
273                 { text: M.str.repository.renameto + ' "' + data.newfile.filename + '"', handler: handleRename },
274                 { text: M.str.moodle.cancel, handler: handleCancel, isDefault: true}]
275             });
276             dialog.setHeader(M.str.repository.fileexistsdialogheader);
277             if (scope.options.env == 'editor') {
278                 dialog.setBody(M.str.repository.fileexistsdialog_editor);
279             } else {
280                 dialog.setBody(M.str.repository.fileexistsdialog_filemanager);
281             }
283             dialog.render(document.body);
284             dialog.show();
285         },
286         print_msg: function(msg, type) {
287             var client_id = this.options.client_id;
288             var dlg_id = 'fp-msg-dlg-'+client_id;
289             function handleYes() {
290                 this.hide();
291             }
292             var icon = YAHOO.widget.SimpleDialog.ICON_INFO;
293             if (type=='error') {
294                 icon = YAHOO.widget.SimpleDialog.ICON_ALARM;
295             }
296             if (!this.msg_dlg) {
297                 this.msg_dlg = new YAHOO.widget.SimpleDialog(dlg_id,
298                      { width: "300px",
299                        fixedcenter: true,
300                        visible: true,
301                        draggable: true,
302                        close: true,
303                        text: msg,
304                        modal: false,
305                        icon: icon,
306                        zindex: 9999992,
307                        constraintoviewport: true,
308                        buttons: [{ text:M.str.moodle.ok, handler:handleYes, isDefault:true }]
309                      });
310                 this.msg_dlg.render(document.body);
311             } else {
312                 this.msg_dlg.setBody(msg);
313             }
314             var header = M.str.moodle.info;
315             if (type=='error') {
316                 header = M.str.moodle.error;
317             }
318             this.msg_dlg.setHeader(header);
319             this.msg_dlg.show();
320         },
321         build_tree: function(node, level) {
322             var client_id = this.options.client_id;
323             var dynload = this.active_repo.dynload;
324             var info = {
325                 label:node.title,
326                 //title:fp_lang.date+' '+node.date+fp_lang.size+' '+node.size,
327                 filename:node.title,
328                 source:node.source?node.source:'',
329                 thumbnail:node.thumbnail,
330                 path:node.path?node.path:[]
331             };
332             var tmpNode = new YAHOO.widget.TextNode(info, level, false);
333             if(node.repo_id) {
334                 tmpNode.repo_id=node.repo_id;
335             }else{
336                 tmpNode.repo_id=this.active_repo.id;
337             }
338             if(node.children) {
339                 if(node.expanded) {
340                     tmpNode.expand();
341                 }
342                 if (dynload) {
343                     tmpNode.scope = this;
344                 }
345                 tmpNode.isLeaf = false;
346                 tmpNode.client_id = client_id;
347                 if (node.path) {
348                     tmpNode.path = node.path;
349                 } else {
350                     tmpNode.path = '';
351                 }
352                 for(var c in node.children) {
353                     this.build_tree(node.children[c], tmpNode);
354                 }
355             } else {
356                 tmpNode.isLeaf = true;
357             }
358         },
359         view_files: function(page) {
360             var p= page?page:null;
361             if (this.active_repo.issearchresult) {
362                 // list view is desiged to display treeview
363                 // it is not working well with search result
364                 this.view_as_icons();
365             } else {
366                 this.viewbar.set('disabled', false);
367                 if (this.viewmode == 1) {
368                     this.view_as_icons();
369                 } else if (this.viewmode == 2) {
370                     this.view_as_list(p);
371                 } else {
372                     this.view_as_icons();
373                 }
374             }
375         },
376         treeview_dynload: function(node, cb) {
377             var scope = node.scope;
378             var client_id = scope.options.client_id;
379             var repository_id = scope.active_repo.id;
380             scope.request({
381                 action:'list',
382                 client_id: client_id,
383                 repository_id: repository_id,
384                 path:node.path?node.path:'',
385                 page:node.page?args.page:'',
386                 callback: function(id, obj, args) {
387                     obj.issearchresult = false;
388                     var list = obj.list;
389                     scope.viewbar.set('disabled', false);
390                     scope.parse_repository_options(obj);
391                     for(k in list) {
392                         scope.build_tree(list[k], node);
393                     }
394                     cb();
395                 }
396             }, false);
397         },
398         view_as_list: function(p) {
399             var scope = this;
400             var page = null;
401             if (!p) {
402                 if (scope.active_repo.page) {
403                     page = scope.active_repo.page;
404                 }
405             } else {
406                 page = p;
407             }
408             scope.request({
409                 action:'list',
410                 client_id: scope.options.client_id,
411                 repository_id: scope.active_repo.id,
412                 path:'',
413                 page:page,
414                 callback: function(id, obj, args) {
415                     scope.parse_repository_options(obj);
416                     if (obj.login) {
417                         scope.viewbar.set('disabled', true);
418                         scope.print_login(obj);
419                         return;
420                     }
421                     var client_id = scope.options.client_id;
422                     var dynload = scope.active_repo.dynload;
423                     var list = obj.list;
424                     var panel_id = '#panel-'+client_id;
425                     scope.viewmode = 2;
426                     Y.one(panel_id).set('innerHTML', '');
428                     scope.print_header();
430                     var html = '<div class="fp-tree-panel" id="treeview-'+client_id+'">';
431                     if (list && list.length==0) {
432                         html += '<div class="fp-emptylist mdl-align">' +M.str.repository.nofilesavailable+'</div>';
433                     }
434                     html += '</div>';
436                     var tree = Y.Node.create(html);
437                     Y.one(panel_id).appendChild(tree);
438                     if (!list || list.length==0) {
439                         return;
440                     }
442                     scope.treeview = new YAHOO.widget.TreeView('treeview-'+client_id);
443                     if (dynload) {
444                         scope.treeview.setDynamicLoad(scope.treeview_dynload, 1);
445                     }
447                     for(k in list) {
448                         scope.build_tree(list[k], scope.treeview.getRoot());
449                     }
450                     scope.treeview.subscribe('clickEvent', function(e){
451                         if(e.node.isLeaf){
452                             var fileinfo = {};
453                             fileinfo['title'] = e.node.data.filename;
454                             fileinfo['source'] = e.node.data.source;
455                             fileinfo['thumbnail'] = e.node.data.thumbnail;
456                             scope.select_file(fileinfo);
457                         }
458                     });
459                     scope.treeview.draw();
460                 }
461             }, true);
462         },
463         view_as_icons: function() {
464             var scope = this;
465             var client_id = this.options.client_id;
466             var list = this.filelist;
467             var panel_id = '#panel-'+client_id;
468             this.viewmode = 1;
469             Y.one(panel_id).set('innerHTML', '');
471             this.print_header();
473             var html = '<div class="fp-grid-panel" id="fp-grid-panel-'+client_id+'">';
474             if (list && list.length==0) {
475                 html += '<div class="fp-emptylist mdl-align">' +M.str.repository.nofilesavailable+'</div>';
476             }
477             html += '</div>';
479             var gridpanel = Y.Node.create(html);
480             Y.one('#panel-'+client_id).appendChild(gridpanel);
481             var count = 0;
482             for(var k in list) {
483                 var node = list[k];
484                 var grid = document.createElement('DIV');
485                 grid.className='fp-grid';
486                 // the file name
487                 var title = document.createElement('DIV');
488                 title.id = 'grid-title-'+client_id+'-'+String(count);
489                 title.className = 'label';
490                 var filename = node.title;
491                 if (node.shorttitle) {
492                     filename = node.shorttitle;
493                 }
494                 var filename_id = 'filname-link-'+client_id+'-'+String(count);
495                 title.innerHTML += '<a href="###" id="'+filename_id+'" title="'+node.title+'"><span>'+filename+"</span></a>";
498                 if(node.thumbnail_width){
499                     grid.style.width = node.thumbnail_width+'px';
500                     title.style.width = (node.thumbnail_width-10)+'px';
501                 } else {
502                     grid.style.width = title.style.width = '90px';
503                 }
504                 var frame = document.createElement('DIV');
505                 frame.style.textAlign='center';
506                 if(node.thumbnail_height){
507                     frame.style.height = node.thumbnail_height+'px';
508                 }
509                 var img = document.createElement('img');
510                 img.src = node.thumbnail;
511                 img.title = node.title;
512                 if(node.thumbnail_alt) {
513                     img.alt = node.thumbnail_alt;
514                 }
515                 if(node.thumbnail_title) {
516                     img.title = node.thumbnail_title;
517                 }
519                 var link = document.createElement('A');
520                 link.href='###';
521                 link.id = 'img-id-'+client_id+'-'+String(count);
522                 if(node.url) {
523                     // hide
524                     //grid.innerHTML += '<p><a target="_blank" href="'+node.url+'">'+M.str.repository.preview+'</a></p>';
525                 }
526                 link.appendChild(img);
527                 frame.appendChild(link);
528                 grid.appendChild(frame);
529                 grid.appendChild(title);
530                 gridpanel.appendChild(grid);
532                 var y_title = Y.one('#'+title.id);
533                 var y_file = Y.one('#'+link.id);
534                 var dynload = this.active_repo.dynload;
535                 if(node.children) {
536                     y_file.on('click', function(e, p) {
537                         if(dynload) {
538                             var params = {'path':p.path};
539                             scope.list(params);
540                         }else{
541                             this.filelist = p.children;
542                             this.view_files();
543                         }
544                     }, this, node);
545                     y_title.on('click', function(e, p, id){
546                         var icon = Y.one(id);
547                         icon.simulate('click');
548                     }, this, node, '#'+link.id);
549                 } else {
550                     var fileinfo = {};
551                     fileinfo['title'] = list[k].title;
552                     fileinfo['source'] = list[k].source;
553                     fileinfo['thumbnail'] = list[k].thumbnail;
554                     fileinfo['haslicense'] = list[k].haslicense?true:false;
555                     fileinfo['hasauthor'] = list[k].hasauthor?true:false;
556                     y_title.on('click', function(e, args) {
557                         this.select_file(args);
558                     }, this, fileinfo);
559                     y_file.on('click', function(e, args) {
560                         this.select_file(args);
561                     }, this, fileinfo);
562                 }
563                 count++;
564             }
565         },
566         select_file: function(args) {
567             var client_id = this.options.client_id;
568             var thumbnail = Y.one('#fp-grid-panel-'+client_id);
569             if(thumbnail){
570                 thumbnail.setStyle('display', 'none');
571             }
572             var header = Y.one('#fp-header-'+client_id);
573             if (header) {
574                 header.setStyle('display', 'none');
575             }
576             var footer = Y.one('#fp-footer-'+client_id);
577             if (footer) {
578                 footer.setStyle('display', 'none');
579             }
580             var path = Y.one('#path-'+client_id);
581             if(path){
582                 path.setStyle('display', 'none');
583             }
584             var panel = Y.one('#panel-'+client_id);
585             var form_id = 'fp-rename-form-'+client_id;
586             var html = '<div class="fp-rename-form" id="'+form_id+'">';
587             html += '<p><img src="'+args.thumbnail+'" /></p>';
588             html += '<table width="100%">';
589             html += '<tr><td class="mdl-right"><label for="newname-'+client_id+'">'+M.str.repository.saveas+':</label></td>';
590             html += '<td class="mdl-left"><input type="text" id="newname-'+client_id+'" value="'+args.title+'" /></td></tr>';
592             var le_checked = '';
593             var le_style = '';
594             if (this.options.repositories[this.active_repo.id].return_types == 1) {
595                 // support external links only
596                 le_checked = 'checked';
597                 le_style = ' style="display:none;"';
598             } else if(this.options.repositories[this.active_repo.id].return_types == 2) {
599                 // support internal files only
600                 le_style = ' style="display:none;"';
601             }
602             if ((this.options.externallink && this.options.env == 'editor' && this.options.return_types != 1)) {
603                 html += '<tr'+le_style+'><td></td><td class="mdl-left"><input type="checkbox" id="linkexternal-'+client_id+'" value="" '+le_checked+' />'+M.str.repository.linkexternal+'</td></tr>';
604             }
606             if (!args.hasauthor) {
607                 // the author of the file
608                 html += '<tr><td class="mdl-right"><label for="text-author">'+M.str.repository.author+' :</label></td>';
609                 html += '<td class="mdl-left"><input id="text-author-'+client_id+'" type="text" name="author" value="'+this.options.author+'" /></td>';
610                 html += '</tr>';
611             }
613             if (!args.haslicense) {
614                 // the license of the file
615                 var licenses = this.options.licenses;
616                 html += '<tr><td class="mdl-right"><label for="select-license-'+client_id+'">'+M.str.repository.chooselicense+' :</label></td>';
617                 html += '<td class="mdl-left"><select name="license" id="select-license-'+client_id+'">';
618                 var recentlicense = YAHOO.util.Cookie.get('recentlicense');
619                 if (recentlicense) {
620                     this.options.defaultlicense=recentlicense;
621                 }
622                 for (var i in licenses) {
623                     if (this.options.defaultlicense==licenses[i].shortname) {
624                         var selected = ' selected';
625                     } else {
626                         var selected = '';
627                     }
628                     html += '<option value="'+licenses[i].shortname+'"'+selected+'>'+licenses[i].fullname+'</option>';
629                 }
630                 html += '</select></td></tr>';
631             }
632             html += '</table>';
634             html += '<p><input type="hidden" id="filesource-'+client_id+'" value="'+args.source+'" />';
635             html += '<input type="button" id="fp-confirm-'+client_id+'" value="'+M.str.repository.getfile+'" />';
636             html += '<input type="button" id="fp-cancel-'+client_id+'" value="'+M.str.moodle.cancel+'" /></p>';
637             html += '</div>';
639             var getfile_form = Y.Node.create(html);
640             panel.appendChild(getfile_form);
642             var getfile = Y.one('#fp-confirm-'+client_id);
643             getfile.on('click', function(e) {
644                 var client_id = this.options.client_id;
645                 var scope = this;
646                 var repository_id = this.active_repo.id;
647                 var title = Y.one('#newname-'+client_id).get('value');
648                 var filesource = Y.one('#filesource-'+client_id).get('value');
649                 var params = {'title':title, 'source':filesource, 'savepath': this.options.savepath};
650                 var license = Y.one('#select-license-'+client_id);
651                 if (license) {
652                     params['license'] = license.get('value');
653                     YAHOO.util.Cookie.set('recentlicense', license.get('value'));
654                 }
655                 var author = Y.one('#text-author-'+client_id);
656                 if (author){
657                     params['author'] = author.get('value');
658                 }
660                 if (this.options.externallink && this.options.env == 'editor') {
661                     // in editor, images are stored in '/' only
662                     params.savepath = '/';
663                     // when image or media button is clicked
664                     if ( this.options.return_types != 1 ) {
665                         var linkexternal = Y.one('#linkexternal-'+client_id);
666                         if (linkexternal && linkexternal.get('checked')) {
667                             params['linkexternal'] = 'yes';
668                         }
669                     } else {
670                         // when link button in editor clicked
671                         params['linkexternal'] = 'yes';
672                     }
673                 }
675                 if (this.options.env == 'url') {
676                     params['linkexternal'] = 'yes';
677                 }
679                 this.wait('download', title);
680                 this.request({
681                     action:'download',
682                     client_id: client_id,
683                     repository_id: repository_id,
684                     'params': params,
685                     onerror: function(id, obj, args) {
686                         scope.view_files();
687                     },
688                     callback: function(id, obj, args) {
689                         if (scope.options.editor_target && scope.options.env=='editor') {
690                             scope.options.editor_target.value=obj.url;
691                             scope.options.editor_target.onchange();
692                         }
693                         scope.hide();
694                         obj.client_id = client_id;
695                         var formcallback_scope = null;
696                         if (args.scope.options.magicscope) {
697                             formcallback_scope = args.scope.options.magicscope;
698                         } else {
699                             formcallback_scope = args.scope;
700                         }
701                         scope.options.formcallback.apply(formcallback_scope, [obj]);
702                     }
703                 }, true);
704             }, this);
705             var elform = Y.one('#'+form_id);
706             elform.on('keydown', function(e) {
707                 if (e.keyCode == 13) {
708                     getfile.simulate('click');
709                     e.preventDefault();
710                 }
711             }, this);
712             var cancel = Y.one('#fp-cancel-'+client_id);
713             cancel.on('click', function(e) {
714                 this.view_files();
715             }, this);
716             var treeview = Y.one('#treeview-'+client_id);
717             if (treeview){
718                 treeview.setStyle('display', 'none');
719             }
720         },
721         wait: function(type) {
722             var panel = Y.one('#panel-'+this.options.client_id);
723             panel.set('innerHTML', '');
724             var name = '';
725             var str = '<div style="text-align:center">';
726             if(type=='load') {
727                 str += '<img src="'+M.util.image_url('i/loading')+'" />';
728                 str += '<p>'+M.str.repository.loading+'</p>';
729             }else{
730                 str += '<img src="'+M.util.image_url('i/progressbar')+'" />';
731                 str += '<p>'+M.str.repository.copying+' <strong>'+name+'</strong></p>';
732             }
733             str += '</div>';
734             try {
735                 panel.set('innerHTML', str);
736             } catch(e) {
737                 alert(e.toString());
738             }
739         },
740         render: function() {
741             var client_id = this.options.client_id;
742             var scope = this;
743             var filepicker_id = 'filepicker-'+client_id;
744             var fpnode = Y.Node.create('<div class="file-picker" id="'+filepicker_id+'"></div>');
745             Y.one(document.body).appendChild(fpnode);
746             // render file picker panel
747             this.mainui = new YAHOO.widget.Panel(filepicker_id, {
748                 draggable: true,
749                 close: true,
750                 underlay: 'none',
751                 zindex: 9999990,
752                 monitorresize: false,
753                 xy: [50, YAHOO.util.Dom.getDocumentScrollTop()+20]
754             });
755             var layout = null;
756             this.mainui.beforeRenderEvent.subscribe(function() {
757                 YAHOO.util.Event.onAvailable('layout-'+client_id, function() {
758                     layout = new YAHOO.widget.Layout('layout-'+client_id, {
759                         height: 480, width: 700,
760                         units: [
761                         {position: 'top', height: 32, resize: false,
762                         body:'<div class="yui-buttongroup fp-viewbar" id="fp-viewbar-'+client_id+'"></div><div class="fp-searchbar" id="search-div-'+client_id+'"></div>', gutter: '2'},
763                         {position: 'left', width: 200, resize: true, scroll:true,
764                         body:'<ul class="fp-list" id="fp-list-'+client_id+'"></ul>', gutter: '0 5 0 2', minWidth: 150, maxWidth: 300 },
765                         {position: 'center', body: '<div class="fp-panel" id="panel-'+client_id+'"></div>',
766                         scroll: true, gutter: '0 2 0 0' }
767                         ]
768                     });
769                     layout.render();
770                     scope.show_recent_repository();
771                 });
772             });
774             this.mainui.setHeader(M.str.repository.filepicker);
775             this.mainui.setBody('<div id="layout-'+client_id+'"></div>');
776             this.mainui.render();
777             this.rendered = true;
779             var scope = this;
780             // adding buttons
781             var view_icons = {label: M.str.repository.iconview, value: 't', 'checked': true,
782                 onclick: {
783                     fn: function(){
784                         scope.view_as_icons();
785                     }
786                 }
787             };
788             var view_listing = {label: M.str.repository.listview, value: 'l',
789                 onclick: {
790                     fn: function(){
791                         scope.view_as_list();
792                     }
793                 }
794             };
795             this.viewbar = new YAHOO.widget.ButtonGroup({
796                 id: 'btngroup-'+client_id,
797                 name: 'buttons',
798                 disabled: true,
799                 container: 'fp-viewbar-'+client_id
800             });
801             this.viewbar.addButtons([view_icons, view_listing]);
802             // processing repository listing
803             var r = this.options.repositories;
804             Y.on('contentready', function(el) {
805                 var list = Y.one(el);
806                 var count = 0;
807                 // Resort the repositories by sortorder
808                 var sorted_repositories = new Array();
809                 for (var i in r) {
810                     sorted_repositories[r[i].sortorder - 1] = r[i];
811                 }
812                 for (var i in sorted_repositories){
813                     repository = sorted_repositories[i];
814                     var id = 'repository-'+client_id+'-'+repository.id;
815                     var link_id = id + '-link';
816                     list.append('<li id="'+id+'"><a class="fp-repo-name" id="'+link_id+'" href="###">'+repository.name+'</a></li>');
817                     Y.one('#'+link_id).prepend('<img src="'+repository.icon+'" width="16" height="16" />&nbsp;');
818                     Y.one('#'+link_id).on('click', function(e, scope, repository_id) {
819                         YAHOO.util.Cookie.set('recentrepository', repository_id);
820                         scope.repository_id = repository_id;
821                         this.list({'repo_id':repository_id});
822                     }, this /*handler running scope*/, this/*second argument*/, repository.id/*third argument of handler*/);
823                     count++;
824                 }
825                 if (count==0) {
826                     if (this.options.externallink) {
827                         list.set('innerHTML', M.str.repository.norepositoriesexternalavailable);
828                     } else {
829                         list.set('innerHTML', M.str.repository.norepositoriesavailable);
830                     }
831                 }
832             }, '#fp-list-'+client_id, this /* handler running scope */, '#fp-list-'+client_id /*first argument of handler*/);
833         },
834         parse_repository_options: function(data) {
835             this.filelist = data.list?data.list:null;
836             this.filepath = data.path?data.path:null;
837             this.active_repo = {};
838             this.active_repo.issearchresult = Boolean(data.issearchresult);
839             this.active_repo.dynload = data.dynload?data.dynload:false;
840             this.active_repo.pages = Number(data.pages?data.pages:null);
841             this.active_repo.page = Number(data.page?data.page:null);
842             this.active_repo.id = data.repo_id?data.repo_id:null;
843             this.active_repo.nosearch = data.nosearch?true:false;
844             this.active_repo.norefresh = data.norefresh?true:false;
845             this.active_repo.nologin = data.nologin?true:false;
846             this.active_repo.logouttext = data.logouttext?data.logouttext:null;
847             this.active_repo.help = data.help?data.help:null;
848             this.active_repo.manage = data.manage?data.manage:null;
849         },
850         print_login: function(data) {
851             this.parse_repository_options(data);
852             var client_id = this.options.client_id;
853             var repository_id = data.repo_id;
854             var l = this.logindata = data.login;
855             var loginurl = '';
856             var panel = Y.one('#panel-'+client_id);
857             var action = 'login';
858             if (data['login_btn_action']) {
859                 action=data['login_btn_action'];
860             }
861             var form_id = 'fp-form-'+client_id;
862             var download_button_id = 'fp-form-download-button-'+client_id;
863             var search_button_id   = 'fp-form-search-button-'+client_id;
864             var login_button_id    = 'fp-form-login-button-'+client_id;
865             var popup_button_id    = 'fp-form-popup-button-'+client_id;
867             var str = '<div class="fp-login-form">';
868             str += '<form id="'+form_id+'">';
869             var has_pop = false;
870             str +='<table width="100%">';
871             for(var k in l) {
872                 str +='<tr>';
873                 if(l[k].type=='popup') {
874                     // pop element
875                     loginurl = l[k].url;
876                     str += '<td colspan="2"><p class="fp-popup">'+M.str.repository.popup+'</p>';
877                     str += '<p class="fp-popup"><button id="'+popup_button_id+'">'+M.str.repository.login+'</button>';
878                     str += '</p></td>';
879                     action = 'popup';
880                 }else if(l[k].type=='textarea') {
881                     // textarea element
882                     str += '<td colspan="2"><p><textarea id="'+l[k].id+'" name="'+l[k].name+'"></textarea></p></td>';
883                 }else if(l[k].type=='select') {
884                     // select element
885                     str += '<td align="right"><label>'+l[k].label+':</label></td>';
886                     str += '<td align="left"><select id="'+l[k].id+'" name="'+l[k].name+'">';
887                     for (i in l[k].options) {
888                         str += '<option value="'+l[k].options[i].value+'">'+l[k].options[i].label+'</option>';
889                     }
890                     str += '</select></td>';
891                 }else{
892                     // input element
893                     var label_id = '';
894                     var field_id = '';
895                     var field_value = '';
896                     if(l[k].id) {
897                         label_id = ' for="'+l[k].id+'"';
898                         field_id = ' id="'+l[k].id+'"';
899                     }
900                     if (l[k].label) {
901                         str += '<td align="right" width="30%" valign="center">';
902                         str += '<label'+label_id+'>'+l[k].label+'</label> </td>';
903                     } else {
904                         str += '<td width="30%"></td>';
905                     }
906                     if(l[k].value) {
907                         field_value = ' value="'+l[k].value+'"';
908                     }
909                     if(l[k].type=='radio'){
910                         var list = l[k].value.split('|');
911                         var labels = l[k].value_label.split('|');
912                         str += '<td align="left">';
913                         for(var item in list) {
914                             str +='<input type="'+l[k].type+'"'+' name="'+l[k].name+'"'+
915                                 field_id+' value="'+list[item]+'" />'+labels[item]+'<br />';
916                         }
917                         str += '</td>';
918                     }else{
919                         str += '<td align="left">';
920                         str += '<input type="'+l[k].type+'"'+' name="'+l[k].name+'"'+field_value+' '+field_id+' />';
921                         str += '</td>';
922                     }
923                 }
924                 str +='</tr>';
925             }
926             str +='</table>';
927             str += '</form>';
929             // custom lable text
930             var btn_label = data['login_btn_label']?data['login_btn_label']:M.str.repository.submit;
931             if (action != 'popup') {
932                 str += '<p><input type="button" id="';
933                 switch (action) {
934                     case 'search':
935                         str += search_button_id;
936                         break;
937                     case 'download':
938                         str += download_button_id;
939                         break;
940                     default:
941                         str += login_button_id;
942                         break;
943                 }
944                 str += '" value="'+btn_label+'" /></p>';
945             }
947             str += '</div>';
949             // insert login form
950             try {
951                 panel.set('innerHTML', str);
952             } catch(e) {
953                 alert(M.str.repository.xhtmlerror);
954             }
955             // register buttons
956             // process login action
957             var login_button = Y.one('#'+login_button_id);
958             var scope = this;
959             if (login_button) {
960                 login_button.on('click', function(){
961                     // collect form data
962                     var data = this.logindata;
963                     var scope = this;
964                     var params = {};
965                     for (var k in data) {
966                         if(data[k].type!='popup') {
967                             var el = Y.one('[name='+data[k].name+']');
968                             var type = el.get('type');
969                             params[data[k].name] = '';
970                             if(type == 'checkbox') {
971                                 params[data[k].name] = el.get('checked');
972                             } else {
973                                 params[data[k].name] = el.get('value');
974                             }
975                         }
976                     }
977                     // start ajax request
978                     this.request({
979                         'params': params,
980                         'scope': scope,
981                         'action':'signin',
982                         'path': '',
983                         'client_id': client_id,
984                         'repository_id': repository_id,
985                         'callback': function(id, o, args) {
986                             scope.parse_repository_options(o);
987                             scope.view_files();
988                         }
989                     }, true);
990                 }, this);
991             }
992             var search_button = Y.one('#'+search_button_id);
993             if (search_button) {
994                 search_button.on('click', function(){
995                     var data = this.logindata;
996                     var params = {};
998                     for (var k in data) {
999                         if(data[k].type!='popup') {
1000                             var el = document.getElementsByName(data[k].name)[0];
1001                             params[data[k].name] = '';
1002                             if(el.type == 'checkbox') {
1003                                 params[data[k].name] = el.checked;
1004                             } else if(el.type == 'radio') {
1005                                 var tmp = document.getElementsByName(data[k].name);
1006                                 for(var i in tmp) {
1007                                     if (tmp[i].checked) {
1008                                         params[data[k].name] = tmp[i].value;
1009                                     }
1010                                 }
1011                             } else {
1012                                 params[data[k].name] = el.value;
1013                             }
1014                         }
1015                     }
1016                     this.request({
1017                             scope: scope,
1018                             action:'search',
1019                             client_id: client_id,
1020                             repository_id: repository_id,
1021                             form: {id: 'fp-form-'+scope.options.client_id,upload:false,useDisabled:true},
1022                             callback: function(id, o, args) {
1023                                 o.issearchresult = true;
1024                                 scope.parse_repository_options(o);
1025                                 scope.view_files();
1026                             }
1027                     }, true);
1028                 }, this);
1029             }
1030             var download_button = Y.one('#'+download_button_id);
1031             if (download_button) {
1032                 download_button.on('click', function(){
1033                     alert('download');
1034                 });
1035             }
1036             var popup_button = Y.one('#'+popup_button_id);
1037             if (popup_button) {
1038                 popup_button.on('click', function(e){
1039                     M.core_filepicker.active_filepicker = this;
1040                     window.open(loginurl, 'repo_auth', 'location=0,status=0,width=500,height=300,scrollbars=yes');
1041                     e.preventDefault();
1042                 }, this);
1043             }
1044             var elform = Y.one('#'+form_id);
1045             elform.on('keydown', function(e) {
1046                 if (e.keyCode == 13) {
1047                     switch (action) {
1048                         case 'search':
1049                             search_button.simulate('click');
1050                             break;
1051                         default:
1052                             login_button.simulate('click');
1053                             break;
1054                     }
1055                     e.preventDefault();
1056                 }
1057             }, this);
1059         },
1060         search: function(args) {
1061             var data = this.logindata;
1062             var params = {};
1064             for (var k in data) {
1065                 if(data[k].type!='popup') {
1066                     var el = document.getElementsByName(data[k].name)[0];
1067                     params[data[k].name] = '';
1068                     if(el.type == 'checkbox') {
1069                         params[data[k].name] = el.checked;
1070                     } else if(el.type == 'radio') {
1071                         var tmp = document.getElementsByName(data[k].name);
1072                         for(var i in tmp) {
1073                             if (tmp[i].checked) {
1074                                 params[data[k].name] = tmp[i].value;
1075                             }
1076                         }
1077                     } else {
1078                         params[data[k].name] = el.value;
1079                     }
1080                 }
1081             }
1082             this.request({
1083                     scope: scope,
1084                     action:'search',
1085                     client_id: client_id,
1086                     repository_id: repository_id,
1087                     form: {id: 'fp-form-'+scope.options.client_id,upload:false,useDisabled:true},
1088                     callback: function(id, o, args) {
1089                         o.issearchresult = true;
1090                         scope.parse_repository_options(o);
1091                         scope.view_files();
1092                     }
1093             }, true);
1094         },
1095         list: function(args) {
1096             var scope = this;
1097             if (!args) {
1098                 args = {};
1099             }
1100             if (!args.repo_id) {
1101                 args.repo_id = scope.active_repo.id;
1102             }
1103             scope.request({
1104                 action:'list',
1105                 client_id: scope.options.client_id,
1106                 repository_id: args.repo_id,
1107                 path:args.path?args.path:'',
1108                 page:args.page?args.page:'',
1109                 callback: function(id, obj, args) {
1110                     Y.all('#fp-list-'+scope.options.client_id+' li a').setStyle('backgroundColor', 'transparent');
1111                     var el = Y.one('#repository-'+scope.options.client_id+'-'+obj.repo_id+'-link');
1112                     if (el) {
1113                         el.setStyle('backgroundColor', '#AACCEE');
1114                     }
1115                     if (obj.login) {
1116                         scope.viewbar.set('disabled', true);
1117                         scope.print_login(obj);
1118                     } else if (obj.upload) {
1119                         scope.viewbar.set('disabled', true);
1120                         scope.parse_repository_options(obj);
1121                         scope.create_upload_form(obj);
1123                     } else if (obj.iframe) {
1125                     } else if (obj.list) {
1126                         obj.issearchresult = false;
1127                         scope.viewbar.set('disabled', false);
1128                         scope.parse_repository_options(obj);
1129                         scope.view_files();
1130                     }
1131                 }
1132             }, true);
1133         },
1134         create_upload_form: function(data) {
1135             var client_id = this.options.client_id;
1136             Y.one('#panel-'+client_id).set('innerHTML', '');
1137             var types = this.options.accepted_types;
1139             this.print_header();
1140             var id = data.upload.id+'_'+client_id;
1141             var str = '<div id="'+id+'_div" class="fp-upload-form mdl-align">';
1142             str += '<form id="'+id+'" enctype="multipart/form-data" method="POST">';
1143             str += '<table width="100%">';
1144             str += '<tr><td class="mdl-right">';
1145             str += '<label for="'+id+'_file">'+data.upload.label+': </label></td>';
1146             str += '<td class="mdl-left"><input type="file" id="'+id+'_file" name="repo_upload_file" />';
1147             str += '<tr><td class="mdl-right"><label for="newname-'+client_id+'">'+M.str.repository.saveas+':</label></td>';
1148             str += '<td class="mdl-left"><input type="text" name="title" id="newname-'+client_id+'" value="" /></td></tr>';
1149             str += '<input type="hidden" name="itemid" value="'+this.options.itemid+'" />';
1150             for (var i in types) {
1151                 str += '<input type="hidden" name="accepted_types[]" value="'+types[i]+'" />';
1152             }
1153             str += '</td></tr><tr>';
1154             str += '<td class="mdl-right"><label>'+M.str.repository.author+': </label></td>';
1155             str += '<td class="mdl-left"><input type="text" name="author" value="'+this.options.author+'" /></td>';
1156             str += '</tr>';
1157             str += '<tr>';
1158             str += '<td class="mdl-right">'+M.str.repository.chooselicense+': </td>';
1159             str += '<td class="mdl-left">';
1160             var licenses = this.options.licenses;
1161             str += '<select name="license" id="select-license-'+client_id+'">';
1162             var recentlicense = YAHOO.util.Cookie.get('recentlicense');
1163             if (recentlicense) {
1164                 this.options.defaultlicense=recentlicense;
1165             }
1166             for (var i in licenses) {
1167                 if (this.options.defaultlicense==licenses[i].shortname) {
1168                     var selected = ' selected';
1169                 } else {
1170                     var selected = '';
1171                 }
1172                 str += '<option value="'+licenses[i].shortname+'"'+selected+'>'+licenses[i].fullname+'</option>';
1173             }
1174             str += '</select>';
1175             str += '</td>';
1176             str += '</tr></table>';
1177             str += '</form>';
1178             str += '<div class="fp-upload-btn"><button id="'+id+'_action">'+M.str.repository.upload+'</button></div>';
1179             str += '</div>';
1180             var upload_form = Y.Node.create(str);
1181             Y.one('#panel-'+client_id).appendChild(upload_form);
1182             var scope = this;
1183             Y.one('#'+id+'_action').on('click', function(e) {
1184                 e.preventDefault();
1185                 var license = Y.one('#select-license-'+client_id).get('value');
1186                 YAHOO.util.Cookie.set('recentlicense', license);
1187                 if (!Y.one('#'+id+'_file').get('value')) {
1188                     scope.print_msg(M.str.repository.nofilesattached, 'error');
1189                     return false;
1190                 }
1191                 scope.request({
1192                         scope: scope,
1193                         action:'upload',
1194                         client_id: client_id,
1195                         params: {'savepath':scope.options.savepath},
1196                         repository_id: scope.active_repo.id,
1197                         form: {id: id, upload:true},
1198                         onerror: function(id, o, args) {
1199                             scope.create_upload_form(data);
1200                         },
1201                         callback: function(id, o, args) {
1202                             if (scope.options.editor_target&&scope.options.env=='editor') {
1203                                 scope.options.editor_target.value=o.url;
1204                                 scope.options.editor_target.onchange();
1205                             }
1206                             scope.hide();
1207                             o.client_id = client_id;
1208                             var formcallback_scope = null;
1209                             if (args.scope.options.magicscope) {
1210                                 formcallback_scope = args.scope.options.magicscope;
1211                             } else {
1212                                 formcallback_scope = args.scope;
1213                             }
1214                             scope.options.formcallback.apply(formcallback_scope, [o]);
1215                         }
1216                 }, true);
1217             }, this);
1218         },
1219         print_header: function() {
1220             var r = this.active_repo;
1221             var scope = this;
1222             var client_id = this.options.client_id;
1223             var repository_id = this.active_repo.id;
1224             var panel = Y.one('#panel-'+client_id);
1225             var str = '<div id="fp-header-'+client_id+'">';
1226             str += '<div class="fp-toolbar" id="repo-tb-'+client_id+'"></div>';
1227             str += '</div>';
1228             var head = Y.Node.create(str);
1229             panel.appendChild(head);
1230             //if(this.active_repo.pages < 8){
1231                 this.print_paging('header');
1232             //}
1234             var toolbar = Y.one('#repo-tb-'+client_id);
1236             if(!r.nosearch) {
1237                 var html = '<a href="###"><img src="'+M.util.image_url('a/search')+'" /> '+M.str.repository.search+'</a>';
1238                 var search = Y.Node.create(html);
1239                 search.on('click', function() {
1240                     scope.request({
1241                         scope: scope,
1242                         action:'searchform',
1243                         repository_id: repository_id,
1244                         callback: function(id, obj, args) {
1245                             var scope = args.scope;
1246                             var client_id = scope.options.client_id;
1247                             var repository_id = scope.active_repo.id;
1248                             var container = document.getElementById('fp-search-dlg');
1249                             if(container) {
1250                                 container.innerHTML = '';
1251                                 container.parentNode.removeChild(container);
1252                             }
1253                             var container = document.createElement('DIV');
1254                             container.id = 'fp-search-dlg';
1256                             var dlg_title = document.createElement('DIV');
1257                             dlg_title.className = 'hd';
1258                             dlg_title.innerHTML = M.str.repository.search;
1260                             var dlg_body = document.createElement('DIV');
1261                             dlg_body.className = 'bd';
1263                             var sform = document.createElement('FORM');
1264                             sform.method = 'POST';
1265                             sform.id = "fp-search-form";
1266                             sform.innerHTML = obj.form;
1268                             dlg_body.appendChild(sform);
1269                             container.appendChild(dlg_title);
1270                             container.appendChild(dlg_body);
1271                             Y.one(document.body).appendChild(container);
1272                             var search_dialog= null;
1273                             function dialog_handler() {
1274                                 scope.viewbar.set('disabled', false);
1275                                 scope.request({
1276                                         scope: scope,
1277                                         action:'search',
1278                                         client_id: client_id,
1279                                         repository_id: repository_id,
1280                                         form: {id: 'fp-search-form',upload:false,useDisabled:true},
1281                                         callback: function(id, o, args) {
1282                                             scope.parse_repository_options(o);
1283                                             scope.view_files();
1284                                         }
1285                                 }, true);
1286                                 search_dialog.cancel();
1287                             }
1288                             Y.one('#fp-search-form').on('keydown', function(e){
1289                                 if (e.keyCode == 13) {
1290                                     dialog_handler();
1291                                     e.preventDefault();
1292                                 }
1293                             }, this);
1295                             search_dialog = new YAHOO.widget.Dialog("fp-search-dlg", {
1296                                postmethod: 'async',
1297                                draggable: true,
1298                                width : "30em",
1299                                modal: true,
1300                                fixedcenter : true,
1301                                zindex: 9999991,
1302                                visible : false,
1303                                constraintoviewport : true,
1304                                buttons: [
1305                                {
1306                                    text:M.str.repository.submit,
1307                                    handler:dialog_handler,
1308                                    isDefault:true
1309                                }, {
1310                                    text:M.str.moodle.cancel,
1311                                    handler:function(){
1312                                        this.destroy()
1313                                    }
1314                                }]
1315                             });
1316                             search_dialog.render();
1317                             search_dialog.show();
1318                         }
1319                     });
1320                 },this);
1321                 toolbar.appendChild(search);
1322             }
1323             // weather we use cache for this instance, this button will reload listing anyway
1324             if(!r.norefresh) {
1325                 var html = '<a href="###"><img src="'+M.util.image_url('a/refresh')+'" /> '+M.str.repository.refresh+'</a>';
1326                 var refresh = Y.Node.create(html);
1327                 refresh.on('click', function() {
1328                     this.list();
1329                 }, this);
1330                 toolbar.appendChild(refresh);
1331             }
1332             if(!r.nologin) {
1333                 var label = r.logouttext?r.logouttext:M.str.repository.logout;
1334                 var html = '<a href="###"><img src="'+M.util.image_url('a/logout')+'" /> '+label+'</a>';
1335                 var logout = Y.Node.create(html);
1336                 logout.on('click', function() {
1337                     this.request({
1338                         action:'logout',
1339                         client_id: client_id,
1340                         repository_id: repository_id,
1341                         path:'',
1342                         callback: function(id, obj, args) {
1343                             scope.viewbar.set('disabled', true);
1344                             scope.print_login(obj);
1345                         }
1346                     }, true);
1347                 }, this);
1348                 toolbar.appendChild(logout);
1349             }
1351             if(r.manage) {
1352                 var mgr = document.createElement('A');
1353                 mgr.href = r.manage;
1354                 mgr.target = "_blank";
1355                 mgr.innerHTML = '<img src="'+M.util.image_url('a/setting')+'" /> '+M.str.repository.manageurl;
1356                 toolbar.appendChild(mgr);
1357             }
1358             if(r.help) {
1359                 var help = document.createElement('A');
1360                 help.href = r.help;
1361                 help.target = "_blank";
1362                 help.innerHTML = '<img src="'+M.util.image_url('a/help')+'" /> '+M.str.repository.help;
1363                 toolbar.appendChild(help);
1364             }
1366             this.print_path();
1367         },
1368         get_page_button: function(page) {
1369             var r = this.active_repo;
1370             var css = '';
1371             if (page == r.page) {
1372                 css = 'class="cur_page" ';
1373             }
1374             var str = '<a '+css+'href="###" id="repo-page-'+page+'">';
1375             return str;
1376         },
1377         print_paging: function(html_id) {
1378             var client_id = this.options.client_id;
1379             var scope = this;
1380             var r = this.active_repo;
1381             var str = '';
1382             var action = '';
1383             var lastpage = r.pages;
1384             var lastpagetext = r.pages;
1385             if (r.pages == -1) {
1386                 lastpage = r.page + 1;
1387                 lastpagetext = M.str.moodle.next;
1388             }
1389             if (lastpage > 1) {
1390                 str += '<div class="fp-paging" id="paging-'+html_id+'-'+client_id+'">';
1391                 str += this.get_page_button(1)+'1</a> ';
1393                 var span = 5;
1394                 var ex = (span-1)/2;
1396                 if (r.page+ex>=lastpage) {
1397                     var max = lastpage;
1398                 } else {
1399                     if (r.page<span) {
1400                         var max = span;
1401                     } else {
1402                         var max = r.page+ex;
1403                     }
1404                 }
1406                 // won't display upper boundary
1407                 if (r.page >= span) {
1408                     str += ' ... ';
1409                     for(var i=r.page-ex; i<max; i++) {
1410                         str += this.get_page_button(i);
1411                         str += String(i);
1412                         str += '</a> ';
1413                     }
1414                 } else {
1415                     // this very first elements
1416                     for(var i = 2; i < max; i++) {
1417                         str += this.get_page_button(i);
1418                         str += String(i);
1419                         str += '</a> ';
1420                     }
1421                 }
1423                 // won't display upper boundary
1424                 if (max==lastpage) {
1425                     str += this.get_page_button(lastpage)+lastpagetext+'</a>';
1426                 } else {
1427                     str += this.get_page_button(max)+max+'</a>';
1428                     str += ' ... '+this.get_page_button(lastpage)+lastpagetext+'</a>';
1429                 }
1430                 str += '</div>';
1431             }
1432             if (str) {
1433                 var a = Y.Node.create(str);
1434                 Y.one('#fp-header-'+client_id).appendChild(a);
1436                 Y.all('#fp-header-'+client_id+' .fp-paging a').each(
1437                     function(node, id) {
1438                         node.on('click', function(e) {
1439                             var id = node.get('id');
1440                             var re = new RegExp("repo-page-(\\d+)", "i");
1441                             var result = id.match(re);
1442                             var args = {};
1443                             args.page = result[1];
1444                             if (scope.active_repo.issearchresult) {
1445                                 scope.request({
1446                                         scope: scope,
1447                                         action:'search',
1448                                         client_id: client_id,
1449                                         repository_id: r.id,
1450                                         params: {'page':result[1]},
1451                                         callback: function(id, o, args) {
1452                                             o.issearchresult = true;
1453                                             scope.parse_repository_options(o);
1454                                             scope.view_files(result[1]);
1455                                         }
1456                                 }, true);
1458                             } else {
1459                                 if (scope.viewmode == 2) {
1460                                     scope.view_as_list(result[1]);
1461                                 } else {
1462                                     scope.list(args);
1463                                 }
1464                             }
1465                         });
1466                     });
1467             }
1468         },
1469         print_path: function() {
1470             var client_id = this.options.client_id;
1471             var panel = Y.one('#panel-'+client_id);
1472             var p = this.filepath;
1473             if (p && p.length!=0) {
1474                 var path = Y.Node.create('<div id="path-'+client_id+'" class="fp-pathbar"></div>');
1475                 panel.appendChild(path);
1476                 for(var i = 0; i < p.length; i++) {
1477                     var link_path = p[i].path;
1478                     var link = document.createElement('A');
1479                     link.href = "###";
1480                     link.innerHTML = p[i].name;
1481                     link.id = 'path-node-'+client_id+'-'+i;
1482                     var sep = Y.Node.create('<span>/</span>');
1483                     path.appendChild(link);
1484                     path.appendChild(sep);
1485                     Y.one('#'+link.id).on('click', function(Y, path){
1486                         this.list({'path':path});
1487                         }, this, link_path)
1488                 }
1489             }
1490         },
1491         hide: function() {
1492             this.mainui.hide();
1493         },
1494         show: function() {
1495             if (this.rendered) {
1496                 var panel = Y.one('#panel-'+this.options.client_id);
1497                 panel.set('innerHTML', '');
1498                 this.mainui.show();
1499                 this.show_recent_repository();
1500             } else {
1501                 this.launch();
1502             }
1503         },
1504         launch: function() {
1505             this.render();
1506         },
1507         show_recent_repository: function() {
1508             var repository_id = YAHOO.util.Cookie.get('recentrepository');
1509             if (this.options.repositories[repository_id]) {
1510                 this.list({'repo_id':repository_id});
1511             }
1512         }
1513     });
1514     var loading = Y.one('#filepicker-loading-'+options.client_id);
1515     if (loading) {
1516         loading.setStyle('display', 'none');
1517     }
1518     M.core_filepicker.instances[options.client_id] = new FilePickerHelper(options);