From 679c5fa73f8708df882e0002a24246df71d34970 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotrek=20Koszuli=C5=84ski?= <pkoszulinski@gmail.com>
Date: Sun, 11 Mar 2018 18:22:14 +0100
Subject: [PATCH] Cleaned up the image.styles configuration by getting rid of
 the 'imageStyle:' prefix from style names.

---
 docs/_snippets/features/image-style-custom.js |  6 ++---
 docs/features/image.md                        | 19 ++++++++-----
 src/imagestyle.js                             | 11 ++++----
 src/imagestyle/imagestylecommand.js           |  7 +++--
 src/imagestyle/imagestyleediting.js           | 27 ++++++++++++-------
 src/imagestyle/utils.js                       |  9 +++----
 tests/imagestyle/imagestyleediting.js         | 12 ++++-----
 tests/imagestyle/utils.js                     | 18 ++++++++-----
 8 files changed, 66 insertions(+), 43 deletions(-)

diff --git a/docs/_snippets/features/image-style-custom.js b/docs/_snippets/features/image-style-custom.js
index 9b1137f3..3c35c620 100644
--- a/docs/_snippets/features/image-style-custom.js
+++ b/docs/_snippets/features/image-style-custom.js
@@ -12,13 +12,13 @@ ClassicEditor
 		image: {
 			styles: [
 				// This option is equal to a situation where no style is applied.
-				'imageStyle:full',
+				'full',
 
 				// This represents an image aligned to left.
-				'imageStyle:alignLeft',
+				'alignLeft',
 
 				// This represents an image aligned to right.
-				'imageStyle:alignRight'
+				'alignRight'
 			],
 
 			toolbar: [ 'imageTextAlternative', '|', 'imageStyle:alignLeft', 'imageStyle:full', 'imageStyle:alignRight' ]
diff --git a/docs/features/image.md b/docs/features/image.md
index b4918e83..2d8ad846 100644
--- a/docs/features/image.md
+++ b/docs/features/image.md
@@ -122,13 +122,13 @@ ClassicEditor
 
 			styles: [
 				// This option is equal to a situation where no style is applied.
-				'imageStyle:full',
+				'full',
 
 				// This represents an image aligned to left.
-				'imageStyle:alignLeft',
+				'alignLeft',
 
 				// This represents an image aligned to right.
-				'imageStyle:alignRight'
+				'alignRight'
 			]
 		}
 	} )
@@ -136,7 +136,7 @@ ClassicEditor
 	.catch( ... );
 ```
 
-In the code sample above we used predefined image styles – `'imageStyle:full'`, `'imageStyle:alignLeft'` and `'imageStyle:alignRight'`. The latter two apply, respectively, `.image-style-align-left` and  `.image-style-align-right` classes to the `<figure>` element.
+In the code sample above we used predefined image styles – `'full'`, `'alignLeft'` and `'alignRight'`. The latter two apply, respectively, `.image-style-align-left` and  `.image-style-align-right` classes to the `<figure>` element.
 
 See the result below:
 
@@ -162,7 +162,9 @@ you can also define your own styles or modify the existing ones.
 	Reusing (or modifying) predefined styles has this advantage that CKEditor 5 will use its official translations for the defined button titles.
 </info-box>
 
-TODO (example)...
+You can find advanced examples in the {@link module:image/image~ImageConfig#styles `image.styles`} configuration option's documentation.
+
+TODO (live example)...
 
 ## Image upload
 
@@ -211,7 +213,12 @@ The {@link module:image/image~Image} plugin registers:
 
 The {@link module:image/imagestyle~ImageStyle} plugin registers:
 
-* A command for each defined style (based on the {@link module:image/image~ImageConfig#styles `image.styles`} configuration option) &mdash; e.g. `'imageStyle:full'` and `'imageStyle:side'`,
+* The `'imageStyle'` command that accepts value based on the {@link module:image/image~ImageConfig#styles `image.styles`} configuration option (e.g. `'full'` and `'side'`):
+
+	```js
+	editor.execute( 'imageStyle', { value: 'side' } );
+	```
+
 * A button for each defined style &mdash; e.g. `'imageStyle:full'` and `'imageStyle:side'`.
 
 ## Contribute
diff --git a/src/imagestyle.js b/src/imagestyle.js
index 1d6a1554..f5236763 100644
--- a/src/imagestyle.js
+++ b/src/imagestyle.js
@@ -37,12 +37,11 @@ export default class ImageStyle extends Plugin {
 
 /**
  * Available image styles.
- * The option is used by the {@link module:image/imagestyle/imagestyleediting~ImageStyleEditing} feature.
  *
  * The default value is:
  *
  *		const imageConfig = {
- *			styles: [ 'imageStyle:full', 'imageStyle:side' ]
+ *			styles: [ 'full', 'side' ]
  *		};
  *
  * which configures two default styles:
@@ -96,11 +95,11 @@ export default class ImageStyle extends Plugin {
  * The feature creates commands based on defined styles, so you can change the style of a selected image by executing
  * the following command:
  *
- *		editor.execute( 'imageStyle:side' );
+ *		editor.execute( 'imageStyle' { value: 'side' } );
  *
- * The features creates also buttons which execute the commands, so assuming that you use the
- * default image styles setting you can {@link module:image/image~ImageConfig#toolbar configure the image toolbar}
- * to contain these options:
+ * The feature creates also buttons which execute the command. So, assuming that you use the
+ * default image styles setting, you can {@link module:image/image~ImageConfig#toolbar configure the image toolbar}
+ * (or any other toolbar) to contain these options:
  *
  *		const imageConfig = {
  *			toolbar: [ 'imageStyle:full', 'imageStyle:side' ]
diff --git a/src/imagestyle/imagestylecommand.js b/src/imagestyle/imagestylecommand.js
index 92f39131..6a2f7c3e 100644
--- a/src/imagestyle/imagestylecommand.js
+++ b/src/imagestyle/imagestylecommand.js
@@ -26,7 +26,7 @@ export default class ImageStyleCommand extends Command {
 		super( editor );
 
 		/**
-		 * Cached name of a default style if present. If there is no default style it defaults to false.
+		 * Cached name of the default style if present. If there is no default style it defaults to `false`.
 		 *
 		 * @type {Boolean|String}
 		 * @private
@@ -71,8 +71,11 @@ export default class ImageStyleCommand extends Command {
 	/**
 	 * Executes the command.
 	 *
+	 *		editor.execute( 'imageStyle', { value: 'side' } );
+	 *
 	 * @param {Object} options
-	 * @param {String} options.value
+	 * @param {String} options.value The name of the style (based on the
+	 * {@link module:image/image~ImageConfig#styles `image.styles`} configuration option).
 	 * @fires execute
 	 */
 	execute( options = {} ) {
diff --git a/src/imagestyle/imagestyleediting.js b/src/imagestyle/imagestyleediting.js
index bf8713fc..5e8399fb 100644
--- a/src/imagestyle/imagestyleediting.js
+++ b/src/imagestyle/imagestyleediting.js
@@ -44,7 +44,7 @@ export default class ImageStyleEditing extends Plugin {
 		const editing = editor.editing;
 
 		// Define default configuration.
-		editor.config.define( 'image.styles', [ 'imageStyle:full', 'imageStyle:side' ] );
+		editor.config.define( 'image.styles', [ 'full', 'side' ] );
 
 		// Get configuration.
 		const styles = normalizeImageStyles( editor.config.get( 'image.styles' ) );
@@ -69,25 +69,34 @@ export default class ImageStyleEditing extends Plugin {
 /**
  * Image style format descriptor.
  *
- *		import fullWidthIcon from 'path/to/icon.svg`;
+ *		import fullSizeIcon from 'path/to/icon.svg';
  *
  *		const imageStyleFormat = {
- *			name: 'fullSizeImage',
- *			icon: fullWidthIcon,
+ *			name: 'fullSize',
+ *			icon: fullSizeIcon,
  *			title: 'Full size image',
  *			className: 'image-full-size'
  *		}
  *
  * @typedef {Object} module:image/imagestyle/imagestyleediting~ImageStyleFormat
+ *
  * @property {String} name The unique name of the style. It will be used to:
- * * register the {@link module:core/command~Command command} which will apply this style,
- * * store the style's button in the editor {@link module:ui/componentfactory~ComponentFactory},
- * * store the style in the `imageStyle` model attribute.
+ *
+ * * store the chosen style in the model by setting the `imageStyle` attribute of the `<image>` element,
+ * * as a value of the {@link module:image/imagestyle/imagestylecommand~ImageStyleCommand#execute `imageStyle` command},
+ * * when registering button for each of the styles (`'imageStyle:{name}'`) in the
+ * {@link module:ui/componentfactory~ComponentFactory UI components factory} (this functionality is provided by the
+ * {@link module:image/imagestyle/imagestyleui~ImageStyleUI} plugin),
+ *
  * @property {Boolean} [isDefault] When set, the style will be used as the default one.
  * A default style does not apply any CSS class to the view element.
+ *
  * @property {String} icon One of the following to be used when creating the style's button:
- *  * An SVG icon source (as an XML string),
- *  * One of {@link module:image/imagestyle/utils~defaultIcons} to use a default icon provided by the plugin.
+ *
+ * * An SVG icon source (as an XML string),
+ * * One of {@link module:image/imagestyle/utils~defaultIcons} to use a default icon provided by the plugin.
+ *
  * @property {String} title The style's title.
+ *
  * @property {String} className The CSS class used to represent the style in view.
  */
diff --git a/src/imagestyle/utils.js b/src/imagestyle/utils.js
index 04392bd9..f80de3b3 100644
--- a/src/imagestyle/utils.js
+++ b/src/imagestyle/utils.js
@@ -108,18 +108,18 @@ export function normalizeImageStyles( configuredStyles = [] ) {
 function _normalizeStyle( style ) {
 	// Just the name of the style has been passed.
 	if ( typeof style == 'string' ) {
-		// If it's one of the defaults, just use it.
-		// Clone the style to avoid overriding defaults.
-		const styleName = style.indexOf( 'imageStyle:' ) === 0 ? style.substr( 11 ) : style;
+		const styleName = style;
 
+		// If it's one of the defaults, just use it.
 		if ( defaultStyles[ styleName ] ) {
+			// Clone the style to avoid overriding defaults.
 			style = Object.assign( {}, defaultStyles[ styleName ] );
 		}
 		// If it's just a name but none of the defaults, warn because probably it's a mistake.
 		else {
 			log.warn(
 				'image-style-not-found: There is no such image style of given name.',
-				{ name: style }
+				{ name: styleName }
 			);
 
 			// Normalize the style anyway to prevent errors.
@@ -128,7 +128,6 @@ function _normalizeStyle( style ) {
 			};
 		}
 	}
-
 	// If an object style has been passed and if the name matches one of the defaults,
 	// extend it with defaults – the user wants to customize a default style.
 	// Note: Don't override the user–defined style object, clone it instead.
diff --git a/tests/imagestyle/imagestyleediting.js b/tests/imagestyle/imagestyleediting.js
index ae8a95fc..58996b61 100644
--- a/tests/imagestyle/imagestyleediting.js
+++ b/tests/imagestyle/imagestyleediting.js
@@ -71,7 +71,7 @@ describe( 'ImageStyleEditing', () => {
 				.then( newEditor => {
 					editor = newEditor;
 
-					expect( newEditor.config.get( 'image.styles' ) ).to.deep.equal( [ 'imageStyle:full', 'imageStyle:side' ] );
+					expect( newEditor.config.get( 'image.styles' ) ).to.deep.equal( [ 'full', 'side' ] );
 				} );
 		} );
 
@@ -264,7 +264,7 @@ describe( 'ImageStyleEditing', () => {
 				.then( newEditor => {
 					editor = newEditor;
 
-					expect( newEditor.config.get( 'image.styles' ) ).to.deep.equal( [ 'imageStyle:full', 'imageStyle:side' ] );
+					expect( newEditor.config.get( 'image.styles' ) ).to.deep.equal( [ 'full', 'side' ] );
 				} );
 		} );
 
@@ -274,14 +274,14 @@ describe( 'ImageStyleEditing', () => {
 					plugins: [ ImageStyleEditing ],
 					image: {
 						styles: [
-							'imageStyle:side'
+							'side'
 						]
 					}
 				} )
 				.then( newEditor => {
 					editor = newEditor;
 
-					expect( newEditor.config.get( 'image.styles' ) ).to.deep.equal( [ 'imageStyle:side' ] );
+					expect( newEditor.config.get( 'image.styles' ) ).to.deep.equal( [ 'side' ] );
 				} );
 		} );
 
@@ -291,14 +291,14 @@ describe( 'ImageStyleEditing', () => {
 					plugins: [ ImageStyleEditing ],
 					image: {
 						styles: [
-							{ name: 'imageStyle:side' }
+							{ name: 'side' }
 						]
 					}
 				} )
 				.then( newEditor => {
 					editor = newEditor;
 
-					expect( newEditor.config.get( 'image.styles' ) ).to.deep.equal( [ { name: 'imageStyle:side' } ] );
+					expect( newEditor.config.get( 'image.styles' ) ).to.deep.equal( [ { name: 'side' } ] );
 				} );
 		} );
 	} );
diff --git a/tests/imagestyle/utils.js b/tests/imagestyle/utils.js
index 9cf45b88..3da975d7 100644
--- a/tests/imagestyle/utils.js
+++ b/tests/imagestyle/utils.js
@@ -18,7 +18,13 @@ testUtils.createSinonSandbox();
 describe( 'ImageStyle utils', () => {
 	let imageStyles;
 
-	describe( 'imageStyles()', () => {
+	describe( 'normalizeImageStyles()', () => {
+		// Since this function is all about normalizing the config object, make sure it doesn't throw
+		// if the config is empty (which may happen e.g. if only ImageStyleUI was loaded).
+		it( 'does not throw when given undefined', () => {
+			expect( normalizeImageStyles() ).to.deep.equal( [] );
+		} );
+
 		describe( 'object format', () => {
 			beforeEach( () => {
 				imageStyles = normalizeImageStyles( [
@@ -57,35 +63,35 @@ describe( 'ImageStyle utils', () => {
 
 		describe( 'string format', () => {
 			it( 'should use one of default styles if #name matches', () => {
-				expect( normalizeImageStyles( [ 'imageStyle:full' ] ) ).to.deep.equal( [ {
+				expect( normalizeImageStyles( [ 'full' ] ) ).to.deep.equal( [ {
 					name: 'full',
 					title: 'Full size image',
 					icon: fullWidthIcon,
 					isDefault: true
 				} ] );
 
-				expect( normalizeImageStyles( [ 'imageStyle:side' ] ) ).to.deep.equal( [ {
+				expect( normalizeImageStyles( [ 'side' ] ) ).to.deep.equal( [ {
 					name: 'side',
 					title: 'Side image',
 					icon: rightIcon,
 					className: 'image-style-side'
 				} ] );
 
-				expect( normalizeImageStyles( [ 'imageStyle:alignLeft' ] ) ).to.deep.equal( [ {
+				expect( normalizeImageStyles( [ 'alignLeft' ] ) ).to.deep.equal( [ {
 					name: 'alignLeft',
 					title: 'Left aligned image',
 					icon: leftIcon,
 					className: 'image-style-align-left'
 				} ] );
 
-				expect( normalizeImageStyles( [ 'imageStyle:alignCenter' ] ) ).to.deep.equal( [ {
+				expect( normalizeImageStyles( [ 'alignCenter' ] ) ).to.deep.equal( [ {
 					name: 'alignCenter',
 					title: 'Centered image',
 					icon: centerIcon,
 					className: 'image-style-align-center'
 				} ] );
 
-				expect( normalizeImageStyles( [ 'imageStyle:alignRight' ] ) ).to.deep.equal( [ {
+				expect( normalizeImageStyles( [ 'alignRight' ] ) ).to.deep.equal( [ {
 					name: 'alignRight',
 					title: 'Right aligned image',
 					icon: rightIcon,