Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I/7579: Allow disabling image resize handles #7654

Merged
merged 33 commits into from
Jul 23, 2020
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c184cd3
Separate standalone plugin — ImageResizeHandles.
panr Jul 17, 2020
fff2016
Disable resize handles if user sets `image.disableResizeHandles: true…
panr Jul 17, 2020
145b6a9
Update ImageResizeEditing plugin.
panr Jul 17, 2020
59878b1
Update ImageResize plugin.
panr Jul 17, 2020
6c2a01c
Update WidgetResize plugin to stop executing infinitely `redrawFocuse…
panr Jul 17, 2020
24532ce
Prevent from redrawing the resize handles when plugin is disabled.
panr Jul 17, 2020
af796b4
Merge branch 'master' into i/7579
panr Jul 17, 2020
f8b7e12
Update manual test for ImageResizeUI.
panr Jul 17, 2020
4fcdefe
Fix unit tests.
panr Jul 20, 2020
7095181
Merge branch 'master' into i/7579
panr Jul 20, 2020
35911ae
Fix `imageresizehandles` module path.
panr Jul 20, 2020
26fcbdd
Add `disableResizeHandles` API docs.
panr Jul 20, 2020
b9e8e28
Update image feature docs.
panr Jul 20, 2020
88bf240
Fix unit tests for "ImageResizeHandles".
panr Jul 20, 2020
a91b95d
Merge branch 'master' into i/7579
panr Jul 20, 2020
80a7964
Update unit tests for widget.
panr Jul 21, 2020
22c2c64
Merge branch 'master' into i/7579
panr Jul 21, 2020
a87b931
Change plugin name from `ImageResizeUI` to `ImageResizeButtons`.
panr Jul 22, 2020
0c97df0
Get rid of the fps comment.
panr Jul 22, 2020
c3bf5af
Update snippets.
panr Jul 22, 2020
f91a67d
Update manual test for the resize plugin.
panr Jul 22, 2020
7d4e5dd
Remove config option for disabling the image resize handles.
panr Jul 22, 2020
7f1470e
Update docs.
panr Jul 22, 2020
4a87aeb
Update image resize buttons manual test to match description.
jodator Jul 23, 2020
1217cfa
Update image resize requires test description.
jodator Jul 23, 2020
3c3c6d5
Update image resize feature guide.
jodator Jul 23, 2020
6ddb8fa
Refactor ImageResizeHandles unit test.
panr Jul 23, 2020
7f4732f
Add missing await.
jodator Jul 23, 2020
c40b3ad
Refactor ImageResizeEditing unit test.
panr Jul 23, 2020
28bad66
Fix feature doc wording.
panr Jul 23, 2020
97eabec
Merge branch 'master' into i/7579
panr Jul 23, 2020
5a702bd
Get rid of the redundant fixes for Resizer.
panr Jul 23, 2020
0e9ccc0
Bring back the old throttling for redrawing handles.
panr Jul 23, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div id="snippet-image-resizeui-dropdown">
<div id="snippet-image-resize-buttons-dropdown">
<h3>Resize me using the dropdown!</h3>

<figure class="image">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config.js';

ClassicEditor
.create( document.querySelector( '#snippet-image-resizeui-dropdown' ), {
.create( document.querySelector( '#snippet-image-resize-buttons-dropdown' ), {
removePlugins: [ 'LinkImage' ],
toolbar: {
viewportTopOffset: window.getViewportTopOffsetConfig()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div id="snippet-image-resizeui">
<div id="snippet-image-resize-buttons">
<h3>Resize me using image toolbar buttons!</h3>

<figure class="image">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config.js';

ClassicEditor
.create( document.querySelector( '#snippet-image-resizeui' ), {
.create( document.querySelector( '#snippet-image-resize-buttons' ), {
removePlugins: [ 'LinkImage' ],
toolbar: {
viewportTopOffset: window.getViewportTopOffsetConfig()
Expand Down
84 changes: 81 additions & 3 deletions packages/ckeditor5-image/docs/features/image.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,49 @@ The plugin also gives you an ability to change the size of the image through the

### Methods to resize images

The editor offers three ways to resize images. One of them (resize handles) is
The editor offers different ways to resize images either by using resize handles or by using dedicated UI components.

#### Using handles

In this case, the user is able to resize images via dragging square handles displayed in each corner of the image. Once [image resizing was enabled](#enabling-image-resizing), this option does not require any additional configuration.

{@snippet features/image-resize}

You can configure the editor for resizing images by handles in two different ways:

- By installing the {@link module:image/imageresize~ImageResize} plugin, which contains **all** needed features (`ImageResizeEditing`, `ImageResizeHandles`, `ImageResizeButtons`).

```js
import Image from '@ckeditor/ckeditor5-image/src/image';
import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize';

ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Image, ImageResize, ... ],
...
} )
.then( ... )
.catch( ... );
```

- Or by installing the combination of {@link module:image/imageresize/imageresizeediting~ImageResizeEditing} and {@link module:image/imageresize/imageresizehandles~ImageResizeHandles} plugins.

```js
import Image from '@ckeditor/ckeditor5-image/src/image';
import ImageResizeEditing from '@ckeditor/ckeditor5-image/src/imageresize/imageresizeediting';
import ImageResizeHandles from '@ckeditor/ckeditor5-image/src/imageresize/imageresizehandles';

ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Image, ImageResizeEditing, ImageResizeHandles, ... ],
...
} )
.then( ... )
.catch( ... );
```

Both ways enable resize handles by default.

#### Using the dropdown

In this case, the user is able to choose from a set of predefined options. These options can be displayed in the image toolbar in form of a dropdown.
Expand Down Expand Up @@ -263,7 +298,7 @@ const imageConfiguration = {
}
```

{@snippet features/image-resizeuidropdown}
{@snippet features/image-resize-buttons-dropdown}

#### Using standalone buttons

Expand Down Expand Up @@ -299,7 +334,50 @@ const imageConfiguration = {
}
```

{@snippet features/image-resizeui}
{@snippet features/image-resize-buttons}

### Disabling image resize handles

If for some reason you want to configure the editor where you can resize the images only by the buttons, you can do it by omitting {@link module:image/imageresize/imageresizehandles~ImageResizeHandles `ImageResizeHandles`} plugin. This means that your plugins setup should look like this: `plugins: [ 'ImageResizeEditing', 'ImageResizeButtons', ... ]` instead of `plugins: [ 'ImageResize', ... ]`. It will only enable resizing image feature by the chosen UI ([dropdown](#using-the-dropdown) or [standalone buttons](#using-standalone-buttons)) in the image toolbar.

```js
import Image from '@ckeditor/ckeditor5-image/src/image';
import ImageToolbar from '@ckeditor/ckeditor5-image/src/imagetoolbar';
import ImageResizeEditing from '@ckeditor/ckeditor5-image/src/imageresize/imageresizeedititing';
import ImageResizeButtons from '@ckeditor/ckeditor5-image/src/imageresize/imageresizebuttons';

ClassicEditor
.create( document.querySelector( '#editor' ), {
plugins: [ Image, ImageResizeEditing, ImageResizeButtons, ImageToolbar, ... ],
image: {
resizeOptions: [
{
name: 'imageResize:original',
value: null,
icon: 'original'
},
{
name: 'imageResize:50',
value: '50',
icon: 'medium'
},
{
name: 'imageResize:75',
value: '75',
icon: 'large'
}
],
toolbar: [
// ...,
'imageResize:50',
'imageResize:75',
'imageResize:original',
]
}
} )
.then( ... )
.catch( ... );
```

### Enabling image resizing

Expand Down
11 changes: 6 additions & 5 deletions packages/ckeditor5-image/src/imageresize.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
*/

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import ImageResizeUI from './imageresize/imageresizeui';
import ImageResizeButtons from './imageresize/imageresizebuttons';
import ImageResizeEditing from './imageresize/imageresizeediting';
import ImageResizeHandles from './imageresize/imageresizehandles';

import '../theme/imageresize.css';

Expand All @@ -25,7 +26,7 @@ export default class ImageResize extends Plugin {
* @inheritDoc
*/
static get requires() {
return [ ImageResizeEditing, ImageResizeUI ];
return [ ImageResizeEditing, ImageResizeHandles, ImageResizeButtons ];
}

/**
Expand Down Expand Up @@ -127,10 +128,10 @@ export default class ImageResize extends Plugin {
*
* **Resizing images using individual buttons**
*
* If you want to have separate buttons for {@link module:image/imageresize/imageresizeui~ImageResizeOption each option},
* If you want to have separate buttons for {@link module:image/imageresize/imageresizebuttons~ImageResizeOption each option},
* pass their names to the {@link module:image/image~ImageConfig#toolbar `config.image.toolbar`} instead. Please keep in mind
* that this time **you must define the additional
* {@link module:image/imageresize/imageresizeui~ImageResizeOption `icon` property}**:
* {@link module:image/imageresize/imageresizebuttons~ImageResizeOption `icon` property}**:
*
* ClassicEditor
* .create( editorElement, {
Expand Down Expand Up @@ -196,5 +197,5 @@ export default class ImageResize extends Plugin {
* .then( ... )
* .catch( ... );
*
* @member {Array.<module:image/imageresize/imageresizeui~ImageResizeOption>} module:image/image~ImageConfig#resizeOptions
* @member {Array.<module:image/imageresize/imageresizebuttons~ImageResizeOption>} module:image/image~ImageConfig#resizeOptions
*/
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

/**
* @module image/imageresize/imageresizeui
* @module image/imageresize/imageresizebuttons
*/

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
Expand All @@ -31,13 +31,13 @@ const RESIZE_ICONS = {
};

/**
* The `ImageResizeUI` plugin.
* The `ImageResizeButtons` plugin.
*
* It adds a possibility to resize images using the toolbar dropdown or individual buttons, depending on the plugin configuration.
*
* @extends module:core/plugin~Plugin
*/
export default class ImageResizeUI extends Plugin {
export default class ImageResizeButtons extends Plugin {
/**
* @inheritDoc
*/
Expand All @@ -49,7 +49,7 @@ export default class ImageResizeUI extends Plugin {
* @inheritDoc
*/
static get pluginName() {
return 'ImageResizeUI';
return 'ImageResizeButtons';
}

/**
Expand Down Expand Up @@ -94,7 +94,7 @@ export default class ImageResizeUI extends Plugin {
* A helper function that creates a standalone button component for the plugin.
*
* @private
* @param {module:image/imageresize/imageresizeui~ImageResizeOption} resizeOption A model of resize option.
* @param {module:image/imageresize/imageresizebuttons~ImageResizeOption} resizeOption A model of resize option.
*/
_registerImageResizeButton( option ) {
const editor = this.editor;
Expand All @@ -112,13 +112,13 @@ export default class ImageResizeUI extends Plugin {
* buttons, a valid `icon` token must be set for each option.
*
* See all valid options described in the
* {@link module:image/imageresize/imageresizeui~ImageResizeOption plugin configuration}.
* {@link module:image/imageresize/imageresizebuttons~ImageResizeOption plugin configuration}.
*
* @error imageresizeui-missing-icon
* @param {module:image/imageresize/imageresizeui~ImageResizeOption} option Invalid image resize option.
* @error imageresizebuttons-missing-icon
* @param {module:image/imageresize/imageresizebuttons~ImageResizeOption} option Invalid image resize option.
*/
throw new CKEditorError(
'imageresizeui-missing-icon: ' +
'imageresizebuttons-missing-icon: ' +
'The resize option "' + name + '" misses the "icon" property ' +
'or the property value doesn\'t match any of available icons.',
editor,
Expand Down Expand Up @@ -151,7 +151,7 @@ export default class ImageResizeUI extends Plugin {
* the editor configuration.
*
* @private
* @param {Array.<module:image/imageresize/imageresizeui~ImageResizeOption>} options An array of configured options.
* @param {Array.<module:image/imageresize/imageresizebuttons~ImageResizeOption>} options An array of configured options.
*/
_registerImageResizeDropdown( options ) {
const editor = this.editor;
Expand Down Expand Up @@ -202,7 +202,7 @@ export default class ImageResizeUI extends Plugin {
* A helper function for creating an option label value string.
*
* @private
* @param {module:image/imageresize/imageresizeui~ImageResizeOption} option A resize option object.
* @param {module:image/imageresize/imageresizebuttons~ImageResizeOption} option A resize option object.
* @param {Boolean} [forTooltip] An optional flag for creating a tooltip label.
* @returns {String} A user-defined label, a label combined from the value and resize unit or the default label
* for reset options (`Original`).
Expand Down Expand Up @@ -231,7 +231,7 @@ export default class ImageResizeUI extends Plugin {
* A helper function that parses resize options and returns list item definitions ready for use in a dropdown.
*
* @private
* @param {Array.<module:image/imageresize/imageresizeui~ImageResizeOption>} options The resize options.
* @param {Array.<module:image/imageresize/imageresizebuttons~ImageResizeOption>} options The resize options.
* @param {module:image/imageresize/imageresizecommand~ImageResizeCommand} command A resize image command.
* @returns {Iterable.<module:ui/dropdown/utils~ListDropdownItemDefinition>} Dropdown item definitions.
*/
Expand Down Expand Up @@ -274,7 +274,7 @@ function getIsOnButtonCallback( value ) {
/**
* An image resize option used in the {@link module:image/image~ImageConfig#resizeOptions image resize configuration}.
*
* @typedef {Object} module:image/imageresize/imageresizeui~ImageResizeOption
* @typedef {Object} module:image/imageresize/imageresizebuttons~ImageResizeOption
* @property {String} name A name of the UI component that changes the image size.
* * If you configure the feature using individual resize buttons, you can refer to this name in the
* {@link module:image/image~ImageConfig#toolbar image toolbar configuration}.
Expand Down
58 changes: 5 additions & 53 deletions packages/ckeditor5-image/src/imageresize/imageresizeediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,17 @@
*/

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import WidgetResize from '@ckeditor/ckeditor5-widget/src/widgetresize';
import ImageResizeCommand from './imageresizecommand';

/**
* The image resize feature.
* The image resize editing feature.
*
* It adds a possibility to resize each image using handles or manually by
* {@link module:image/imageresize/imageresizeui~ImageResizeUI} buttons.
* {@link module:image/imageresize/imageresizebuttons~ImageResizeButtons} buttons.
*
* @extends module:core/plugin~Plugin
*/
export default class ImageResizeEditing extends Plugin {
/**
* @inheritDoc
*/
static get requires() {
return [ WidgetResize ];
}

/**
* @inheritDoc
*/
Expand All @@ -45,55 +37,15 @@ export default class ImageResizeEditing extends Plugin {
this._registerConverters();

editor.commands.add( 'imageResize', command );

editor.editing.downcastDispatcher.on( 'insert:image', ( evt, data, conversionApi ) => {
const widget = conversionApi.mapper.toViewElement( data.item );

const resizer = editor.plugins
.get( WidgetResize )
.attachTo( {
unit: editor.config.get( 'image.resizeUnit' ) || '%',

modelElement: data.item,
viewElement: widget,
editor,

getHandleHost( domWidgetElement ) {
return domWidgetElement.querySelector( 'img' );
},
getResizeHost( domWidgetElement ) {
return domWidgetElement;
},
// TODO consider other positions.
isCentered() {
const imageStyle = data.item.getAttribute( 'imageStyle' );

return !imageStyle || imageStyle == 'full' || imageStyle == 'alignCenter';
},

onCommit( newValue ) {
editor.execute( 'imageResize', { width: newValue } );
}
} );

resizer.on( 'updateSize', () => {
if ( !widget.hasClass( 'image_resized' ) ) {
editor.editing.view.change( writer => {
writer.addClass( 'image_resized', widget );
} );
}
} );

resizer.bind( 'isEnabled' ).to( command );
}, { priority: 'low' } );
}

/**
* @private
*/
_registerSchema() {
this.editor.model.schema.extend( 'image', {
allowAttributes: 'width'
this.editor.model.schema.extend( 'image', { allowAttributes: 'width' } );
this.editor.model.schema.setAttributeProperties( 'width', {
panr marked this conversation as resolved.
Show resolved Hide resolved
isFormatting: true
} );
}

Expand Down
Loading