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

Added: Use Tab to entry table if whole widget is selected.

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

+ 75 - 41
packages/ckeditor5-table/src/tableediting.js

@@ -78,65 +78,99 @@ export default class TablesEditing extends Plugin {
 		editor.commands.add( 'insertRow', new InsertRowCommand( editor ) );
 		editor.commands.add( 'insertColumn', new InsertColumnCommand( editor ) );
 
-		this.listenTo( editor.editing.view.document, 'keydown', ( evt, data ) => {
-			const tabPressed = data.keyCode == keyCodes.tab;
+		this.listenTo( editor.editing.view.document, 'keydown', ( ...args ) => this._handleTabOnSelectedTable( ...args ) );
+		this.listenTo( editor.editing.view.document, 'keydown', ( ...args ) => this._handleTabInsideTable( ...args ) );
+	}
 
-			// Act only on TAB & SHIFT-TAB - Do not override native CTRL+TAB handler.
-			if ( !tabPressed || data.ctrlKey ) {
-				return;
-			}
+	_handleTabOnSelectedTable( evt, data ) {
+		const tabPressed = data.keyCode == keyCodes.tab;
 
-			const selection = editor.model.document.selection;
+		// Act only on TAB & SHIFT-TAB - Do not override native CTRL+TAB handler.
+		if ( !tabPressed || data.ctrlKey ) {
+			return;
+		}
+
+		const editor = this.editor;
+		const selection = editor.model.document.selection;
 
-			const table = getParentTable( selection.getFirstPosition() );
+		if ( !selection.isCollapsed && selection.rangeCount === 1 && selection.getFirstRange().isFlat ) {
+			const selectedElement = selection.getSelectedElement();
 
-			if ( !table ) {
+			if ( !selectedElement ) {
 				return;
 			}
 
-			data.preventDefault();
-			data.stopPropagation();
+			if ( selectedElement.name === 'table' ) {
+				evt.stop();
+				data.preventDefault();
+				data.stopPropagation();
 
-			const tableCell = selection.focus.parent;
-			const tableRow = tableCell.parent;
+				editor.model.change( writer => {
+					writer.setSelection( Range.createIn( selectedElement.getChild( 0 ).getChild( 0 ) ) );
+				} );
+			}
+		}
+	}
 
-			const rowIndex = table.getChildIndex( tableRow );
-			const cellIndex = tableRow.getChildIndex( tableCell );
+	_handleTabInsideTable( evt, data ) {
+		const tabPressed = data.keyCode == keyCodes.tab;
 
-			const isForward = !data.shiftKey;
+		// Act only on TAB & SHIFT-TAB - Do not override native CTRL+TAB handler.
+		if ( !tabPressed || data.ctrlKey ) {
+			return;
+		}
 
-			if ( !isForward && cellIndex === 0 && rowIndex === 0 ) {
-				// It's the first cell of a table - don't do anything (stay in current position).
-				return;
-			}
+		const editor = this.editor;
+		const selection = editor.model.document.selection;
 
-			const indexOfLastCellInRow = tableRow.childCount - 1;
+		const table = getParentTable( selection.getFirstPosition() );
 
-			if ( isForward && rowIndex === table.childCount - 1 && cellIndex === indexOfLastCellInRow ) {
-				// It's a last table cell in a table - so create a new row at table's end.
-				editor.execute( 'insertRow', { at: table.childCount } );
-			}
+		if ( !table ) {
+			return;
+		}
 
-			let moveToCell;
+		data.preventDefault();
+		data.stopPropagation();
 
-			if ( isForward && cellIndex === indexOfLastCellInRow ) {
-				// Move to first cell in next row.
-				const nextRow = table.getChild( rowIndex + 1 );
+		const tableCell = selection.focus.parent;
+		const tableRow = tableCell.parent;
 
-				moveToCell = nextRow.getChild( 0 );
-			} else if ( !isForward && cellIndex === 0 ) {
-				// Move to last cell in a previous row.
-				const prevRow = table.getChild( rowIndex - 1 );
+		const rowIndex = table.getChildIndex( tableRow );
+		const cellIndex = tableRow.getChildIndex( tableCell );
 
-				moveToCell = prevRow.getChild( prevRow.childCount - 1 );
-			} else {
-				// Move to next/previous cell otherwise.
-				moveToCell = tableRow.getChild( cellIndex + ( isForward ? 1 : -1 ) );
-			}
+		const isForward = !data.shiftKey;
+
+		if ( !isForward && cellIndex === 0 && rowIndex === 0 ) {
+			// It's the first cell of a table - don't do anything (stay in current position).
+			return;
+		}
+
+		const indexOfLastCellInRow = tableRow.childCount - 1;
+
+		if ( isForward && rowIndex === table.childCount - 1 && cellIndex === indexOfLastCellInRow ) {
+			// It's a last table cell in a table - so create a new row at table's end.
+			editor.execute( 'insertRow', { at: table.childCount } );
+		}
+
+		let moveToCell;
+
+		if ( isForward && cellIndex === indexOfLastCellInRow ) {
+			// Move to first cell in next row.
+			const nextRow = table.getChild( rowIndex + 1 );
+
+			moveToCell = nextRow.getChild( 0 );
+		} else if ( !isForward && cellIndex === 0 ) {
+			// Move to last cell in a previous row.
+			const prevRow = table.getChild( rowIndex - 1 );
+
+			moveToCell = prevRow.getChild( prevRow.childCount - 1 );
+		} else {
+			// Move to next/previous cell otherwise.
+			moveToCell = tableRow.getChild( cellIndex + ( isForward ? 1 : -1 ) );
+		}
 
-			editor.model.change( writer => {
-				writer.setSelection( Range.createIn( moveToCell ) );
-			} );
+		editor.model.change( writer => {
+			writer.setSelection( Range.createIn( moveToCell ) );
 		} );
 	}
 }

+ 42 - 0
packages/ckeditor5-table/tests/tableediting.js

@@ -183,6 +183,48 @@ describe( 'TableEditing', () => {
 					[ '[21]', '22' ]
 				] ) );
 			} );
+
+			describe( 'on table widget selected', () => {
+				it( 'should move caret to the first table cell on TAB', () => {
+					const spy = sinon.spy();
+
+					editor.editing.view.document.on( 'keydown', spy );
+
+					setModelData( model, '[' + modelTable( [
+						[ '11', '12' ]
+					] ) + ']' );
+
+					editor.editing.view.document.fire( 'keydown', domEvtDataStub );
+
+					sinon.assert.calledOnce( domEvtDataStub.preventDefault );
+					sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
+
+					expect( formatModelTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
+						[ '[11]', '12' ]
+					] ) );
+
+					// Should cancel event - so no other tab handler is called.
+					sinon.assert.notCalled( spy );
+				} );
+
+				it( 'shouldn\' do anything on other blocks', () => {
+					const spy = sinon.spy();
+
+					editor.editing.view.document.on( 'keydown', spy );
+
+					setModelData( model, '[<paragraph>foo</paragraph>]' );
+
+					editor.editing.view.document.fire( 'keydown', domEvtDataStub );
+
+					sinon.assert.notCalled( domEvtDataStub.preventDefault );
+					sinon.assert.notCalled( domEvtDataStub.stopPropagation );
+
+					expect( formatModelTable( getModelData( model ) ) ).to.equal( '[<paragraph>foo</paragraph>]' );
+
+					// Should not cancel event.
+					sinon.assert.calledOnce( spy );
+				} );
+			} );
 		} );
 
 		describe( 'on SHIFT+TAB', () => {