Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge branch 'master' into i/6150
Browse files Browse the repository at this point in the history
  • Loading branch information
Reinmar committed Feb 28, 2020
2 parents dc4864b + 379c022 commit 3713344
Show file tree
Hide file tree
Showing 6 changed files with 392 additions and 102 deletions.
24 changes: 5 additions & 19 deletions src/tableclipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ export default class TableClipboard extends Plugin {
*/
this._tableSelection = editor.plugins.get( 'TableSelection' );

this.listenTo( viewDocument, 'copy', ( evt, data ) => this._onCopy( evt, data ), { priority: 'normal' } );
this.listenTo( viewDocument, 'cut', ( evt, data ) => this._onCut( evt, data ), { priority: 'high' } );
this.listenTo( viewDocument, 'copy', ( evt, data ) => this._onCopyCut( evt, data ) );
this.listenTo( viewDocument, 'cut', ( evt, data ) => this._onCopyCut( evt, data ) );
}

/**
* A clipboard "copy" event handler.
* Copies table content to a clipboard on "copy" & "cut" events.
*
* @param {module:utils/eventinfo~EventInfo} evt An object containing information about the handled event.
* @param {Object} data Clipboard event data.
* @private
*/
_onCopy( evt, data ) {
_onCopyCut( evt, data ) {
const tableSelection = this._tableSelection;

if ( !tableSelection.hasMultiCellSelection ) {
Expand All @@ -72,26 +72,12 @@ export default class TableClipboard extends Plugin {
const dataController = this.editor.data;
const viewDocument = this.editor.editing.view.document;

const content = dataController.toView( tableSelection.getSelectionAsFragment() );
const content = dataController.toView( this._tableSelection.getSelectionAsFragment() );

viewDocument.fire( 'clipboardOutput', {
dataTransfer: data.dataTransfer,
content,
method: evt.name
} );
}

/**
* A clipboard "cut" event handler.
*
* @param {module:utils/eventinfo~EventInfo} evt An object containing information about the handled event.
* @param {Object} data Clipboard event data.
* @private
*/
_onCut( evt, data ) {
if ( this._tableSelection.hasMultiCellSelection ) {
data.preventDefault();
evt.stop();
}
}
}
76 changes: 74 additions & 2 deletions src/tableselection.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import TableUtils from './tableutils';
import { setupTableSelectionHighlighting } from './tableselection/converters';
import MouseSelectionHandler from './tableselection/mouseselectionhandler';
import { findAncestor } from './commands/utils';
import { clearTableCellsContents } from './tableselection/utils';
import cropTable from './tableselection/croptable';

import '../theme/tableselection.css';
Expand Down Expand Up @@ -95,13 +96,38 @@ export default class TableSelection extends Plugin {
*/
init() {
const editor = this.editor;
const selection = editor.model.document.selection;
const model = editor.model;
const selection = model.document.selection;

this._tableUtils = editor.plugins.get( 'TableUtils' );

setupTableSelectionHighlighting( editor, this );

selection.on( 'change:range', () => this._clearSelectionOnExternalChange( selection ) );
this.listenTo( selection, 'change:range', () => this._clearSelectionOnExternalChange( selection ) );
this.listenTo( model, 'deleteContent', ( evt, args ) => this._handleDeleteContent( evt, args ), { priority: 'high' } );
}

/**
* @inheritDoc
*/
afterInit() {
const editor = this.editor;

const deleteCommand = editor.commands.get( 'delete' );

if ( deleteCommand ) {
this.listenTo( deleteCommand, 'execute', event => {
this._handleDeleteCommand( event, { isForward: false } );
}, { priority: 'high' } );
}

const forwardDeleteCommand = editor.commands.get( 'forwardDelete' );

if ( forwardDeleteCommand ) {
this.listenTo( forwardDeleteCommand, 'execute', event => {
this._handleDeleteCommand( event, { isForward: true } );
}, { priority: 'high' } );
}
}

/**
Expand Down Expand Up @@ -279,4 +305,50 @@ export default class TableSelection extends Plugin {
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 );
} );
}
}
}
2 changes: 1 addition & 1 deletion src/tableselection/croptable.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { findAncestor } from '../commands/utils';
* tableSelection.startSelectingFrom( startCell )
* tableSelection.setSelectingFrom( endCell )
*
* const croppedTable = cropTable( tableSelection.getSelectedTableCells );
* const croppedTable = cropTable( tableSelection.getSelectedTableCells() );
*
* **Note**: This function is used also by {@link module:table/tableselection~TableSelection#getSelectionAsFragment}
*
Expand Down
31 changes: 31 additions & 0 deletions src/tableselection/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/**
* @module table/tableselection/utils
*/

/**
* Clears contents of the passed table cells.
*
* This is to be used with table selection
*
* tableSelection.startSelectingFrom( startCell )
* tableSelection.setSelectingFrom( endCell )
*
* clearTableCellsContents( editor.model, tableSelection.getSelectedTableCells() );
*
* **Note**: This function is used also by {@link module:table/tableselection~TableSelection#getSelectionAsFragment}
*
* @param {module:engine/model/model~Model} model
* @param {Iterable.<module:engine/model/element~Element>} tableCells
*/
export function clearTableCellsContents( model, tableCells ) {
model.change( writer => {
for ( const tableCell of tableCells ) {
model.deleteContent( writer.createSelection( tableCell, 'in' ) );
}
} );
}
Loading

0 comments on commit 3713344

Please sign in to comment.