Bladeren bron

Used KeystrokeHandler instead of Template binding to avoid code duplication.

Aleksander Nowodzinski 8 jaren geleden
bovenliggende
commit
ee3bee8545
2 gewijzigde bestanden met toevoegingen van 79 en 37 verwijderingen
  1. 35 12
      packages/ckeditor5-ui/src/list/listitemview.js
  2. 44 25
      packages/ckeditor5-ui/tests/list/listitemview.js

+ 35 - 12
packages/ckeditor5-ui/src/list/listitemview.js

@@ -9,6 +9,7 @@
 
 import View from '../view';
 import Template from '../template';
+import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
 
 /**
  * The list item view class.
@@ -31,6 +32,14 @@ export default class ListItemView extends View {
 		 */
 		this.set( 'tabindex', -1 );
 
+		/**
+		 * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
+		 *
+		 * @readonly
+		 * @member {module:utils/keystrokehandler~KeystrokeHandler}
+		 */
+		this.keystrokes = new KeystrokeHandler();
+
 		const bind = this.bindTemplate;
 
 		this.template = new Template( {
@@ -53,18 +62,7 @@ export default class ListItemView extends View {
 			],
 
 			on: {
-				// Execute on mouse click.
-				click: bind.to( 'execute' ),
-
-				// Execute on Enter and Space key press.
-				keydown: bind.to( evt => {
-					const keyCode = evt.keyCode;
-
-					if ( keyCode == 13 || keyCode == 32 ) {
-						this.fire( 'execute' );
-						evt.preventDefault();
-					}
-				} )
+				click: bind.to( 'execute' )
 			}
 		} );
 
@@ -103,6 +101,19 @@ export default class ListItemView extends View {
 		 */
 	}
 
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		const onKeystrokePress = getKeystrokePressCallback( this );
+
+		this.keystrokes.listenTo( this.element );
+
+		// Execute on Enter and Space key press.
+		this.keystrokes.set( 'Enter', onKeystrokePress );
+		this.keystrokes.set( [ 32 ], onKeystrokePress );
+	}
+
 	/**
 	 * Focuses the list item.
 	 */
@@ -110,3 +121,15 @@ export default class ListItemView extends View {
 		this.element.focus();
 	}
 }
+
+// Returns the Enter and Space keystroke handler for given ListItemView.
+//
+// @private
+// @param {module:ui/list/listitemview~ListItemView} view
+// @returns {Function} A listener for {@link module:utils/keystrokehandler~KeystrokeHandler}.
+function getKeystrokePressCallback( view ) {
+	return ( data, cancel ) => {
+		view.fire( 'execute' );
+		cancel();
+	};
+}

+ 44 - 25
packages/ckeditor5-ui/tests/list/listitemview.js

@@ -3,9 +3,10 @@
  * For licensing, see LICENSE.md.
  */
 
-/* globals Event */
+/* global Event */
 
 import ListItemView from '../../src/list/listitemview';
+import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
 
 describe( 'ListItemView', () => {
 	let view;
@@ -24,6 +25,48 @@ describe( 'ListItemView', () => {
 		it( 'creates element from template', () => {
 			expect( view.element.classList.contains( 'ck-list__item' ) ).to.be.true;
 		} );
+
+		it( 'should create #keystrokes instance', () => {
+			expect( view.keystrokes ).to.be.instanceOf( KeystrokeHandler );
+		} );
+	} );
+
+	describe( 'init()', () => {
+		it( 'starts listening for #keystrokes coming from #element', () => {
+			const spy = sinon.spy( view.keystrokes, 'listenTo' );
+
+			view.init();
+			sinon.assert.calledOnce( spy );
+			sinon.assert.calledWithExactly( spy, view.element );
+		} );
+
+		// https://github.com/ckeditor/ckeditor5-ui/issues/153
+		it( 'triggers view#execute event when Enter or Space key is pressed', () => {
+			const spy = sinon.spy();
+			const evtData = {
+				keyCode: 10,
+				preventDefault: sinon.spy(),
+				stopPropagation: sinon.spy()
+			};
+
+			view.on( 'execute', spy );
+			view.keystrokes.press( evtData );
+
+			sinon.assert.notCalled( spy );
+			sinon.assert.notCalled( evtData.preventDefault );
+
+			evtData.keyCode = 13;
+			view.keystrokes.press( evtData );
+
+			sinon.assert.calledOnce( spy );
+			sinon.assert.calledOnce( evtData.preventDefault );
+
+			evtData.keyCode = 32;
+			view.keystrokes.press( evtData );
+
+			sinon.assert.calledTwice( spy );
+			sinon.assert.calledTwice( evtData.preventDefault );
+		} );
 	} );
 
 	describe( 'DOM bindings', () => {
@@ -86,30 +129,6 @@ describe( 'ListItemView', () => {
 				view.element.dispatchEvent( new Event( 'click' ) );
 				expect( spy.calledOnce ).to.be.true;
 			} );
-
-			// https://github.com/ckeditor/ckeditor5-ui/issues/153
-			it( 'triggers view#execute event when Enter or Space key is pressed', () => {
-				const spy = sinon.spy();
-				const evt = new Event( 'keydown' );
-				const preventSpy = sinon.spy( evt, 'preventDefault' );
-
-				view.on( 'execute', spy );
-
-				evt.keyCode = 10;
-				view.element.dispatchEvent( evt );
-				expect( spy.calledOnce ).to.be.false;
-				expect( preventSpy.calledOnce ).to.be.false;
-
-				evt.keyCode = 13;
-				view.element.dispatchEvent( evt );
-				expect( spy.calledOnce ).to.be.true;
-				expect( preventSpy.calledOnce ).to.be.true;
-
-				evt.keyCode = 32;
-				view.element.dispatchEvent( evt );
-				expect( spy.calledTwice ).to.be.true;
-				expect( preventSpy.calledTwice ).to.be.true;
-			} );
 		} );
 	} );