Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge pull request #213 from ckeditor/t/208
Browse files Browse the repository at this point in the history
Feature: Introduced `Input#isInput()`. Closes #214. Fixed the `TextTransformation` feature so it willl trigger only for typing changes. Closes #208.
  • Loading branch information
scofalik authored Jul 24, 2019
2 parents 6ef7d47 + 2e23a1c commit 0e26850
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 65 deletions.
23 changes: 23 additions & 0 deletions src/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,27 @@ export default class Input extends Plugin {
injectUnsafeKeystrokesHandling( editor );
injectTypingMutationsHandling( editor );
}

/**
* Checks batch if it is a result of user input - e.g. typing.
*
* const input = editor.plugins.get( 'Input' );
*
* editor.model.document.on( 'change:data', ( evt, batch ) => {
* if ( input.isTyping( batch ) ) {
* console.log( 'The user typed something...' );
* }
* } );
*
* **Note:** This method checks if the batch was created using {@link module:typing/inputcommand~InputCommand 'input'}
* command as typing changes coming from user input are inserted to the document using that command.
*
* @param {module:engine/model/batch~Batch} batch A batch to check.
* @returns {Boolean}
*/
isInput( batch ) {
const inputCommand = this.editor.commands.get( 'input' );

return inputCommand._batches.has( batch );
}
}
12 changes: 12 additions & 0 deletions src/inputcommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ export default class InputCommand extends Command {
* @member {module:typing/utils/changebuffer~ChangeBuffer} #_buffer
*/
this._buffer = new ChangeBuffer( editor.model, undoStepSize );

/**
* Stores batches created by the input command. The batches are used to differentiate input batches from other batches using
* {@link module:typing/input~Input#isInput} method.
*
* @type {WeakSet<module:engine/model/batch~Batch>}
* @protected
*/
this._batches = new WeakSet();
}

/**
Expand Down Expand Up @@ -98,6 +107,9 @@ export default class InputCommand extends Command {
this._buffer.unlock();

this._buffer.input( textInsertions );

// Store the batch as an 'input' batch for the Input.isInput( batch ) check.
this._batches.add( this._buffer.batch );
} );
}
}
5 changes: 5 additions & 0 deletions src/texttransformation.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export default class TextTransformation extends Plugin {
init() {
const editor = this.editor;
const model = editor.model;
const input = editor.plugins.get( 'Input' );

const configuredTransformations = getConfiguredTransformations( editor.config.get( 'typing.transformations' ) );

Expand All @@ -110,6 +111,10 @@ export default class TextTransformation extends Plugin {
const watcher = new TextWatcher( editor.model, text => from.test( text ) );

watcher.on( 'matched:data', ( evt, data ) => {
if ( !input.isInput( data.batch ) ) {
return;
}

const matches = from.exec( data.text );
const replaces = to( matches.slice( 1 ) );

Expand Down
15 changes: 11 additions & 4 deletions src/textwatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default class TextWatcher {
return;
}

this._evaluateTextBeforeSelection( 'data' );
this._evaluateTextBeforeSelection( 'data', { batch } );
} );
}

Expand All @@ -79,8 +79,9 @@ export default class TextWatcher {
*
* @private
* @param {'data'|'selection'} suffix Suffix used for generating event name.
* @param {Object} data Data object for event.
*/
_evaluateTextBeforeSelection( suffix ) {
_evaluateTextBeforeSelection( suffix, data = {} ) {
const text = this._getText();

const textHasMatch = this.testCallback( text );
Expand All @@ -97,18 +98,24 @@ export default class TextWatcher {
this.hasMatch = textHasMatch;

if ( textHasMatch ) {
const eventData = Object.assign( data, { text } );

/**
* Fired whenever the text watcher found a match for data changes.
*
* @event matched:data
* @param {Object} data Event data.
* @param {String} data.text The full text before selection.
* @param {module:engine/model/batch~Batch} data.batch A batch associated with a change.
*/

/**
* Fired whenever the text watcher found a match for selection changes.
*
* @event matched:selection
* @param {Object} data Event data.
* @param {String} data.text The full text before selection.
*/
this.fire( `matched:${ suffix }`, { text } );
this.fire( `matched:${ suffix }`, eventData );
}
}

Expand Down
23 changes: 23 additions & 0 deletions tests/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,29 @@ describe( 'Input feature', () => {
return editor.destroy();
} );

describe( 'isInput()', () => {
let input;

beforeEach( () => {
input = editor.plugins.get( 'Input' );
} );

it( 'returns true for batch created using "input" command', done => {
model.document.once( 'change:data', ( evt, batch ) => {
expect( input.isInput( batch ) ).to.be.true;
done();
} );

editor.execute( 'input', { text: 'foo' } );
} );

it( 'returns false for batch not created using "input" command', () => {
const batch = model.createBatch();

expect( input.isInput( batch ) ).to.be.false;
} );
} );

describe( 'mutations handling', () => {
it( 'should handle text mutation', () => {
viewDocument.fire( 'mutations', [
Expand Down
14 changes: 5 additions & 9 deletions tests/texttransformation-integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictest
import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';

import TextTransformation from '../src/texttransformation';
import Typing from '../src/typing';

describe( 'Text transformation feature - integration', () => {
let editorElement, editor, model, doc;
Expand All @@ -32,7 +33,7 @@ describe( 'Text transformation feature - integration', () => {
describe( 'with undo', () => {
beforeEach( () => {
return ClassicTestEditor
.create( editorElement, { plugins: [ Paragraph, TextTransformation, UndoEditing ] } )
.create( editorElement, { plugins: [ Typing, Paragraph, TextTransformation, UndoEditing ] } )
.then( newEditor => {
editor = newEditor;
model = editor.model;
Expand All @@ -48,10 +49,7 @@ describe( 'Text transformation feature - integration', () => {
writer.insertText( '(c', doc.selection.focus );
} );

model.enqueueChange( model.createBatch(), writer => {
writer.setSelection( doc.getRoot().getChild( 0 ), 'end' );
writer.insertText( ')', doc.selection.focus );
} );
editor.execute( 'input', { text: ')' } );

expect( editor.getData(), 'inserted text' ).to.equal( '<p>foo©</p>' );

Expand All @@ -72,10 +70,8 @@ describe( 'Text transformation feature - integration', () => {
writer.insertText( 'foo bar baz(c', doc.selection.focus );
} );

model.enqueueChange( model.createBatch(), writer => {
writer.setSelection( doc.getRoot().getChild( 0 ), 'end' );
writer.insertText( ')', doc.selection.focus );
} );
editor.execute( 'input', { text: ')' } );

expect( editor.getData() ).to.equal( '<p>foo bar baz©</p>' );

editor.execute( 'undo' );
Expand Down
Loading

0 comments on commit 0e26850

Please sign in to comment.