浏览代码

Added the possibility to pass the context to off().

fredck 10 年之前
父节点
当前提交
844b27c2d0
共有 2 个文件被更改,包括 48 次插入4 次删除
  1. 8 4
      packages/ckeditor5-ui/src/emitter.js
  2. 40 0
      packages/ckeditor5-ui/tests/emitter/emitter.js

+ 8 - 4
packages/ckeditor5-ui/src/emitter.js

@@ -79,8 +79,10 @@ CKEDITOR.define( [ 'eventinfo', 'utils' ], function( EventInfo, utils ) {
 		 *
 		 * @param {String} event The name of the event.
 		 * @param {Function} callback The function to stop being called.
+		 * @param {Object} [ctx] The context object to be removed, pared with the given callback. To handle cases where
+		 * the same callback is used several times with different contexts.
 		 */
-		off: function( event, callback ) {
+		off: function( event, callback, ctx ) {
 			var callbacks = getCallbacksIfAny( this, event );
 
 			if ( !callbacks ) {
@@ -89,9 +91,11 @@ CKEDITOR.define( [ 'eventinfo', 'utils' ], function( EventInfo, utils ) {
 
 			for ( var i = 0; i < callbacks.length; i++ ) {
 				if ( callbacks[ i ].callback == callback ) {
-					// Remove the callback from the list (fixing the next index).
-					callbacks.splice( i, 1 );
-					i--;
+					if ( !ctx || ctx == callbacks[ i ].ctx ) {
+						// Remove the callback from the list (fixing the next index).
+						callbacks.splice( i, 1 );
+						i--;
+					}
 				}
 			}
 		},

+ 40 - 0
packages/ckeditor5-ui/tests/emitter/emitter.js

@@ -251,6 +251,46 @@ describe( 'off', function() {
 	it( 'should not fail with unknown events', function() {
 		emitter.off( 'test', function() {} );
 	} );
+
+	it( 'should remove all entries for the same callback', function() {
+		var spy1 = sinon.spy().named( 1 );
+		var spy2 = sinon.spy().named( 2 );
+
+		emitter.on( 'test', spy1 );
+		emitter.on( 'test', spy2 );
+		emitter.on( 'test', spy1 );
+		emitter.on( 'test', spy2 );
+
+		emitter.fire( 'test' );
+
+		emitter.off( 'test', spy1 );
+
+		emitter.fire( 'test' );
+
+		sinon.assert.callCount( spy1, 2 );
+		sinon.assert.callCount( spy2, 4 );
+	} );
+
+	it( 'should remove the callback for a specific context only', function() {
+		var spy = sinon.spy().named( 1 );
+
+		var ctx1 = { ctx: 1 };
+		var ctx2 = { ctx: 2 };
+
+		emitter.on( 'test', spy, ctx1 );
+		emitter.on( 'test', spy, ctx2 );
+
+		emitter.fire( 'test' );
+
+		spy.reset();
+
+		emitter.off( 'test', spy, ctx1 );
+
+		emitter.fire( 'test' );
+
+		sinon.assert.calledOnce( spy );
+		sinon.assert.calledOn( spy, ctx2 );
+	} );
 } );
 
 describe( 'listenTo', function() {