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

Schema#schema.checkAttributeInSelection() checks attributes of text #1550

Merged
merged 7 commits into from
Sep 21, 2018
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
53 changes: 53 additions & 0 deletions tests/model/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,27 @@ describe( 'Schema', () => {
return true;
}
} );

schema.addAttributeCheck( ( ctx, attributeName ) => {
// Disallow 'italic' on $text that has attribute 'bold'.
if ( inTextWithBold( ctx ) && attributeName == 'italic' ) {
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing blank line.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right above there's another addAttributeCheck() call. Why haven't you extended it?


// Allow 'italic' on p>$text.
if ( ctx.endsWith( 'p $text' ) && attributeName == 'italic' ) {
return true;
}

// Allow 'italic' on $root>p.
if ( ctx.endsWith( '$root p' ) && attributeName == 'italic' ) {
return true;
}

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

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

it( 'should check attributes of the selection (selection at the beginning of the text)', () => {
setData( model, '<p><$text bold="true">[]foo</$text></p>' );
expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is suspicious... why is it false? What gave the selection the bold attr? I guess setData() did, but I'd remove this test because it's confusing.

} );

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

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

it( 'should check attributes of the selection (an attribute sets manually)', () => {
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;
} );
} );

describe( 'when selection is not collapsed', () => {
Expand Down Expand Up @@ -1102,6 +1150,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