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

Commit 70742f9

Browse files
authored
Merge pull request #28 from ckeditor/t/7
Fix: Image will be inserted after the block if the selection is placed at the block's end. Closes #7.
2 parents c3bbb57 + 8328916 commit 70742f9

File tree

4 files changed

+59
-22
lines changed

4 files changed

+59
-22
lines changed

src/imageuploadcommand.js

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,7 @@ export default class ImageUploadCommand extends Command {
4444
}
4545

4646
doc.enqueueChanges( () => {
47-
let insertPosition;
48-
const selectedElement = selection.getSelectedElement();
49-
50-
// If selected element is placed directly in root - put image after it.
51-
if ( selectedElement && selectedElement.parent.is( 'rootElement' ) ) {
52-
insertPosition = ModelPosition.createAfter( selectedElement );
53-
} else {
54-
// If selection is inside some block - put image before it.
55-
const firstBlock = doc.selection.getSelectedBlocks().next().value;
56-
57-
if ( firstBlock ) {
58-
insertPosition = ModelPosition.createBefore( firstBlock );
59-
}
60-
}
47+
const insertPosition = getInsertionPosition( doc );
6148

6249
// No position to insert.
6350
if ( !insertPosition ) {
@@ -77,3 +64,33 @@ export default class ImageUploadCommand extends Command {
7764
} );
7865
}
7966
}
67+
68+
/**
69+
* Returns correct image insertion position.
70+
*
71+
* @param {module:engine/model/document~Document} doc
72+
* @returns {module:engine/model/position~Position|undefined}
73+
*/
74+
function getInsertionPosition( doc ) {
75+
const selection = doc.selection;
76+
const selectedElement = selection.getSelectedElement();
77+
78+
// If selected element is placed directly in root - return position after that element.
79+
if ( selectedElement && selectedElement.parent.is( 'rootElement' ) ) {
80+
return ModelPosition.createAfter( selectedElement );
81+
}
82+
83+
const firstBlock = doc.selection.getSelectedBlocks().next().value;
84+
85+
if ( firstBlock ) {
86+
const positionAfter = ModelPosition.createAfter( firstBlock );
87+
88+
// If selection is at the end of the block - return position after the block.
89+
if ( selection.focus.isTouching( positionAfter ) ) {
90+
return positionAfter;
91+
}
92+
93+
// Otherwise return position before the block.
94+
return ModelPosition.createBefore( firstBlock );
95+
}
96+
}

tests/imageuploadcommand.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,31 @@ describe( 'ImageUploadCommand', () => {
3939

4040
describe( '_doExecute', () => {
4141
it( 'should insert image', () => {
42+
const file = createNativeFileMock();
43+
setModelData( document, '<paragraph>[]foo</paragraph>' );
44+
45+
command._doExecute( { file } );
46+
47+
const id = fileRepository.getLoader( file ).id;
48+
expect( getModelData( document ) ).to.equal( `[<image uploadId="${ id }"></image>]<paragraph>foo</paragraph>` );
49+
} );
50+
51+
it( 'should insert image after block if selection is at its end', () => {
4252
const file = createNativeFileMock();
4353
setModelData( document, '<paragraph>foo[]</paragraph>' );
4454

4555
command._doExecute( { file } );
4656

57+
const id = fileRepository.getLoader( file ).id;
58+
expect( getModelData( document ) ).to.equal( `<paragraph>foo</paragraph>[<image uploadId="${ id }"></image>]` );
59+
} );
60+
61+
it( 'should insert image before block if selection is in the middle', () => {
62+
const file = createNativeFileMock();
63+
setModelData( document, '<paragraph>f{}oo</paragraph>' );
64+
65+
command._doExecute( { file } );
66+
4767
const id = fileRepository.getLoader( file ).id;
4868
expect( getModelData( document ) ).to.equal( `[<image uploadId="${ id }"></image>]<paragraph>foo</paragraph>` );
4969
} );
@@ -87,7 +107,7 @@ describe( 'ImageUploadCommand', () => {
87107
const file = createNativeFileMock();
88108
const spy = sinon.spy( batch, 'insert' );
89109

90-
setModelData( document, '<paragraph>foo[]</paragraph>' );
110+
setModelData( document, '<paragraph>[]foo</paragraph>' );
91111

92112
command._doExecute( { batch, file } );
93113
const id = fileRepository.getLoader( file ).id;

tests/imageuploadengine.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ describe( 'ImageUploadEngine', () => {
6161
const spy = sinon.spy( editor, 'execute' );
6262
const fileMock = createNativeFileMock();
6363
const dataTransfer = new DataTransfer( { files: [ fileMock ] } );
64-
setModelData( document, '<paragraph>foo bar baz[]</paragraph>' );
64+
setModelData( document, '<paragraph>[]foo bar baz</paragraph>' );
6565

6666
viewDocument.fire( 'clipboardInput', { dataTransfer } );
6767

tests/imageuploadprogress.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ describe( 'ImageUploadProgress', () => {
5353
} );
5454

5555
it( 'should convert image\'s "reading" uploadStatus attribute', () => {
56-
setModelData( document, '<paragraph>foo[]</paragraph>' );
56+
setModelData( document, '<paragraph>[]foo</paragraph>' );
5757
editor.execute( 'imageUpload', { file: createNativeFileMock() } );
5858

5959
expect( getViewData( viewDocument ) ).to.equal(
@@ -64,7 +64,7 @@ describe( 'ImageUploadProgress', () => {
6464
} );
6565

6666
it( 'should convert image\'s "uploading" uploadStatus attribute', ( done ) => {
67-
setModelData( document, '<paragraph>foo[]</paragraph>' );
67+
setModelData( document, '<paragraph>[]foo</paragraph>' );
6868
editor.execute( 'imageUpload', { file: createNativeFileMock() } );
6969

7070
document.once( 'changesDone', () => {
@@ -82,7 +82,7 @@ describe( 'ImageUploadProgress', () => {
8282
} );
8383

8484
it( 'should update progressbar width on progress', ( done ) => {
85-
setModelData( document, '<paragraph>foo[]</paragraph>' );
85+
setModelData( document, '<paragraph>[]foo</paragraph>' );
8686
editor.execute( 'imageUpload', { file: createNativeFileMock() } );
8787

8888
document.once( 'changesDone', () => {
@@ -102,7 +102,7 @@ describe( 'ImageUploadProgress', () => {
102102
} );
103103

104104
it( 'should convert image\'s "complete" uploadStatus attribute', ( done ) => {
105-
setModelData( document, '<paragraph>foo[]</paragraph>' );
105+
setModelData( document, '<paragraph>[]foo</paragraph>' );
106106
editor.execute( 'imageUpload', { file: createNativeFileMock() } );
107107

108108
document.once( 'changesDone', () => {
@@ -126,7 +126,7 @@ describe( 'ImageUploadProgress', () => {
126126
const uploadProgress = editor.plugins.get( ImageUploadProgress );
127127
uploadProgress.placeholder = base64Sample;
128128

129-
setModelData( document, '<paragraph>foo[]</paragraph>' );
129+
setModelData( document, '<paragraph>[]foo</paragraph>' );
130130
editor.execute( 'imageUpload', { file: createNativeFileMock() } );
131131

132132
expect( getViewData( viewDocument ) ).to.equal(
@@ -141,7 +141,7 @@ describe( 'ImageUploadProgress', () => {
141141
consumable.consume( data.item, eventNameToConsumableType( evt.name ) );
142142
}, { priority: 'highest' } );
143143

144-
setModelData( document, '<paragraph>foo[]</paragraph>' );
144+
setModelData( document, '<paragraph>[]foo</paragraph>' );
145145
editor.execute( 'imageUpload', { file: createNativeFileMock() } );
146146

147147
expect( getViewData( viewDocument ) ).to.equal(

0 commit comments

Comments
 (0)