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

Commit 8fa632c

Browse files
authored
Merge pull request #1550 from ckeditor/t/1546
Fix: `Schema#schema.checkAttributeInSelection()` will include selection's attributes in the context of the check. Closes #1546.
2 parents 6e4d3f8 + d0cd559 commit 8fa632c

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

src/model/schema.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
1414
import Range from './range';
1515
import Position from './position';
1616
import Element from './element';
17+
import Text from './text';
1718
import TreeWalker from './treewalker';
1819

1920
/**
@@ -488,8 +489,14 @@ export default class Schema {
488489
*/
489490
checkAttributeInSelection( selection, attribute ) {
490491
if ( selection.isCollapsed ) {
492+
const firstPosition = selection.getFirstPosition();
493+
const context = [
494+
...firstPosition.getAncestors(),
495+
new Text( '', selection.getAttributes() )
496+
];
497+
491498
// Check whether schema allows for a text with the attribute in the selection.
492-
return this.checkAttribute( [ ...selection.getFirstPosition().getAncestors(), '$text' ], attribute );
499+
return this.checkAttribute( context, attribute );
493500
} else {
494501
const ranges = selection.getRanges();
495502

tests/model/schema.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,9 @@ describe( 'Schema', () => {
10351035
allowIn: '$root',
10361036
allowAttributes: [ 'name', 'title' ]
10371037
} );
1038+
schema.extend( '$text', {
1039+
allowAttributes: [ 'italic' ]
1040+
} );
10381041

10391042
schema.addAttributeCheck( ( ctx, attributeName ) => {
10401043
// Allow 'bold' on p>$text.
@@ -1046,6 +1049,15 @@ describe( 'Schema', () => {
10461049
if ( ctx.endsWith( '$root p' ) && attributeName == 'bold' ) {
10471050
return true;
10481051
}
1052+
1053+
// Disallow 'italic' on $text that has 'bold' already.
1054+
if ( inTextWithBold( ctx ) && attributeName == 'italic' ) {
1055+
return false;
1056+
}
1057+
1058+
function inTextWithBold( context ) {
1059+
return context.endsWith( '$text' ) && context.last.getAttribute( 'bold' );
1060+
}
10491061
} );
10501062
} );
10511063

@@ -1062,6 +1074,51 @@ describe( 'Schema', () => {
10621074
setData( model, '[]' );
10631075
expect( schema.checkAttributeInSelection( doc.selection, attribute ) ).to.be.false;
10641076
} );
1077+
1078+
it( 'should check attributes of the selection (selection inside the $text[bold])', () => {
1079+
setData( model, '<p><$text bold="true">f[]oo</$text></p>' );
1080+
1081+
expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.false;
1082+
1083+
model.change( writer => {
1084+
writer.removeSelectionAttribute( 'bold' );
1085+
} );
1086+
1087+
expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.true;
1088+
} );
1089+
1090+
it( 'should check attributes of the selection (attribute set manually on selection)', () => {
1091+
setData( model, '<p>foo[]bar</p>' );
1092+
1093+
expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.true;
1094+
1095+
model.change( writer => {
1096+
writer.setSelectionAttribute( 'bold', true );
1097+
} );
1098+
1099+
expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.false;
1100+
} );
1101+
1102+
it( 'should pass all selection\'s attributes to checkAttribute()', done => {
1103+
schema.on( 'checkAttribute', ( evt, args ) => {
1104+
const context = args[ 0 ];
1105+
const attributeName = args[ 1 ];
1106+
1107+
expect( attributeName ).to.equal( 'italic' );
1108+
expect( Array.from( context.last.getAttributeKeys() ) ).to.deep.equal( [ 'bold', 'underline' ] );
1109+
1110+
done();
1111+
}, { priority: 'highest' } );
1112+
1113+
setData( model, '<p>foo[]bar</p>' );
1114+
1115+
model.change( writer => {
1116+
writer.setSelectionAttribute( 'bold', true );
1117+
writer.setSelectionAttribute( 'underline', true );
1118+
} );
1119+
1120+
expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.false;
1121+
} );
10651122
} );
10661123

10671124
describe( 'when selection is not collapsed', () => {
@@ -1102,6 +1159,11 @@ describe( 'Schema', () => {
11021159
setData( model, '[<figure name="figure" title="title"></figure>]' );
11031160
expect( schema.checkAttributeInSelection( doc.selection, 'title' ) ).to.be.true;
11041161
} );
1162+
1163+
it( 'should check attributes of text', () => {
1164+
setData( model, '<p><$text bold="true">f[o]o</$text></p>' );
1165+
expect( schema.checkAttributeInSelection( doc.selection, 'italic' ) ).to.be.false;
1166+
} );
11051167
} );
11061168
} );
11071169

0 commit comments

Comments
 (0)