8
0
فهرست منبع

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.
Piotrek Koszuliński 7 سال پیش
والد
کامیت
cd248cde62
2فایلهای تغییر یافته به همراه70 افزوده شده و 1 حذف شده
  1. 8 1
      packages/ckeditor5-engine/src/model/schema.js
  2. 62 0
      packages/ckeditor5-engine/tests/model/schema.js

+ 8 - 1
packages/ckeditor5-engine/src/model/schema.js

@@ -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';
 
 /**
@@ -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();
 

+ 62 - 0
packages/ckeditor5-engine/tests/model/schema.js

@@ -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.
@@ -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' );
+				}
 			} );
 		} );
 
@@ -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', () => {
@@ -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;
+			} );
 		} );
 	} );