8
0
Pārlūkot izejas kodu

Add stub file for table styles conversion tests.

Maciej Gołaszewski 6 gadi atpakaļ
vecāks
revīzija
a6c02b47af

+ 5 - 370
packages/ckeditor5-table/src/tablestyle.js

@@ -8,23 +8,11 @@
  */
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
-import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
-import { findAncestor } from './commands/utils';
-
-function downcastToStyle( conversion, modelAttribute, viewStyleName ) {
-	conversion.for( 'downcast' ).attributeToAttribute( {
-		model: modelAttribute,
-		view: modelAttributeValue => ( {
-			key: 'style',
-			value: {
-				[ viewStyleName ]: modelAttributeValue
-			}
-		} )
-	} );
-}
+import TableStyleEditing from './tablestyleediting';
+import TableStyleUI from './tablestyleui';
 
 /**
- * The table editing feature.
+ * The table style feature.
  *
  * @extends module:core/plugin~Plugin
  */
@@ -32,360 +20,7 @@ export default class TableStyle extends Plugin {
 	/**
 	 * @inheritDoc
 	 */
-	init() {
-		const editor = this.editor;
-		const model = editor.model;
-		const schema = model.schema;
-		const conversion = editor.conversion;
-
-		schema.extend( 'table', {
-			allowAttributes: [ 'borderWidth', 'borderColor', 'borderStyle', 'background-color', 'width', 'height' ]
-		} );
-
-		schema.extend( 'tableRow', {
-			allowAttributes: [ 'height' ]
-		} );
-
-		schema.extend( 'tableCell', {
-			allowAttributes: [
-				'borderWidth', 'borderColor', 'borderStyle',
-				'background-color', 'padding', 'vertical-align', 'width', 'height' ]
-		} );
-
-		// Table attributes.
-		setupTableConversion( conversion, 'background-color' );
-		setupTableConversion( conversion, 'width' );
-		setupTableConversion( conversion, 'height' );
-
-		// Table row attributes.
-		setupConversion( conversion, 'height', 'tableRow' );
-
-		upcastBorderStyles( conversion, 'td' );
-		upcastBorderStyles( conversion, 'th' );
-		upcastBorderStyles( conversion, 'table' );
-
-		downcastToStyle( conversion, 'borderStyle', 'border-style' );
-		downcastToStyle( conversion, 'borderColor', 'border-color' );
-		downcastToStyle( conversion, 'borderWidth', 'border-width' );
-
-		setupConversion( conversion, 'background-color', 'tableCell' );
-		setupConversion( conversion, 'padding', 'tableCell' );
-		setupConversion( conversion, 'vertical-align', 'tableCell' );
-		setupConversion( conversion, 'width', 'tableCell' );
-
-		this._setupUI( editor );
-	}
-
-	// TODO: remove me
-	_setupUI( editor ) {
-		editor.ui.componentFactory.add( 'borderWidth', locale => {
-			const button = new ButtonView( locale );
-
-			button.set( {
-				label: 'Border width',
-				icon: false,
-				tooltip: true,
-				withText: true
-			} );
-
-			button.on( 'execute', () => {
-				const model = editor.model;
-				const document = model.document;
-				const selection = document.selection;
-				const firstPosition = selection.getFirstPosition();
-
-				const tableCell = findAncestor( 'tableCell', firstPosition );
-
-				const border = tableCell.getAttribute( 'border' );
-
-				let currentWidth;
-
-				if ( border ) {
-					const borderWidth = ( border && border.width ) || {};
-
-					// Unify width to one value. If different values are set default to top (or right, etc).
-					currentWidth = borderWidth.top || borderWidth.right || borderWidth.bottom || borderWidth.left;
-				}
-
-				// eslint-disable-next-line no-undef,no-alert
-				const newWidth = prompt( 'Set border width:', currentWidth || '' );
-
-				const parts = /^([0-9]*[.]?[0-9]*)([a-z]{2,4})?/.exec( newWidth );
-				const unit = parts[ 2 ];
-
-				const borderWidthToSet = parts[ 1 ] + ( unit || 'px' );
-
-				// TODO: Command, setting new value is dumb on `border` object.
-				editor.model.change( writer => {
-					writer.setAttribute( 'borderWidth', {
-						top: borderWidthToSet,
-						right: borderWidthToSet,
-						bottom: borderWidthToSet,
-						left: borderWidthToSet
-					}, tableCell );
-				} );
-			} );
-
-			return button;
-		} );
-
-		editor.ui.componentFactory.add( 'borderColor', locale => {
-			const button = new ButtonView( locale );
-
-			button.set( {
-				label: 'Border color',
-				icon: false,
-				tooltip: true,
-				withText: true
-			} );
-
-			button.on( 'execute', () => {
-				const model = editor.model;
-				const document = model.document;
-				const selection = document.selection;
-				const firstPosition = selection.getFirstPosition();
-
-				const tableCell = findAncestor( 'tableCell', firstPosition );
-
-				const border = tableCell.getAttribute( 'border' );
-
-				let currentColor;
-
-				if ( border ) {
-					const borderColor = ( border && border.color ) || {};
-
-					// Unify width to one value. If different values are set default to top (or right, etc).
-					currentColor = borderColor.top || borderColor.right || borderColor.bottom || borderColor.left;
-				}
-
-				// eslint-disable-next-line no-undef,no-alert
-				const newColor = prompt( 'Set new border color:', currentColor || '' );
-
-				// TODO: Command, setting new value is dumb on `border` object.
-				editor.model.change( writer => {
-					writer.setAttribute( 'borderColor', {
-						top: newColor,
-						right: newColor,
-						bottom: newColor,
-						left: newColor
-					}, tableCell );
-				} );
-			} );
-
-			return button;
-		} );
-
-		editor.ui.componentFactory.add( 'borderStyle', locale => {
-			const button = new ButtonView( locale );
-
-			button.set( {
-				label: 'Border style',
-				icon: false,
-				tooltip: true,
-				withText: true
-			} );
-
-			button.on( 'execute', () => {
-				const model = editor.model;
-				const document = model.document;
-				const selection = document.selection;
-				const firstPosition = selection.getFirstPosition();
-
-				const tableCell = findAncestor( 'tableCell', firstPosition );
-
-				const border = tableCell.getAttribute( 'border' );
-
-				let currentStyle;
-
-				if ( border ) {
-					const borderStyle = ( border && border.style ) || {};
-
-					// Unify width to one value. If different values are set default to top (or right, etc).
-					currentStyle = borderStyle.top || borderStyle.right || borderStyle.bottom || borderStyle.left;
-				}
-
-				// eslint-disable-next-line no-undef,no-alert
-				const newStyle = prompt( 'Set new border style:', currentStyle || '' );
-
-				// TODO: Command, setting new value is dumb on `border` object.
-				editor.model.change( writer => {
-					writer.setAttribute( 'borderStyle', {
-						top: newStyle,
-						right: newStyle,
-						bottom: newStyle,
-						left: newStyle
-					}, tableCell );
-				} );
-			} );
-
-			return button;
-		} );
-
-		editor.ui.componentFactory.add( 'backgroundColor', locale => {
-			const button = new ButtonView( locale );
-
-			button.set( {
-				label: 'Background color',
-				icon: false,
-				tooltip: true,
-				withText: true
-			} );
-
-			button.on( 'execute', () => {
-				const model = editor.model;
-				const document = model.document;
-				const selection = document.selection;
-				const firstPosition = selection.getFirstPosition();
-
-				const tableCell = findAncestor( 'tableCell', firstPosition );
-
-				const backgroundColor = tableCell.getAttribute( 'background-color' );
-
-				// eslint-disable-next-line no-undef,no-alert
-				const newColor = prompt( 'Set new background color:', backgroundColor || '' );
-
-				editor.model.change( writer => {
-					writer.setAttribute( 'background-color', newColor, tableCell );
-				} );
-			} );
-
-			return button;
-		} );
-
-		editor.ui.componentFactory.add( 'padding', locale => {
-			const button = new ButtonView( locale );
-
-			button.set( {
-				label: 'Cell padding',
-				icon: false,
-				tooltip: true,
-				withText: true
-			} );
-
-			button.on( 'execute', () => {
-				const model = editor.model;
-				const document = model.document;
-				const selection = document.selection;
-				const firstPosition = selection.getFirstPosition();
-
-				const tableCell = findAncestor( 'tableCell', firstPosition );
-
-				const padding = tableCell.getAttribute( 'padding' );
-
-				let currentPadding;
-
-				if ( padding ) {
-					// Unify width to one value. If different values are set default to top (or right, etc).
-					currentPadding = padding.top || padding.right || padding.bottom || padding.left;
-				}
-
-				// eslint-disable-next-line no-undef,no-alert
-				const newPadding = prompt( 'Set new padding:', currentPadding || '' );
-
-				editor.model.change( writer => {
-					writer.setAttribute( 'padding', newPadding, tableCell );
-				} );
-			} );
-
-			return button;
-		} );
+	static requires() {
+		return [ TableStyleEditing, TableStyleUI ];
 	}
 }
-
-function setupConversion( conversion, styleName, modelName ) {
-	// General upcast 'border' attribute (requires model border attribute to be allowed).
-	upcastAttribute( conversion, styleName, modelName );
-
-	// Downcast table cell only (table has own downcast converter).
-	conversion.for( 'downcast' ).attributeToAttribute( {
-		model: {
-			name: modelName,
-			key: styleName
-		},
-		view: modelAttributeValue => ( {
-			key: 'style',
-			value: {
-				[ styleName ]: modelAttributeValue
-			}
-		} )
-	} );
-}
-
-function upcastAttribute( conversion, styleName, modelName ) {
-	conversion.for( 'upcast' ).attributeToAttribute( {
-		view: {
-			styles: {
-				[ styleName ]: /[\s\S]+/
-			}
-		},
-		model: {
-			name: modelName,
-			key: styleName,
-			value: viewElement => viewElement.getNormalizedStyle( styleName )
-		}
-	} );
-}
-
-function upcastBorderStyles( conversion, viewElement ) {
-	conversion.for( 'upcast' ).add( dispatcher => dispatcher.on( 'element:' + viewElement, ( evt, data, conversionApi ) => {
-		let matcherPattern;
-
-		if ( data.viewItem.hasStyle( 'border' ) ) {
-			matcherPattern = {
-				styles: [ 'border' ]
-			};
-		} else {
-			const stylesToConsume = [
-				'border-top',
-				'border-right',
-				'border-bottom',
-				'border-left'
-			].filter( styleName => data.viewItem.hasStyle( styleName ) );
-
-			if ( stylesToConsume.length ) {
-				matcherPattern = {
-					styles: stylesToConsume
-				};
-			} else {
-				return;
-			}
-		}
-
-		// Try to consume appropriate values from consumable values list.
-		const toMatch = matcherPattern;
-
-		if ( !conversionApi.consumable.test( data.viewItem, toMatch ) ) {
-			return;
-		}
-
-		const modelElement = [ ...data.modelRange.getItems( { shallow: true } ) ].pop();
-
-		conversionApi.consumable.consume( data.viewItem, toMatch );
-
-		if ( conversionApi.schema.checkAttribute( modelElement, 'borderStyle' ) ) {
-			conversionApi.writer.setAttribute( 'borderStyle', data.viewItem.getNormalizedStyle( 'border-style' ), modelElement );
-		}
-
-		if ( conversionApi.schema.checkAttribute( modelElement, 'borderColor' ) ) {
-			conversionApi.writer.setAttribute( 'borderColor', data.viewItem.getNormalizedStyle( 'border-color' ), modelElement );
-		}
-
-		if ( conversionApi.schema.checkAttribute( modelElement, 'borderWidth' ) ) {
-			conversionApi.writer.setAttribute( 'borderWidth', data.viewItem.getNormalizedStyle( 'border-width' ), modelElement );
-		}
-	} ) );
-}
-
-function setupTableConversion( conversion, styleName ) {
-	upcastAttribute( conversion, styleName, 'table' );
-
-	// Properly downcast table border attribute on <table> and not on <figure>.
-	conversion.for( 'downcast' ).add( dispatcher => dispatcher.on( `attribute:${ styleName }:table`, ( evt, data, conversionApi ) => {
-		const { item, attributeNewValue } = data;
-		const { mapper, writer } = conversionApi;
-
-		const table = [ ...mapper.toViewElement( item ).getChildren() ].find( child => child.is( 'table' ) );
-
-		writer.setStyle( styleName, attributeNewValue, table );
-	} ) );
-}

+ 172 - 0
packages/ckeditor5-table/src/tablestyleediting.js

@@ -0,0 +1,172 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/**
+ * @module table/tablestyleediting
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+
+/**
+ * The tablestyle editing feature.
+ *
+ * @extends module:core/plugin~Plugin
+ */
+export default class TableStyleEditing extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		const editor = this.editor;
+		const model = editor.model;
+		const schema = model.schema;
+		const conversion = editor.conversion;
+
+		schema.extend( 'table', {
+			allowAttributes: [ 'borderWidth', 'borderColor', 'borderStyle', 'background-color', 'width', 'height' ]
+		} );
+
+		schema.extend( 'tableRow', {
+			allowAttributes: [ 'height' ]
+		} );
+
+		schema.extend( 'tableCell', {
+			allowAttributes: [
+				'borderWidth', 'borderColor', 'borderStyle',
+				'background-color', 'padding', 'vertical-align', 'width', 'height' ]
+		} );
+
+		// Table attributes.
+		setupTableConversion( conversion, 'background-color' );
+		setupTableConversion( conversion, 'width' );
+		setupTableConversion( conversion, 'height' );
+
+		// Table row attributes.
+		setupConversion( conversion, 'height', 'tableRow' );
+
+		upcastBorderStyles( conversion, 'td' );
+		upcastBorderStyles( conversion, 'th' );
+		upcastBorderStyles( conversion, 'table' );
+
+		downcastToStyle( conversion, 'borderStyle', 'border-style' );
+		downcastToStyle( conversion, 'borderColor', 'border-color' );
+		downcastToStyle( conversion, 'borderWidth', 'border-width' );
+
+		setupConversion( conversion, 'background-color', 'tableCell' );
+		setupConversion( conversion, 'padding', 'tableCell' );
+		setupConversion( conversion, 'vertical-align', 'tableCell' );
+		setupConversion( conversion, 'width', 'tableCell' );
+	}
+}
+
+function setupConversion( conversion, styleName, modelName ) {
+	// General upcast 'border' attribute (requires model border attribute to be allowed).
+	upcastAttribute( conversion, styleName, modelName );
+
+	// Downcast table cell only (table has own downcast converter).
+	conversion.for( 'downcast' ).attributeToAttribute( {
+		model: {
+			name: modelName,
+			key: styleName
+		},
+		view: modelAttributeValue => ( {
+			key: 'style',
+			value: {
+				[ styleName ]: modelAttributeValue
+			}
+		} )
+	} );
+}
+
+function upcastAttribute( conversion, styleName, modelName ) {
+	conversion.for( 'upcast' ).attributeToAttribute( {
+		view: {
+			styles: {
+				[ styleName ]: /[\s\S]+/
+			}
+		},
+		model: {
+			name: modelName,
+			key: styleName,
+			value: viewElement => viewElement.getNormalizedStyle( styleName )
+		}
+	} );
+}
+
+function upcastBorderStyles( conversion, viewElement ) {
+	conversion.for( 'upcast' ).add( dispatcher => dispatcher.on( 'element:' + viewElement, ( evt, data, conversionApi ) => {
+		let matcherPattern;
+
+		if ( data.viewItem.hasStyle( 'border' ) ) {
+			matcherPattern = {
+				styles: [ 'border' ]
+			};
+		} else {
+			const stylesToConsume = [
+				'border-top',
+				'border-right',
+				'border-bottom',
+				'border-left'
+			].filter( styleName => data.viewItem.hasStyle( styleName ) );
+
+			if ( stylesToConsume.length ) {
+				matcherPattern = {
+					styles: stylesToConsume
+				};
+			} else {
+				return;
+			}
+		}
+
+		// Try to consume appropriate values from consumable values list.
+		const toMatch = matcherPattern;
+
+		if ( !conversionApi.consumable.test( data.viewItem, toMatch ) ) {
+			return;
+		}
+
+		const modelElement = [ ...data.modelRange.getItems( { shallow: true } ) ].pop();
+
+		conversionApi.consumable.consume( data.viewItem, toMatch );
+
+		if ( conversionApi.schema.checkAttribute( modelElement, 'borderStyle' ) ) {
+			conversionApi.writer.setAttribute( 'borderStyle', data.viewItem.getNormalizedStyle( 'border-style' ), modelElement );
+		}
+
+		if ( conversionApi.schema.checkAttribute( modelElement, 'borderColor' ) ) {
+			conversionApi.writer.setAttribute( 'borderColor', data.viewItem.getNormalizedStyle( 'border-color' ), modelElement );
+		}
+
+		if ( conversionApi.schema.checkAttribute( modelElement, 'borderWidth' ) ) {
+			conversionApi.writer.setAttribute( 'borderWidth', data.viewItem.getNormalizedStyle( 'border-width' ), modelElement );
+		}
+	} ) );
+}
+
+function downcastToStyle( conversion, modelAttribute, viewStyleName ) {
+	conversion.for( 'downcast' ).attributeToAttribute( {
+		model: modelAttribute,
+		view: modelAttributeValue => ( {
+			key: 'style',
+			value: {
+				[ viewStyleName ]: modelAttributeValue
+			}
+		} )
+	} );
+}
+
+function setupTableConversion( conversion, styleName ) {
+	upcastAttribute( conversion, styleName, 'table' );
+
+	// Properly downcast table border attribute on <table> and not on <figure>.
+	conversion.for( 'downcast' ).add( dispatcher => dispatcher.on( `attribute:${ styleName }:table`, ( evt, data, conversionApi ) => {
+		const { item, attributeNewValue } = data;
+		const { mapper, writer } = conversionApi;
+
+		const table = [ ...mapper.toViewElement( item ).getChildren() ].find( child => child.is( 'table' ) );
+
+		writer.setStyle( styleName, attributeNewValue, table );
+	} ) );
+}

+ 232 - 0
packages/ckeditor5-table/src/tablestyleui.js

@@ -0,0 +1,232 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/**
+ * @module table/tablestyleui
+ */
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+import { findAncestor } from './commands/utils';
+
+/**
+ * The table style UI feature.
+ *
+ * @extends module:core/plugin~Plugin
+ */
+export default class TableStyleUI extends Plugin {
+	/**
+	 * @inheritDoc
+	 */
+	init() {
+		this._setupUI();
+	}
+
+	_setupUI() {
+		const editor = this.editor;
+		const model = editor.model;
+		const document = model.document;
+		const selection = document.selection;
+
+		const componentFactory = editor.ui.componentFactory;
+
+		componentFactory.add( 'borderWidth', locale => {
+			const button = new ButtonView( locale );
+
+			button.set( {
+				label: 'Border width',
+				icon: false,
+				tooltip: true,
+				withText: true
+			} );
+
+			button.on( 'execute', () => {
+				const firstPosition = selection.getFirstPosition();
+
+				const tableCell = findAncestor( 'tableCell', firstPosition );
+
+				const border = tableCell.getAttribute( 'border' );
+
+				let currentWidth;
+
+				if ( border ) {
+					const borderWidth = ( border && border.width ) || {};
+
+					// Unify width to one value. If different values are set default to top (or right, etc).
+					currentWidth = borderWidth.top || borderWidth.right || borderWidth.bottom || borderWidth.left;
+				}
+
+				// eslint-disable-next-line no-undef,no-alert
+				const newWidth = prompt( 'Set border width:', currentWidth || '' );
+
+				const parts = /^([0-9]*[.]?[0-9]*)([a-z]{2,4})?/.exec( newWidth );
+				const unit = parts[ 2 ];
+
+				const borderWidthToSet = parts[ 1 ] + ( unit || 'px' );
+
+				// TODO: Command, setting new value is dumb on `border` object.
+				editor.model.change( writer => {
+					writer.setAttribute( 'borderWidth', {
+						top: borderWidthToSet,
+						right: borderWidthToSet,
+						bottom: borderWidthToSet,
+						left: borderWidthToSet
+					}, tableCell );
+				} );
+			} );
+
+			return button;
+		} );
+
+		componentFactory.add( 'borderColor', locale => {
+			const button = new ButtonView( locale );
+
+			button.set( {
+				label: 'Border color',
+				icon: false,
+				tooltip: true,
+				withText: true
+			} );
+
+			button.on( 'execute', () => {
+				const firstPosition = selection.getFirstPosition();
+
+				const tableCell = findAncestor( 'tableCell', firstPosition );
+
+				const border = tableCell.getAttribute( 'border' );
+
+				let currentColor;
+
+				if ( border ) {
+					const borderColor = ( border && border.color ) || {};
+
+					// Unify width to one value. If different values are set default to top (or right, etc).
+					currentColor = borderColor.top || borderColor.right || borderColor.bottom || borderColor.left;
+				}
+
+				// eslint-disable-next-line no-undef,no-alert
+				const newColor = prompt( 'Set new border color:', currentColor || '' );
+
+				// TODO: Command, setting new value is dumb on `border` object.
+				editor.model.change( writer => {
+					writer.setAttribute( 'borderColor', {
+						top: newColor,
+						right: newColor,
+						bottom: newColor,
+						left: newColor
+					}, tableCell );
+				} );
+			} );
+
+			return button;
+		} );
+
+		componentFactory.add( 'borderStyle', locale => {
+			const button = new ButtonView( locale );
+
+			button.set( {
+				label: 'Border style',
+				icon: false,
+				tooltip: true,
+				withText: true
+			} );
+
+			button.on( 'execute', () => {
+				const firstPosition = selection.getFirstPosition();
+
+				const tableCell = findAncestor( 'tableCell', firstPosition );
+
+				const border = tableCell.getAttribute( 'border' );
+
+				let currentStyle;
+
+				if ( border ) {
+					const borderStyle = ( border && border.style ) || {};
+
+					// Unify width to one value. If different values are set default to top (or right, etc).
+					currentStyle = borderStyle.top || borderStyle.right || borderStyle.bottom || borderStyle.left;
+				}
+
+				// eslint-disable-next-line no-undef,no-alert
+				const newStyle = prompt( 'Set new border style:', currentStyle || '' );
+
+				// TODO: Command, setting new value is dumb on `border` object.
+				editor.model.change( writer => {
+					writer.setAttribute( 'borderStyle', {
+						top: newStyle,
+						right: newStyle,
+						bottom: newStyle,
+						left: newStyle
+					}, tableCell );
+				} );
+			} );
+
+			return button;
+		} );
+
+		componentFactory.add( 'backgroundColor', locale => {
+			const button = new ButtonView( locale );
+
+			button.set( {
+				label: 'Background color',
+				icon: false,
+				tooltip: true,
+				withText: true
+			} );
+
+			button.on( 'execute', () => {
+				const firstPosition = selection.getFirstPosition();
+
+				const tableCell = findAncestor( 'tableCell', firstPosition );
+
+				const backgroundColor = tableCell.getAttribute( 'background-color' );
+
+				// eslint-disable-next-line no-undef,no-alert
+				const newColor = prompt( 'Set new background color:', backgroundColor || '' );
+
+				editor.model.change( writer => {
+					writer.setAttribute( 'background-color', newColor, tableCell );
+				} );
+			} );
+
+			return button;
+		} );
+
+		componentFactory.add( 'padding', locale => {
+			const button = new ButtonView( locale );
+
+			button.set( {
+				label: 'Cell padding',
+				icon: false,
+				tooltip: true,
+				withText: true
+			} );
+
+			button.on( 'execute', () => {
+				const firstPosition = selection.getFirstPosition();
+
+				const tableCell = findAncestor( 'tableCell', firstPosition );
+
+				const padding = tableCell.getAttribute( 'padding' );
+
+				let currentPadding;
+
+				if ( padding ) {
+					// Unify width to one value. If different values are set default to top (or right, etc).
+					currentPadding = padding.top || padding.right || padding.bottom || padding.left;
+				}
+
+				// eslint-disable-next-line no-undef,no-alert
+				const newPadding = prompt( 'Set new padding:', currentPadding || '' );
+
+				editor.model.change( writer => {
+					writer.setAttribute( 'padding', newPadding, tableCell );
+				} );
+			} );
+
+			return button;
+		} );
+	}
+}

+ 57 - 0
packages/ckeditor5-table/tests/converters/tablestyles.js

@@ -0,0 +1,57 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import Widget from '@ckeditor/ckeditor5-widget/src/widget';
+import TableEditing from '../../src/tableediting';
+import TableStyleEditing from '../../src/tablestyleediting';
+
+describe( 'Table styles conversion', () => {
+	let editor, model;
+
+	beforeEach( () => {
+		return VirtualTestEditor
+			.create( {
+				plugins: [ TableEditing, TableStyleEditing, Paragraph, Widget ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+
+				// Since this part of test tests only view->model conversion editing pipeline is not necessary
+				// so defining model->view converters won't be necessary.
+				editor.editing.destroy();
+			} );
+	} );
+
+	describe( 'upcast', () => {
+		describe( 'table cell', () => {
+			it( 'should parser border shorthand', () => {
+				editor.setData( '<table><tr><td style="border:1px solid blue">foo</td></tr></table>' );
+
+				const tableCell = model.document.getRoot().getNodeByPath( [ 0, 0, 0 ] );
+
+				assertTRBLAttribute( tableCell, 'borderColor', 'blue' );
+				assertTRBLAttribute( tableCell, 'borderStyle', 'solid' );
+				assertTRBLAttribute( tableCell, 'borderWidth', '1px' );
+			} );
+		} );
+	} );
+
+	/**
+	 * Assertion helper for top-right-bottom-left attribute object.
+	 *
+	 * @param {module:engine/model/node~Node} tableCell
+	 * @param {String} key Attribute key
+	 * @param {String} top Top value
+	 * @param {String} [right=top] Right value - defaults to top if not provided.
+	 * @param {String} [bottom=top] Bottom value - defaults to top (right value must be defined).
+	 * @param {String} [left=right] Left value - defaults to right (bottom and right values must be defined).
+	 */
+	function assertTRBLAttribute( tableCell, key, top, right = top, bottom = top, left = right ) {
+		expect( tableCell.getAttribute( key ) ).to.deep.equal( { top, right, bottom, left } );
+	}
+} );

+ 3 - 25
packages/ckeditor5-table/tests/converters/upcasttable.js

@@ -9,8 +9,8 @@ import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import ImageEditing from '@ckeditor/ckeditor5-image/src/image/imageediting';
 import Widget from '@ckeditor/ckeditor5-widget/src/widget';
 
-import { defaultConversion, defaultSchema, formatTable, modelTable } from '../_utils/utils';
-import { assertEqualMarkup } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
+import { formatTable, modelTable } from '../_utils/utils';
+import TableEditing from '../../src/tableediting';
 
 describe( 'upcastTable()', () => {
 	let editor, model;
@@ -18,16 +18,12 @@ describe( 'upcastTable()', () => {
 	beforeEach( () => {
 		return VirtualTestEditor
 			.create( {
-				plugins: [ Paragraph, ImageEditing, Widget ]
+				plugins: [ TableEditing, Paragraph, ImageEditing, Widget ]
 			} )
 			.then( newEditor => {
 				editor = newEditor;
 				model = editor.model;
 
-				defaultSchema( model.schema, false );
-
-				defaultConversion( editor.conversion, true );
-
 				// Since this part of test tests only view->model conversion editing pipeline is not necessary
 				// so defining model->view converters won't be necessary.
 				editor.editing.destroy();
@@ -561,22 +557,4 @@ describe( 'upcastTable()', () => {
 			);
 		} );
 	} );
-
-	describe( 'styles', () => {
-		describe( 'table cell borders', () => {
-			it( 'should pass', () => {
-				editor.setData( '<table><tr><td style="border:1px solid blue">foo</td></tr></table>' );
-
-				assertEqualMarkup( getModelData( model, { withoutSelection: true } ),
-					'<table>' +
-						'<tableRow>' +
-							'<tableCell border="1px solid blue">' +
-								'<paragraph>foo</paragraph>' +
-							'</tableCell>' +
-						'</tableRow>' +
-					'</table>'
-				);
-			} );
-		} );
-	} );
 } );