[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 * 34 * FileManager options: 35 * ===== 36 * this.options.currentpath 37 * this.options.itemid 38 */ 39 40 41 M.form_filemanager = {templates:{}}; 42 43 M.form_filemanager.set_templates = function(Y, templates) { 44 M.form_filemanager.templates = templates; 45 } 46 47 /** 48 * This fucntion is called for each file picker on page. 49 */ 50 M.form_filemanager.init = function(Y, options) { 51 var FileManagerHelper = function(options) { 52 FileManagerHelper.superclass.constructor.apply(this, arguments); 53 }; 54 FileManagerHelper.NAME = "FileManager"; 55 FileManagerHelper.ATTRS = { 56 options: {}, 57 lang: {} 58 }; 59 60 Y.extend(FileManagerHelper, Y.Base, { 61 api: M.cfg.wwwroot+'/repository/draftfiles_ajax.php', 62 menus: {}, 63 initializer: function(options) { 64 this.options = options; 65 if (options.mainfile) { 66 this.enablemainfile = options.mainfile; 67 } 68 this.client_id = options.client_id; 69 this.currentpath = '/'; 70 this.maxfiles = options.maxfiles; 71 this.maxbytes = options.maxbytes; 72 this.areamaxbytes = options.areamaxbytes; 73 this.emptycallback = null; // Used by drag and drop upload 74 75 this.filepicker_options = options.filepicker?options.filepicker:{}; 76 this.filepicker_options.client_id = this.client_id; 77 this.filepicker_options.context = options.context; 78 this.filepicker_options.maxfiles = this.maxfiles; 79 this.filepicker_options.maxbytes = this.maxbytes; 80 this.filepicker_options.areamaxbytes = this.areamaxbytes; 81 this.filepicker_options.env = 'filemanager'; 82 this.filepicker_options.itemid = options.itemid; 83 84 if (options.filecount) { 85 this.filecount = options.filecount; 86 } else { 87 this.filecount = 0; 88 } 89 // prepare filemanager for drag-and-drop upload 90 this.filemanager = Y.one('#filemanager-'+options.client_id); 91 if (this.filemanager.hasClass('filemanager-container') || !this.filemanager.one('.filemanager-container')) { 92 this.dndcontainer = this.filemanager; 93 } else { 94 this.dndcontainer = this.filemanager.one('.filemanager-container'); 95 if (!this.dndcontainer.get('id')) { 96 this.dndcontainer.generateID(); 97 } 98 } 99 // save template for one path element and location of path bar 100 if (this.filemanager.one('.fp-path-folder')) { 101 this.pathnode = this.filemanager.one('.fp-path-folder'); 102 this.pathbar = this.pathnode.get('parentNode'); 103 this.pathbar.removeChild(this.pathnode); 104 } 105 // initialize 'select file' panel 106 this.selectnode = Y.Node.createWithFilesSkin(M.form_filemanager.templates.fileselectlayout); 107 this.selectnode.setAttribute('aria-live', 'assertive'); 108 this.selectnode.setAttribute('role', 'dialog'); 109 this.selectnode.generateID(); 110 111 var labelid = 'fm-dialog-label_'+ this.selectnode.get('id'); 112 this.selectui = new M.core.dialogue({ 113 draggable : true, 114 headerContent: '<h3 id="' + labelid +'">' + M.util.get_string('edit', 'moodle') + '</h3>', 115 bodyContent : this.selectnode, 116 centered : true, 117 width : '480px', 118 modal : true, 119 visible : false 120 }); 121 Y.one('#'+this.selectnode.get('id')).setAttribute('aria-labelledby', labelid); 122 this.selectui.hide(); 123 this.setup_select_file(); 124 // setup buttons onclick events 125 this.setup_buttons(); 126 // set event handler for lazy loading of thumbnails 127 this.filemanager.one('.fp-content').on(['scroll','resize'], this.content_scrolled, this); 128 // display files 129 this.viewmode = 1; // TODO take from cookies? 130 this.filemanager.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').removeClass('checked') 131 this.filemanager.all('.fp-vb-icons').addClass('checked') 132 this.refresh(this.currentpath); // MDL-31113 get latest list from server 133 }, 134 135 wait: function() { 136 this.filemanager.addClass('fm-updating'); 137 }, 138 request: function(args, redraw) { 139 var api = this.api + '?action='+args.action; 140 var params = {}; 141 var scope = this; 142 if (args['scope']) { 143 scope = args['scope']; 144 } 145 params['sesskey'] = M.cfg.sesskey; 146 params['client_id'] = this.client_id; 147 params['filepath'] = this.currentpath; 148 params['itemid'] = this.options.itemid?this.options.itemid:0; 149 if (args['params']) { 150 for (i in args['params']) { 151 params[i] = args['params'][i]; 152 } 153 } 154 var cfg = { 155 method: 'POST', 156 on: { 157 complete: function(id,o,p) { 158 if (!o) { 159 alert('IO FATAL'); 160 return; 161 } 162 var data = null; 163 try { 164 data = Y.JSON.parse(o.responseText); 165 } catch(e) { 166 scope.print_msg(M.util.get_string('invalidjson', 'repository'), 'error'); 167 Y.error(M.util.get_string('invalidjson', 'repository')+":\n"+o.responseText); 168 return; 169 } 170 if (data && data.tree && scope.set_current_tree) { 171 scope.set_current_tree(data.tree); 172 } 173 args.callback(id,data,p); 174 } 175 }, 176 arguments: { 177 scope: scope 178 }, 179 headers: { 180 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' 181 }, 182 data: build_querystring(params) 183 }; 184 if (args.form) { 185 cfg.form = args.form; 186 } 187 Y.io(api, cfg); 188 if (redraw) { 189 this.wait(); 190 } 191 }, 192 filepicker_callback: function(obj) { 193 this.filecount++; 194 this.check_buttons(); 195 this.refresh(this.currentpath); 196 if (typeof M.core_formchangechecker != 'undefined') { 197 M.core_formchangechecker.set_form_changed(); 198 } 199 }, 200 check_buttons: function() { 201 if (this.filecount>0) { 202 this.filemanager.removeClass('fm-nofiles'); 203 } else { 204 this.filemanager.addClass('fm-nofiles'); 205 } 206 if (this.filecount >= this.maxfiles && this.maxfiles!=-1) { 207 this.filemanager.addClass('fm-maxfiles'); 208 } 209 else { 210 this.filemanager.removeClass('fm-maxfiles'); 211 } 212 }, 213 refresh: function(filepath) { 214 var scope = this; 215 this.currentpath = filepath; 216 if (!filepath) { 217 filepath = this.currentpath; 218 } else { 219 this.currentpath = filepath; 220 } 221 this.request({ 222 action: 'list', 223 scope: scope, 224 params: {'filepath':filepath}, 225 callback: function(id, obj, args) { 226 scope.filecount = obj.filecount; 227 scope.options = obj; 228 scope.lazyloading = {}; 229 scope.check_buttons(); 230 scope.render(obj); 231 } 232 }, true); 233 }, 234 /** displays message in a popup */ 235 print_msg: function(msg, type) { 236 var header = M.util.get_string('error', 'moodle'); 237 if (type != 'error') { 238 type = 'info'; // one of only two types excepted 239 header = M.util.get_string('info', 'moodle'); 240 } 241 if (!this.msg_dlg) { 242 this.msg_dlg_node = Y.Node.createWithFilesSkin(M.form_filemanager.templates.message); 243 var nodeid = this.msg_dlg_node.generateID(); 244 245 this.msg_dlg = new M.core.dialogue({ 246 draggable : true, 247 bodyContent : this.msg_dlg_node, 248 centered : true, 249 modal : true, 250 visible : false, 251 }); 252 this.msg_dlg_node.one('.fp-msg-butok').on('click', function(e) { 253 e.preventDefault(); 254 this.msg_dlg.hide(); 255 }, this); 256 } 257 258 this.msg_dlg.set('headerContent', header); 259 this.msg_dlg_node.removeClass('fp-msg-info').removeClass('fp-msg-error').addClass('fp-msg-'+type) 260 this.msg_dlg_node.one('.fp-msg-text').setContent(Y.Escape.html(msg)); 261 this.msg_dlg.show(); 262 }, 263 is_disabled: function() { 264 return this.filemanager.ancestor('.fitem.disabled') != null; 265 }, 266 setup_buttons: function() { 267 var button_download = this.filemanager.one('.fp-btn-download'); 268 var button_create = this.filemanager.one('.fp-btn-mkdir'); 269 var button_addfile = this.filemanager.one('.fp-btn-add'); 270 271 // setup 'add file' button 272 button_addfile.on('click', this.show_filepicker, this); 273 274 var dndarrow = this.filemanager.one('.dndupload-arrow'); 275 if (dndarrow) { 276 dndarrow.on('click', this.show_filepicker, this); 277 } 278 279 // setup 'make a folder' button 280 if (this.options.subdirs) { 281 button_create.on('click',function(e) { 282 e.preventDefault(); 283 if (this.is_disabled()) { 284 return; 285 } 286 var scope = this; 287 // a function used to perform an ajax request 288 var perform_action = function(e) { 289 e.preventDefault(); 290 var foldername = Y.one('#fm-newname-'+scope.client_id).get('value'); 291 if (!foldername) { 292 scope.mkdir_dialog.hide(); 293 return; 294 } 295 scope.request({ 296 action:'mkdir', 297 params: {filepath:scope.currentpath, newdirname:foldername}, 298 callback: function(id, obj, args) { 299 var filepath = obj.filepath; 300 scope.mkdir_dialog.hide(); 301 scope.refresh(filepath); 302 Y.one('#fm-newname-'+scope.client_id).set('value', ''); 303 if (typeof M.core_formchangechecker != 'undefined') { 304 M.core_formchangechecker.set_form_changed(); 305 } 306 } 307 }); 308 }; 309 var validate_folder_name = function() { 310 var valid = false; 311 var foldername = Y.one('#fm-newname-'+scope.client_id).get('value'); 312 if (foldername.length > 0) { 313 valid = true; 314 } 315 var btn = Y.one('#fm-mkdir-butcreate-'+scope.client_id); 316 if (btn) { 317 btn.set('disabled', !valid); 318 } 319 return valid; 320 }; 321 if (!this.mkdir_dialog) { 322 var node = Y.Node.createWithFilesSkin(M.form_filemanager.templates.mkdir); 323 this.mkdir_dialog = new M.core.dialogue({ 324 draggable : true, 325 bodyContent : node, 326 centered : true, 327 modal : true, 328 visible : false, 329 }); 330 node.one('.fp-dlg-butcreate').set('id', 'fm-mkdir-butcreate-'+this.client_id).on('click', 331 perform_action, this); 332 node.one('input').set('id', 'fm-newname-'+this.client_id).on('keydown', function(e) { 333 var valid = Y.bind(validate_folder_name, this)(); 334 if (valid && e.keyCode === 13) { 335 Y.bind(perform_action, this)(e); 336 } 337 }, this); 338 node.one('#fm-newname-'+this.client_id).on(['keyup', 'change'], function(e) { 339 Y.bind(validate_folder_name, this)(); 340 }, this); 341 342 node.one('label').set('for', 'fm-newname-' + this.client_id); 343 node.all('.fp-dlg-butcancel').on('click', function(e){e.preventDefault();this.mkdir_dialog.hide();}, this); 344 node.all('.fp-dlg-curpath').set('id', 'fm-curpath-'+this.client_id); 345 } 346 this.mkdir_dialog.show(); 347 348 // Default folder name: 349 var foldername = M.util.get_string('newfolder', 'repository'); 350 while (this.has_folder(foldername)) { 351 foldername = increment_filename(foldername, true); 352 } 353 Y.one('#fm-newname-'+scope.client_id).set('value', foldername); 354 Y.bind(validate_folder_name, this)(); 355 Y.one('#fm-newname-'+scope.client_id).focus().select(); 356 Y.all('#fm-curpath-'+scope.client_id).setContent(this.currentpath); 357 }, this); 358 } else { 359 this.filemanager.addClass('fm-nomkdir'); 360 } 361 362 // setup 'download this folder' button 363 button_download.on('click',function(e) { 364 e.preventDefault(); 365 if (this.is_disabled()) { 366 return; 367 } 368 var scope = this; 369 370 var image_downloading = this.filemanager.one('.fp-img-downloading'); 371 if (image_downloading.getStyle('display') == 'inline') { 372 return; 373 } 374 image_downloading.setStyle('display', 'inline'); 375 376 // perform downloaddir ajax request 377 this.request({ 378 action: 'downloaddir', 379 scope: scope, 380 callback: function(id, obj, args) { 381 var image_downloading = scope.filemanager.one('.fp-img-downloading'); 382 image_downloading.setStyle('display', 'none'); 383 384 if (obj) { 385 scope.refresh(obj.filepath); 386 node = Y.Node.create('<iframe></iframe>').setStyles({ 387 visibility : 'hidden', 388 width : '1px', 389 height : '1px' 390 }); 391 node.set('src', obj.fileurl); 392 Y.one('body').appendChild(node); 393 } else { 394 scope.print_msg(M.util.get_string('draftareanofiles', 'repository'), 'error'); 395 } 396 } 397 }); 398 }, this); 399 400 this.filemanager.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details'). 401 on('click', function(e) { 402 e.preventDefault(); 403 var viewbar = this.filemanager.one('.fp-viewbar') 404 if (!this.is_disabled() && (!viewbar || !viewbar.hasClass('disabled'))) { 405 this.filemanager.all('.fp-vb-icons,.fp-vb-tree,.fp-vb-details').removeClass('checked') 406 if (e.currentTarget.hasClass('fp-vb-tree')) { 407 this.viewmode = 2; 408 } else if (e.currentTarget.hasClass('fp-vb-details')) { 409 this.viewmode = 3; 410 } else { 411 this.viewmode = 1; 412 } 413 e.currentTarget.addClass('checked') 414 this.render(); 415 this.filemanager.one('.fp-content').setAttribute('tabIndex', '0'); 416 this.filemanager.one('.fp-content').focus(); 417 } 418 }, this); 419 }, 420 421 show_filepicker: function (e) { 422 // if maxfiles == -1, the no limit 423 e.preventDefault(); 424 if (this.is_disabled()) { 425 return; 426 } 427 var options = this.filepicker_options; 428 options.formcallback = this.filepicker_callback; 429 // XXX: magic here, to let filepicker use filemanager scope 430 options.magicscope = this; 431 options.savepath = this.currentpath; 432 M.core_filepicker.show(Y, options); 433 }, 434 435 print_path: function() { 436 var p = this.options.path; 437 this.pathbar.setContent('').addClass('empty'); 438 if (p && p.length!=0 && this.viewmode != 2) { 439 for(var i = 0; i < p.length; i++) { 440 var el = this.pathnode.cloneNode(true); 441 this.pathbar.appendChild(el); 442 443 if (i == 0) { 444 el.addClass('first'); 445 } 446 if (i == p.length-1) { 447 el.addClass('last'); 448 } 449 450 if (i%2) { 451 el.addClass('even'); 452 } else { 453 el.addClass('odd'); 454 } 455 el.one('.fp-path-folder-name').setContent(Y.Escape.html(p[i].name)). 456 on('click', function(e, path) { 457 e.preventDefault(); 458 if (!this.is_disabled()) { 459 this.refresh(path); 460 } 461 }, this, p[i].path); 462 } 463 this.pathbar.removeClass('empty'); 464 } 465 }, 466 get_filepath: function(obj) { 467 if (obj.path && obj.path.length) { 468 return obj.path[obj.path.length-1].path; 469 } 470 return ''; 471 }, 472 treeview_dynload: function(node, cb) { 473 var retrieved_children = {}; 474 if (node.children) { 475 for (var i in node.children) { 476 retrieved_children[node.children[i].path] = node.children[i]; 477 } 478 } 479 if (!node.path || node.path == '/') { 480 // this is a root pseudo folder 481 node.fileinfo.filepath = '/'; 482 node.fileinfo.type = 'folder'; 483 node.fileinfo.fullname = node.fileinfo.title; 484 node.fileinfo.filename = '.'; 485 } 486 this.request({ 487 action:'list', 488 params: {filepath:node.path?node.path:''}, 489 scope:this, 490 callback: function(id, obj, args) { 491 var list = obj.list; 492 var scope = args.scope; 493 // check that user did not leave the view mode before recieving this response 494 if (!(scope.viewmode == 2 && node && node.getChildrenEl())) { 495 return; 496 } 497 if (cb != null) { // (in manual mode do not update current path) 498 scope.options = obj; 499 scope.currentpath = node.path?node.path:'/'; 500 } 501 node.highlight(false); 502 node.origlist = obj.list ? obj.list : null; 503 node.origpath = obj.path ? obj.path : null; 504 node.children = []; 505 for(k in list) { 506 if (list[k].type == 'folder' && retrieved_children[list[k].filepath]) { 507 // if this child is a folder and has already been retrieved 508 retrieved_children[list[k].filepath].fileinfo = list[k]; 509 node.children[node.children.length] = retrieved_children[list[k].filepath]; 510 } else { 511 // append new file to the list 512 scope.view_files([list[k]]); 513 } 514 } 515 if (cb == null) { 516 node.refresh(); 517 } else { 518 // invoke callback requested by TreeView component 519 cb(); 520 } 521 scope.content_scrolled(); 522 } 523 }, false); 524 }, 525 content_scrolled: function(e) { 526 setTimeout(Y.bind(function() { 527 if (this.processingimages) {return;} 528 this.processingimages = true; 529 var scope = this, 530 fpcontent = this.filemanager.one('.fp-content'), 531 fpcontenty = fpcontent.getY(), 532 fpcontentheight = fpcontent.getStylePx('height'), 533 is_node_visible = function(node) { 534 var offset = node.getY()-fpcontenty; 535 if (offset <= fpcontentheight && (offset >=0 || offset+node.getStylePx('height')>=0)) { 536 return true; 537 } 538 return false; 539 }; 540 // replace src for visible images that need to be lazy-loaded 541 if (scope.lazyloading) { 542 fpcontent.all('img').each( function(node) { 543 if (node.get('id') && scope.lazyloading[node.get('id')] && is_node_visible(node)) { 544 node.setImgRealSrc(scope.lazyloading); 545 } 546 }); 547 } 548 this.processingimages = false; 549 }, this), 200) 550 }, 551 view_files: function(appendfiles) { 552 this.filemanager.removeClass('fm-updating').removeClass('fm-noitems'); 553 if ((appendfiles == null) && (!this.options.list || this.options.list.length == 0) && this.viewmode != 2) { 554 this.filemanager.addClass('fm-noitems'); 555 return; 556 } 557 var list = (appendfiles != null) ? appendfiles : this.options.list; 558 var element_template; 559 if (this.viewmode == 2 || this.viewmode == 3) { 560 element_template = Y.Node.create(M.form_filemanager.templates.listfilename); 561 } else { 562 this.viewmode = 1; 563 element_template = Y.Node.create(M.form_filemanager.templates.iconfilename); 564 } 565 var options = { 566 viewmode : this.viewmode, 567 appendonly : appendfiles != null, 568 filenode : element_template, 569 callbackcontext : this, 570 callback : function(e, node) { 571 if (e.preventDefault) { e.preventDefault(); } 572 if (node.type == 'folder') { 573 this.refresh(node.filepath); 574 } else { 575 this.select_file(node); 576 } 577 }, 578 rightclickcallback : function(e, node) { 579 if (e.preventDefault) { e.preventDefault(); } 580 this.select_file(node); 581 }, 582 classnamecallback : function(node) { 583 var classname = ''; 584 if (node.type == 'folder' || (!node.type && !node.filename)) { 585 classname = classname + ' fp-folder'; 586 } 587 if (node.filename || node.filepath || (node.path && node.path != '/')) { 588 classname = classname + ' fp-hascontextmenu'; 589 } 590 if (node.isref) { 591 classname = classname + ' fp-isreference'; 592 } 593 if (node.refcount) { 594 classname = classname + ' fp-hasreferences'; 595 } 596 if (node.originalmissing) { 597 classname = classname + ' fp-originalmissing'; 598 } 599 if (node.sortorder == 1) { classname = classname + ' fp-mainfile';} 600 return Y.Lang.trim(classname); 601 } 602 }; 603 if (this.viewmode == 2) { 604 options.dynload = true; 605 options.filepath = this.options.path; 606 options.treeview_dynload = this.treeview_dynload; 607 options.norootrightclick = true; 608 options.callback = function(e, node) { 609 // TODO MDL-32736 e is not an event here but an object with properties 'event' and 'node' 610 if (!node.fullname) {return;} 611 if (node.type != 'folder') { 612 if (e.node.parent && e.node.parent.origpath) { 613 // set the current path 614 this.options.path = e.node.parent.origpath; 615 this.options.list = e.node.parent.origlist; 616 this.print_path(); 617 } 618 this.currentpath = node.filepath; 619 this.select_file(node); 620 } else { 621 // save current path and filelist (in case we want to jump to other viewmode) 622 this.options.path = e.node.origpath; 623 this.options.list = e.node.origlist; 624 this.currentpath = node.filepath; 625 this.print_path(); 626 //this.content_scrolled(); 627 } 628 }; 629 } 630 if (!this.lazyloading) { 631 this.lazyloading={}; 632 } 633 this.filemanager.one('.fp-content').fp_display_filelist(options, list, this.lazyloading); 634 this.content_scrolled(); 635 }, 636 populate_licenses_select: function(node) { 637 if (!node) { 638 return; 639 } 640 node.setContent(''); 641 var licenses = this.options.licenses; 642 for (var i in licenses) { 643 var option = Y.Node.create('<option/>'). 644 set('value', licenses[i].shortname). 645 setContent(Y.Escape.html(licenses[i].fullname)); 646 node.appendChild(option) 647 } 648 }, 649 set_current_tree: function(tree) { 650 var appendfilepaths = function(list, node) { 651 if (!node || !node.children || !node.children.length) {return;} 652 for (var i in node.children) { 653 list[list.length] = node.children[i].filepath; 654 appendfilepaths(list, node.children[i]); 655 } 656 } 657 var list = ['/']; 658 appendfilepaths(list, tree); 659 var selectnode = this.selectnode; 660 node = selectnode.one('.fp-path select'); 661 node.setContent(''); 662 for (var i in list) { 663 node.appendChild(Y.Node.create('<option/>'). 664 set('value', list[i]).setContent(Y.Escape.html(list[i]))); 665 } 666 }, 667 update_file: function(confirmed) { 668 var selectnode = this.selectnode; 669 var fileinfo = this.selectui.fileinfo; 670 671 var newfilename = Y.Lang.trim(selectnode.one('.fp-saveas input').get('value')); 672 var filenamechanged = (newfilename && newfilename != fileinfo.fullname); 673 var pathselect = selectnode.one('.fp-path select'), 674 pathindex = pathselect.get('selectedIndex'), 675 targetpath = pathselect.get("options").item(pathindex).get('value'); 676 var filepathchanged = (targetpath != this.get_parent_folder_name(fileinfo)); 677 var newauthor = Y.Lang.trim(selectnode.one('.fp-author input').get('value')); 678 var authorchanged = (newauthor != Y.Lang.trim(fileinfo.author)); 679 var licenseselect = selectnode.one('.fp-license select'), 680 licenseindex = licenseselect.get('selectedIndex'), 681 newlicense = licenseselect.get("options").item(licenseindex).get('value'); 682 var licensechanged = (newlicense != fileinfo.license); 683 684 var params, action; 685 var dialog_options = {callback:this.update_file, callbackargs:[true], scope:this}; 686 if (fileinfo.type == 'folder') { 687 if (!newfilename) { 688 this.print_msg(M.util.get_string('entername', 'repository'), 'error'); 689 return; 690 } 691 if (filenamechanged || filepathchanged) { 692 if (!confirmed) { 693 dialog_options.message = M.util.get_string('confirmrenamefolder', 'repository'); 694 this.show_confirm_dialog(dialog_options); 695 return; 696 } 697 params = {filepath:fileinfo.filepath, newdirname:newfilename, newfilepath:targetpath}; 698 action = 'updatedir'; 699 } 700 } else { 701 if (!newfilename) { 702 this.print_msg(M.util.get_string('enternewname', 'repository'), 'error'); 703 return; 704 } 705 if ((filenamechanged || filepathchanged) && !confirmed && fileinfo.refcount) { 706 dialog_options.message = M.util.get_string('confirmrenamefile', 'repository', fileinfo.refcount); 707 this.show_confirm_dialog(dialog_options); 708 return; 709 } 710 if (filenamechanged || filepathchanged || licensechanged || authorchanged) { 711 params = {filepath:fileinfo.filepath, filename:fileinfo.fullname, 712 newfilename:newfilename, newfilepath:targetpath, 713 newlicense:newlicense, newauthor:newauthor}; 714 action = 'updatefile'; 715 } 716 } 717 if (!action) { 718 // no changes 719 this.selectui.hide(); 720 return; 721 } 722 selectnode.addClass('loading'); 723 this.request({ 724 action: action, 725 scope: this, 726 params: params, 727 callback: function(id, obj, args) { 728 if (obj.error) { 729 selectnode.removeClass('loading'); 730 args.scope.print_msg(obj.error, 'error'); 731 } else { 732 args.scope.selectui.hide(); 733 args.scope.refresh((obj && obj.filepath) ? obj.filepath : '/'); 734 if (typeof M.core_formchangechecker != 'undefined') { 735 M.core_formchangechecker.set_form_changed(); 736 } 737 } 738 } 739 }); 740 }, 741 /** 742 * Displays a confirmation dialog 743 * Expected attributes in dialog_options: message, callback, callbackargs(optional), scope(optional) 744 */ 745 show_confirm_dialog: function(dialog_options) { 746 // instead of M.util.show_confirm_dialog(e, dialog_options); 747 if (!this.confirm_dlg) { 748 this.confirm_dlg_node = Y.Node.createWithFilesSkin(M.form_filemanager.templates.confirmdialog); 749 var node = this.confirm_dlg_node; 750 node.generateID(); 751 this.confirm_dlg = new M.core.dialogue({ 752 draggable : true, 753 bodyContent : node, 754 centered : true, 755 modal : true, 756 visible : false, 757 buttons : {} 758 }); 759 var handle_confirm = function(ev) { 760 var dlgopt = this.confirm_dlg.dlgopt; 761 ev.preventDefault(); 762 this.confirm_dlg.hide(); 763 if (dlgopt.callback) { 764 if (dlgopt.callbackargs) { 765 dlgopt.callback.apply(dlgopt.scope || this, dlgopt.callbackargs); 766 } else { 767 dlgopt.callback.apply(dlgopt.scope || this); 768 } 769 } 770 } 771 var handle_cancel = function(ev) { 772 ev.preventDefault(); 773 this.confirm_dlg.hide(); 774 } 775 node.one('.fp-dlg-butconfirm').on('click', handle_confirm, this); 776 node.one('.fp-dlg-butcancel').on('click', handle_cancel, this); 777 } 778 this.confirm_dlg.dlgopt = dialog_options; 779 this.confirm_dlg_node.one('.fp-dlg-text').setContent(dialog_options.message); 780 this.confirm_dlg.show(); 781 }, 782 setup_select_file: function() { 783 var selectnode = this.selectnode; 784 // bind labels with corresponding inputs 785 selectnode.all('.fp-saveas,.fp-path,.fp-author,.fp-license').each(function (node) { 786 node.all('label').set('for', node.one('input,select').generateID()); 787 }); 788 this.populate_licenses_select(selectnode.one('.fp-license select')); 789 // register event on clicking buttons 790 selectnode.one('.fp-file-update').on('click', function(e) { 791 e.preventDefault(); 792 this.update_file(); 793 }, this); 794 selectnode.all('form').on('keydown', function(e) { 795 if (e.keyCode == 13) { 796 e.preventDefault(); 797 this.update_file(); 798 } 799 }, this); 800 selectnode.one('.fp-file-download').on('click', function(e) { 801 e.preventDefault(); 802 if (this.selectui.fileinfo.type != 'folder') { 803 node = Y.Node.create('<iframe></iframe>').setStyles({ 804 visibility : 'hidden', 805 width : '1px', 806 height : '1px' 807 }); 808 node.set('src', this.selectui.fileinfo.url); 809 Y.one('body').appendChild(node); 810 } 811 }, this); 812 selectnode.one('.fp-file-delete').on('click', function(e) { 813 e.preventDefault(); 814 var dialog_options = {}; 815 var params = {}; 816 var fileinfo = this.selectui.fileinfo; 817 dialog_options.scope = this; 818 params.filepath = fileinfo.filepath; 819 if (fileinfo.type == 'folder') { 820 params.filename = '.'; 821 dialog_options.message = M.util.get_string('confirmdeletefolder', 'repository'); 822 } else { 823 params.filename = fileinfo.fullname; 824 if (fileinfo.refcount) { 825 dialog_options.message = M.util.get_string('confirmdeletefilewithhref', 'repository', fileinfo.refcount); 826 } else { 827 dialog_options.message = M.util.get_string('confirmdeletefile', 'repository'); 828 } 829 } 830 dialog_options.callbackargs = [params]; 831 dialog_options.callback = function(params) { 832 //selectnode.addClass('loading'); 833 this.request({ 834 action: 'delete', 835 scope: this, 836 params: params, 837 callback: function(id, obj, args) { 838 //args.scope.selectui.hide(); 839 args.scope.filecount--; 840 args.scope.refresh(obj.filepath); 841 if (typeof M.core_formchangechecker != 'undefined') { 842 M.core_formchangechecker.set_form_changed(); 843 } 844 } 845 }); 846 }; 847 this.selectui.hide(); // TODO remove this after confirm dialog is replaced with YUI3 848 this.show_confirm_dialog(dialog_options); 849 }, this); 850 selectnode.one('.fp-file-zip').on('click', function(e) { 851 e.preventDefault(); 852 var params = {}; 853 var fileinfo = this.selectui.fileinfo; 854 if (fileinfo.type != 'folder') { 855 // this button should not even be shown 856 return; 857 } 858 params['filepath'] = fileinfo.filepath; 859 params['filename'] = '.'; 860 selectnode.addClass('loading'); 861 this.request({ 862 action: 'zip', 863 scope: this, 864 params: params, 865 callback: function(id, obj, args) { 866 args.scope.selectui.hide(); 867 args.scope.refresh(obj.filepath); 868 } 869 }); 870 }, this); 871 selectnode.one('.fp-file-unzip').on('click', function(e) { 872 e.preventDefault(); 873 var params = {}; 874 var fileinfo = this.selectui.fileinfo; 875 if (fileinfo.type != 'zip') { 876 // this button should not even be shown 877 return; 878 } 879 params['filepath'] = fileinfo.filepath; 880 params['filename'] = fileinfo.fullname; 881 selectnode.addClass('loading'); 882 this.request({ 883 action: 'unzip', 884 scope: this, 885 params: params, 886 callback: function(id, obj, args) { 887 args.scope.selectui.hide(); 888 args.scope.refresh(obj.filepath); 889 } 890 }); 891 }, this); 892 selectnode.one('.fp-file-setmain').on('click', function(e) { 893 e.preventDefault(); 894 var params = {}; 895 var fileinfo = this.selectui.fileinfo; 896 if (!this.enablemainfile || fileinfo.type == 'folder') { 897 // this button should not even be shown for folders or when mainfile is disabled 898 return; 899 } 900 params['filepath'] = fileinfo.filepath; 901 params['filename'] = fileinfo.fullname; 902 selectnode.addClass('loading'); 903 this.request({ 904 action: 'setmainfile', 905 scope: this, 906 params: params, 907 callback: function(id, obj, args) { 908 args.scope.selectui.hide(); 909 args.scope.refresh(fileinfo.filepath); 910 } 911 }); 912 }, this); 913 selectnode.all('.fp-file-cancel').on('click', function(e) { 914 e.preventDefault(); 915 // TODO if changed asked to confirm, the same with close button 916 this.selectui.hide(); 917 }, this); 918 }, 919 get_parent_folder_name: function(node) { 920 if (node.type != 'folder' || node.filepath.length < node.fullname.length+1) { 921 return node.filepath; 922 } 923 var basedir = node.filepath.substr(0, node.filepath.length - node.fullname.length - 1); 924 var lastdir = node.filepath.substr(node.filepath.length - node.fullname.length - 2); 925 if (lastdir == '/' + node.fullname + '/') { 926 return basedir; 927 } 928 return node.filepath; 929 }, 930 select_file: function(node) { 931 if (this.is_disabled()) { 932 return; 933 } 934 var selectnode = this.selectnode; 935 selectnode.removeClass('loading').removeClass('fp-folder'). 936 removeClass('fp-file').removeClass('fp-zip').removeClass('fp-cansetmain'); 937 if (node.type == 'folder' || node.type == 'zip') { 938 selectnode.addClass('fp-'+node.type); 939 } else { 940 selectnode.addClass('fp-file'); 941 } 942 if (this.enablemainfile && (node.sortorder != 1) && node.type == 'file') { 943 selectnode.addClass('fp-cansetmain'); 944 } 945 this.selectui.fileinfo = node; 946 selectnode.one('.fp-saveas input').set('value', node.fullname); 947 var foldername = this.get_parent_folder_name(node); 948 selectnode.all('.fp-author input').set('value', node.author ? node.author : ''); 949 selectnode.all('.fp-license select option[selected]').set('selected', false); 950 selectnode.all('.fp-license select option[value='+node.license+']').set('selected', true); 951 selectnode.all('.fp-path select option[selected]').set('selected', false); 952 selectnode.all('.fp-path select option').each(function(el){ 953 if (el.get('value') == foldername) { 954 el.set('selected', true); 955 } 956 }); 957 selectnode.all('.fp-author input, .fp-license select').set('disabled',(node.type == 'folder')?'disabled':''); 958 // display static information about a file (when known) 959 var attrs = ['datemodified','datecreated','size','dimensions','original','reflist']; 960 for (var i in attrs) { 961 if (selectnode.one('.fp-'+attrs[i])) { 962 var value = (node[attrs[i]+'_f']) ? node[attrs[i]+'_f'] : (node[attrs[i]] ? node[attrs[i]] : ''); 963 // Escape if the attribute being evaluated is not for the list of reference files. 964 if (attrs[i] !== 'reflist') { 965 value = Y.Escape.html(value); 966 } 967 selectnode.one('.fp-'+attrs[i]).addClassIf('fp-unknown', ''+value == '') 968 .one('.fp-value').setContent(value); 969 } 970 } 971 // display thumbnail 972 var imgnode = Y.Node.create('<img/>'). 973 set('src', node.realthumbnail ? node.realthumbnail : node.thumbnail). 974 setStyle('maxHeight', ''+(node.thumbnail_height ? node.thumbnail_height : 90)+'px'). 975 setStyle('maxWidth', ''+(node.thumbnail_width ? node.thumbnail_width : 90)+'px'); 976 selectnode.one('.fp-thumbnail').setContent('').appendChild(imgnode); 977 // load original location if applicable 978 if (node.isref && !node.original) { 979 selectnode.one('.fp-original').removeClass('fp-unknown').addClass('fp-loading'); 980 this.request({ 981 action: 'getoriginal', 982 scope: this, 983 params: {'filepath':node.filepath,'filename':node.fullname}, 984 callback: function(id, obj, args) { 985 // check if we did not select another file meanwhile 986 var scope = args.scope; 987 if (scope.selectui.fileinfo && node && 988 scope.selectui.fileinfo.filepath == node.filepath && 989 scope.selectui.fileinfo.fullname == node.fullname) { 990 selectnode.one('.fp-original').removeClass('fp-loading'); 991 if (obj.original) { 992 node.original = obj.original; 993 selectnode.one('.fp-original .fp-value').setContent(Y.Escape.html(node.original)); 994 } else { 995 selectnode.one('.fp-original .fp-value').setContent(M.util.get_string('unknownsource', 'repository')); 996 } 997 } 998 } 999 }, false); 1000 } 1001 // load references list if applicable 1002 selectnode.one('.fp-refcount').setContent(node.refcount ? M.util.get_string('referencesexist', 'repository', node.refcount) : ''); 1003 if (node.refcount && !node.reflist) { 1004 selectnode.one('.fp-reflist').removeClass('fp-unknown').addClass('fp-loading'); 1005 this.request({ 1006 action: 'getreferences', 1007 scope: this, 1008 params: {'filepath':node.filepath,'filename':node.fullname}, 1009 callback: function(id, obj, args) { 1010 // check if we did not select another file meanwhile 1011 var scope = args.scope; 1012 if (scope.selectui.fileinfo && node && 1013 scope.selectui.fileinfo.filepath == node.filepath && 1014 scope.selectui.fileinfo.fullname == node.fullname) { 1015 selectnode.one('.fp-reflist').removeClass('fp-loading'); 1016 if (obj.references) { 1017 node.reflist = ''; 1018 for (var i in obj.references) { 1019 node.reflist += '<li>'+Y.Escape.html(obj.references[i])+'</li>'; 1020 } 1021 selectnode.one('.fp-reflist .fp-value').setContent(node.reflist); 1022 } else { 1023 selectnode.one('.fp-reflist .fp-value').setContent(''); 1024 } 1025 } 1026 } 1027 }, false); 1028 } 1029 // update dialog header 1030 var nodename = node.fullname; 1031 // Limit the string length so it fits nicely on mobile devices 1032 var namelength = 50; 1033 if (nodename.length > namelength) { 1034 nodename = nodename.substring(0, namelength) + '...'; 1035 } 1036 Y.one('#fm-dialog-label_'+selectnode.get('id')).setContent(Y.Escape.html(M.util.get_string('edit', 'moodle')+' '+nodename)); 1037 // show panel 1038 this.selectui.show(); 1039 Y.one('#'+selectnode.get('id')).focus(); 1040 }, 1041 render: function() { 1042 this.print_path(); 1043 this.view_files(); 1044 }, 1045 has_folder: function(foldername) { 1046 var element; 1047 for (var i in this.options.list) { 1048 element = this.options.list[i]; 1049 if (element.type == 'folder' && element.fullname == foldername) { 1050 return true; 1051 } 1052 } 1053 return false; 1054 } 1055 }); 1056 1057 // finally init everything needed 1058 // hide loading picture, display filemanager interface 1059 var filemanager = Y.one('#filemanager-'+options.client_id); 1060 filemanager.removeClass('fm-loading').addClass('fm-loaded'); 1061 1062 var manager = new FileManagerHelper(options); 1063 var dndoptions = { 1064 filemanager: manager, 1065 acceptedtypes: options.filepicker.accepted_types, 1066 clientid: options.client_id, 1067 author: options.author, 1068 maxfiles: options.maxfiles, 1069 maxbytes: options.maxbytes, 1070 areamaxbytes: options.areamaxbytes, 1071 itemid: options.itemid, 1072 repositories: manager.filepicker_options.repositories, 1073 containerid: manager.dndcontainer.get('id'), 1074 contextid: options.context.id 1075 }; 1076 M.form_dndupload.init(Y, dndoptions); 1077 };
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |