[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-core/js/ -> bp-plupload.js (source)

   1  /* global bp, plupload, BP_Uploader, _, JSON, Backbone */
   2  
   3  window.wp = window.wp || {};
   4  window.bp = window.bp || {};
   5  
   6  ( function( exports, $ ) {
   7  
   8      // Bail if not set
   9      if ( typeof BP_Uploader === 'undefined' ) {
  10          return;
  11      }
  12  
  13      /**
  14       * Extend the bp global with what we need from the wp one.
  15       * and make sure previously defined BuddyPress attributes
  16       * are not removed (eg: bp.mentions)
  17       */
  18      _.extend( bp, _.pick( wp, 'Backbone', 'ajax', 'template' ) );
  19  
  20      // Init Models, Collections, Views and the BuddyPress Uploader
  21      bp.Models      = bp.Models || {};
  22      bp.Collections = bp.Collections || {};
  23      bp.Views       = bp.Views || {};
  24      bp.Uploader    = {};
  25  
  26      /**
  27       * BuddyPress Uploader.
  28       *
  29       * This is an adapted version of wp.Uploader
  30       */
  31      bp.Uploader.uploader = function() {
  32          var self = this,
  33              isIE = navigator.userAgent.indexOf('Trident/') !== -1 || navigator.userAgent.indexOf('MSIE ') !== -1;
  34  
  35          this.params  = BP_Uploader.settings;
  36          this.strings = BP_Uploader.strings;
  37  
  38          this.supports = {
  39              upload: this.params.browser.supported
  40          };
  41  
  42          this.supported = this.supports.upload;
  43  
  44          if ( ! this.supported ) {
  45              /*jshint -W020 */
  46              BP_Uploader = undefined;
  47              return;
  48          }
  49  
  50          // Make sure flash sends cookies (seems in IE it does without switching to urlstream mode)
  51          if ( ! isIE && 'flash' === plupload.predictRuntime( this.params.defaults ) &&
  52              ( ! this.params.defaults.required_features || ! this.params.defaults.required_features.hasOwnProperty( 'send_binary_string' ) ) ) {
  53  
  54              this.params.defaults.required_features = this.params.defaults.required_features || {};
  55              this.params.defaults.required_features.send_binary_string = true;
  56          }
  57  
  58          this.uploader = new plupload.Uploader( this.params.defaults );
  59  
  60          /**
  61           * After the Uploader has been initialized, initialize some behaviors for the dropzone.
  62           *
  63           * @event Init
  64           * @param {plupload.Uploader} uploader Uploader instance.
  65           */
  66          this.uploader.bind( 'Init', function( uploader ) {
  67              var container    = $( '#' + self.params.defaults.container ),
  68                  drop_element = $( '#' + self.params.defaults.drop_element );
  69  
  70              if ( 'html4' === uploader.runtime ) {
  71                  uploader.settings.multipart_params.html4 = true;
  72              }
  73  
  74              /**
  75               * Avatars need to be cropped, by default we are using an original
  76               * max width of 450px, but there can be cases when this max width
  77               * is larger than the one of the Avatar UI (eg: on mobile). To avoid any
  78               * difficulties, we're adding a ui_available_width argument to the bp_params
  79               * object and set it according to the container width. This value will be
  80               * checked during the upload process to eventually adapt the resized avatar.
  81               */
  82              if ( 'bp_avatar_upload' ===  uploader.settings.multipart_params.action ) {
  83                   uploader.settings.multipart_params.bp_params.ui_available_width = container.width();
  84              }
  85  
  86              if ( uploader.features.dragdrop && ! self.params.browser.mobile ) {
  87                  container.addClass( 'drag-drop' );
  88                  drop_element.bind( 'dragover.wp-uploader', function() {
  89                      container.addClass( 'drag-over' );
  90                  } ).bind( 'dragleave.wp-uploader, drop.wp-uploader', function() {
  91                      container.removeClass( 'drag-over' );
  92                  } );
  93              } else {
  94                  container.removeClass( 'drag-drop' );
  95                  drop_element.unbind( '.wp-uploader' );
  96              }
  97  
  98          } );
  99  
 100          // See https://core.trac.wordpress.org/ticket/37039
 101          this.uploader.bind( 'postinit', function( up ) {
 102              up.refresh();
 103          });
 104  
 105          // Init BuddyPress Uploader
 106          this.uploader.init();
 107  
 108          /**
 109           * Feedback callback.
 110           *
 111           * Add a new message to the errors collection, so it's possible
 112           * to give some feedback to the user
 113           *
 114           * @param  {string}        message
 115           * @param  {object}        data
 116           * @param  {plupload.File} file     File that was uploaded.
 117           */
 118          this.feedback = function( message, data, file ) {
 119              if ( ! _.isNull( file ) && file.item ) {
 120                  file.item.clear();
 121              }
 122  
 123              bp.Uploader.filesError.unshift( {
 124                  message: message,
 125                  data:    data,
 126                  file:    file
 127              } );
 128          };
 129  
 130          /**
 131           * After files were filtered and added to the queue, create a model for each.
 132           *
 133           * @event FilesAdded
 134           * @param {plupload.Uploader} uploader Uploader instance.
 135           * @param {Array}             files    Array of file objects that were added to queue by the user.
 136           */
 137          this.uploader.bind( 'FilesAdded', function( uploader, files ) {
 138              var hundredmb = 100 * 1024 * 1024, max = parseInt( uploader.settings.max_file_size, 10 ),
 139                  _this = this;
 140  
 141              /**
 142               * In case the multiple selection is false (eg: avatar) stop the process and send
 143               * and event containing a warning
 144               */
 145              if ( ! uploader.settings.multi_selection && files.length > 1 ) {
 146                  for ( var i in files ) {
 147                      uploader.removeFile( files[i] );
 148                  }
 149  
 150                  $( self ).trigger( 'bp-uploader-warning', self.strings.unique_file_warning );
 151                  return;
 152              }
 153  
 154              _.each( files, function( file ) {
 155                  var attributes;
 156  
 157                  // Ignore failed uploads.
 158                  if ( plupload.FAILED === file.status ) {
 159                      return;
 160                  }
 161  
 162                  if ( max > hundredmb && file.size > hundredmb && uploader.runtime !== 'html5' ) {
 163                      _this.uploadSizeError( uploader, file, true );
 164                  } else {
 165                      attributes = _.extend( {
 166                          id:        file.id,
 167                          file:      file,
 168                          uploading: true,
 169                          date:      new Date(),
 170                          filename:  file.name
 171                      }, _.pick( file, 'loaded', 'size', 'percent' ) );
 172  
 173                      file.item = new bp.Models.File( attributes );
 174                      bp.Uploader.filesQueue.add( file.item );
 175                  }
 176  
 177              } );
 178  
 179              uploader.refresh();
 180              uploader.start();
 181          } );
 182  
 183          /**
 184           * Update each file item on progress
 185           *
 186           * @event UploadProgress
 187           * @param {plupload.Uploader} uploader Uploader instance.
 188           * @param {Object}            file
 189           */
 190          this.uploader.bind( 'UploadProgress', function( uploader, file ) {
 191              file.item.set( _.pick( file, 'loaded', 'percent' ) );
 192          } );
 193  
 194          /**
 195           * After a file is successfully uploaded, update its model.
 196           *
 197           * @event FileUploaded
 198           * @param {plupload.Uploader} uploader Uploader instance.
 199           * @param {plupload.File}     file     File that was uploaded.
 200           * @param {Object}            response Object with response properties.
 201           * @return {mixed}
 202           */
 203          this.uploader.bind( 'FileUploaded', function( uploader, file, response ) {
 204              var message = self.strings.default_error;
 205  
 206              try {
 207                  response = JSON.parse( response.response );
 208              } catch ( e ) {
 209                  return self.feedback( message, e, file );
 210              }
 211  
 212              if ( ! _.isObject( response ) || _.isUndefined( response.success ) ) {
 213                  return self.feedback( message, null, file );
 214              } else if ( ! response.success ) {
 215                  if ( response.data && response.data.message ) {
 216                      message = response.data.message;
 217                  }
 218  
 219                  return self.feedback( message, response.data, file );
 220              }
 221  
 222              _.each(['file','loaded','size','percent'], function( key ) {
 223                  file.item.unset( key );
 224              } );
 225  
 226              file.item.set( _.extend( response.data, { uploading: false } ) );
 227  
 228              //  Add the file to the Uploaded ones
 229              bp.Uploader.filesUploaded.add( file.item );
 230  
 231          } );
 232  
 233          /**
 234           * Trigger an event to inform a new upload is being processed
 235           *
 236           * Mainly used to remove an eventual warning
 237           *
 238           * @event BeforeUpload
 239           * @param {plupload.Uploader} uploader Uploader instance.
 240           * @param {Array}             files    Array of file objects that were added to queue by the user.
 241           */
 242          this.uploader.bind( 'BeforeUpload', function( uploader, files ) {
 243              $( self ).trigger( 'bp-uploader-new-upload', uploader, files );
 244          } );
 245  
 246          /**
 247           * Reset the filesQueue once the upload is complete
 248           *
 249           * @event BeforeUpload
 250           * @param {plupload.Uploader} uploader Uploader instance.
 251           * @param {Array}             files    Array of file objects that were added to queue by the user.
 252           */
 253          this.uploader.bind( 'UploadComplete', function( uploader, files ) {
 254              $( self ).trigger( 'bp-uploader-upload-complete', uploader, files );
 255              bp.Uploader.filesQueue.reset();
 256          } );
 257  
 258          /**
 259           * Map Plupload errors & Create a warning when plupload failed
 260           *
 261           * @event Error
 262           * @param {plupload.Uploader} uploader Uploader instance.
 263           * @param {Object}            pluploadError Plupload error
 264           */
 265          this.uploader.bind( 'Error', function( uploader, pluploadError ) {
 266              var message = self.strings.default_error,
 267                  key,
 268                  errors = {
 269                      'FAILED':                 self.strings.upload_failed,
 270                      'FILE_EXTENSION_ERROR':   self.strings.invalid_filetype,
 271                      'IMAGE_FORMAT_ERROR':     self.strings.not_an_image,
 272                      'IMAGE_MEMORY_ERROR':     self.strings.image_memory_exceeded,
 273                      'IMAGE_DIMENSIONS_ERROR': self.strings.image_dimensions_exceeded,
 274                      'GENERIC_ERROR':          self.strings.upload_failed,
 275                      'IO_ERROR':               self.strings.io_error,
 276                      'HTTP_ERROR':             self.strings.http_error,
 277                      'SECURITY_ERROR':         self.strings.security_error,
 278                      'FILE_SIZE_ERROR':        self.strings.file_exceeds_size_limit.replace( '%s' , $( '<span />' ).text( pluploadError.file.name ).html() )
 279                  };
 280  
 281              // Check for plupload errors.
 282              for ( key in errors ) {
 283                  if ( pluploadError.code === plupload[ key ] ) {
 284                      message = errors[ key ];
 285                      break;
 286                  }
 287              }
 288  
 289              $( self ).trigger( 'bp-uploader-warning', message );
 290              uploader.refresh();
 291          } );
 292      };
 293  
 294      // Create a very generic Model for files
 295      bp.Models.File = Backbone.Model.extend( {
 296          file: {}
 297      } );
 298  
 299      // Add Collections to store queue, uploaded files and errors
 300      $.extend( bp.Uploader, {
 301          filesQueue    : new Backbone.Collection(),
 302          filesUploaded : new Backbone.Collection(),
 303          filesError    : new Backbone.Collection()
 304      } );
 305  
 306      // Extend wp.Backbone.View with .prepare() and .inject()
 307      bp.View = bp.Backbone.View.extend( {
 308          inject: function( selector ) {
 309              this.render();
 310              $(selector).html( this.el );
 311              this.views.ready();
 312          },
 313  
 314          prepare: function() {
 315              if ( ! _.isUndefined( this.model ) && _.isFunction( this.model.toJSON ) ) {
 316                  return this.model.toJSON();
 317              } else {
 318                  return {};
 319              }
 320          }
 321      } );
 322  
 323      // BuddyPress Uploader main view
 324      bp.Views.Uploader = bp.View.extend( {
 325          className: 'bp-uploader-window',
 326          template: bp.template( 'upload-window' ),
 327  
 328          defaults: _.pick( BP_Uploader.settings.defaults, 'container', 'drop_element', 'browse_button' ),
 329  
 330          initialize: function() {
 331              this.warnings = [];
 332              this.model    = new Backbone.Model( this.defaults );
 333              this.on( 'ready', this.initUploader );
 334          },
 335  
 336          initUploader: function() {
 337              this.uploader = new bp.Uploader.uploader();
 338              $( this.uploader ).on( 'bp-uploader-warning', _.bind( this.setWarning, this ) );
 339              $( this.uploader ).on( 'bp-uploader-new-upload', _.bind( this.resetWarning, this ) );
 340          },
 341  
 342          setWarning: function( event, message ) {
 343              if ( _.isUndefined( message ) ) {
 344                  return;
 345              }
 346  
 347              var warning = new bp.Views.uploaderWarning( {
 348                  value: message
 349              } ).render();
 350  
 351              this.warnings.push( warning );
 352  
 353              this.$el.after( warning.el );
 354          },
 355  
 356          resetWarning: function() {
 357              if ( 0 === this.warnings.length ) {
 358                  return;
 359              }
 360  
 361              // Remove all warning views
 362              _.each( this.warnings, function( view ) {
 363                  view.remove();
 364              } );
 365  
 366              // Reset Warnings
 367              this.warnings = [];
 368          }
 369      } );
 370  
 371      // BuddyPress Uploader warning view
 372      bp.Views.uploaderWarning = bp.View.extend( {
 373          tagName: 'p',
 374          className: 'warning',
 375  
 376          initialize: function() {
 377              this.value = this.options.value;
 378          },
 379  
 380          render: function() {
 381              this.$el.html( this.value );
 382              return this;
 383          }
 384      } );
 385  
 386      // BuddyPress Uploader Files view
 387      bp.Views.uploaderStatus = bp.View.extend( {
 388          className: 'files',
 389  
 390          initialize: function() {
 391              _.each( this.collection.models, this.addFile, this );
 392              this.collection.on( 'change:percent', this.progress, this );
 393              bp.Uploader.filesError.on( 'add', this.feedback, this );
 394          },
 395  
 396          addFile: function( file ) {
 397              this.views.add( new bp.Views.uploaderProgress( { model: file } ) );
 398          },
 399  
 400          progress:function( model ) {
 401              if ( ! _.isUndefined( model.get( 'percent' ) ) ) {
 402                  $( '#' + model.get('id') + ' .bp-progress .bp-bar' ).css( 'width', model.get('percent') + '%' );
 403              }
 404          },
 405  
 406          feedback: function( model ) {
 407              if ( ! _.isUndefined( model.get( 'message' ) ) && ! _.isUndefined( model.get( 'file' ) ) ) {
 408                  $( '#' + model.get( 'file' ).id ).html( model.get( 'message' ) ).addClass( 'error' );
 409              }
 410          }
 411      } );
 412  
 413      // BuddyPress Uploader File progress view
 414      bp.Views.uploaderProgress = bp.View.extend( {
 415          className: 'bp-uploader-progress',
 416          template: bp.template( 'progress-window' )
 417      } );
 418  
 419  })( bp, jQuery );


Generated: Sat Sep 21 01:01:46 2019 Cross-referenced by PHPXref 0.7.1