Explorar o código

Internal (autoformat): Implemented block styles for non-empty headings.

Marek Lewandowski %!s(int64=5) %!d(string=hai) anos
pai
achega
9945d2f53d

+ 1 - 1
packages/ckeditor5-autoformat/src/autoformat.js

@@ -125,7 +125,7 @@ export default class Autoformat extends Plugin {
 				.filter( name => name.match( /^heading[1-6]$/ ) )
 				.filter( name => name.match( /^heading[1-6]$/ ) )
 				.forEach( modelName => {
 				.forEach( modelName => {
 					const level = modelName[ 7 ];
 					const level = modelName[ 7 ];
-					const pattern = new RegExp( `^(#{${ level }})\\s$` );
+					const pattern = new RegExp( `^(#{${ level }})\\s` );
 
 
 					blockAutoformatEditing( this.editor, this, pattern, () => {
 					blockAutoformatEditing( this.editor, this, pattern, () => {
 						if ( !command.isEnabled || command.value === modelName ) {
 						if ( !command.isEnabled || command.value === modelName ) {

+ 16 - 3
packages/ckeditor5-autoformat/src/blockautoformatediting.js

@@ -2,7 +2,10 @@
  * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
+
 import LiveRange from '@ckeditor/ckeditor5-engine/src/model/liverange';
 import LiveRange from '@ckeditor/ckeditor5-engine/src/model/liverange';
+import first from '@ckeditor/ckeditor5-utils/src/first';
+import Position from '@ckeditor/ckeditor5-engine/src/model/position';
 
 
 /**
 /**
  * The block autoformatting engine. It allows to format various block patterns. For example,
  * The block autoformatting engine. It allows to format various block patterns. For example,
@@ -82,8 +85,8 @@ export default function blockAutoformatEditing( editor, plugin, pattern, callbac
 
 
 		const blockToFormat = entry.position.parent;
 		const blockToFormat = entry.position.parent;
 
 
-		// Block formatting should be disabled in codeBlocks, and in non-empty blocks (ckeditor5#5671).
-		if ( blockToFormat.is( 'codeBlock' ) || blockToFormat.childCount !== 1 ) {
+		// Block formatting should be disabled in codeBlocks (#5800).
+		if ( blockToFormat.is( 'codeBlock' ) ) {
 			return;
 			return;
 		}
 		}
 
 
@@ -93,13 +96,23 @@ export default function blockAutoformatEditing( editor, plugin, pattern, callbac
 			return;
 			return;
 		}
 		}
 
 
-		const match = pattern.exec( blockToFormat.getChild( 0 ).data );
+		const firstNode = blockToFormat.getChild( 0 );
+		const match = pattern.exec( firstNode.data );
 
 
 		// ...and this text node's data match the pattern.
 		// ...and this text node's data match the pattern.
 		if ( !match ) {
 		if ( !match ) {
 			return;
 			return;
 		}
 		}
 
 
+		const range = first( editor.model.document.selection.getRanges() );
+
+		// We're only handling a collapsed selection that is right after the matched text (#5671).
+		const expectedPosition = ( new Position( range.root, firstNode.getPath() ) ).getShiftedBy( match[ 0 ].length );
+
+		if ( !( range.isCollapsed && range.end.isEqual( expectedPosition ) ) ) {
+			return;
+		}
+
 		// Use enqueueChange to create new batch to separate typing batch from the auto-format changes.
 		// Use enqueueChange to create new batch to separate typing batch from the auto-format changes.
 		editor.model.enqueueChange( writer => {
 		editor.model.enqueueChange( writer => {
 			// Matched range.
 			// Matched range.

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

@@ -261,6 +261,15 @@ describe( 'Autoformat', () => {
 
 
 			expect( getData( model ) ).to.equal( '<paragraph>Foo<softBreak></softBreak># []</paragraph>' );
 			expect( getData( model ) ).to.equal( '<paragraph>Foo<softBreak></softBreak># []</paragraph>' );
 		} );
 		} );
+
+		it( 'should convert a header that already contains a text', () => {
+			setData( model, '<heading1>###[]foo</heading1>' );
+			model.change( writer => {
+				writer.insertText( ' ', doc.selection.getFirstPosition() );
+			} );
+
+			expect( getData( model ) ).to.equal( '<heading3>[]foo</heading3>' );
+		} );
 	} );
 	} );
 
 
 	describe( 'Block quote', () => {
 	describe( 'Block quote', () => {

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

@@ -167,6 +167,18 @@ describe( 'blockAutoformatEditing', () => {
 			sinon.assert.notCalled( spy );
 			sinon.assert.notCalled( spy );
 		} );
 		} );
 
 
+		it( 'should not call callback when typing in the middle of block text', () => {
+			const spy = testUtils.sinon.spy();
+			blockAutoformatEditing( editor, plugin, /^[*]\s/, spy );
+
+			setData( model, '<paragraph>* foo[]bar</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)', () => {
 		it( 'should not call callback when after inline element (typing after softBreak in a "matching" paragraph)', () => {
 			// Configure the schema.
 			// Configure the schema.
 			model.schema.register( 'softBreak', {
 			model.schema.register( 'softBreak', {