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

Changed: Make block content tab key event listener higher priority then table's one.

Maciej Gołaszewski 7 лет назад
Родитель
Сommit
ad2040494f

+ 53 - 69
packages/ckeditor5-table/src/tableediting.js

@@ -10,7 +10,6 @@
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import { upcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
 import Range from '@ckeditor/ckeditor5-engine/src/model/range';
-import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
 
 import upcastTable, { upcastTableCell } from './converters/upcasttable';
 import {
@@ -31,7 +30,7 @@ import RemoveRowCommand from './commands/removerowcommand';
 import RemoveColumnCommand from './commands/removecolumncommand';
 import SetHeaderRowCommand from './commands/setheaderrowcommand';
 import SetHeaderColumnCommand from './commands/setheadercolumncommand';
-import { getParentElement, getParentTable } from './commands/utils';
+import { getParentElement } from './commands/utils';
 import TableUtils from '../src/tableutils';
 import injectTablePostFixer from './converters/table-post-fixer';
 
@@ -137,8 +136,9 @@ export default class TableEditing extends Plugin {
 		injectTablePostFixer( model );
 
 		// Handle tab key navigation.
-		this.listenTo( editor.editing.view.document, 'keydown', ( ...args ) => this._handleTabOnSelectedTable( ...args ) );
-		this.listenTo( editor.editing.view.document, 'keydown', ( ...args ) => this._handleTabInsideTable( ...args ) );
+		this.editor.keystrokes.set( 'Tab', ( ...args ) => this._handleTabOnSelectedTable( ...args ), { priority: 'low' } );
+		this.editor.keystrokes.set( 'Tab', this._getTabHandler( true ), { priority: 'low' } );
+		this.editor.keystrokes.set( 'Shift+Tab', this._getTabHandler( false ), { priority: 'low' } );
 	}
 
 	/**
@@ -156,27 +156,18 @@ export default class TableEditing extends Plugin {
 	 * @param {module:utils/eventinfo~EventInfo} eventInfo
 	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
 	 */
-	_handleTabOnSelectedTable( eventInfo, domEventData ) {
-		const tabPressed = domEventData.keyCode == keyCodes.tab;
-
-		// Act only on TAB & SHIFT-TAB - Do not override native CTRL+TAB handler.
-		if ( !tabPressed || domEventData.ctrlKey ) {
-			return;
-		}
-
+	_handleTabOnSelectedTable( domEventData, cancel ) {
 		const editor = this.editor;
 		const selection = editor.model.document.selection;
 
 		if ( !selection.isCollapsed && selection.rangeCount === 1 && selection.getFirstRange().isFlat ) {
 			const selectedElement = selection.getSelectedElement();
 
-			if ( !selectedElement || selectedElement.name != 'table' ) {
+			if ( !selectedElement || !selectedElement.is( 'table' ) ) {
 				return;
 			}
 
-			eventInfo.stop();
-			domEventData.preventDefault();
-			domEventData.stopPropagation();
+			cancel();
 
 			editor.model.change( writer => {
 				writer.setSelection( Range.createIn( selectedElement.getChild( 0 ).getChild( 0 ) ) );
@@ -185,77 +176,70 @@ export default class TableEditing extends Plugin {
 	}
 
 	/**
-	 * Handles {@link module:engine/view/document~Document#event:keydown keydown} events for the <kbd>Tab</kbd> key executed inside table
-	 * cell.
+	 * Returns a handler for {@link module:engine/view/document~Document#event:keydown keydown} events for the <kbd>Tab</kbd> key executed
+	 * inside table cell.
 	 *
 	 * @private
-	 * @param {module:utils/eventinfo~EventInfo} eventInfo
-	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
+	 * @param {Boolean} isForward Whether this handler will move selection to the next cell or previous.
 	 */
-	_handleTabInsideTable( eventInfo, domEventData ) {
-		const tabPressed = domEventData.keyCode == keyCodes.tab;
-
-		// Act only on TAB & SHIFT-TAB - Do not override native CTRL+TAB handler.
-		if ( !tabPressed || domEventData.ctrlKey ) {
-			return;
-		}
-
+	_getTabHandler( isForward ) {
 		const editor = this.editor;
-		const selection = editor.model.document.selection;
 
-		const firstPosition = selection.getFirstPosition();
+		return ( domEventData, cancel ) => {
+			const selection = editor.model.document.selection;
 
-		const table = getParentTable( firstPosition );
+			const firstPosition = selection.getFirstPosition();
 
-		if ( !table ) {
-			return;
-		}
+			const tableCell = getParentElement( 'tableCell', firstPosition );
 
-		domEventData.preventDefault();
-		domEventData.stopPropagation();
+			if ( !tableCell ) {
+				return;
+			}
 
-		const tableCell = getParentElement( 'tableCell', firstPosition );
-		const tableRow = tableCell.parent;
+			cancel();
 
-		const currentRowIndex = table.getChildIndex( tableRow );
-		const currentCellIndex = tableRow.getChildIndex( tableCell );
+			const tableRow = tableCell.parent;
+			const table = tableRow.parent;
 
-		const isForward = !domEventData.shiftKey;
-		const isFirstCellInRow = currentCellIndex === 0;
+			const currentRowIndex = table.getChildIndex( tableRow );
+			const currentCellIndex = tableRow.getChildIndex( tableCell );
 
-		if ( !isForward && isFirstCellInRow && currentRowIndex === 0 ) {
-			// It's the first cell of a table - don't do anything (stay in current position).
-			return;
-		}
+			const isFirstCellInRow = currentCellIndex === 0;
 
-		const isLastCellInRow = currentCellIndex === tableRow.childCount - 1;
-		const isLastRow = currentRowIndex === table.childCount - 1;
+			if ( !isForward && isFirstCellInRow && currentRowIndex === 0 ) {
+				// It's the first cell of a table - don't do anything (stay in current position).
+				return;
+			}
 
-		if ( isForward && isLastRow && isLastCellInRow ) {
-			editor.plugins.get( TableUtils ).insertRows( table, { at: table.childCount } );
-		}
+			const isLastCellInRow = currentCellIndex === tableRow.childCount - 1;
+			const isLastRow = currentRowIndex === table.childCount - 1;
 
-		let cellToFocus;
+			if ( isForward && isLastRow && isLastCellInRow ) {
+				editor.plugins.get( TableUtils ).insertRows( table, { at: table.childCount } );
+			}
 
-		// Move to first cell in next row.
-		if ( isForward && isLastCellInRow ) {
-			const nextRow = table.getChild( currentRowIndex + 1 );
+			let cellToFocus;
 
-			cellToFocus = nextRow.getChild( 0 );
-		}
-		// Move to last cell in a previous row.
-		else if ( !isForward && isFirstCellInRow ) {
-			const previousRow = table.getChild( currentRowIndex - 1 );
+			// Move to first cell in next row.
+			if ( isForward && isLastCellInRow ) {
+				const nextRow = table.getChild( currentRowIndex + 1 );
 
-			cellToFocus = previousRow.getChild( previousRow.childCount - 1 );
-		}
-		// Move to next/previous cell.
-		else {
-			cellToFocus = tableRow.getChild( currentCellIndex + ( isForward ? 1 : -1 ) );
-		}
+				cellToFocus = nextRow.getChild( 0 );
+			}
+			// Move to last cell in a previous row.
+			else if ( !isForward && isFirstCellInRow ) {
+				const previousRow = table.getChild( currentRowIndex - 1 );
 
-		editor.model.change( writer => {
-			writer.setSelection( Range.createIn( cellToFocus ) );
-		} );
+				cellToFocus = previousRow.getChild( previousRow.childCount - 1 );
+			}
+			// Move to next/previous cell.
+			else {
+				cellToFocus = tableRow.getChild( currentCellIndex + ( isForward ? 1 : -1 ) );
+			}
+
+			editor.model.change( writer => {
+				writer.setSelection( Range.createIn( cellToFocus ) );
+			} );
+		};
 	}
 }

+ 20 - 1
packages/ckeditor5-table/tests/tableediting.js

@@ -293,6 +293,24 @@ describe( 'TableEditing', () => {
 				] ) );
 			} );
 
+			it( 'should listen with lower priority then its children', () => {
+				// Cancel TAB event.
+				editor.keystrokes.set( 'Tab', ( data, cancel ) => cancel() );
+
+				setModelData( model, modelTable( [
+					[ '11[]', '12' ]
+				] ) );
+
+				editor.editing.view.document.fire( 'keydown', domEvtDataStub );
+
+				sinon.assert.calledOnce( domEvtDataStub.preventDefault );
+				sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
+
+				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
+					[ '11[]', '12' ]
+				] ) );
+			} );
+
 			describe( 'on table widget selected', () => {
 				beforeEach( () => {
 					editor.model.schema.register( 'block', {
@@ -307,7 +325,7 @@ describe( 'TableEditing', () => {
 				it( 'should move caret to the first table cell on TAB', () => {
 					const spy = sinon.spy();
 
-					editor.editing.view.document.on( 'keydown', spy );
+					editor.keystrokes.set( 'Tab', spy, { priority: 'lowest' } );
 
 					setModelData( model, '[' + modelTable( [
 						[ '11', '12' ]
@@ -377,6 +395,7 @@ describe( 'TableEditing', () => {
 
 				sinon.assert.calledOnce( domEvtDataStub.preventDefault );
 				sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
+
 				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
 					[ '[11]', '12' ]
 				] ) );