/**
* @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/
/**
* @module enter/entercommand
*/
import Command from '@ckeditor/ckeditor5-core/src/command';
import Position from '@ckeditor/ckeditor5-engine/src/model/position';
/**
* Enter command. It is used by the {@link module:enter/enter~Enter Enter feature} to handle the Enter key.
*
* @extends module:core/command~Command
*/
export default class EnterCommand extends Command {
/**
* @inheritDoc
*/
execute() {
const doc = this.editor.document;
const batch = doc.batch();
doc.enqueueChanges( () => {
enterBlock( this.editor.data, batch, doc.selection, doc.schema );
this.fire( 'afterExecute', { batch } );
} );
}
}
// Creates a new block in the way that the Enter key is expected to work.
//
// @param {engine.controller.DataController} dataController
// @param {module:engine/model/batch~Batch} batch A batch to which the deltas will be added.
// @param {module:engine/model/selection~Selection} selection Selection on which the action should be performed.
// @param {module:engine/model/schema~Schema} schema
function enterBlock( dataController, batch, selection, schema ) {
const isSelectionEmpty = selection.isCollapsed;
const range = selection.getFirstRange();
const startElement = range.start.parent;
const endElement = range.end.parent;
// Don't touch the roots and other limit elements.
if ( schema.limits.has( startElement.name ) || schema.limits.has( endElement.name ) ) {
// Delete the selected content but only if inside a single limit element.
// Abort, when crossing limit elements boundary (e.g.
y]y
->
y
->^y
else { selection.setCollapsedAt( endElement ); } } } } function splitBlock( batch, selection, splitPos ) { const oldElement = splitPos.parent; const newElement = new oldElement.constructor( oldElement.name, oldElement.getAttributes() ); if ( splitPos.isAtEnd ) { // If the split is at the end of element, instead of splitting, just create a clone of position's parent // element and insert it after split element. The result is the same but less operations are done // and it's more semantically correct (when it comes to operational transformation). batch.insert( Position.createAfter( splitPos.parent ), newElement ); } else if ( splitPos.isAtStart ) { // If the split is at the start of element, instead of splitting, just create a clone of position's parent // element and insert it before split element. The result is the same but less operations are done // and it's more semantically correct (when it comes to operational transformation). batch.insert( Position.createBefore( splitPos.parent ), newElement ); } else { batch.split( splitPos ); } selection.setCollapsedAt( splitPos.parent.nextSibling ); }