Explorar el Código

Merge branch 'master' into i/5696

Aleksander Nowodzinski hace 6 años
padre
commit
c3515a3987

+ 7 - 5
packages/ckeditor5-autoformat/src/blockautoformatediting.js

@@ -88,14 +88,16 @@ export default class BlockAutoformatEditing {
 				return;
 			}
 
-			const item = entry.position.textNode || entry.position.nodeAfter;
+			const blockToFormat = entry.position.parent;
 
-			if ( !item.parent.is( 'paragraph' ) ) {
+			// Block formatting should trigger only if the entire content of a paragraph is a single text node... (see ckeditor5#5671).
+			if ( !blockToFormat.is( 'paragraph' ) || blockToFormat.childCount !== 1 ) {
 				return;
 			}
 
-			const match = pattern.exec( item.data );
+			const match = pattern.exec( blockToFormat.getChild( 0 ).data );
 
+			// ...and this text node's data match the pattern.
 			if ( !match ) {
 				return;
 			}
@@ -103,8 +105,8 @@ export default class BlockAutoformatEditing {
 			// Use enqueueChange to create new batch to separate typing batch from the auto-format changes.
 			editor.model.enqueueChange( writer => {
 				// Matched range.
-				const start = writer.createPositionAt( item.parent, 0 );
-				const end = writer.createPositionAt( item.parent, match[ 0 ].length );
+				const start = writer.createPositionAt( blockToFormat, 0 );
+				const end = writer.createPositionAt( blockToFormat, match[ 0 ].length );
 				const range = new LiveRange( start, end );
 
 				const wasChanged = callback( { match } );

+ 36 - 0
packages/ckeditor5-autoformat/tests/autoformat.js

@@ -81,6 +81,15 @@ describe( 'Autoformat', () => {
 
 			expect( getData( model ) ).to.equal( '<listItem listIndent="0" listType="bulleted">- []</listItem>' );
 		} );
+
+		it( 'should not replace asterisk character after <softBreak>', () => {
+			setData( model, '<paragraph>Foo<softBreak></softBreak>*[]</paragraph>' );
+			model.change( writer => {
+				writer.insertText( ' ', doc.selection.getFirstPosition() );
+			} );
+
+			expect( getData( model ) ).to.equal( '<paragraph>Foo<softBreak></softBreak>* []</paragraph>' );
+		} );
 	} );
 
 	describe( 'Numbered list', () => {
@@ -128,6 +137,15 @@ describe( 'Autoformat', () => {
 
 			expect( getData( model ) ).to.equal( '<paragraph>3. []</paragraph>' );
 		} );
+
+		it( 'should not replace digit character after <softBreak>', () => {
+			setData( model, '<paragraph>Foo<softBreak></softBreak>1.[]</paragraph>' );
+			model.change( writer => {
+				writer.insertText( ' ', doc.selection.getFirstPosition() );
+			} );
+
+			expect( getData( model ) ).to.equal( '<paragraph>Foo<softBreak></softBreak>1. []</paragraph>' );
+		} );
 	} );
 
 	describe( 'Heading', () => {
@@ -212,6 +230,15 @@ describe( 'Autoformat', () => {
 
 			expect( getData( model ) ).to.equal( '<paragraph># []</paragraph>' );
 		} );
+
+		it( 'should not replace hash character after <softBreak>', () => {
+			setData( model, '<paragraph>Foo<softBreak></softBreak>#[]</paragraph>' );
+			model.change( writer => {
+				writer.insertText( ' ', doc.selection.getFirstPosition() );
+			} );
+
+			expect( getData( model ) ).to.equal( '<paragraph>Foo<softBreak></softBreak># []</paragraph>' );
+		} );
 	} );
 
 	describe( 'Block quote', () => {
@@ -250,6 +277,15 @@ describe( 'Autoformat', () => {
 
 			expect( getData( model ) ).to.equal( '<listItem listIndent="0" listType="bulleted">1. > []</listItem>' );
 		} );
+
+		it( 'should not replace greater-than character after <softBreak>', () => {
+			setData( model, '<paragraph>Foo<softBreak></softBreak>>[]</paragraph>' );
+			model.change( writer => {
+				writer.insertText( ' ', doc.selection.getFirstPosition() );
+			} );
+
+			expect( getData( model ) ).to.equal( '<paragraph>Foo<softBreak></softBreak>> []</paragraph>' );
+		} );
 	} );
 
 	describe( 'Inline autoformat', () => {

+ 57 - 0
packages/ckeditor5-autoformat/tests/blockautoformatediting.js

@@ -128,6 +128,63 @@ describe( 'BlockAutoformatEditing', () => {
 			sinon.assert.notCalled( spy );
 		} );
 
+		it( 'should not call callback when after inline element', () => {
+			// Configure the schema.
+			model.schema.register( 'softBreak', {
+				allowWhere: '$text',
+				isInline: true
+			} );
+			editor.conversion.for( 'upcast' )
+				.elementToElement( {
+					model: 'softBreak',
+					view: 'br'
+				} );
+			editor.conversion.for( 'downcast' )
+				.elementToElement( {
+					model: 'softBreak',
+					view: ( modelElement, viewWriter ) => viewWriter.createEmptyElement( 'br' )
+				} );
+
+			const spy = testUtils.sinon.spy();
+			new BlockAutoformatEditing( editor, /^[*]\s/, spy ); // eslint-disable-line no-new
+
+			setData( model, '<paragraph>*<softBreak></softBreak>[]</paragraph>' );
+			model.change( writer => {
+				writer.insertText( ' ', doc.selection.getFirstPosition() );
+			} );
+
+			sinon.assert.notCalled( spy );
+		} );
+
+		it( 'should not call callback when after inline element (typing after softBreak in a "matching" paragraph)', () => {
+			// Configure the schema.
+			model.schema.register( 'softBreak', {
+				allowWhere: '$text',
+				isInline: true
+			} );
+			editor.conversion.for( 'upcast' )
+				.elementToElement( {
+					model: 'softBreak',
+					view: 'br'
+				} );
+			editor.conversion.for( 'downcast' )
+				.elementToElement( {
+					model: 'softBreak',
+					view: ( modelElement, viewWriter ) => viewWriter.createEmptyElement( 'br' )
+				} );
+
+			const spy = testUtils.sinon.spy();
+			new BlockAutoformatEditing( editor, /^[*]\s/, spy ); // eslint-disable-line no-new
+
+			setData( model, '<paragraph>* <softBreak></softBreak>[]</paragraph>' );
+
+			model.change( writer => {
+				writer.insertText( ' ', doc.selection.getFirstPosition() );
+			} );
+
+			sinon.assert.notCalled( spy );
+		} );
+
 		it( 'should stop if callback returned false', () => {
 			new BlockAutoformatEditing( editor, /^[*]\s$/, () => false ); // eslint-disable-line no-new