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