Ver Fonte

Merge branch 'master' into i/6197

# Conflicts:
#	src/tableproperties/tablepropertiesediting.js
Maciej Gołaszewski há 6 anos atrás
pai
commit
d703c65abc
29 ficheiros alterados com 863 adições e 31 exclusões
  1. 6 0
      packages/ckeditor5-table/docs/_snippets/features/build-table-source.js
  2. 54 0
      packages/ckeditor5-table/docs/_snippets/features/table-styling.html
  3. 32 0
      packages/ckeditor5-table/docs/_snippets/features/table-styling.js
  4. 4 0
      packages/ckeditor5-table/docs/features/table.md
  5. 28 0
      packages/ckeditor5-table/src/commands/utils.js
  6. 1 1
      packages/ckeditor5-table/src/converters/tableproperties.js
  7. 16 1
      packages/ckeditor5-table/src/tablecellproperties/commands/tablecellborderwidthcommand.js
  8. 16 0
      packages/ckeditor5-table/src/tablecellproperties/commands/tablecellheightcommand.js
  9. 15 1
      packages/ckeditor5-table/src/tablecellproperties/commands/tablecellpaddingcommand.js
  10. 14 2
      packages/ckeditor5-table/src/tablecellproperties/commands/tablecellpropertycommand.js
  11. 16 0
      packages/ckeditor5-table/src/tablecellproperties/commands/tablecellwidthcommand.js
  12. 16 1
      packages/ckeditor5-table/src/tableproperties/commands/tableborderwidthcommand.js
  13. 16 0
      packages/ckeditor5-table/src/tableproperties/commands/tableheightcommand.js
  14. 14 2
      packages/ckeditor5-table/src/tableproperties/commands/tablepropertycommand.js
  15. 16 0
      packages/ckeditor5-table/src/tableproperties/commands/tablewidthcommand.js
  16. 23 4
      packages/ckeditor5-table/src/tableproperties/tablepropertiesediting.js
  17. 10 2
      packages/ckeditor5-table/src/ui/utils.js
  18. 1 1
      packages/ckeditor5-table/tests/_utils/utils.js
  19. 56 0
      packages/ckeditor5-table/tests/tablecellproperties/commands/tablecellborderwidthcommand.js
  20. 56 0
      packages/ckeditor5-table/tests/tablecellproperties/commands/tablecellheightcommand.js
  21. 56 0
      packages/ckeditor5-table/tests/tablecellproperties/commands/tablecellpaddingcommand.js
  22. 56 0
      packages/ckeditor5-table/tests/tablecellproperties/commands/tablecellwidthcommand.js
  23. 72 0
      packages/ckeditor5-table/tests/tablecellproperties/tablecellpropertiesediting.js
  24. 56 0
      packages/ckeditor5-table/tests/tableproperties/commands/tableborderwidthcommand.js
  25. 60 4
      packages/ckeditor5-table/tests/tableproperties/commands/tableheightcommand.js
  26. 60 4
      packages/ckeditor5-table/tests/tableproperties/commands/tablewidthcommand.js
  27. 72 4
      packages/ckeditor5-table/tests/tableproperties/tablepropertiesediting.js
  28. 16 4
      packages/ckeditor5-table/tests/ui/utils.js
  29. 5 0
      packages/ckeditor5-table/theme/table.css

+ 6 - 0
packages/ckeditor5-table/docs/_snippets/features/build-table-source.js

@@ -9,8 +9,14 @@ import ClassicEditor from '@ckeditor/ckeditor5-build-classic/src/ckeditor';
 
 import Table from '@ckeditor/ckeditor5-table/src/table';
 import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
+import TableProperties from '@ckeditor/ckeditor5-table/src/tableproperties';
+import TableCellProperties from '@ckeditor/ckeditor5-table/src/tablecellproperties';
 
 ClassicEditor.builtinPlugins.push( Table );
 ClassicEditor.builtinPlugins.push( TableToolbar );
 
 window.ClassicEditor = ClassicEditor;
+window.CKEditorPlugins = {
+	TableProperties,
+	TableCellProperties
+};

+ 54 - 0
packages/ckeditor5-table/docs/_snippets/features/table-styling.html

@@ -0,0 +1,54 @@
+<div id="snippet-table-styling">
+	<p>The ultimate table of <a href="https://en.wikipedia.org/wiki/List_of_coffee_drinks">coffee drinks</a>:</p>
+	<table>
+		<thead>
+			<tr>
+				<th rowspan="2"></th>
+				<th scope="col" rowspan="2">Espresso</th>
+				<th scope="colgroup" colspan="2">Milk</th>
+				<th scope="col" rowspan="2">Water</th>
+			</tr>
+			<tr>
+				<th scope="col">Steamed</th>
+				<th scope="col">Foam</th>
+			</tr>
+		</thead>
+		<tbody>
+			<tr>
+				<th scope="row">Cappuccino</th>
+				<td>yes</td>
+				<td>yes</td>
+				<td>yes</td>
+				<td>no</td>
+			</tr>
+			<tr>
+				<th scope="row">Macchiato</th>
+				<td>yes</td>
+				<td>no</td>
+				<td>yes</td>
+				<td>no</td>
+			</tr>
+			<tr>
+				<th scope="row">Latte</th>
+				<td>yes</td>
+				<td>yes</td>
+				<td>no</td>
+				<td>no</td>
+			</tr>
+			<tr>
+				<th scope="row">Americano</th>
+				<td>yes</td>
+				<td>no</td>
+				<td>no</td>
+				<td>yes</td>
+			</tr>
+		</tbody>
+	</table>
+</div>
+
+<style>
+	.ck.ck-content table td,
+	.ck.ck-content table th {
+		vertical-align: middle;
+	}
+</style>

+ 32 - 0
packages/ckeditor5-table/docs/_snippets/features/table-styling.js

@@ -0,0 +1,32 @@
+/**
+ * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/* globals ClassicEditor, CKEditorPlugins, console, window, document */
+
+import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+
+ClassicEditor
+	.create( document.querySelector( '#snippet-table-styling' ), {
+		extraPlugins: [
+			CKEditorPlugins.TableProperties,
+			CKEditorPlugins.TableCellProperties,
+		],
+		cloudServices: CS_CONFIG,
+		toolbar: {
+			items: [
+				'insertTable', '|', 'heading', '|', 'bold', 'italic', '|', 'undo', 'redo'
+			],
+			viewportTopOffset: window.getViewportTopOffsetConfig()
+		},
+		table: {
+			contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties' ]
+		}
+	} )
+	.then( editor => {
+		window.editorStyling = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 4 - 0
packages/ckeditor5-table/docs/features/table.md

@@ -11,6 +11,10 @@ The {@link module:table/table~Table} feature offers table creation and editing t
 
 {@snippet features/table}
 
+## Styling tables
+
+{@snippet features/table-styling}
+
 ## Installation
 
 <info-box info>

+ 28 - 0
packages/ckeditor5-table/src/commands/utils.js

@@ -85,3 +85,31 @@ export function getSingleValue( objectOrString ) {
 		return top;
 	}
 }
+
+/**
+ * Adds a unit to a value if the value is a number or a string representing a number.
+ *
+ * **Note**: It does nothing to non-numeric values.
+ *
+ *		getSingleValue( 25, 'px' );		// '25px'
+ *		getSingleValue( 25, 'em' );		// '25em'
+ *		getSingleValue( '25em', 'px' );	// '25em'
+ *		getSingleValue( 'foo', 'px' );	// 'foo'
+ *
+ * @param {*} value
+ * @param {String} defaultUnit A default unit added to a numeric value.
+ * @returns {String|*}
+ */
+export function addDefaultUnitToNumericValue( value, defaultUnit ) {
+	const numericValue = parseFloat( value );
+
+	if ( Number.isNaN( numericValue ) ) {
+		return value;
+	}
+
+	if ( String( numericValue ) !== String( value ) ) {
+		return value;
+	}
+
+	return `${ numericValue }${ defaultUnit }`;
+}

+ 1 - 1
packages/ckeditor5-table/src/converters/tableproperties.js

@@ -114,7 +114,7 @@ export function downcastTableAttribute( conversion, modelAttribute, styleName )
 		if ( attributeNewValue ) {
 			writer.setStyle( styleName, attributeNewValue, table );
 		} else {
-			writer.removeAttribute( styleName, table );
+			writer.removeStyle( styleName, table );
 		}
 	} ) );
 }

+ 16 - 1
packages/ckeditor5-table/src/tablecellproperties/commands/tablecellborderwidthcommand.js

@@ -7,8 +7,8 @@
  * @module table/tablecellproperties/commands/tablecellborderwidthcommand
  */
 
+import { addDefaultUnitToNumericValue, getSingleValue } from '../../commands/utils';
 import TableCellPropertyCommand from './tablecellpropertycommand';
-import { getSingleValue } from '../../commands/utils';
 
 /**
  * The table cell border width command.
@@ -22,6 +22,14 @@ import { getSingleValue } from '../../commands/utils';
  *			value: '5px'
  *		} );
  *
+ * **Note**: This command adds the default `'px'` unit to numeric values. Executing:
+ *
+ *		editor.execute( 'tableCellBorderWidth', {
+ *			value: '5'
+ *		} );
+ *
+ * will set the `borderWidth` attribute to `'5px'` in the model.
+ *
  * @extends module:core/command~Command
  */
 export default class TableCellBorderWidthCommand extends TableCellPropertyCommand {
@@ -44,4 +52,11 @@ export default class TableCellBorderWidthCommand extends TableCellPropertyComman
 
 		return getSingleValue( tableCell.getAttribute( this.attributeName ) );
 	}
+
+	/**
+	 * @inheritDoc
+	 */
+	_getValueToSet( value ) {
+		return addDefaultUnitToNumericValue( value, 'px' );
+	}
 }

+ 16 - 0
packages/ckeditor5-table/src/tablecellproperties/commands/tablecellheightcommand.js

@@ -7,6 +7,7 @@
  * @module table/tablecellproperties/commands/tablecellheightcommand
  */
 
+import { addDefaultUnitToNumericValue } from '../../commands/utils';
 import TableCellPropertyCommand from './tablecellpropertycommand';
 
 /**
@@ -21,6 +22,14 @@ import TableCellPropertyCommand from './tablecellpropertycommand';
  *			value: '50px'
  *		} );
  *
+ * **Note**: This command adds the default `'px'` unit to numeric values. Executing:
+ *
+ *		editor.execute( 'tableCellHeight', {
+ *			value: '50'
+ *		} );
+ *
+ * will set the `height` attribute to `'50px'` in the model.
+ *
  * @extends module:table/tablecellproperties/commands/tablecellpropertycommand
  */
 export default class TableCellHeightCommand extends TableCellPropertyCommand {
@@ -32,4 +41,11 @@ export default class TableCellHeightCommand extends TableCellPropertyCommand {
 	constructor( editor ) {
 		super( editor, 'height' );
 	}
+
+	/**
+	 * @inheritDoc
+	 */
+	_getValueToSet( value ) {
+		return addDefaultUnitToNumericValue( value, 'px' );
+	}
 }

+ 15 - 1
packages/ckeditor5-table/src/tablecellproperties/commands/tablecellpaddingcommand.js

@@ -7,8 +7,8 @@
  * @module table/tablecellproperties/commands/tablecellpaddingcommand
  */
 
+import { addDefaultUnitToNumericValue, getSingleValue } from '../../commands/utils';
 import TableCellPropertyCommand from './tablecellpropertycommand';
-import { getSingleValue } from '../../commands/utils';
 
 /**
  * The table cell padding command.
@@ -22,6 +22,13 @@ import { getSingleValue } from '../../commands/utils';
  *			value: '5px'
  *		} );
  *
+ * **Note**: This command adds the default `'px'` unit to numeric values. Executing:
+ *
+ *		editor.execute( 'tableCellPadding', {
+ *			value: '5'
+ *		} );
+ *
+ * will set the `padding` attribute to `'5px'` in the model.
  * @extends module:table/tablecellproperties/commands/tablecellpropertycommand
  */
 export default class TableCellPaddingCommand extends TableCellPropertyCommand {
@@ -44,4 +51,11 @@ export default class TableCellPaddingCommand extends TableCellPropertyCommand {
 
 		return getSingleValue( tableCell.getAttribute( this.attributeName ) );
 	}
+
+	/**
+	 * @inheritDoc
+	 */
+	_getValueToSet( value ) {
+		return addDefaultUnitToNumericValue( value, 'px' );
+	}
 }

+ 14 - 2
packages/ckeditor5-table/src/tablecellproperties/commands/tablecellpropertycommand.js

@@ -62,10 +62,11 @@ export default class TableCellPropertyCommand extends Command {
 
 		const tableCells = Array.from( selection.getSelectedBlocks() )
 			.map( element => findAncestor( 'tableCell', model.createPositionAt( element, 0 ) ) );
+		const valueToSet = this._getValueToSet( value );
 
 		model.enqueueChange( batch || 'default', writer => {
-			if ( value ) {
-				tableCells.forEach( tableCell => writer.setAttribute( this.attributeName, value, tableCell ) );
+			if ( valueToSet ) {
+				tableCells.forEach( tableCell => writer.setAttribute( this.attributeName, valueToSet, tableCell ) );
 			} else {
 				tableCells.forEach( tableCell => writer.removeAttribute( this.attributeName, tableCell ) );
 			}
@@ -86,4 +87,15 @@ export default class TableCellPropertyCommand extends Command {
 
 		return tableCell.getAttribute( this.attributeName );
 	}
+
+	/**
+	 * Returns the proper model value. Can be used to add a default unit to numeric values.
+	 *
+	 * @private
+	 * @param {*} value
+	 * @returns {*}
+	 */
+	_getValueToSet( value ) {
+		return value;
+	}
 }

+ 16 - 0
packages/ckeditor5-table/src/tablecellproperties/commands/tablecellwidthcommand.js

@@ -7,6 +7,7 @@
  * @module table/tablecellproperties/commands/tablecellwidthcommand
  */
 
+import { addDefaultUnitToNumericValue } from '../../commands/utils';
 import TableCellPropertyCommand from './tablecellpropertycommand';
 
 /**
@@ -21,6 +22,14 @@ import TableCellPropertyCommand from './tablecellpropertycommand';
  *			value: '50px'
  *		} );
  *
+ * **Note**: This command adds a default `'px'` unit to a numeric values. Executing:
+ *
+ *		editor.execute( 'tableCellWidth', {
+ *			value: '50'
+ *		} );
+ *
+ * Will set `width` attribute to `'50px'` in the model.
+ *
  * @extends module:table/tablecellproperties/commands/tablecellpropertycommand
  */
 export default class TableCellWidthCommand extends TableCellPropertyCommand {
@@ -32,4 +41,11 @@ export default class TableCellWidthCommand extends TableCellPropertyCommand {
 	constructor( editor ) {
 		super( editor, 'width' );
 	}
+
+	/**
+	 * @inheritDoc
+	 */
+	_getValueToSet( value ) {
+		return addDefaultUnitToNumericValue( value, 'px' );
+	}
 }

+ 16 - 1
packages/ckeditor5-table/src/tableproperties/commands/tableborderwidthcommand.js

@@ -7,8 +7,8 @@
  * @module table/tableproperties/commands/tableborderwidthcommand
  */
 
+import { addDefaultUnitToNumericValue, getSingleValue } from '../../commands/utils';
 import TablePropertyCommand from './tablepropertycommand';
-import { getSingleValue } from '../../commands/utils';
 
 /**
  * The table width border command.
@@ -22,6 +22,14 @@ import { getSingleValue } from '../../commands/utils';
  *			value: '5px'
  *		} );
  *
+ * **Note**: This command adds the default `'px'` unit to numeric values. Executing:
+ *
+ *		editor.execute( 'tableBorderWidth', {
+ *			value: '5'
+ *		} );
+ *
+ * Will set the `borderWidth` attribute to `'5px'` in the model.
+ *
  * @extends module:table/tableproperties/commands/tablepropertycommand
  */
 export default class TableBorderWidthCommand extends TablePropertyCommand {
@@ -44,4 +52,11 @@ export default class TableBorderWidthCommand extends TablePropertyCommand {
 
 		return getSingleValue( table.getAttribute( this.attributeName ) );
 	}
+
+	/**
+	 * @inheritDoc
+	 */
+	_getValueToSet( value ) {
+		return addDefaultUnitToNumericValue( value, 'px' );
+	}
 }

+ 16 - 0
packages/ckeditor5-table/src/tableproperties/commands/tableheightcommand.js

@@ -8,6 +8,7 @@
  */
 
 import TablePropertyCommand from './tablepropertycommand';
+import { addDefaultUnitToNumericValue } from '../../commands/utils';
 
 /**
  * The table height command.
@@ -21,6 +22,14 @@ import TablePropertyCommand from './tablepropertycommand';
  *			value: '500px'
  *		} );
  *
+ * **Note**: This command adds the default `'px'` unit to numeric values. Executing:
+ *
+ *		editor.execute( 'tableHeight', {
+ *			value: '50'
+ *		} );
+ *
+ * Will set the `height` attribute to `'50px'` in the model.
+ *
  * @extends module:core/command~Command
  */
 export default class TableHeightCommand extends TablePropertyCommand {
@@ -32,4 +41,11 @@ export default class TableHeightCommand extends TablePropertyCommand {
 	constructor( editor ) {
 		super( editor, 'height' );
 	}
+
+	/**
+	 * @inheritDoc
+	 */
+	_getValueToSet( value ) {
+		return addDefaultUnitToNumericValue( value, 'px' );
+	}
 }

+ 14 - 2
packages/ckeditor5-table/src/tableproperties/commands/tablepropertycommand.js

@@ -61,10 +61,11 @@ export default class TablePropertyCommand extends Command {
 		const { value, batch } = options;
 
 		const table = findAncestor( 'table', selection.getFirstPosition() );
+		const valueToSet = this._getValueToSet( value );
 
 		model.enqueueChange( batch || 'default', writer => {
-			if ( value ) {
-				writer.setAttribute( this.attributeName, value, table );
+			if ( valueToSet ) {
+				writer.setAttribute( this.attributeName, valueToSet, table );
 			} else {
 				writer.removeAttribute( this.attributeName, table );
 			}
@@ -85,4 +86,15 @@ export default class TablePropertyCommand extends Command {
 
 		return table.getAttribute( this.attributeName );
 	}
+
+	/**
+	 * Returns the proper model value. Can be used to add a default unit to numeric values.
+	 *
+	 * @private
+	 * @param {*} value
+	 * @returns {*}
+	 */
+	_getValueToSet( value ) {
+		return value;
+	}
 }

+ 16 - 0
packages/ckeditor5-table/src/tableproperties/commands/tablewidthcommand.js

@@ -7,6 +7,7 @@
  * @module table/tableproperties/commands/tablewidthcommand
  */
 
+import { addDefaultUnitToNumericValue } from '../../commands/utils';
 import TablePropertyCommand from './tablepropertycommand';
 
 /**
@@ -21,6 +22,14 @@ import TablePropertyCommand from './tablepropertycommand';
  *			value: '400px'
  *		} );
  *
+ * **Note**: This command adds the default `'px'` unit to numeric values. Executing:
+ *
+ *		editor.execute( 'tableWidth', {
+ *			value: '50'
+ *		} );
+ *
+ * Will set the `width` attribute to `'50px'` in the model.
+ *
  * @extends module:table/tableproperties/commands/tablepropertycommand
  */
 export default class TableWidthCommand extends TablePropertyCommand {
@@ -32,4 +41,11 @@ export default class TableWidthCommand extends TablePropertyCommand {
 	constructor( editor ) {
 		super( editor, 'width' );
 	}
+
+	/**
+	 * @inheritDoc
+	 */
+	_getValueToSet( value ) {
+		return addDefaultUnitToNumericValue( value, 'px' );
+	}
 }

+ 23 - 4
packages/ckeditor5-table/src/tableproperties/tablepropertiesediting.js

@@ -11,8 +11,13 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import { addBorderRules } from '@ckeditor/ckeditor5-engine/src/view/styles/border';
 import { addBackgroundRules } from '@ckeditor/ckeditor5-engine/src/view/styles/background';
 
-import TableEditing from './../tableediting';
-import { downcastTableAttribute, upcastBorderStyles, upcastStyleToAttribute } from './../converters/tableproperties';
+import TableEditing from '../tableediting';
+import {
+	downcastAttributeToStyle,
+	downcastTableAttribute,
+	upcastBorderStyles,
+	upcastStyleToAttribute
+} from '../converters/tableproperties';
 import TableBackgroundColorCommand from './commands/tablebackgroundcolorcommand';
 import TableBorderColorCommand from './commands/tablebordercolorcommand';
 import TableBorderStyleCommand from './commands/tableborderstylecommand';
@@ -76,10 +81,10 @@ export default class TablePropertiesEditing extends Plugin {
 		enableAlignmentProperty( schema, conversion );
 		editor.commands.add( 'tableAlignment', new TableAlignmentCommand( editor ) );
 
-		enableProperty( schema, conversion, 'width', 'width' );
+		enableTableToFigureProperty( schema, conversion, 'width', 'width' );
 		editor.commands.add( 'tableWidth', new TableWidthCommand( editor ) );
 
-		enableProperty( schema, conversion, 'height', 'height' );
+		enableTableToFigureProperty( schema, conversion, 'height', 'height' );
 		editor.commands.add( 'tableHeight', new TableHeightCommand( editor ) );
 
 		viewDoc.addStyleProcessorRules( addBackgroundRules );
@@ -166,3 +171,17 @@ function enableProperty( schema, conversion, modelAttribute, styleName ) {
 	upcastStyleToAttribute( conversion, 'table', modelAttribute, styleName );
 	downcastTableAttribute( conversion, modelAttribute, styleName );
 }
+
+// Enables conversion for an attribute for simple view (figure) to model (table) mappings.
+//
+// @param {String} modelAttribute
+// @param {String} styleName
+// @param {module:engine/model/schema~Schema} schema
+// @param {module:engine/conversion/conversion~Conversion} conversion
+function enableTableToFigureProperty( schema, conversion, modelAttribute, styleName ) {
+	schema.extend( 'table', {
+		allowAttributes: [ modelAttribute ]
+	} );
+	upcastStyleToAttribute( conversion, 'table', modelAttribute, styleName );
+	downcastAttributeToStyle( conversion, 'table', modelAttribute, styleName );
+}

+ 10 - 2
packages/ckeditor5-table/src/ui/utils.js

@@ -153,7 +153,7 @@ export function colorFieldValidator( value ) {
 }
 
 /**
- * Returns `true` when the passed value is an empty string or a valid CSS length expression.
+ * Returns `true` when the passed value is an empty string, number without unit or a valid CSS length expression.
  * Otherwise, `false` is returned.
  *
  * See {@link module:engine/view/styles/utils~isLength}.
@@ -164,7 +164,7 @@ export function colorFieldValidator( value ) {
 export function lengthFieldValidator( value ) {
 	value = value.trim();
 
-	return isEmpty( value ) || isLength( value );
+	return isEmpty( value ) || isNumberString( value ) || isLength( value );
 }
 
 /**
@@ -234,3 +234,11 @@ export function fillToolbar( { view, icons, toolbar, labels, propertyName, nameT
 		toolbar.items.add( button );
 	}
 }
+
+// A simple helper method to detect number strings.
+// I allows full number notation, so omitting 0 is not allowed:
+function isNumberString( value ) {
+	const parsedValue = parseFloat( value );
+
+	return !Number.isNaN( parsedValue ) && value === String( parsedValue );
+}

+ 1 - 1
packages/ckeditor5-table/tests/_utils/utils.js

@@ -317,7 +317,7 @@ export function assertTableStyle( editor, tableStyle, figureStyle ) {
  * An assertion helper for testing the `<td>` style attribute.
  *
  * @param {module:core/editor/editor~Editor} editor
- * @param {String} tableCellStyle A style to assert on td.
+ * @param {String} [tableCellStyle=''] A style to assert on td.
  */
 export function assertTableCellStyle( editor, tableCellStyle ) {
 	assertEqualMarkup( editor.getData(),

+ 56 - 0
packages/ckeditor5-table/tests/tablecellproperties/commands/tablecellborderwidthcommand.js

@@ -121,6 +121,62 @@ describe( 'table cell properties', () => {
 					sinon.assert.calledWith( spy, batch );
 				} );
 
+				it( 'should add default unit for numeric values (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableCellStyle( editor, 'border-bottom:25px;border-left:25px;border-right:25px;border-top:25px;' );
+				} );
+
+				it( 'should add default unit for numeric values (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableCellStyle( editor, 'border-bottom:25px;border-left:25px;border-right:25px;border-top:25px;' );
+				} );
+
+				it( 'should not add default unit for numeric values with unit', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '25pt' } );
+
+					assertTableCellStyle( editor, 'border-bottom:25pt;border-left:25pt;border-right:25pt;border-top:25pt;' );
+				} );
+
+				it( 'should add default unit to floats (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25.1 } );
+
+					assertTableCellStyle( editor, 'border-bottom:25.1px;border-left:25.1px;border-right:25.1px;border-top:25.1px;' );
+				} );
+
+				it( 'should add default unit to floats (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '0.1' } );
+
+					assertTableCellStyle( editor, 'border-bottom:0.1px;border-left:0.1px;border-right:0.1px;border-top:0.1px;' );
+				} );
+
+				it( 'should pass invalid values', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 'bar' } );
+
+					assertTableCellStyle( editor, 'border-bottom:bar;border-left:bar;border-right:bar;border-top:bar;' );
+				} );
+
+				it( 'should pass invalid value (string passed, CSS float without leading 0)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '.2' } );
+
+					assertTableCellStyle( editor, 'border-bottom:.2;border-left:.2;border-right:.2;border-top:.2;' );
+				} );
+
 				describe( 'collapsed selection', () => {
 					it( 'should set selected table cell borderWidth to a passed value', () => {
 						setData( model, modelTable( [ [ 'foo[]' ] ] ) );

+ 56 - 0
packages/ckeditor5-table/tests/tablecellproperties/commands/tablecellheightcommand.js

@@ -96,6 +96,62 @@ describe( 'table cell properties', () => {
 					sinon.assert.calledWith( spy, batch );
 				} );
 
+				it( 'should add default unit for numeric values (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableCellStyle( editor, 'height:25px;' );
+				} );
+
+				it( 'should add default unit for numeric values (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableCellStyle( editor, 'height:25px;' );
+				} );
+
+				it( 'should not add default unit for numeric values with unit', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '25pt' } );
+
+					assertTableCellStyle( editor, 'height:25pt;' );
+				} );
+
+				it( 'should add default unit to floats (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25.1 } );
+
+					assertTableCellStyle( editor, 'height:25.1px;' );
+				} );
+
+				it( 'should add default unit to floats (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '0.1' } );
+
+					assertTableCellStyle( editor, 'height:0.1px;' );
+				} );
+
+				it( 'should pass invalid values', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 'bar' } );
+
+					assertTableCellStyle( editor, 'height:bar;' );
+				} );
+
+				it( 'should pass invalid value (string passed, CSS float without leading 0)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '.2' } );
+
+					assertTableCellStyle( editor, 'height:.2;' );
+				} );
+
 				describe( 'collapsed selection', () => {
 					it( 'should set selected table cell height to a passed value', () => {
 						setData( model, modelTable( [ [ 'foo[]' ] ] ) );

+ 56 - 0
packages/ckeditor5-table/tests/tablecellproperties/commands/tablecellpaddingcommand.js

@@ -121,6 +121,62 @@ describe( 'table cell properties', () => {
 					sinon.assert.calledWith( spy, batch );
 				} );
 
+				it( 'should add default unit for numeric values (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableCellStyle( editor, 'padding:25px;' );
+				} );
+
+				it( 'should add default unit for numeric values (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableCellStyle( editor, 'padding:25px;' );
+				} );
+
+				it( 'should not add default unit for numeric values with unit', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '25pt' } );
+
+					assertTableCellStyle( editor, 'padding:25pt;' );
+				} );
+
+				it( 'should add default unit to floats (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25.1 } );
+
+					assertTableCellStyle( editor, 'padding:25.1px;' );
+				} );
+
+				it( 'should add default unit to floats (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '0.1' } );
+
+					assertTableCellStyle( editor, 'padding:0.1px;' );
+				} );
+
+				it( 'should pass invalid values', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 'bar' } );
+
+					assertTableCellStyle( editor, 'padding:bar;' );
+				} );
+
+				it( 'should pass invalid value (string passed, CSS float without leading 0)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '.2' } );
+
+					assertTableCellStyle( editor, 'padding:.2;' );
+				} );
+
 				describe( 'collapsed selection', () => {
 					it( 'should set selected table cell padding to a passed value', () => {
 						setData( model, modelTable( [ [ 'foo[]' ] ] ) );

+ 56 - 0
packages/ckeditor5-table/tests/tablecellproperties/commands/tablecellwidthcommand.js

@@ -96,6 +96,62 @@ describe( 'table cell properties', () => {
 					sinon.assert.calledWith( spy, batch );
 				} );
 
+				it( 'should add default unit for numeric values (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableCellStyle( editor, 'width:25px;' );
+				} );
+
+				it( 'should add default unit for numeric values (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableCellStyle( editor, 'width:25px;' );
+				} );
+
+				it( 'should not add default unit for numeric values with unit', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '25pt' } );
+
+					assertTableCellStyle( editor, 'width:25pt;' );
+				} );
+
+				it( 'should add default unit to floats (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25.1 } );
+
+					assertTableCellStyle( editor, 'width:25.1px;' );
+				} );
+
+				it( 'should add default unit to floats (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '0.1' } );
+
+					assertTableCellStyle( editor, 'width:0.1px;' );
+				} );
+
+				it( 'should pass invalid values', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 'bar' } );
+
+					assertTableCellStyle( editor, 'width:bar;' );
+				} );
+
+				it( 'should pass invalid value (string passed, CSS float without leading 0)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '.2' } );
+
+					assertTableCellStyle( editor, 'width:.2;' );
+				} );
+
 				describe( 'collapsed selection', () => {
 					it( 'should set selected table cell width to a passed value', () => {
 						setData( model, modelTable( [ [ 'foo[]' ] ] ) );

+ 72 - 0
packages/ckeditor5-table/tests/tablecellproperties/tablecellpropertiesediting.js

@@ -644,6 +644,24 @@ describe( 'table cell properties', () => {
 
 					assertTableCellStyle( editor, 'background-color:#f00;' );
 				} );
+
+				it( 'should downcast backgroundColor removal', () => {
+					model.change( writer => writer.setAttribute( 'backgroundColor', '#f00', tableCell ) );
+
+					model.change( writer => writer.removeAttribute( 'backgroundColor', tableCell ) );
+
+					assertTableCellStyle( editor );
+				} );
+
+				it( 'should downcast backgroundColor change', () => {
+					model.change( writer => writer.setAttribute( 'backgroundColor', '#f00', tableCell ) );
+
+					assertTableCellStyle( editor, 'background-color:#f00;' );
+
+					model.change( writer => writer.setAttribute( 'backgroundColor', '#ba7', tableCell ) );
+
+					assertTableCellStyle( editor, 'background-color:#ba7;' );
+				} );
 			} );
 		} );
 
@@ -876,6 +894,24 @@ describe( 'table cell properties', () => {
 
 					assertTableCellStyle( editor, 'padding:2px 3px 4px 5px;' );
 				} );
+
+				it( 'should downcast padding removal', () => {
+					model.change( writer => writer.setAttribute( 'padding', '1337px', tableCell ) );
+
+					model.change( writer => writer.removeAttribute( 'padding', tableCell ) );
+
+					assertTableCellStyle( editor );
+				} );
+
+				it( 'should downcast padding change', () => {
+					model.change( writer => writer.setAttribute( 'padding', '1337px', tableCell ) );
+
+					assertTableCellStyle( editor, 'padding:1337px;' );
+
+					model.change( writer => writer.setAttribute( 'padding', '1410em', tableCell ) );
+
+					assertTableCellStyle( editor, 'padding:1410em;' );
+				} );
 			} );
 		} );
 
@@ -939,6 +975,24 @@ describe( 'table cell properties', () => {
 						'<figure class="table"><table><tbody><tr><td style="width:20px;">foo</td></tr></tbody></table></figure>'
 					);
 				} );
+
+				it( 'should downcast width removal', () => {
+					model.change( writer => writer.setAttribute( 'width', '1337px', tableCell ) );
+
+					model.change( writer => writer.removeAttribute( 'width', tableCell ) );
+
+					assertTableCellStyle( editor );
+				} );
+
+				it( 'should downcast width change', () => {
+					model.change( writer => writer.setAttribute( 'width', '1337px', tableCell ) );
+
+					assertTableCellStyle( editor, 'width:1337px;' );
+
+					model.change( writer => writer.setAttribute( 'width', '1410em', tableCell ) );
+
+					assertTableCellStyle( editor, 'width:1410em;' );
+				} );
 			} );
 		} );
 
@@ -1002,6 +1056,24 @@ describe( 'table cell properties', () => {
 						'<figure class="table"><table><tbody><tr><td style="height:20px;">foo</td></tr></tbody></table></figure>'
 					);
 				} );
+
+				it( 'should downcast height removal', () => {
+					model.change( writer => writer.setAttribute( 'height', '1337px', tableCell ) );
+
+					model.change( writer => writer.removeAttribute( 'height', tableCell ) );
+
+					assertTableCellStyle( editor );
+				} );
+
+				it( 'should downcast height change', () => {
+					model.change( writer => writer.setAttribute( 'height', '1337px', tableCell ) );
+
+					assertTableCellStyle( editor, 'height:1337px;' );
+
+					model.change( writer => writer.setAttribute( 'height', '1410em', tableCell ) );
+
+					assertTableCellStyle( editor, 'height:1410em;' );
+				} );
 			} );
 		} );
 	} );

+ 56 - 0
packages/ckeditor5-table/tests/tableproperties/commands/tableborderwidthcommand.js

@@ -121,6 +121,62 @@ describe( 'table properties', () => {
 					sinon.assert.calledWith( spy, batch );
 				} );
 
+				it( 'should add default unit for numeric values (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableStyle( editor, 'border-bottom:25px;border-left:25px;border-right:25px;border-top:25px;' );
+				} );
+
+				it( 'should add default unit for numeric values (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableStyle( editor, 'border-bottom:25px;border-left:25px;border-right:25px;border-top:25px;' );
+				} );
+
+				it( 'should not add default unit for numeric values with unit', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '25pt' } );
+
+					assertTableStyle( editor, 'border-bottom:25pt;border-left:25pt;border-right:25pt;border-top:25pt;' );
+				} );
+
+				it( 'should add default unit to floats (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25.1 } );
+
+					assertTableStyle( editor, 'border-bottom:25.1px;border-left:25.1px;border-right:25.1px;border-top:25.1px;' );
+				} );
+
+				it( 'should add default unit to floats (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '0.1' } );
+
+					assertTableStyle( editor, 'border-bottom:0.1px;border-left:0.1px;border-right:0.1px;border-top:0.1px;' );
+				} );
+
+				it( 'should pass invalid values', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 'bar' } );
+
+					assertTableStyle( editor, 'border-bottom:bar;border-left:bar;border-right:bar;border-top:bar;' );
+				} );
+
+				it( 'should pass invalid value (string passed, CSS float without leading 0)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '.2' } );
+
+					assertTableStyle( editor, 'border-bottom:.2;border-left:.2;border-right:.2;border-top:.2;' );
+				} );
+
 				describe( 'collapsed selection', () => {
 					it( 'should set selected table borderWidth to a passed value', () => {
 						setData( model, modelTable( [ [ 'foo[]' ] ] ) );

+ 60 - 4
packages/ckeditor5-table/tests/tableproperties/commands/tableheightcommand.js

@@ -96,13 +96,69 @@ describe( 'table properties', () => {
 					sinon.assert.calledWith( spy, batch );
 				} );
 
+				it( 'should add default unit for numeric values (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableStyle( editor, null, 'height:25px;' );
+				} );
+
+				it( 'should add default unit for numeric values (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableStyle( editor, null, 'height:25px;' );
+				} );
+
+				it( 'should not add default unit for numeric values with unit', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '25pt' } );
+
+					assertTableStyle( editor, null, 'height:25pt;' );
+				} );
+
+				it( 'should add default unit to floats (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25.1 } );
+
+					assertTableStyle( editor, null, 'height:25.1px;' );
+				} );
+
+				it( 'should add default unit to floats (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '0.1' } );
+
+					assertTableStyle( editor, null, 'height:0.1px;' );
+				} );
+
+				it( 'should pass invalid values', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 'bar' } );
+
+					assertTableStyle( editor, null, 'height:bar;' );
+				} );
+
+				it( 'should pass invalid value (string passed, CSS float without leading 0)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '.2' } );
+
+					assertTableStyle( editor, null, 'height:.2;' );
+				} );
+
 				describe( 'collapsed selection', () => {
 					it( 'should set selected table height to a passed value', () => {
 						setData( model, modelTable( [ [ 'foo[]' ] ] ) );
 
 						command.execute( { value: '25px' } );
 
-						assertTableStyle( editor, 'height:25px;' );
+						assertTableStyle( editor, null, 'height:25px;' );
 					} );
 
 					it( 'should change selected table height to a passed value', () => {
@@ -110,7 +166,7 @@ describe( 'table properties', () => {
 
 						command.execute( { value: '25px' } );
 
-						assertTableStyle( editor, 'height:25px;' );
+						assertTableStyle( editor, null, 'height:25px;' );
 					} );
 
 					it( 'should remove height from a selected table if no value is passed', () => {
@@ -128,7 +184,7 @@ describe( 'table properties', () => {
 
 						command.execute( { value: '25px' } );
 
-						assertTableStyle( editor, 'height:25px;' );
+						assertTableStyle( editor, null, 'height:25px;' );
 					} );
 
 					it( 'should change selected table height to a passed value', () => {
@@ -136,7 +192,7 @@ describe( 'table properties', () => {
 
 						command.execute( { value: '25px' } );
 
-						assertTableStyle( editor, 'height:25px;' );
+						assertTableStyle( editor, null, 'height:25px;' );
 					} );
 
 					it( 'should remove height from a selected table if no value is passed', () => {

+ 60 - 4
packages/ckeditor5-table/tests/tableproperties/commands/tablewidthcommand.js

@@ -96,13 +96,69 @@ describe( 'table properties', () => {
 					sinon.assert.calledWith( spy, batch );
 				} );
 
+				it( 'should add default unit for numeric values (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableStyle( editor, null, 'width:25px;' );
+				} );
+
+				it( 'should add default unit for numeric values (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25 } );
+
+					assertTableStyle( editor, null, 'width:25px;' );
+				} );
+
+				it( 'should not add default unit for numeric values with unit', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '25pt' } );
+
+					assertTableStyle( editor, null, 'width:25pt;' );
+				} );
+
+				it( 'should add default unit to floats (number passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 25.1 } );
+
+					assertTableStyle( editor, null, 'width:25.1px;' );
+				} );
+
+				it( 'should add default unit to floats (string passed)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '0.1' } );
+
+					assertTableStyle( editor, null, 'width:0.1px;' );
+				} );
+
+				it( 'should pass invalid values', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: 'bar' } );
+
+					assertTableStyle( editor, null, 'width:bar;' );
+				} );
+
+				it( 'should pass invalid value (string passed, CSS float without leading 0)', () => {
+					setData( model, modelTable( [ [ 'foo[]' ] ] ) );
+
+					command.execute( { value: '.2' } );
+
+					assertTableStyle( editor, null, 'width:.2;' );
+				} );
+
 				describe( 'collapsed selection', () => {
 					it( 'should set selected table width to a passed value', () => {
 						setData( model, modelTable( [ [ 'foo[]' ] ] ) );
 
 						command.execute( { value: '25px' } );
 
-						assertTableStyle( editor, 'width:25px;' );
+						assertTableStyle( editor, null, 'width:25px;' );
 					} );
 
 					it( 'should change selected table width to a passed value', () => {
@@ -110,7 +166,7 @@ describe( 'table properties', () => {
 
 						command.execute( { value: '25px' } );
 
-						assertTableStyle( editor, 'width:25px;' );
+						assertTableStyle( editor, null, 'width:25px;' );
 					} );
 
 					it( 'should remove width from a selected table if no value is passed', () => {
@@ -128,7 +184,7 @@ describe( 'table properties', () => {
 
 						command.execute( { value: '25px' } );
 
-						assertTableStyle( editor, 'width:25px;' );
+						assertTableStyle( editor, null, 'width:25px;' );
 					} );
 
 					it( 'should change selected table width to a passed value', () => {
@@ -136,7 +192,7 @@ describe( 'table properties', () => {
 
 						command.execute( { value: '25px' } );
 
-						assertTableStyle( editor, 'width:25px;' );
+						assertTableStyle( editor, null, 'width:25px;' );
 					} );
 
 					it( 'should remove width from a selected table if no value is passed', () => {

+ 72 - 4
packages/ckeditor5-table/tests/tableproperties/tablepropertiesediting.js

@@ -593,6 +593,24 @@ describe( 'table properties', () => {
 
 					assertTableStyle( editor, 'background-color:#f00;' );
 				} );
+
+				it( 'should downcast backgroundColor removal', () => {
+					model.change( writer => writer.setAttribute( 'backgroundColor', '#f00', table ) );
+
+					model.change( writer => writer.removeAttribute( 'backgroundColor', table ) );
+
+					assertTableStyle( editor );
+				} );
+
+				it( 'should downcast backgroundColor change', () => {
+					model.change( writer => writer.setAttribute( 'backgroundColor', '#f00', table ) );
+
+					assertTableStyle( editor, 'background-color:#f00;' );
+
+					model.change( writer => writer.setAttribute( 'backgroundColor', '#ba7', table ) );
+
+					assertTableStyle( editor, 'background-color:#ba7;' );
+				} );
 			} );
 		} );
 
@@ -602,12 +620,19 @@ describe( 'table properties', () => {
 			} );
 
 			describe( 'upcast conversion', () => {
-				it( 'should upcast width', () => {
+				it( 'should upcast width from <table>', () => {
 					editor.setData( '<table style="width:1337px"><tr><td>foo</td></tr></table>' );
 					const table = model.document.getRoot().getNodeByPath( [ 0 ] );
 
 					expect( table.getAttribute( 'width' ) ).to.equal( '1337px' );
 				} );
+
+				it( 'should upcast width from <figure>', () => {
+					editor.setData( '<figure style="width:1337px"><table><tr><td>foo</td></tr></table></figure>' );
+					const table = model.document.getRoot().getNodeByPath( [ 0 ] );
+
+					expect( table.getAttribute( 'width' ) ).to.equal( '1337px' );
+				} );
 			} );
 
 			describe( 'downcast conversion', () => {
@@ -640,7 +665,25 @@ describe( 'table properties', () => {
 				it( 'should downcast width', () => {
 					model.change( writer => writer.setAttribute( 'width', '1337px', table ) );
 
-					assertTableStyle( editor, 'width:1337px;' );
+					assertTableStyle( editor, null, 'width:1337px;' );
+				} );
+
+				it( 'should downcast width removal', () => {
+					model.change( writer => writer.setAttribute( 'width', '1337px', table ) );
+
+					model.change( writer => writer.removeAttribute( 'width', table ) );
+
+					assertTableStyle( editor );
+				} );
+
+				it( 'should downcast width change', () => {
+					model.change( writer => writer.setAttribute( 'width', '1337px', table ) );
+
+					assertTableStyle( editor, null, 'width:1337px;' );
+
+					model.change( writer => writer.setAttribute( 'width', '1410em', table ) );
+
+					assertTableStyle( editor, null, 'width:1410em;' );
 				} );
 			} );
 		} );
@@ -651,12 +694,19 @@ describe( 'table properties', () => {
 			} );
 
 			describe( 'upcast conversion', () => {
-				it( 'should upcast height', () => {
+				it( 'should upcast height from <table>', () => {
 					editor.setData( '<table style="height:1337px"><tr><td>foo</td></tr></table>' );
 					const table = model.document.getRoot().getNodeByPath( [ 0 ] );
 
 					expect( table.getAttribute( 'height' ) ).to.equal( '1337px' );
 				} );
+
+				it( 'should upcast height from <figure>', () => {
+					editor.setData( '<figure style="height:1337px"><table><tr><td>foo</td></tr></table></figure>' );
+					const table = model.document.getRoot().getNodeByPath( [ 0 ] );
+
+					expect( table.getAttribute( 'height' ) ).to.equal( '1337px' );
+				} );
 			} );
 
 			describe( 'downcast conversion', () => {
@@ -669,7 +719,25 @@ describe( 'table properties', () => {
 				it( 'should downcast height', () => {
 					model.change( writer => writer.setAttribute( 'height', '1337px', table ) );
 
-					assertTableStyle( editor, 'height:1337px;' );
+					assertTableStyle( editor, null, 'height:1337px;' );
+				} );
+
+				it( 'should downcast height removal', () => {
+					model.change( writer => writer.setAttribute( 'height', '1337px', table ) );
+
+					model.change( writer => writer.removeAttribute( 'height', table ) );
+
+					assertTableStyle( editor );
+				} );
+
+				it( 'should downcast height change', () => {
+					model.change( writer => writer.setAttribute( 'height', '1337px', table ) );
+
+					assertTableStyle( editor, null, 'height:1337px;' );
+
+					model.change( writer => writer.setAttribute( 'height', '1410em', table ) );
+
+					assertTableStyle( editor, null, 'height:1410em;' );
 				} );
 
 				it( 'should consume converted item', () => {

+ 16 - 4
packages/ckeditor5-table/tests/ui/utils.js

@@ -211,11 +211,11 @@ describe( 'UI Utils', () => {
 	} );
 
 	describe( 'colorFieldValidator()', () => {
-		it( 'should passe for an empty value', () => {
+		it( 'should pass for an empty value', () => {
 			expect( colorFieldValidator( '' ) ).to.be.true;
 		} );
 
-		it( 'should passe for white spaces', () => {
+		it( 'should pass for white spaces', () => {
 			expect( colorFieldValidator( '  ' ) ).to.be.true;
 		} );
 
@@ -233,11 +233,11 @@ describe( 'UI Utils', () => {
 	} );
 
 	describe( 'lengthFieldValidator()', () => {
-		it( 'should passe for an empty value', () => {
+		it( 'should pass for an empty value', () => {
 			expect( lengthFieldValidator( '' ) ).to.be.true;
 		} );
 
-		it( 'should passe for white spaces', () => {
+		it( 'should pass for white spaces', () => {
 			expect( lengthFieldValidator( '  ' ) ).to.be.true;
 		} );
 
@@ -247,6 +247,18 @@ describe( 'UI Utils', () => {
 			expect( lengthFieldValidator( ' 12em ' ) ).to.be.true;
 		} );
 
+		it( 'should pass for number without unit', () => {
+			expect( lengthFieldValidator( '1' ) ).to.be.true;
+			expect( lengthFieldValidator( '12.1' ) ).to.be.true;
+			expect( lengthFieldValidator( '0.125 ' ) ).to.be.true;
+		} );
+
+		it( 'should not pass for invalid number values', () => {
+			expect( lengthFieldValidator( '.1 ' ) ).to.be.false;
+			expect( lengthFieldValidator( '45. ' ) ).to.be.false;
+			expect( lengthFieldValidator( '45.1.1 ' ) ).to.be.false;
+		} );
+
 		it( 'should pass for lengths surrounded by white spaces', () => {
 			expect( lengthFieldValidator( '3px ' ) ).to.be.true;
 			expect( lengthFieldValidator( ' 12em ' ) ).to.be.true;

+ 5 - 0
packages/ckeditor5-table/theme/table.css

@@ -13,6 +13,11 @@
 		border-collapse: collapse;
 		border-spacing: 0;
 
+		/* Table width and height are set on the parent <figure>. Make sure the table inside stretches
+		to the full dimensions of the container (https://github.com/ckeditor/ckeditor5/issues/6186). */
+		width: 100%;
+		height: 100%;
+
 		/* The outer border of the table should be slightly darker than the inner lines.
 		Also see https://github.com/ckeditor/ckeditor5-table/issues/50. */
 		border: 1px double hsl(0, 0%, 70%);