8
0
فهرست منبع

Merge pull request #1023 from ckeditor/t/1021

Fixed: Block filler was rendered before UI elements, interfering with their positioning. Now it will be properly rendered at the end of an element. Closes #1021.
Piotrek Koszuliński 8 سال پیش
والد
کامیت
65a798cfb4

+ 2 - 1
packages/ckeditor5-engine/src/view/attributeelement.js

@@ -120,7 +120,8 @@ function getFillerOffset() {
 		return null;
 	}
 
-	return 0;
+	// Render block filler at the end of element (after all ui elements).
+	return this.childCount;
 }
 
 // Returns total count of children that are not {@link module:engine/view/uielement~UIElement UIElements}.

+ 9 - 1
packages/ckeditor5-engine/src/view/containerelement.js

@@ -78,5 +78,13 @@ export default class ContainerElement extends Element {
 //
 // @returns {Number|null} Block filler offset or `null` if block filler is not needed.
 function getFillerOffset() {
-	return Array.from( this.getChildren() ).some( element => !element.is( 'uiElement' ) ) ? null : 0;
+	for ( const child of this.getChildren() ) {
+		// If there's any non-UI element – don't render the bogus.
+		if ( !child.is( 'uiElement' ) ) {
+			return null;
+		}
+	}
+
+	// If there are only UI elements – render the bogus at the end of the element.
+	return this.childCount;
 }

+ 5 - 5
packages/ckeditor5-engine/tests/view/attributeelement.js

@@ -138,19 +138,19 @@ describe( 'AttributeElement', () => {
 			expect( attribute.getFillerOffset() ).to.be.null;
 		} );
 
-		it( 'should return position 0 if it is the only nested element in the container and has UIElement inside', () => {
+		it( 'should return offset after all children if it is the only nested element in the container and has UIElement inside', () => {
 			const { selection } = parse(
 				'<container:p><attribute:b><attribute:i>[]<ui:span></ui:span></attribute:i></attribute:b></container:p>' );
 			const attribute = selection.getFirstPosition().parent;
 
-			expect( attribute.getFillerOffset() ).to.equals( 0 );
+			expect( attribute.getFillerOffset() ).to.equal( 1 );
 		} );
 
-		it( 'should return 0 if there is no parent container element and has UIElement inside', () => {
-			const { selection } = parse( '<attribute:b>[]<ui:span></ui:span></attribute:b>' );
+		it( 'should return offset after all children if there is no parent container element and has UIElement inside', () => {
+			const { selection } = parse( '<attribute:b>[]<ui:span></ui:span><ui:span></ui:span></attribute:b>' );
 			const attribute = selection.getFirstPosition().parent;
 
-			expect( attribute.getFillerOffset() ).to.equal( 0 );
+			expect( attribute.getFillerOffset() ).to.equal( 2 );
 		} );
 	} );
 } );

+ 2 - 2
packages/ckeditor5-engine/tests/view/containerelement.js

@@ -52,8 +52,8 @@ describe( 'ContainerElement', () => {
 			expect( parse( '<container:p></container:p>' ).getFillerOffset() ).to.equals( 0 );
 		} );
 
-		it( 'should return position 0 if element contains only ui elements', () => {
-			expect( parse( '<container:p><ui:span></ui:span></container:p>' ).getFillerOffset() ).to.equals( 0 );
+		it( 'should return offset after all children if element contains only ui elements', () => {
+			expect( parse( '<container:p><ui:span></ui:span><ui:span></ui:span></container:p>' ).getFillerOffset() ).to.equals( 2 );
 		} );
 
 		it( 'should return null if element is not empty', () => {

+ 1 - 3
packages/ckeditor5-engine/tests/view/manual/uielement.html

@@ -12,12 +12,10 @@
 		font-size: 8px;
 		border-top: 1px solid #dadada;
 		font-family: sans-serif;
-	}
-
-	.ui-element span {
 		background-color: #7a7a7a;
 		color: white;
 		padding: 1px 5px;
+		display: inline-block;
 	}
 </style>
 <div id="container">

+ 2 - 2
packages/ckeditor5-engine/tests/view/manual/uielement.js

@@ -19,7 +19,7 @@ class MyUIElement extends UIElement {
 
 		root.setAttribute( 'contenteditable', 'false' );
 		root.classList.add( 'ui-element' );
-		root.innerHTML = '<span>END OF PARAGRAPH</span>';
+		root.innerHTML = 'END OF PARAGRAPH';
 
 		return root;
 	}
@@ -33,7 +33,7 @@ class UIElementTestPlugin extends Plugin {
 		// Add some UIElement to each paragraph.
 		editing.modelToView.on( 'insert:paragraph', ( evt, data, consumable, conversionApi ) => {
 			const viewP = conversionApi.mapper.toViewElement( data.item );
-			viewP.appendChildren( new MyUIElement( 'div' ) );
+			viewP.appendChildren( new MyUIElement( 'span' ) );
 		}, { priority: 'lowest' } );
 	}
 }