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

Image resizer #94

Merged
merged 96 commits into from
Aug 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
9e6d7ce
Internal: Initial resizer API mocks.
mlewand Apr 29, 2019
d16d34b
Internal: Some basic logic to show up the resizers.
mlewand May 21, 2019
2a51e26
Added WidgetResizer plugin class.
mlewand Jun 26, 2019
df924cf
Internal: dirty version that just shows an overlay when resize handle…
mlewand Jun 27, 2019
d37af34
Internal: mocked very basic implementation for the ResizeContext.upda…
mlewand Jun 27, 2019
bdb110d
Internal: more precise resizing.
mlewand Jun 27, 2019
d7d17ef
Internal: mocked aligning the resize shadow with resize host width.
mlewand Jun 27, 2019
866de28
Internal: workaround to use render event to catch dom element that is…
mlewand Jun 28, 2019
c156ec4
Internal: next implementation of the resizer. This was required to ac…
mlewand Jun 28, 2019
8874fad
Internal: redraw the resizer's overlay once commit change has been re…
mlewand Jul 1, 2019
6d9a991
Internal: added img[height] entry to schema and a basic downcast conv…
mlewand Jul 1, 2019
da6528b
Internal: introduced img[height] upcast converter.
mlewand Jul 1, 2019
da3836c
Internal: enhanced CSS colors for the resized elements.
mlewand Jul 1, 2019
c9aa59a
Internal: added a support for resizing height using bottom handlers.
mlewand Jul 1, 2019
a989d0f
Internal: added extra render, otherwise handler would be mispositione…
mlewand Jul 1, 2019
b636ee6
Internal: now widget resizer accepts additional options. This will al…
mlewand Jul 1, 2019
d3b96bd
Internal: adjusted resizer CSS so that it doesn't block pointer event…
mlewand Jul 1, 2019
9751add
Internal: keep the resized object scale when using handlers.
mlewand Jul 5, 2019
97e1c8f
Internal: simplified resizing logic.
mlewand Jul 5, 2019
f68aeb1
Internal: made the resizing shadow follow the mouse cursor.
mlewand Jul 8, 2019
75cf6e4
Internal: removed unused context properties.
mlewand Jul 8, 2019
620d14c
Internal: introduced resized dimension information, also adjusted sty…
mlewand Jul 9, 2019
9e63118
Internal: adjusted resizing styles.
mlewand Jul 9, 2019
12ef207
Internal: make the sizer UI appear next to the dragged handler.
mlewand Jul 9, 2019
62f7d7f
Internal: fixed sizer alignment for bottom left corner.
mlewand Jul 9, 2019
45a1b8e
Internal: [WIP] delegating resizer strategy into a dedicated type.
mlewand Jul 10, 2019
2184992
Internal: refined resizing relative to the center point.
mlewand Jul 10, 2019
837288f
Internal: improved resizer visuals.
mlewand Jul 17, 2019
c9f3486
Internal: allow for providing a custom pixel ratio function.
mlewand Jul 17, 2019
769a0c4
Internal: added top-bound resizer.
mlewand Jul 18, 2019
43a1974
Internal: top-bound resizer now supports resizing focus host as well …
mlewand Jul 18, 2019
c515998
Internal: adjusted how aspect ratio is computed if no custom function…
mlewand Jul 19, 2019
728b351
Internal: exposed a observable method that allows you to implement a …
mlewand Jul 19, 2019
b446325
Internal: added a possibility to resize the image itself in resizerce…
mlewand Jul 22, 2019
b820a19
Internal: changed the default resizing strategy into center.
mlewand Jul 22, 2019
2430e23
Internal: changed the default resize type.
mlewand Jul 22, 2019
243e33f
Smaller resizer size and changed its position.
Jul 24, 2019
70df28b
Internal: Adjusted resize cursors.
mlewand Jul 25, 2019
26308f7
Internal: Use width inline style rather than height attribute.
mlewand Jul 25, 2019
670554d
Internal: Adjusted mouseover observer to trigger ~30 times per second.
mlewand Jul 25, 2019
a6a2305
Internal: Reduced resize handler outline thickness.
mlewand Jul 25, 2019
37e62e9
Improved resizer & tooltip styling.
Jul 25, 2019
a53b76f
Internal: Listening for events outside of the editable.
mlewand Jul 25, 2019
1520448
Internal: Added a possibility to specify whether resized object is ce…
mlewand Aug 2, 2019
350a249
Internal: Resizer wrapper will be sized based on element offset metrics.
mlewand Aug 5, 2019
8e605ca
Internal: Fixed an issue with resizer border after undoing.
mlewand Aug 6, 2019
92ecfa0
Internal: Fixed an issue where center-aligned image would not be prop…
mlewand Aug 7, 2019
bc4f934
Internal: Fixed a case where resize shadow would remain unaffected by…
mlewand Aug 7, 2019
3ed0812
Make sure resizer is visible only when the editor is focused.
mlewand Aug 8, 2019
fcd1c78
Internal: Further adjusted resizer focus selector.
mlewand Aug 9, 2019
af100d5
Internal: Minor code cleanup.
mlewand Aug 9, 2019
0e2903a
Internal: Simplified resizer's commit method.
mlewand Aug 9, 2019
2acf275
Internal: Removing leftovers after multiple resizing strategies.
mlewand Aug 12, 2019
5afaa59
Internal: Removed unused DOM observers.
mlewand Aug 12, 2019
a95ed36
Merge branch 'master' into t/ckeditor5-image/241
oleq Aug 12, 2019
a6d96c8
Internal: Removed unusued widget feature generic type.
mlewand Aug 12, 2019
29bbf4d
Docs: More resizer API docs.
mlewand Aug 12, 2019
deb43ab
Internal: Removed redundant code.
mlewand Aug 12, 2019
f5126e1
Internal: Fixed center resizing compensation. Also added some missing…
mlewand Aug 12, 2019
45416fe
Internal: Removed unused logic, simplified the code.
mlewand Aug 12, 2019
d06de01
Internal: Cleaned up some CSS.
mlewand Aug 12, 2019
d076a17
Internal: Moved most of methods from strategy to the context itself.
mlewand Aug 12, 2019
09c89d9
Internal: Merged ResizerTopBound class back into ResizeContext.
mlewand Aug 12, 2019
14d4dc6
Internal: Simplified UI building.
mlewand Aug 12, 2019
8001bc3
Internal: Use Rect type instead native DOM getBoundingClientRect.
mlewand Aug 12, 2019
7ca16fc
Internal: Cleanup docs and removed stray isActive variable.
mlewand Aug 12, 2019
0ab8a2f
Docs: Updated the docs.
mlewand Aug 12, 2019
4f4f444
Internal: Moved several properties to a protected scope.
mlewand Aug 12, 2019
6a29d70
Internal: Throttle mousemove/redraw events.
mlewand Aug 12, 2019
e0bb0da
Internal: WidgetResizer.apply will now return a created context. Also…
mlewand Aug 13, 2019
fdff936
Merge branch 'master' into t/ckeditor5-image/241
Reinmar Aug 13, 2019
05261ff
Cleanup, use px unit for width.
Reinmar Aug 13, 2019
c529432
Refactoring.
Reinmar Aug 13, 2019
0f09252
Refactoring.
Reinmar Aug 13, 2019
f360a43
Simplfied observers.
Reinmar Aug 13, 2019
45df167
Refactoring.
Reinmar Aug 13, 2019
11415d9
Intenral: Removed unused class.
mlewand Aug 13, 2019
fdb76ee
Internal: Extracted resizer state class.
mlewand Aug 14, 2019
293dfc7
Internal: Removed unused variables.
mlewand Aug 14, 2019
310661b
Move things around.
Reinmar Aug 14, 2019
c6d778f
Merge branch 'master' into t/ckeditor5-image/241
Reinmar Aug 14, 2019
b0d9081
Moar refactoring.
Reinmar Aug 14, 2019
bc97672
Removed the shadow thing concept.
Reinmar Aug 14, 2019
d5e67fc
Fixed classes naming.
Reinmar Aug 14, 2019
0fe6ebd
Naming.
Reinmar Aug 14, 2019
e4a62d8
Use RTL-proof character.
Reinmar Aug 14, 2019
97919bb
Improved naming.
Reinmar Aug 14, 2019
28971ce
Expose onCommit to the consumer.
Reinmar Aug 14, 2019
5a589f3
Round sizes.
Reinmar Aug 14, 2019
5f4e014
Introduced Resizer#isEnabled.
Reinmar Aug 16, 2019
197b0da
Internal: Added generic support for percent-based resizing.
mlewand Aug 16, 2019
51bbc5f
Added support for percents.
Reinmar Aug 16, 2019
5688291
Docs: Improved API docs.
mlewand Aug 19, 2019
9797970
Docs: Added more docs to the options.onCommit.
mlewand Aug 19, 2019
2e704e7
Docs: Removed aspect ratio resizer option.
mlewand Aug 19, 2019
1a31082
Internal: SizeUI property of the resizer has now become a protected m…
mlewand Aug 19, 2019
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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"@ckeditor/ckeditor5-core": "^12.2.1",
"@ckeditor/ckeditor5-engine": "^13.2.1",
"@ckeditor/ckeditor5-ui": "^13.0.2",
"@ckeditor/ckeditor5-utils": "^13.0.1"
"@ckeditor/ckeditor5-utils": "^13.0.1",
"lodash-es": "^4.17.10"
},
"devDependencies": {
"@ckeditor/ckeditor5-basic-styles": "^11.1.3",
Expand Down
162 changes: 162 additions & 0 deletions src/widgetresize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/**
* @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 widget/widgetresize
*/

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import Resizer from './widgetresize/resizer';
import DomEmitterMixin from '@ckeditor/ckeditor5-utils/src/dom/emittermixin';
import global from '@ckeditor/ckeditor5-utils/src/dom/global';
import { throttle } from 'lodash-es';

/**
* Widget resize feature plugin.
*
* Use the {@link module:widget/widgetresize~WidgetResize#attachTo} method to create a resizer for the specified widget.
*
* @extends module:core/plugin~Plugin
*/
export default class WidgetResize extends Plugin {
/**
* @inheritDoc
*/
static get pluginName() {
return 'WidgetResize';
}

init() {
this.resizers = [];
this.activeResizer = null;

const domDocument = global.window.document;
const THROTTLE_THRESHOLD = 16; // 16ms = ~60fps

this.editor.model.schema.setAttributeProperties( 'width', {
isFormatting: true
} );

this._observer = Object.create( DomEmitterMixin );

this._observer.listenTo( domDocument, 'mousedown', ( event, domEventData ) => {
if ( !Resizer.isResizeHandle( domEventData.target ) ) {
return;
}

const resizeHandle = domEventData.target;

this.activeResizer = this._getResizerByHandle( resizeHandle );

if ( this.activeResizer ) {
this.activeResizer.begin( resizeHandle );
}
} );

this._observer.listenTo( domDocument, 'mousemove', throttle( ( event, domEventData ) => {
if ( this.activeResizer ) {
this.activeResizer.updateSize( domEventData );
}
}, THROTTLE_THRESHOLD ) );

this._observer.listenTo( domDocument, 'mouseup', () => {
if ( this.activeResizer ) {
this.activeResizer.commit();

this.activeResizer = null;
}
} );

const redrawResizers = throttle( () => {
for ( const context of this.resizers ) {
context.redraw();
}
}, THROTTLE_THRESHOLD );

// Redrawing on any change of the UI of the editor (including content changes).
this.editor.ui.on( 'update', redrawResizers );

// Resizers need to be redrawn upon window resize, because new window might shrink resize host.
this._observer.listenTo( global.window, 'resize', redrawResizers );
}

destroy() {
this._observer.stopListening();
}

/**
* @param {module:widget/widgetresize~ResizerOptions} [options] Resizer options.
* @returns {module:widget/widgetresize/resizer~Resizer}
*/
attachTo( options ) {
const resizer = new Resizer( options );

resizer.attach();

this.editor.editing.view.once( 'render', () => resizer.redraw() );

this.resizers.push( resizer );

return resizer;
}

_getResizerByHandle( domResizeHandle ) {
for ( const resizer of this.resizers ) {
if ( resizer.containsHandle( domResizeHandle ) ) {
return resizer;
}
}
}
}

/**
* Interface describing a resizer. It allows to specify resizing host, custom logic for calculating aspect ratio etc.
*
* @interface ResizerOptions
*/

/**
* @member {module:engine/model/element~Element} module:widget/widgetresize~ResizerOptions#modelElement
*/

/**
* @member {module:engine/view/containerelement~ContainerElement} module:widget/widgetresize~ResizerOptions#viewElement
*/

/**
* @member {module:engine/view/downcastwriter~DowncastWriter} module:widget/widgetresize~ResizerOptions#downcastWriter
*/

/**
* A callback to be executed once resizing process is done.
*
* It receives a `Number` (`newValue`) as a parameter.
*
* For example, {@link module:image/imageresize~ImageResize} uses it to execute image resize command,
* which puts new value into the model.
*
* ```js
* {
* modelElement: data.item,
* viewElement: widget,
* downcastWriter: conversionApi.writer,
*
* onCommit( newValue ) {
* editor.execute( 'imageResize', { width: newValue } );
* }
* };
* ```
*
*
* @member {Function} module:widget/widgetresize~ResizerOptions#onCommit
*/

/**
* @member {Function} module:widget/widgetresize~ResizerOptions#getResizeHost
*/

/**
* @member {Function} module:widget/widgetresize~ResizerOptions#isCentered
*/
Loading