Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge pull request #183 from ckeditor/t/ckeditor5-alignment/16
Browse files Browse the repository at this point in the history
Other: Updated naming of UI components & commands.

BREAKING CHANGE: Renamed the `'imageUpload'` command to `'uploadImage'`.
BREAKING CHANGE: The `'imageStyleFull'`, `'imageStyleSide'`, `'imageStyleAlignLeft'`, `'imageStyleAlignRight'` and `'imageStyleAlignCenter'` commands are no longer available. They were replaced by the `'imageStyle'` command that accepts name of an image style as a value.
BREAKING CHANGE: The `'imageStyleFull'`, `'imageStyleSide'`, `'imageStyleAlignLeft'`, `'imageStyleAlignRight'` and `'imageStyleAlignCenter'` UI components are no longer available. Replaced by `'imageStyle:full'`, `'imageStyle:side'`, `'imageStyle:alignLeft'`, `'imageStyle:alignRight'` and `'imageStyle:alignCenter'`.
BREAKING CHANGE: The `ImageStyleCommand#value` property is no longer a boolean only. Now it represents a name of an image style of the currently selected image element.
BREAKING CHANGE: The `ImageStyleCommand` constructor's second parameter is now an array of supported image styles.
  • Loading branch information
Reinmar authored Mar 11, 2018
2 parents 8b60192 + 679c5fa commit 2e7fbee
Show file tree
Hide file tree
Showing 23 changed files with 229 additions and 187 deletions.
8 changes: 4 additions & 4 deletions docs/_snippets/features/image-style-custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ ClassicEditor
image: {
styles: [
// This option is equal to a situation where no style is applied.
'imageStyleFull',
'full',

// This represents an image aligned to left.
'imageStyleAlignLeft',
'alignLeft',

// This represents an image aligned to right.
'imageStyleAlignRight'
'alignRight'
],

toolbar: [ 'imageTextAlternative', '|', 'imageStyleAlignLeft', 'imageStyleFull', 'imageStyleAlignRight' ]
toolbar: [ 'imageTextAlternative', '|', 'imageStyle:alignLeft', 'imageStyle:full', 'imageStyle:alignRight' ]
},
toolbar: {
viewportTopOffset: 60
Expand Down
41 changes: 24 additions & 17 deletions docs/features/image.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ The [`@ckeditor/ckeditor5-image`](https://www.npmjs.com/package/@ckeditor/ckedit
* {@link module:image/imagetoolbar~ImageToolbar} adds the image feature's contextual toolbar,
* {@link module:image/imagecaption~ImageCaption} adds support for captions,
* {@link module:image/imagestyle~ImageStyle} adds support for image styles,
* {@link module:image/imageupload~ImageUpload} adds support for uploading dropped or pasted images (note: it is currently located in the [`@ckeditor/ckeditor5-upload`](https://www.npmjs.com/package/@ckeditor/ckeditor5-upload) package but will be moved to the `@ckeditor/ckeditor5-image` package).
* {@link module:image/imageupload~ImageUpload} adds support for uploading dropped or pasted images (see: {@link features/image-upload Image upload}).

<info-box info>
The first four features listed above (so all except the upload support) are enabled by default in all builds.
All features listed above are enabled by default in all builds.
</info-box>

## Base image support
Expand Down Expand Up @@ -100,7 +100,7 @@ A side image:
<info-box>
The actual styling of the images is the developer's job. The editor comes with some default styles, but they will only be applied to images inside the editor. The developer needs to style them on the target pages.

Here you can find the source of the default styles applied by the editor: [`ckeditor5-image/theme/theme.scss`](https://github.com/ckeditor/ckeditor5-image/blob/master/theme/theme.scss).
Here you can find the source of the default styles applied by the editor: [`ckeditor5-image/theme/imagestyle.css`](https://github.com/ckeditor/ckeditor5-image/blob/master/theme/imagestyle.css).
</info-box>

Below you can see a demo of the editor with the image styles feature enabled. The default configuration is used. You can change the styles of images through the image's contextual toolbar.
Expand All @@ -118,25 +118,25 @@ ClassicEditor
.create( document.querySelector( '#editor' ), {
image: {
// You need to configure the image toolbar too, so it uses the new style buttons.
toolbar: [ 'imageTextAlternative', '|', 'imageStyleAlignLeft', 'imageStyleFull', 'imageStyleAlignRight' ],
toolbar: [ 'imageTextAlternative', '|', 'imageStyle:alignLeft', 'imageStyle:full', 'imageStyle:alignRight' ],

styles: [
// This option is equal to a situation where no style is applied.
'imageStyleFull',
'full',

// This represents an image aligned to left.
'imageStyleAlignLeft',
'alignLeft',

// This represents an image aligned to right.
'imageStyleAlignRight'
'alignRight'
]
}
} )
.then( ... )
.catch( ... );
```

In the code sample above we used predefined image styles – `'imageStyleFull'`, `'imageStyleAlignLeft'` and `'imageStyleAlignRight'`. 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:

Expand All @@ -150,19 +150,21 @@ See the result below:

Besides using the {@link module:image/imagestyle/utils~defaultStyles 5 predefined styles}:

* `'imageStyleFull'`,
* `'imageStyleSide'`,
* `'imageStyleAlignLeft'`,
* `'imageStyleAlignCenter'`,
* `'imageStyleAlignRight'`
* `'full'`,
* `'side'`,
* `'alignLeft'`,
* `'alignCenter'`,
* `'alignRight'`

you can also define your own styles or modify the existing ones.

<info-box>
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

Expand Down Expand Up @@ -194,7 +196,7 @@ ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Image, ImageToolbar, ImageCaption, ImageStyle ],
image: {
toolbar: [ 'imageTextAlternative', '|', 'imageStyleFull', 'imageStyleSide' ]
toolbar: [ 'imageTextAlternative', '|', 'imageStyle:full', 'imageStyle:side' ]
}
} )
.then( ... )
Expand All @@ -211,8 +213,13 @@ 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. `'imageStyleFull'` and `'imageStyleSide'`,
* A button for each defined style &mdash; e.g. `'imageStyleFull'` and `'imageStyleSide'`.
* 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

Expand Down
17 changes: 8 additions & 9 deletions src/imagestyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: [ 'imageStyleFull', 'imageStyleSide' ]
* styles: [ 'full', 'side' ]
* };
*
* which configures two default styles:
Expand All @@ -65,10 +64,10 @@ export default class ImageStyle extends Plugin {
* styles: [
* // This will only customize the icon of the "full" style.
* // Note: 'right' is one of default icons provided by the feature.
* { name: 'imageStyleFull', icon: 'right' },
* { name: 'full', icon: 'right' },
*
* // This will customize the icon, title and CSS class of the default "side" style.
* { name: 'imageStyleSide', icon: customIcon, title: 'My side style', class: 'custom-side-image' }
* { name: 'side', icon: customIcon, title: 'My side style', class: 'custom-side-image' }
* ]
* };
*
Expand Down Expand Up @@ -96,14 +95,14 @@ 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( 'imageStyleSide' );
* 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: [ 'imageStyleFull', 'imageStyleSide' ]
* toolbar: [ 'imageStyle:full', 'imageStyle:side' ]
* };
*
* @member {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>} module:image/image~ImageConfig#styles
Expand Down
47 changes: 31 additions & 16 deletions src/imagestyle/imagestylecommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,34 @@ export default class ImageStyleCommand extends Command {
* Creates an instance of the image style command. Each command instance is handling one style.
*
* @param {module:core/editor/editor~Editor} editor The editor instance.
* @param {module:image/imagestyle/imagestyleediting~ImageStyleFormat} style A style to be applied by this command.
* @param {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>} styles A styles that this command supports.
*/
constructor( editor, style ) {
constructor( editor, styles ) {
super( editor );

/**
* The value of the command &mdash; `true` if a style handled by the command is applied on a currently selected image,
* `false` otherwise.
* Cached name of the default style if present. If there is no default style it defaults to `false`.
*
* @readonly
* @observable
* @member {Boolean} #value
* @type {Boolean|String}
* @private
*/
this._defaultStyle = false;

/**
* A style handled by this command.
*
* @readonly
* @member {module:image/imagestyle/imagestyleediting~ImageStyleFormat} #style
* @member {Array.<module:image/imagestyle/imagestyleediting~ImageStyleFormat>} #styles
*/
this.style = style;
this.styles = styles.reduce( ( styles, style ) => {
styles[ style.name ] = style;

if ( style.isDefault ) {
this._defaultStyle = style.name;
}

return styles;
}, {} );
}

/**
Expand All @@ -53,20 +60,28 @@ export default class ImageStyleCommand extends Command {

if ( !element ) {
this.value = false;
} else if ( this.style.isDefault ) {
this.value = !element.hasAttribute( 'imageStyle' );
} else if ( element.hasAttribute( 'imageStyle' ) ) {
const attributeValue = element.getAttribute( 'imageStyle' );
this.value = this.styles[ attributeValue ] ? attributeValue : false;
} else {
this.value = ( element.getAttribute( 'imageStyle' ) == this.style.name );
this.value = this._defaultStyle;
}
}

/**
* Executes the command.
*
* editor.execute( 'imageStyle', { value: 'side' } );
*
* @param {Object} options
* @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() {
if ( this.value ) {
execute( options = {} ) {
const styleName = options.value;

if ( !this.styles[ styleName ] ) {
return;
}

Expand All @@ -76,10 +91,10 @@ export default class ImageStyleCommand extends Command {
model.change( writer => {
// Default style means that there is no `imageStyle` attribute in the model.
// https://github.com/ckeditor/ckeditor5-image/issues/147
if ( this.style.isDefault ) {
if ( this.styles[ styleName ].isDefault ) {
writer.removeAttribute( 'imageStyle', imageElement );
} else {
writer.setAttribute( 'imageStyle', this.style.name, imageElement );
writer.setAttribute( 'imageStyle', styleName, imageElement );
}
} );
}
Expand Down
33 changes: 20 additions & 13 deletions src/imagestyle/imagestyleediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default class ImageStyleEditing extends Plugin {
const editing = editor.editing;

// Define default configuration.
editor.config.define( 'image.styles', [ 'imageStyleFull', 'imageStyleSide' ] );
editor.config.define( 'image.styles', [ 'full', 'side' ] );

// Get configuration.
const styles = normalizeImageStyles( editor.config.get( 'image.styles' ) );
Expand All @@ -61,35 +61,42 @@ export default class ImageStyleEditing extends Plugin {
// Converter for figure element from view to model.
data.upcastDispatcher.on( 'element:figure', viewToModelStyleAttribute( styles ), { priority: 'low' } );

// Register separate command for each style.
for ( const style of styles ) {
editor.commands.add( style.name, new ImageStyleCommand( editor, style ) );
}
// Register imageStyle command.
editor.commands.add( 'imageStyle', new ImageStyleCommand( editor, styles ) );
}
}

/**
* 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.
*/
10 changes: 6 additions & 4 deletions src/imagestyle/imagestyleui.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ export default class ImageStyleUI extends Plugin {
_createButton( style ) {
const editor = this.editor;

editor.ui.componentFactory.add( style.name, locale => {
const command = editor.commands.get( style.name );
const componentName = `imageStyle:${ style.name }`;

editor.ui.componentFactory.add( componentName, locale => {
const command = editor.commands.get( 'imageStyle' );
const view = new ButtonView( locale );

view.set( {
Expand All @@ -80,9 +82,9 @@ export default class ImageStyleUI extends Plugin {
} );

view.bind( 'isEnabled' ).to( command, 'isEnabled' );
view.bind( 'isOn' ).to( command, 'value' );
view.bind( 'isOn' ).to( command, 'value', value => value === style.name );

this.listenTo( view, 'execute', () => editor.execute( style.name ) );
this.listenTo( view, 'execute', () => editor.execute( 'imageStyle', { value: style.name } ) );

return view;
} );
Expand Down
Loading

0 comments on commit 2e7fbee

Please sign in to comment.