[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
1 /* global plupload, BP_Uploader, _, JSON, Backbone */ 2 3 window.wp = window.wp || {}; 4 window.bp = window.bp || {}; 5 6 ( function( bp, $ ) { 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 89 drop_element.on( 'dragover.wp-uploader', function() { 90 container.addClass( 'drag-over' ); 91 } ); 92 93 drop_element.on( 'dragleave.wp-uploader, drop.wp-uploader', function() { 94 container.removeClass( 'drag-over' ); 95 } ); 96 } else { 97 container.removeClass( 'drag-drop' ); 98 drop_element.off( '.wp-uploader' ); 99 } 100 101 } ); 102 103 // See https://core.trac.wordpress.org/ticket/37039. 104 this.uploader.bind( 'postinit', function( up ) { 105 up.refresh(); 106 }); 107 108 // Init BuddyPress Uploader. 109 this.uploader.init(); 110 111 /** 112 * Feedback callback. 113 * 114 * Add a new message to the errors collection, so it's possible 115 * to give some feedback to the user. 116 * 117 * @param {string} message 118 * @param {object} data 119 * @param {plupload.File} file File that was uploaded. 120 */ 121 this.feedback = function( message, data, file ) { 122 if ( ! _.isNull( file ) && file.item ) { 123 file.item.clear(); 124 } 125 126 bp.Uploader.filesError.unshift( { 127 message: message, 128 data: data, 129 file: file 130 } ); 131 }; 132 133 /** 134 * After files were filtered and added to the queue, create a model for each. 135 * 136 * @event FilesAdded 137 * @param {plupload.Uploader} uploader Uploader instance. 138 * @param {Array} files Array of file objects that were added to queue by the user. 139 */ 140 this.uploader.bind( 'FilesAdded', function( uploader, files ) { 141 var hundredmb = 100 * 1024 * 1024, max = parseInt( uploader.settings.max_file_size, 10 ), 142 _this = this; 143 144 /** 145 * In case the multiple selection is false (eg: avatar) stop the process and send 146 * and event containing a warning. 147 */ 148 if ( ! uploader.settings.multi_selection && files.length > 1 ) { 149 for ( var i in files ) { 150 uploader.removeFile( files[i] ); 151 } 152 153 $( self ).trigger( 'bp-uploader-warning', self.strings.unique_file_warning ); 154 return; 155 } 156 157 _.each( files, function( file ) { 158 var attributes; 159 160 // Ignore failed uploads. 161 if ( plupload.FAILED === file.status ) { 162 return; 163 } 164 165 if ( max > hundredmb && file.size > hundredmb && uploader.runtime !== 'html5' ) { 166 _this.uploadSizeError( uploader, file, true ); 167 } else { 168 attributes = _.extend( { 169 id: file.id, 170 file: file, 171 uploading: true, 172 date: new Date(), 173 filename: file.name 174 }, _.pick( file, 'loaded', 'size', 'percent' ) ); 175 176 file.item = new bp.Models.File( attributes ); 177 bp.Uploader.filesQueue.add( file.item ); 178 } 179 180 } ); 181 182 uploader.refresh(); 183 uploader.start(); 184 } ); 185 186 /** 187 * Update each file item on progress. 188 * 189 * @event UploadProgress 190 * @param {plupload.Uploader} uploader Uploader instance. 191 * @param {Object} file 192 */ 193 this.uploader.bind( 'UploadProgress', function( uploader, file ) { 194 file.item.set( _.pick( file, 'loaded', 'percent' ) ); 195 } ); 196 197 /** 198 * After a file is successfully uploaded, update its model. 199 * 200 * @event FileUploaded 201 * @param {plupload.Uploader} uploader Uploader instance. 202 * @param {plupload.File} file File that was uploaded. 203 * @param {Object} response Object with response properties. 204 * @return {mixed} 205 */ 206 this.uploader.bind( 'FileUploaded', function( uploader, file, response ) { 207 var message = self.strings.default_error; 208 209 try { 210 response = JSON.parse( response.response ); 211 } catch ( e ) { 212 return self.feedback( message, e, file ); 213 } 214 215 if ( ! _.isObject( response ) || _.isUndefined( response.success ) ) { 216 return self.feedback( message, null, file ); 217 } else if ( ! response.success ) { 218 if ( response.data && response.data.message ) { 219 message = response.data.message; 220 } 221 222 return self.feedback( message, response.data, file ); 223 } 224 225 _.each(['file','loaded','size','percent'], function( key ) { 226 file.item.unset( key ); 227 } ); 228 229 file.item.set( _.extend( response.data, { uploading: false } ) ); 230 231 // Add the file to the Uploaded ones. 232 bp.Uploader.filesUploaded.add( file.item ); 233 234 } ); 235 236 /** 237 * Trigger an event to inform a new upload is being processed. 238 * 239 * Mainly used to remove an eventual warning. 240 * 241 * @event BeforeUpload 242 * @param {plupload.Uploader} uploader Uploader instance. 243 * @param {Array} files Array of file objects that were added to queue by the user. 244 */ 245 this.uploader.bind( 'BeforeUpload', function( uploader, files ) { 246 $( self ).trigger( 'bp-uploader-new-upload', uploader, files ); 247 } ); 248 249 /** 250 * Reset the filesQueue once the upload is complete. 251 * 252 * @event BeforeUpload 253 * @param {plupload.Uploader} uploader Uploader instance. 254 * @param {Array} files Array of file objects that were added to queue by the user. 255 */ 256 this.uploader.bind( 'UploadComplete', function( uploader, files ) { 257 $( self ).trigger( 'bp-uploader-upload-complete', uploader, files ); 258 bp.Uploader.filesQueue.reset(); 259 } ); 260 261 /** 262 * Map Plupload errors & Create a warning when plupload failed. 263 * 264 * @event Error 265 * @param {plupload.Uploader} uploader Uploader instance. 266 * @param {Object} pluploadError Plupload error 267 */ 268 this.uploader.bind( 'Error', function( uploader, pluploadError ) { 269 var message = self.strings.default_error, 270 key, 271 errors = { 272 'FAILED': self.strings.upload_failed, 273 'FILE_EXTENSION_ERROR': self.strings.invalid_filetype, 274 'IMAGE_FORMAT_ERROR': self.strings.not_an_image, 275 'IMAGE_MEMORY_ERROR': self.strings.image_memory_exceeded, 276 'IMAGE_DIMENSIONS_ERROR': self.strings.image_dimensions_exceeded, 277 'GENERIC_ERROR': self.strings.upload_failed, 278 'IO_ERROR': self.strings.io_error, 279 'HTTP_ERROR': self.strings.http_error, 280 'SECURITY_ERROR': self.strings.security_error, 281 'FILE_SIZE_ERROR': self.strings.file_exceeds_size_limit.replace( '%s' , $( '<span />' ).text( pluploadError.file.name ).html() ) 282 }; 283 284 // Check for plupload errors. 285 for ( key in errors ) { 286 if ( pluploadError.code === plupload[ key ] ) { 287 message = errors[ key ]; 288 break; 289 } 290 } 291 292 $( self ).trigger( 'bp-uploader-warning', message ); 293 uploader.refresh(); 294 } ); 295 }; 296 297 // Create a very generic Model for files. 298 bp.Models.File = Backbone.Model.extend( { 299 file: {} 300 } ); 301 302 // Add Collections to store queue, uploaded files and errors. 303 $.extend( bp.Uploader, { 304 filesQueue : new Backbone.Collection(), 305 filesUploaded : new Backbone.Collection(), 306 filesError : new Backbone.Collection() 307 } ); 308 309 // Extend wp.Backbone.View with .prepare() and .inject(). 310 bp.View = bp.Backbone.View.extend( { 311 inject: function( selector ) { 312 this.render(); 313 $(selector).html( this.el ); 314 this.views.ready(); 315 }, 316 317 prepare: function() { 318 if ( ! _.isUndefined( this.model ) && _.isFunction( this.model.toJSON ) ) { 319 return this.model.toJSON(); 320 } else { 321 return {}; 322 } 323 } 324 } ); 325 326 // BuddyPress Uploader main view. 327 bp.Views.Uploader = bp.View.extend( { 328 className: 'bp-uploader-window', 329 template: bp.template( 'upload-window' ), 330 331 defaults: _.pick( BP_Uploader.settings.defaults, 'container', 'drop_element', 'browse_button' ), 332 333 initialize: function() { 334 this.warnings = []; 335 this.model = new Backbone.Model( this.defaults ); 336 this.on( 'ready', this.initUploader ); 337 }, 338 339 initUploader: function() { 340 this.uploader = new bp.Uploader.uploader(); 341 $( this.uploader ).on( 'bp-uploader-warning', _.bind( this.setWarning, this ) ); 342 $( this.uploader ).on( 'bp-uploader-new-upload', _.bind( this.resetWarning, this ) ); 343 }, 344 345 setWarning: function( event, message ) { 346 if ( _.isUndefined( message ) ) { 347 return; 348 } 349 350 var warning = new bp.Views.uploaderWarning( { 351 value: message 352 } ).render(); 353 354 this.warnings.push( warning ); 355 356 this.$el.after( warning.el ); 357 }, 358 359 resetWarning: function() { 360 if ( 0 === this.warnings.length ) { 361 return; 362 } 363 364 // Remove all warning views. 365 _.each( this.warnings, function( view ) { 366 view.remove(); 367 } ); 368 369 // Reset Warnings. 370 this.warnings = []; 371 } 372 } ); 373 374 // BuddyPress Uploader warning view. 375 bp.Views.uploaderWarning = bp.View.extend( { 376 tagName: 'p', 377 className: 'warning', 378 379 initialize: function() { 380 this.value = this.options.value; 381 }, 382 383 render: function() { 384 this.$el.html( this.value ); 385 return this; 386 } 387 } ); 388 389 // BuddyPress Uploader Files view. 390 bp.Views.uploaderStatus = bp.View.extend( { 391 className: 'files', 392 393 initialize: function() { 394 _.each( this.collection.models, this.addFile, this ); 395 this.collection.on( 'change:percent', this.progress, this ); 396 bp.Uploader.filesError.on( 'add', this.feedback, this ); 397 }, 398 399 addFile: function( file ) { 400 this.views.add( new bp.Views.uploaderProgress( { model: file } ) ); 401 }, 402 403 progress:function( model ) { 404 if ( ! _.isUndefined( model.get( 'percent' ) ) ) { 405 $( '#' + model.get('id') + ' .bp-progress .bp-bar' ).css( 'width', model.get('percent') + '%' ); 406 } 407 }, 408 409 feedback: function( model ) { 410 if ( ! _.isUndefined( model.get( 'message' ) ) && ! _.isUndefined( model.get( 'file' ) ) ) { 411 $( '#' + model.get( 'file' ).id ).html( model.get( 'message' ) ).addClass( 'error' ); 412 } 413 } 414 } ); 415 416 // BuddyPress Uploader File progress view. 417 bp.Views.uploaderProgress = bp.View.extend( { 418 className: 'bp-uploader-progress', 419 template: bp.template( 'progress-window' ) 420 } ); 421 422 })( window.bp, jQuery );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:57 2024 | Cross-referenced by PHPXref 0.7.1 |