Kaynağa Gözat

Soft break inside list element will be handled correctly.

Kamil Piechaczek 7 yıl önce
ebeveyn
işleme
1ab1e8d62f

+ 14 - 1
packages/ckeditor5-list/src/utils.js

@@ -26,5 +26,18 @@ export function createViewListItemElement( writer ) {
 function getFillerOffset() {
 	const hasOnlyLists = !this.isEmpty && ( this.getChild( 0 ).name == 'ul' || this.getChild( 0 ).name == 'ol' );
 
-	return this.isEmpty || hasOnlyLists ? 0 : null;
+	if ( this.isEmpty || hasOnlyLists ) {
+		return 0;
+	}
+
+	const children = [ ...this.getChildren() ];
+	const lastChild = children[ this.childCount - 1 ];
+
+	// Block filler is required after a `<br>` if it's the last element in its container.
+	// See: https://github.com/ckeditor/ckeditor5/issues/1312#issuecomment-436669045.
+	if ( lastChild && lastChild.is( 'element', 'br' ) ) {
+		return this.childCount;
+	}
+
+	return null;
 }

+ 53 - 0
packages/ckeditor5-list/tests/utils.js

@@ -69,6 +69,59 @@ describe( 'utils', () => {
 
 				expect( item.getFillerOffset() ).to.be.null;
 			} );
+
+			// Block filler is required after the `<br>` element if the element is the last child in the container.
+			// See: https://github.com/ckeditor/ckeditor5/issues/1312#issuecomment-436669045.
+			describe( 'for <br> elements in container', () => {
+				it( 'returns offset of the last child which is the <br> element (1)', () => {
+					const item = createViewListItemElement( writer );
+
+					writer.insert( writer.createPositionAt( item, 0 ), writer.createEmptyElement( 'br' ) );
+
+					expect( item.getFillerOffset() ).to.equal( 1 );
+				} );
+
+				it( 'returns offset of the last child which is the <br> element (2)', () => {
+					const item = createViewListItemElement( writer );
+
+					writer.insert( writer.createPositionAt( item, 0 ), writer.createEmptyElement( 'br' ) );
+					writer.insert( writer.createPositionAt( item, 1 ), writer.createEmptyElement( 'br' ) );
+
+					expect( item.getFillerOffset() ).to.equal( 2 );
+				} );
+
+				it( 'always returns the last <br> element in the container', () => {
+					const item = createViewListItemElement( writer );
+
+					writer.insert( writer.createPositionAt( item, 0 ), writer.createText( 'foo' ) );
+					writer.insert( writer.createPositionAt( item, 1 ), writer.createEmptyElement( 'br' ) );
+					writer.insert( writer.createPositionAt( item, 2 ), writer.createEmptyElement( 'br' ) );
+
+					expect( item.getFillerOffset() ).to.equal( 3 );
+				} );
+
+				it( 'works fine with non-empty container with multi <br> elements', () => {
+					const item = createViewListItemElement( writer );
+
+					writer.insert( writer.createPositionAt( item, 0 ), writer.createText( 'foo' ) );
+					writer.insert( writer.createPositionAt( item, 1 ), writer.createEmptyElement( 'br' ) );
+					writer.insert( writer.createPositionAt( item, 2 ), writer.createText( 'bar' ) );
+					writer.insert( writer.createPositionAt( item, 3 ), writer.createEmptyElement( 'br' ) );
+
+					expect( item.getFillerOffset() ).to.equal( 4 );
+				} );
+
+				it( 'empty element must be the <br> element', () => {
+					const item = createViewListItemElement( writer );
+
+					writer.insert(
+						writer.createPositionAt( item, 0 ),
+						writer.createEmptyElement( 'img' )
+					);
+
+					expect( item.getFillerOffset() ).to.be.null;
+				} );
+			} );
 		} );
 	} );
 } );