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