[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/form/ -> filemanager.js (source)

   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  };


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1