@@ -11,6 +11,7 @@ import ModelPosition from '../../src/model/position';
1111import ViewDocument from '../../src/view/document' ;
1212import ViewContainerElement from '../../src/view/containerelement' ;
1313import ViewAttributeElement from '../../src/view/attributeelement' ;
14+ import ViewUIElement from '../../src/view/uielement' ;
1415import { mergeAttributes } from '../../src/view/writer' ;
1516
1617import Mapper from '../../src/conversion/mapper' ;
@@ -314,6 +315,69 @@ describe( 'model-selection-to-view-converters', () => {
314315 . to . equal ( '<div>foo{}bar</div>' ) ;
315316 } ) ;
316317
318+ // #1072 - if the container has only ui elements, collapsed selection attribute should be rendered after those ui elements.
319+ it ( 'selection with attribute before ui element - no non-ui children' , ( ) => {
320+ setModelData ( modelDoc , '' ) ;
321+
322+ // Add two ui elements to view.
323+ viewRoot . appendChildren ( [
324+ new ViewUIElement ( 'span' ) ,
325+ new ViewUIElement ( 'span' )
326+ ] ) ;
327+
328+ modelSelection . setRanges ( [ new ModelRange ( new ModelPosition ( modelRoot , [ 0 ] ) ) ] ) ;
329+ modelSelection . setAttribute ( 'bold' , true ) ;
330+
331+ // Convert model to view.
332+ dispatcher . convertSelection ( modelSelection , [ ] ) ;
333+
334+ // Stringify view and check if it is same as expected.
335+ expect ( stringifyView ( viewRoot , viewSelection , { showType : false } ) )
336+ . to . equal ( '<div><span></span><span></span><strong>[]</strong></div>' ) ;
337+ } ) ;
338+
339+ // #1072.
340+ it ( 'selection with attribute before ui element - has non-ui children #1' , ( ) => {
341+ setModelData ( modelDoc , 'x' ) ;
342+
343+ modelSelection . setRanges ( [ new ModelRange ( new ModelPosition ( modelRoot , [ 1 ] ) ) ] ) ;
344+ modelSelection . setAttribute ( 'bold' , true ) ;
345+
346+ // Convert model to view.
347+ dispatcher . convertInsertion ( ModelRange . createIn ( modelRoot ) ) ;
348+
349+ // Add ui element to view.
350+ const uiElement = new ViewUIElement ( 'span' ) ;
351+ viewRoot . insertChildren ( 1 , uiElement ) ;
352+
353+ dispatcher . convertSelection ( modelSelection , [ ] ) ;
354+
355+ // Stringify view and check if it is same as expected.
356+ expect ( stringifyView ( viewRoot , viewSelection , { showType : false } ) )
357+ . to . equal ( '<div>x<strong>[]</strong><span></span></div>' ) ;
358+ } ) ;
359+
360+ // #1072.
361+ it ( 'selection with attribute before ui element - has non-ui children #2' , ( ) => {
362+ setModelData ( modelDoc , '<$text bold="true">x</$text>y' ) ;
363+
364+ modelSelection . setRanges ( [ new ModelRange ( new ModelPosition ( modelRoot , [ 1 ] ) ) ] ) ;
365+ modelSelection . setAttribute ( 'bold' , true ) ;
366+
367+ // Convert model to view.
368+ dispatcher . convertInsertion ( ModelRange . createIn ( modelRoot ) ) ;
369+
370+ // Add ui element to view.
371+ const uiElement = new ViewUIElement ( 'span' ) ;
372+ viewRoot . insertChildren ( 1 , uiElement ) ;
373+
374+ dispatcher . convertSelection ( modelSelection , [ ] ) ;
375+
376+ // Stringify view and check if it is same as expected.
377+ expect ( stringifyView ( viewRoot , viewSelection , { showType : false } ) )
378+ . to . equal ( '<div><strong>x{}</strong><span></span>y</div>' ) ;
379+ } ) ;
380+
317381 it ( 'consumes consumable values properly' , ( ) => {
318382 // Add callbacks that will fire before default ones.
319383 // This should prevent default callbacks doing anything.
0 commit comments