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 #122 from ckeditor/t/117
Browse files Browse the repository at this point in the history
Fix: Fixed an error where using spellchecker on a word with a style applied sometimes resulted in that word being removed. Closes #117.
  • Loading branch information
Reinmar authored Oct 2, 2017
2 parents 9a5e22b + b3ba937 commit 1e8d02b
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 8 deletions.
15 changes: 8 additions & 7 deletions src/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,9 +408,10 @@ function getMutationsContainer( mutations ) {
.find( element => element.is( 'containerElement' ) || element.is( 'rootElement' ) );
}

// Returns true if container children have mutated and more than a single text node was changed. Single text node
// child insertion is handled in {@link module:typing/input~MutationHandler#_handleTextNodeInsertion} and text
// mutation is handled in {@link module:typing/input~MutationHandler#_handleTextMutation}.
// Returns true if container children have mutated or more than a single text node was changed.
//
// Single text node child insertion is handled in {@link module:typing/input~MutationHandler#_handleTextNodeInsertion}
// while text mutation is handled in {@link module:typing/input~MutationHandler#_handleTextMutation}.
//
// @private
// @param {Array.<module:engine/view/observer/mutationobserver~MutatedText|
Expand All @@ -421,14 +422,14 @@ function containerChildrenMutated( mutations ) {
return false;
}

// Check if all mutations are `children` type, and there is no single text node mutation.
// Check if there is any mutation of `children` type or any mutation that changes more than one text node.
for ( const mutation of mutations ) {
if ( mutation.type !== 'children' || getSingleTextNodeChange( mutation ) ) {
return false;
if ( mutation.type === 'children' && !getSingleTextNodeChange( mutation ) ) {
return true;
}
}

return true;
return false;
}

// Returns true if provided array contains only {@link module:engine/model/text~Text model text nodes}.
Expand Down
76 changes: 75 additions & 1 deletion tests/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe( 'Input feature', () => {

return VirtualTestEditor
.create( {
plugins: [ Input, Paragraph ]
plugins: [ Input, Paragraph, Bold ]
} )
.then( newEditor => {
// Mock image feature.
Expand Down Expand Up @@ -126,6 +126,50 @@ describe( 'Input feature', () => {
expect( getViewData( view ) ).to.equal( '<p>x{}</p>' );
} );

it( 'should handle multiple text mutations', () => {
editor.setData( '<p>foo<strong>bar</strong></p>' );

view.fire( 'mutations', [
{
type: 'text',
oldText: 'foo',
newText: 'foob',
node: viewRoot.getChild( 0 ).getChild( 0 )
},
{
type: 'text',
oldText: 'bar',
newText: 'ar',
node: viewRoot.getChild( 0 ).getChild( 1 ).getChild( 0 )
}
] );

expect( getModelData( model ) ).to.equal( '<paragraph>foob[]<$text bold="true">ar</$text></paragraph>' );
expect( getViewData( view ) ).to.equal( '<p>foob{}<strong>ar</strong></p>' );
} );

it( 'should handle multiple text node insertion', () => {
editor.setData( '<p></p><p></p>' );

view.fire( 'mutations', [
{
type: 'children',
oldChildren: [],
newChildren: [ new ViewText( 'x' ) ],
node: viewRoot.getChild( 0 )
},
{
type: 'children',
oldChildren: [],
newChildren: [ new ViewText( 'y' ) ],
node: viewRoot.getChild( 1 )
}
] );

expect( getModelData( model ) ).to.equal( '<paragraph>x</paragraph><paragraph>y[]</paragraph>' );
expect( getViewData( view ) ).to.equal( '<p>x</p><p>y{}</p>' );
} );

it( 'should do nothing when two nodes were inserted', () => {
editor.setData( '<p></p>' );

Expand Down Expand Up @@ -947,6 +991,36 @@ describe( 'Input feature', () => {
expect( getModelData( model ) ).to.equal( '<paragraph><$text bold="true">[]textx</$text></paragraph>' );
expect( getViewData( view ) ).to.equal( '<p><strong>{}textx</strong></p>' );
} );

// #117.
it( 'should handle mixed mutations', () => {
setModelData( model, '<paragraph><$text bold="true">Foo bar aple</$text></paragraph>' );

const paragraph = viewRoot.getChild( 0 );
const strong = paragraph.getChild( 0 );
const viewSelection = new ViewSelection();
viewSelection.setCollapsedAt( paragraph, 0 );

// Simulate mutations and DOM change.
domRoot.childNodes[ 0 ].innerHTML = '<strong>Foo bar </strong><b>apple</b>';
view.fire( 'mutations', [
{
type: 'text',
oldText: 'Foo bar aple',
newText: 'Foo bar ',
node: viewRoot.getChild( 0 ).getChild( 0 )
},
{
type: 'children',
oldChildren: [ strong ],
newChildren: [ strong, new ViewElement( 'b', null, new ViewText( 'apple' ) ) ],
node: paragraph
}
], viewSelection );

expect( getModelData( model ) ).to.equal( '<paragraph><$text bold="true">[]Foo bar apple</$text></paragraph>' );
expect( getViewData( view ) ).to.equal( '<p><strong>{}Foo bar apple</strong></p>' );
} );
} );
} );

0 comments on commit 1e8d02b

Please sign in to comment.