@@ -16,11 +16,14 @@ import {
1616 getLabel ,
1717 toWidgetEditable ,
1818 setHighlightHandling ,
19+ findOptimalInsertionPosition ,
1920 WIDGET_CLASS_NAME
2021} from '../src/utils' ;
2122import UIElement from '@ckeditor/ckeditor5-engine/src/view/uielement' ;
2223import env from '@ckeditor/ckeditor5-utils/src/env' ;
2324import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils' ;
25+ import Model from '@ckeditor/ckeditor5-engine/src/model/model' ;
26+ import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model' ;
2427
2528describe ( 'widget utils' , ( ) => {
2629 let element , writer , viewDocument ;
@@ -337,4 +340,85 @@ describe( 'widget utils', () => {
337340 expect ( addSpy . secondCall . args [ 1 ] ) . to . equal ( secondDescriptor ) ;
338341 } ) ;
339342 } ) ;
343+
344+ describe ( 'findOptimalInsertionPosition()' , ( ) => {
345+ let model , doc ;
346+
347+ beforeEach ( ( ) => {
348+ model = new Model ( ) ;
349+ doc = model . document ;
350+
351+ doc . createRoot ( ) ;
352+
353+ model . schema . register ( 'paragraph' , { inheritAllFrom : '$block' } ) ;
354+ model . schema . register ( 'image' ) ;
355+ model . schema . register ( 'span' ) ;
356+
357+ model . schema . extend ( 'image' , {
358+ allowIn : '$root' ,
359+ isObject : true
360+ } ) ;
361+
362+ model . schema . extend ( 'span' , { allowIn : 'paragraph' } ) ;
363+ model . schema . extend ( '$text' , { allowIn : 'span' } ) ;
364+ } ) ;
365+
366+ it ( 'returns position after selected element' , ( ) => {
367+ setData ( model , '<paragraph>x</paragraph>[<image></image>]<paragraph>y</paragraph>' ) ;
368+
369+ const pos = findOptimalInsertionPosition ( doc . selection ) ;
370+
371+ expect ( pos . path ) . to . deep . equal ( [ 2 ] ) ;
372+ } ) ;
373+
374+ it ( 'returns position inside empty block' , ( ) => {
375+ setData ( model , '<paragraph>x</paragraph><paragraph>[]</paragraph><paragraph>y</paragraph>' ) ;
376+
377+ const pos = findOptimalInsertionPosition ( doc . selection ) ;
378+
379+ expect ( pos . path ) . to . deep . equal ( [ 1 , 0 ] ) ;
380+ } ) ;
381+
382+ it ( 'returns position before block if at the beginning of that block' , ( ) => {
383+ setData ( model , '<paragraph>x</paragraph><paragraph>[]foo</paragraph><paragraph>y</paragraph>' ) ;
384+
385+ const pos = findOptimalInsertionPosition ( doc . selection ) ;
386+
387+ expect ( pos . path ) . to . deep . equal ( [ 1 ] ) ;
388+ } ) ;
389+
390+ it ( 'returns position before block if in the middle of that block' , ( ) => {
391+ setData ( model , '<paragraph>x</paragraph><paragraph>f[]oo</paragraph><paragraph>y</paragraph>' ) ;
392+
393+ const pos = findOptimalInsertionPosition ( doc . selection ) ;
394+
395+ expect ( pos . path ) . to . deep . equal ( [ 1 ] ) ;
396+ } ) ;
397+
398+ it ( 'returns position after block if at the end of that block' , ( ) => {
399+ setData ( model , '<paragraph>x</paragraph><paragraph>foo[]</paragraph><paragraph>y</paragraph>' ) ;
400+
401+ const pos = findOptimalInsertionPosition ( doc . selection ) ;
402+
403+ expect ( pos . path ) . to . deep . equal ( [ 2 ] ) ;
404+ } ) ;
405+
406+ // Checking if isTouching() was used.
407+ it ( 'returns position after block if at the end of that block (deeply nested)' , ( ) => {
408+ setData ( model , '<paragraph>x</paragraph><paragraph>foo<span>bar[]</span></paragraph><paragraph>y</paragraph>' ) ;
409+
410+ const pos = findOptimalInsertionPosition ( doc . selection ) ;
411+
412+ expect ( pos . path ) . to . deep . equal ( [ 2 ] ) ;
413+ } ) ;
414+
415+ it ( 'returns selection focus if not in a block' , ( ) => {
416+ model . schema . extend ( '$text' , { allowIn : '$root' } ) ;
417+ setData ( model , 'foo[]bar' ) ;
418+
419+ const pos = findOptimalInsertionPosition ( doc . selection ) ;
420+
421+ expect ( pos . path ) . to . deep . equal ( [ 3 ] ) ;
422+ } ) ;
423+ } ) ;
340424} ) ;
0 commit comments