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 #1550 from ckeditor/t/1546
Browse files Browse the repository at this point in the history
Fix: `Schema#schema.checkAttributeInSelection()` will include selection's attributes in the context of the check. Closes #1546.
  • Loading branch information
Reinmar committed Sep 21, 2018
2 parents 6e4d3f8 + d0cd559 commit 8fa632c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/model/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
import Range from './range';
import Position from './position';
import Element from './element';
import Text from './text';
import TreeWalker from './treewalker';

/**
Expand Down Expand Up @@ -488,8 +489,14 @@ export default class Schema {
*/
checkAttributeInSelection( selection, attribute ) {
if ( selection.isCollapsed ) {
const firstPosition = selection.getFirstPosition();
const context = [
...firstPosition.getAncestors(),
new Text( '', selection.getAttributes() )
];

// Check whether schema allows for a text with the attribute in the selection.
return this.checkAttribute( [ ...selection.getFirstPosition().getAncestors(), '$text' ], attribute );
return this.checkAttribute( context, attribute );
} else {
const ranges = selection.getRanges();

Expand Down
62 changes: 62 additions & 0 deletions tests/model/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,9 @@ describe( 'Schema', () => {
allowIn: '$root',
allowAttributes: [ 'name', 'title' ]
} );
schema.extend( '$text', {
allowAttributes: [ 'italic' ]
} );

schema.addAttributeCheck( ( ctx, attributeName ) => {
// Allow 'bold' on p>$text.
Expand All @@ -1046,6 +1049,15 @@ describe( 'Schema', () => {
if ( ctx.endsWith( '$root p' ) && attributeName == 'bold' ) {
return true;
}

// Disallow 'italic' on $text that has 'bold' already.
if ( inTextWithBold( ctx ) && attributeName == 'italic' ) {
return false;
}

function inTextWithBold( context ) {
return context.endsWith( '$text' ) && context.last.getAttribute( 'bold' );
}
} );
} );

Expand All @@ -1062,6 +1074,51 @@ describe( 'Schema', () => {
setData( model, '[]' );
expect( schema.checkAttributeInSelection( doc.selection, attribute ) ).to.be.false;
} );

it( 'should check attributes of the selection (selection inside the $text[bold])', () => {
setData( model, '<p><$text bold="true">f[]oo</$text></p>' );

expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.false;

model.change( writer => {
writer.removeSelectionAttribute( 'bold' );
} );

expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.true;
} );

it( 'should check attributes of the selection (attribute set manually on selection)', () => {
setData( model, '<p>foo[]bar</p>' );

expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.true;

model.change( writer => {
writer.setSelectionAttribute( 'bold', true );
} );

expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.false;
} );

it( 'should pass all selection\'s attributes to checkAttribute()', done => {
schema.on( 'checkAttribute', ( evt, args ) => {
const context = args[ 0 ];
const attributeName = args[ 1 ];

expect( attributeName ).to.equal( 'italic' );
expect( Array.from( context.last.getAttributeKeys() ) ).to.deep.equal( [ 'bold', 'underline' ] );

done();
}, { priority: 'highest' } );

setData( model, '<p>foo[]bar</p>' );

model.change( writer => {
writer.setSelectionAttribute( 'bold', true );
writer.setSelectionAttribute( 'underline', true );
} );

expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.false;
} );
} );

describe( 'when selection is not collapsed', () => {
Expand Down Expand Up @@ -1102,6 +1159,11 @@ describe( 'Schema', () => {
setData( model, '[<figure name="figure" title="title"></figure>]' );
expect( schema.checkAttributeInSelection( doc.selection, 'title' ) ).to.be.true;
} );

it( 'should check attributes of text', () => {
setData( model, '<p><$text bold="true">f[o]o</$text></p>' );
expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.false;
} );
} );
} );

Expand Down

0 comments on commit 8fa632c

Please sign in to comment.