JGonera has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/68531


Change subject: EventEmitter tweaks
......................................................................

EventEmitter tweaks

* Prevent accidental object's function calling when emitting events.
* Add #one for callbacks that should be fired only once.
* Don't use $.extend( obj.prototype, EventEmitter.prorotype ), can be
  bug prone (name clashes, EventEmitter constructor not called).

Change-Id: I11de9760fa7e6fe5a0ef57204321689e6fcc6a0b
---
M javascripts/common/eventemitter.js
M javascripts/common/mf-api.js
M javascripts/modules/mf-photo.js
3 files changed, 42 insertions(+), 18 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/MobileFrontend 
refs/changes/31/68531/1

diff --git a/javascripts/common/eventemitter.js 
b/javascripts/common/eventemitter.js
index 783e580..29f8e6b 100644
--- a/javascripts/common/eventemitter.js
+++ b/javascripts/common/eventemitter.js
@@ -1,6 +1,18 @@
 ( function( M, $ ) {
 
-       function EventEmitter() {}
+       function callbackProxy( callback ) {
+               return function() {
+                       var args = Array.prototype.slice.call( arguments, 1 );
+                       callback.apply( callback, args );
+               };
+       }
+
+       function EventEmitter() {
+               // use a separate object for binding events to avoid 
accidentally
+               // invoking object's methods when emitting events, e.g. don't 
call
+               // obj.something() when doing obj.emit( 'something' )
+               this._eventEmitter = $( {} );
+       }
 
        /**
         * Bind a callback to the event.
@@ -9,10 +21,18 @@
         * @param {Function} callback Callback to be bound.
         */
        EventEmitter.prototype.on = function( event, callback ) {
-               $( this ).on( event, function() {
-                       var args = Array.prototype.slice.call( arguments, 1 );
-                       callback.apply( callback, args );
-               } );
+               this._eventEmitter.on( event, callbackProxy( callback ) );
+               return this;
+       };
+
+       /**
+        * Bind a callback to the event and run it only once.
+        *
+        * @param {string} event Event name.
+        * @param {Function} callback Callback to be bound.
+        */
+       EventEmitter.prototype.one = function( event, callback ) {
+               this._eventEmitter.one( event, callbackProxy( callback ) );
                return this;
        };
 
@@ -24,7 +44,7 @@
         */
        EventEmitter.prototype.emit = function( event /* , arg1, arg2, ... */ ) 
{
                var args = Array.prototype.slice.call( arguments, 1 );
-               $( this ).trigger( event, args );
+               this._eventEmitter.trigger( event, args );
                return this;
        };
 
diff --git a/javascripts/common/mf-api.js b/javascripts/common/mf-api.js
index d6958fc..4e772e1 100644
--- a/javascripts/common/mf-api.js
+++ b/javascripts/common/mf-api.js
@@ -20,6 +20,8 @@
                this.initialize( options );
        }
 
+       Api.prototype = new EventEmitter();
+
        // FIXME: make Api and View inherit from an abstract Class object
        /**
         * Constructor that can be overriden.
@@ -74,7 +76,9 @@
                                // need to bind this event before we open the 
connection (see note at
                                // 
https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress)
                                xhr.upload.addEventListener( 'progress', 
function( ev ) {
-                                       request.emit( 'progress', ev );
+                                       if ( ev.lengthComputable ) {
+                                               self.emit( 'progress', request, 
ev.loaded / ev.total );
+                                       }
                                } );
                        }
                        return xhr;
@@ -82,7 +86,6 @@
                */
 
                request = $.ajax( options );
-               $.extend( request, EventEmitter.prototype );
                this.requests.push( request );
                return request;
        };
diff --git a/javascripts/modules/mf-photo.js b/javascripts/modules/mf-photo.js
index 09c81e7..c52c07f 100644
--- a/javascripts/modules/mf-photo.js
+++ b/javascripts/modules/mf-photo.js
@@ -5,7 +5,6 @@
                CtaDrawer = M.require( 'CtaDrawer' ),
                funnel = $.cookie( 'mwUploadsFunnel' ) || 'article',
                showCta = mw.config.get( 'wgMFEnablePhotoUploadCTA' ) || funnel 
=== 'nearby',
-               EventEmitter = M.require( 'eventemitter' ),
                ProgressBar = M.require( 'widgets/progress-bar' ),
                Overlay = M.require( 'Overlay' ),
                ownershipMessage = mw.msg( 'mobile-frontend-photo-ownership', 
mw.config.get( 'wgUserName' ), mw.user ),
@@ -179,7 +178,8 @@
 
                        function doUpload( token ) {
                                var formData = new FormData(),
-                                       ext = options.file.name.slice( 
options.file.name.lastIndexOf( '.' ) + 1 );
+                                       ext = options.file.name.slice( 
options.file.name.lastIndexOf( '.' ) + 1 ),
+                                       request;
 
                                options.fileName = generateFileName( 
options.description, '.' + ext );
 
@@ -201,7 +201,7 @@
                                        } )
                                );
 
-                               self.post( formData, {
+                               request = self.post( formData, {
                                        // iOS seems to ignore the cache 
parameter so sending r parameter
                                        // send useformat=mobile for sites 
where endpoint is a desktop url so that they are mobile edit tagged
                                        url: apiUrl + '?useformat=mobile&r=' + 
Math.random(),
@@ -209,10 +209,6 @@
                                        cache: false,
                                        contentType: false,
                                        processData: false
-                               } ).on( 'progress', function( ev ) {
-                                       if ( ev.lengthComputable ) {
-                                               self.emit( 'progress', 
ev.loaded / ev.total );
-                                       }
                                } ).done( function( data ) {
                                        var descriptionUrl = '',
                                                warnings = data.upload ? 
data.upload.warnings : false;
@@ -253,7 +249,14 @@
                                                result.reject( status + ': ' + 
error );
                                        }
                                } );
+
+                               self.on( 'progress', function( req, progress ) {
+                                       if ( req === request ) {
+                                               self.emit( 'uploadProgress', 
progress );
+                                       }
+                               } );
                        }
+
                        self.getToken( 'edit', endpoint ).done( function( token 
) {
                                doUpload( token );
                        } ).fail( function( err ) {
@@ -263,8 +266,6 @@
                        return result;
                }
        } );
-
-       $.extend( PhotoApi.prototype, EventEmitter.prototype );
 
        LearnMoreOverlay = Overlay.extend( {
                defaults: {
@@ -666,7 +667,7 @@
                                self.emit( 'error' );
                        } );
 
-                       api.on( 'progress', function( value ) {
+                       api.on( 'uploadProgress', function( value ) {
                                progressPopup.setValue( value );
                        } );
                }

-- 
To view, visit https://gerrit.wikimedia.org/r/68531
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I11de9760fa7e6fe5a0ef57204321689e6fcc6a0b
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: JGonera <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to