8
0
Просмотр исходного кода

Fixed: DomEmitterMixin#stopListening should respect listeners attached
with useCapture. Closes #146.

Aleksander Nowodzinski 8 лет назад
Родитель
Сommit
63f56e624b

+ 5 - 3
packages/ckeditor5-utils/src/dom/emittermixin.js

@@ -196,7 +196,7 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
 			return;
 		}
 
-		const domListener = this._createDomListener( event );
+		const domListener = this._createDomListener( event, !!options.useCapture );
 
 		// Attach the native DOM listener to DOM Node.
 		this._domNode.addEventListener( event, domListener, !!options.useCapture );
@@ -244,9 +244,11 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
 	 * @param {String} event
 	 *
 	 * @method module:utils/dom/emittermixin~ProxyEmitter#_createDomListener
+	 * @param {String} event The name of the event.
+	 * @param {Boolean} useCapture Indicates whether the listener was created for capturing event.
 	 * @returns {Function} The DOM listener callback.
 	 */
-	_createDomListener( event ) {
+	_createDomListener( event, useCapture ) {
 		const domListener = domEvt => {
 			this.fire( event, domEvt );
 		};
@@ -255,7 +257,7 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
 		// detach it from the DOM Node, when it is no longer necessary.
 		// See: {@link off}.
 		domListener.removeListener = () => {
-			this._domNode.removeEventListener( event, domListener );
+			this._domNode.removeEventListener( event, domListener, useCapture );
 			delete this._domListeners[ event ];
 		};
 

+ 47 - 0
packages/ckeditor5-utils/tests/dom/emittermixin.js

@@ -129,6 +129,18 @@ describe( 'DomEmitterMixin', () => {
 			sinon.assert.calledTwice( spy2 );
 		} );
 
+		it( 'should stop listening to a specific event callback (re–listen)', () => {
+			const spy = testUtils.sinon.spy();
+
+			domEmitter.listenTo( node, 'event', spy );
+			node.dispatchEvent( new Event( 'event' ) );
+			domEmitter.stopListening( node, 'event', spy );
+
+			domEmitter.listenTo( node, 'event', spy );
+			node.dispatchEvent( new Event( 'event' ) );
+			sinon.assert.calledTwice( spy );
+		} );
+
 		it( 'should stop listening to an specific event', () => {
 			const spy1a = testUtils.sinon.spy();
 			const spy1b = testUtils.sinon.spy();
@@ -455,5 +467,40 @@ describe( 'DomEmitterMixin', () => {
 
 			sinon.assert.calledOnce( spy );
 		} );
+
+		describe( 'event capturing', () => {
+			beforeEach( () => {
+				document.body.appendChild( node );
+			} );
+
+			afterEach( () => {
+				document.body.removeChild( node );
+			} );
+
+			it( 'should remove listeners when re–listen', () => {
+				const spy = testUtils.sinon.spy();
+
+				domEmitter.listenTo( document, 'test', spy, { useCapture: true } );
+
+				node.dispatchEvent( new Event( 'test' ) );
+				sinon.assert.calledOnce( spy );
+
+				domEmitter.stopListening( document, 'test' );
+
+				node.dispatchEvent( new Event( 'test' ) );
+				sinon.assert.calledOnce( spy );
+
+				// Listen again.
+				domEmitter.listenTo( document, 'test', spy, { useCapture: true } );
+
+				node.dispatchEvent( new Event( 'test', { bubbles: false } ) );
+				sinon.assert.calledTwice( spy );
+
+				domEmitter.stopListening( document, 'test' );
+
+				node.dispatchEvent( new Event( 'test', { bubbles: false } ) );
+				sinon.assert.calledTwice( spy );
+			} );
+		} );
 	} );
 } );