Browse Source

Add delete command handler to override default selection placement when a table fragment is selected.

Maciej Gołaszewski 5 năm trước cách đây
mục cha
commit
8e2d1f6b84

+ 62 - 20
packages/ckeditor5-table/src/tableselection.js

@@ -96,35 +96,31 @@ export default class TableSelection extends Plugin {
 	 */
 	 */
 	init() {
 	init() {
 		const editor = this.editor;
 		const editor = this.editor;
-		const selection = editor.model.document.selection;
-		const viewDoc = editor.editing.view.document;
+		const model = editor.model;
+		const selection = model.document.selection;
 
 
 		this._tableUtils = editor.plugins.get( 'TableUtils' );
 		this._tableUtils = editor.plugins.get( 'TableUtils' );
 
 
 		setupTableSelectionHighlighting( editor, this );
 		setupTableSelectionHighlighting( editor, this );
 
 
 		this.listenTo( selection, 'change:range', () => this._clearSelectionOnExternalChange( selection ) );
 		this.listenTo( selection, 'change:range', () => this._clearSelectionOnExternalChange( selection ) );
-		this.listenTo( viewDoc, 'delete', evt => {
-			if ( this.hasMultiCellSelection ) {
-				evt.stop();
-
-				// TODO: why not deleteContent decorator???
-				clearTableCellsContents( editor.model, this.getSelectedTableCells() );
-			}
-		}, { priority: 'high' } );
-
-		this.listenTo( editor.model, 'deleteContent', ( evt, args ) => {
-			const [ selection ] = args;
+		this.listenTo( model, 'deleteContent', ( evt, args ) => this._handleDeleteContent( evt, args ), { priority: 'high' } );
+	}
 
 
-			if ( this.hasMultiCellSelection && selection.is( 'documentSelection' ) ) {
-				evt.stop();
+	/**
+	 * @inheritDoc
+	 */
+	afterInit() {
+		const editor = this.editor;
 
 
-				clearTableCellsContents( this.editor.model, this.getSelectedTableCells() );
+		const deleteCommand = editor.commands.get( 'delete' );
+		const forwardDeleteCommand = editor.commands.get( 'forwardDelete' );
 
 
-				editor.model.change( writer => {
-					writer.setSelection( Array.from( this.getSelectedTableCells() ).pop(), 0 );
-				} );
-			}
+		this.listenTo( deleteCommand, 'execute', event => {
+			this._handleDeleteCommand( event, { isForward: false } );
+		}, { priority: 'high' } );
+		this.listenTo( forwardDeleteCommand, 'execute', event => {
+			this._handleDeleteCommand( event, { isForward: true } );
 		}, { priority: 'high' } );
 		}, { priority: 'high' } );
 	}
 	}
 
 
@@ -303,4 +299,50 @@ export default class TableSelection extends Plugin {
 			this.clearSelection();
 			this.clearSelection();
 		}
 		}
 	}
 	}
+
+	/**
+	 * It overrides default `model.deleteContent()` behavior over a selected table fragment.
+	 *
+	 * @private
+	 * @param {module:utils/eventinfo~EventInfo} event
+	 * @param {Array.<*>} args Delete content method arguments.
+	 */
+	_handleDeleteContent( event, args ) {
+		const [ selection ] = args;
+		const model = this.editor.model;
+
+		if ( this.hasMultiCellSelection && selection.is( 'documentSelection' ) ) {
+			event.stop();
+
+			clearTableCellsContents( model, this.getSelectedTableCells() );
+
+			model.change( writer => {
+				writer.setSelection( Array.from( this.getSelectedTableCells() ).pop(), 0 );
+			} );
+		}
+	}
+
+	/**
+	 * It overrides default `DeleteCommand` behavior over a selected table fragment.
+	 *
+	 * @private
+	 * @param {module:utils/eventinfo~EventInfo} event
+	 * @param {Object} options
+	 * @param {Boolean} options.isForward Whether it handles forward or backward delete.
+	 */
+	_handleDeleteCommand( event, options ) {
+		const model = this.editor.model;
+
+		if ( this.hasMultiCellSelection ) {
+			event.stop();
+
+			clearTableCellsContents( model, this.getSelectedTableCells() );
+
+			const tableCell = options.isForward ? this._startElement : this._endElement;
+
+			model.change( writer => {
+				writer.setSelection( tableCell, 0 );
+			} );
+		}
+	}
 }
 }