Proyectos de Subversion Moodle

Rev

Ir a la última revisión | | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
/**
16
 *
17
 * File Manager UI
18
 * =====
19
 * this.api, stores the URL to make ajax request
20
 * this.currentpath
21
 * this.filepicker_options
22
 * this.movefile_dialog
23
 * this.mkdir_dialog
24
 * this.rename_dialog
25
 * this.client_id
26
 * this.filecount, how many files in this filemanager
27
 * this.maxfiles
28
 * this.maxbytes
29
 * this.areamaxbytes, the maximum size of the area
30
 * this.filemanager, contains reference to filemanager Node
31
 * this.selectnode, contains referenct to select-file Node
32
 * this.selectui, M.core.dialogue to select the file
33
 * this.viewmode, contains current view mode - icons, tree or details
34
 *
35
 * FileManager options:
36
 * =====
37
 * this.options.currentpath
38
 * this.options.itemid
39
 */
40
 
41
/* eslint camelcase: off */
42
 
43
M.form_filemanager = {
44
    templates: {},
45
    formChangeChecker: null,
46
};
47
 
48
require(['core_form/changechecker'], function(FormChangeChecker) {
49
    // This is a nasty, hacky, way of doing it but it's the smallest evil.
50
    M.form_filemanager.formChangeChecker = FormChangeChecker;
51
});
52
 
53
M.form_filemanager.set_templates = function(Y, templates) {
54
    M.form_filemanager.templates = templates;
55
};
56
 
57
/**
58
 * This fucntion is called for each file picker on page.
59
 */
60
M.form_filemanager.init = function(Y, options) {
61
    var FileManagerHelper = function(options) {
62
        FileManagerHelper.superclass.constructor.apply(this, arguments);
63
    };
64
    FileManagerHelper.NAME = "FileManager";
65
    FileManagerHelper.ATTRS = {
66
        options: {},
67
        lang: {}
68
    };
69
 
70
    Y.extend(FileManagerHelper, Y.Base, {
71
        api: M.cfg.wwwroot+'/repository/draftfiles_ajax.php',
72
        menus: {},
73
        initializer: function(options) {
74
            this.options = options;
75
            if (options.mainfile) {
76
                this.enablemainfile = options.mainfile;
77
            }
78
            this.client_id = options.client_id;
79
            this.currentpath = '/';
80
            this.maxfiles = options.maxfiles;
81
            this.maxbytes = options.maxbytes;
82
            this.areamaxbytes = options.areamaxbytes;
83
            this.userprefs = options.userprefs;
84
            this.emptycallback = null; // Used by drag and drop upload
85
 
86
            this.filepicker_options = options.filepicker?options.filepicker:{};
87
            this.filepicker_options.client_id = this.client_id;
88
            this.filepicker_options.context = options.context;
89
            this.filepicker_options.maxfiles = this.maxfiles;
90
            this.filepicker_options.maxbytes = this.maxbytes;
91
            this.filepicker_options.areamaxbytes = this.areamaxbytes;
92
            this.filepicker_options.env = 'filemanager';
93
            this.filepicker_options.itemid = options.itemid;
94
 
95
            if (options.filecount) {
96
                this.filecount = options.filecount;
97
            } else {
98
                this.filecount = 0;
99
            }
100
            // prepare filemanager for drag-and-drop upload
101
            this.filemanager = Y.one('#filemanager-'+options.client_id);
102
            if (this.filemanager.hasClass('filemanager-container') || !this.filemanager.one('.filemanager-container')) {
103
                this.dndcontainer = this.filemanager;
104
            } else  {
105
                this.dndcontainer = this.filemanager.one('.filemanager-container');
106
                if (!this.dndcontainer.get('id')) {
107
                    this.dndcontainer.generateID();
108
                }
109
            }
110
            // save template for one path element and location of path bar
111
            if (this.filemanager.one('.fp-path-folder')) {
112
                this.pathnode = this.filemanager.one('.fp-path-folder');
113
                this.pathbar = this.pathnode.get('parentNode');
114
                this.pathbar.removeChild(this.pathnode);
115
            }
116
            // initialize 'select file' panel
117
            this.selectnode = Y.Node.create(M.form_filemanager.templates.fileselectlayout);
118
            this.selectnode.setAttribute('aria-live', 'assertive');
119
            this.selectnode.setAttribute('role', 'dialog');
120
            this.selectnode.generateID();
121
 
122
            var labelid = 'fm-dialog-label_'+ this.selectnode.get('id');
123
            this.selectui = new M.core.dialogue({
124
                draggable    : true,
125
                headerContent: '<h3 id="' + labelid +'">' + M.util.get_string('edit', 'moodle') + '</h3>',
126
                bodyContent  : this.selectnode,
127
                centered     : true,
128
                width        : '480px',
129
                modal        : true,
130
                visible      : false
131
            });
132
            Y.one('#'+this.selectnode.get('id')).setAttribute('aria-labelledby', labelid);
133
            this.selectui.hide();
134
            this.setup_select_file();
135
            // setup buttons onclick events
136
            this.setup_buttons();
137
            // set event handler for lazy loading of thumbnails
138
            this.filemanager.one('.fp-content').on(['scroll','resize'], this.content_scrolled, this);
139
            // display files
140
            this.viewmode = this.get_preference("recentviewmode");
141
            if (this.viewmode != 2 && this.viewmode != 3) {
142
                this.viewmode = 1;
143
            }
144
            var viewmodeselectors = {'1': '.fp-vb-icons', '2': '.fp-vb-tree', '3': '.fp-vb-details'};
145
            this.filemanager.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').removeClass('checked');
146
            this.filemanager.all(viewmodeselectors[this.viewmode]).addClass('checked');
147
            this.refresh(this.currentpath); // MDL-31113 get latest list from server
148
        },
149
 
150
        wait: function() {
151
           this.filemanager.addClass('fm-updating');
152
        },
153
        request: function(args, redraw) {
154
            var api = this.api + '?action='+args.action;
155
            var params = {};
156
            var scope = this;
157
            if (args['scope']) {
158
                scope = args['scope'];
159
            }
160
            params['sesskey'] = M.cfg.sesskey;
161
            params['client_id'] = this.client_id;
162
            params['filepath'] = this.currentpath;
163
            params['itemid'] = this.options.itemid?this.options.itemid:0;
164
            if (args['params']) {
165
                for (i in args['params']) {
166
                    params[i] = args['params'][i];
167
                }
168
            }
169
            var cfg = {
170
                method: 'POST',
171
                on: {
172
                    complete: function(id,o,p) {
173
                        if (!o) {
174
                            alert('IO FATAL');
175
                            return;
176
                        }
177
                        var data = null;
178
                        try {
179
                            data = Y.JSON.parse(o.responseText);
180
                        } catch(e) {
181
                            scope.print_msg(M.util.get_string('invalidjson', 'repository'), 'error');
182
                            Y.error(M.util.get_string('invalidjson', 'repository')+":\n"+o.responseText);
183
                            return;
184
                        }
185
                        if (data && data.tree && scope.set_current_tree) {
186
                            scope.set_current_tree(data.tree);
187
                        }
188
                        args.callback(id,data,p);
189
                    }
190
                },
191
                arguments: {
192
                    scope: scope
193
                },
194
                headers: {
195
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
196
                },
197
                data: build_querystring(params)
198
            };
199
            if (args.form) {
200
                cfg.form = args.form;
201
            }
202
            Y.io(api, cfg);
203
            if (redraw) {
204
                this.wait();
205
            }
206
        },
207
        filepicker_callback: function(obj) {
208
            this.filecount++;
209
            this.check_buttons();
210
            this.refresh(this.currentpath);
211
            M.form_filemanager.formChangeChecker.markFormChangedFromNode(this.filemanager.getDOMNode());
212
 
213
            require(['core_form/events'], function(FormEvent) {
214
                FormEvent.notifyUploadChanged(this.filemanager.get('id'));
215
            }.bind(this));
216
        },
217
        check_buttons: function() {
218
            if (this.filecount>0) {
219
                this.filemanager.removeClass('fm-nofiles');
220
            } else {
221
                this.filemanager.addClass('fm-nofiles');
222
            }
223
            if (this.filecount >= this.maxfiles && this.maxfiles!=-1) {
224
                this.filemanager.addClass('fm-maxfiles');
225
            }
226
            else {
227
                this.filemanager.removeClass('fm-maxfiles');
228
            }
229
        },
230
        refresh: function(filepath, action) {
231
            var scope = this;
232
            this.currentpath = filepath;
233
            if (!filepath) {
234
                filepath = this.currentpath;
235
            } else {
236
                this.currentpath = filepath;
237
            }
238
            this.request({
239
                action: 'list',
240
                scope: scope,
241
                params: {'filepath':filepath},
242
                callback: function(id, obj, args) {
243
                    scope.filecount = obj.filecount;
244
                    scope.options = obj;
245
                    scope.lazyloading = {};
246
                    scope.check_buttons();
247
                    scope.render(obj, action);
248
                }
249
            }, true);
250
        },
251
        /** displays message in a popup */
252
        print_msg: function(msg, type, options) {
253
            var header = M.util.get_string('error', 'moodle');
254
            if (type != 'error') {
255
                type = 'info'; // one of only two types excepted
256
                header = M.util.get_string('info', 'moodle');
257
            }
258
            if (!this.msg_dlg) {
259
                this.msg_dlg_node = Y.Node.create(M.form_filemanager.templates.message);
260
                var nodeid = this.msg_dlg_node.generateID();
261
                var previousActiveElement = null;
262
                if (typeof options.previousActiveElement != 'undefined') {
263
                    previousActiveElement = options.previousActiveElement;
264
                }
265
                this.msg_dlg = new M.core.dialogue({
266
                    draggable    : true,
267
                    bodyContent  : this.msg_dlg_node,
268
                    centered     : true,
269
                    modal        : true,
270
                    visible      : false,
271
                    focusAfterHide: previousActiveElement,
272
                });
273
                this.msg_dlg_node.one('.fp-msg-butok').on('click', function(e) {
274
                    e.preventDefault();
275
                    this.msg_dlg.hide();
276
                }, this);
277
            }
278
 
279
            this.msg_dlg.set('headerContent', header);
280
            this.msg_dlg_node.removeClass('fp-msg-info').removeClass('fp-msg-error').addClass('fp-msg-'+type)
281
            this.msg_dlg_node.one('.fp-msg-text').setContent(Y.Escape.html(msg));
282
            this.msg_dlg.show();
283
        },
284
        is_disabled: function() {
285
            return this.filemanager.ancestor('.fitem.disabled') != null;
286
        },
287
        getSelectedFiles: function() {
288
            var markedFiles = this.filemanager.all('[data-togglegroup][data-toggle=slave]:checked');
289
            var filenames = [];
290
            markedFiles.each(function(item) {
291
                var fileinfo = this.options.list.find(function(element) {
292
                    return item.getData().fullname == element.fullname;
293
                });
294
                if (fileinfo && fileinfo != undefined) {
295
                    filenames.push({
296
                        filepath: fileinfo.filepath,
297
                        filename: fileinfo.filename
298
                    });
299
                }
300
            }, this);
301
 
302
            return filenames;
303
        },
304
        setup_buttons: function() {
305
            var button_download = this.filemanager.one('.fp-btn-download');
306
            var button_create   = this.filemanager.one('.fp-btn-mkdir');
307
            var button_addfile  = this.filemanager.one('.fp-btn-add');
308
            var buttonDeleteFile = this.filemanager.one('.fp-btn-delete');
309
 
310
            // setup 'add file' button
311
            button_addfile.on('click', this.show_filepicker, this);
312
 
313
            var dndarrow = this.filemanager.one('.dndupload-arrow');
314
            if (dndarrow) {
315
                dndarrow.on('click', this.show_filepicker, this);
316
            }
317
 
318
            // setup 'make a folder' button
319
            if (this.options.subdirs) {
320
                button_create.on('click',function(e) {
321
                    e.preventDefault();
322
                    if (this.is_disabled()) {
323
                        return;
324
                    }
325
                    var scope = this;
326
                    // a function used to perform an ajax request
327
                    var perform_action = function(e) {
328
                        e.preventDefault();
329
                        var foldername = Y.one('#fm-newname-'+scope.client_id).get('value');
330
                        if (!foldername) {
331
                            scope.mkdir_dialog.hide();
332
                            return;
333
                        }
334
                        scope.request({
335
                            action:'mkdir',
336
                            params: {filepath:scope.currentpath, newdirname:foldername},
337
                            callback: function(id, obj, args) {
338
                                var filepath = obj.filepath;
339
                                scope.mkdir_dialog.hide();
340
                                scope.refresh(filepath);
341
                                Y.one('#fm-newname-'+scope.client_id).set('value', '');
342
                                M.form_filemanager.formChangeChecker.markFormChangedFromNode(scope.filemanager.getDOMNode());
343
                            }
344
                        });
345
                    };
346
                    var validate_folder_name = function() {
347
                        var valid = false;
348
                        var foldername = Y.one('#fm-newname-'+scope.client_id).get('value');
349
                        if (foldername.length > 0) {
350
                            valid = true;
351
                        }
352
                        var btn = Y.one('#fm-mkdir-butcreate-'+scope.client_id);
353
                        if (btn) {
354
                            btn.set('disabled', !valid);
355
                        }
356
                        return valid;
357
                    };
358
                    if (!this.mkdir_dialog) {
359
                        var node = Y.Node.create(M.form_filemanager.templates.mkdir);
360
                        this.mkdir_dialog = new M.core.dialogue({
361
                            draggable    : true,
362
                            bodyContent  : node,
363
                            centered     : true,
364
                            modal        : true,
365
                            visible      : false,
366
                            focusAfterHide: e.target.ancestor('a', true),
367
                        });
368
                        node.one('.fp-dlg-butcreate').set('id', 'fm-mkdir-butcreate-'+this.client_id).on('click',
369
                                perform_action, this);
370
                        node.one('input').set('id', 'fm-newname-'+this.client_id).on('keydown', function(e) {
371
                            var valid = Y.bind(validate_folder_name, this)();
372
                            if (valid && e.keyCode === 13) {
373
                                Y.bind(perform_action, this)(e);
374
                            }
375
                        }, this);
376
                        node.one('#fm-newname-'+this.client_id).on(['keyup', 'change'], function(e) {
377
                            Y.bind(validate_folder_name, this)();
378
                        }, this);
379
 
380
                        node.one('label').set('for', 'fm-newname-' + this.client_id);
381
                        node.all('.fp-dlg-butcancel').on('click', function(e){e.preventDefault();this.mkdir_dialog.hide();}, this);
382
                        node.all('.fp-dlg-curpath').set('id', 'fm-curpath-'+this.client_id);
383
                    }
384
                    this.mkdir_dialog.show();
385
 
386
                    // Default folder name:
387
                    var foldername = M.util.get_string('newfolder', 'repository');
388
                    while (this.has_folder(foldername)) {
389
                        foldername = increment_filename(foldername, true);
390
                    }
391
                    Y.one('#fm-newname-'+scope.client_id).set('value', foldername);
392
                    Y.bind(validate_folder_name, this)();
393
                    Y.one('#fm-newname-'+scope.client_id).focus().select();
394
                    Y.all('#fm-curpath-'+scope.client_id).setContent(this.currentpath);
395
                }, this);
396
            } else {
397
                this.filemanager.addClass('fm-nomkdir');
398
            }
399
 
400
            // setup 'download this folder' button
401
            button_download.on('click',function(e) {
402
                e.preventDefault();
403
                if (this.is_disabled()) {
404
                    return;
405
                }
406
                var scope = this;
407
 
408
                var image_downloading = this.filemanager.one('.fp-img-downloading');
409
                if (image_downloading.getStyle('display') == 'inline') {
410
                    return;
411
                }
412
                image_downloading.setStyle('display', 'inline');
413
                var filenames = this.getSelectedFiles();
414
 
415
                // perform downloaddir ajax request
416
                this.request({
417
                    action: 'downloadselected',
418
                    scope: scope,
419
                    params: {selected: Y.JSON.stringify(filenames)},
420
                    callback: function(id, obj, args) {
421
                        var image_downloading = scope.filemanager.one('.fp-img-downloading');
422
                        image_downloading.setStyle('display', 'none');
423
 
424
                        if (obj) {
425
                            scope.refresh(obj.filepath);
426
                            node = Y.Node.create('<iframe></iframe>').setStyles({
427
                                visibility : 'hidden',
428
                                width : '1px',
429
                                height : '1px'
430
                            });
431
                            node.set('src', obj.fileurl);
432
                            Y.one('body').appendChild(node);
433
                        } else {
434
                            scope.print_msg(M.util.get_string('draftareanofiles', 'repository'), 'error');
435
                        }
436
                    }
437
                });
438
            }, this);
439
 
440
            buttonDeleteFile.on('click', function(e) {
441
                e.preventDefault();
442
                var dialogOptions = {};
443
                var filenames = this.getSelectedFiles();
444
                var previousActiveElement = e.target.ancestor('a', true);
445
 
446
                if (!filenames.length) {
447
                    var options = {};
448
                    options.previousActiveElement = previousActiveElement;
449
                    this.print_msg(M.util.get_string('nofilesselected', 'repository'), 'error', options);
450
                    return;
451
                }
452
 
453
                dialogOptions.scope = this;
454
                var params = {
455
                    selected: Y.JSON.stringify(filenames)
456
                };
457
                dialogOptions.header = M.util.get_string('confirm', 'moodle');
458
                dialogOptions.message = M.util.get_string('confirmdeleteselectedfile', 'repository', filenames.length);
459
                dialogOptions.previousActiveElement = previousActiveElement;
460
                dialogOptions.callbackargs = [params];
461
                dialogOptions.callback = function(params) {
462
                    this.request({
463
                        action: 'deleteselected',
464
                        scope: this,
465
                        params: params,
466
                        callback: function(id, obj, args) {
467
                            // Do something here
468
                            args.scope.filecount -= params.length;
469
                            if (obj && obj.length) {
470
                                args.scope.refresh(obj[0], {action: 'delete'});
471
                            }
472
                            M.form_filemanager.formChangeChecker.markFormChangedFromNode(this.scope.filemanager.getDOMNode());
473
 
474
                            require(['core_form/events'], function(FormEvent) {
475
                                FormEvent.notifyUploadChanged(this.scope.filemanager.get('id'));
476
                            }.bind(this));
477
                        }
478
                    });
479
                };
480
                this.show_confirm_dialog(dialogOptions);
481
            }, this);
482
 
483
            this.filemanager.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').
484
                on('click', function(e) {
485
                    e.preventDefault();
486
                    var viewbar = this.filemanager.one('.fp-viewbar')
487
                    if (!this.is_disabled() && (!viewbar || !viewbar.hasClass('disabled'))) {
488
                        this.filemanager.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').removeClass('checked')
489
                        if (e.currentTarget.hasClass('fp-vb-tree')) {
490
                            this.viewmode = 2;
491
                        } else if (e.currentTarget.hasClass('fp-vb-details')) {
492
                            this.viewmode = 3;
493
                        } else {
494
                            this.viewmode = 1;
495
                        }
496
                        e.currentTarget.addClass('checked')
497
                        this.render();
498
                        this.filemanager.one('.fp-content').setAttribute('tabIndex', '0');
499
                        this.filemanager.one('.fp-content').focus();
500
                        this.set_preference('recentviewmode', this.viewmode);
501
                    }
502
                }, this);
503
        },
504
 
505
        show_filepicker: function (e) {
506
            // if maxfiles == -1, the no limit
507
            e.preventDefault();
508
            if (this.is_disabled()) {
509
                return;
510
            }
511
            var options = this.filepicker_options;
512
            options.formcallback = this.filepicker_callback;
513
            // XXX: magic here, to let filepicker use filemanager scope
514
            options.magicscope = this;
515
            options.savepath = this.currentpath;
516
            options.previousActiveElement = e.target.ancestor('a', true);
517
            M.core_filepicker.show(Y, options);
518
        },
519
 
520
        print_path: function() {
521
            var p = this.options.path;
522
            this.pathbar.setContent('').addClass('empty');
523
            if (p && p.length!=0 && this.viewmode != 2) {
524
                for(var i = 0; i < p.length; i++) {
525
                    var el = this.pathnode.cloneNode(true);
526
                    this.pathbar.appendChild(el);
527
 
528
                    if (i == 0) {
529
                        el.addClass('first');
530
                    }
531
                    if (i == p.length-1) {
532
                        el.addClass('last');
533
                    }
534
 
535
                    if (i%2) {
536
                        el.addClass('even');
537
                    } else {
538
                        el.addClass('odd');
539
                    }
540
                    el.one('.fp-path-folder-name').setContent(Y.Escape.html(p[i].name)).
541
                        on('click', function(e, path) {
542
                            e.preventDefault();
543
                            if (!this.is_disabled()) {
544
                                this.refresh(path);
545
                            }
546
                        }, this, p[i].path);
547
                }
548
                this.pathbar.removeClass('empty');
549
            }
550
        },
551
        get_filepath: function(obj) {
552
            if (obj.path && obj.path.length) {
553
                return obj.path[obj.path.length-1].path;
554
            }
555
            return '';
556
        },
557
        treeview_dynload: function(node, cb) {
558
            var retrieved_children = {};
559
            if (node.children) {
560
                for (var i in node.children) {
561
                    retrieved_children[node.children[i].path] = node.children[i];
562
                }
563
            }
564
            if (!node.path || node.path == '/') {
565
                // this is a root pseudo folder
566
                node.fileinfo.filepath = '/';
567
                node.fileinfo.type = 'folder';
568
                node.fileinfo.fullname = node.fileinfo.title;
569
                node.fileinfo.filename = '.';
570
            }
571
            this.request({
572
                action:'list',
573
                params: {filepath:node.path?node.path:''},
574
                scope:this,
575
                callback: function(id, obj, args) {
576
                    var list = obj.list;
577
                    var scope = args.scope;
578
                    // check that user did not leave the view mode before recieving this response
579
                    if (!(scope.viewmode == 2 && node && node.getChildrenEl())) {
580
                        return;
581
                    }
582
                    if (cb != null) { // (in manual mode do not update current path)
583
                        scope.options = obj;
584
                        scope.currentpath = node.path?node.path:'/';
585
                    }
586
                    node.highlight(false);
587
                    node.origlist = obj.list ? obj.list : null;
588
                    node.origpath = obj.path ? obj.path : null;
589
                    node.children = [];
590
                    for(k in list) {
591
                        if (list[k].type == 'folder' && retrieved_children[list[k].filepath]) {
592
                            // if this child is a folder and has already been retrieved
593
                            retrieved_children[list[k].filepath].fileinfo = list[k];
594
                            node.children[node.children.length] = retrieved_children[list[k].filepath];
595
                        } else {
596
                            // append new file to the list
597
                            scope.view_files([list[k]]);
598
                        }
599
                    }
600
                    if (cb == null) {
601
                        node.refresh();
602
                    } else {
603
                        // invoke callback requested by TreeView component
604
                        cb();
605
                    }
606
                    scope.content_scrolled();
607
                }
608
            }, false);
609
        },
610
        content_scrolled: function(e) {
611
            setTimeout(Y.bind(function() {
612
                if (this.processingimages) {return;}
613
                this.processingimages = true;
614
                var scope = this,
615
                    fpcontent = this.filemanager.one('.fp-content'),
616
                    fpcontenty = fpcontent.getY(),
617
                    fpcontentheight = fpcontent.getStylePx('height'),
618
                    is_node_visible = function(node) {
619
                        var offset = node.getY()-fpcontenty;
620
                        if (offset <= fpcontentheight && (offset >=0 || offset+node.getStylePx('height')>=0)) {
621
                            return true;
622
                        }
623
                        return false;
624
                    };
625
                // replace src for visible images that need to be lazy-loaded
626
                if (scope.lazyloading) {
627
                    fpcontent.all('img').each( function(node) {
628
                        if (node.get('id') && scope.lazyloading[node.get('id')] && is_node_visible(node)) {
629
                            node.setImgRealSrc(scope.lazyloading);
630
                        }
631
                    });
632
                }
633
                this.processingimages = false;
634
            }, this), 200)
635
        },
636
        view_files: function(appendfiles, actionfiles) {
637
            this.filemanager.removeClass('fm-updating').removeClass('fm-noitems');
638
            if ((appendfiles == null) && (!this.options.list || this.options.list.length == 0) && this.viewmode != 2) {
639
                this.filemanager.addClass('fm-noitems');
640
                // This is used to focus after refreshing the list files is empty by deletion file action.
641
                if (actionfiles !== undefined && actionfiles.action == 'delete') {
642
                    this.filemanager.one('.fp-btn-add a').focus();
643
                }
644
                return;
645
            }
646
            var list = (appendfiles != null) ? appendfiles : this.options.list;
647
            var element_template;
648
            if (this.viewmode == 2 || this.viewmode == 3) {
649
                element_template = Y.Node.create(M.form_filemanager.templates.listfilename);
650
            } else {
651
                this.viewmode = 1;
652
                element_template = Y.Node.create(M.form_filemanager.templates.iconfilename);
653
            }
654
 
655
            if (this.viewmode == 1 || this.viewmode == 2) {
656
                this.filemanager.one('.fp-btn-delete').addClass('d-none');
657
            } else {
658
                this.filemanager.one('.fp-btn-delete').removeClass('d-none');
659
            }
660
            var options = {
661
                viewmode : this.viewmode,
662
                appendonly : appendfiles != null,
663
                filenode : element_template,
664
                disablecheckboxes: false,
665
                callbackcontext : this,
666
                callback : function(e, node) {
667
                    if (e.preventDefault) { e.preventDefault(); }
668
                    if (node.type == 'folder') {
669
                        this.refresh(node.filepath);
670
                    } else {
671
                        // This is used to focus on file after dialogue closed.
672
                        var previousActiveElement = e.target.ancestor('a', true);
673
                        this.options.previousActiveElement = previousActiveElement;
674
                        this.selectui.set('focusOnPreviousTargetAfterHide', true);
675
                        this.selectui.set('focusAfterHide', previousActiveElement);
676
                        this.select_file(node);
677
                    }
678
                },
679
                rightclickcallback : function(e, node) {
680
                    if (e.preventDefault) { e.preventDefault(); }
681
                    this.select_file(node);
682
                },
683
                classnamecallback : function(node) {
684
                    var classname = '';
685
                    if (node.type == 'folder' || (!node.type && !node.filename)) {
686
                        classname = classname + ' fp-folder';
687
                    }
688
                    if (node.filename || node.filepath || (node.path && node.path != '/')) {
689
                        classname = classname + ' fp-hascontextmenu';
690
                    }
691
                    if (node.isref) {
692
                        classname = classname + ' fp-isreference';
693
                    }
694
                    if (node.refcount) {
695
                        classname = classname + ' fp-hasreferences';
696
                    }
697
                    if (node.originalmissing) {
698
                        classname = classname + ' fp-originalmissing';
699
                    }
700
                    if (node.sortorder == 1) { classname = classname + ' fp-mainfile';}
701
                    return Y.Lang.trim(classname);
702
                }
703
            };
704
            if (this.viewmode == 2) {
705
                options.dynload = true;
706
                options.filepath = this.options.path;
707
                options.treeview_dynload = this.treeview_dynload;
708
                options.norootrightclick = true;
709
                options.callback = function(e, node) {
710
                    // TODO MDL-32736 e is not an event here but an object with properties 'event' and 'node'
711
                    if (!node.fullname) {return;}
712
                    if (node.type != 'folder') {
713
                        if (e.node.parent && e.node.parent.origpath) {
714
                            // set the current path
715
                            this.options.path = e.node.parent.origpath;
716
                            this.options.list = e.node.parent.origlist;
717
                            this.print_path();
718
                        }
719
                        this.currentpath = node.filepath;
720
                        var previousActiveElement = Y.Node(e.event.target).ancestor('a', true);
721
                        this.options.previousActiveElement = previousActiveElement;
722
                        this.selectui.set('focusOnPreviousTargetAfterHide', true);
723
                        this.selectui.set('focusAfterHide', previousActiveElement);
724
                        this.select_file(node);
725
                    } else {
726
                        // save current path and filelist (in case we want to jump to other viewmode)
727
                        this.options.path = e.node.origpath;
728
                        this.options.list = e.node.origlist;
729
                        this.currentpath = node.filepath;
730
                        this.print_path();
731
                        //this.content_scrolled();
732
                    }
733
                };
734
            }
735
            if (!this.lazyloading) {
736
                this.lazyloading={};
737
            }
738
            this.filemanager.one('.fp-content').fp_display_filelist(options, list, this.lazyloading);
739
            this.content_scrolled();
740
            // This is used to focus after refreshing the list files by update file and set main file action.
741
            if (actionfiles !== undefined) {
742
                if (actionfiles.action == 'updatefile' || actionfiles.action == 'setmainfile') {
743
                    var fileslist = this.filemanager.one('.fp-content');
744
                    fileslist.all('a').each(function(parentnode) {
745
                        parentnode.all('.fp-filename').each(function(childnode) {
746
                            if (childnode.get('innerHTML') == actionfiles.newfilename) {
747
                                parentnode.focus();
748
                            }
749
                        });
750
                    });
751
                }
752
                if (actionfiles.action == 'delete') {
753
                    this.filemanager.one('.fp-btn-delete a').focus();
754
                }
755
            }
756
        },
757
        populateLicensesSelect: function(licensenode, filenode) {
758
            if (!licensenode) {
759
                return;
760
            }
761
            licensenode.setContent('');
762
            var selectedlicense = this.filepicker_options.defaultlicense;
763
            if (filenode) {
764
                // File has a license already, use it.
765
                selectedlicense = filenode.license;
766
            } else if (this.filepicker_options.rememberuserlicensepref && this.get_preference('recentlicense')) {
767
                // When 'Remember user licence preference' is enabled use the last license selected by the user, if any.
768
                selectedlicense = this.get_preference('recentlicense');
769
            }
770
            var licenses = this.filepicker_options.licenses;
771
            for (var i in licenses) {
772
                // Include the file's current license, even if not enabled, to prevent displaying
773
                // misleading information about which license the file currently has assigned to it.
774
                if (licenses[i].enabled == true || (filenode !== undefined && licenses[i].shortname === filenode.license)) {
775
                    var option = Y.Node.create('<option/>').
776
                    set('selected', (licenses[i].shortname == selectedlicense)).
777
                    set('value', licenses[i].shortname).
778
                    setContent(Y.Escape.html(licenses[i].fullname));
779
                    licensenode.appendChild(option);
780
                }
781
            }
782
        },
783
        set_current_tree: function(tree) {
784
            var appendfilepaths = function(list, node) {
785
                if (!node || !node.children || !node.children.length) {return;}
786
                for (var i in node.children) {
787
                    list[list.length] = node.children[i].filepath;
788
                    appendfilepaths(list, node.children[i]);
789
                }
790
            }
791
            var list = ['/'];
792
            appendfilepaths(list, tree);
793
            var selectnode = this.selectnode;
794
            node = selectnode.one('.fp-path select');
795
            node.setContent('');
796
            for (var i in list) {
797
                node.appendChild(Y.Node.create('<option/>').
798
                    set('value', list[i]).setContent(Y.Escape.html(list[i])));
799
            }
800
        },
801
        update_file: function(confirmed) {
802
            var selectnode = this.selectnode;
803
            var fileinfo = this.selectui.fileinfo;
804
 
805
            var newfilename = Y.Lang.trim(selectnode.one('.fp-saveas input').get('value'));
806
            var filenamechanged = (newfilename && newfilename != fileinfo.fullname);
807
            var pathselect = selectnode.one('.fp-path select'),
808
                    pathindex = pathselect.get('selectedIndex'),
809
                    targetpath = pathselect.get("options").item(pathindex).get('value');
810
            var filepathchanged = (targetpath != this.get_parent_folder_name(fileinfo));
811
            var newauthor = Y.Lang.trim(selectnode.one('.fp-author input').get('value'));
812
            var authorchanged = (newauthor != Y.Lang.trim(fileinfo.author));
813
            var licenseselect = selectnode.one('.fp-license select'),
814
                    licenseindex = licenseselect.get('selectedIndex'),
815
                    newlicense = licenseselect.get("options").item(licenseindex).get('value');
816
            var licensechanged = (newlicense != fileinfo.license);
817
 
818
            var params, action;
819
            var dialog_options = {callback:this.update_file, callbackargs:[true], scope:this};
820
            if (fileinfo.type == 'folder') {
821
                if (!newfilename) {
822
                    this.print_msg(M.util.get_string('entername', 'repository'), 'error');
823
                    return;
824
                }
825
                if (filenamechanged || filepathchanged) {
826
                    if (!confirmed) {
827
                        dialog_options.message = M.util.get_string('confirmrenamefolder', 'repository');
828
                        this.show_confirm_dialog(dialog_options);
829
                        this.selectui.hide();
830
                        return;
831
                    }
832
                    params = {filepath:fileinfo.filepath, newdirname:newfilename, newfilepath:targetpath};
833
                    action = 'updatedir';
834
                }
835
            } else {
836
                if (!newfilename) {
837
                    this.print_msg(M.util.get_string('enternewname', 'repository'), 'error');
838
                    return;
839
                }
840
 
841
                if ((filenamechanged || filepathchanged) && !confirmed) {
842
                    var warnings = '';
843
                    var originalfilenamearr = fileinfo.fullname.split('.');
844
                    var originalextension = (originalfilenamearr.length > 1) ? originalfilenamearr.pop() : "";
845
                    var newfilenamearr = newfilename.split('.');
846
                    var newextension = (newfilenamearr.length > 1) ? newfilenamearr.pop() : "";
847
 
848
                    if (newextension !== originalextension) {
849
                        if (newextension === "") {
850
                            var string = M.util.get_string('originalextensionremove', 'repository', originalextension);
851
                        } else {
852
                            var stringvars = {
853
                                originalextension: originalextension,
854
                                newextension: newextension
855
                            }
856
                            string = M.util.get_string('originalextensionchange', 'repository', stringvars);
857
                        }
858
                        warnings = warnings.concat('<li>', string, '</li>');
859
                    }
860
                    if (fileinfo.refcount) {
861
                        var string = M.util.get_string('aliaseschange', 'repository', fileinfo.refcount);
862
                        warnings = warnings.concat('<li>', string, '</li>');
863
                    }
864
                    if (warnings.length > 0) {
865
                        var message = '';
866
                        var confirmmsg = M.util.get_string('confirmrenamefile', 'repository', fileinfo.refcount);
867
                        dialog_options.message = message.concat('<p>', confirmmsg, '</p>',
868
                            '<ul class="px-5">', warnings, '</ul>');
869
                        this.show_confirm_dialog(dialog_options);
870
                        return;
871
                    }
872
                }
873
                if (filenamechanged || filepathchanged || licensechanged || authorchanged) {
874
                    params = {filepath:fileinfo.filepath, filename:fileinfo.fullname,
875
                        newfilename:newfilename, newfilepath:targetpath,
876
                        newlicense:newlicense, newauthor:newauthor};
877
                    action = 'updatefile';
878
                }
879
            }
880
            if (!action) {
881
                // no changes
882
                this.selectui.hide();
883
                return;
884
            }
885
            selectnode.addClass('loading');
886
            this.request({
887
                action: action,
888
                scope: this,
889
                params: params,
890
                callback: function(id, obj, args) {
891
                    if (obj.error) {
892
                        selectnode.removeClass('loading');
893
                        args.scope.print_msg(obj.error, 'error');
894
                    } else {
895
                        args.scope.selectui.hide();
896
                        var actionfile = {action: action, newfilename: newfilename};
897
                        args.scope.refresh((obj && obj.filepath) ? obj.filepath : '/', actionfile);
898
                        M.form_filemanager.formChangeChecker.markFormChangedFromNode(this.scope.filemanager.getDOMNode());
899
                    }
900
                }
901
            });
902
        },
903
        /**
904
         * Displays a confirmation dialog
905
         * Expected attributes in dialog_options: message, callback, callbackargs(optional), scope(optional)
906
         */
907
        show_confirm_dialog: function(dialogOptions) {
908
            require(['core/notification', 'core/str'], function(Notification, Str) {
909
                Notification.saveCancelPromise(
910
                    Str.get_string('confirm', 'moodle'),
911
                    dialogOptions.message,
912
                    Str.get_string('yes', 'moodle')
913
                ).then(function() {
914
                    dialogOptions.callback.apply(dialogOptions.scope, dialogOptions.callbackargs);
915
                    return;
916
                }).catch(function() {
917
                    // User cancelled.
918
                });
919
            });
920
        },
921
        setup_select_file: function() {
922
            var selectnode = this.selectnode;
923
            var scope = this;
924
            // bind labels with corresponding inputs
925
            selectnode.all('.fp-saveas,.fp-path,.fp-author,.fp-license').each(function (node) {
926
                node.all('label').set('for', node.one('input,select').generateID());
927
            });
928
            // register event on clicking buttons
929
            selectnode.one('.fp-file-update').on('click', function(e) {
930
                e.preventDefault();
931
                this.update_file();
932
            }, this);
933
            selectnode.all('form input').on('key', function(e) {
934
                e.preventDefault();
935
                scope.update_file();
936
            }, 'enter');
937
            selectnode.one('.fp-file-download').on('click', function(e) {
938
                e.preventDefault();
939
                if (this.selectui.fileinfo.type != 'folder') {
940
                    node = Y.Node.create('<iframe></iframe>').setStyles({
941
                        visibility : 'hidden',
942
                        width : '1px',
943
                        height : '1px'
944
                    });
945
                    node.set('src', this.selectui.fileinfo.url);
946
                    Y.one('body').appendChild(node);
947
                }
948
            }, this);
949
            selectnode.one('.fp-file-delete').on('click', function(e) {
950
                e.preventDefault();
951
                var dialog_options = {
952
                    scope: this,
953
                    header: M.util.get_string('confirm', 'moodle'),
954
                };
955
                var params = {};
956
                var fileinfo = this.selectui.fileinfo;
957
                params.filepath = fileinfo.filepath;
958
                if (fileinfo.type == 'folder') {
959
                    params.filename = '.';
960
                    dialog_options.message = M.util.get_string('confirmdeletefolder', 'repository');
961
                } else {
962
                    params.filename = fileinfo.fullname;
963
                    if (fileinfo.refcount) {
964
                        dialog_options.message = M.util.get_string('confirmdeletefilewithhref', 'repository', fileinfo.refcount);
965
                    } else {
966
                        dialog_options.message = M.util.get_string('confirmdeletefile', 'repository');
967
                    }
968
                }
969
                dialog_options.callbackargs = [params];
970
                dialog_options.callback = function(params) {
971
                    //selectnode.addClass('loading');
972
                    this.request({
973
                        action: 'delete',
974
                        scope: this,
975
                        params: params,
976
                        callback: function(id, obj, args) {
977
                            //args.scope.selectui.hide();
978
                            args.scope.filecount--;
979
                            args.scope.refresh(obj.filepath, {action: 'delete'});
980
                            M.form_filemanager.formChangeChecker.markFormChangedFromNode(this.scope.filemanager.getDOMNode());
981
 
982
                            require(['core_form/events'], function(FormEvent) {
983
                                FormEvent.notifyUploadChanged(this.scope.filemanager.get('id'));
984
                            }.bind(this));
985
                        }
986
                    });
987
                };
988
                this.selectui.hide(); // TODO remove this after confirm dialog is replaced with YUI3
989
                // This is used to focus on before active element after confirm dialogue closed.
990
                if (this.options.previousActiveElement !== undefined) {
991
                    dialog_options.previousActiveElement = this.options.previousActiveElement;
992
                }
993
                this.show_confirm_dialog(dialog_options);
994
            }, this);
995
            selectnode.one('.fp-file-zip').on('click', function(e) {
996
                e.preventDefault();
997
                var params = {};
998
                var fileinfo = this.selectui.fileinfo;
999
                if (fileinfo.type != 'folder') {
1000
                    // this button should not even be shown
1001
                    return;
1002
                }
1003
                params['filepath']   = fileinfo.filepath;
1004
                params['filename']   = '.';
1005
                selectnode.addClass('loading');
1006
                this.request({
1007
                    action: 'zip',
1008
                    scope: this,
1009
                    params: params,
1010
                    callback: function(id, obj, args) {
1011
                        args.scope.selectui.hide();
1012
                        args.scope.refresh(obj.filepath);
1013
                    }
1014
                });
1015
            }, this);
1016
            selectnode.one('.fp-file-unzip').on('click', function(e) {
1017
                e.preventDefault();
1018
                var params = {};
1019
                var fileinfo = this.selectui.fileinfo;
1020
                if (fileinfo.type != 'zip') {
1021
                    // this button should not even be shown
1022
                    return;
1023
                }
1024
                params['filepath'] = fileinfo.filepath;
1025
                params['filename'] = fileinfo.fullname;
1026
                // The unlimited value of areamaxbytes is -1, it is defined by FILE_AREA_MAX_BYTES_UNLIMITED.
1027
                params['areamaxbytes'] = this.areamaxbytes ? this.areamaxbytes : -1;
1028
                selectnode.addClass('loading');
1029
                this.request({
1030
                    action: 'unzip',
1031
                    scope: this,
1032
                    params: params,
1033
                    callback: function(id, obj, args) {
1034
                        if (obj.error) {
1035
                            selectnode.removeClass('loading');
1036
                            args.scope.print_msg(obj.error, 'error', options);
1037
                        } else {
1038
                            args.scope.selectui.hide();
1039
                            args.scope.refresh(obj.filepath);
1040
                        }
1041
                    }
1042
                });
1043
            }, this);
1044
            selectnode.one('.fp-file-setmain').on('click', function(e) {
1045
                e.preventDefault();
1046
                var params = {};
1047
                var fileinfo = this.selectui.fileinfo;
1048
                if (!this.enablemainfile || fileinfo.type == 'folder') {
1049
                    // this button should not even be shown for folders or when mainfile is disabled
1050
                    return;
1051
                }
1052
                params['filepath'] = fileinfo.filepath;
1053
                params['filename'] = fileinfo.fullname;
1054
                selectnode.addClass('loading');
1055
                this.request({
1056
                    action: 'setmainfile',
1057
                    scope: this,
1058
                    params: params,
1059
                    callback: function(id, obj, args) {
1060
                        args.scope.selectui.hide();
1061
                        var actionfile = {action: 'setmainfile', newfilename: fileinfo.fullname};
1062
                        args.scope.refresh(fileinfo.filepath, actionfile);
1063
                    }
1064
                });
1065
            }, this);
1066
            selectnode.all('.fp-file-cancel').on('click', function(e) {
1067
                e.preventDefault();
1068
                // TODO if changed asked to confirm, the same with close button
1069
                this.selectui.hide();
1070
            }, this);
1071
            selectnode.all('.fp-file-update, .fp-file-download, .fp-file-delete, .fp-file-zip, .fp-file-unzip, ' +
1072
                '.fp-file-setmain, .fp-file-cancel').on('key', function(e) {
1073
                    e.preventDefault();
1074
                    this.simulate('click');
1075
            }, 'enter');
1076
        },
1077
        get_parent_folder_name: function(node) {
1078
            if (node.type != 'folder' || node.filepath.length < node.fullname.length+1) {
1079
                return node.filepath;
1080
            }
1081
            var basedir = node.filepath.substr(0, node.filepath.length - node.fullname.length - 1);
1082
            var lastdir = node.filepath.substr(node.filepath.length - node.fullname.length - 2);
1083
            if (lastdir == '/' + node.fullname + '/') {
1084
                return basedir;
1085
            }
1086
            return node.filepath;
1087
        },
1088
        select_file: function(node) {
1089
            if (this.is_disabled()) {
1090
                return;
1091
            }
1092
            var selectnode = this.selectnode;
1093
            selectnode.removeClass('loading').removeClass('fp-folder').
1094
                removeClass('fp-file').removeClass('fp-zip').removeClass('fp-cansetmain');
1095
            if (node.type == 'folder' || node.type == 'zip') {
1096
                selectnode.addClass('fp-'+node.type);
1097
            } else {
1098
                selectnode.addClass('fp-file');
1099
            }
1100
            if (this.enablemainfile && (node.sortorder != 1) && node.type == 'file') {
1101
                selectnode.addClass('fp-cansetmain');
1102
            }
1103
            this.selectui.fileinfo = node;
1104
            selectnode.one('.fp-saveas input').set('value', node.fullname);
1105
            var foldername = this.get_parent_folder_name(node);
1106
            selectnode.all('.fp-author input').set('value', node.author ? node.author : '');
1107
            this.populateLicensesSelect(selectnode.one('.fp-license select'), node);
1108
            selectnode.all('.fp-path select option[selected]').set('selected', false);
1109
            selectnode.all('.fp-path select option').each(function(el){
1110
                if (el.get('value') == foldername) {
1111
                    el.set('selected', true);
1112
                }
1113
            });
1114
            selectnode.all('.fp-author input, .fp-license select').set('disabled',(node.type == 'folder')?'disabled':'');
1115
            // display static information about a file (when known)
1116
            var attrs = ['datemodified','datecreated','size','dimensions','original','reflist'];
1117
            for (var i in attrs) {
1118
                if (selectnode.one('.fp-'+attrs[i])) {
1119
                    var value = (node[attrs[i]+'_f']) ? node[attrs[i]+'_f'] : (node[attrs[i]] ? node[attrs[i]] : '');
1120
                    // Escape if the attribute being evaluated is not for the list of reference files.
1121
                    if (attrs[i] !== 'reflist') {
1122
                        value = Y.Escape.html(value);
1123
                    }
1124
                    selectnode.one('.fp-'+attrs[i]).addClassIf('fp-unknown', ''+value == '')
1125
                        .one('.fp-value').setContent(value);
1126
                }
1127
            }
1128
            // display thumbnail
1129
            var imgnode = Y.Node.create('<img/>').
1130
                set('src', node.realthumbnail ? node.realthumbnail : node.thumbnail).
1131
                setStyle('maxHeight', ''+(node.thumbnail_height ? node.thumbnail_height : 90)+'px').
1132
                setStyle('maxWidth', ''+(node.thumbnail_width ? node.thumbnail_width : 90)+'px');
1133
            selectnode.one('.fp-thumbnail').setContent('').appendChild(imgnode);
1134
            // load original location if applicable
1135
            if (node.isref && !node.original) {
1136
                selectnode.one('.fp-original').removeClass('fp-unknown').addClass('fp-loading');
1137
                this.request({
1138
                    action: 'getoriginal',
1139
                    scope: this,
1140
                    params: {'filepath':node.filepath,'filename':node.fullname},
1141
                    callback: function(id, obj, args) {
1142
                        // check if we did not select another file meanwhile
1143
                        var scope = args.scope;
1144
                        if (scope.selectui.fileinfo && node &&
1145
                                scope.selectui.fileinfo.filepath == node.filepath &&
1146
                                scope.selectui.fileinfo.fullname == node.fullname) {
1147
                            selectnode.one('.fp-original').removeClass('fp-loading');
1148
                            if (obj.original) {
1149
                                node.original = obj.original;
1150
                                selectnode.one('.fp-original .fp-value').setContent(Y.Escape.html(node.original));
1151
                            } else {
1152
                                selectnode.one('.fp-original .fp-value').setContent(M.util.get_string('unknownsource', 'repository'));
1153
                            }
1154
                        }
1155
                    }
1156
                }, false);
1157
            }
1158
            // load references list if applicable
1159
            selectnode.one('.fp-refcount').setContent(node.refcount ? M.util.get_string('referencesexist', 'repository', node.refcount) : '');
1160
            if (node.refcount && !node.reflist) {
1161
                selectnode.one('.fp-reflist').removeClass('fp-unknown').addClass('fp-loading');
1162
                this.request({
1163
                    action: 'getreferences',
1164
                    scope: this,
1165
                    params: {'filepath':node.filepath,'filename':node.fullname},
1166
                    callback: function(id, obj, args) {
1167
                        // check if we did not select another file meanwhile
1168
                        var scope = args.scope;
1169
                        if (scope.selectui.fileinfo && node &&
1170
                                scope.selectui.fileinfo.filepath == node.filepath &&
1171
                                scope.selectui.fileinfo.fullname == node.fullname) {
1172
                            selectnode.one('.fp-reflist').removeClass('fp-loading');
1173
                            if (obj.references) {
1174
                                node.reflist = '';
1175
                                for (var i in obj.references) {
1176
                                    node.reflist += '<li>'+Y.Escape.html(obj.references[i])+'</li>';
1177
                                }
1178
                                selectnode.one('.fp-reflist .fp-value').setContent(node.reflist);
1179
                            } else {
1180
                                selectnode.one('.fp-reflist .fp-value').setContent('');
1181
                            }
1182
                        }
1183
                    }
1184
                }, false);
1185
            }
1186
            // update dialog header
1187
            var nodename = node.fullname;
1188
            // Limit the string length so it fits nicely on mobile devices
1189
            var namelength = 50;
1190
            if (nodename.length > namelength) {
1191
                nodename = nodename.substring(0, namelength) + '...';
1192
            }
1193
            Y.one('#fm-dialog-label_'+selectnode.get('id')).setContent(Y.Escape.html(M.util.get_string('edit', 'moodle')+' '+nodename));
1194
            // show panel
1195
            this.selectui.show();
1196
            Y.one('#'+selectnode.get('id')).focus();
1197
        },
1198
        render: function(obj, action) {
1199
            this.print_path();
1200
            this.view_files(null, action);
1201
        },
1202
        has_folder: function(foldername) {
1203
            var element;
1204
            for (var i in this.options.list) {
1205
                element = this.options.list[i];
1206
                if (element.type == 'folder' && element.fullname == foldername) {
1207
                    return true;
1208
                }
1209
            }
1210
            return false;
1211
        },
1212
        get_preference: function(name) {
1213
            if (this.userprefs[name]) {
1214
                return this.userprefs[name];
1215
            } else {
1216
                return false;
1217
            }
1218
        },
1219
        set_preference: function(name, value) {
1220
            if (this.userprefs[name] != value) {
1221
                require(['core_user/repository'], function(UserRepository) {
1222
                    UserRepository.setUserPreference('filemanager_' + name, value);
1223
                    this.userprefs[name] = value;
1224
                }.bind(this));
1225
            }
1226
        },
1227
    });
1228
 
1229
    // finally init everything needed
1230
    // hide loading picture, display filemanager interface
1231
    var filemanager = Y.one('#filemanager-'+options.client_id);
1232
    filemanager.removeClass('fm-loading').addClass('fm-loaded');
1233
 
1234
    var manager = new FileManagerHelper(options);
1235
    var dndoptions = {
1236
        filemanager: manager,
1237
        acceptedtypes: options.filepicker.accepted_types,
1238
        clientid: options.client_id,
1239
        author: options.author,
1240
        maxfiles: options.maxfiles,
1241
        maxbytes: options.maxbytes,
1242
        areamaxbytes: options.areamaxbytes,
1243
        itemid: options.itemid,
1244
        repositories: manager.filepicker_options.repositories,
1245
        containerid: manager.dndcontainer.get('id'),
1246
        contextid: options.context.id
1247
    };
1248
    M.form_dndupload.init(Y, dndoptions);
1249
};