Skip to content

Commit

Permalink
Merge pull request #15092 from ckeditor/ck/15088-add-image-sizes-on-i…
Browse files Browse the repository at this point in the history
…mage-paste

Internal (image): Image `width` and `height` attributes should be added when pasting a copied image. Closes #15088.
  • Loading branch information
arkflpc authored Oct 2, 2023
2 parents 99f1516 + 8c553af commit 47accf1
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 4 deletions.
23 changes: 22 additions & 1 deletion packages/ckeditor5-image/src/image/imageblockediting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import { Plugin } from 'ckeditor5/src/core';
import { ClipboardPipeline, type ClipboardInputTransformationEvent } from 'ckeditor5/src/clipboard';
import { ClipboardPipeline, type ClipboardInputTransformationEvent, type ClipboardContentInsertionEvent } from 'ckeditor5/src/clipboard';
import { UpcastWriter, type ViewElement } from 'ckeditor5/src/engine';

import {
Expand Down Expand Up @@ -128,6 +128,8 @@ export default class ImageBlockEditing extends Plugin {
* if they decided to put their image there.
*
* See the `ImageInlineEditing` for the similar integration that works in the opposite direction.
*
* The feature also sets image `width` and `height` attributes on paste.
*/
private _setupClipboardIntegration(): void {
const editor = this.editor;
Expand Down Expand Up @@ -175,5 +177,24 @@ export default class ImageBlockEditing extends Plugin {
data.content = writer.createDocumentFragment( blockViewImages );
}
} );

this.listenTo<ClipboardContentInsertionEvent>(
clipboardPipeline,
'contentInsertion',
( evt, data ) => {
if ( data.method !== 'paste' ) {
return;
}

model.change( writer => {
const range = writer.createRangeIn( data.content );

for ( const item of range.getItems() ) {
if ( item.is( 'element', 'imageBlock' ) ) {
imageUtils.setImageNaturalSizeAttributes( item );
}
}
} );
} );
}
}
23 changes: 22 additions & 1 deletion packages/ckeditor5-image/src/image/imageinlineediting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import { Plugin } from 'ckeditor5/src/core';
import { ClipboardPipeline, type ClipboardInputTransformationEvent } from 'ckeditor5/src/clipboard';
import { ClipboardPipeline, type ClipboardInputTransformationEvent, type ClipboardContentInsertionEvent } from 'ckeditor5/src/clipboard';
import { UpcastWriter, type ViewElement } from 'ckeditor5/src/engine';

import {
Expand Down Expand Up @@ -136,6 +136,8 @@ export default class ImageInlineEditing extends Plugin {
* in the clipboard pipeline.
*
* See the `ImageBlockEditing` for the similar integration that works in the opposite direction.
*
* The feature also sets image `width` and `height` attributes when pasting.
*/
private _setupClipboardIntegration(): void {
const editor = this.editor;
Expand Down Expand Up @@ -200,5 +202,24 @@ export default class ImageInlineEditing extends Plugin {
data.content = writer.createDocumentFragment( inlineViewImages );
}
} );

this.listenTo<ClipboardContentInsertionEvent>(
clipboardPipeline,
'contentInsertion',
( evt, data ) => {
if ( data.method !== 'paste' ) {
return;
}

model.change( writer => {
const range = writer.createRangeIn( data.content );

for ( const item of range.getItems() ) {
if ( item.is( 'element', 'imageInline' ) ) {
imageUtils.setImageNaturalSizeAttributes( item );
}
}
} );
} );
}
}
40 changes: 39 additions & 1 deletion packages/ckeditor5-image/tests/image/imageblockediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/* global document, Event */
/* global document, Event, setTimeout */

import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
Expand Down Expand Up @@ -710,5 +710,43 @@ describe( 'ImageBlockEditing', () => {
'[<imageBlock alt="abc" src="/assets/sample.png"></imageBlock>]'
);
} );

it( 'should add image width and height on image paste', done => {
const dataTransfer = new DataTransfer( {
types: [ 'text/html' ],
getData: () => '<figure class="image"><img src="/assets/sample.png" /></figure>'
} );

setModelData( model, '<paragraph>[]</paragraph>' );

viewDocument.fire( 'clipboardInput', { dataTransfer, method: 'paste' } );

setTimeout( () => {
expect( getModelData( model ) ).to.equal(
'[<imageBlock height="96" src="/assets/sample.png" width="96"></imageBlock>]'
);

done();
}, 100 );
} );

it( 'should not add image width and height on image method other than paste', done => {
const dataTransfer = new DataTransfer( {
types: [ 'text/html' ],
getData: () => '<figure class="image"><img src="/assets/sample.png" /></figure>'
} );

setModelData( model, '<paragraph>[]</paragraph>' );

viewDocument.fire( 'clipboardInput', { dataTransfer, method: 'foo' } );

setTimeout( () => {
expect( getModelData( model ) ).to.equal(
'[<imageBlock src="/assets/sample.png"></imageBlock>]'
);

done();
}, 100 );
} );
} );
} );
40 changes: 39 additions & 1 deletion packages/ckeditor5-image/tests/image/imageinlineediting.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/

/* global document, Event */
/* global document, Event, setTimeout */

import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
Expand Down Expand Up @@ -838,6 +838,44 @@ describe( 'ImageInlineEditing', () => {
'<paragraph>f<imageInline resizedWidth="25%" src="/assets/sample.png"></imageInline>[]oo</paragraph>'
);
} );

it( 'should add image width and height on image paste', done => {
const dataTransfer = new DataTransfer( {
types: [ 'text/html' ],
getData: () => '<img src="/assets/sample.png" />'
} );

setModelData( model, '<paragraph>f[]oo</paragraph>' );

viewDocument.fire( 'clipboardInput', { dataTransfer, method: 'paste' } );

setTimeout( () => {
expect( getModelData( model ) ).to.equal(
'<paragraph>f<imageInline height="96" src="/assets/sample.png" width="96"></imageInline>[]oo</paragraph>'
);

done();
}, 100 );
} );

it( 'should not add image width and height on image method other than paste', done => {
const dataTransfer = new DataTransfer( {
types: [ 'text/html' ],
getData: () => '<img src="/assets/sample.png" />'
} );

setModelData( model, '<paragraph>f[]oo</paragraph>' );

viewDocument.fire( 'clipboardInput', { dataTransfer, method: 'foo' } );

setTimeout( () => {
expect( getModelData( model ) ).to.equal(
'<paragraph>f<imageInline src="/assets/sample.png"></imageInline>[]oo</paragraph>'
);

done();
}, 100 );
} );
} );

describe( 'integration with the caption element', () => {
Expand Down

0 comments on commit 47accf1

Please sign in to comment.