8
0
فهرست منبع

Added: Initial tables support.

Maciej Gołaszewski 7 سال پیش
والد
کامیت
4c61b72e2a

+ 129 - 0
packages/ckeditor5-table/src/converters.js

@@ -0,0 +1,129 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module tables/converters
+ */
+
+import Position from '../../ckeditor5-engine/src/view/position';
+
+export function createTableCell( viewElement, modelWriter ) {
+	const attributes = {};
+
+	if ( viewElement.name === 'th' ) {
+		attributes.isHeading = true;
+	}
+
+	return modelWriter.createElement( 'tableCell', attributes );
+}
+
+export function createTableRow( viewElement, modelWriter ) {
+	const attributes = {};
+
+	if ( viewElement.parent.name === 'tfoot' ) {
+		attributes.isFooter = true;
+	}
+
+	if ( viewElement.parent.name === 'thead' ) {
+		attributes.isHeading = true;
+	}
+
+	return modelWriter.createElement( 'tableRow', attributes );
+}
+
+export function downcastTableCell( dispatcher ) {
+	dispatcher.on( 'insert:tableCell', ( evt, data, conversionApi ) => {
+		const viewElementName = data.item.getAttribute( 'isHeading' ) ? 'th' : 'td';
+		const tableCellElement = conversionApi.writer.createContainerElement( viewElementName, {} );
+
+		if ( !tableCellElement ) {
+			return;
+		}
+
+		if ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {
+			return;
+		}
+
+		const viewPosition = conversionApi.mapper.toViewPosition( data.range.start );
+
+		conversionApi.mapper.bindElements( data.item, tableCellElement );
+		conversionApi.writer.insert( viewPosition, tableCellElement );
+	}, { priority: 'normal' } );
+}
+
+export function downcastTable( dispatcher ) {
+	dispatcher.on( 'insert:table', ( evt, data, conversionApi ) => {
+		const tableElement = conversionApi.writer.createContainerElement( 'table' );
+
+		if ( !tableElement ) {
+			return;
+		}
+
+		if ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {
+			return;
+		}
+
+		const { headings, footers, rows } = _extractSectionsRows( data.item );
+
+		if ( headings.length ) {
+			_createTableSection( 'thead', tableElement, headings, conversionApi );
+		}
+
+		if ( rows.length ) {
+			_createTableSection( 'tbody', tableElement, rows, conversionApi );
+		}
+
+		if ( footers.length ) {
+			_createTableSection( 'tfoot', tableElement, footers, conversionApi );
+		}
+
+		const viewPosition = conversionApi.mapper.toViewPosition( data.range.start );
+
+		conversionApi.mapper.bindElements( data.item, tableElement );
+		conversionApi.writer.insert( viewPosition, tableElement );
+	}, { priority: 'normal' } );
+}
+
+function _extractSectionsRows( table ) {
+	const tableRows = [ ...table.getChildren() ];
+
+	const headings = [];
+	const footers = [];
+	const rows = [];
+
+	for ( const tableRow of tableRows ) {
+		if ( tableRow.getAttribute( 'isHeading' ) ) {
+			headings.push( tableRow );
+		} else if ( tableRow.getAttribute( 'isFooter' ) ) {
+			footers.push( tableRow );
+		} else {
+			rows.push( tableRow );
+		}
+	}
+
+	return { headings, footers, rows };
+}
+
+function _createTableSection( elementName, tableElement, rows, conversionApi ) {
+	const tableBodyElement = conversionApi.writer.createContainerElement( elementName );
+	conversionApi.writer.insert( Position.createAt( tableElement, 'end' ), tableBodyElement );
+
+	rows.map( row => _downcastTableRow( row, conversionApi, tableBodyElement ) );
+}
+
+function _downcastTableRow( tableRow, conversionApi, parent ) {
+	const tableRowElement = conversionApi.writer.createContainerElement( 'tr' );
+
+	if ( !tableRowElement ) {
+		return;
+	}
+
+	if ( !conversionApi.consumable.consume( tableRow, 'insert' ) ) {
+		return;
+	}
+
+	conversionApi.mapper.bindElements( tableRow, tableRowElement );
+	conversionApi.writer.insert( Position.createAt( parent, 'end' ), tableRowElement );
+}

+ 29 - 0
packages/ckeditor5-table/src/tables.js

@@ -0,0 +1,29 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module tables/tables
+ */
+
+import Plugin from '../../ckeditor5-core/src/plugin';
+
+import TablesEditing from './tablesediting';
+import TablesUI from './tablesui';
+
+export default class Tables extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	static get requires() {
+		return [ TablesEditing, TablesUI ];
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	static get pluginName() {
+		return 'Tables';
+	}
+}

+ 60 - 0
packages/ckeditor5-table/src/tablesediting.js

@@ -0,0 +1,60 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module tables/tablesediting
+ */
+
+import Plugin from '../../ckeditor5-core/src/plugin';
+import { upcastElementToElement } from '../../ckeditor5-engine/src/conversion/upcast-converters';
+import { createTableCell, createTableRow, downcastTableCell, downcastTable } from './converters';
+
+export default class TablesEditing extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		const editor = this.editor;
+		const schema = editor.model.schema;
+		const conversion = editor.conversion;
+
+		schema.register( 'table', {
+			allowWhere: '$block',
+			allowAttributes: [],
+			isBlock: true,
+			isObject: true
+		} );
+
+		schema.register( 'tableRow', {
+			allowIn: 'table',
+			allowAttributes: [ 'isHeading', 'isFooter' ],
+			isBlock: true,
+			isLimit: true
+		} );
+
+		schema.register( 'tableCell', {
+			allowIn: 'tableRow',
+			allowContentOf: '$block',
+			allowAttributes: [ 'isHeading', 'colspan', 'rowspan' ],
+			isBlock: true,
+			isLimit: true
+		} );
+
+		// Table conversion.
+		conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'table', view: 'table' } ) );
+		conversion.for( 'downcast' ).add( downcastTable );
+
+		// Table row upcast only since downcast conversion is done in `downcastTable()`.
+		conversion.for( 'upcast' ).add( upcastElementToElement( { model: createTableRow, view: 'tr' } ) );
+
+		// Table cell conversion.
+		conversion.for( 'upcast' ).add( upcastElementToElement( { model: createTableCell, view: 'td' } ) );
+		conversion.for( 'upcast' ).add( upcastElementToElement( { model: createTableCell, view: 'th' } ) );
+		conversion.for( 'downcast' ).add( downcastTableCell );
+
+		conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
+		conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
+	}
+}

+ 13 - 0
packages/ckeditor5-table/src/tablesui.js

@@ -0,0 +1,13 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module tables/tablesui
+ */
+
+import Plugin from '../../ckeditor5-core/src/plugin';
+
+export default class TablesUI extends Plugin {
+}