From a2f484dbd2c287d4c7079405c63088daef6ce39d Mon Sep 17 00:00:00 2001 From: Szymon Cofalik Date: Wed, 6 Feb 2019 17:03:57 +0100 Subject: [PATCH] Feature: Cancel `BlockAutoformatEditing` autoformatting if given callback returned `false`. --- src/autoformat.js | 4 ++++ src/blockautoformatediting.js | 13 ++++++++++--- tests/autoformat.js | 14 ++++++++++++++ tests/blockautoformatediting.js | 11 +++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/autoformat.js b/src/autoformat.js index 7ee848c..a299331 100644 --- a/src/autoformat.js +++ b/src/autoformat.js @@ -128,6 +128,10 @@ export default class Autoformat extends Plugin { // eslint-disable-next-line no-new new BlockAutoformatEditing( this.editor, pattern, () => { + if ( !command.isEnabled ) { + return false; + } + this.editor.execute( 'heading', { value: commandValue } ); } ); } ); diff --git a/src/blockautoformatediting.js b/src/blockautoformatediting.js index ac59405..a82b502 100644 --- a/src/blockautoformatediting.js +++ b/src/blockautoformatediting.js @@ -7,6 +7,8 @@ * @module autoformat/blockautoformatediting */ +import LiveRange from '@ckeditor/ckeditor5-engine/src/model/liverange'; + /** * The block autoformatting engine. It allows to format various block patterns. For example, * it can be configured to turn a paragraph starting with `*` and followed by a space into a list item. @@ -78,6 +80,7 @@ export default class BlockAutoformatEditing { if ( changes.length != 1 || entry.type !== 'insert' || entry.name != '$text' || entry.length != 1 ) { return; } + const item = entry.position.textNode || entry.position.nodeAfter; if ( !item.parent.is( 'paragraph' ) ) { @@ -95,12 +98,16 @@ export default class BlockAutoformatEditing { // Matched range. const start = writer.createPositionAt( item.parent, 0 ); const end = writer.createPositionAt( item.parent, match[ 0 ].length ); - const range = writer.createRange( start, end ); + const range = new LiveRange( start, end ); + + const wasChanged = callback( { match } ); // Remove matched text. - writer.remove( range ); + if ( wasChanged !== false ) { + writer.remove( range ); + } - callback( { match } ); + range.detach(); } ); } ); } diff --git a/tests/autoformat.js b/tests/autoformat.js index e2cdf83..fa412f2 100644 --- a/tests/autoformat.js +++ b/tests/autoformat.js @@ -154,6 +154,7 @@ describe( 'Autoformat', () => { function HeadingPlugin( editor ) { editor.commands.add( 'heading', command ); + command.refresh(); } return VirtualTestEditor @@ -187,6 +188,19 @@ describe( 'Autoformat', () => { return editor.destroy(); } ); } ); + + it( 'should not replace if heading command is disabled', () => { + setData( model, '#[]' ); + + model.change( writer => { + editor.commands.get( 'heading' ).refresh = () => {}; + editor.commands.get( 'heading' ).isEnabled = false; + + writer.insertText( ' ', doc.selection.getFirstPosition() ); + } ); + + expect( getData( model ) ).to.equal( '# []' ); + } ); } ); describe( 'Block quote', () => { diff --git a/tests/blockautoformatediting.js b/tests/blockautoformatediting.js index c2418ee..16459ef 100644 --- a/tests/blockautoformatediting.js +++ b/tests/blockautoformatediting.js @@ -123,6 +123,17 @@ describe( 'BlockAutoformatEditing', () => { sinon.assert.notCalled( spy ); } ); + + it( 'should stop if callback returned false', () => { + new BlockAutoformatEditing( editor, /^[*]\s$/, () => false ); // eslint-disable-line no-new + + setData( model, '*[]' ); + model.change( writer => { + writer.insertText( ' ', doc.selection.getFirstPosition() ); + } ); + + expect( getData( model ) ).to.equal( '* []' ); + } ); } ); it( 'should ignore transparent batches', () => {