Przeglądaj źródła

Other: Make `EmitterMixin.off()` use `stopListening()` internally.

Maciej Gołaszewski 8 lat temu
rodzic
commit
57b59c1771

+ 19 - 11
packages/ckeditor5-utils/src/dom/emittermixin.js

@@ -55,9 +55,11 @@ const DomEmitterMixin = extend( {}, EmitterMixin, {
 		// Check if emitter is an instance of DOM Node. If so, replace the argument with
 		// corresponding ProxyEmitter (or create one if not existing).
 		if ( isDomNode( emitter ) ) {
-			emitter = this._getProxyEmitter( emitter ) || new ProxyEmitter( emitter );
+			const proxy = this._getProxyEmitter( emitter ) || new ProxyEmitter( emitter );
 
-			emitter.registerEvent( event, callback, options );
+			proxy.attach( event, callback, options );
+
+			emitter = proxy;
 		}
 
 		// Execute parent class method with Emitter (or ProxyEmitter) instance.
@@ -96,6 +98,10 @@ const DomEmitterMixin = extend( {}, EmitterMixin, {
 
 		// Execute parent class method with Emitter (or ProxyEmitter) instance.
 		EmitterMixin.stopListening.call( this, emitter, event, callback );
+
+		if ( emitter instanceof ProxyEmitter ) {
+			emitter.detach( event, callback );
+		}
 	},
 
 	/**
@@ -173,15 +179,12 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
 	 * @param {String} event The name of the event.
 	 * @param {Function} callback The function to be called on event.
 	 * @param {Object} [options={}] Additional options.
-	 * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of this event callback. The higher
-	 * the priority value the sooner the callback will be fired. Events having the same priority are called in the
-	 * order they were added.
 	 * @param {Boolean} [options.useCapture=false] Indicates that events of this type will be dispatched to the registered
 	 * listener before being dispatched to any EventTarget beneath it in the DOM tree.
 	 *
 	 * @method module:utils/dom/emittermixin~ProxyEmitter#on
 	 */
-	registerEvent( event, callback, options = {} ) {
+	attach( event, callback, options = {} ) {
 		// If the DOM Listener for given event already exist it is pointless
 		// to attach another one.
 		if ( this._domListeners && this._domListeners[ event ] ) {
@@ -206,14 +209,10 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
 	 * Stops executing the callback on the given event.
 	 *
 	 * @param {String} event The name of the event.
-	 * @param {Function} callback The function to stop being called.
 	 *
 	 * @method module:utils/dom/emittermixin~ProxyEmitter#off
 	 */
-	off( event, callback ) {
-		// Execute parent class method first.
-		EmitterMixin.off.call( this, event, callback );
-
+	detach( event ) {
 		let events;
 
 		// Remove native DOM listeners which are orphans. If no callbacks
@@ -264,6 +263,15 @@ function getNodeUID( node ) {
 	return node[ 'data-ck-expando' ] || ( node[ 'data-ck-expando' ] = uid() );
 }
 
+// Checks (naively) if given node is native DOM Node.
+//
+// @private
+// @param {Node} node
+// @return {Boolean} True when native DOM Node.
+function isDomNode( node ) {
+	return !!node && isNative( node.addEventListener );
+}
+
 /**
  * Interface representing classes which mix in {@link module:utils/dom/emittermixin~EmitterMixin}.
  *

+ 25 - 14
packages/ckeditor5-utils/src/emittermixin.js

@@ -80,23 +80,14 @@ const EmitterMixin = {
 
 	/**
 	 * Stops executing the callback on the given event.
+	 * Shorthand for {@link #stopListening this.stopListening( this, event, callback) }.
 	 *
 	 * @method #off
 	 * @param {String} event The name of the event.
 	 * @param {Function} callback The function to stop being called.
 	 */
 	off( event, callback ) {
-		const lists = getCallbacksListsForNamespace( this, event );
-
-		for ( const callbacks of lists ) {
-			for ( let 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--;
-				}
-			}
-		}
+		this.stopListening( this, event, callback );
 	},
 
 	/**
@@ -212,13 +203,14 @@ const EmitterMixin = {
 
 		// All params provided. off() that single callback.
 		if ( callback ) {
-			emitter.off( event, callback );
+			offCallback( emitter, event, callback );
 		}
 		// Only `emitter` and `event` provided. off() all callbacks for that event.
 		else if ( eventCallbacks ) {
 			while ( ( callback = eventCallbacks.pop() ) ) {
-				emitter.off( event, callback );
+				offCallback( emitter, event, callback );
 			}
+
 			delete emitterInfo.callbacks[ event ];
 		}
 		// Only `emitter` provided. off() all events for that emitter.
@@ -278,7 +270,7 @@ const EmitterMixin = {
 					// Remove the called mark for the next calls.
 					delete eventInfo.off.called;
 
-					this.off( event, callbacks[ i ].callback );
+					offCallback( this, event, callbacks[ i ].callback );
 				}
 
 				// Do not execute next callbacks if stop() was called.
@@ -571,6 +563,25 @@ function fireDelegatedEvents( destinations, eventInfo, fireArgs ) {
 	}
 }
 
+// Removes callback from emitter for given event.
+//
+// @param {module:utils/emittermixin~Emitter} emitter
+// @param {String} event
+// @param {Function} callback
+function offCallback( emitter, event, callback ) {
+	const lists = getCallbacksListsForNamespace( emitter, event );
+
+	for ( const callbacks of lists ) {
+		for ( let 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--;
+			}
+		}
+	}
+}
+
 /**
  * Interface representing classes which mix in {@link module:utils/emittermixin~EmitterMixin}.
  *