浏览代码

Changed: Properly upcast table cell contents.

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

+ 53 - 2
packages/ckeditor5-table/src/converters/upcasttable.js

@@ -53,9 +53,12 @@ export default function upcastTable() {
 			} else {
 				// Create one row and one table cell for empty table.
 				const row = conversionApi.writer.createElement( 'tableRow' );
-
 				conversionApi.writer.insert( row, ModelPosition.createAt( table, 'end' ) );
-				conversionApi.writer.insertElement( 'tableCell', ModelPosition.createAt( row, 'end' ) );
+
+				const tableCell = conversionApi.writer.createElement( 'tableCell' );
+				conversionApi.writer.insert( tableCell, ModelPosition.createAt( row, 'end' ) );
+
+				conversionApi.writer.insertElement( 'paragraph', ModelPosition.createAt( tableCell, 'end' ) );
 			}
 
 			// Set conversion result range.
@@ -85,6 +88,54 @@ export default function upcastTable() {
 	};
 }
 
+export function upcastTableCell( elementName ) {
+	return dispatcher => {
+		dispatcher.on( `element:${ elementName }`, ( evt, data, conversionApi ) => {
+			const viewTableCell = data.viewItem;
+
+			// When element was already consumed then skip it.
+			if ( !conversionApi.consumable.test( viewTableCell, { name: true } ) ) {
+				return;
+			}
+
+			const tableCell = conversionApi.writer.createElement( 'tableCell' );
+
+			// Insert element on allowed position.
+			const splitResult = conversionApi.splitToAllowedParent( tableCell, data.modelCursor );
+			conversionApi.writer.insert( tableCell, splitResult.position );
+			conversionApi.consumable.consume( viewTableCell, { name: true } );
+
+			for ( const child of viewTableCell.getChildren() ) {
+				conversionApi.convertItem( child, ModelPosition.createAt( tableCell, 'end' ) );
+			}
+
+			// Set conversion result range.
+			data.modelRange = new ModelRange(
+				// Range should start before inserted element
+				ModelPosition.createBefore( tableCell ),
+				// Should end after but we need to take into consideration that children could split our
+				// element, so we need to move range after parent of the last converted child.
+				// before: <allowed>[]</allowed>
+				// after: <allowed>[<converted><child></child></converted><child></child><converted>]</converted></allowed>
+				ModelPosition.createAfter( tableCell )
+			);
+
+			// Now we need to check where the modelCursor should be.
+			// If we had to split parent to insert our element then we want to continue conversion inside split parent.
+			//
+			// before: <allowed><notAllowed>[]</notAllowed></allowed>
+			// after:  <allowed><notAllowed></notAllowed><converted></converted><notAllowed>[]</notAllowed></allowed>
+			if ( splitResult.cursorParent ) {
+				data.modelCursor = ModelPosition.createAt( splitResult.cursorParent );
+
+				// Otherwise just continue after inserted element.
+			} else {
+				data.modelCursor = data.modelRange.end;
+			}
+		}, { priority: 'normal' } );
+	};
+}
+
 // Scans table rows and extracts required metadata from the table:
 //
 // headingRows    - the number of rows that goes as table header.

+ 3 - 48
packages/ckeditor5-table/src/tableediting.js

@@ -10,10 +10,9 @@
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import { upcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
 import Range from '@ckeditor/ckeditor5-engine/src/model/range';
-import Position from '@ckeditor/ckeditor5-engine/src/model/position';
 import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
 
-import upcastTable from './converters/upcasttable';
+import upcastTable, { upcastTableCell } from './converters/upcasttable';
 import {
 	downcastInsertCell,
 	downcastInsertRow,
@@ -64,7 +63,6 @@ export default class TableEditing extends Plugin {
 
 		schema.register( 'tableCell', {
 			allowIn: 'tableRow',
-			allowContentOf: '$block',
 			allowAttributes: [ 'colspan', 'rowspan' ],
 			isLimit: true
 		} );
@@ -93,8 +91,8 @@ export default class TableEditing extends Plugin {
 		conversion.for( 'downcast' ).add( downcastRemoveRow() );
 
 		// Table cell conversion.
-		conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
-		conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+		conversion.for( 'upcast' ).add( upcastTableCell( 'td' ) );
+		conversion.for( 'upcast' ).add( upcastTableCell( 'th' ) );
 
 		conversion.for( 'editingDowncast' ).add( downcastInsertCell( { asWidget: true } ) );
 		conversion.for( 'dataDowncast' ).add( downcastInsertCell() );
@@ -133,8 +131,6 @@ export default class TableEditing extends Plugin {
 		// Handle tab key navigation.
 		this.listenTo( editor.editing.view.document, 'keydown', ( ...args ) => this._handleTabOnSelectedTable( ...args ) );
 		this.listenTo( editor.editing.view.document, 'keydown', ( ...args ) => this._handleTabInsideTable( ...args ) );
-		// Add listener to 'enter' key pressed inside table cell.
-		this.listenTo( editor.editing.view.document, 'enter', ( ...args ) => this._handleEnterInsideTable( ...args ) );
 	}
 
 	/**
@@ -254,45 +250,4 @@ export default class TableEditing extends Plugin {
 			writer.setSelection( Range.createIn( cellToFocus ) );
 		} );
 	}
-
-	/**
-	 * Handles {@link module:engine/view/document~Document#event:enter keydown} events for the <kbd>Enter</kbd> key executed inside table
-	 * cell.
-	 *
-	 * @private
-	 * @param {module:utils/eventinfo~EventInfo} evt
-	 * @param {module:engine/view/observer/domeventdata~DomEventData} data
-	 */
-	_handleEnterInsideTable( evt, data ) {
-		// Do not act on SHIFT-ENTER.
-		if ( data.isSoft ) {
-			return;
-		}
-
-		const editor = this.editor;
-
-		const position = editor.model.document.selection.getFirstPosition();
-		const parent = position.parent;
-
-		// Either the selection is not inside a table or it is in a table cell that has already a block content.
-		if ( parent.name != 'tableCell' || ( !parent.getChild( 0 ) || !parent.getChild( 0 ).is( 'text' ) ) ) {
-			return;
-		}
-
-		data.preventDefault();
-		// Stop the event to prevent default enter event listener.
-		evt.stop();
-
-		editor.model.change( writer => {
-			// Wrap $text from table cell in paragraph.
-			writer.wrap( Range.createIn( parent ), 'paragraph' );
-
-			// Enforce selection to be inside newly created paragraph as consequent 'enter' keys would create nested paragraphs otherwise.
-			const positionInParagraph = Position.createFromParentAndOffset( parent.getChild( 0 ), position.offset );
-			writer.setSelection( positionInParagraph );
-
-			// Execute 'enter' command.
-			editor.execute( 'enter' );
-		} );
-	}
 }

+ 2 - 3
packages/ckeditor5-table/tests/_utils/utils.js

@@ -178,9 +178,8 @@ export function defaultConversion( conversion, asWidget = false ) {
 
 	// Table cell conversion.
 	conversion.for( 'downcast' ).add( downcastInsertCell( { asWidget } ) );
-	conversion.for( 'upcast' ).add( upcastTableCell() );
-	// conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'td' } ) );
-	// conversion.for( 'upcast' ).add( upcastElementToElement( { model: 'tableCell', view: 'th' } ) );
+	conversion.for( 'upcast' ).add( upcastTableCell( 'td' ) );
+	conversion.for( 'upcast' ).add( upcastTableCell( 'th' ) );
 
 	// Table attributes conversion.
 	conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );

+ 81 - 37
packages/ckeditor5-table/tests/converters/upcasttable.js

@@ -7,13 +7,18 @@ import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtest
 import { upcastElementToElement } from '@ckeditor/ckeditor5-engine/src/conversion/upcast-converters';
 import { getData as getModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
-import upcastTable from '../../src/converters/upcasttable';
+import upcastTable, { upcastTableCell } from '../../src/converters/upcasttable';
+import { formatTable } from '../_utils/utils';
+import Paragraph from '../../../ckeditor5-paragraph/src/paragraph';
 
 describe( 'upcastTable()', () => {
 	let editor, model;
 
 	beforeEach( () => {
-		return VirtualTestEditor.create()
+		return VirtualTestEditor
+			.create( {
+				plugins: [ Paragraph ]
+			} )
 			.then( newEditor => {
 				editor = newEditor;
 				model = editor.model;
@@ -24,26 +29,31 @@ describe( 'upcastTable()', () => {
 				schema.register( 'table', {
 					allowWhere: '$block',
 					allowAttributes: [ 'headingRows', 'headingColumns' ],
+					isLimit: true,
 					isObject: true
 				} );
 
-				schema.register( 'tableRow', { allowIn: 'table' } );
+				schema.register( 'tableRow', {
+					allowIn: 'table',
+					isLimit: true
+				} );
 
 				schema.register( 'tableCell', {
 					allowIn: 'tableRow',
-					allowContentOf: '$block',
 					allowAttributes: [ 'colspan', 'rowspan' ],
 					isLimit: true
 				} );
 
+				schema.extend( '$block', { allowIn: 'tableCell' } );
+
 				conversion.for( 'upcast' ).add( upcastTable() );
 
 				// 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.for( 'upcast' ).add( upcastTableCell( 'td' ) );
+				conversion.for( 'upcast' ).add( upcastTableCell( 'th' ) );
 
 				conversion.attributeToAttribute( { model: 'colspan', view: 'colspan' } );
 				conversion.attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );
@@ -55,7 +65,7 @@ describe( 'upcastTable()', () => {
 	} );
 
 	function expectModel( data ) {
-		expect( getModelData( model, { withoutSelection: true } ) ).to.equal( data );
+		expect( formatTable( getModelData( model, { withoutSelection: true } ) ) ).to.equal( formatTable( data ) );
 	}
 
 	it( 'should convert table figure', () => {
@@ -69,7 +79,7 @@ describe( 'upcastTable()', () => {
 
 		expectModel(
 			'<table>' +
-			'<tableRow><tableCell>1</tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
 			'</table>'
 		);
 	} );
@@ -83,7 +93,7 @@ describe( 'upcastTable()', () => {
 
 		expectModel(
 			'<table>' +
-			'<tableRow><tableCell>1</tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
 			'</table>'
 		);
 	} );
@@ -91,7 +101,7 @@ describe( 'upcastTable()', () => {
 	it( 'should not convert empty figure', () => {
 		'<figure class="table"></figure>';
 
-		expectModel( '' );
+		expectModel( '<paragraph></paragraph>' );
 	} );
 
 	it( 'should convert if figure do not have class="table" attribute', () => {
@@ -105,7 +115,7 @@ describe( 'upcastTable()', () => {
 
 		expectModel(
 			'<table>' +
-			'<tableRow><tableCell>1</tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
 			'</table>'
 		);
 	} );
@@ -119,12 +129,12 @@ describe( 'upcastTable()', () => {
 
 		expectModel(
 			'<table headingRows="1">' +
-			'<tableRow><tableCell>1</tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
 			'</table>'
 		);
 	} );
 
-	it( 'should create table model from table with one thead with more then on row', () => {
+	it( 'should create table model from table with one thead with more then one row', () => {
 		editor.setData(
 			'<table>' +
 			'<thead>' +
@@ -137,9 +147,9 @@ describe( 'upcastTable()', () => {
 
 		expectModel(
 			'<table headingRows="3">' +
-			'<tableRow><tableCell>1</tableCell></tableRow>' +
-			'<tableRow><tableCell>2</tableCell></tableRow>' +
-			'<tableRow><tableCell>3</tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>2</paragraph></tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>3</paragraph></tableCell></tableRow>' +
 			'</table>'
 		);
 	} );
@@ -155,9 +165,9 @@ describe( 'upcastTable()', () => {
 
 		expectModel(
 			'<table headingRows="1">' +
-			'<tableRow><tableCell>1</tableCell></tableRow>' +
-			'<tableRow><tableCell>2</tableCell></tableRow>' +
-			'<tableRow><tableCell>3</tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>2</paragraph></tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>3</paragraph></tableCell></tableRow>' +
 			'</table>'
 		);
 	} );
@@ -172,8 +182,8 @@ describe( 'upcastTable()', () => {
 
 		expectModel(
 			'<table headingRows="1">' +
-			'<tableRow><tableCell>1</tableCell></tableRow>' +
-			'<tableRow><tableCell>2</tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>2</paragraph></tableCell></tableRow>' +
 			'</table>'
 		);
 	} );
@@ -187,7 +197,7 @@ describe( 'upcastTable()', () => {
 
 		expectModel(
 			'<table>' +
-			'<tableRow><tableCell>1</tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
 			'</table>'
 		);
 	} );
@@ -199,7 +209,7 @@ describe( 'upcastTable()', () => {
 		);
 
 		expectModel(
-			'<table><tableRow><tableCell></tableCell></tableRow></table>'
+			'<table><tableRow><tableCell><paragraph></paragraph></tableCell></tableRow></table>'
 		);
 	} );
 
@@ -212,17 +222,17 @@ describe( 'upcastTable()', () => {
 		);
 
 		expectModel(
-			'<table><tableRow><tableCell>bar</tableCell></tableRow></table>'
+			'<table><tableRow><tableCell><paragraph>bar</paragraph></tableCell></tableRow></table>'
 		);
 	} );
 
 	it( 'should create table model from some broken table', () => {
 		editor.setData(
-			'<table><td><p>foo</p></td></table>'
+			'<table><td><z>foo</z></td></table>'
 		);
 
 		expectModel(
-			'<table><tableRow><tableCell>foo</tableCell></tableRow></table>'
+			'<table><tableRow><tableCell><paragraph>foo</paragraph></tableCell></tableRow></table>'
 		);
 	} );
 
@@ -245,8 +255,8 @@ describe( 'upcastTable()', () => {
 		expectModel(
 			'<div>foo</div>' +
 			'<table headingRows="1">' +
-			'<tableRow><tableCell>1</tableCell></tableRow>' +
-			'<tableRow><tableCell>2</tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>1</paragraph></tableCell></tableRow>' +
+			'<tableRow><tableCell><paragraph>2</paragraph></tableCell></tableRow>' +
 			'</table>' +
 			'<div>bar</div>'
 		);
@@ -258,8 +268,19 @@ describe( 'upcastTable()', () => {
 			allowAttributes: [ 'headingRows' ],
 			isObject: true
 		} );
+		editor.model.schema.register( 'fooCell', {
+			allowIn: 'fooRow',
+			isObject: true
+		} );
+		editor.model.schema.register( 'fooRow', {
+			allowIn: 'fooTable',
+			isObject: true
+		} );
 
 		editor.conversion.elementToElement( { model: 'fooTable', view: 'table', converterPriority: 'high' } );
+		editor.conversion.elementToElement( { model: 'fooRow', view: 'tr', converterPriority: 'high' } );
+		editor.conversion.elementToElement( { model: 'fooCell', view: 'td', converterPriority: 'high' } );
+		editor.conversion.elementToElement( { model: 'fooCell', view: 'th', converterPriority: 'high' } );
 
 		editor.setData(
 			'<table>' +
@@ -268,7 +289,7 @@ describe( 'upcastTable()', () => {
 		);
 
 		expectModel(
-			'<fooTable></fooTable>'
+			'<fooTable><fooRow><fooCell></fooCell></fooRow></fooTable>'
 		);
 	} );
 
@@ -296,19 +317,34 @@ describe( 'upcastTable()', () => {
 			expectModel(
 				'<table headingColumns="2" headingRows="1">' +
 				'<tableRow>' +
-				'<tableCell>11</tableCell><tableCell>12</tableCell><tableCell>13</tableCell><tableCell>14</tableCell>' +
+					'<tableCell><paragraph>11</paragraph></tableCell>' +
+					'<tableCell><paragraph>12</paragraph></tableCell>' +
+					'<tableCell><paragraph>13</paragraph></tableCell>' +
+					'<tableCell><paragraph>14</paragraph></tableCell>' +
 				'</tableRow>' +
 				'<tableRow>' +
-				'<tableCell>21</tableCell><tableCell>22</tableCell><tableCell>23</tableCell><tableCell>24</tableCell>' +
+					'<tableCell><paragraph>21</paragraph></tableCell>' +
+					'<tableCell><paragraph>22</paragraph></tableCell>' +
+					'<tableCell><paragraph>23</paragraph></tableCell>' +
+					'<tableCell><paragraph>24</paragraph></tableCell>' +
 				'</tableRow>' +
 				'<tableRow>' +
-				'<tableCell>31</tableCell><tableCell>32</tableCell><tableCell>33</tableCell><tableCell>34</tableCell>' +
+					'<tableCell><paragraph>31</paragraph></tableCell>' +
+					'<tableCell><paragraph>32</paragraph></tableCell>' +
+					'<tableCell><paragraph>33</paragraph></tableCell>' +
+					'<tableCell><paragraph>34</paragraph></tableCell>' +
 				'</tableRow>' +
 				'<tableRow>' +
-				'<tableCell>41</tableCell><tableCell>42</tableCell><tableCell>43</tableCell><tableCell>44</tableCell>' +
+					'<tableCell><paragraph>41</paragraph></tableCell>' +
+					'<tableCell><paragraph>42</paragraph></tableCell>' +
+					'<tableCell><paragraph>43</paragraph></tableCell>' +
+					'<tableCell><paragraph>44</paragraph></tableCell>' +
 				'</tableRow>' +
 				'<tableRow>' +
-				'<tableCell>51</tableCell><tableCell>52</tableCell><tableCell>53</tableCell><tableCell>54</tableCell>' +
+					'<tableCell><paragraph>51</paragraph></tableCell>' +
+					'<tableCell><paragraph>52</paragraph></tableCell>' +
+					'<tableCell><paragraph>53</paragraph></tableCell>' +
+					'<tableCell><paragraph>54</paragraph></tableCell>' +
 				'</tableRow>' +
 				'</table>'
 			);
@@ -332,13 +368,21 @@ describe( 'upcastTable()', () => {
 			expectModel(
 				'<table headingColumns="3" headingRows="1">' +
 				'<tableRow>' +
-				'<tableCell>11</tableCell><tableCell>12</tableCell><tableCell>13</tableCell><tableCell>14</tableCell>' +
+					'<tableCell><paragraph>11</paragraph></tableCell>' +
+					'<tableCell><paragraph>12</paragraph></tableCell>' +
+					'<tableCell><paragraph>13</paragraph></tableCell>' +
+					'<tableCell><paragraph>14</paragraph></tableCell>' +
 				'</tableRow>' +
 				'<tableRow>' +
-				'<tableCell>21</tableCell><tableCell>22</tableCell><tableCell>23</tableCell><tableCell>24</tableCell>' +
+					'<tableCell><paragraph>21</paragraph></tableCell>' +
+					'<tableCell><paragraph>22</paragraph></tableCell>' +
+					'<tableCell><paragraph>23</paragraph></tableCell>' +
+					'<tableCell><paragraph>24</paragraph></tableCell>' +
 				'</tableRow>' +
 				'<tableRow>' +
-				'<tableCell colspan="2">31</tableCell><tableCell>33</tableCell><tableCell>34</tableCell>' +
+				'<tableCell colspan="2"><paragraph>31</paragraph></tableCell>' +
+					'<tableCell><paragraph>33</paragraph></tableCell>' +
+					'<tableCell><paragraph>34</paragraph></tableCell>' +
 				'</tableRow>' +
 				'</table>'
 			);

+ 12 - 3
packages/ckeditor5-table/tests/integration.js

@@ -55,7 +55,10 @@ describe( 'TableToolbar integration', () => {
 		} );
 
 		it( 'should allow the BalloonToolbar to be displayed when a table content is selected', () => {
-			setModelData( newEditor.model, '<paragraph>foo</paragraph><table><tableRow><tableCell>x[y]z</tableCell></tableRow></table>' );
+			setModelData(
+				newEditor.model,
+				'<paragraph>foo</paragraph><table><tableRow><tableCell><paragraph>x[y]z</paragraph></tableCell></tableRow></table>'
+			);
 
 			balloonToolbar.show();
 
@@ -63,7 +66,10 @@ describe( 'TableToolbar integration', () => {
 		} );
 
 		it( 'should prevent the BalloonToolbar from being displayed when a table is selected as whole', () => {
-			setModelData( newEditor.model, '<paragraph>foo</paragraph>[<table><tableRow><tableCell>foo</tableCell></tableRow></table>]' );
+			setModelData(
+				newEditor.model,
+				'<paragraph>foo</paragraph>[<table><tableRow><tableCell><paragraph>foo</paragraph></tableCell></tableRow></table>]'
+			);
 
 			balloonToolbar.show();
 
@@ -76,7 +82,10 @@ describe( 'TableToolbar integration', () => {
 			const normalPrioritySpy = sinon.spy();
 
 			// Select an table
-			setModelData( newEditor.model, '<paragraph>foo</paragraph>[<table><tableRow><tableCell>x</tableCell></tableRow></table>]' );
+			setModelData(
+				newEditor.model,
+				'<paragraph>foo</paragraph>[<table><tableRow><tableCell><paragraph>x</paragraph></tableCell></tableRow></table>]'
+			);
 
 			newEditor.listenTo( balloonToolbar, 'show', highestPrioritySpy, { priority: 'highest' } );
 			newEditor.listenTo( balloonToolbar, 'show', highPrioritySpy, { priority: 'high' } );

+ 0 - 196
packages/ckeditor5-table/tests/manual/table.html

@@ -52,200 +52,4 @@
 		</tr>
 		</tbody>
 	</table>
-
-	<p>Table with everything:</p>
-
-	<figure>
-		<figcaption>Data about the planets of our solar system (Planetary facts taken from <a
-			href="http://nssdc.gsfc.nasa.gov/planetary/factsheet/">Nasa's Planetary Fact Sheet - Metric</a>.
-		</figcaption>
-		<table>
-			<thead>
-			<tr>
-				<td colspan="2">&nbsp;</td>
-				<th scope="col">Name</th>
-				<th scope="col">Mass (10<sup>24</sup>kg)</th>
-				<th scope="col">Diameter (km)</th>
-				<th scope="col">Density (kg/m<sup>3</sup>)</th>
-				<th scope="col">Gravity (m/s<sup>2</sup>)</th>
-				<th scope="col">Length of day (hours)</th>
-				<th scope="col">Distance from Sun (10<sup>6</sup>km)</th>
-				<th scope="col">Mean temperature (°C)</th>
-				<th scope="col">Number of moons</th>
-				<th scope="col">Notes</th>
-			</tr>
-			</thead>
-			<tbody>
-			<tr>
-				<th colspan="2" rowspan="4" scope="rowgroup">Terrestrial planets</th>
-				<th scope="row">Mercury</th>
-				<td>0.330</td>
-				<td>4,879</td>
-				<td>5427</td>
-				<td>3.7</td>
-				<td>4222.6</td>
-				<td>57.9</td>
-				<td>167</td>
-				<td>0</td>
-				<td>Closest to the Sun</td>
-			</tr>
-			<tr>
-				<th scope="row">Venus</th>
-				<td>4.87</td>
-				<td>12,104</td>
-				<td>5243</td>
-				<td>8.9</td>
-				<td>2802.0</td>
-				<td>108.2</td>
-				<td>464</td>
-				<td>0</td>
-				<td>&nbsp;</td>
-			</tr>
-			<tr>
-				<th scope="row">Earth</th>
-				<td>5.97</td>
-				<td>12,756</td>
-				<td>5514</td>
-				<td>9.8</td>
-				<td>24.0</td>
-				<td>149.6</td>
-				<td>15</td>
-				<td>1</td>
-				<td>Our world</td>
-			</tr>
-			<tr>
-				<th scope="row">Mars</th>
-				<td>0.642</td>
-				<td>6,792</td>
-				<td>3933</td>
-				<td>3.7</td>
-				<td>24.7</td>
-				<td>227.9</td>
-				<td>-65</td>
-				<td>2</td>
-				<td>The red planet</td>
-			</tr>
-			<tr>
-				<th scope="rowgroup" rowspan="4">Jovian planets</th>
-				<th scope="rowgroup" rowspan="2">Gas giants</th>
-				<th scope="row">Jupiter</th>
-				<td>1898</td>
-				<td>142,984</td>
-				<td>1326</td>
-				<td>23.1</td>
-				<td>9.9</td>
-				<td>778.6</td>
-				<td>-110</td>
-				<td>67</td>
-				<td>The largest planet</td>
-			</tr>
-			<tr>
-				<th scope="row">Saturn</th>
-				<td>568</td>
-				<td>120,536</td>
-				<td>687</td>
-				<td>9.0</td>
-				<td>10.7</td>
-				<td>1433.5</td>
-				<td>-140</td>
-				<td>62</td>
-				<td>&nbsp;</td>
-			</tr>
-			<tr>
-				<th scope="rowgroup" rowspan="2">Ice giants</th>
-				<th scope="row">Uranus</th>
-				<td>86.8</td>
-				<td>51,118</td>
-				<td>1271</td>
-				<td>8.7</td>
-				<td>17.2</td>
-				<td>2872.5</td>
-				<td>-195</td>
-				<td>27</td>
-				<td>&nbsp;</td>
-			</tr>
-			<tr>
-				<th scope="row">Neptune</th>
-				<td>102</td>
-				<td>49,528</td>
-				<td>1638</td>
-				<td>11.0</td>
-				<td>16.1</td>
-				<td>4495.1</td>
-				<td>-200</td>
-				<td>14</td>
-				<td>&nbsp;</td>
-			</tr>
-			<tr>
-				<th colspan="2" scope="rowgroup">Dwarf planets</th>
-				<th scope="row">Pluto</th>
-				<td>0.0146</td>
-				<td>2,370</td>
-				<td>2095</td>
-				<td>0.7</td>
-				<td>153.3</td>
-				<td>5906.4</td>
-				<td>-225</td>
-				<td>5</td>
-				<td>Declassified as a planet in 2006, but this <a
-					href="http://www.usatoday.com/story/tech/2014/10/02/pluto-planet-solar-system/16578959/">remains controversial</a>.
-				</td>
-			</tr>
-			</tbody>
-		</table>
-	</figure>
-
-	<p>Table with 2 tbody:</p>
-
-	<table>
-		<tbody>
-		<tr>
-			<td>a</td>
-			<td>b</td>
-			<td>c</td>
-		</tr>
-		</tbody>
-		<tbody>
-		<tr>
-			<td>a</td>
-			<td>b</td>
-			<td>c</td>
-		</tr>
-		</tbody>
-	</table>
-
-	<p>Table with no tbody:</p>
-
-	<table>
-		<tr>
-			<td>a</td>
-			<td>b</td>
-			<td>c</td>
-		</tr>
-		<tr>
-			<td>a</td>
-			<td>b</td>
-			<td>c</td>
-		</tr>
-	</table>
-
-	<p>Table with thead section between two tbody sections</p>
-
-	<table>
-		<tbody>
-		<tr>
-			<td>2</td>
-		</tr>
-		</tbody>
-		<thead>
-		<tr>
-			<td>1</td>
-		</tr>
-		</thead>
-		<tbody>
-		<tr>
-			<td>3</td>
-		</tr>
-		</tbody>
-	</table>
 </div>

+ 15 - 12
packages/ckeditor5-table/tests/tableediting.js

@@ -69,7 +69,7 @@ describe( 'TableEditing', () => {
 		expect( model.schema.checkAttribute( [ 'tableCell' ], 'rowspan' ) ).to.be.true;
 
 		// Table cell contents:
-		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], '$text' ) ).to.be.true;
+		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], '$text' ) ).to.be.false;
 		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], '$block' ) ).to.be.true;
 		expect( model.schema.checkChild( [ '$root', 'table', 'tableRow', 'tableCell' ], 'table' ) ).to.be.false;
 	} );
@@ -137,7 +137,7 @@ describe( 'TableEditing', () => {
 	describe( 'conversion in data pipeline', () => {
 		describe( 'model to view', () => {
 			it( 'should create tbody section', () => {
-				setModelData( model, '<table><tableRow><tableCell>foo[]</tableCell></tableRow></table>' );
+				setModelData( model, '<table><tableRow><tableCell><paragraph>foo[]</paragraph></tableCell></tableRow></table>' );
 
 				expect( editor.getData() ).to.equal(
 					'<figure class="table">' +
@@ -151,7 +151,10 @@ describe( 'TableEditing', () => {
 			} );
 
 			it( 'should create thead section', () => {
-				setModelData( model, '<table headingRows="1"><tableRow><tableCell>foo[]</tableCell></tableRow></table>' );
+				setModelData(
+					model,
+					'<table headingRows="1"><tableRow><tableCell><paragraph>foo[]</paragraph></tableCell></tableRow></table>'
+				);
 
 				expect( editor.getData() ).to.equal(
 					'<figure class="table">' +
@@ -170,7 +173,7 @@ describe( 'TableEditing', () => {
 				editor.setData( '<table><tbody><tr><td>foo</td></tr></tbody></table>' );
 
 				expect( getModelData( model, { withoutSelection: true } ) )
-					.to.equal( '<table><tableRow><tableCell>foo</tableCell></tableRow></table>' );
+					.to.equal( '<table><tableRow><tableCell><paragraph>foo</paragraph></tableCell></tableRow></table>' );
 			} );
 		} );
 	} );
@@ -243,7 +246,7 @@ describe( 'TableEditing', () => {
 				sinon.assert.calledOnce( domEvtDataStub.preventDefault );
 				sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
 				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
-					[ '11', '[<paragraph>12</paragraph>]' ]
+					[ '11', '[12]' ]
 				] ) );
 			} );
 
@@ -256,7 +259,7 @@ describe( 'TableEditing', () => {
 
 				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
 					[ '11', '12' ],
-					[ '[<paragraph></paragraph>]', '' ]
+					[ '[]', '' ]
 				] ) );
 			} );
 
@@ -270,7 +273,7 @@ describe( 'TableEditing', () => {
 
 				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
 					[ '11', '12' ],
-					[ '[<paragraph>21</paragraph>]', '22' ]
+					[ '[21]', '22' ]
 				] ) );
 			} );
 
@@ -285,7 +288,7 @@ describe( 'TableEditing', () => {
 					[
 						'11',
 						'<paragraph>12</paragraph><paragraph>foo</paragraph><paragraph>bar</paragraph>',
-						'[<paragraph>13</paragraph>]'
+						'[13]'
 					],
 				] ) );
 			} );
@@ -316,7 +319,7 @@ describe( 'TableEditing', () => {
 					sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
 
 					expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
-						[ '[<paragraph>11</paragraph>]', '12' ]
+						[ '[11]', '12' ]
 					] ) );
 
 					// Should cancel event - so no other tab handler is called.
@@ -375,7 +378,7 @@ describe( 'TableEditing', () => {
 				sinon.assert.calledOnce( domEvtDataStub.preventDefault );
 				sinon.assert.calledOnce( domEvtDataStub.stopPropagation );
 				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
-					[ '[<paragraph>11</paragraph>]', '12' ]
+					[ '[11]', '12' ]
 				] ) );
 			} );
 
@@ -400,7 +403,7 @@ describe( 'TableEditing', () => {
 				editor.editing.view.document.fire( 'keydown', domEvtDataStub );
 
 				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
-					[ '11', '[<paragraph>12</paragraph>]' ],
+					[ '11', '[12]' ],
 					[ '21', '22' ]
 				] ) );
 			} );
@@ -414,7 +417,7 @@ describe( 'TableEditing', () => {
 
 				expect( formatTable( getModelData( model ) ) ).to.equal( formattedModelTable( [
 					[
-						'[<paragraph>11</paragraph>]',
+						'[11]',
 						'<paragraph>12</paragraph><paragraph>foo</paragraph><paragraph>bar</paragraph>',
 						'13'
 					],

+ 9 - 3
packages/ckeditor5-table/tests/tabletoolbar.js

@@ -123,7 +123,10 @@ describe( 'TableToolbar', () => {
 		} );
 
 		it( 'should show the toolbar on ui#update when the table content is selected', () => {
-			setData( model, '<paragraph>[foo]</paragraph><table><tableRow><tableCell>bar</tableCell></tableRow></table>' );
+			setData(
+				model,
+				'<paragraph>[foo]</paragraph><table><tableRow><tableCell><paragraph>bar</paragraph></tableCell></tableRow></table>'
+			);
 
 			expect( balloon.visibleView ).to.be.null;
 
@@ -147,7 +150,7 @@ describe( 'TableToolbar', () => {
 		} );
 
 		it( 'should not engage when the toolbar is in the balloon yet invisible', () => {
-			setData( model, '<table><tableRow><tableCell>x[y]z</tableCell></tableRow></table>' );
+			setData( model, '<table><tableRow><tableCell><paragraph>x[y]z</paragraph></tableCell></tableRow></table>' );
 
 			expect( balloon.visibleView ).to.equal( toolbar );
 
@@ -170,7 +173,10 @@ describe( 'TableToolbar', () => {
 		} );
 
 		it( 'should hide the toolbar on render if the table is de–selected', () => {
-			setData( model, '<paragraph>foo</paragraph><table><tableRow><tableCell>[]</tableCell></tableRow></table>' );
+			setData(
+				model,
+				'<paragraph>foo</paragraph><table><tableRow><tableCell><paragraph>[]</paragraph></tableCell></tableRow></table>'
+			);
 
 			expect( balloon.visibleView ).to.equal( toolbar );