浏览代码

Refactor InsertTableCommand and create the `TableUtils#createTable()` method.

Maciej Gołaszewski 7 年之前
父节点
当前提交
ffc3d89a6a

+ 11 - 25
packages/ckeditor5-table/src/commands/inserttablecommand.js

@@ -9,6 +9,7 @@
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
 import Position from '@ckeditor/ckeditor5-engine/src/model/position';
+import TableUtils from '../tableutils';
 
 /**
  * The insert table command.
@@ -21,11 +22,12 @@ export default class InsertTableCommand extends Command {
 	 */
 	refresh() {
 		const model = this.editor.model;
-		const doc = model.document;
+		const selection = model.document.selection;
+		const schema = model.schema;
 
-		const validParent = getValidParent( doc.selection.getFirstPosition() );
+		const validParent = getInsertTableParent( selection.getFirstPosition() );
 
-		this.isEnabled = model.schema.checkChild( validParent, 'table' );
+		this.isEnabled = schema.checkChild( validParent, 'table' );
 	}
 
 	/**
@@ -39,8 +41,8 @@ export default class InsertTableCommand extends Command {
 	 */
 	execute( options = {} ) {
 		const model = this.editor.model;
-		const document = model.document;
-		const selection = document.selection;
+		const selection = model.document.selection;
+		const tableUtils = this.editor.plugins.get( TableUtils );
 
 		const rows = parseInt( options.rows ) || 2;
 		const columns = parseInt( options.columns ) || 2;
@@ -48,33 +50,17 @@ export default class InsertTableCommand extends Command {
 		const firstPosition = selection.getFirstPosition();
 
 		const isRoot = firstPosition.parent === firstPosition.root;
-		const insertTablePosition = isRoot ? Position.createAt( firstPosition ) : Position.createAfter( firstPosition.parent );
+		const insertPosition = isRoot ? Position.createAt( firstPosition ) : Position.createAfter( firstPosition.parent );
 
-		model.change( writer => {
-			const table = writer.createElement( 'table' );
-
-			writer.insert( table, insertTablePosition );
-
-			// Create rows x columns table.
-			for ( let row = 0; row < rows; row++ ) {
-				const row = writer.createElement( 'tableRow' );
-
-				writer.insert( row, table, 'end' );
-
-				for ( let column = 0; column < columns; column++ ) {
-					const cell = writer.createElement( 'tableCell' );
-
-					writer.insert( cell, row, 'end' );
-				}
-			}
-		} );
+		tableUtils.createTable( insertPosition, rows, columns );
 	}
 }
 
 // Returns valid parent to insert table
 //
 // @param {module:engine/model/position} position
-function getValidParent( position ) {
+function getInsertTableParent( position ) {
 	const parent = position.parent;
+
 	return parent === parent.root ? parent : parent.parent;
 }

+ 26 - 5
packages/ckeditor5-table/src/tableutils.js

@@ -21,7 +21,7 @@ export default class TableUtils extends Plugin {
 	/**
 	 * Returns table cell location in table.
 	 *
-	 * @param tableCell
+	 * @param {module:engine/model/element~Element} tableCell
 	 * @returns {Object}
 	 */
 	getCellLocation( tableCell ) {
@@ -39,6 +39,25 @@ export default class TableUtils extends Plugin {
 		}
 	}
 
+	/**
+	 * Creates an empty table at given position.
+	 *
+	 * @param {module:engine/model/position~Position} position Position at which insert a table.
+	 * @param {Number} rows Number of rows to create.
+	 * @param {Number} columns Number of columns to create.
+	 */
+	createTable( position, rows, columns ) {
+		const model = this.editor.model;
+
+		model.change( writer => {
+			const table = writer.createElement( 'table' );
+
+			writer.insert( table, position );
+
+			createEmptyRows( writer, table, 0, rows, columns );
+		} );
+	}
+
 	insertRows( table, options = {} ) {
 		const model = this.editor.model;
 
@@ -209,8 +228,10 @@ export default class TableUtils extends Plugin {
 	}
 }
 
-// @param writer
-// @param table
+// Creates empty rows at given index in an existing table.
+//
+// @param {module:engine/model/writer~Writer} writer
+// @param {module:engine/model/element~Element} table
 // @param {Number} insertAt Row index of row insertion.
 // @param {Number} rows Number of rows to create.
 // @param {Number} tableCellToInsert Number of cells to insert in each row.
@@ -231,8 +252,8 @@ function createEmptyRows( writer, table, insertAt, rows, tableCellToInsert ) {
 // Creates cells at given position.
 //
 // @param {Number} columns Number of columns to create
-// @param {module:engine/model/writer} writer
-// @param {module:engine/model/position} insertPosition
+// @param {module:engine/model/writer~Writer} writer
+// @param {module:engine/model/position~Position} insertPosition
 function createCells( columns, writer, insertPosition ) {
 	for ( let i = 0; i < columns; i++ ) {
 		const cell = writer.createElement( 'tableCell' );

+ 48 - 46
packages/ckeditor5-table/tests/commands/inserttablecommand.js

@@ -10,58 +10,60 @@ import { upcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversio
 import InsertTableCommand from '../../src/commands/inserttablecommand';
 import { downcastInsertTable } from '../../src/converters/downcast';
 import upcastTable from '../../src/converters/upcasttable';
+import TableUtils from '../../src/tableutils';
 
 describe( 'InsertTableCommand', () => {
 	let editor, model, command;
 
 	beforeEach( () => {
-		return ModelTestEditor.create()
-			.then( newEditor => {
-				editor = newEditor;
-				model = editor.model;
-				command = new InsertTableCommand( editor );
-
-				const conversion = editor.conversion;
-				const schema = model.schema;
-
-				schema.register( 'table', {
-					allowWhere: '$block',
-					allowAttributes: [ 'headingRows' ],
-					isBlock: true,
-					isObject: true
-				} );
-
-				schema.register( 'tableRow', {
-					allowIn: 'table',
-					allowAttributes: [],
-					isBlock: true,
-					isLimit: true
-				} );
-
-				schema.register( 'tableCell', {
-					allowIn: 'tableRow',
-					allowContentOf: '$block',
-					allowAttributes: [ 'colspan', 'rowspan' ],
-					isBlock: true,
-					isLimit: true
-				} );
-
-				model.schema.register( 'p', { inheritAllFrom: '$block' } );
-
-				// Table conversion.
-				conversion.for( 'upcast' ).add( upcastTable() );
-				conversion.for( 'downcast' ).add( downcastInsertTable() );
-
-				// Table row upcast only since downcast conversion is done in `downcastTable()`.
-				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableRow', view: 'tr' } ) );
-
-				// Table cell conversion.
-				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
-				conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
-
-				conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
-				conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+		return ModelTestEditor.create( {
+			plugins: [ TableUtils ]
+		} ).then( newEditor => {
+			editor = newEditor;
+			model = editor.model;
+			command = new InsertTableCommand( editor );
+
+			const conversion = editor.conversion;
+			const schema = model.schema;
+
+			schema.register( 'table', {
+				allowWhere: '$block',
+				allowAttributes: [ 'headingRows' ],
+				isBlock: true,
+				isObject: true
 			} );
+
+			schema.register( 'tableRow', {
+				allowIn: 'table',
+				allowAttributes: [],
+				isBlock: true,
+				isLimit: true
+			} );
+
+			schema.register( 'tableCell', {
+				allowIn: 'tableRow',
+				allowContentOf: '$block',
+				allowAttributes: [ 'colspan', 'rowspan' ],
+				isBlock: true,
+				isLimit: true
+			} );
+
+			model.schema.register( 'p', { inheritAllFrom: '$block' } );
+
+			// Table conversion.
+			conversion.for( 'upcast' ).add( upcastTable() );
+			conversion.for( 'downcast' ).add( downcastInsertTable() );
+
+			// Table row upcast only since downcast conversion is done in `downcastTable()`.
+			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableRow', view: 'tr' } ) );
+
+			// Table cell conversion.
+			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
+			conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+
+			conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
+			conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+		} );
 	} );
 
 	afterEach( () => {