|
|
@@ -82,7 +82,7 @@ describe.only( 'Image resizer', () => {
|
|
|
describe( 'standard image', () => {
|
|
|
let widget;
|
|
|
|
|
|
- beforeEach( async () => {
|
|
|
+ beforeEach( async function() {
|
|
|
await editor.setData( `<p>foo</p><figure><img src="${ imageFixture }"></figure>` );
|
|
|
|
|
|
widget = viewDocument.getRoot().getChild( 1 );
|
|
|
@@ -91,42 +91,62 @@ describe.only( 'Image resizer', () => {
|
|
|
preventDefault: sinon.spy()
|
|
|
};
|
|
|
|
|
|
+ this.widget = widget;
|
|
|
+
|
|
|
viewDocument.fire( 'mousedown', domEventDataMock );
|
|
|
} );
|
|
|
|
|
|
it( 'shrinks correctly with left-bottom handler', generateResizeTest( {
|
|
|
expectedWidth: 80,
|
|
|
- pointerOffset: { x: 10, y: -10 },
|
|
|
+ pointerOffset: {
|
|
|
+ x: 10,
|
|
|
+ y: -10
|
|
|
+ },
|
|
|
resizerPosition: 'bottom-left'
|
|
|
} ) );
|
|
|
|
|
|
it( 'shrinks correctly with right-bottom handler', generateResizeTest( {
|
|
|
expectedWidth: 80,
|
|
|
- pointerOffset: { x: -10, y: -10 },
|
|
|
+ pointerOffset: {
|
|
|
+ x: -10,
|
|
|
+ y: -10
|
|
|
+ },
|
|
|
resizerPosition: 'bottom-right'
|
|
|
} ) );
|
|
|
|
|
|
it( 'enlarges correctly with right-bottom handler, x axis only', generateResizeTest( {
|
|
|
expectedWidth: 110,
|
|
|
- pointerOffset: { x: 10, y: 0 },
|
|
|
+ pointerOffset: {
|
|
|
+ x: 10,
|
|
|
+ y: 0
|
|
|
+ },
|
|
|
resizerPosition: 'bottom-right'
|
|
|
} ) );
|
|
|
|
|
|
it( 'enlarges correctly with right-bottom handler, y axis only', generateResizeTest( {
|
|
|
expectedWidth: 120,
|
|
|
- pointerOffset: { x: 0, y: 10 },
|
|
|
+ pointerOffset: {
|
|
|
+ x: 0,
|
|
|
+ y: 10
|
|
|
+ },
|
|
|
resizerPosition: 'bottom-right'
|
|
|
} ) );
|
|
|
|
|
|
it( 'enlarges correctly with left-bottom handler, x axis only', generateResizeTest( {
|
|
|
expectedWidth: 110,
|
|
|
- pointerOffset: { x: -10, y: 0 },
|
|
|
+ pointerOffset: {
|
|
|
+ x: -10,
|
|
|
+ y: 0
|
|
|
+ },
|
|
|
resizerPosition: 'bottom-left'
|
|
|
} ) );
|
|
|
|
|
|
it( 'enlarges correctly with left-bottom handler, y axis only', generateResizeTest( {
|
|
|
expectedWidth: 120,
|
|
|
- pointerOffset: { x: 0, y: 10 },
|
|
|
+ pointerOffset: {
|
|
|
+ x: 0,
|
|
|
+ y: 10
|
|
|
+ },
|
|
|
resizerPosition: 'bottom-left'
|
|
|
} ) );
|
|
|
|
|
|
@@ -134,87 +154,45 @@ describe.only( 'Image resizer', () => {
|
|
|
|
|
|
it( 'enlarges correctly with left-top handler', generateResizeTest( {
|
|
|
expectedWidth: 120,
|
|
|
- pointerOffset: { x: -10, y: -10 },
|
|
|
+ pointerOffset: {
|
|
|
+ x: -10,
|
|
|
+ y: -10
|
|
|
+ },
|
|
|
resizerPosition: 'top-left'
|
|
|
} ) );
|
|
|
|
|
|
it( 'enlarges correctly with left-top handler, y axis only', generateResizeTest( {
|
|
|
expectedWidth: 120,
|
|
|
- pointerOffset: { x: 0, y: -10 },
|
|
|
+ pointerOffset: {
|
|
|
+ x: 0,
|
|
|
+ y: -10
|
|
|
+ },
|
|
|
resizerPosition: 'top-left'
|
|
|
} ) );
|
|
|
|
|
|
it( 'enlarges correctly with right-top handler', generateResizeTest( {
|
|
|
expectedWidth: 120,
|
|
|
- pointerOffset: { x: 10, y: -10 },
|
|
|
+ pointerOffset: {
|
|
|
+ x: 10,
|
|
|
+ y: -10
|
|
|
+ },
|
|
|
resizerPosition: 'top-right'
|
|
|
} ) );
|
|
|
|
|
|
- it( 'enlarges correctly with left-right handler, y axis only', generateResizeTest( {
|
|
|
+ it( 'enlarges correctly with right-top handler, y axis only', generateResizeTest( {
|
|
|
expectedWidth: 120,
|
|
|
- pointerOffset: { x: 0, y: -10 },
|
|
|
+ pointerOffset: {
|
|
|
+ x: 0,
|
|
|
+ y: -10
|
|
|
+ },
|
|
|
resizerPosition: 'top-right'
|
|
|
} ) );
|
|
|
-
|
|
|
- function generateResizeTest( options ) {
|
|
|
- // options.resizerPosition - top-left / top-right / bottom-right / bottom-left
|
|
|
- // options.pointerOffset - object - pointer offset relative to the dragged corner. Negative values are perfectly fine.
|
|
|
- // e.g. { x: 10, y: -5 }
|
|
|
- // options.expectedWidth
|
|
|
- // Returns a test case that puts
|
|
|
- return () => {
|
|
|
- const domResizeWrapper = view.domConverter.mapViewToDom( widget.getChild( 1 ) );
|
|
|
- const domBottomLeftResizer = domResizeWrapper.querySelector( `.ck-widget__resizer-${ options.resizerPosition }` );
|
|
|
- const domImage = view.domConverter.mapViewToDom( widget ).querySelector( 'img' );
|
|
|
- const imageTopLeftPosition = getElementPosition( domImage );
|
|
|
- const resizerPositionParts = options.resizerPosition.split( '-' );
|
|
|
-
|
|
|
- const initialPointerPosition = {
|
|
|
- pageX: imageTopLeftPosition.x,
|
|
|
- pageY: imageTopLeftPosition.y
|
|
|
- };
|
|
|
-
|
|
|
- if ( resizerPositionParts.includes( 'right' ) ) {
|
|
|
- initialPointerPosition.pageX += FIXTURE_WIDTH;
|
|
|
- }
|
|
|
-
|
|
|
- if ( resizerPositionParts.includes( 'bottom' ) ) {
|
|
|
- initialPointerPosition.pageY += FIXTURE_HEIGHT;
|
|
|
- }
|
|
|
-
|
|
|
- const finishPointerPosition = Object.assign( {}, initialPointerPosition );
|
|
|
-
|
|
|
- finishPointerPosition.pageX += options.pointerOffset.x || 0;
|
|
|
- finishPointerPosition.pageY += options.pointerOffset.y || 0;
|
|
|
-
|
|
|
- fireMouseEvent( domBottomLeftResizer, 'mousedown', initialPointerPosition );
|
|
|
- fireMouseEvent( domBottomLeftResizer, 'mousemove', initialPointerPosition );
|
|
|
-
|
|
|
- // We need to wait as mousemove events are throttled.
|
|
|
- return wait( 30 )
|
|
|
- .then( () => {
|
|
|
- fireMouseEvent( domBottomLeftResizer, 'mousemove', finishPointerPosition );
|
|
|
-
|
|
|
- expect( domImage.width ).to.be.closeTo( options.expectedWidth, 1 );
|
|
|
-
|
|
|
- fireMouseEvent( domBottomLeftResizer, 'mouseup', finishPointerPosition );
|
|
|
-
|
|
|
- expect( getData( editor.model, {
|
|
|
- withoutSelection: true
|
|
|
- } ) ).to.match( /<paragraph>foo<\/paragraph><image src=".+?" width="(\d+)"><\/image>/ );
|
|
|
-
|
|
|
- const modelItem = editor.model.document.getRoot().getChild( 1 );
|
|
|
-
|
|
|
- expect( modelItem.getAttribute( 'width' ) ).to.be.closeTo( options.expectedWidth, 1, 'Model check' );
|
|
|
- } );
|
|
|
- };
|
|
|
- }
|
|
|
} );
|
|
|
|
|
|
describe( 'side image', () => {
|
|
|
let widget;
|
|
|
|
|
|
- beforeEach( async () => {
|
|
|
+ beforeEach( async function() {
|
|
|
await editor.setData( `<p>foo</p><figure class="image image-style-side"><img src="${ imageFixture }"></figure>` );
|
|
|
|
|
|
widget = viewDocument.getRoot().getChild( 1 );
|
|
|
@@ -223,66 +201,104 @@ describe.only( 'Image resizer', () => {
|
|
|
preventDefault: sinon.spy()
|
|
|
};
|
|
|
|
|
|
+ this.widget = widget;
|
|
|
+
|
|
|
viewDocument.fire( 'mousedown', domEventDataMock );
|
|
|
} );
|
|
|
|
|
|
- it( 'shrinks correctly with left-bottom handler', () => {
|
|
|
- const expectedWidth = 80;
|
|
|
-
|
|
|
- const domResizeWrapper = view.domConverter.mapViewToDom( widget.getChild( 1 ) );
|
|
|
- const domBottomLeftResizer = domResizeWrapper.querySelector( '.ck-widget__resizer-bottom-left' );
|
|
|
- const domImage = view.domConverter.mapViewToDom( widget ).querySelector( 'img' );
|
|
|
- const imageTopLeftPosition = getElementPosition( domImage );
|
|
|
-
|
|
|
- const initialPointerPosition = {
|
|
|
- pageX: imageTopLeftPosition.x,
|
|
|
- pageY: imageTopLeftPosition.y + FIXTURE_HEIGHT
|
|
|
- };
|
|
|
-
|
|
|
- const finishPointerPosition = {
|
|
|
- pageX: imageTopLeftPosition.x + 20,
|
|
|
- pageY: imageTopLeftPosition.y + FIXTURE_HEIGHT - 10
|
|
|
- };
|
|
|
+ it( 'shrinks correctly with left-bottom handler', generateResizeTest( {
|
|
|
+ isSideImage: true,
|
|
|
+ expectedWidth: 80,
|
|
|
+ pointerOffset: {
|
|
|
+ x: 20,
|
|
|
+ y: -10
|
|
|
+ },
|
|
|
+ resizerPosition: 'bottom-left'
|
|
|
+ } ) );
|
|
|
|
|
|
- fireMouseEvent( domBottomLeftResizer, 'mousedown', initialPointerPosition );
|
|
|
- fireMouseEvent( domBottomLeftResizer, 'mousemove', initialPointerPosition );
|
|
|
+ it( 'shrinks correctly with right-bottom handler', generateResizeTest( {
|
|
|
+ isSideImage: true,
|
|
|
+ expectedWidth: 80,
|
|
|
+ pointerOffset: {
|
|
|
+ x: -20,
|
|
|
+ y: -10
|
|
|
+ },
|
|
|
+ resizerPosition: 'bottom-right'
|
|
|
+ } ) );
|
|
|
|
|
|
- // We need to wait as mousemove events are throttled.
|
|
|
- return wait( 30 )
|
|
|
- .then( () => {
|
|
|
- fireMouseEvent( domBottomLeftResizer, 'mousemove', finishPointerPosition );
|
|
|
+ it( 'enlarges correctly with left-bottom handler', generateResizeTest( {
|
|
|
+ isSideImage: true,
|
|
|
+ expectedWidth: 120,
|
|
|
+ pointerOffset: {
|
|
|
+ x: -10,
|
|
|
+ y: 10
|
|
|
+ },
|
|
|
+ resizerPosition: 'bottom-left'
|
|
|
+ } ) );
|
|
|
+ } );
|
|
|
|
|
|
- expect( domImage.width ).to.be.closeTo( expectedWidth, 1, 'View width check' );
|
|
|
+ function isVisible( element ) {
|
|
|
+ // Checks if the DOM element is visible to the end user.
|
|
|
+ return element.offsetParent !== null;
|
|
|
+ }
|
|
|
|
|
|
- fireMouseEvent( domBottomLeftResizer, 'mouseup', finishPointerPosition );
|
|
|
+ function fireMouseEvent( target, eventType, eventData ) {
|
|
|
+ // Using initMouseEvent instead of MouseEvent constructor, as MouseEvent constructor doesn't support passing pageX
|
|
|
+ // and pageY. See https://stackoverflow.com/questions/45843458/setting-click-events-pagex-and-pagey-always-reverts-to-0
|
|
|
+ // However there's still a problem, that events created with `initMouseEvent` have **floored** pageX, pageY numbers.
|
|
|
+ const event = document.createEvent( 'MouseEvent' );
|
|
|
+ event.initMouseEvent( eventType, true, true, window, null, 0, 0, eventData.pageX, eventData.pageY, false, false, false, false,
|
|
|
+ MOUSE_BUTTON_MAIN, null );
|
|
|
|
|
|
- expect( getData( editor.model, {
|
|
|
- withoutSelection: true
|
|
|
- } ) ).to.match( /<paragraph>foo<\/paragraph><image imageStyle="side" src=".+?" width="(\d+)"><\/image>/ );
|
|
|
+ target.dispatchEvent( event );
|
|
|
+ }
|
|
|
|
|
|
- const modelItem = editor.model.document.getRoot().getChild( 1 );
|
|
|
+ function getElementPosition( element ) {
|
|
|
+ // Returns top left corner point.
|
|
|
+ const viewportPosition = element.getBoundingClientRect();
|
|
|
|
|
|
- expect( modelItem.getAttribute( 'width' ) ).to.be.closeTo( expectedWidth, 1, 'Model check' );
|
|
|
- } );
|
|
|
- } );
|
|
|
+ return {
|
|
|
+ x: viewportPosition.left + window.scrollX,
|
|
|
+ y: viewportPosition.top + window.scrollY
|
|
|
+ };
|
|
|
+ }
|
|
|
|
|
|
- it( 'shrinks correctly with right-bottom handler', () => {
|
|
|
- const expectedWidth = 80;
|
|
|
+ function wait( delay ) {
|
|
|
+ return new Promise( resolve => window.setTimeout( () => resolve(), delay ) );
|
|
|
+ }
|
|
|
|
|
|
+ function generateResizeTest( options ) {
|
|
|
+ // options.resizerPosition - top-left / top-right / bottom-right / bottom-left
|
|
|
+ // options.pointerOffset - object - pointer offset relative to the dragged corner. Negative values are perfectly fine.
|
|
|
+ // e.g. { x: 10, y: -5 }
|
|
|
+ // options.expectedWidth
|
|
|
+ // [options.isSideImage=false]
|
|
|
+ // Returns a test case that puts
|
|
|
+ return function() {
|
|
|
+ const widget = this.widget;
|
|
|
const domResizeWrapper = view.domConverter.mapViewToDom( widget.getChild( 1 ) );
|
|
|
- const domBottomLeftResizer = domResizeWrapper.querySelector( '.ck-widget__resizer-bottom-left' );
|
|
|
+ const domBottomLeftResizer = domResizeWrapper.querySelector( `.ck-widget__resizer-${ options.resizerPosition }` );
|
|
|
const domImage = view.domConverter.mapViewToDom( widget ).querySelector( 'img' );
|
|
|
const imageTopLeftPosition = getElementPosition( domImage );
|
|
|
+ const resizerPositionParts = options.resizerPosition.split( '-' );
|
|
|
|
|
|
const initialPointerPosition = {
|
|
|
- pageX: imageTopLeftPosition.x + FIXTURE_WIDTH,
|
|
|
- pageY: imageTopLeftPosition.y + FIXTURE_HEIGHT
|
|
|
+ pageX: imageTopLeftPosition.x,
|
|
|
+ pageY: imageTopLeftPosition.y
|
|
|
};
|
|
|
|
|
|
- const finishPointerPosition = {
|
|
|
- pageX: imageTopLeftPosition.x + FIXTURE_WIDTH - 20,
|
|
|
- pageY: imageTopLeftPosition.y + FIXTURE_HEIGHT - 10
|
|
|
- };
|
|
|
+ if ( resizerPositionParts.includes( 'right' ) ) {
|
|
|
+ initialPointerPosition.pageX += FIXTURE_WIDTH;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( resizerPositionParts.includes( 'bottom' ) ) {
|
|
|
+ initialPointerPosition.pageY += FIXTURE_HEIGHT;
|
|
|
+ }
|
|
|
+
|
|
|
+ const finishPointerPosition = Object.assign( {}, initialPointerPosition );
|
|
|
+
|
|
|
+ finishPointerPosition.pageX += options.pointerOffset.x || 0;
|
|
|
+ finishPointerPosition.pageY += options.pointerOffset.y || 0;
|
|
|
|
|
|
fireMouseEvent( domBottomLeftResizer, 'mousedown', initialPointerPosition );
|
|
|
fireMouseEvent( domBottomLeftResizer, 'mousemove', initialPointerPosition );
|
|
|
@@ -292,48 +308,21 @@ describe.only( 'Image resizer', () => {
|
|
|
.then( () => {
|
|
|
fireMouseEvent( domBottomLeftResizer, 'mousemove', finishPointerPosition );
|
|
|
|
|
|
- expect( domImage.width ).to.be.closeTo( expectedWidth, 1 );
|
|
|
+ expect( domImage.width ).to.be.closeTo( options.expectedWidth, 1 );
|
|
|
|
|
|
fireMouseEvent( domBottomLeftResizer, 'mouseup', finishPointerPosition );
|
|
|
|
|
|
+ const modelDataRegExp = !options.isSideImage ? /<paragraph>foo<\/paragraph><image src=".+?" width="(\d+)"><\/image>/ :
|
|
|
+ /<paragraph>foo<\/paragraph><image imageStyle="side" src=".+?" width="(\d+)"><\/image>/;
|
|
|
+
|
|
|
expect( getData( editor.model, {
|
|
|
withoutSelection: true
|
|
|
- } ) ).to.match( /<paragraph>foo<\/paragraph><image imageStyle="side" src=".+?" width="(\d+)"><\/image>/ );
|
|
|
+ } ) ).to.match( modelDataRegExp );
|
|
|
|
|
|
const modelItem = editor.model.document.getRoot().getChild( 1 );
|
|
|
|
|
|
- expect( modelItem.getAttribute( 'width' ) ).to.be.closeTo( expectedWidth, 1, 'Model check' );
|
|
|
+ expect( modelItem.getAttribute( 'width' ) ).to.be.closeTo( options.expectedWidth, 1, 'Model check' );
|
|
|
} );
|
|
|
- } );
|
|
|
- } );
|
|
|
-
|
|
|
- function isVisible( element ) {
|
|
|
- // Checks if the DOM element is visible to the end user.
|
|
|
- return element.offsetParent !== null;
|
|
|
- }
|
|
|
-
|
|
|
- function fireMouseEvent( target, eventType, eventData ) {
|
|
|
- // Using initMouseEvent instead of MouseEvent constructor, as MouseEvent constructor doesn't support passing pageX
|
|
|
- // and pageY. See https://stackoverflow.com/questions/45843458/setting-click-events-pagex-and-pagey-always-reverts-to-0
|
|
|
- // However there's still a problem, that events created with `initMouseEvent` have **floored** pageX, pageY numbers.
|
|
|
- const event = document.createEvent( 'MouseEvent' );
|
|
|
- event.initMouseEvent( eventType, true, true, window, null, 0, 0, eventData.pageX, eventData.pageY, false, false, false, false,
|
|
|
- MOUSE_BUTTON_MAIN, null );
|
|
|
-
|
|
|
- target.dispatchEvent( event );
|
|
|
- }
|
|
|
-
|
|
|
- function getElementPosition( element ) {
|
|
|
- // Returns top left corner point.
|
|
|
- const viewportPosition = element.getBoundingClientRect();
|
|
|
-
|
|
|
- return {
|
|
|
- x: viewportPosition.left + window.scrollX,
|
|
|
- y: viewportPosition.top + window.scrollY
|
|
|
};
|
|
|
}
|
|
|
-
|
|
|
- function wait( delay ) {
|
|
|
- return new Promise( resolve => window.setTimeout( () => resolve(), delay ) );
|
|
|
- }
|
|
|
} );
|