Parcourir la source

Updated value and isEnabled calculation in heading command.

Szymon Kupś il y a 8 ans
Parent
commit
2c4e5fe3da

+ 26 - 5
packages/ckeditor5-heading/src/headingcommand.js

@@ -39,7 +39,10 @@ export default class HeadingCommand extends Command {
 		this.set( 'value', false );
 
 		// Update current value each time changes are done on document.
-		this.listenTo( editor.document, 'changesDone', () => this._updateValue() );
+		this.listenTo( editor.document, 'changesDone', () => {
+			this._updateValue();
+			this.refreshState();
+		} );
 
 		/**
 		 * Unique identifier of the command, also element's name in the model.
@@ -111,11 +114,29 @@ export default class HeadingCommand extends Command {
 	 * @private
 	 */
 	_updateValue() {
-		const block = this.editor.document.selection.getSelectedBlocks().next().value;
+		const block = this._getSelectedBlock();
+
+		this.value = !!block && block.is( this.modelElement );
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	_checkEnabled() {
+		const block = this._getSelectedBlock();
+		const schema = this.editor.document.schema;
 
-		if ( block ) {
-			this.value = block.is( this.modelElement );
-		}
+		return !!block && schema.check( { name: this.modelElement, inside: block.parent.name } ) && !schema.objects.has( block.name );
+	}
+
+	/**
+	 * Returns currently selected block.
+	 *
+	 * @private
+	 * @returns {module:engine/model/element~Element}
+	 */
+	_getSelectedBlock() {
+		return this.editor.document.selection.getSelectedBlocks().next().value;
 	}
 }
 

+ 1 - 1
packages/ckeditor5-heading/tests/heading.js

@@ -58,7 +58,7 @@ describe( 'Heading', () => {
 			const dropdown = editor.ui.componentFactory.create( 'headings' );
 
 			expect( dropdown ).to.be.instanceOf( DropdownView );
-			expect( dropdown.buttonView.isEnabled ).to.be.true;
+			expect( dropdown.buttonView.isEnabled ).to.be.false;
 			expect( dropdown.buttonView.isOn ).to.be.undefined;
 			expect( dropdown.buttonView.label ).to.equal( 'Choose heading' );
 			expect( dropdown.buttonView.tooltip ).to.equal( 'Heading' );

+ 62 - 0
packages/ckeditor5-heading/tests/headingcommand.js

@@ -33,6 +33,15 @@ describe( 'HeadingCommand', () => {
 				schema.registerItem( option.modelElement, '$block' );
 			}
 
+			schema.registerItem( 'notBlock' );
+			schema.allow( { name: 'notBlock', inside: '$root' } );
+			schema.allow( { name: '$text', inside: 'notBlock' } );
+
+			schema.registerItem( 'object' );
+			schema.allow( { name: 'object', inside: '$root' } );
+			schema.allow( { name: '$text', inside: 'object' } );
+			schema.objects.add( 'object' );
+
 			root = document.getRoot();
 		} );
 	} );
@@ -70,6 +79,19 @@ describe( 'HeadingCommand', () => {
 
 				expect( commands[ modelElement ].value ).to.be.true;
 			} );
+
+			it( `equals false if moved from ${ modelElement } to non-block element`, () => {
+				setData( document, `<${ modelElement }>[foo]</${ modelElement }><notBlock>foo</notBlock>` );
+				const element = document.getRoot().getChild( 1 );
+
+				expect( commands[ modelElement ].value ).to.be.true;
+
+				document.enqueueChanges( () => {
+					document.selection.setRanges( [ Range.createIn( element ) ] );
+				} );
+
+				expect( commands[ modelElement ].value ).to.be.false;
+			} );
 		}
 	} );
 
@@ -191,4 +213,44 @@ describe( 'HeadingCommand', () => {
 			}
 		} );
 	} );
+
+	describe( 'isEnabled', () => {
+		for ( let option of options ) {
+			test( option.modelElement );
+		}
+
+		function test( modelElement ) {
+			let command;
+
+			beforeEach( () => {
+				command = commands[ modelElement ];
+			} );
+
+			describe( `${ modelElement } command`, () => {
+				it( 'should be enabled when inside another block', () => {
+					setData( document, '<paragraph>f{}oo</paragraph>' );
+
+					expect( command.isEnabled ).to.be.true;
+				} );
+
+				it( 'should be disabled if inside non-block', () => {
+					setData( document, '<notBlock>f{}oo</notBlock>' );
+
+					expect( command.isEnabled ).to.be.false;
+				} );
+
+				it( 'should be disabled if inside object', () => {
+					setData( document, '<object>f{}oo</object>' );
+
+					expect( command.isEnabled ).to.be.false;
+				} );
+
+				it( 'should be disabled if selection is placed on object', () => {
+					setData( document, '[<object>foo</object>]' );
+
+					expect( command.isEnabled ).to.be.false;
+				} );
+			} );
+		}
+	} );
 } );