Explorar el Código

Simplify block autoformat trigger logic.

Maciej Gołaszewski hace 6 años
padre
commit
3f0a941cb5

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

@@ -88,16 +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 text = getStartText( editor.model.createRangeIn( item.parent ) );
-
-			const match = pattern.exec( text );
+			const match = pattern.exec( blockToFormat.getChild( 0 ).data );
 
+			// ...and this text node's data match the pattern.
 			if ( !match ) {
 				return;
 			}
@@ -105,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 } );
@@ -121,23 +121,3 @@ export default class BlockAutoformatEditing {
 		} );
 	}
 }
-
-/**
- * Returns the text from given renge up to the first inline element.
- *
- * @param {module:engine/model/range~Range} range
- * @returns {String}
- */
-export function getStartText( range ) {
-	let text = '';
-
-	for ( const item of range.getItems() ) {
-		if ( !( item.is( 'text' ) || item.is( 'textProxy' ) ) ) {
-			return text;
-		}
-
-		text = text + item.data;
-	}
-
-	return text;
-}

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

@@ -156,6 +156,35 @@ describe( 'BlockAutoformatEditing', () => {
 			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