Przeglądaj źródła

Added event capturing option to DOMEmitterMixin.

Oskar Wrobel 9 lat temu
rodzic
commit
23739417e5

+ 6 - 2
packages/ckeditor5-ui/src/domemittermixin.js

@@ -52,10 +52,12 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
 	 * the priority value the sooner the callback will be fired. Events having the same priority are called in the
 	 * order they were added.
 	 * @param {Object} [options.context] The object that represents `this` in the callback. Defaults to the object firing the event.
+	 * @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 ui.ProxyEmitter#on
 	 */
-	on( event ) {
+	on( event, callback, options = {} ) {
 		// Execute parent class method first.
 		EmitterMixin.on.apply( this, arguments );
 
@@ -68,7 +70,7 @@ extend( ProxyEmitter.prototype, EmitterMixin, {
 		const domListener = this._createDomListener( event );
 
 		// Attach the native DOM listener to DOM Node.
-		this._domNode.addEventListener( event, domListener );
+		this._domNode.addEventListener( event, domListener, !!options.useCapture );
 
 		if ( !this._domListeners ) {
 			this._domListeners = {};
@@ -173,6 +175,8 @@ const DOMEmitterMixin = extend( {}, EmitterMixin, {
 	 * the priority value the sooner the callback will be fired. Events having the same priority are called in the
 	 * order they were added.
 	 * @param {Object} [options.context] The object that represents `this` in the callback. Defaults to the object firing the event.
+	 * @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 ui.DOMEmitterMixin#listenTo
 	 */

+ 30 - 0
packages/ckeditor5-ui/tests/domemittermixin.js

@@ -74,6 +74,36 @@ describe( 'DOMEmitterMixin', () => {
 
 			sinon.assert.calledOnce( spy );
 		} );
+
+		describe( 'event capturing', () => {
+			beforeEach( () => {
+				document.body.appendChild( node );
+			} );
+
+			afterEach( () => {
+				document.body.removeChild( node );
+			} );
+
+			it( 'should not use capturing at default', () => {
+				const spy = testUtils.sinon.spy();
+
+				domEmitter.listenTo( document, 'test', spy );
+
+				node.dispatchEvent( new Event( 'test', { bubbles: false } ) );
+
+				sinon.assert.notCalled( spy );
+			} );
+
+			it( 'should optionally use capturing', () => {
+				const spy = testUtils.sinon.spy();
+
+				domEmitter.listenTo( document, 'test', spy, { useCapture: true } );
+
+				node.dispatchEvent( new Event( 'test', { bubbles: false } ) );
+
+				sinon.assert.calledOnce( spy );
+			} );
+		} );
 	} );
 
 	describe( 'stopListening', () => {